Related
I need inline image buttons for EDIT and DELETE functionality.
But, I don't need default inline editing or inbuilt dialog popup as , my design is as follow.
add/edit form is appear first and then, below that section, - grid is appearing.
On click of - row inline "Edit" image button , need to populate row data on above form.
To achieve this, on click of edit image button, I need to have javascript function call along with row data object.
How to achieve this ? Can any one share me the column code and function which can allow me to achieve this ?
Below is jqgrid stuff:
$('#CategoriesGrdList').jqGrid({
ajaxGridOptions: {
error: function () {
$('#CategoriesGrdList')[0].grid.hDiv.loading = false;
alert('An error has occurred.');
}
},
url: '#Url.Action("GetAllCategoriesList", "Categories")/' + 0,
gridview: true,
autoencode: true,
postData: { categoryId: 1 },
datatype: 'json',
jsonReader: { root: 'List', page: 'Page', total: 'TotalPages', records: 'TotalCount', repeatitems: false, id: 'Id' },
mtype: 'GET',
colNames: ['Id', 'Code', 'Description', 'IsActive', "actions"],
colModel: [
{ name: 'Id', index: 'Id', hidden: true, key: true },
{ name: 'Code', index: 'Code', width: 170 },
{ name: 'Description', index: 'Description', width: 170 },
{ name: 'IsActive', index: 'IsActive', width: 170 },
{
name: 'actions', index: 'actions', formatter: 'actions',
formatoptions: {
keys: true,
editbutton: false,
delOptions: { url: '#Url.Action("DeleteCategory", "Categories")' }
}
}
],
pager: $('#CategoriesGrdPager'),
sortname: 'Code',
rowNum: 3,
rowList: [3, 6, 9],
width: '725',
height: '100%',
viewrecords: true,
beforeSelectRow: function (rowid, e) {
return true;
},
sortorder: 'desc'
}).navGrid('#CategoriesGrdPager', { edit: false, add: false, del: false, search: false, refresh: true });
You could add custom icons to the actions column of each line on gridComplete. See example below.
$('#CategoriesGrdList').jqGrid({
...
sortorder: 'desc',
gridComplete: function () {
var ids = $("#CategoriesGrdList").jqGrid('getDataIDs');
for (var i = 0; i < ids.length; i++) {
var id = ids[i];
var editIcon = "<div style='float: left;' class='ui-pg-div' onclick='myEditRow(\"" + id + "\");'><a class='ui-icon ui-icon-pencil'></a></div>";
var deleteIcon = "<div style='float: left;' class='ui-pg-div' onclick='myDeleteRow(\"" + id + "\");'><a class='ui-icon ui-icon-trash'></a></div>";
$("#gridDocs").jqGrid('setRowData', ids[i], { actions: editIcon + deleteIcon });
}
}
}).navGrid('#CategoriesGrdPager', { edit: false, add: false, del: false, search: false, refresh: true });
function myEditRow(rowId) {
var rowData = $("#CategoriesGrdList").jqGrid('getRowData', id);
//do something with the data i.e.
$('#nameEditInput').val(rowData.Code);
}
function myDeleteRow(rowId) {
//your delete code...
$("#" + id).hide();
}
When I drag and drop in jqGrid, I need to trigger a change in order for my items on the server side. I felt this would be a simple exercise, but I have yet to encounter a code example of how this can be achieved. I have looked at trying to use the jQueryUI events information, but the target is listed as the entire grid. I have been able to extract the source row Id from the onstop event via ui.helper.context.id, but I have had no luck what-so-ever identifying the dropped-on-item (and more importantly its id) within the list.
Just to clarify, I am dragging and dropping within the same jqGrid in an attempt to re-order the items on the server.
I have a jqGrid:
$("#modelList").jqGrid({
url: getMSModelsJsonUrl + '?manuf=1',
datatype: "json",
colNames: ['ID', 'Name'],
colModel: [
{ name: 'optionValue', key: true, index: 'optionValue', width: 55, editable: false, hidden: true, editrules: { edithidden: true } },
{ name: 'optionDisplay', index: 'optionDisplay', width: 155, editable: false }
],
onSelectRow: function (id) {
var manuf = $("#manufList").jqGrid('getGridParam', 'selrow');
self.modelsTableInfo.currentSelection(manuf);
$('#bodyList').setGridParam({ url: getMSBodiesJsonUrl + '?manuf=' + manuf + '&model=' + id }).trigger('reloadGrid');
},
loadComplete: function () {
var grid = $("#modelList"),
ids = grid.jqGrid("getDataIDs");
if (ids && ids.length > 0)
grid.jqGrid("setSelection", ids[0]);
},
sortname: 'optionValue',
viewrecords: true,
sortorder: "desc",
caption: "Models",
height: 350,
rowNum: 1000,
autowidth: true
});
and a drag and drop binding thus:
$("#modelList").jqGrid('gridDnD', {
connectWith: '#modelList',
onstop: function (event, ui) {
var draggedItem = ui.helper.context.id;
var dragTarget = event.target.id;
alert(draggedItem +" to "+dragTarget );
},
beforedrop: function (event, ui, data, source, target) {
return data;
}
});
When something is dragged and dropped with the above code, it reports the source and target id as being the same.
I must be missing something here, as this all seems like an obvious use of the drag and drop functionality.
-- Edit ---
I ended up going for this solution that uses tableDnD as well, as I couldn't get jqGrid working (I'd love to see a solution though)
jQuery("#modelList").tableDnD({
scrollAmount: 0,
onDrop: function(table, row) {
var rows = table.tBodies[0].rows;
var rowIdBeforeNewPosition =null;
for (var i=0; i
if (rows[i].id === row.id) {
if (i > 0)
rowIdBeforeNewPosition = rows[i-1].id;
}
}
var manufId = $("#manufList").jqGrid('getGridParam', 'selrow');
$.ajax({ url: setModelOrderJSONUrl + '?manufId=' + manufId + '&modelIdToMove=' + row.id + '&modelIdToPositionAfter=' + rowIdBeforeNewPosition, type: "POST" }).done(function (wasSuccessful) {
if (!wasSuccessful)
$('#modelList').trigger('reloadGrid'); //Reload to reflect true situation
});
}
});
$("#modelList").jqGrid({
url: getMSModelsJsonUrl + '?manuf=1',
datatype: "json",
colNames: ['ID', 'Name'],
colModel: [
{ name: 'optionValue', key: true, index: 'optionValue', width: 55, editable: false, hidden: true, editrules: { edithidden: true } },
{ name: 'optionDisplay', index: 'optionDisplay', width: 155, editable: false }
],
onSelectRow: function (id) {
var manuf = $("#manufList").jqGrid('getGridParam', 'selrow');
self.modelsTableInfo.currentSelection(manuf);
$('#bodyList').setGridParam({ url: getMSBodiesJsonUrl + '?manuf=' + manuf + '&model=' + id }).trigger('reloadGrid');
},
loadComplete: function () {
var grid = $("#modelList"),
ids = grid.jqGrid("getDataIDs");
if (ids && ids.length > 0)
grid.jqGrid("setSelection", ids[0]);
},
gridComplete: function () {
$("#_empty", "#modelList").addClass("nodrag nodrop");
jQuery("#modelList").tableDnDUpdate();
},
sortname: 'optionValue',
viewrecords: true,
sortorder: "desc",
caption: "Models",
height: 350,
rowNum: 1000,
autowidth: true
});
I have a Jqgrid, In my MVC view, there is no problem in displaying the data in the grid. But I want to apply the custom paging in the grid, so i have created the method in my controller which takes two parameters (pageNumber and rowSize) and returns the data based on the these two parameters.
Now my question is that how can i send these two property of grid to the controller and get the changes reflected on the grid.
Note: i also tried to send the value of rowSize using ajax on the button click but after executing the code in the server there is no changes in the grid(as i expected).
View:
<table id="jQGridDemo">
</table>
<div id="jQGridDemoPager">
</div>
<script type="text/javascript">
jQuery("#jQGridDemo").jqGrid({
datatype: "json",
colNames: ['Id', 'First Name', 'Last Name', 'Last 4 SSN', 'Department',
'Age', 'Salary', "Address", 'Marital Status'],
colModel: [
{ name: 'ID', index: '_id', width: 20, stype: 'text' },
{ name: 'FirstName', index: 'FirstName', width: 150 },
{ name: 'LastName', index: 'LastName', width: 150 },
{ name: 'LastSSN', index: 'LastSSN', width: 100 },
{ name: 'Department', index: 'Department', width: 80, align: "right" },
{ name: 'Age', index: 'Salary', width: 80, align: "right" },
{ name: 'Salary', index: 'Salary', width: 80, align: "right" },
{ name: 'Address', index: 'Address', width: 150, sortable: false },
{ name: 'MaritalStatus', index: 'MaritalStatus', width: 100, sortable: false }
],
rowNum: 10,
loadonce: false,
rowList: [5, 10, 20, 50],
pager: "#jQGridDemoPager",
height: "100%",
sortname: 'ID',
viewrecords: true,
sortorder: "desc",
caption: "List Employee Details",
url: '/Home/Records'
});
$(".ui-pg-input").click(function () {
alert(this.value);
$.ajax({
type: 'POST',
url: window.location + "Home/Records",
data: {
pageNumber: this.value
},
success: function (data) {
alert("ajax call completed");
},
error: function () {
alert("Something went Wrong");
}
});
})
</script>
Controller
public JsonResult Records(int pageNumber=3, int rowSize = 5)
{
// code for custom paging
return json;
}
JSON Returned from Server:
[{"ID":1,"FirstName":"Alan","LastName":"Donald","LastSSN":"123","Department":"Bowler","Age":"44 ","Salary":"1000000 ","Address":"South Africa","MaritalStatus":"Married ","EntityState":2,"EntityKey":{"EntitySetName":"tbl_Details","EntityContainerName":"JQGridDBEntities","EntityKeyValues":[{"Key":"ID","Value":1}],"IsTemporary":false}},{"ID":2,"FirstName":"Donald","LastName":"Duck","LastSSN":"345","Department":"Actor","Age":"98 ","Salary":"2000000 ","Address":"USA","MaritalStatus":null,"EntityState":2,"EntityKey":{"EntitySetName":"tbl_Details","EntityContainerName":"JQGridDBEntities","EntityKeyValues":[{"Key":"ID","Value":2}],"IsTemporary":false}},{"ID":3,"FirstName":"Virat","LastName":"Kohli","LastSSN":"111","Department":"Batsman","Age":"28 ","Salary":"1000000 ","Address":"India","MaritalStatus":"Unknown ","EntityState":2,"EntityKey":{"EntitySetName":"tbl_Details","EntityContainerName":"JQGridDBEntities","EntityKeyValues":[{"Key":"ID","Value":3}],"IsTemporary":false}},{"ID":4,"FirstName":"MS","LastName":"Dhoni","LastSSN":"112","Department":"Captain","Age":"31 ","Salary":"9000000 ","Address":"India","MaritalStatus":"Married ","EntityState":2,"EntityKey":{"EntitySetName":"tbl_Details","EntityContainerName":"JQGridDBEntities","EntityKeyValues":[{"Key":"ID","Value":4}],"IsTemporary":false}},{"ID":5,"FirstName":"Sachin","LastName":"Tendulkar","LastSSN":"113","Department":"Superman","Age":"40 ","Salary":"90000000 ","Address":"India","MaritalStatus":"Married ","EntityState":2,"EntityKey":{"EntitySetName":"tbl_Details","EntityContainerName":"JQGridDBEntities","EntityKeyValues":[{"Key":"ID","Value":5}],"IsTemporary":false}},{"ID":6,"FirstName":"Virendra","LastName":"Sehwag","LastSSN":"114","Department":"Batsman","Age":"36 ","Salary":"8000000 ","Address":"India","MaritalStatus":"Married ","EntityState":2,"EntityKey":{"EntitySetName":"tbl_Details","EntityContainerName":"JQGridDBEntities","EntityKeyValues":[{"Key":"ID","Value":6}],"IsTemporary":false}},{"ID":7,"FirstName":"Zaheer","LastName":"Khan","LastSSN":"115","Department":"Bowler","Age":"36 ","Salary":"3000000 ","Address":"India","MaritalStatus":"Married ","EntityState":2,"EntityKey":{"EntitySetName":"tbl_Details","EntityContainerName":"JQGridDBEntities","EntityKeyValues":[{"Key":"ID","Value":7}],"IsTemporary":false}},{"ID":8,"FirstName":"Demo","LastName":"Demo","LastSSN":"Demo","Department":"Demo","Age":"Demo ","Salary":"Demo ","Address":"Demo","MaritalStatus":"Demo ","EntityState":2,"EntityKey":{"EntitySetName":"tbl_Details","EntityContainerName":"JQGridDBEntities","EntityKeyValues":[{"Key":"ID","Value":8}],"IsTemporary":false}},{"ID":9,"FirstName":"Demo","LastName":"Demo","LastSSN":"Demo","Department":"Demo","Age":"Demo ","Salary":"Demo ","Address":"Demo","MaritalStatus":"Demo ","EntityState":2,"EntityKey":{"EntitySetName":"tbl_Details","EntityContainerName":"JQGridDBEntities","EntityKeyValues":[{"Key":"ID","Value":9}],"IsTemporary":false}},{"ID":10,"FirstName":"Demo","LastName":"Demo","LastSSN":"Demo","Department":"Demo","Age":"Demo ","Salary":"Demo ","Address":"Demo","MaritalStatus":"Demo ","EntityState":2,"EntityKey":{"EntitySetName":"tbl_Details","EntityContainerName":"JQGridDBEntities","EntityKeyValues":[{"Key":"ID","Value":10}],"IsTemporary":false}}]
I think there are misunderstanding how jqGrid works. If you don't use loadonce: true option jqGrid send automatically request to url with additional parameters which specify the page size and the requested page. So you don't need to many any $.ajax and you don't need to bind $(".ui-pg-input").click. Default names of 1-based "page number" parameter is page and the name of "row size" parameter is rows. So you need just rename parameters of Records actions.
Alternatively you can use prmNames option of jqGrid (see the documentation) to inform jqGrid to use other parameter names as default page and rows. For example you can add the option
prmNames: {page: "pageNumber", rows: "rowSize"}
to solve your problem.
I've been trawling across the web for answers, and maybe it's a case of it being more complicated than I expect (or I just don't understand the solutions), but I am looking for a way to simply delete a selected row from my jqgrid by clicking the trash icon.
Currently my grid is being populated with Linq to SQL data.
Here is my grid:
jQuery("#grid").jqGrid({
url: '<%= ResolveUrl("~/Home/GetData") %>',
datatype: "json",
mtype: 'GET',
postData: { DDLid: function () { return jQuery("#DDL option:selected").val(); } },
colNames: ['Col1', 'Col2'],
colModel: [
{ name: 'Col1', index: 'Col1', width: 200, editable: false },
{ name: 'Col2', index: 'Col2', width: 200, editable: false }
],
jsonReader: {
repeatitems: false
},
rowNum: 10,
pager: jQuery('#gridpager'),
sortname: 'Type',
viewrecords: true,
sortorder: "asc",
caption: "Table"
}).navGrid('#gridpager', { del: true, add: false, edit: false, search: false }, {}, {}, {url: "Delete"});
Now the 'id' in post data is NOT the primary key in this table - I just need it to help populate the grid.
What I would like to get is the selected row id and pass it to the Delete method, but I can't find any way to do that.
I have tried using jQuery("#grid").getGridParam('selrow') in the postData but it always returns null.
Any help would be greatly appreciated.
Here is my delete method, for reference:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Delete(int DDLid)
{
int row = Convert.ToInt32(/*I NEED THIS ID*/);
var query = from x in _ctx.DataTable
where ((x.id == row))
select x;
_ctx.DataTable.DeleteOnSubmit(query.Single());
_ctx.SubmitChanges();
return Json(true);
}
This method is called and is fine, but I am getting the wrong id. I need the selected row's id. This breaks because the DDLid returns more than one row (since it is used to populate the grid).
I hope that makes sense.
I discovered where I would pass the selected index (but then I realised I was looking for the primary key, rather than selected index, but it is the same result regardless)
I needed to add this to my navGrid:
{url: "Delete", mtype: "POST", reloadAfterSubmit: true,
serializeDelData: function (postdata) {
var selectedrowindex = jQuery("#grid").jqGrid('getGridParam', 'selrow');
var dataFromCellByColumnIndex = jQuery('#grid').jqGrid ('getCell', selectedrowindex , 1);
return {DDLid: postdata.id, name: dataFromCellByColumnIndex};
}
});
So this passes a column value to my delete method as well as the DDLid, but I could easily swap dataFromCellByColumnIndex with selectedrowindex.
You should just implement Delete action having id parameter:
public JsonResult Delete(string id) {
...
}
To reference the action in the JavaScript code I would use 'url: <%= Url.Action("Delete") %>' instead of url: "Delete" which you use currently.
You can download here demo project which I created for the answer. The project implement deleting of the row together with many other features which you currently not need.
You can make another post inside delete method with your own params. After defining grid, you can define each action in detail. It is posting actual delete with correctid and original one is posting fake id. JQgrid is using row count for delete not the primary key. They may change it with recent versions, but this was working Jqgrid 3.8
jQuery("#ClientGrid").jqGrid('navGrid', '#ClientGridPager',
{ view: true, edit: true, search: false }, //options
{height: 240, caption: 'Edit Client', beforeShowForm: hideIDColumn, reloadAfterSubmit: true, mtype: 'POST', url: "/Settings/EditClient", jqModal: false, closeOnEscape: true, bottominfo: "Fields marked with (*) are required" }, // edit options
{height: 340, caption: 'Add Client', beforeShowForm: hideIDColumn, reloadAfterSubmit: true, mtype: 'POST', url: "/Settings/CreateClient", jqModal: false, closeOnEscape: true, bottominfo: "Fields marked with (*) are required", closeAfterAdd: true }, // add options
//delete method
{reloadAfterSubmit: true, beforeSubmit: function (postdata, formid)
{
var lastselectedID = -1;
if (ClientGridrow != null || typeof (ClientGridrow) != "undefined")
{
lastselectedID = $("#ClientGrid").getCell(ClientGridrow, 'ID_PK');
}
//CUSTOME delete to send taskid instead of rowid
$.ajax({ type: "POST", url: "/Settings/DeleteClient/?objid=" + lastselectedID,
data: "", success: function (response)
{
$("#ClientGrid").trigger("reloadGrid"); //reloadAfterSubmit: true is not working in Chrome
}
});
return [true, "Delete failed message"];
}, caption: 'Delete Client', datatype: 'local', url: "/Settings/DeleteClient/?objid=-1", jqModal: false, closeOnEscape: true
}, // del options..we make two posts
{closeOnEscape: true }, // search options
{height: 230, width: 350, jqModal: false, closeOnEscape: true} // view options
);
So I've got basic example of jqgrid working in ASP.NET MVC, the javascript looks like this:
$(document).ready(function() {
$("#list").jqGrid({
url: '../../Home/Example',
datatype: 'json',
myType: 'GET',
colNames: ['Id', 'Action', 'Parameters'],
colModel: [
{ name: 'id', index: 'id', width: 55, resizable: true },
{ name: 'action', index: 'action', width: 90, resizable: true },
{ name: 'paramters', index: 'parameters', width: 120, resizable: true}],
pager: $('#pager'),
rowNum: 10,
rowList: [10, 20, 30],
sortname: 'id',
sortorder: 'desc',
viewrecords: true,
multikey: "ctrlKey",
imgpath: '../../themes/basic/images',
caption: 'Messages'
});
Now I am trying to implement the search button that they have in the jqgrid examples (click on Manipulating/Grid Data). But I don't see how they implement it. I'm expecting e.g. a "search:true" and a method to implement it.
Has anyone implemented search on jqgrid or know of examples that show explicitly how to do it?
I recently implemented this myself (yesterday actually) for the first time. The biggest hurdle for me was figuring out how to write the controller function. The function signature is what took me the longest to figure out (notice the _search, searchField, searchOper, and searchString parameters as those are missing from most of asp.net mvc examples I've seen). The javascript posts to the controller for both the initial load and for the search call. You'll see in the code that I'm checking whether the _search parameter is true or not.
Below is the controller and the javascript code. My apologies for any formatting issues as this is my first time posting on here.
public ActionResult GetAppGroups(string sidx, string sord, int page, int rows, bool _search, string searchField, string searchOper, string searchString)
{
List<AppGroup> groups = service.GetAppGroups();
List<AppGroup> results;
if (_search)
results = groups.Where(x => x.Name.Contains(searchString)).ToList();
else
results = groups.Skip(page * rows).Take(rows).ToList();
int i = 1;
var jsonData = new
{
total = groups.Count / 20,
page = page,
records = groups.Count,
rows = (
from appgroup in results
select new
{
i = i++,
cell = new string[] {
appgroup.Name,
appgroup.Description
}
}).ToArray()
};
return Json(jsonData);
}
And here is my HTML/Javascript:
$(document).ready(function() {
$("#listGroups").jqGrid({
url: '<%= ResolveUrl("~/JSON/GetAppGroups/") %>',
datatype: 'json',
mtype: 'GET',
caption: 'App Groups',
colNames: ['Name', 'Description'],
colModel: [
{ name: 'Name', index: 'Name', width: 250, resizable: true, editable: false},
{ name: 'Description', index: 'Description', width: 650, resizable: true, editable: false},
],
loadtext: 'Loading Unix App Groups...',
multiselect: true,
pager: $("#pager"),
rowNum: 10,
rowList: [5,10,20,50],
sortname: 'ID',
sortorder: 'desc',
viewrecords: true,
imgpath: '../scripts/jqgrid/themes/basic/images'
//});
}).navGrid('#pager', {search:true, edit: false, add:false, del:false, searchtext:"Search"});
See my article on codeproject, which explains how we can do multiple search in jqgrid:
Using jqGrid’s search toolbar with multiple filters in ASP.NET MVC
I use IModelBinder for grid's settings binding, expression trees for sorting and filtering data.
In case you're still wondering about dealing with optional parameters, just declare them as nullables by adding a ? after the type name.
Now you'll be able to compare them with null to check if they are absent.
Note that you don't need to do this with strings, as they are already nullable.
#Alan - ok, I used your method and extended my webservice to expect those additional three parameters and check for "_search" is true/false. But, in order to make this work, I had to add this to my ajax call in the JavaScript:
if (!postdata._search) {
jQuery("#mygrid").appendPostData( {searchField:'', searchOper:'', searchString:''});
}
Just follow this link. It has all implementations explained...
You can create a button searchBtn and can invoke search form on click
$("#searchBtn").click(function(){
jQuery("#list4").searchGrid(
{options}
)});