Let's say I have a data like this:
[
{ID: 1, SomeForeignKeyID: 4, IsFkEnabled: true},
{ID: 2, SomeForeignKeyID: 9, IsFkEnabled: false}
]
Kendo Grid is using this data:
columns.Bound(m => m.ID);
columns.ForeignKey(p => p.SomeForeignKeyID, ViewBag.ForeignKeys as IEnumerable<object>, "Value", "Name");
Here's the problem: how to make ForeignKey column editable, but only in rows, where IsFkEnabled == true? Edit mode is InCell.
Notes:
this solution works for in-cell editing only (inline or popup editing
require a different approach)
the first approach can lead to unwanted visual effects (grid
jumping) under certain circumstances; if you experience that, I
recommend approach #2
approach #2 may not work if you want to use the MVC wrappers (although it may be possible to extend Kendo.Mvc.UI.Fluent.GridEventBuilder); in that case, you'll need to bind the edit handler in JS
Approach #1
Use the grid's edit event and then do something like this:
$("#grid").kendoGrid({
dataSource: dataSource,
height: "300px",
columns: columns,
editable: true,
edit: function (e) {
var fieldName = e.container.find("input").attr("name");
// alternative (if you don't have the name attribute in your editable):
// var columnIndex = this.cellIndex(e.container);
// var fieldName = this.thead.find("th").eq(columnIndex).data("field");
if (!isEditable(fieldName, e.model)) {
this.closeCell(); // prevent editing
}
}
});
/**
* #returns {boolean} True if the column with the given field name is editable
*/
function isEditable(fieldName, model) {
if (fieldName === "SomeForeignKeyID") {
// condition for the field "SomeForeignKeyID"
// (default to true if defining property doesn't exist)
return model.hasOwnProperty("IsFkEnabled") && model.IsFkEnabled;
}
// additional checks, e.g. to only allow editing unsaved rows:
// if (!model.isNew()) { return false; }
return true; // default to editable
}
Demo here (updated for Q1 2014)
To use this via the MVC fluent syntax, simply give the anonymous edit function above a name (e.g. onEdit):
function onEdit(e) {
var fieldName = e.container.find("input").attr("name");
// alternative (if you don't have the name attribute in your editable):
// var columnIndex = this.cellIndex(e.container);
// var fieldName = this.thead.find("th").eq(columnIndex).data("field");
if (!isEditable(fieldName, e.model)) {
this.closeCell(); // prevent editing
}
}
and reference it like this:
#(Html.Kendo().Grid()
.Name("Grid")
.Events(events => events.Edit("onEdit"))
)
The disadvantage to this is that the editor gets created first before the edit event is triggered, which can sometimes have undesirable visual effects.
Approach #2
Extend the grid by overriding its editCell method with a variation that triggers a beforeEdit event; for that to work with grid options, you'll also need to override the init method:
var oEditCell = kendo.ui.Grid.fn.editCell;
var oInit = kendo.ui.Grid.fn.init;
kendo.ui.Grid = kendo.ui.Grid.extend({
init: function () {
oInit.apply(this, arguments);
if (typeof this.options.beforeEdit === "function") {
this.bind("beforeEdit", this.options.beforeEdit.bind(this));
}
},
editCell: function (cell) {
var that = this,
cell = $(cell),
column = that.columns[that.cellIndex(cell)],
model = that._modelForContainer(cell),
event = {
container: cell,
model: model,
field: column.field
};
if (model && this.trigger("beforeEdit", event)) {
// don't edit if prevented in beforeEdit
if (event.isDefaultPrevented()) return;
}
oEditCell.call(this, cell);
}
});
kendo.ui.plugin(kendo.ui.Grid);
then use it similar to #1:
$("#grid").kendoGrid({
dataSource: dataSource,
height: "300px",
columns: columns,
editable: true,
beforeEdit: function(e) {
var columnIndex = this.cellIndex(e.container);
var fieldName = this.thead.find("th").eq(columnIndex).data("field");
if (!isEditable(fieldName, e.model)) {
e.preventDefault();
}
}
});
The difference of this approach is that the editor won't get created (and focused) first. The beforeEdit method is using the same isEditable method from #1.
See a demo for this approach here.
If you want to use this approach with MVC wrappers but don't want / can't extend GridEventBuilder, you can still bind your event handler in JavaScript (place below the grid MVC initializer):
$(function() {
var grid = $("#grid").data("kendoGrid");
grid.bind("beforeEdit", onEdit.bind(grid));
});
None of these approaches worked for me. A very simple implentation looks like this
edit: function (e) {
e.container.find("input[name='Name']").each(function () { $(this).attr("disabled", "disabled") });
}
Where edit is part of the kendo grid declaration and Name is the actual name of the field.
Please try with the below code snippet.
VIEW
<script type="text/javascript">
function errorHandler(e) {
if (e.errors) {
var message = "Errors:\n";
$.each(e.errors, function (key, value) {
if ('errors' in value) {
$.each(value.errors, function () {
message += this + "\n";
});
}
});
alert(message);
}
}
function onGridEdit(arg) {
if (arg.container.find("input[name=IsFkEnabled]").length > 0) {
arg.container.find("input[name=IsFkEnabled]").click(function () {
if ($(this).is(":checked") == false) {
}
else {
arg.model.IsFkEnabled = true;
$("#Grid").data("kendoGrid").closeCell(arg.container);
$("#Grid").data("kendoGrid").editCell(arg.container.next());
}
});
}
if (arg.container.find("input[name=FID]").length > 0) {
if (arg.model.IsFkEnabled == false) {
$("#Grid").data("kendoGrid").closeCell(arg.container)
}
}
}
</script>
<div>
#(Html.Kendo().Grid<MvcApplication1.Models.TestModels>()
.Name("Grid")
.Columns(columns =>
{
columns.Bound(p => p.ID);
columns.Bound(p => p.Name);
columns.Bound(p => p.IsFkEnabled);
columns.ForeignKey(p => p.FID, (System.Collections.IEnumerable)ViewData["TestList"], "Value", "Text");
})
.ToolBar(toolBar => toolBar.Save())
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Pageable()
.Sortable()
.Scrollable()
.Filterable()
.Events(e => e.Edit("onGridEdit"))
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.ServerOperation(false)
.Events(events => events.Error("errorHandler"))
.Model(model =>
{
model.Id(p => p.ID);
model.Field(p => p.ID).Editable(false);
})
.Read(read => read.Action("ForeignKeyColumn_Read", "Home"))
.Update(update => update.Action("ForeignKeyColumn_Update", "Home"))
)
)
</div>
MODEL
namespace MvcApplication1.Models
{
public class TestModels
{
public int ID { get; set; }
public string Name { get; set; }
public bool IsFkEnabled { get; set; }
public int FID { get; set; }
}
}
CONTROLLER
public class HomeController : Controller
{
public ActionResult Index()
{
List<SelectListItem> items = new List<SelectListItem>();
for (int i = 1; i < 6; i++)
{
SelectListItem item = new SelectListItem();
item.Text = "text" + i.ToString();
item.Value = i.ToString();
items.Add(item);
}
ViewData["TestList"] = items;
return View();
}
public ActionResult ForeignKeyColumn_Read([DataSourceRequest] DataSourceRequest request)
{
List<TestModels> models = new List<TestModels>();
for (int i = 1; i < 6; i++)
{
TestModels model = new TestModels();
model.ID = i;
model.Name = "Name" + i;
if (i % 2 == 0)
{
model.IsFkEnabled = true;
}
model.FID = i;
models.Add(model);
}
return Json(models.ToDataSourceResult(request));
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ForeignKeyColumn_Update([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<TestModels> tests)
{
if (tests != null && ModelState.IsValid)
{
// Save/Update logic comes here
}
return Json(ModelState.ToDataSourceResult());
}
}
If you want to download demo then click here.
The simplest way is to use the dataBound event to conditionally apply one of the special CSS classes to the cells that the grid ignore for editing:
http://dojo.telerik.com/izOka
dataBound: function(e) {
var colIndex = 1;
var rows = this.table.find("tr:not(.k-grouping-row)");
for (var i = 0; i < rows.length; i++) {
var row = rows[i];
var model = this.dataItem(row);
if (!model.Discontinued) {
var cell = $($(row).find("td")[colIndex]);
cell.addClass("k-group-cell");
}
}
},
Another approach is to use your own "editor" function for column definition that provides either an input element or a plain div depending on your condition.
Use Template column instead of Bound column
columns.Template(#<text></text>).ClientTemplate("#=Id#").Title("Id");
Related
I have a controller that uses a ViewBag to bring the data into the view.
var _021CheckBox = dc.OptionsTbls.Where(a => a.Question_ID == 21).ToList();
ViewBag.CheckBoxfacilities = new SelectList(_021CheckBox, "ID", "QOption").ToList();
Then i have the View that's supposed to submit a string back to the controller but it only sends the first selected item. I even tried Javascript to combine the two but that did not work either. here's my view (both listboxfor and loop
//Loop
#for (int i = 0; i < ViewBag.CheckBoxfacilities.Count; i++)
{
#Html.HiddenFor(model => model._021CheckBox[i], new { #id = "_021CheckBox" })
<input name="_021CheckBox" type="checkbox" value="#ViewBag.CheckBoxfacilities[i].Text" id="#ViewBag.CheckBoxfacilities[i].Value" /> #ViewBag.CheckBoxfacilities[i].Text <br />
}
// listboxfor
#Html.ListBoxFor(m => m._021CheckBox, new MultiSelectList(ViewBag.CheckBoxfacilities, "Value", "Text"), new { #Multiple = "multiple" })
//JavaScript that appends the value
<script>
var Values = [];
$('input[name=_021CheckBox]').change(function () {
if (this.checked) {
Values.push($(this).val() + ";");
}
else {
Values.pop(this);
}
$('#_021CheckBox').val(Values).appendTo('form');
document.getElementById("_021CheckBox").value = Values;
});
</script>
here is my Model. I think maybe this is where i'm messing up
[Table("TBLMajorQuestions")]
public partial class TBLMajorQuestion
{
[Key]
public int ID { get; set; }
public string _021CheckBox { get; set; }
}
I think i was trying to fit a square peg into a circle. The easiest thing to do is editvmy column from _021CheckBox to _021aCheckBox and to add two more columns into my table. _021bCheckBox and _021cCheckBox. Now i change them from strings to bits and update my model accordingly.
In the view, i took out all the extra javascript and did #html.CheckBoxFor(m => m._021aCheckBox). Done! Did the same for the other two checkboxes.
I'm still a newb at coding and just started javascript about a month ago. Sorry for the poopy code.. Any help would me so much appreciated. Thanks..
So I have a kendo grid that I am using with razor and mvc. I will also need to bind the check mark and row changes so that it will update my drop down list (CustomerServiceCustomerCodeList)... but I will try to figure that part out when I get there... First more importantly I need to get the select all button working properly. My checkboxes are established with the client template and header template. I need to figure out how to select all the check marks in my header template part of the grid using jquery. The client template check individual boxes code works but not my check all. I've tried hundreds of different approaches and cant seem to get it working. Please help.
Kendo grid :
#model IEnumerable<MyEntity.Shipment.ShipmentServiceLevel>
#{
var userCustomerCode = HttpContext.Current.Session["ServiceLevelCustomerCode"];
}
#(Html.Kendo().Grid(Model)
.Name("ServiceLevelGrid")
.Reorderable(reorder => reorder.Columns(true))
.Columns(columns =>
{
columns.Bound(s => s.IsSelected).Template(#<text></text>)
.HeaderTemplate("<input type='checkbox' class='chkbx k-checkbox' id='selectAllCheck' />")
.ClientTemplate("<input type='checkbox' id='eachCheckbox' class='chkbxq k-checkbox' />")
.Sortable(false)
.Filterable(false)
.Width(40);
columns.Bound(s => s.ServiceLevelCode).Title("Code").Width(73);
columns.Bound(s => s.ServiceLevelDescription);
columns.Command(command => { command.Edit();}).Width(77);
})
.Sortable()
.Scrollable()
//.Editable(ed => ed.Mode(GridEditMode.InCell))
.Selectable(s => s
.Type(GridSelectionType.Row)
.Mode(GridSelectionMode.Multiple)
)
.PersistSelection(false)
.HtmlAttributes(new { style = "min-height:280px; height:280px;", id = "ServiceLevelGrid" })
.DataSource(dataSource =>
{
dataSource
.Ajax()
//.Events(ev =>
//{
// //ev.Change("CustomServiceLevel_DataSourceChange");
// //ev.Edit("CustomServiceLevelEdit");
// ev.Save("CustomServiceLevelSave");
// //ev.Sync("resyncChildGrid");
// //ev.RequestEnd("AddressBook_requestEnd");
//})
.Model(model =>
{
model.Id(s => s.ServiceLevelCode);
model.Field(field => field.IsSelected).Editable(true);
model.Field(field => field.ServiceLevelCode).Editable(false);
model.Field(field => field.ServiceLevelCustomDescription).Editable(true);
})
.Batch(true)
.Update(update =>
{
update.Action("ServiceLevelGrid_Update", "UserAccount", new {Area = "Management", CustomerCode = userCustomerCode});
//update.Data("ServiceLevel_GetCustomList_Data");
})
.Read(read =>
{
read.Action("ServiceLevelGrid_Read", "UserAccount", new {Area = "Management", CustomerCode = userCustomerCode});
//read.Data("ServiceLevel_GetCustomList_Data");
});
})
)
#*.Events(ev => ev.DataBound("CustomServiceLevelGrid_DataBound"))*#
Here is my Jquery.
debugger;
//customer code dropdown list bind to grid
function ServiceLevel_GetCustomList_Data(event) {
var customServiceCustomerCodeList = $("#CustomServiceCustomerCodeList").data("kendoDropDownList"),
customServiceCustomerCodeList_DataItem = customServiceCustomerCodeList.dataItem(),
customServiceCustomerCodeList_ItemValue = customServiceCustomerCodeList_DataItem["OrganizationCode"];
var customServiceDataModel = {
customerCode: customServiceCustomerCodeList_ItemValue
}
return customServiceDataModel;
};
//Checkbox grid
debugger;
console.log();
$('#ServiceLevelGrid').on("click", ".k-checkbox", function (e) {
grdChkBoxClick(e);
});
function grdChkBoxClick(e) {
var row = $(e.target).closest('tr');
grdChkBoxUpdate(row);
};
};
//individual check box select
function grdChkBoxUpdate(row) {
debugger;
console.log();
var grid = $("#ServiceLevelGrid").data("kendoGrid"),
dataItem = grid.items().length > 0 ? grid.dataItem(row) : undefined,
isItemChecked = ($("#eachCheckbox", row).prop("checked") === true);
debugger;
console.log();
if (isItemChecked) {
var isSelected = dataItem.IsSelected;
dataItem.dirty = true;
dataItem.IsSelected = true;
console.log("isSelected: " + isSelected);
} else {
dataItem.dirty = true;
dataItem.IsSelected = false;
}
}
function checkAll(row) {
$(".chkbxq").each(function () {
debugger;
console.log();
// handle the checkbox logic
// add logic to check if is checked or not and do proper handling based on that
$(this).attr('checked', row);
// update dataItem to reflect changes.... (update model and dirty flag)
grdChkBoxUpdate;
var row = $(e.target).closest('tr');
grdChkBoxUpdate(row);
});
}
function checkAll(row) {
$(".chkbxq").each(function () {
debugger;
console.log();
function sRow() {
var trLength = $("#ServiceLevelGrid .k - checkbox table tr").length;
if (trLength > 0) {
$("#ServiceLevelGrid .k - checkbox table tr").each(function(i) {
grdChkBoxUpdate(this);
});
}
}
var isSelected = $(".k-checkbox", "#ServiceLevelGrid thead").attr("aria-checked");
if (isSelected !== "true") {
$(".k-checkbox", "#ServiceLevelGrid thead").click();
}
$(this).attr('checked', row);
var row = $(e.target).closest('tr');
grdChkBoxUpdate(row);
});
}
I still relatively new to ASP.Net and the concepts of communicating between client and server. I am using DevExpress tools but I believe this issue is more of a misunderstanding of the concept.
I have a GridView within a partial view that is loaded via an Action #Html.Action('MessageGridView'). This works no problem and data is loaded fine with the index and a returned model.
#Html.DevExpress().GridView(settings =>
{
settings.Width = System.Web.UI.WebControls.Unit.Percentage(100);
settings.Name = "preparedMessagesGrid";
settings.CallbackRouteValues = new { Controller = "Messages", Action = "MessagesGridView" };
settings.KeyFieldName = "Id";
settings.SettingsBehavior.AllowSelectByRowClick = true;
settings.SettingsBehavior.AllowSelectSingleRowOnly = true;
settings.ClientSideEvents.Init = "GridViewInit";
settings.ClientSideEvents.SelectionChanged = "OnSelectionChanged";
settings.ClientSideEvents.BeginCallback = "OnBeginCallback";
settings.SettingsBehavior.AllowEllipsisInText = true;
settings.PreRender = settings.Init = (sender, e) =>
{
MVCxGridView gridView = sender as MVCxGridView;
gridView.Selection.SelectAll();
};
settings.Columns.Add("Name");
settings.Columns.Add("Description");
}).Bind(Model.preparedMessages).GetHtml()
What I am trying to achieve is when the user selects the row I wish the data to be loaded into the popup control when clicked. Is there a way I can set the parameters dynamically for the popup control callback?
#Html.DevExpress().PopupControl(settings =>
{
settings.Name = "pcModalMode";
settings.Width = 100;
settings.AllowDragging = true;
settings.CloseAction = CloseAction.CloseButton;
settings.CloseOnEscape = true;
settings.PopupAnimationType = AnimationType.None;
settings.HeaderText = "Login";
settings.Modal = true;
settings.PopupHorizontalAlign = PopupHorizontalAlign.WindowCenter;
settings.PopupVerticalAlign = PopupVerticalAlign.WindowCenter;
settings.CallbackRouteValues = new { Controller = "Messages", Action = "Load", new { id = THIS NEEDS TO BE SELECTED ID VALUE} };
settings.LoadContentViaCallback = LoadContentViaCallback.OnFirstShow;
}).GetHtml()
It works if I set the value static so I'm one step away from getting this working. What I have researched is that I can get the values from the GridView in javascript using the selection changed event.
function OnSelectionChanged(s, e) {
s.GetSelectedFieldValues("Id", GetSelectedFieldValueCallback);
}
I can then retrieve this value but can I set this to my popup control or am I misunderstanding being relatively new and possibly I could do this server side for when the ViewGrid callback is performed, then set it server side with a session of some sort?
You're just one step away to get currently selected grid value with this function:
function OnSelectionChanged(s, e) {
s.GetSelectedFieldValues('Id', GetSelectedFieldValueCallback);
}
What you need to do is declaring GetSelectedFieldValueCallback method as this (I got from a test that selectedValue contains array with single value for single grid row selection, use zero index to assign the value):
var id; // a global variable set to hold selected row key value from grid
function GetSelectedFieldValueCallback(selectedValue) {
if (selectedValue.length == 0)
return;
id = parseInt(selectedValue[0]);
pcModalMode.PerformCallback();
}
Then setting BeginCallback on PopupControl helper as given below, note that for DevExpress HTML helpers you can use customArgs in client-side to pass action method parameters instead of using CallbackRouteValues with id parameter:
#Html.DevExpress().PopupControl(settings =>
{
settings.Name = "pcModalMode";
// other stuff
settings.CallbackRouteValues = new { Controller = "Messages", Action = "Load" };
settings.ClientSideEvents.BeginCallback = "OnPopUpBeginCallback";
settings.ClientSideEvents.EndCallback = "OnPopUpEndCallback";
// other stuff
}).GetHtml()
// JS function for popup callback
function OnPopUpBeginCallback(s, e) {
e.customArgs["id"] = id; // this sends 'id' as action method parameter to `Load` action
}
// Optional end callback
function OnPopUpEndCallback(s, e) {
if (!pcModalMode.IsVisible())
pcModalMode.Show();
}
Finally, let's putting them all together in view & controller code:
View
<!-- View page -->
<script type="text/javascript">
var id;
function OnSelectionChanged(s, e) {
s.GetSelectedFieldValues('Id', GetSelectedFieldValueCallback);
}
function GetSelectedFieldValueCallback(selectedValue) {
if (selectedValue.length == 0)
return;
id = parseInt(selectedValue[0]);
pcModalMode.PerformCallback();
}
function OnPopUpBeginCallback(s, e) {
e.customArgs["id"] = id;
}
function OnPopUpEndCallback(s, e) {
if (!pcModalMode.IsVisible())
pcModalMode.Show();
}
</script>
GridView (partial view)
#Html.DevExpress().GridView(settings =>
{
settings.Name = "preparedMessagesGrid";
// other stuff
settings.ClientSideEvents.SelectionChanged = "OnSelectionChanged";
}).Bind(Model.preparedMessages).GetHtml()
Popup (partial view)
#Html.DevExpress().PopupControl(settings =>
{
settings.Name = "pcModalMode";
// other stuff
settings.CallbackRouteValues = new { Controller = "Messages", Action = "Load" };
settings.ClientSideEvents.BeginCallback = "OnPopUpBeginCallback";
settings.ClientSideEvents.EndCallback = "OnPopUpEndCallback";
// other stuff
}).GetHtml()
Controller
public class Messages : Controller
{
public ActionResult MessagesGridView()
{
// grid view populating data code lines here
return PartialView("_GridView", data);
}
public ActionResult Load(int id)
{
// code lines to find ID here
return PartialView("_ModalPopup", model);
}
}
References:
(1) Display GridView Row Details in PopupControl Window
(2) How to display detail data within a popup window (MVC)
(3) ASPxClientGridView.GetSelectedFieldValues (DevExpress Documentation)
(4) MVCxClientBeginCallbackEventArgs.customArgs (DevExpress Documentation)
I apologize I am still fairly new to MVC. I currently have a dropdownlist with some options. What I would like to do is depending on the dropdownlist value that I select then I should be able to render a partial view. I want the partial view to load as soon as the user selects from the dropdownlist.
Also, I am able to render my partial view but it's not returning what I need. When I select from the dropdownlist it does not take the functionID..it just returns all of the items regardless of the functionID.
I want the partial view to render based off the functionID.
Thank you very much. Any help is very much appreciated it.
Main View
#Html.DropDownListFor(m => m.FunctionID, new
SelectList(Model.functionList, "FunctionID", "Name"), "Select
Function", new {#id="id"})
<div id="partialPlaceHolder">
</div>
Partial View
#foreach (var items in Model.itemTypeList)
{
<pre> #items.Definitions</pre>
}
Controller
[HttpGet]
public ActionResult ViewOverview()
{
List<Function> functionList;
List<ItemType> itemTypeList;
using (BusinessLogic BLL = new BusinessLogic())
{
functionList = BLL.GetFunctionList();
itemTypeList = BLL.GetItemTypesList();
}
Words viewModel = new Words();
MetricDefinitions(viewModel);
return View(viewModel);
}
[HttpGet]
public ActionResult GetWords()
{
List<Function> functionList;
List<ItemType> itemTypeList;
using (BusinessLogic BLL = new BusinessLogic())
{
functionList = BLL.GetFunctionList();
itemTypeList = BLL.GetItemTypesList();
}
Words viewModel = new Words()
{
itemTypeList = itemTypeList,
functionList = functionList
};
return PartialView("_ViewWords", viewModel);
}
private void MetricDefinitions(Words model)
{
List<Function> functionList;
List<ItemType> itemTypeList;
using (BusinessLogic BLL = new BusinessLogic())
{
functionList = BLL.GetFunctionList();
itemTypeList = BLL.GetItemTypesList();
}
model.functionList = functionList;
model.itemTypeList = itemTypeList;
}
javascript
$(document).ready(function () {
$('#id').change(function () {
var selectedID = $(this).val();
$.get('/Home/GetWords/' + selectedID, function (data) {
$('#partialPlaceHolder').html(data);
/* little fade in effect */
$('#partialPlaceHolder').fadeIn('fast');
});
});
});
I have added NetFiddle. It works here
Can you try to add selectedItem param into action and use jquery .load() function to get partial result into your target element.
[HttpGet]
public ActionResult GetWords(int selectedItem) // add your selectedVal value in controller
{
.....
}
jquery
// it is going to parse partial view into target div
$("#id").on("change", function(){
var url = '#Url.Action("GetWords", "Home")' + "?selectedItem=" + $(this).val();
$("#partialPlaceHolder").load(url, function(){
console.log("It worked");
$('#partialPlaceHolder').fadeIn('fast');
})
})
#{
ViewBag.Title = " Grid with Multicolumn headers";
}
#using Kendo.Mvc.UI
#using SampleUIApp.Areas.GridSample.Models
#model SampleUIApp.Areas.GridSample.Models.GridSampleModel
#{
ViewBag.Title = "Grid Sample - InLine Edit";
Layout = "~/Views/Shared/_PageLayout.cshtml";
}
#section pageBody {
<div style="float:right;margin-right:10px;margin-top:10px;margin-bottom:10px">
#(Html.Kendo().Button()
.Name("Hide_toolbar")
.Events(e => e.Click("Hidetoolbar"))
.Content("Hide Toolbar"))
#(Html.Kendo().Button()
.Name("Show_toolbar")
.Events(e => e.Click("Showtoolbar"))
.Content("Show Toolbar"))
</div>
<br />
<br />
#using (Html.BeginForm("InLineIndex", "GridSample", FormMethod.Post, new { #id = "InLineIndexMain" }))
{
<div id="DetailPanel" class="containerDiv100">
#(Html.Kendo().Grid<GridSampleModel>()
.Name("KendoGrid1") // Grid Name can be used in Javascript, if required.
//Columns defination of the fields.
.Columns(columns =>
{
columns.Template(m => m.SampleId).Title("<input id='checkAll', type='checkbox', class='check-box' />");
columns.Group(group=>group
.Title("Personal Information")
.Columns(info => {
info.Bound(m => m.SampleName).Title("Sample Name").Width(200).Filterable(true).HtmlAttributes(new { #style = "font-size:x-small" });
info.Bound(m => m.Age).Title("Age").Width(100).Filterable(false).Format("{0:d}").HtmlAttributes(new { #style = "text-align:right" });
info.Bound(m => m.Height).Title("Height").Width(150).Locked().Filterable(false).Format("{0:N2}").HtmlAttributes(new { #style = "font-size:x-small" });
info.Bound(m => m.City).Title("City (Auto Complete)").Width(350).Lockable(false).Filterable(true).ClientTemplate("#=City.CityName#");
})
);
//columns.Bound(m => m.Age).Title("Age").Width(100).Filterable(false).Format("{0:d}").HtmlAttributes(new { #style = "text-align:right" });
//columns.Bound(m => m.Height).Title("Height").Width(150).Locked().Filterable(false).Format("{0:N2}").HtmlAttributes(new { #style = "font-size:x-small" });
//columns.Bound(m => m.City).Title("City (Auto Complete)").Width(350).Lockable(false).Filterable(true).ClientTemplate("#=City.CityName#");
columns.Bound(m => m.Category).Title("Category (Drop Down List)").Width(400).Filterable(true).ClientTemplate("#=Category.CategoryName#");
columns.Bound(m => m.EmployeeList).Title("Employee (Multi Select)").Width(300).Filterable(true).ClientTemplate("#= renderSelectedEmployees(data.EmployeeList)#")
.EditorTemplateName("ClientEmployee");
columns.Bound(m => m.EntityStatus).Title("Status (CheckBox)").Width(200);
columns.Bound(m => m.CreditCard).Title("Credit Card No (Masked TextBox)").Width(250).HtmlAttributes(new { #Style = "font-size:x-small" });
columns.Bound(m => m.StartDate).Title("Start Date ").Width(150).Filterable(false).Format("{0:dd/MM/yyyy}").HtmlAttributes(new { #style = "font-size:x-small" });
columns.Bound(m => m.EndDate).Title("End Date").Width(150).Filterable(false).Format("{0:dd/MM/yyyy}").HtmlAttributes(new { #style = "font-size:x-small" });
columns.Bound(m => m.Qty).Title("Quantity").Width(100).ClientTemplate("#=Qty#").HtmlAttributes(new { #Style = "text-align:right" });
columns.Bound(m => m.Rate).Title("Rate").Width(100).ClientTemplate("#=Rate#").Format("{0:N2}").HtmlAttributes(new { #Style = "text-align:right" });
columns.Bound(m => m.LineValue).Title("Value").Width(100).Format("{0:n2}").HtmlAttributes(new { #Style = "text-align:right;" });
columns.Command(commands =>
{
commands.Edit().Text(" ");
commands.Destroy().Text(" ");
commands.Custom("Hide").Click("Hide").HtmlAttributes(new { #style = "min-width : 0;font-size:x-small;" });
}).Title("Commands").Width(200).HtmlAttributes(new { #style = "font-size:x-small" });
})
.ToolBar(toolbar =>
{
toolbar.Custom().Text("Add New Sample").Name("add").HtmlAttributes(new { #class = "Toolbar_right" }).HtmlAttributes(new { #style = "font-size:x-small" }).Url("~/GridSample/GridSample02/Create");
toolbar.Create().HtmlAttributes(new { #class = "Toolbar_right" }).HtmlAttributes(new { #class = "hide-button" });
})
.Editable(editable => editable.Enabled(#Model.EditEnable).Mode(GridEditMode.InLine)) // will make grid editable with all cells
// Here "Enabled(#Model.EditEnable)" will allow user to edit the grid control or not depending on Model's EditEnable value i.e. True / False
.Pageable() // Display grid data in multiple pages depending on PageSize parameter
.Scrollable(config => config.Enabled(true)) // Make grid Scrollable
.Filterable(config => config.Mode(GridFilterMode.Menu)) // Allow to set filters on different columns of the grid
.Sortable() // Allow user to sort the data in grid
.ColumnMenu() // Display menu with different actions on
// Display grid row in different colour it will be helpful to identify which grid row is selected.
.Selectable(selectable => selectable
.Mode(GridSelectionMode.Multiple)
.Type(GridSelectionType.Row))
.Navigatable()
.Resizable(config => { config.Columns(true); })
.Reorderable(config => { config.Columns(true); })
.Events(events => events.Save("OnCellDataModified").Edit("OnCellChange")) // Grid events to call javascripts on different actions.
.DataSource(source => source
.Ajax()
.Batch(false)
.PageSize(5)
.ServerOperation(false)
.Model(model =>
{
model.Id(m => m.SampleId);
model.Field(m => m.Category).DefaultValue(
ViewData["defaultCategory"] as CategoryViewModel);
model.Field(m => m.City).DefaultValue(
ViewData["defaultCity"] as CityViewModel);
//Given below code will not allow user
//to change (either manual / calculated) the given cell value
//But it will also do not change updated value in model
//model.Field(m => m.LineValue).Editable(false);
})
// Actions called from controller
.Read(read => read.Action("Fetch", "GridSample", new { area = "GridSample" }))
.Create(create => create.Action("InLine_Insert", "GridSample", new { area = "GridSample" }))
.Update(update => update.Action("InLine_Update", "GridSample", new { area = "GridSample" }))
.Destroy(delete => delete.Action("Delete", "GridSample", new { area = "GridSample" }))
)
)
</div>
<script type="text/javascript">
// Code added for Keyboard Navigation Support
$(document.body).keydown(function (e) {
if (e.altKey && e.keyCode == 87) {
$("#grid").data("kendoGrid").table.focus();
}
});
function OnSelectEmply(e) {
// This sample javascript function called from Employee MultiSelect Partial View
}
function CalculateTotValue(data) {
return data.Qty * data.Rate;
}
function OnCellChange(e) {
//alert("Cell Change");
//Disable the edit mode depending on the model value of EntityStatus field i.e. True / False
$("#LineValue").prop("disabled", e.model.EntityStatus);
//Set Default values while adding new row in Grid
if (e.model.isNew() && !e.model.dirty) {
e.container
.find("input[name=SampleName]") // get the input element for the field
.val("Sample Name - 4") // set the value
.change(); // trigger change in order to notify the model binding
}
}
function OnCellDataModified(e) {
//alert("Cell Data Modified");
if (e.values && e.values.LineValue) {
//alert("Calculate # LineValue");
var qty = e.values.Qty || e.model.Qty;
var rate = e.values.Rate || e.model.Rate;
e.model.set("LineValue", rate * qty);
e.values.set("LineValue", rate * qty);
$("#KendoGrid1").data("kendoGrid").refresh();
}
else {
if (e.values && (e.values.Qty || e.values.Rate)) {
//alert("Calculate # Qty, Rate");
var qty = e.values.Qty || e.model.Qty;
var rate = e.values.Rate || e.model.Rate;
e.model.set("LineValue", rate * qty);
e.values.set("LineValue", rate * qty);
$("#KendoGrid1").data("kendoGrid").refresh();
}
}
}
function renderSelectedEmployees(List) {
//alert(List.length);
if (List != undefined && List[0] != undefined) {
var text;
$.each(List, function (index) {
if (text == undefined)
text = List[index].EmployeeName;
else
text = text + ", " + List[index].EmployeeName;
})
//alert($("#LineValue").width);
if (text.length > 30) {
text = text.substring(0, 5) + " .... (" + List.length.toString().trim() + ")"
}
return text;
}
else
return "";
}
function Hide(e)
{
var grid = $("#KendoGrid1").data("kendoGrid");
////e.preventDefault();
//var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
//var row = $(this).closest("tr");
//var rowIdx = $("tr", grid.tbody).index(row);
//grid.tbody.find("tr:first").hide();
grid.tbody.closest("tr").Hide();
//grid.tbody.closest("tr").hide();
//var item = this.dataSource.get(); //Get by ID or any other preferred method
//this.tbody.find("tr[data-uid='" + item.uid + "']").hide();
}
function Hidetoolbar() {
$(".k-grid-add").hide();
}
function Showtoolbar() {
$(".k-grid-add").show();
}
$("#kendoGrid1").on("click", ".hide-button", function () {
alert("reached");
$(this).parent().parent().hide();
});
</script>
}
}
As you can see there is custom command button know as hide in my grid.. i wish to hide the row when that button is clicked..
how do i get hat done?
i have tried a line as grid.tbody.find("tr:first").hide();
but this works only for the first line. wha should i do for the other rows?
Your selector will find only the first tr, so only the first line.
You need to change your selecor to:
grid.tbody.closest("tr").hide();
This code is very ugly:
commands.Custom("Hide").Click("Hide").HtmlAttributes(new { #style = "min-width : 0;font-size:x-small;" });
It is mixing server-side code with css and javascript. Forget about the click event and do not give it style attribute. You should give it a class attribute. Let's name its class hide-button.
Define a rule for your hide-button elements in CSS, like this:
.hide-button {
min-width: 0;
font-size: x-small;
}
Make sure that this CSS rule is loaded in your page.
Then, your Javascript should be defined. Since you have not given us the HTML the code generated, I will assume your HTML contains a grid, which contains a tbody, which contains tr elements, which contain td elements. One of the td elements will contain your hide-button in each row. So, you should define this behavior:
$("body").on("click", ".hide-button", function() {
$(this).parent().parent().hide();
});
Note, that since you did not give me enough information, I have used assumptions in my answer. As a result, if any of my assumptions was wrong, the answer will not work for you. If you have any more problems, then make sure that you give me all the information.