Telerik ASP.NET MVC 3 Grid - setting row background - asp.net-mvc-3

I'm using Telerik Grid. I need to set background color for the entire row based on some property in view model. I've tried to do it as below by setting a background in IF statement for each column but backgound applies only on element not all cell (td). Also it seems it's a very "dirty" way to accomplish this task.
#(Html.Telerik().Grid(Model.SomeItems).Name("Grid")
.Columns(columns =>
{
columns.Template(
#<text>
#if (Model.IsOfSpecialColor)
{
<div class="gridRowBackground">
#Html.ActionLink(...)
</div>
}
else
{
#Html.ActionLink(...)
}
</text>).Title("Blabla");
});

You can change it using onRowDataBound event
#(Html.Telerik().Grid<Customer>()
.Name("Grid2")
.DataBinding(d => d.Ajax().Select("Select", "Home"))
.ClientEvents(e => e.OnRowDataBound("onRowDataBound"))
)
and the function is
<script>
function onRowDataBound(e) {
if (e.dataItem.ID == 2) {
e.row.style.backgroundColor = "grey";
}
}
</script>

If you are using server data binding, you can use CellAction. However, if you are using ajax data binding, you will need to use a solution like Tassadaque suggests.
#(Html.Telerik().Grid(Model.SomeItems)
.Name("Grid")
.CellAction(cell =>
{
if (cell.DataItem.IsOfSpecialColor.Value)
{
cell.HtmlAttributes["style"] = "background-color: red";
}
})

Related

Kendo Grid: Toolbar template issue

I have a grid that lists Road information and want a Toolbar Template that will allow me to filter the roads by choosing a Concession from a DropDownList. Something like this
My code:
CSHTML
<div id="datagrid">
#(Html.Kendo().Grid<SustIMS.Models.RoadModel>()
.Name("datagrid_Roads")
.Columns(columns =>
{
columns.Bound(r => r.RoadCode).Title(ViewBag.lblCode).Width(140);
columns.Bound(r => r.RoadType).Title(ViewBag.RoadType).Width(140);
columns.Bound(r => r.RoadMediumDescription).Title(ViewBag.lblDescription);
columns.Bound(r => r.ConcessionCode).Title("CCode").Hidden();
columns.Bound(r => r.ConcessionMediumDescription).Hidden().Title(ViewBag.Concession);
})
.ToolBar(toolbar =>
{
toolbar.Template(#<text>
<div class="toolbar">
<label class="category-label" for="category">Concessão:</label>
#(Html.Kendo().DropDownList()
.Name("concessions")
.OptionLabel("All")
.DataTextField("ConcessionMediumDescription")
.DataValueField("CCode")
.AutoBind(false)
.Events(e => e.Change("concessionChange"))
.DataSource(ds =>
{
ds.Read("ConcessionFiltering", "MasterData");
})
)
</div>
</text>);
})
.HtmlAttributes(new { style = "height: 534px;" })
...
)
)
</div>
<script type="text/javascript">
function concessionChange() {
var value = this.value(),
grid = $("#datagrid_Roads").data("kendoGrid");
if (value) {
grid.dataSource.filter({ field: "ConcessionMediumDescription", operator: "eq", value: value });
} else {
grid.dataSource.filter({});
}
}
Controller
public ActionResult ConcessionFiltering()
{
ConcessionModel cm = new ConcessionModel();
var aux = cm.getConcessions();
return Json(aux.concessions.Select(c => c.concession.mediumDescription).Distinct(), JsonRequestBehavior.AllowGet);
}
This is the current result:
The list is filled with the word "undefined" 16 times, which is the number of concessions I currently have. When I select one of the undefined options, it shows the actual name of the concession, refreshes the grid but doesn't filter it.
I want the list to show the concession names and to filter the grid by concession as I select one of them. What am I missing?
change this
return Json(aux.concessions.Select(c => c.concession.mediumDescription).Distinct(), hJsonRequestBehavior.AllowGet);
to
return Json(aux.concessions.Select(c => new ConcessionModel { Description = c.concession.mediumDescription }).Distinct(), JsonRequestBehavior.AllowGet);
First, double check what Json you are returning from the controller method. It looks like your ConcessionMediumDescriptions may have no data in them.
Second, it looks like, in your controller, that you are returning a list of "ConcessionMediumDescription" data objects.
I am guessing it looks like this...
{ConcessionMediumDescription: {
CCode: 'mycode',
...
}
}
You may consider returning a title field as a part of this Json and to use that for the text field of your dropdown. This is just me guessing from what you are returning in that controller.
Ideal Json would be somting like this...
[{
{{id: 'id1'},{text: 'text1'}},
{{id: 'id2'},{text: 'text2'}}
}]
And you defind your dropdown as such.
.DataTextField("text")
.DataValueField("id")
You have to do json return line like this.
return Json(aux.concessions.Select(c => new { Value = c.concession.DATAVALUE, Text = c.concession.DATATEXT }), JsonRequestBehavior.AllowGet);
Just change DATAVALUE and DATATEXT

