How to add a new row in a group in jqGrid? - javascript

I am totally new to jqGrid. I am populating the grid from an array with datatype:local.
var data=[
{date : "01/01/2012",starttime:"10:15",endtime:"11:15",workfunction:"MA"},
{date : "01/02/2012",starttime:"11:30",endtime:"12:30",workfunction:"CA"},
{date : "01/03/2012",starttime:"13:30",endtime:"14:30",workfunction:"FC"},
{date : "01/01/2012",starttime:"10:15",endtime:"11:15",workfunction:"MA"},
{date : "01/01/2012",starttime:"11:30",endtime:"12:30",workfunction:"CA"},
{date : "01/02/2012",starttime:"13:30",endtime:"14:30",workfunction:"FC"},
{date : "01/02/2012",starttime:"10:15",endtime:"11:15",workfunction:"MA"},
{date : "01/03/2012",starttime:"11:30",endtime:"12:30",workfunction:"CA"},
{date : "01/03/2012",starttime:"13:30",endtime:"14:30",workfunction:"FC"}
];
$("#gridTable").jqGrid({
data : data,
editurl:"clientArray",
datatype: "local",
height : 250,
colNames: [' ','Date','Start Time','End Time','Work Function'],
colModel : [
{name: 'myac', width:80, fixed:true, sortable:false, resize:false, formatter:'actions',formatoptions:{keys:true}},
{name: 'date',index:'date',width: 100,sorttype:'date',editable:true,editoptions : {
dataInit : function(element){
formatDatepicker(element,data);
}
}},
{name: 'starttime',index:'starttime',width: 100,sorttype:'date',editable:true},
{name: 'endtime',index:'endtime',width: 100,sorttype:'date',editable:true},
{name: 'workfunction',index:'workfunction',width: 100,sorttype:'date',editable:true,edittype:"select",editoptions:{value:"MA:MA;CA:CA;FC:FC"}},
],
pager: "#gridPager",
caption : "Weekly Details",
grouping : true,
groupingView : {
groupField:['date']
}
}).navGrid("#gridPager",{edit:true,add:true,del:false},
//edit properties
{
zIndex : 950,
}
);
Given above is the grid I am using. I am grouping the grid according to dates, and I am using jsp as the server side technology. My questions are:
Can we add a row to a group without submitting it to the server.
When a new row is created with a new date, will a new group form.
Can we edit multiple rows and submit all at once.

let me be sure if i understood you right...1. you want to add a row to grid but dont want to submit the data to server? it is possible...2. you have to be more clear on this requirement. 3. yes it is possible to take all the edit data of multiple rows and send the data to server.
I'll start with 3.
you can use multiselect: true here, its like the easiest option. Select the rows which you want to edit and Implement onSelectRow with a function which will make your rows editable on selecting them.
and then you can have a button which will take your edited rows data to server.
how to make rows editable on selecting them
onSelectRow: function(id){
jQuery('#grid').editRow(id, true); }
or there's another alternative keep your all rows in editable mode
gridComplete:OnGridComplete, //add this to your Jqgrid parameters
javascript function
function OnGridComplete(){
var $this = $(this), rows = this.rows, l = rows.length, i, row;
for (i = 0; i < l; i++) {
row = rows[i];
if ($.inArray('jqgrow', row.className.split(' ')) >= 0) {
$this.jqGrid('editRow', row.id, true);
}
}
}
and how to take edited data to server just on one click, see my answer
https://stackoverflow.com/a/11662959/1374763
and now with you first question
you should change the editUrl to clientarray,
jQuery("#grid_id").jqGrid('saveRow',"rowid", false, 'clientArray');
check this link and go to saveRow parametrs, for more info
http://www.trirand.com/jqgridwiki/doku.php?id=wiki:inline_editing

Related

Getting a specific array field length in php

I Want to get a specific field length from a Multidimensional Array but I don't know how and all I could find was sizeof(array) or count(array,count_recursive)
in javascript we can do this like :
var modalInfo = {
name : 'imagePreviewModal',
title : 'show picture',
wh : [500, 400],
tabs : [['imagePreviewTab', body]],
buttons : [],
cancelButton : false
};
window.alert(modalInfo.tabs.length);
body in : tabs : [['imagePreviewTab',body]], is and array.
what i need is the last line, i can get the length of modalInfo array field tabs.
how can I do the same in php?
This should work for you:
$count = count($modalInfo->tabs);

