How to configure beforeShowForm with lib.web.mvc to show non editable columns in add form - jqgrid

Some of my columns are not editable but I want all of the columns to display in the add form.
I was thinking that I can use the "beforeShowForm" event and call a javascript function that will dynamically change the column attribute back to editable so they will show up in the add form.

The typical approach for this is to make fields generally editable and hide them in edit dialog.
You can hide/show fields by looking for table rows which ids are being built like this:
tr_ColumnName
So in case you would have UserName column the id would be like this:
tr_UserName
Assuming you are using jQuery, you can wire-up this to your Lib.Web.Mvc configuration like this:
.Navigator(new Lib.Web.Mvc.JQuery.JqGrid.JqGridNavigatorOptions() { ... },
editActionOptions: new Lib.Web.Mvc.JQuery.JqGrid.JqGridNavigatorEditActionOptions()
{
...
BeforeShowForm : "function(form) { $('#tr_UserName', form).hide(); }"
},
addActionOptions: new Lib.Web.Mvc.JQuery.JqGrid.JqGridNavigatorEditActionOptions()
{
...
BeforeShowForm : "function(form) { $('#tr_UserName', form).show(); }"
}
);

I figured how to use the event beforeShowForm.
Note: I have a using statement at the top of the view, so do not need to use the full namespace
#using Lib.Web.Mvc.JQuery.JqGrid
Here is an example within the Navigator form:
.Navigator(new JqGrid.JqGridNavigatorOptions()
{ Add = true, Edit = false, Delete = false, Search = false },
null,
addActionOptions: new JqGridNavigatorEditActionOptions()
{
Url = Url.Action("Add"),
BeforeShowForm = "function () {$('#bob').jqGrid('setColProp',
'Place', {editable:true})
})

Related

Kendo grid enable editing during insert, disable during edit(applicable to only one column)

I have a scenario where I have a Kendo dropdown, Kendo Datepicker as couple of columns in the grid.
On Add new record, the dropdown should be editable, on Edit mode, this drop down should be non Editable.
I have declared Grid to be Editable in declaration using
.Editable()
model.Field(p => p.CountryName).Editable(true); // where CountryName is kendo dropdown
I am trying to do on Edit this way,
function OnEdit(e) {
if (e.model.isNew() == false) {
e.model.fields["CountryName"].editable = false
}
THe behaviour I observe is Initially on load, Editable is set to true (due to cshtml declaration). When I click on Edit too, the drop down is Editable because of the page load flag that is set.
Even though OnEditmethod is executed and editable is set to false, the grid seems to have loaded before this code execution, hence editable =false is not reflected.
If I click on Edit second time, now the editable is set to false due to the previous call, Hence the dropdown is non editable as expected.
In Summary, the flag setting is not effective for the current action, but for the immediate next action. I am not sure if I have made it clear. Can you guys help?
Update - The other option I tried, during databind to the grid, I tried explicitly settign editable to false to all the grid data. My assumption here was only the loaded rows will have this field set to false. But in this case even the add new record takes Editable false.
var grid2 = $("#Gridprepayment").data("kendoGrid").dataSource.data(requiredData);
$.each(requiredData, function (i, row) {
var model = $("#Gridprepayment").data("kendoGrid").dataSource.at(i);
if (model) {
model.fields["CountryName"].editable = false;
}
});
The best way is to make the column editable .
e.g.
model.Field(d => d.CountryName).Editable(true);
and Onedit function, replace the inner html like mentioned below, for just to display it as label.
function OnEdit(e) {
e.container[0].childNodes['0'].innerHTML = e.model.CountryName;
}
Try disabling the kendo dropdown in the following manner:
function OnEdit(e) {
if (e.model.isNew() == false) {
$("#CountryName").data("kendoDropDownList").enable(false);
}
}
You can try this if you want to show the dropdownList as label in edit mode
function OnEdit(e) {
if(e.container.find("input").attr("id") === 'CountryName') {
this.closeCell();
}
}
Note: The above code was written considering "CountryName" as the id of the dropdown. Please change if the id is different.
I tried this which worked.
It's only a work around :
function OnEdit(e) {
if (e.model.isNew() == false) {
if (e.container.find("input").attr("id") === 'CountryName') {
e.container.find("td:eq(0)").html($("#CountryName").val());
}
}
}

Kendo grid with MVVM, binding column visibility

I have a kendo grid using MVVM.
My problem is I can't seem to set column visibility using the hidden attribute and an expression:
data-columns=
"[{'template':'# if (User!=null) { # #=User.Name# # } #',
'title':'User', 'hidden': User==null}
The template works, but the 'hidden' attribute doesn't seem to.
Is there any way to get this to work?
As an alternative, you could bind to the dataBinding or dataBound event to hide the column conditionally:
data-bind="events:{ dataBinding: onDataBinding }"
View model:
var viewModel = kendo.observable({
User: null,
showHideUserColumn: function (e) {
var grid = e.sender;
if (this.User) {
grid.showColumn("User");
} else {
grid.hideColumn("User");
}
},
onDataBinding: function (e) {
this.showHideUserColumn(e);
// if you want to track changes, (re)bind change tracking
this.unbind("change", this.showHideUserColumn);
this.bind("change", this.showHideUserColumn);
}
});
Only the properties specified via the data-bind attribute participate in MVVM change tracking. The other data attributes are mapped to widget configuration properties and are not evaluated against the view model.
Currently there is no binding which will allow you to hide and show grid columns.