mvc3: Multiline Text area with value defined in the view

I am want to have a text area with multiple lines and a value in MVC3. I can't seem to define a textareafor or an editorfor that has a #Value attribute which I can set. I want to have something like
#Html.TextAreaFor(x => x.model, 10, 15, new{#Value="try"})
Also, I want to be able to do this in the view because the default value will depend on an attribute of another model used within the same view.
Any thoughts please.
The textarea html element does not support the value attribute. So you can't set its value using #Html.TextAreaFor.
So what you have to do is this:
#model MvcApplication.Models.Model
#{
if (1 > 2) // your logic here
{
Model.Description = "value1";
}
else
{
Model.Description = "value2";
}
}
#Html.TextAreaFor(model => model.Description, new { #rows = "10", #cols = "15" })
Let the html helper handle the rendering.
Use Telerik control
Html.Telerik().EditorFor(model => model.Description)
.Name("Editor")
.HtmlAttributes(new { style = "height:400px" })
.Encode(false)
.Value((String)ViewBag.Contents)
.Render();

Binding a grid to a drop down list

I have a grid that I want to show depending on the result of the drop down list. I can't seem to be able to send the values to the select("controller", "action", data) method. How can I do that? I can't get my javascript to handle it.
This is the drop down list
<select id="workoutType" onchange="changed(value)">
#{ foreach (var type in Model.WorkoutTypes)
{
<option value="#type"> #type </option>
}
}
</select>
and here is the grid
#(Html.Telerik().Grid(Model.Approvers)
.Name("Orders")
.DataBinding(dataBinding => dataBinding
//Ajax binding
.Ajax()
//The action method which will return JSON
.Select("__AjaxBinding", "AssetResearch", new { workoutType = ViewData["dropDownValue"] })
)
.Columns(columns =>
{
columns.Bound(o => o.InvestorName).Width(125);
columns.Bound(o => o.ApproverType).Title("Type").Width(100);
columns.Bound(o => o.Email).Title("E-mail Address");
})
.ClientEvents(events => events
.OnDataBinding("onDataBinding")
)
.Pageable()
.Sortable()
)
I tried using Viewbag and sadly I can't seem to pull it off.
$(document).ready(function() {
$('#workoutType').change(function(){
//bind your data here
var data = $(this).value;
// pass into your C# stuff here
});
});
Would something like this work?
this is not the right way to achieve it because the RouteValue cannot be set on the server (when you are rendering the Grid)
One way to achieve it is to use the change event of the DropDOwnList which Phonixblade9 mentioned to make the Grid perform request and fetch its data from the server. This could be achieved through the ajaxRequest method of the Grid.
Here is what I mean:
$(document).ready(function() {
$('#workoutType').change(function(){
var data = $(this).value;
var gridClientObject = $('#Orders').data().tGrid;
gridClientObject.ajaxRequest({workoutType :data});// do not forget to name the parameter in the action again method again 'workoutType'
});
});

How to pass an object from a View to a Partial View within a popup window?

