JqGrid setCell properties lost when sorting column - jqgrid

Just after editing a row (mode inline) I try to change some css properties of cells according the new value.
Typically : After editing of one row all cell of this row that contains the letter "D" I update the cell with a new css property : background-color: grey (using setCell method)
For that I use inline editing :
grid.jqGrid('navGrid',"#pager",{edit:false, add:false, del:false});
grid.jqGrid('inlineNav',"#pager",{edit:true, add:false, del:false, editParams: myEditParam});
For change the background after editing I use the method aftersavefunc
myEditParam :
...
aftersavefunc: function(rowId, dataFromServer)
{
var rowData = $("#list").jqGrid("getRowData", rowId);
for (var key in rowData)
{
if (rowData[key] == "D")
{
key++;
$("#list").jqGrid("setCell",rowId, key, "", {"background-color": "#ECECEC"} );
}
}
},
...
This code works but unfortunatly, when I sort one column of the grid the setCell method is not perserved ! (the cell lost it's background-color: grey)
Does it exist a better method for change the background after editing in function of the new value ?
Thx for your help ;)

I would suggest removing the Style from that event and rather move it to the more general function below. If the style isn't applied you can always trigger a refresh on the jqGrid as part of your after edit code.
The following function will examine each column cell value and if the TestValue is matching add the class to the row.
rowattr: function (rd) {
if (rd.ColumnName == TestValue) { return {"class": "RowBoldClass"}; }//if
},
and the matching class
RowBoldClass { font-weight:bold; .....
My answer from Making a row bold, changing background color - dwr

If you really need to change the format/color/style of the cell in the column which can the value "D" then you should use cellattr (see the answer or this one).
If you need to change the format/color/style of the row then you should use rowattr (see the answer).
One thing is important to understand: neither cellattr nor rowattr will be called at the end of row editing. So you will still have to use aftersavefunc callback.
The current code of aftersavefunc seems me a little strange. First of all I never had requirements to mark the value in any column of the grid based on the value ("D" in your case). Typically one need to test only specific column or columns for the value and then mark the cell or mark some other cell in the row.
In any way one need typically not just add the class in the value will be "D", but remove the class if the value is not "D".
I modified the demo from the answer to support inline editing (one should use double-click to start editing and press Enter to stop editing). The modified demo uses the following code of aftersavefunc additionally to cellattr used in the old demo:
aftersavefunc: function (rowId) {
var closed = $(this).jqGrid("getCell", rowId, "closed"), indexOfColumn;
if (closed === "Yes") {
// add CSS classes to the cell used to mark
$(this).jqGrid("setCell", rowId, "name", "",
"ui-state-error ui-state-error-text");
} else {
// remove CSS classes from the cell used to mark
indexOfColumn = getColumnIndexByName.call(this, "name");
$(this.rows.namedItem(rowId).cells[indexOfColumn])
.removeClass("ui-state-error ui-state-error-text");
}
}

Related

How can I complete an edit with the right arrow key in a Kendo grid cell?

When a Kendo grid cell is open for editing, what is the best way to close the cell (and move to the next cell) with the right arrow key?
Take a look on the following snippet. It is a simple way for doing what you want:
// Bind any keyup interaction on the grid
$("#grid").on("keyup", "input", function(e)
{
// Right arrow keyCode
if (e.keyCode == 39)
{
// Ends current field edition.
// Kendo docs says that editCell method:
// "Switches the specified table cell in edit mode"
// but that doesn't happens and the current cell keeps on edit mode.
var td = $(e.target)
.trigger("blur");
// Find next field
td = td.closest("td").next();
// If no cell was found, look for the next row
if (td.length == 0)
{
td = $(e.target).closest("tr").next().find("td:first");
}
// As ways happens on kendo, a little (ugly)workaround
// for calling editCell, because calling without
// the timer doesn't seem to work.
window.setTimeout(function()
{
grid.editCell(td);
}, 1);
}
});
I don't know why but I could not save a Fiddle for that, I got 500 Internal error. Anyway it seems to achieve what you need. The grid needs to be in edit mode incell.

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());
}
}
}

YUI datatable conditional dropdown editor

