HI,
I am using afterSaveCell that fires if we modifies the cell then it get fires.
My scenario is that i m doing batch update to the database on save change button. But when user edit the cell and got to the other cell then i log the modification in a array.
But if user edit the cell and click on the Save Change button the cell focus not get lost (Still in edit mode) and afterSaveCell not get fired.
IS there any way to fire the Save the cell on buttojn click so that afterSaveCell get fires.
Please, Help..
Thanks..
You can call saveCell method. This method has iRow and iCol as a parameters. To know the this parameters for the current editable cell you can add afterEditCell to the grid. So you save last values of iRow and iCol in a variable outside of jqGrid and use there inside of on click event on "Save Change" button where you call saveCell with these parameters.
// This worked Perfectly fine for me, hope will work for you as well.
var selectedCellId;
var $gridTableObj = $('#jqGridTable');
$gridTableObj.jqGrid({
datatype : "jsonstring",
datastr : gridJSON,
height : ($(window).height() - 110),
width : ($(window).width() - 80),
gridview : true,
loadonce : false,
colNames : columnNames,
colModel : columnModel,
rowNum : gridJSON.length,
viewrecords : true,
subGrid : false,
autoheight : true,
autowidth : false,
shrinkToFit : true,
cellsubmit : 'clientArray',
cellEdit : true,
jsonReader : {
root : "rows",
repeatitems : false
},
onCellSelect : function(id, cellidx, cellvalue) { // use this event to capture edited cellID
selectedCellId = cellidx; // save the cellId to a variable
},
loadComplete : function(data) {
jQuery("tr.jqgrow:odd").addClass("oddRow");
jQuery("tr.jqgrow:even").addClass("evenRow");
}
});
// Attach on click event jqgrid "saveCell" to save the cell.
var gridCellWasClicked = false;
window.parent.document.body.onclick = saveEditedCell; // attach to parent window if any
document.body.onclick = saveEditedCell; // attach to current document.
function saveEditedCell(evt) {
var target = $(evt.target);
var isCellClicked = $gridTableObj.find(target).length; // check if click is inside jqgrid
if(gridCellWasClicked && !isCellClicked) // check if a valid click
{
var rowid = $gridTableObj.jqGrid('getGridParam', 'selrow');
$gridTableObj.jqGrid("saveCell", rowid, selectedCellId);
gridCellWasClicked = false;
}
if(isCellClicked){
gridCellWasClicked = true; // flat to check if there is a cell been edited.
}
};
Related
I use jQuery DataTable and there is a checkbox on the toolbar that is used for retrieving all records or not. As stateSave feature of DataTable does not work properly, I tried to use jquery.cookie in order to keep the checkbox value after reloading the DataTable (because the checkbox is redrawn dynamically on every reload) as shown below:
$(document).ready(function() {
$('#example').DataTable( {
//code omitted for brevity
"serverSide": true,
"ajaxSource": "/Student/GetStudents",
"fnServerData": function (sSource, aoData, fnCallback) {
/* Add some extra data to the sender */
aoData.push({ "name": "isAll", "value": $("#cbIsAll").is(":checked") });
$.getJSON(sSource, aoData, function (json) {
/* Do whatever additional processing you want on the callback, then tell DataTables */
fnCallback(json);
});
},
"fnDrawCallback": function() {
$("div.toolbar").html('<input type="checkbox" id="cbIsAll" name="demo" /> Get all records');
}
});
$(document).on('change', '#cbIsAll', function () {
var isClicked = $('#cbIsAll').is(':checked') ? true : false;
$.cookie('clicked', isClicked, { expires: 1 }); // expires in 1 day
table.ajax.reload();
$('#cbIsAll')[0].checked = ($.cookie('clicked') == "true") ? true : false;
});
});
After debugging the code I saw that although the $('#cbIsAll')[0].checked line is executed properly as true, the checkbox lost value later than this line. Could you please clarify me about where the mistake is? Or is there a better and smart way to keep the checkbox value?
There is no reason to use $.cookie in your case. In the checkbox change event, you can simply store the value of the checked state and use that to set the checked property of the new checkbox generated when you reload the table
var isChecked;
$(document).on('change', '#cbIsAll', function () {
// Store the current value
isChecked = $(this).is(':checked');
....
Then in the datatable's callback function, set the checked state of the checkbox
$('#cbIsAll').prop('checked', isChecked);
Jquery Click event is firing for first time but on second time it is not triggering.
Datatable:
var tableAttendance = $('#tableAttendance').dataTable ({
"bDestroy" : true,
"bAutoWidth" : false,
"bServerSide" : true,
"bDeferRender" : true,
"sServerMethod" : "POST",
"sAjaxSource" : pageUrl (),
"sAjaxDataProp" : "aaData",
"aaSorting" : [[2, 'desc']],
"fnCreatedRow": function( nRow, aData, iDataIndex ) {
$(nRow).attr({
"data-toggle":"context",
"data-target":"#attendance-context-menu"
});
},
"aoColumns" : [
{
"mData" : function (row, type, set) {
return '<div>'+ row['Employee_Name'] +'</div>';
}
}]
});
Jquery Event :
$(document).on('click contextmenu', '#tableAttendance tbody tr', function (e) {
console.log("Event Triggered");
var selectRow = $(this);
if (!selectRow.hasClass('row_selected'))
{
selectRow.addClass('row_selected');
}
else
{
//Other than right click. Because i use multi-select option
if( e.button !== 2 )
selectRow.removeClass('row_selected');
}
});
Working for different row select event. But when i right click(context menu) same row more than once, the event is not triggring
Just tested and your code works for me.
Could you please try to modify your click handler as follows:
$(document).on('click contextmenu', '#dummy tbody tr', function () {
var d = new Date();
console.log("Event Triggered" + d.getMilliseconds());
});
If you are debugging with firebug it could well be that you overlooked the number in front of your logged text.
Messages with the exact same content logged multiple times result in the number being incremented.
Adding milliseconds to the output will slightly modify the message and result in a new line of output.
EDIT:
A right click will result in the value e.button = 2.
This value is checked in your handler if( e.button !== 2 ) and does not execute selectRow.removeClass('row_selected'); because the result of the check is false.
Completely removing the check for e.button would get your right-click to select and deselect the rows.
how to set isDirty() value dynamically in Ext Js
I have form panel which contains textbox, radio buttons and save button. In afterrender function i am setting a value to textbox . after loading the page the isDirty() is returning true, but my requirement is when I click on update button only it should return true.
how I can achieve this.
I tried with trackResetOnLoad= true but its not working.
Fiddle example is
https://fiddle.sencha.com/#fiddle/1d74
Update:-
I need track Change or update after Afterrender function.
You can achieve the same functionality by giving value config to textfield rather than setting anything in afterrender. When you run the below code , you will not get true in isDirty button when you first click it.
Ext.onReady(function() {
var form = new Ext.form.Panel({
itemId:'panelFormID',
trackResetOnLoad: true,
renderTo: Ext.getBody(),
items: [{
xtype: 'textfield'
,name: 'username'
,itemId : 'username'
,fieldLabel: 'username'
, value:'stackoverflow'
},{
xtype: 'textfield'
,name: 'password'
,itemId : 'password'
,fieldLabel: 'password'
}, {
xtype: 'button',
text : 'isDirty' ,handler: function() {
alert(Ext.ComponentQuery.query('#panelFormID')[0].isDirty());
}},
{
xtype: 'button',
text : 'Update' ,
handler: function() {
Ext.ComponentQuery.query('#username')[0].setValue ('resetvalue');
Ext.ComponentQuery.query('#password')[0].setValue ('restpassword');
}
}]
}
})
;
});
You can use form component's setValues method for this purpose. This couldn't change your dirty status while your form's trackResetOnLoad property is true.
In your case you can do it like that;
Ext.ComponentQuery.query('#panelFormID')[0].up('form').getForm().setValues({
username : 'reset value',
password : 'resetpassword'
});
These object properties related with your component's name property. When you miss some field's value it gonna set as empty. so you have to get all of it's value and change your wishes and set again.
Use the below code in your afterrender listener:
var items = Ext.ComponentQuery.query('#panelFormID') [0].getForm().getFields().items,
i = 0,
len = items.length;
for(; i < len; i++) {
var c = items[i];
if(c.mixins && c.mixins.field && typeof c.mixins.field['initValue'] == 'function') {
c.mixins.field.initValue.apply(c);
c.wasDirty = false;
}
}
isDirty() depends upon originalValue of respective component.In afterrender as you set value to field, you also need to set originalValue field.I have added this line in afterrender code:
afterrender :function () {
Ext.ComponentQuery.query('#username')[0].setValue ('stackoverflow');
//new line
Ext.ComponentQuery.query('#username')[0].originalValue='stackoverflow'
Ext.ComponentQuery.query('#panelFormID')[0].trackResetOnLoad = true;
}
Please try using this after setting values (in afterrender function):
Ext.ComponentQuery.query('#panelFormID')[0].form.setValues(Ext.ComponentQuery.query('#panelFormID')[0].form.getValues())
Here's my DataGrid:
// $ is a reference to `this` as it lies in an anonymous function
$.grid = new DataGrid({
store : $.dataStore,
query : {id : "*"},
structure : [
{
noscroll : true,
cells : [{ name : "Recipe", field : 'name', width : '200px' }],
},
{
cells : [
[
{ name : 'ID#', field : 'id', width : '50px'},
{ name : 'Category', field : 'category', width : '100px'},
{ name : 'Status', field : 'status', width : '100px'},
{ name: "Actions", width : '200px', type: dojox.grid.cells._Widget, formatter : $._actionButtons}
]
] // end cells
}
]
}, $.targetNode)
$.grid.startup();
$.grid.on("RowClick", function(e){
console.log(this.getItem(e.rowIndex))
})
And my formatter object for the Actions cell:
_actionButtons : function(){
var _self = this;
var _args = arguments;
this.group = new Pane()
var full = new Button({
label: 'View Full',
style : { fontSize : '80%'},
onClick : function(){
try {
_self.grid.onRowClick.apply(this, arguments)
}catch(e){}
}
});
full._destroyOnRemove = true;
var edit = new Button({
label : 'Edit',
style : {fontSize: '80%'}
});
edit._destroyOnRemove = true;
construct.place(full.domNode, this.group.containerNode)
construct.place(edit.domNode, this.group.containerNode)
return this.group;
}
I'm trying to get access to the event object that would be passed by a normal onRowClick event on the DataGrid. As it sits now this kinda works, but on the on("RowClick"...) block I get multiple logs. Without the try...catch block I get an error as the rowIndex doesn't exist in e, then 2 more logs where it does exist.
This is the 4th or so idea I've had included pub/sub, emit(), etc. I have a feeling that the multiple logs are caused by the bubbling behavior (Button -> Row -> DataGrid or somesuch), but getting the onRowClick's event object to get passed into the Buttons created in the formatter seems impossible.
I just want to access the rowIndex (and other DataGrid-esque properties) from the Button widget's onClick event to process according to the button pressed.
Along the same lines, but here's what I came up with that seems to be working in a direction where what I'm envisioning will happen. Adjusted cell where the buttons will be:
{ name: "Actions", width : '200px', type: dojox.grid.cells._Widget, formatter :
function(){
return $._actionButtons.call($, arguments);
}
}
Adjusted onClick function in the returned Button widget:
_actionButtons : function(){
var _index = arguments[0][1],
_item = this.grid.getItem(_index)
_self = this;
// some code removed
onClick : function(){
console.log(_self.dataStore.getValue(_item, 'name'), "clicked")
}
}
I'll probably end up extending Button to handle this a bit better, but for now, voila!
Sometimes it just helps to write it down and put it out there for your brain to panic and figure out the solution before anyone else does :)
Minor update...
There is the formatterScope parameter for the DataGrid, but it applies to all formatter's and would therefore mess up anything requiring cell scope and not DataGrid scope. The above method allows me to access everything I need.
I have ExtJS GRID with checkcolumn, which is declared this way:
// the check column is created using a custom plugin
sel_column = new Ext.grid.CheckColumn({
sortable: false,
header: 'STE<br />SEL',
dataIndex: 'sel',
width: field_w,
listeners:
{
"mousedown":
{
fn : function(e)
{
$.log( "Sel cellclick" , e );
}
}
}
});
I want add some listener on changfe of it stae, or on mouse click.
Finaly - want id's of rows, where i click this column - to be stored in text field
For now i can understood how to catch click event, i use onMouseDown, this way:
// the check column is created using a custom plugin
sel_column = new Ext.grid.CheckColumn({
sortable: false,
header: 'STE<br />SEL',
dataIndex: 'sel',
width: field_w,
onMouseDown: function( e )
{
$.log( e,"MouseDown" );
}
});
But it fires, when i click ANY cell, not only checkboxed ...
Pls help me
checkbox plugin need modification, after which it can fire click event.
/*
**************************************************************
Sample to add event 'checkchange' in checkbox on checkcolumn,
works with ExtJS 4 or above
*/
//Add you checkcolumn id:'op_check'. No need separate plugin.
//Put this code in You Grid
listeners:{
afterrender:function(){
g = this; //This grid
Ext.getCmp('op_check').on('checkchange', function(c, i){
//Get id from row/record (if in store exist field 'id')
//"i" - in this function is index row, where clicked checkbox
rec = g.store.getAt(i);
id = rec.get('id');
console.log(id); //:)
});
}
}