updated value in grid is not shown at java spring controller

I have a enhanced grid, i want to edit the grid contents and once clicked on Update link, i have to pass newly typed values to the java spring controller where i have logic to save updated values in database. But issue is after i type the value in enhanced grid i need to click somewhere in the grid or make focus on other field so that newly typed value is passed to the spring controller. If i type the new value and the cell is in edit mode and directly click on UPDATE link present in column4 of grid, the old value is passed to the spring controller. Please suggest what changes to be made so that once the mouse is out of the focus of the cell, the newly typed value should save in store and that value should be sent to spring controller when UPDATE link is clicked on column4 of grid.
Please find the fiddle : http://jsfiddle.net/740L0y43/7/
enhanced grid code:
require(['dojo/_base/lang', 'dojox/grid/EnhancedGrid', 'dojo/data/ItemFileWriteStore', 'dijit/form/Button', 'dojo/dom', 'dojo/aspect', 'dojo/domReady!'],
function (lang, EnhancedGrid, ItemFileWriteStore, Button, dom, aspect) {
/*set up data store*/
var data = {
identifier: "id",
items: [{
id : 1,
col2 : "aa",
col3 : "bb",
col4 : "cC"
}]
};
var store = new ItemFileWriteStore({
data: data
});
/*set up layout*/
var layout = [
[{
'name': 'Column 1',singleClickEdit:'true', editable:'true',
'field': 'id',
'width': '100px'
}, {
'name': 'Column 2',singleClickEdit:'true', editable:'true',
'field': 'col2',
'width': '100px'
}, {
'name': 'Column 3',singleClickEdit:'true', editable:'true',
'field': 'col3',
'width': '200px'
}, {
'name': 'Column 4',formatter: updateDetails,
'field': 'col4',
'width': '150px'
}]
];
/*create a new grid*/
var grid = new EnhancedGrid({
id: 'grid',
store: store,
structure: layout,
sortInfo: -1,
});
/*append the new grid to the div*/
grid.placeAt("gridDiv");
/*Call startup() to render the grid*/
grid.startup();
aspect.after(grid, 'renderRow', grid.sort);
var id = 2;
var button = new Button({
onClick: function () {
console.log(arguments);
store.newItem({
id: id,
col2: "col2-" + id,
col3: "col3-" + id,
col4: "col4-" + id
});
id++;
}
}, "addRow");
});
var updateDetails = function(value, rowIndex) {
var col2 = this.grid.getItem(rowIndex).col2;
alert("col2 updated value : " + col2);
return "<a href=\"<%=request.getContextPath()%>/updateInfo.htm?col2="+col2 +"\">" + "UPDATE";
};
spring controller code:
#RequestMapping(value = "/updateInfo", method = RequestMethod.GET)
public ModelAndView updateInfo(HttpServletRequest request,
HttpServletResponse response, #ModelAttribute MyDTO myDto,
#RequestParam("col2") String col2, #RequestParam("col2") String col2){
System.out.println("col2 value: " + col2);
System.out.println("col3 value: " + col3);
//when i type some value in COlumn2/Column3 of enhanced grid and column is still in edit mode then on click of UPDATE , new value is not passed to spring controller, its passing the old value.
...
...
//logic to save in DB
}
This line:
return "<a href=\"<%=request.getContextPath()%>/updateInfo.htm?col2="+col2 +"\">" + "UPDATE";
is returning an anchor with the href as "/contextPath/updateInfo.html?col2=aa". That renders it and that's it; that URL is never changing. Then, when you click on UPDATE, it sends what was in there when the page was rendered, not what the current value in your table is.
If you want to have the current value be sent, you should have your href be "#" and have an onclick="updateValue(1)" like this:
UPDATE
where 1 is the row number.
Then, in your update value function, you'd send an ajax request to update the value. Since you're using dojo, check this out: http://dojotoolkit.org/documentation/tutorials/1.8/ajax/
Here's what your function might look like (some pseudo code, some comments to describe behavior):
function updateValue(rowNum){
//var row = data.items.getRow(rowNum); or something like this
//Call ajax here and send the new row values
}
After messing with dojo for about an hour, and struggling with dojo's scoping and how to call a function that has access to the data grid and/or it's data store (sorry..I had 0 experience with dojo before this question)...here's your easy way out, OP:
http://jsfiddle.net/hm8gpz6o/
The important parts:
EnhancedGrid was NOT re-rendering the formatter generated cell when your data store was updated. This seems like a problem with dojo's EnhancedGrid.
I added the following (onApplyCellEdit will fire when a cell is updated):
/*create a new grid*/
var grid = new EnhancedGrid({
id: 'grid',
store: store,
structure: layout,
sortInfo: -1,
onApplyCellEdit: function(inValue, inRowIndex, inFieldIndex){
refreshGrid();
}
});
And finally, refreshGrid() will force a re-render of the whole grid. I hate that I have to do this:
function refreshGrid(){
grid.startup();
}
Please see the fiddle for the full working example.