I have a view containing a Telerik grid:
Index.cshtml
#(Html.Telerik().Grid(Model)
.Name("Grid")
.DataKeys(keys => keys.Add(c => c.CustomerID))
.ToolBar(toolBar => toolBar.Template(
#<text>
<button id="feedback-open-button" title="Add Customer" class="t-button t-state-default">Add</button>
</text>))
.Columns(columns =>
{
columns.AutoGenerate(column =>
{
//customize autogenereted column's settings
column.Width = "150px";
if (column.Member == "CustomerID")
column.Visible = false;
});
columns.Command(commands => commands
.Custom("editCustomer")
.Text("Edit")
.DataRouteValues(route => route.Add(o => o.CustomerID).RouteKey("CustomerID"))
.Ajax(true)
.Action("EditCustomer", "Grid"))
.HtmlAttributes(new { style = "text-align: center" })
.Width(150);
})
)
I want to add/edit records to this grid using a popup. I have used a Telerik Window, in which I have opened another view as Partial View to add/edit records. This is the code for the window and how I am opening it as a popup for "ADD functionality".
Index.cshtml
#{ Html.Telerik().Window()
.Name("Window")
.Title("Add / Edit Customer")
.Content(#<text>
#Html.Partial("AddEditCustomer", new Customer());
</text>)
.Width(400)
.Draggable(true)
.Modal(true)
.Visible(false)
.Render();
}
#{ Html.Telerik().ScriptRegistrar()
.OnDocumentReady(#<text>
// open the initially hidden window when the button is clicked
$('#feedback-open-button')
.click(function(e) {
e.preventDefault();
$('#Window').data('tWindow').center().open();
});
</text>);
}
I have tried to use the same window for edit. But I am having problem in passing the customer object to the partial view within the window.
CustomerController.cs
public JsonResult EditCustomer(int CustomerID)
{
var model = CustomerModel._CustomerCollection.FirstOrDefault(o => o.CustomerID == CustomerID);
return Json(new { customer = model });
}
Index.cshtml
<script type="text/javascript">
function onComplete(e) {
if (e.name == "editCustomer") {
var detailWindow = $("#Window").data("tWindow");
var customer = e.response.customer;
detailWindow.center().open();
}
}
</script>
How can I pass this "customer" object to the partial view inside the popup window?
The way we deal with this where I work is by creating an empty div in the Telerik window. The "edit" link is an AJAX link which uses the window's div as its target. The link calls the controller method of your choice, and from there rather than returning Json, just return the PartialView you want displayed. The benefit of this approach is you use the customer object just like you would for any normal view/partial.
After the AJAX completes, open the Telerik window and the content should be there.

Custom Button in a ClientRowTemplate on the Telerik MVC Grid

Sorry if this is a repeat. I did a search and didn't find anything that exactly matched my situation.
I have a grid that requires a ClientRowTemplate. I have the template working very well.
I need a button in that RowTemplate that calls back to a controller method through ajax. The controller method needs to perform some complex logic and then return a new set of data to the grid which the grid will then need to bind to. I thought this should work in the same fashion as an ajax binding. For instance, when you do a save or delete (using the built in buttons) an ajax method that is attributed with [GridAction] is called and then has an IQueryable returned. The grid automatically binds to this IQueryable.
How do I do the same thing with a custom button? Is it even possible to add a custom button when using a ClientRowTemplate?
Put a link in the clienttemplate of your grid row
#(Html.Telerik().Grid<myModel>()
.Name("myGrid")
.Columns(columns =>
{
#* You can put a link in your client template to trigger a refresh function *#
columns.Bound(o => o.Id).ClientTemplate("<a href='javascript:refreshGrid(<#= Id #>);'>Refresh</a>");
columns.Bound(e => e.col1);
columns.Bound(e => e.col2);
columns.Bound(e => e.col3);
})
.ClientEvents(events => events.OnDataBinding("myGrid_onRowDataBinding"))
.DataBinding(dataBinding => dataBinding.Ajax().Select("Action", "Controller", new { param1 = ..., param2 = ... } )))
Write your code to refresh grid
<script type="text/javascript">
//parameters needed for grid
var x = ...;
var y = ...;
//grid refresh function
function refreshGrid(id) {
//make a call to server
$.post("/controller/action/" + id, function() {
//after making a successfull call to server
//you may update parameters
x = ...;
y = ...;
//and rebind your grid
$('#myGrid').data('tGrid').rebind();
})
}
//grid on row data binding event
function myGrid_onRowDataBinding(e) {
e.data = $.extend(e.data, { param1: x, param2: y });
}
</script>
That's it
EDIT:
ClientRowTemplate example
You need to change only the grid code. The rest is same.
#(Html.Telerik().Grid<myModel>()
.Name("myGrid")
.ClientRowTemplate(grid => "<div class='firstcolumn'><a href='javascript:refreshGrid(<#= Id #>);'>Refresh</a></div><div class='secondcolumn'>Content....</div>")
.ClientEvents(events => events.OnDataBinding("myGrid_onRowDataBinding"))
.DataBinding(dataBinding => dataBinding.Ajax().Select("Action", "Controller", new { param1 = ..., param2 = ... } )))

Resources