How do I prevent jqGrid from restoring the row after saving - jqgrid

I have a jqGrid in inline editing mode. When the user hits Enter, the record is sent to the server to save. The server returns a success:true or false which I handle in successFunc as follows:
function successFunc(data) {
d = jQuery.parseJSON(data.responseText);
if (!d.success) { alert(d.message); }
return d.success;
}
What I would like is that when d.success is false, the jqGrid should remain in edit mode and not restore. I tried adding a throw "exit" call after the alert. It works, but the Esc and Enter keys do not work any longer.
Is there any way to prevent jqGrid from restoring the row after save?
Thanks

The call to saveRow supports an afterrestorefunc callback:
afterrestorefunc if defined, this function is called in restoreRow (in case the row is not saved with success) method after restoring the row. To this function we pass the rowid
So you could let the grid call restoreRow and then in your callback you can call editRow to force the grid back in to edit mode. Not an ideal solution, but the transition will happen so fast the user probably will not notice.

Related

jqGrid custom recordtext and using loadComplete to get records count

I am trying to change the recordtext of a display grid to a custom format. I am using a treeview as the selector that refreshes the display grid. I need to find the total records for the grid and I am able to get this value using the getGridParam records method when I click on the treeview node and load the display grid.
However, after I get this value and try to create the custom recordtext, the record count is the previous value, not the current records count. I know that the gridComplete happens before the loadComplete, but even placing the get in the gridComplete and the set int he loadComplete, it still doesn't work, even with a reloadGrid trigger. If I click on the treeview node twice, I get the correct value.
I am thinking it is a timing issue as to when the new value is ready to set the recordtext. Any help would be great, thanks in advance.
I recommend you to try updatepager method, which updates the information on the pager. Alternatively you can do for example the following:
loadComplete: function () {
var p = $(this).jqGrid("getGridParam");
p.records = 123;
p.recordtext = "My View {0} - {1} of <i>{2}<i>";
this.updatepager();
}
to see the viewrecords

Call function when "on scroll" event is triggered

I have a grid that is locally initialized from an array data. after adding the rows to it I want to be able to get the event of the scrollbar when it reaches to the end and load more rows locally.
(the grid has certain height and 'overflow-y' : scroll)
How can this be done?
Thanks In Advance.
You can see the code for loading more data at line 1831 of grid.base.js:
case "local":
case "clientside":
beginReq();
ts.p.datatype = "local";
var req = addLocalData();
addJSONData(req,ts.grid.bDiv,rcnt,npage>1,adjust);
$(ts).triggerHandler("jqGridLoadComplete", [req]);
if(lc) { lc.call(ts,req); }
$(ts).triggerHandler("jqGridAfterLoadComplete", [req]);
if (pvis) { ts.grid.populateVisible(); }
endReq();
The good news is that the loadComplete event is called, so you can put your code there. The only complication is that loadComplete may also be called when the grid is initially constructed, so you have to take that into account as well.

jqgrid override select row

I'm using jqGrid's getGridParam('selarrrow') method. My question is what should be the best and simpler way to override this method so that it can ignore rows with a certain property (like having a disabled checkbox or something)
EDIT:
I should make myself a bit more clear.
My grid, has a subgrid and it is initialized with some already selected and 'disabled' rows. On the selectRow event of this subgrid I use
onSelectRow : function(rowId, status) {
listSelected[row_number] = $(this).getGridParam('selarrrow');
},
When I select a row from subgrid, the listSelected object for this row has both the newly selected and the one(s) already selected (and disabled) on init
Thanks
I am not sure that I understand you correctly, but I suppose you need implement beforeSelectRow callback which returns false to prevent selection of some rows.

Hide expand/collapse symbol or deactivate spec. rows in jqGrid subgrid

I have a grid with a subgrid: Only the first row of the Main grid need to have a subgrid.
The solutions I found by Google and http://www.trirand.com/....i:subgrid&s[]=hidecol
doesn't work.
Is there a quick and dirty (hard coded) solution?
Hiding the 'subgrid' column with jQuery("#grid_id").hideCol('subgrid'); remove full column which can be used to expand or collapse the subgrid, so you can not use the way in your case.
I suggest you to clear contain of the 'subgrid' column and unbind the 'click' event for the cells inside of loadComplete event handle:
loadComplete: function() {
$("td.sgcollapsed:not(:first)","#list").unbind('click').html('');
}
you will have the following results:
(You can see the corresponding example live here). It's important to understand, that the loadComplete event will be called on any page, so on the second page you will have subrgid also only on the first row.
If you need to implement more complex logic in choosing of the rows which need have subgrids you can use following code
loadComplete: function() {
var grid = $("#list");
var subGridCells = $("td.sgcollapsed",grid[0]);
$.each(subGridCells,function(i,value){
if (i!==0) {
$(value).unbind('click').html('');
}
});
}
The code above do the same as the statement $("td.sgcollapsed:not(:first)","#list").unbind('click').html(''), but you can easy modify the last version of the code to implement more complex behavior.
UPDATED: If you need detractive subgrid only for some row identified by the rowid you can use
$("#"+rowid+" td.sgcollapsed",grid[0]).unbind('click').html('');
(see live here) inside of the loadComplete. If you need deactivate subgrid for all rows which id is not equal to rowid you can make something like following
$('td.sgcollapsed:not("#'+rowid+' td.sgcollapsed")',grid[0]).unbind('click').html('');
(see live here)
UPDATED: free jqGrid now have new feature described in the answer: hasSubgrid callback which can be specified in subGridOptions. It allows to inform jqGrid which rows should don't have subgrids.

Is there a way to break out of event recursion in jQuery without using a global variable?

I have a form with 2 text inputs and 2 span controls. Normally, when textbox A is changed an event is fired to change span A, and when textbox B is changed, an event is fired to change span B.
However, in one particualar case I would like a change either textbox A or textbox B to update both span A and B. I tried wiring the events up to the corresponding controls in this case, but it didn't work because there is much state that is set up in the event building code (not to mention each event calls 'this', which would make the logic use the wrong control if it were fired from a different one than it was intended).
To make things easy, it would be best to pass a string (representing the other text input id) to the event handler at the time it is created, and then calling the change() event manually on the second control. However, this puts things in an infinite loop of recursion. I thought of a way to get around the recursion, but it reqires a global variable.
Is there a better way than this, preferably one that doesn't require a global variable?
ml_inEvent = false;
$ctlToVal.bind('keyup change', {feedbackCtl: ml_feedback, controlsToMonitor: ary, validationGroup: this.validationGroup, controlToFire: ctlToFire}, function(event) {
// Other processing happens here...
if (event.data.controlToFire != '') {
var $controlToFire = $('#' + event.data.controlToFire);
if ($controlToFire.length) {
// Use a global variable to ensure this event is not fired again
// as a result of calling the other one
if (!ml_inEvent) {
ml_inEvent = true;
$controlToFire.change();
ml_inEvent = false;
}
}
}
});
You can use the extraParameters argument on .trigger() to break out, for example:
$ctlToVal.bind('keyup change', {feedbackCtl: ml_feedback, controlsToMonitor: ary, validationGroup: this.validationGroup, controlToFire: ctlToFire}, function(event, fire) {
// Other processing happens here...
if(fire !== false) $('#' + event.data.controlToFire).trigger('change', false);
});
You can give it a try here. What this does is the event handler callback not only receives the event object but also any other arguments you pass in, in this case we're just using a simple false and a !=== check this in important so undefined (the parameter not passed at all) still changes both controls. So for instance $("#control").change() would change both controls, but still not loop...you can test that here.

Resources