changing data of select2 with x-editable without re-setting source option

How to keep the source of option values updated in x-editable
without re-initialising the editable element with source.
Here is the sandbox : http://jsfiddle.net/wQysh/322/
HTML
<p>X-editable (dev)</p>
<div>
<button id="controller">Add</button>
</div>
<div>
<button id="controller1">Remove</button>
</div>
<div>
<button id="controller2">Update</button>
</div>
<div style="margin: 50px">
</div>
<div style="margin: 50px">
</div>
<div style="margin: 50px">
</div>
<div style="margin: 50px">
</div>
JS :
$.fn.editable.defaults.mode = 'inline';
var count = 4, sources = [];
for(var i = 1; i <= count; i++){
sources.push({ id : i, text : String(i) })
}
var getSource = function() {
//i want this function must be called whenever available options is rendred. to ensure i used JSON.parse
return JSON.parse(JSON.stringify(sources));
};
$('#controller2').click(function(e){
count++;
sources[2].text = String(count);
//to verify live changes, if a new record updated in sources and used instantly
$('#username').editable('setValue', [1, count]); $('#username2').editable('setValue', count);
});
$('#controller').click(function(e){
count++;
sources.push( {id : count, text :String(count) });
//to verify live changes, what if a new record added in sources and used instantly
$('#username').editable('setValue', [1, count]); $('#username2').editable('setValue', count);
});
$('#controller1').click(function(e){
count++;
var a = sources.pop();
//to verify live changes by selecting value that is not present in the list. It should escape those, print the rest all if available in list
$('#username').editable('setValue', [1, a.id]); $('#username2').editable('setValue', a.id);
});
$('#username').editable({ //to keep track of selected values in multi select
type: 'select2',
url: '/post',
autotext : 'always',
value : [1,2],
source : getSource,
emptytext: 'None',
select2: {
multiple : true
}
});
$('#username2').editable({ //to keep track of selected values in single select
type: 'select2',
url: '/post',
autotext : 'always',
value : 2,
source : getSource,
emptytext: 'None',
select2: {
multiple : false
}
});
$('#username3').editable({ //to keep track of available values in multi select
type: 'select2',
url: '/post',
autotext : 'always',
value : null,
source : getSource,
emptytext: 'None',
select2: {
multiple : true
}
});
$('#username4').editable({ //to keep track of available values in single select
type: 'select2',
url: '/post',
autotext : 'always',
value : null,
source : getSource,
emptytext: 'None',
select2: {
multiple : false
}
});
//ajax emulation. Type "err" to see error message
$.mockjax({
url: '/post',
responseTime: 400,
response: function(settings) {
if(settings.data.value == 'err') {
this.status = 500;
this.responseText = 'Validation error!';
} else {
this.responseText = '';
}
}
});
Requirement :
Whenever i add new item in sources, if item is not selected then it should be updated in available options otherwise if selected then view should have updated value at element.
Whenever i update an item in sources, if item is not selected then it should be updated in available options otherwise if selected then view should have updated value at element.
Whenever i delete an item in sources, if item is not selected then it should be removed from the available options otherwise if selected then view should have "None" value (if single select) and rest element values (if multi select) at element.
Not allowed:
to reinit the widget
to reinit the source option
I hope this is possible. But struggling to get the result.
EDIT2 : code did not worked when i used JSON.parse over stringified 'sources' Problem is still unresolved. New fiddle : http://jsfiddle.net/wQysh/322/
(EDIT1 was misleading this question so removed EDIT1)
EDIT3 : so far i am able to achieve this http://jsfiddle.net/wQysh/324/
Here problem is that previous selected values are not rendered, so can't remove the items if selected previously in multi-select
EDIT4: not completely solved, http://jsfiddle.net/wQysh/339/. After add or update the available option does change but after setting that new record, does not reflect in html element after submit.
the answer is to use a custom display function
here is the updated fiddle. http://jsfiddle.net/wQysh/357/
Every time we 'setValue' to editable or on close event editable's 'display' function is called.
in display function existing values is checked by this function
$.fn.editableutils.itemsByValue
where the third parameter accepts the idKey. If we do not provide third parameter while calling this function, it by default takes 'value' as idKey. and 'value' as idKey should not be used when we are using to load array data. ref : http://ivaynberg.github.io/select2/#data_array.
I added display function in which third parameter is 'id'.
and i got the desired result