Pop Up Edit Form for a grid: how can I know which is the currently selected row

I have a Grid which has edit set to Popup.
In my grid model, I have defined a field level validation for uniqueness like below. How can I know which is the currently select row so I can avoid comparing my field value with the same row's value?
model: {
id: "id",
fields: {
id: {
nullable: false,
editable: false,
hidden : true
},
"timeStamp": {
type: "date",
validation: { // validation rules
required: true, // the field is required
unique: function (input) {
if (!input.is("[name=timeStamp]")) {
return true;
}
input.attr("data-unique-msg", '${msg.UNIQUE_TIME}' );
var data = grid.dataSource.data();
//HOW CAN I KNOW WHICH ROW Is currently selected?
I am also working with custom validators on a Kendo Grid Popup Window. I used the following code to obtain the model:
var m = $(input).closest('.k-popup-edit-form').data('kendoEditable').options.model;
I prefer this mechanism because I don't have refer to the grid object, making the code more portable from page to page.
Maybe a little tricky solution but it should work... Each record in a DataSource has a Unique Id assigned by Kendo UI. These uid, for popup editing is used in the window in such a way that Kendo UI can easily identify the record being edited without having to save the state. You should do the same.
Your function just need to do:
var uid = $(input).closest(".k-popup-edit-form").data("uid");
var item = grid.dataSource.getByUid(uid);
Now, item contains all the fields of the record being edited.

Kendo UI grid - batch update not executed

I'm implementing a simple (at least ,that was the goal) Kendo UI grid that displays two columns: one holding a checkbox, bound to a boolean, and one holding a display name for the item. The checkbox column has a simple template, and the change() event of the checkbox is handled so that the model in the datasource gets updated. I have verified this, and it works.
The data source has been configured for batch, and defines a transport for read and update. Both call a function that perform the ajax call. As I said before, the read function is handled as expected. However, the update function defined on the transport is not. The sync() on the datasource is triggered with a simple button whose click event is hooked to a function that calls datasource.sync() (or grid.saveChanges()).
transport: {
read: function(options) {
return loadStuff(options);
},
update: function (options) {
return updateStuff(options);
}
}
When debugging in the Kendo UI code, it looks like the models attribute on the ModelSet is always empty, and therefore the sync() decides that there's nothing to sync. Anyone got a clue what is happening here?
UPDATE:
Looks like something may be wrong when handling the checkbox check / uncheck. Apparently I should use something like
$('#divGrid').on('click', '.chkbx', function() {
var checked = $(this).is(':checked');
var grid = $('#divGrid').data().kendoGrid;
var dataItem = grid.dataItem($(this).closest('tr'));
dataItem.set("Selected", checked);
});
Unfortunately, it looks like the set() method is not defined on the data item. When debugging, it only contains the data, and no Model object having the set() method.
UPDATE 2:
Tried wrapping the data returned from the ajax call in a model defined with Model.define(). That seems to solve the issue of the model not being dirty, as the _modified property on the model returns true. However, the models array in the ModelSet remains empty. Is this a bug in Kendo UI, or am I going the wrong way?
You don't actually need to bind to click event on the checkboxes.
I´ve posted an example on using it in JSFiddle where you can see it running. This example displays in a grid two columns: first text (tick) and second boolean rendered as a checkbox (selected); the update is batch (so, it's pretty close to what you have).
Questions to keep in mind are:
For displaying the checkbox while not in edit mode, you should define a template, something like this. You might realize that the checkbox is in disabled state by default since you want to edit it as other fields (selecting the cell first). This also guarantees that the model is correctly updated:
{
field : "selected",
title : "Selected",
template: "<input type='checkbox' name='selected' #= selected ? 'checked' : '' # disabled/>"
}
Define in the model that this field is boolean:
schema : {
id : "id",
model: {
fields: {
symbol : { type: "string" },
selected: { type: "boolean" }
}
}
},
Define the transport.update function, something like:
transport: {
read : function (operation) {
// Your function for reading
},
update: function (operation) {
// Display modified data in an alert
alert("update" + JSON.stringify(operation.data.models, null, 4));
// Invoke updating function
// that should ends with an operation.success(the_new_data)
// In this example just say ok
operation.success(operation.data.models)
}
}
EDIT: If you want to be able to modify the checkbox state without having to enter in edit mode first, you should:
Remove the disabled from the template:
{
field : "selected",
title : "Selected",
template : "<input type='checkbox' name='selected' #= selected ? 'checked' : '' #/>"
},
Then bind the click event on checkboxes to the following handler function:
$("#stocks_tbl").on("click", "input:checkbox", function(ev) {
var dataItem = grid.dataItem($(this).closest('tr'));
dataItem.set("selected", this.checked);
});
Where #stocks_tbl is the id of the div that contains the grid. You might see it running here.
NOTE: It's important the on with the three parameters for making it live

jqgrid change cell value and stay in edit mode

I'm using inline editing in my grid , I have some cases which i want to change the value of a cell inside a column. I'm changing it with setCell ,and it works good. my problem is that after the change the cell losts it's edit mode while all other cells of the row are in edit mode. I want to keep the cell in edit mode after i changed it.
for now what i did is saved the row and then selected it again and made in in edit mode - but i don't think it is a good solution - Is there a way to keep in edit mode while changin it?
Thank's In Advance.
If you need to implement the behavior of dependency cells which are all in the editing mode you have to modify the cell contain manually with respect of jQuery.html function for example. If the name of the column which you want to modify has the name "description", and you use 'blur' event on another "code" column then you can do about the following
editoptions: {
dataEvents: [
{
type: 'blur',
fn: function(e) {
var newCodeValue = $(e.target).val();
// get the information from any source about the
// description of based on the new code value
// and construct full new HTML contain of the "description"
// cell. It should include "<input>", "<select>" or
// some another input elements. Let us you save the result
// in the variable descriptionEditHtml then you can use
// populate descriptionEditHtml in the "description" edit cell
if ($(e.target).is('.FormElement')) {
// form editing
var form = $(e.target).closest('form.FormGrid');
$("#description.FormElement",form[0]).html(descriptionEditHtml);
} else {
// inline editing
var row = $(e.target).closest('tr.jqgrow');
var rowId = row.attr('id');
$("#"+rowId+"_description",row[0]).html(descriptionEditHtml);
}
}
}
]
}
The code will work for both inline and form editing.
The working example of dependent <select> elements you can find here.
blur does not fire if value is changed and enter is pressed immediately without moving to other cell. So better is to use
editrules = new
{
custom = true,
custom_func = function( val, col ) { ... }
},
and move this code from blur to custom_func as described in
jqgrid: how send and receive row data keeping edit mode

Resources