Related
I am working with jqGrid 4.4.4V, I have two grids let say grid1 and grid2,
when i add multiple Rows to grid2 from grid1 the row id's are updating like 0,1,...But when i am adding single row each the id is starting from '0'.So, if i do multiple times like this, all rowIds will be like '0' only. Is there any way to make rowIds as always unique.
Note: the data is not adding manually to the grid, is getting from a sql. Below are the code for two grids.
grid1:
$("#grid1").jqGrid({
url: "/.......some handler path",
datatype: 'json',
contentType: "application/json; charset-utf-8",
mtype: 'Get',
colNames: ['Val ID', 'Val Name', 'Description', 'Dept', 'Vam', 'Venue', 'Venue', 'Solution', 'Method', 'Type'],
colModel: [
{ name: 'valId', index: 'valId', hidden: true },
{ name: 'valName', index: 'valName', formatter: Namefield, width: 400 },
{ name: 'description', index: 'description', width: 300 },
{ name: 'dep', index: 'dep', width: 300 },
{ name: 'vam', index: 'vam', width: 300 },
{ name: 'venueId', index: 'venueId', hidden: true },
{ name: 'venue', index: 'venue', width: 250 },
{ name: 'solution', index: 'solution', width: 400 },
{ name: 'Method', index: 'Method', width: 300 },
{ name: 'Type', index: 'Type', hidden: true },
],
pager: $('#pager'),
key:true,
rowNum: 10,
rowList: [10, 20, 30, 40],
height: '100%',
viewrecords: true,
caption: '',
sortname: 'Val Name',
sortorder: "desc",
emptyrecords: 'No records to display',
autowidth: true,
multiselect: true,
multiselectWidth: 50,
jsonReader: {
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
Id: "0"
}
});
grid2:
$("#grid2").jqGrid({
datatype: 'function',
mtype: 'Post',
colNames: ['Val ID', 'Val Name', 'Description', 'Dept', 'Vam', 'Venue ID', 'Venue', 'Solution', 'Method', 'Type'],
colModel: [
{ name: 'valId', index: 'valId', hidden: true },
{ name: 'valName', index: 'valName', formatter: Namefield, width: 400 },
{ name: 'description', index: 'description', width: 300 },
{ name: 'dep', index: 'dep', width: 300 },
{ name: 'vam', index: 'vam', width: 300 },
{ name: 'venueId', index: 'venueId', hidden: true },
{ name: 'venue', index: 'venue', width: 250 },
{ name: 'solution', index: 'solution', width: 400 },
{ name: 'Method', index: 'Method', width: 300 },
{ name: 'Type', index: 'Type', hidden: true },
{ name: 'delete', index: 'delete', width: 50, formatter: Close, align: 'center' }
],
pager: $('#pager'),
key:true,
rowNum: 10,
rowList: [10, 20, 30, 40],
height: '100%',
viewrecords: true,
caption: '',
sortname: 'Val Name',
sortorder: "desc",
emptyrecords: 'No records to display',
autowidth: true,
multiselect: true,
multiselectWidth: 50,
jsonReader: {
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
Id: "0"
}
});
Where I am using the add and del methods as below,
var selRowIdsArray = [];
var myGrid = $("#grid1");
var SelectedGrid = $('#grid2');
//get no of selected rows count
var selRowIds = $("#grid1").jqGrid('getGridParam', 'selarrrow');
if (selRowIds.length !== 0) {
if (selRowIdsArray.length == 0) {
selRowIdsArray.push.apply(selRowIdsArray, selRowIds);
}
for (i = 0; i < selRowIdsArray.length; i++) {
selRowIdsInt = selRowIdsArray[i];
var selRowId = myGrid.getRowData(selRowIdsInt);
SelectedGrid.jqGrid('addRowData', i, selRowId);
myGrid.jqGrid('delRowData', selRowIdsInt);
}
}
Thanks for your help.
The solution of you problem could be very easy if you good understand what is rowid and what do idPrefix option of jqGrid. It's the value of id attribute of <tr> elements of the corresponding HTML <table>, which displays the data. The internal implementation of jqGrid is so, that jqGrid must assign id to every row of the grid, which corresponds the data. It's strictly recommended to include an unique id property in every item. It could be native id from the database or some composite key like id1 + "_" + id2, which hold full information about the native ids from the backend. I recommend you to examine the picture from the article.
You can place the id under any other name as id. If you use repeatitems: false option of jsonReader, and valId is the name of the unique id, then you should use
jsonReader: { id: "valId" }
to inform jqGrid about that. Including of any other properties of jsonReader with default values, like you did, is unneeded. Any other properties of jsonReader, like Id (instead of id), will be just ignored. After that you can remove unneeded hidden column valId from the grid, which saves the same information in <td> elements of the grid.
I recommend to add one more option, if you use editing of the grid
prmNames: { id: "valId" }
The option renames the id property, send on editing of the grid, to valId. Thus you can just continue to use valId instead of id.
Next you should understand that rowid can be not the same as id (valId). If you have more as one grid on the page then it will be strictly recommended to use idPrefix. It's supported even on the retro version 4.4.4 of jqGrid (4 years old version), which you use. For example, you can use idPrefix: "g1_" in the first grid and idPrefix: "g2_" in the second grid. It prevents id dupplicates on HTML page, because the rowid will be build from id (valId) with the corresponding id prefix, different for both grids.
After understanding the meaning of rowid, it should be clear how one can move selected rows from one grid to another. The statement
var selRowIds = $("#grid1").jqGrid('getGridParam', 'selarrrow');
var idPrefix1 = $("#grid1").jqGrid('getGridParam', 'idPrefix');
gives you the rowids (with the idPrefix of the first grid) of selected rows and the prefix idPrefix1, which you use. You can use $.jgrid.stripPref to strip the prefix, getRowData to get the row data and to use addRowData to add the same data to the second grid, using the same id
var i, id, item;
for (i = 0; i < selRowIds.length; i++) {
id = $.jgrid.stripPref(idPrefix1, selRowIds[i]);
item = myGrid.jqGrid("getRowData", id);
SelectedGrid.jqGrid("addRowData", id, item);
}
addRowData will automatically use idPrefix of the second grid.
Finally, I'd recommend you to drop using of retro version 4.4.4 which is dead since many years. I'd suggest you to use the current version (4.13.6) of free jqGrid - it's the fork of jqGrid, which I develop starting with the end of 2014. If you installed 4.4.4 because of usage of wrong NuGet package jQuery.jqGrid, then you should uninstall the package and install another one: free-jqGrid.
I have implemented the autocomplete filter functionality in my jqGrid.
However this is not working, I believe there are 2 issues.
I have a column which uses a formatter. With this column included, the filtering will not trigger a load at all. Without this column, the filtering will trigger a load, however will not filter the results.
I have read that the index or jsonmap must be the same as the name in the colModel in order for filtering to work. I have ensured that these match, still with no luck.
Code:
loadData: function (someData) {
$(model.table).GridUnload();
$(model.table).jqGrid({
url: $(model.tableURL).val(),
datatype: 'JSON',
mtype: 'POST',
postData: {
someData: someData
},
emptyrecords: 'No Wholesalers',
viewrecords: true,
autowidth: true,
shirnkToFit: false,
rowNum: -1,
loadtext: 'Loading...',
multiselect: false,
width: "100%",
height: "100%",
colModel: [
{ label: 'Wholesaler', name: 'WholesalerName', jsonmap: 'WholesalerName', sortable: false, align: 'center', width: '250' },
{
label: 'Amount Complete', name: 'PercentageComplete', jsonmap:'PercentageComplete', search: false, sortable: false, align: 'center',
formatter: function (cellvalue, options, rowObj) {
return '<div class="progress progress-striped pos-rel" data-percent="' + rowObj.PercentageComplete + '%">' +
'<div class="progress-bar progress-bar-success" style="width:' + rowObj.PercentageComplete + '%;"></div></div>';
}
},
{ label: 'No of Customers', name: 'NoOfCustomers', jsonmap: 'NoOfCustomers', search: false, sortable: false, align: 'center' },
{ label: 'Last Updated', name: 'LastUpdated', jsonmap: 'LastUpdated', search: false, sortable: false, align: 'center' },
{ label: 'Last Update By', name: 'LastUpdateBy', jsonmap: 'LastUpdateBy', search: false, sortable: false, align: 'center' },
],
altrows: true,
loadComplete: function () {
var table = this;
//model.update()
},
loadError: function (xhr, st, err) {
alert(err);
}
}
).jqGrid('filterToolbar', {
stringResult: true, searchOnEnter: false, ignoreCase: true,
})
},
Turns out I didn't have loadonce: true set.
Therefore when filtering on keypress, the grid was being reloaded and re populated with data from the server.
I am trying to add button instead of View column but i tried with formatter still button is not loading but records are coming for the rest of the columns.
Below is my code:
$(function () {
$("#grid").jqGrid({
url: "/Location/LocationsList1",
datatype: 'json',
mtype: 'Get',
colNames: ['Id', 'Country Name', 'State Name', 'City Name', 'Location Name','View'],
colModel: [
{ key: true, hidden: true, name: 'Id', index: 'Id', editable: true },
{ key: false, name: 'CountryName', index: 'CountryName', editable: true },
{ key: false, name: 'StateName', index: 'StateName', editable: true },
{ key: false, name: 'CityName', index: 'CityName', editable: true },
{ key: false, name: 'Name', index: 'Name', editable: true },
{ key: false, name: 'View', index: 'View', editable: true,formatter:ViewButton }],
pager: jQuery('#pager'),
rowNum: 10,
rowList: [10, 20, 30, 40],
height: '100%',
viewrecords: true,
caption: 'Location',
emptyrecords: 'No records to display',
jsonReader: {
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
Id: "0"
},
});
});
function ViewButton(cellvalue, options, rowObject) {
var rowid= options.rowid;
var button = "<button class=\"viewLineItem\" id="+ rowid+">View Line Item</button>"
$('#' + rowid).die();
$('#' + rowid).live('click', function (rowId) {
alert("hi");
alert(rowId);
});
};
I am new to JqGrid and don't know how it works. Any guidance/Help will be appreciated.
The code has some problems
options has no rowid property, but it has rowId property. You should change options.rowid to options.rowId
The formatter will be called during building the HTML fragment of the grid body. No element of the grid exist at the moment on the page. Thus you can't use $('#' + rowid).live('click', ...); at the moment.
The formatter have to return the HTML fragment, which will be placed in the corresponding cell (inside of <td>). One misses return button; at the end of the formatter.
There are exist well-known name conversion in JavaScript. One should use functions, which starts with capital letter only if you define the constructor of the new class. You see that ViewButton will be displayed in the other color to distinguish classes from other function. You should rename ViewButton to viewButton to hold the standard name conversion of JavaScript.
It's better don't specify index property in colModel. In the same way one should not include the properties with the defaul value, like key: false. To specify common property for many columns you can use cmTemplate property.
One should reduce the number of global functions, because the functions will be considerd as the properties of window object.
instead of usage hidden column with name: 'Id' one can specify id: 'Id' property of jsonReader. You use repeatitems: false property, which means that every item of input data has properties CountryName, StateName and so on. The default name of the id property (the rowid - the id of <tr> elements) is id, but you use Id instead. The property id: "Id" informs jqGrid about it.
The modified code could be about the following
$(function () {
function viewButton(cellvalue, options, rowObject) {
return "<button class=\"viewLineItem\" id=\"" +
options.rowId + "\">View Line Item</button>";
}
$("#grid").jqGrid({
url: "/Location/LocationsList1",
datatype: 'json',
colNames: ['Id', 'Country Name', 'State Name', 'City Name', 'Location Name','View'],
colModel: [
{ name: 'Id', key: true, hidden: true },
{ name: 'CountryName' },
{ name: 'StateName' },
{ name: 'CityName' },
{ name: 'Name' },
{ name: 'View', editable: false, formatter: viewButton }
],
cmTemplate: { editable: true },
pager: '#pager',
rowNum: 10,
rowList: [10, 20, 30, 40],
height: '100%',
viewrecords: true,
caption: 'Location',
emptyrecords: 'No records to display',
jsonReader: { repeatitems: false, id: "Id" }
});
$("#jqGridA").click(function (e) {
var $td = $(e.target).closest("tr.jqgrow>td"),
rowid = $td.parent().attr("id"),
p = $(this).jqGrid("getGridParam");
if ($td.length > 0 && p.colModel[$td[0].cellIndex].name === "View") {
alert(rowid);
}
});
});
The last part of the above code ($("#jqGridA").click(...);) register one click handler for the whole grid. If the user clicks on any cell then the event handler will be called because of event bubbling. The e.target gives as the DOM element, which was clicked (for example the <button>). By using closest we can go to the outer <td> element, which parent is the row (<tr>) of the grid. The .attr("id") of the row is the rowid. Such binding works more effectively as binding click handler to every button inside of the grid.
By the way jqGrid has already one click event handler. One can use beforeSelectRow callback, because it will be called inside of the click handler. One should only don't forget to return true from the beforeSelectRow callback to inform jqGrid that you allow to select the row. The callback beforeSelectRow has already rowid as the first parameter, which simplify our code a little. The final code will be
$(function () {
function viewButton(cellvalue, options, rowObject) {
return "<button class=\"viewLineItem\" id=\"" +
options.rowId + "\">View Line Item</button>";
}
$("#grid").jqGrid({
url: "/Location/LocationsList1",
datatype: 'json',
colNames: ['Id', 'Country Name', 'State Name', 'City Name', 'Location Name','View'],
colModel: [
{ name: 'CountryName' },
{ name: 'StateName' },
{ name: 'CityName' },
{ name: 'Name' },
{ name: 'View', editable: false, formatter: viewButton }
],
cmTemplate: { editable: true },
pager: '#pager',
rowNum: 10,
rowList: [10, 20, 30, 40],
height: '100%',
viewrecords: true,
caption: 'Location',
emptyrecords: 'No records to display',
jsonReader: { repeatitems: false, id: "Id" },
beforeSelectRow: function (rowid, e) {
var $td = $(e.target).closest("tr.jqgrow>td"),
p = $(this).jqGrid("getGridParam");
if ($td.length > 0 && p.colModel[$td[0].cellIndex].name === "View") {
alert(rowid);
}
}
});
});
I am new to web development, I have run into this problem and have researched and tried many other methods to no avail. I need to populate a drop down list in a jqgrid only with values that are in my database. The url that I am using to do this gives me the correct response in JSON as follows (note that I only sent through selected fields):
{
"serviceBranchResult": [
{
"branch_services": [],
"queues": [],
"service_description": null,
"service_id": 2,
"service_name": "Forex",
"service_status": null
},
{
"branch_services": [],
"queues": [],
"service_description": null,
"service_id": 3,
"service_name": "Tellers",
"service_status": null
}
]
}
When I try to do a dropdownlist from the method below without reading the json from the url it works 100% however it isnt dynamic, I use the method getAllSelectOptions() and where I am using it in the grid looks like this:
function getAllSelectOptions() {
var services = {
'1':'Forex', '2':'Tellers', '3':'Consultants'};
return services;
}
My code for the grid:
url: "http://localhost:8080/service.svc/employees/3"
datatype: "json",
type: "GET",
contentType: "application/json; charset=utf-8",
height: '250',
colNames: ['ID', 'Name', 'Surname', 'Username', 'Email', 'Branch ID', 'User Type', 'Status', 'Speciality'],
colModel: [
{ name: 'employee_id', index: 'employee_id'},
{ name: 'employee_name', index: 'employee_name', editable: true },
{ name: 'employee_surname', index: 'employee_surname', editable: true },
{ name: 'employee_username', index: 'employee_username', editable: true },
{ name: 'employee_email', index: 'employee_email', editable: true },
{ name: 'branch_id', index: 'branch_id', editable: true },
{ name: 'user_type', index: 'user_type', editable: true },
{ name: 'employee_state', index: 'employee_state', editable: true },
{ name: 'employee_speciality', index: 'employee_speciality', editable: true,
sortable: true,
align: 'center',
editable: true,
cellEdit: true,
edittype: 'select',
formatter: 'select',
editoptions: { value: getAllSelectOptions() }
}],
rowNum: 20,
rowList: [10, 20, 30],
pager: '#pager_jqgrid',
And this works perfectly.
However I use this following method to potentially replace the getAllSelectOptions() method and it does return the information when I use alert boxes, but does not work.
function availAtBranch() {
$.ajax({
type: "GET",
url: "http://localhost:8080/service.svc/branch/3",
dataType: "json",
success: function (data) {
$.each(data.serviceBranchResult, function (i, obj) {
//alert(obj.service_id + ":" + obj.service_name);
var div_data = obj.service_name + ":" + obj.service_name;
//alert(div_data);
});
return div_data;
}
});
I think it has something to do with how in parsing the JSON to the editoptions method, or sending an object through. How do I get my JSON to be in the format as described in the getAllSelectOptions() method, or how do I display my data in the dropdownlist. Thank you in advance
I have an ASP.Net MVC site with a KOGrid in one of my views. This pulls data by making an Ajax call to a controller which then selects from SQL Server via EF. My data table can be seen below:
I have the following column definition for my KO Grid:
self.columnDefs = [
{ width: 50, field: 'workflowTask_WorkflowTaskId', displayName: 'Id' },
{ width: 150, field: 'Timestamp', displayName: 'Timestamp', cellFilter: function (data) { return moment(data).format('DD/MM/YYYY h:mm a') } },
{ width: 100, field: 'currentState', displayName: 'Crnt State' },
{ width: 500, field: 'note', displayName: 'Notes' },
{ width: 100, field: 'previousState', displayName: 'Prev State' },
{ width: 100, field: 'currentUser', displayName: 'Crnt User', sortable: false },
{ width: 100, field: 'amendedByUser', displayName: 'Amnd By', sortable: false },
{ width: 100, field: 'previousUser', displayName: 'Prev User', sortable: false }
];
I have the following grid options:
self.gridOptions = {
data: self.recs,
columnDefs: self.columnDefs,
autogenerateColumns: false,
showGroupPanel: true,
canSelectRows: false,
showFilter: true,
filterOptions: self.filterOptions,
enablePaging: true,
pagingOptions: self.pagingOptions,
sortInfo: self.sortInfo,
rowHeight: 35
};
I have an observable array to hold the data to be displayed in the kogrid:
self.recs = ko.observableArray([]);
This is populated by the following javascript function:
self.get = function () {
$loadingIndicator.show();
$.ajax({
url: BASE_URL + 'TaskHistory/GetRecords',
type: 'get',
data: {
'page': self.pagingOptions.currentPage(),
'pageSize': self.pagingOptions.pageSize(),
'filter': self.filterOptions.filterText == undefined ? '' : self.filterOptions.filterText(),
'sort': self.sortInfo().column.field + ' ' + self.sortInfo().direction
},
contentType: 'application/json; charset=utf-8',
success: function (data) {
self.pagingOptions.totalServerItems(data.RecCount);
var recsArray = [];
$.each(data.PageOfRecords, function (key, value) {
recsArray.push(
new Task(value.WorkflowTaskHistoryId,
value.Timestamp,
value.PreviousState,
value.CurrentState,
value.AmendedByUser,
value.Note,
value.PreviousUser,
value.CurrentUser,
value.WorkflowTask_WorkflowTaskId));
});
self.recs(recsArray);
}
});
$loadingIndicator.hide();
};
As can be seen in the following screen grab from Chrome Developer tools, this observable is correctly populated:
My problem is - when displayed, the date shown are all for the current machine datetime - not related to the data retrieved from the ajax call, as shown below:
Can anyone see where I went wrong please?
You have a typo in your code, in your column def you have 'Timestamp' with a capital T but your property is called timestamp.
So the fix is very simple:
{ width: 150, field: 'timestamp', displayName: 'Timestamp', cellFilter: function (data) { return moment(data).format('DD/MM/YYYY h:mm a') } },
Why the strange behavior:
the KoGrid does not check that you provide a valid field name and in this case it passes undefined to the cellFilter function as the data parameter
if you call moment function without a valid date it defaults to the current time, that is why all your columns show the same time