Showing serial number in jqgrid

I want to show serial number as first column in jqgrid.since, database records doesn't has contigous 'ids', I can't use it.
Is there any simple way to accomplish this?
Update:
sample code:
$(document).ready(function()
{
$("#list").jqGrid(
{
url:'<%=Url.class_variable_get(:##baseurl) %>/address_books/show.json',
datatype:'json',
mtype:'get',
colNames:['Id','Name','Email Id','Number'],
colModel:[
{name:'address_book_id',index:'address_book_id',sorttype:'int',sortable:true,width:100},
{name:'name',index:'name',sortable:true,width:300},
{name:'email',index:'email',sortable:true,width:265},
{name:'number',index:'number',sorttype:'int',sortable:true,width:300},
],
pager:$('#pager'),
emptyrecords: "No Records to display",
pginput:true,
pgbuttons:true,
rowNum:10,
rowList:[5,10,20,30],
viewrecords:true,
sortorder: "desc",
//multiselect:true,
loadonce:true,
gridview:false,
sortname:'name',
caption: " Contacts List",
jsonReader: {
repeatitems : false,
cell:"",
id: "0"
},
height: 80
});
$("#list").jqGrid('navGrid','#pager',{edit:false,add:false,del:false,search:true},{multipleSearch:true});
});
This question/answer should contain information on how to redraw the jqgrid based on redefined table data: jqGrid add new column
Regarding the addition of a you might add a time stamp to each of the records, or even the value of a counter; something like:
var recordsSet = [];
$.each(databaseRecords, function(i, record) {
record.idx = Date.now();
record._id = i;
recordSet.push(record);
});
/* code to populate or redraw using update recordSet array jqgrid here */
You shoud then be able to assign either the _id field or the idx field (sample property names only) to the index property of your column models in the call to jqgrid.

Saving dynamically generated jqgrid columns

I have a jqgrid with generated columns like this (in a ASP.NET MVC 3 project). They use inline editing :
#foreach (var template in Model.TemplateList.Where(m => m.Type == 2))
{
<text>
{ name: 'A'+'#template.ID', index: 'A'+'#template.ID', width: 40, align: 'left',
editable: true,
editoptions: { dataEvents: [{ type: 'keyup', fn: function (e) {
var $tr = $(e.target).closest("tr.jqgrow"), rowId = $tr.attr("id");
var nextRow = parseInt(rowId, 10) + 1;
var total = parseInt(e.target.value, 10);
if (isNaN(total)) {
total = 0;
}
ChangeValue('A'+'#template.ID', total, $tr);
}}]}},
</text>
}
The columns are generated and work well, until I try to save them. I'm trying to give the value to the controller, but it doesn't seem to work. I already tried to give the same name to all column to get them in an array :
... name: 'templateColumns', index: 'A'+'#template.ID', width: 40, align: 'left', ...
and in the controller :
public ActionResult SaveRow(string[] templateColumns)
but it didn't work (I only got the value of the last column)
I think you can not have same names for all the columns, check the link i gave u in comments. Now if you give one column name as ''A'+'#template.ID'' and lets suppose it is getting rendered like A1, A2 then in your controller you should accept something like this only.
public ActionResult SaveRow(string A1, string A2)
Your column name and parameters in controller should be same.

Categories

Resources