Related
How can I create a hyperlink using date retrieved by JSON/JavaScript?
{ "mData": "FileRef" } - here I would like to have a hyperlink instead only text value.
Below JavaScript function used by me.
<script type="text/javascript">
function LoadZipCodes(state)
{
var call = $.ajax({
url: _spPageContextInfo.webAbsoluteUrl + "/_api/Web/Lists/GetByTitle('SharePointList')/items?$select=FileRef",
type: "GET",
dataType: "json",
headers: {
Accept: "application/json;odata=verbose"
}
});
call.done(function (data,textStatus, jqXHR){
$('#example').dataTable({
"bDestroy": true,
"bProcessing": true,
"aaData": data.d.results,
"aoColumns": [
{ "mData": "FileRef" }
]
});
});
call.fail(function (jqXHR,textStatus,errorThrown){
alert("Error retrieving Tasks: " + jqXHR.responseText);
});
}
</script>
This is my Jsp Page using jQuery
jQuery("#jqGrid01").jqGrid({
url: "JqGridDemoJson.action",
datatype:"json",
height: 200,
rowNum: 10,
rowList: [10,20,30],
colNames:['Inv No','Name'],
colModel:[
{name:'id',index:'id', editable: true,sorttype:"int",search:true},
{name:'name',index:'name', editable: true,width:30}
],
pager: "#jqGridPager01",
viewrecords: true,
add: true,
edit: true,
addtext: 'Add',
edittext: 'Edit',
caption: "Data",
hidegrid:false
});
This is my action retriveing list:
{"JQgridAction":"success",
"mitnolist":
[{"id":1,"name":"MIT\/1009\/SUF-"},
{"id":2,"name":"MIT\/1010\/SUF-"},
{"id":5,"name":"MIT\/1011\/SUF-Adma Site"},
]}
This list unable to load on the above JQgrid.
Your json is an object while jqgrid uses [{}, {}, {},...] array of multiple objects so you have to return your json as this example:
[{"id":1,"name":"MIT\/1009\/SUF-"},
{"id":2,"name":"MIT\/1010\/SUF-"},
{"id":5,"name":"MIT\/1011\/SUF-Adma Site"}]
or there is another way that you write a js ajax function and pass the required data to your jqgrid:
$.ajax({
url: "JqGridDemoJson.action",
dataType: 'json',
type: 'post',
success: function(data){
makeGrid(data.mitnolist); // as this seems to be populated in grid
}
});
now in your jqgrid you can do this:
function makeGrid(gData){ // pass in args
$("#grid").jqGrid({
data: gData, // your data to populate in grid
datatype: "local", // now change the datatype to local
.....
});
}
A small working example.
I'm trying to populate a JqGrid inside the success function of an Ajax call. My ajax call is passing a date parameter to the function which will filter the results. My grid loads, but no data is displayed and it says Loading... above my grids caption. I'm using a drop down to filter results based on date. My json data has been verified to be valid.
$(document).ready(function () {
$("[name='DDLItems']").change(function () {
var selection = $(this).val();
var dataToSend = {
//holds selected value
idDate: selection
};
$.ajax({
type: "POST",
url: "Invoice/Filter",
data: dataToSend,
success: function (dataJson) {
// alert(JSON.stringify(dataJson));
$("#grid").jqGrid({ //set your grid id
data: dataJson, //insert data from the data object we created above
datatype: json,
mtype: 'GET',
contentType: "application/json; charset=utf-8",
width: 500, //specify width; optional
colNames: ['Invoice_Numbers', 'Amt_Totals','f', 'ff', 't'], //define column names
colModel: [
{ name: 'Invoice_Number', index: 'Invoice_Number', key: true, width: 50 },
{ name: 'Amt_Total', index: 'Amt_Total', width: 50 },
{ name: 'Amt_Due', index: 'Amt_Due', width: 50 },
{ name: 'Amt_Paid', index: 'Amt_Paid', width: 50 },
{ name: 'Due_Date', index: 'Due_Date', width: 50 },
], //define column models
pager: jQuery('#pager'), //set your pager div id
sortname: 'Invoice_Number', //the column according to which data is to be sorted; optional
viewrecords: false, //if true, displays the total number of records, etc. as: "View X to Y out of Zā optional
sortorder: "asc", //sort order; optional
caption: "jqGrid Example", //title of grid
});
},
-- controller
[HttpPost] // Selected DDL value
public JsonResult Filter(int idDate)
{
switch (idDate)
// switch statement goes here
var dataJson = new UserBAL().GetInvoice(date);
return Json(new { agent = dataJson}, JsonRequestBehavior.AllowGet);
Here's the answer if anyone else comes across this. This is what I ended up doing, the rows are getting filtered passed on the date parameter I'm passing to the URL of the function. Having the Grid populate inside the Ajax call also seemed like it was a problem so I had to take it out.
public JsonResult JqGrid(int idDate)
{
switch (idDate)
#region switch date
--Switch Statement--
#endregion
var invoices = new UserBAL().GetInvoice(date);
return Json(invoices, JsonRequestBehavior.AllowGet);
}
[HttpPost] // pretty much does nothing, used as a middle man for ajax call
public JsonResult JqGridz(int idDate)
{
switch (idDate)
#region switch date
--Switch Statement--
#endregion
var invoices = new UserBAL().GetInvoice(date);
return Json(invoices, JsonRequestBehavior.AllowGet);
}
Yes these two functions seem very redundant and they are. I don't know why my post wouldn't update data, but I needed to reload the grid each time and when I did that it would call the first function. So yea the post jqGridz is kinda of just a middle man.
Here's the jquery code I used
var dropdown
var Url = '/Invoice/JqGrid/?idDate=0'
$(document).ready(function () {
$("#jqgrid").jqGrid({
url: Url,
datatype: 'json',
mtype: 'GET', //insert data from the data object we created above
width: 500,
colNames: ['ID','Invoice #', 'Total Amount', 'Amount Due', 'Amount Paid', 'Due Date'], //define column names
colModel: [
{ name: 'InvoiceID', index: 'Invoice_Number', key: true, hidden: true, width: 50, align: 'left' },
{ name: 'Invoice_Number', index: 'Invoice_Number', width: 50, align: 'left'},
{ name: 'Amt_Total', index: 'Amt_Total', width: 50, align: 'left' },
{ name: 'Amt_Due', index: 'Amt_Due', width: 50, align: 'left' },
{ name: 'Amt_Paid', index: 'Amt_Paid', width: 50, align: 'left' },
{ name: 'Due_Date', index: 'Due_Date', formatter: "date", formatoptions: { "srcformat": "Y-m-d", newformat: "m/d/Y" }, width: 50, align: 'left' },
],
pager: jQuery('#pager'),
sortname: 'Invoice_Number',
viewrecords: false,
editable: true,
sortorder: "asc",
caption: "Invoices",
});
$("[name='DDLItems']").change(function () {
var selection = $(this).val();
dropdown = {
//holds selected value
idDate: selection
};
$.ajax({
type: "POST",
url: "Invoice/JqGridz",
data: dropdown,
async: false,
cache: false,
success: function (data) {
$("#jqgrid").setGridParam({ url: Url + selection})
$("#jqgrid").trigger('reloadGrid');
}
})
})
});
Are you actually passing a value to your controller? I see you have data: dataToSend which doesn't match to your controllers idDate.
Is there a reason you are trying to setup your grid this way? Do you not want to deal with paging, or I'm not even sure if your setup would handle rebuild a grid when a user picks the date for a 2nd time.
My personal suggestion would be that you:
setup your grid separately, hidden if you don't want it visible on page load
set it's datatype to local so the grid doesn't load on page load
on the change event:
show the grid
change the postdata parameter the grid has
set the url of the controller/action which will feed the data back to the grid
trigger a grid reload
I'm using JqGrid with Django framework. That's JS:
jQuery("#list").jqGrid({
url:'{% url views.manage.devicesajax %}',
datatype: 'json',
mtype: 'GET',
colNames:['DID', 'UDID', 'Owner', 'Name', 'First seen', 'Last seen'],
colModel :[
{name:'did', index:'did', width: 30, searchoptions:{sopt:['eq','ne','bw','cn']}},
{name:'udid', index:'udid', width: 120, editable: true, searchoptions:{sopt:['eq','ne','bw','cn']}},
{name:'d_owner', index:'d_owner', width: 70, editable: true, searchoptions:{sopt:['eq','ne','bw','cn']}},
{name:'d_name', index:'d_name', editable: true, searchoptions:{sopt:['eq','ne','bw','cn']}},
{name:'d_firstseen', index:'d_firstseen', width: 80},
{name:'d_lastseen', index:'d_lastseen', width: 80}],
pager: jQuery('#pager'),
rowNum:20,
rowList:[20,50,100],
sortname: 'did',
sortorder: "desc",
multiselect: true,
viewrecords: true,
imgpath: 'themes/basic/images',
caption: 'Devices list',
height: 330,
width: 1000,
onSelectRow: function(id) {
var id = $("#list").getRowData(id).message_id;
message_id = id;
},
editurl: "{% url views.manage.deviceseditajax %}"
});
When I do edit row in JqGrid I get error from editurl:
Forbidden (403)
CSRF verification failed. Request aborted.
It's because csrf_token doesn't pass to editurl with the other data.
How to add csrf_token to the POST request to editurl ?
This code works perfectly ( complete piece of jqgrid init ):
jQuery("#list").jqGrid({
url:'{% url views.manage.devicesajax %}',
datatype: 'json',
mtype: 'GET',
colNames:['DID', 'UDID', 'Owner', 'Name', 'First seen', 'Last seen'],
colModel :[
{name:'did', index:'did', width: 30, searchoptions:{sopt:['eq','ne','bw','cn']}},
{name:'udid', index:'udid', width: 120, editable: true, searchoptions:{sopt:['eq','ne','bw','cn']}},
{name:'d_owner', index:'d_owner', width: 70, editable: true, searchoptions:{sopt:['eq','ne','bw','cn']}},
{name:'d_name', index:'d_name', editable: true, searchoptions:{sopt:['eq','ne','bw','cn']}},
{name:'d_firstseen', index:'d_firstseen', width: 80},
{name:'d_lastseen', index:'d_lastseen', width: 80}],
pager: jQuery('#pager'),
rowNum:20,
rowList:[20,50,100],
sortname: 'did',
sortorder: "desc",
multiselect: true,
viewrecords: true,
imgpath: 'themes/basic/images',
caption: 'Devices list',
height: 330,
width: 1000,
editurl: "{% url views.manage.deviceseditajax %}",
});
jQuery("#list").navGrid('#pager',{edit:true,add:true,del:true,search:true},
{
closeAfterEdit:true,
reloadAfterSubmit:true,
closeOnEscape:true,
editData: {csrfmiddlewaretoken: '{{ csrf_token }}'}
},
{
closeAfterAdd:true,
reloadAfterSubmit:true,
closeOnEscape:true,
editData: {csrfmiddlewaretoken: '{{ csrf_token }}'}
},
{
closeOnEscape:true,
delData: {csrfmiddlewaretoken: '{{ csrf_token }}'}
},
{
caption: "Search",
Find: "Find",
Reset: "Reset",
sopt : ['eq', 'cn'],
matchText: " match",
rulesText: " rules",
closeAfterSearch: true,
afterShowSearch: function ()
{
$('#reset_filter1_block').show();
}
}
);
I don't use Django framework and not familiar with the csrf_token, but after searching in Google it seems that you need to set it in the HTTP header of the request: xhr.setRequestHeader('X-CSRF-Token', csrf_token);. To do this in case of jqGrid you can use loadBeforeSend event handler:
loadBeforeSend: function(jqXHR) {
// you should modify the next line to get the CSRF tocken
// in any way (for example $('meta[name=csrf]').attr('content')
// if you have <meta name="csrf" content="abcdefjklmnopqrstuvwxyz="/>)
var csrf_token = '<%= token_value %>'; // any way to get
jqXHR.setRequestHeader('X-CSRF-Token', csrf_token);
}
See here for a very close problem.
UPDATED: To post additional data in case of form editing usage you can use editData: editData: { csrfmiddlewaretoken:'<%= token_value %>' }. For example:
jQuery("#list").jqGrid('navGrid','#pager',{},
{ // Edit option (parameters of editGridRow method)
recreateForm:true,
reloadAfterSubmit:false,
closeOnEscape:true,
savekey: [true,13],
closeAfterEdit:true,
ajaxEditOptions: {
beforeSend: function(jqXHR) {
// you should modify the next line to get the CSRF tocken
// in any way (for example $('meta[name=csrf]').attr('content')
// if you have <meta name="csrf" content="abcdefjklmnopqrstuvwxyz="/>)
var csrf_token = '<%= token_value %>'; // any way to get
jqXHR.setRequestHeader('X-CSRF-Token', csrf_token);
}
},
editData: {
csrfmiddlewaretoken: '<%= token_value %>'
}
},
{ // Add options (parameters of editGridRow method)
recreateForm:true,
reloadAfterSubmit:false,
closeOnEscape:true,
savekey: [true,13],
closeAfterAdd:true,
ajaxEditOptions: {
beforeSend: function(jqXHR) {
// you should modify the next line to get the CSRF tocken
// in any way (for example $('meta[name=csrf]').attr('content')
// if you have <meta name="csrf" content="abcdefjklmnopqrstuvwxyz="/>)
var csrf_token = '<%= token_value %>'; // any way to get
jqXHR.setRequestHeader('X-CSRF-Token', csrf_token);
}
},
editData: {
csrfmiddlewaretoken: '<%= token_value %>'
}
}
);
I placed here both ways: setting of 'X-CSRF-Token' HTTP header and posting of the csrfmiddlewaretoken parameter. You can remove one way after the corresponding experiments.
If you use some parameters for all grids on the page you can better change the defaults (see here for details)
jQuery.extend(jQuery.jgrid.edit, {
recreateForm:true,
reloadAfterSubmit:false,
closeOnEscape:true,
savekey: [true,13],
closeAfterAdd:true,
closeAfterEdit:true,
ajaxEditOptions: {
beforeSend: function(jqXHR) {
// you should modify the next line to get the CSRF tocken
// in any way (for example $('meta[name=csrf]').attr('content')
// if you have <meta name="csrf" content="abcdefjklmnopqrstuvwxyz="/>)
var csrf_token = '<%= token_value %>'; // any way to get
jqXHR.setRequestHeader('X-CSRF-Token', csrf_token);
}
},
editData: {
csrfmiddlewaretoken: '<%= token_value %>'
}
});
The setting is common for both Add and Edit forms. So you can use navGrid in the simplified form.
jQuery("#list").jqGrid('navGrid','#pager');
Check your cookies. Django's CSRF also save a cookie csrftoken which does have the same value as the csrf_token which you would use in a form. You can use any Javascript cookie library to get the cookie and pass it to the POST request as csrfmiddlewaretoken.
According to the jqGrid documentation, you can pass a postData options.
If you're using jQuery Cookie plugin, you can add something like :
postData: {
csrfmiddlewaretoken: $.cookie(CSRF_COOKIE_NAME)
},
to your list of options to jqGrid.
The CSRF_COOKIE_NAME is set in your django application settings.py and is 'csrftoken' by default.
I found simple solution using latest JqGrid and Inline Edit submit csrf_token to request POST django without #csrf_exempt
onSelectRow: function(id){
if(id && id!==lastSel){
$(selector).restoreRow(lastSel);
lastSel=id;
}
var editparameters = {
extraparam: {csrfmiddlewaretoken: $('.token-data').data('token')},
keys: true,
};
$(selector).jqGrid('editRow', id, editparameters);
}
For example, please see on my blog post:
http://yodi.polatic.me/jqgrid-inline-editing-integration-with-django-send-csrf-token/
I have a tree-grid with autoloading rows. The goal is to sort the grid by tree column, right on client side.
But each time I click on sort column header, it issues an Ajax call for sorting, but all I need is on-place sorting using the local data.
Do I have incorrect grid parameters or doesn't tree work with client-side sorting on tree column?
Current jqGrid params for sorting are are:
loadonce: true, // to enable sorting on client side
sortable: true //to enable sorting
To get client-side sorting to work, I needed to call reloadGrid after the grid was loaded:
loadComplete: function() {
jQuery("#myGridID").trigger("reloadGrid"); // Call to fix client-side sorting
}
I did not have to do this on another grid in my application because it was configured to use data retrieved via another AJAX call, instead of data retrieved directly by the grid:
editurl: "clientArray"
datatype: "local"
I'm using client-side sorting on jqGrid and retrieving a new set of json data when a select list changes. You need to set rowTotal to an amount higher or equal to the number of rows returned, and then set the data type to 'json' just before reloading the grid.
// Select list value changed
$('#alertType').change(function () {
var val = $('#alertType').val();
var newurl = '/Data/GetGridData/' + val;
$("#list").jqGrid().setGridParam({ url: newurl, datatype: 'json' }).trigger("reloadGrid");
});
// jqGrid setup
$(function () {
$("#list").jqGrid({
url: '/Data/GetGridData/-1',
datatype: 'json',
rowTotal: 2000,
autowidth: true,
height:'500px',
mtype: 'GET',
loadonce: true,
sortable:true,
...
viewrecords: true,
caption: 'Overview',
jsonReader : {
root: "rows",
total: "total",
repeatitems: false,
id: "0"
},
loadtext: "Loading data...",
});
});
$(function () {
$("#list").jqGrid({
url: '/Data/GetGridData/-1',
datatype: 'json',
rowTotal: 2000,
autowidth: true,
height:'500px',
mtype: 'GET',
loadonce: true,
sortable:true,
...
viewrecords: true,
caption: 'Overview',
jsonReader : {
root: "rows",
total: "total",
repeatitems: false,
id: "0"
},
loadtext: "Loading data...",
});
});