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.
Related
when I export jqgrid to excel, I am not getting expected result. I am getting right data for two columns and for the rest columns it says undefined, also I am getting two extra columns at the end (please see the attached pic). I am using same export function for other jqgrid and I am getting right output there. I don't understand why I am getting this kind of result for this jqgird. I already spent more than 2 days on this but can't output right result. Any help will be highly appreciated.
$("#dataTable").jqGrid({
url: '/test/getAllData.html',
datatype: "json",
colNames: ['id', 'Material name', 'Unit', 'Supplier', 'Date', 'Amount'],
colModel: [
{ name: 'id', index: 'id',width: 300 },
{ name: 'MaterialName', index: 'MaterialName', width: 300 },,
{ name: 'unit', index: 'unit', width: 300 },
{ name: 'supplier', index: 'supplier', width: 300 },
{ name: 'date', index: 'date', width: 300 },
{ name: 'amount', index: 'amount', width: 300 }
],
rowNum: 100,
rowList: [25, 50, 75, 100],
pager: '#dataTablePager',
viewrecords: true,
ignoreCase: true,
loadonce: false,
viewrecords: true,
jsoonReader: {
repeatitems:false;
},
loadComplete : function () {
exportToExcel("dataTable"); //export function
}
});
<div id="dataTable"/>
</div id="dataTablePager"/>
There was some issues on export js function , export js function was setting colmodels manually with different names so I was getting undefined. I have fixed this issue
I am trying to show data in group using jqGrid. It creates multiple group for same name.
Below is My Code
jQuery("#jqGridManage").jqGrid({
datatype: "local",
data: Projectdata,
colNames: ['Action', 'Opportunity Id', 'Salesforce Opportunity ID', 'Project Name (Opportunity Name)', 'Project Type', 'Type Of Revenue', 'Milestone Description', 'Amount', 'PO Number', 'PO Amount', 'Close Date', 'Assigned To',
'Business Unit', 'Product', 'Channel Name', 'Sales Person', 'Vertical', 'Customer Name', 'Customer Contact','Region'],
colModel: [
{ name: 'actionBtn', search: false, frozen: true, width: 200, align: 'center'},
{ name: 'OpportunityID', index: 'id', frozen: true },//, cellattr: arrtSetting
{ name: 'SalesforceOpportunityId', index: 'invdate', frozen: true },
{ name: 'OpportunityName', index: 'name', frozen: true },
{ name: 'ProjectTypeLongName', index: 'amount', frozen: true },
{ name: 'ProjectTypeChildName', index: 'tax', frozen: true },
{ name: 'ChannelName', index: 'total', frozen: true },
{ name: 'Amount', index: 'amount' },
{ name: 'PONumber', index: 'closedate' },
{ name: 'POAllocatedAmount', index: 'closedate' },
{ name: 'CloseDate', index: 'closedate' },
{ name: 'AssignedTo', index: 'note' },
{ name: 'BusinessUnit', index: 'note' },
{ name: 'Product', index: 'product' },
{ name: 'Channel Name', index: 'stage' },
{ name: 'SalesPerson', index: 'salesperson' },
{ name: 'Vertical', index: 'vertical' },
{ name: 'CustomerName', index: 'customername' },
{ name: 'CustomerContactNumber', index: 'currency' },
{ name: 'Region', index: 'amountexpected' }
],
shrinkToFit: false,
pager: "#jqGridPagerManage",
viewrecords: true,
autowidth: true,
height: 450,
sortname: "OpportunityID",
grouping: true,
groupingView: {
groupField: ["OpportunityID"],
groupColumnShow: [true, true],
groupCollapse: false,
groupDataSorted: true
},
resizeStop: function () {
resizeColumnHeader.call(this);
fixPositionsOfFrozenDivs.call(this);
fixGboxHeight.call(this);
},
loadComplete: function () {
fixPositionsOfFrozenDivs.call(this);
},
gridComplete: function () {
var ids = $("#jqGridManage").jqGrid('getDataIDs');
for (var i = 0; i < ids.length; i++) {
var rowId = ids[i],
// statusId = $("#list").jqGrid ('getCell', rowId, 'statusId'),
// activeBtn = "";
// if (statusId == 0) { // Inactive
activeBtn = "<button class='ManageEditBtn ManageEdit'><i class='fa fa-edit'></i> Edit</button> <button class='ManageEdit ManageCreate'><i class='fa fa-plus'></i> Create Invoice</button>";
//"onclick='publish(" + rowId + ")' />";
// }
jQuery("#jqGridManage").jqGrid('setRowData', rowId, { actionBtn: activeBtn });
}
},
})
In my code data coming from backend. I am grouping by OpportunityID; there are 4 opprtunity id's but each group is showing multiple times. Below is My screenshow for reference.
I have referred other same questions also but that are not helpful. Can anybody help me in this?
colModel, which you use have many inconsistencies. You should remove of index properties. If you use index in combination with datatype: "local", then the value of index property should corresponds the name property or to reference name of another column of colModel. The best choice is not using any index property at all.
Additionally you have to fix the name of Channel Name column. The value of name property will be used for building ids of some internal elements on the HTML page and HTML5 don't allow the usage of spaces in id.
The problem IMHO is that your data coming from the server should be sorted by OpportunityID. Check if this is true.
Another cause can be in your gridComplete event. Remove this event and see if the grouping is ok.
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 have two JavaScript files called FileA.js and FileB.js.
FileA.js contains the following function:
Reports.CompanySearch.InitGrid = function (viewModel, emptyInit) {
var columns = [
{
name: 'CompanyName',
width: 150,
hidedlg: true,
search: false,
formatter: function namelinkformatter(cellvalue, options, rowObject) {
return "<a href='#/CompanyDetails/" + rowObject["Id"] + "'>" + rowObject["CompanyName"] + "</a>";
}
},
{ name: 'Address', width: 300, search: false },
{ name: 'City', width: 100, search: false },
{ name: 'State', width: 50, search: false },
{ name: 'Zip', width: 80, search: false, hidden: true },
{ name: 'Country', width: 120, search: false, hidden: true }
];
var grid = $("#searchGrid");
grid.jqGrid({
jsonReader: { root: 'rows', total: 'total', page: 'page', records: 'records', cell: 'cell', id: 'Id', repeatitems: false },
colNames: [
'Company Name',
'Address',
'City',
'State',
'Zip',
'Country'],
colModel: columns,
postData: Reports.CompanySearch.CreateSearchModel(viewModel),
url: '/CompanyReport/Search',
datatype: emptyInit ? 'local' : 'json',
mtype: 'POST',
viewrecords: true,
loadonce: false,
shrinkToFit: false,
multiselect: false,
autowidth: true,
altRows: true,
height: 'auto'
});};
Basically the function creates on a page (Page A) a data grid which contains a list of companies loaded from a table in SQL Server.
The Company name has a link, allowing users to click it and get the company detail on a different page (Page B).
Page A is controlled by JavaScript FileA.js and Page B by JavaScript FileB.js.
I would like to pass the Company ZipCode to a function in FileB.js everytime the user clicks on the company name.
The solutions I ran into on the web were not helpful so far and any help would be very appreciated. Thanks!
Since you're using Knockout, have a look at Components.
The way to coordinate the two is to have a parent file that knows about both of them and mediates between them. The parent would create the data objects and pass them to both of the component objects.
I have a database containing many to many relations, so a Post can have multiple Tags, and a Tag can be assigned to multiple Posts
I am using jqgrid to display all the posts in a grid using the following code:
Javascript:
//grid
jQuery(document).ready(function () {
//post grid
jQuery("#tablePosts").jqGrid({
url: '/Admin/ListPosts/',
datatype: 'json',
mtype: 'GET',
colNames: ['ID', 'Title', 'Short Description', 'Description', 'Category', 'Tags', 'Published', 'Posted Date', 'Modified Date', 'UrlSlug', 'Meta'],
colModel: [
{ name: 'PostID', index: 'PostID', width: 50, stype: 'text' },
{ name: 'Title', index: 'Title', width: 150 },
{ name: 'ShortDescription', index: 'ShortDescription', width: 150, sortable: false },
{ name: 'Description', index: 'Description', width: 200, sortable: false },
{ name: 'Category', index: 'Category', width: 100 },
{ name: 'Tags', index: 'Tags', width: 100, sortable: false},
{ name: 'Published', index: 'Published', width: 80 },
{ name: 'PostedOn', index: 'PostedOn', width: 130 },
{ name: 'Modified', index: 'Modified', width: 130 },
{ name: 'UrlSlug', index: 'UrlSlug', width: 80, sortable: false },
{ name: 'Meta', index: 'Meta', width: 80, sortable: false }
],
rowNum: 10,
rowList: [5, 10, 20, 50],
viewrecords: true,
pager: '#pagerPosts',
height: '100%',
sortname: 'PostedOn',
sortorder: "desc",
//width to null && shrink to false so the width of the grid inherit parent and resizes with the parent
width: null,
shrinkToFit: false
});
});
and this is my controller action:
public ActionResult ListPosts(string sidx, string sord, int page, int rows)
{
int pageNo = page - 1;
int pageSize = rows;
//for paging
int totalRecords = repository.TotalPosts(true) + repository.TotalPosts(false);
int totalPages = (int)Math.Ceiling((float)totalRecords / (float)rows); //round up to smallest integral number greater than returned valued
//for records
var posts = repository.AllPosts(pageNo, pageSize, sidx, sord == "asc");
var jsonData = new
{
total = totalPages,
page = page,
records = totalRecords,
rows = (
from post in posts
select new
{
id = post.PostID,
cell = new string[] {
post.PostID.ToString(),
post.Title,
post.ShortDescription,
post.Description,
post.Category.Name,
post.Tags.ToString(),
post.Published.ToString(),
post.PostedOn.ToString(),
post.Modified.ToString(),
post.UrlSlug,
post.Meta
}
}).ToArray()
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
In my rows, I defined post tags as a string just to remove errors and I couldn't figure out how to display Tags as a list, and this is my grid:
as you can see, Tags column is not displaying Tag names, how do you display them correctly?
Insted of post.Tags.ToString() use string.Join(",",post.Tags.Select(t => t.Name))
Or pass array of tags to your view and use custom formatter
Formatter may looks like this:
function tagFormatter(cellvalue, options, rowObject)
{
var text = ""
if (cellvalue.length > 0)
{
for (var i = 0; i < cellvalue.length; i++)
{
text += cellvalue[i].Name;
if (i < cellvalue.length - 1)
{
text += ", ";
}
}
}
return text;
}
It will display comma-separated tags names;
And tag row:
{ name: 'Tags', index: 'Tags', width: 100, sortable: false, formatter: tagFormatter },
Is it helpful?