I'm currently editing an application which uses YUI 2.5. I haven't used it before and could use some help.
I want to be able to add a dropdown editor for a particular column's rows using datatable, but I only want it to appear if specific values appear in another column in the corresponding row.
Is it possible to add some kind of If statement in the column definitions? Would I have to use a custom formatter?
eg.
var eventColumnDefs = [
{key:"event_id", sortable:false},
{key:"event_name", sortable:true},
{key:"extended", sortable:true, formatter: function (o) {
if (event_name=type1||event_name=type4||event_name=type5) {
editor:"dropdown", editorOptions:{dropdownOptions:eventData.extendedList}
}
}
}];
I know this code wouldn't work, by the way, I would just appreciate a bit of guidance.
You are close. In the column definition you add the information about the dropdown editor as if you always wanted it to show up. Now, going to the code sample here: http://developer.yahoo.com/yui/datatable/#cellediting
See the last line that attaches onEventShowCellEditor to whatever event you want to make the editor pop up? That is where you put the conditional. Instead of just asking to show the cell editor under any circumstance, you put some code there, like:
myDataTable.subscribe("cellClickEvent", function (ev) {
if ( ** whatever ** ) {
this.myDataTable.onEventShowCellEditor.apply(this, arguments);
}
});
I haven't been doing YUI2 for quite some time now so I don't remember the details on the arguments received by the event listener. I believe that you might also use showCellEditor() instead of onEventShowCellEditor, the later only massages the arguments as received from the event listener and ends up calling showCellEditor so you might as well skip it.
Found a hacky solution as follows
In Column Definitions:
var eventColumnDefs = [
{key:"player_name", sortable:true, editor:"dropdown", editorOptions:{dropdownOptions:currenteam}}
];
Then later on in initialiseTables:
eventDataTable.subscribe("cellClickEvent", function(ev) {
var target, column, field;
target = ev.target;
column = this.getColumn(target);
if (column.key === "player_name") {
field= this.getRecord(target).getData("team_id");
}
if (hometeamlistID == field) {
currenteam=hometeamlist;
} else if (awayteamlistID == field) {
currenteam=awayteamlist;
}
eventDataTable._oColumnSet._aDefinitions[8].editorOptions.dropdownOptions = currenteam;
});
hometeamlist, awayteamlist, hometeamlistID and awayteamlistID are pulled from an XML string. I haven't included that code above, but some of it is included in my question here:
YUI 2.5. Populating a dropdown from XML

jqGrid Custom Formatter Set Cell wont work with options.rowId

Ive been through all the posts, finally got setCell to work with hardcoded values, but not using the options.rowId.
function StatusFormatter(cellvalue, options, rowObject) {
if (cellvalue == 'C'){
jQuery("#list").setCell(options.rowId , 'SOORDLINE', '', { color: 'red' });
jQuery("#list").setCell("[2.000]", 'SOORDLINE', '', { color: 'red' });
jQuery("#list").setCell('[2.000]', 'SOREQDATE', '', { color: 'red' });
jQuery("#list").setCell(options.rowId, 'SOPRICE', '', { color: 'red' });
}
return cellvalue;
};
The FIRST and LAST lines dont work, but the 2 with the hardcoded rowId DO work. I inspected what comes back in the option.rowId and they are the same as the hardcoded values, (just different depending on the row of course. What am I missing? Please help. I dont see any difference between the lines, or values.
EDITED-
I tried the answer, and it seems to be what I need. I tried the following
{ name: 'SOORDLINE', index: 'SOORDLINE', width: 25, search: false ,celattr: function () { return ' style="color: red"'; }
},
To aleast make them all red before I dove into the logic, and it didnt do anything for me.
Sorry, but you use custom formatter in absolute wrong way. The goal of the custom formatter to to provide HTML fragment to fill the content of the cells in the corresponding column. So the StatusFormatter will be called before the row with the id equal to options.rowId will be created. Moreover for performance purpose one use typically gridview: true. in the case the whole content of the grid (the whole body of the grid) will be constructed first as string and only after that will be placed in the grid body in one operation. It improve the performance because after placing of any element web browser have to recalculate position of all other elements on the page.
If you want to set text color on the SOORDLINE cell you should cellattr instead:
celattr: function () { return ' style="color: red"'; }
The celattr can be used also in the form celattr: function (rowId, cellValue, rawObject) {...} and you can test the property of rawObject which represent of the values for any column and return the cell style based on the cell value.
Alternatively you can enumerate the rows inside of loadComplete and set the style on <tr> element instead of setting the same styles for every row. See the answer as an example.

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