Returning JSON Data to JQGrid is prompting to save a file - asp.net-mvc-4

I'm new to ASP.Net MVC. I'm trying a sample program to bind a JQGrid with data. When I return the JSON data from the Controller , the system is prompting me with a pop up "Do you want to Save the file ..".I beleive my browser is not able to understand JSON data. I went through the other post in StackOverFlow and none of them seem to help me. I'm running this on IE8 set to Compatibility mode. Please see the code below:
Index.cshtml
#{
ViewBag.Title = "Home Page";
}
<link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
<link href="~/Content/jquery.jqGrid/ui.jqgrid.css" rel="stylesheet" type="text/css" />
<link href="~/Content/themes/base/jquery.ui.all.css" rel="stylesheet" type="text/css" />
<script src="~/Scripts/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="~/Scripts/i18n/grid.locale-en.js" type="text/javascript"></script>
<script src="~/Scripts/jquery.jqGrid.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#myGrid").jqGrid({
url: '../../Home/About/GetJQGridData',
datatype: 'json',
contentType: 'application/json',
myType: 'GET',
colNames: ['Id', 'Name'],
colModel: [
{ name: 'Id', index: 'Id' },
{ name: 'Name', index: 'Name' }
],
jsonReader: {
root: 'Data',
id: 'id',
repeatitems: false
},
pager: $('#myPager'),
rowNum: 5,
rowList: [2, 5, 10],
width: 600,
viewrecords: true,
caption: 'Jqgrid MVC Tutorial'
});
});
</script>
<table id="myGrid"></table>
<div id="myPager"></div>`
My Controller code is as follows:
HomeController.cs
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult GetJQGridData()
{
var jqGridData = new JQGridObject()
{
Data = GetSomeSampleData(),
Page = "1",
PageSize = 3, // u can change this !
SortColumn = "Name",
SortOrder = "asc"
};
return Json(jqGridData, JsonRequestBehavior.AllowGet);
}
public List<Fruit> GetSomeSampleData()
{
return new List<Fruit>
{
new Fruit{Id = 1, Name = "Apple" },
new Fruit{Id = 2, Name = "Melon" },
new Fruit{Id = 3, Name = "Orange" },
new Fruit{Id = 4, Name = "Grapes" },
new Fruit{Id = 5, Name = "Pineapple" },
new Fruit{Id = 6, Name = "Mango" },
new Fruit{Id = 7, Name = "Bannana" },
new Fruit{Id = 8, Name = "Cherry" }
};
}
Any help would be highly appreciated.
Thanks

First thing that jumps out at me is that your Controller/View is being referenced incorrectly
url: '../../Home/About/GetJQGridData',
should be
url: '/Home/GetJQGridData',
You shouldn't need to set a jsonReader as well on the client.

Related

dojox.grid.DataGrid sort order bug on mixed case strings?

I know Dojo is getting quite old now but we still have apps that are using it.
One thing that was pointed out was the sort facility on the dojox.grid.DataGrid table of users. Our users table has grown over time so it's useful to order by the name column. However, we find that, while most names were entered with a Capital first letter, some names were entered all in lowercase and when I click on the name column header for sorting, I find that the Capitalised names appear in alphabetical order BUT followed by lowercase name in the same order at the bottom.
e.g. The raw data:
Tom
Dick
harry
After "sorting" displays as :
Dick
Tom
harry
Code example, using Dojo 1.8.3, as follows:
require(["dojox/grid/EnhancedGrid",
"dojo/data/ItemFileWriteStore",
"dojo/parser",
"dojo/on",
'dojo/domReady!'
],
function(EnhancedGrid, ItemFileWriteStore, Filter, parser, on) {
var data = {
items: [
{ name: 'Tom', age: 29 },
{ name: 'Dick', age: 9 },
{ name: 'harry', age: 19 }
]
};
var gridStore = new ItemFileWriteStore({
data: data
});
var gridStructure = [
[
{ 'name': 'Name', 'field': 'name' },
{ 'name': 'Age' , 'field': 'age' }
]
];
var mygrid = new EnhancedGrid({
id: "grid",
store: gridStore,
structure: gridStructure,
autoHeight: true,
autoWidth: true
}, "mydatagrid");
mygrid.startup();
}
);
<link href="https://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dojox/grid/enhanced/resources/claro/EnhancedGrid.css" rel="stylesheet" />
<link href="https://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dijit/themes/claro/claro.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dojo/dojo.js"></script>
<div id="container" class="claro">
<div id="mydatagrid"></div>
</div>
How do I sort a column of mixed case names correctly?
i.e. to display sorted grid as:
Dick
harry
Tom
Thanks
I managed to get a solution through a suggestion on a related DataGrid post: dojox.grid.DataGrid custom sort method?
Basically, you can use the "comparatorMap" of the ItemFileWriteStore (or ItemFileReadStore)
require(["dojox/grid/EnhancedGrid",
"dojo/data/ItemFileWriteStore",
"dojo/parser",
"dojo/on",
'dojo/domReady!'
],
function(EnhancedGrid, ItemFileWriteStore, Filter, parser, on) {
var data = {
items: [
{ name: 'Tom', age: 29 },
{ name: 'Dick', age: 9 },
{ name: 'harry', age: 19 }
]
};
var gridStore = new ItemFileWriteStore({
data: data
});
var gridStructure = [
[
{ 'name': 'Name', 'field': 'name' },
{ 'name': 'Age' , 'field': 'age' }
]
];
//====================================================================================
//= Define the comparator function for "Name" ========================================
//====================================================================================
gridStore.comparatorMap = {};
gridStore.comparatorMap["name"] = function(a,b) {
var nameA = a.toLowerCase().trim(), nameB = b.toLowerCase().trim();
if (nameA < nameB) //sort string ascending
return -1;
if (nameA > nameB)
return 1;
return 0; //default return value (no sorting)
}
//====================================================================================
//====================================================================================
//====================================================================================
var mygrid = new EnhancedGrid({
id: "grid",
store: gridStore,
structure: gridStructure,
autoHeight: true,
autoWidth: true
}, "mydatagrid");
mygrid.startup();
}
);
<link href="https://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dojox/grid/enhanced/resources/claro/EnhancedGrid.css" rel="stylesheet" />
<link href="https://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dijit/themes/claro/claro.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dojo/dojo.js"></script>
<div id="container" class="claro">
<div id="mydatagrid"></div>
</div>

Dojo Select onchange not firing on creating Select box programmatically

I have two dojo select dropdowns. First dropdown is populated on page load and on selecting a value from first drop down, second select box should be populated.
I create the second select box programatically and i destroy it for every on change event of the first dropdown box.( this is to avoid widget already registered error).
But when i select any of the option from second drop down select, it does not fire onchange event.
Pls help on this.
My code is
require(["dojo/parser","dijit/form/RadioButton","dojo/ready","dojo/data/ItemFileReadStore","dijit/registry","dijit/form/Select","dojo/ready","dojo/dom-form", "dojo/dom", "dojo/on", "dojo/request","dojo/domReady"],
function(parser,RadioButton,ready,ItemFileReadStore,registry,Select,ready,Form,dom,on,request){
parser.parse();
var manuData;
var modelData;
var shaftType;
var modelId;
var clubMfr;
var clubType;
var manufacturerList;
dojo.connect(dijit.byId("clubtype"),"onChange",function(event){
clubType=registry.byId("clubtype").get('value');
console.log(clubType);
var id= registry.byId("clubtype");
var option1= registry.byId("manufacturer");
request("/tradeIn/"+clubType).then(function(list){
manuData=list;
var data1 = dojo.fromJson(manuData);
var readstore=new ItemFileReadStore({ data:{
identifier : "manufacturer",
label: "manufacturer",
items : data1,
}});
if(typeof registry.byId("manufacturerId") != "undefined"){
registry.byId("manufacturerId").destroyRecursive();
}
manufacturerList=new Select({
name:"manufacturerId",
id:"manufacturerId",
store:readstore,
onSetStore: function() {
this.options.unshift({selected:'true',label:'Choose One', value:'NULL'});
this._loadChildren();
}
}).placeAt("manuList");
manufacturerList.startup();
});
}
);
dojo.connect(
dijit.byId("manufacturerId"),"onChange",function(event){
var manufacturerId=registry.byId("manufacturerId").get('value');
clubMfr=manufacturerId;
var model= registry.byId("model");
model.removeOption(dijit.byId("model").getOptions());
request("/tradeIn/"+manufacturerId+"/"+clubType).then(function(list){
modelData=list;
var data1 = dojo.fromJson(modelData);
var readstore=new ItemFileReadStore({ data:{
identifier : "model",
label: "model",
items : data1
}});
if(typeof registry.byId("modelId") != "undefined"){
registry.byId("modelId").destroyRecursive();
}
var modelList=new Select({
name:"modelId",
id:"modelId",
store:readstore,
onSetStore: function() {
this.options.unshift({selected:'true',label:'Choose One', value:'NULL'});
this._loadChildren();
}
}).placeAt("modelList");
modelList.startup();
});
}
);
dojo.connect(
dijit.byId("model"),"onChange",function(event){
modelId=registry.byId("model").get('value');
console.log("model "+modelId);
}
);
});
You need to disconnect the onChange event before destroying the select and to reconnect it after creating the select. To achieve the disconnection, you can use own() method.
Here is how it should look like:
if(typeof registry.byId("manufacturerId") != "undefined"){
registry.byId("manufacturerId").destroyRecursive();
}
manufacturerList=new Select({/* ... */});
manufacturerList.own(dojo.connect(
dijit.byId("manufacturerId"),"onChange",function(event){ /* ... */ }
));
Note: This is extremely dirty. The proper approach would be to NOT destroy the second select and instead to update its data.
See the snippets for updating it:
require(['dijit/form/Select', 'dojo/data/ItemFileReadStore', 'dojo/domReady!'], function(Select, ItemFileReadStore) {
var initialStoreData = [
{value: "AL", label: "Alabama"},
{value: "AK", label: "Alaska"},
{value: "AZ", label: "Arizona"}
];
var changedStoreData = [
{value: "CA", label: "California"},
{value: "CO", label: "Colorado"},
{value: "CT", label: "Connecticut"}
];
var prepareData = function(storeData) {
//because the store return sorted data, I have added a space before the word 'Choose'. So it comes first
return [{value: '', label: ' Choose one'}].concat(storeData);
}
var readStore=new ItemFileReadStore({
data:{
identifier: "value",
label: "label",
items: prepareData(initialStoreData)
}
});
var selectWidget = new Select({
store: readStore
});
selectWidget.placeAt(document.getElementById('test'));
selectWidget.startup();
btn.onclick = function() {
var newReadStore=new ItemFileReadStore({
data:{
identifier: "value",
label: "label",
items: prepareData(changedStoreData)
}
});
selectWidget.set('store', newReadStore);
}
});
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/resources/dojo.css">
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/tundra/tundra.css">
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/form/resources/CheckedMultiSelect.css">
<div id="test" class="tundra">
<button id="btn">change data in select</button>
</div>

Add PercentDoneByStoryPoint to HTML DIV

In the 1.x version of the Rally SDK I was able to query and assign to an HTML DIV with a query like the following:
var querySI48 = {
type : 'portfolioitem',
query:'(Name = "Q3 2015 Release (2.8.0)")',
key : 'SI48Key',
fetch: 'PercentDoneByStoryCount'
};
And assign it to a DIV like this:
var WS215 = document.getElementById("WS215");
WS215.innerHTML = "<h2>" + pisInfo + "%</h2>";
How can I assign the PercentDoneByStoryPoint to a DIV with the 2.X SDK? I'm creating a dashboard in Confluence that contains Rally data.
Something similar to the following should do the trick:
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script type="text/javascript" src="/apps/2.0/sdk.js"></script>
<script type="text/javascript">
Rally.onReady(function() {
Ext.define('Rally.example.App', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
var me = this;
var divTemplateString = "<h2>{0}: Percent Done by Story Count = {1}</h2>";
Ext.create('Rally.data.wsapi.Store', {
model: 'PortfolioItem/Feature',
fetch: true,
autoLoad: true,
filters: [
{
property: 'FormattedID',
value: 'F15'
}
],
listeners: {
load: function(store, data, success) {
var formattedID = data[0].get('FormattedID');
var pctDoneByStoryCount = data[0].get('PercentDoneByStoryCount');
var divHTML = Ext.String.format(divTemplateString, formattedID, pctDoneByStoryCount);
var div = Ext.get('F15');
me.add({
xtype: 'container',
html: divHTML,
renderTo: div
});
}
},
});
}
});
Rally.launchApp('Rally.example.App', {
name: 'Example'
});
});
</script>
<style type="text/css">
</style>
</head>
<body>
<div id="F15"</div>
</body>
</html>

Datatables Single Column Filter

I read api doc and find individual column searching to filter data by column row, great but i just need add one dropdown filter by name on top (beside number filter)
Current setup (use tabletool and bootstrap)
$('table').DataTable({
'aLengthMenu': [[25, 50, 75, -1], [25, 50, 75, 'All']],
'iDisplayLength': 25,
'stateSave': true,
'oLanguage': {
'sLengthMenu': 'Show : _MENU_',
'sSearch': 'Search : _INPUT_',
},
'oTableTools': {
'sSwfPath': 'media/swf/copy_csv_xls_pdf.swf'
},
/*
'order': [[ 1, 'asc' ]],
'aoColumnDefs': [
{
'bSortable': false,
'aTargets': [ -1, 0 ]
}
]
*/
});
If you are using Datatables Version 1.10 and upwards you want to use the DOM option to position a div in the header where you want to add your filter and add your select to it.
var table;
$(document).ready(function () {
table = $('#example').dataTable({
"dom": "l<'#myFilter'>frtip"
});
var myFilter = '<select id="mySelect">'
+ '<option value="1">Searchval 1</option>'
+ '<option value="2">Searchval 2</option>'
+ '<option value="3">Searchval 3</option>'
+ '</select>';
$("#myFilter").html(myFilter);
table.fnDraw();
});
Then add a custom filter function.
$.fn.dataTable.ext.search.push(
function (settings, data) {
//your filter stuff belongs here
return true;
});
And redraw the table everytime you change your filter.
$("body").on("change", "#mySelect", function () {
table.fnDraw();
});
See this JSFiddle for an example of what more or less should fit your requirements.
That idea is implemented in this DataTables plug-in, you may check out working DEMO:
$(document).ready(function () {
//Source data definition
var tableData = [
{item: 'banana', category: 'fruit', color: 'yellow'},
{item: 'pear', category: 'fruit', color: 'green'},
{item: 'cabbage', category: 'vegie', color: 'green'},
{item: 'carrot', category: 'vegie', color: 'red'},
{item: 'apple', category: 'fruit', color: 'red'},
{item: 'kiwi', category: 'fruit', color: 'brown'}
];
//DataTable definition
window.dataTable = $('#mytable').DataTable({
sDom: 'tF',
data: tableData,
columns: [{
data: 'item',
title: 'Item'
}, {
data: 'category',
title: 'Category'
}, {
data: 'color',
title: 'Color'
}]
});
});
<!doctype html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.mfilter.tk/js/mfilter.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.mfilter.tk/css/mfilter.min.css">
</head>
<body>
<table id="mytable"></table>
</body>
</html>

My extjs grid is not showing in new archictecture

I am using the architecture for my extjs app is from this blog post
http://blog.extjs.eu/know-how/writing-a-big-application-in-ext/
So here is my index.html Please read the whole question for complete answer.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Reseller DashBoard</title>
<!-- ** CSS ** -->
<!-- base library -->
<link rel="stylesheet" type="text/css" href="./ext/resources/css/ext-all.css" />
<link rel="stylesheet" type="text/css" href="./ext/resources/css/xtheme-gray.css" />
<!-- overrides to base library -->
<!-- ** Javascript ** -->
<!-- ExtJS library: base/adapter -->
<script type="text/javascript" src="./ext/adapter/ext/ext-base-debug.js"></script>
<!-- ExtJS library: all widgets -->
<script type="text/javascript" src="./ext/ext-all-debug.js"></script>
<!-- overrides to base library -->
<!-- page specific -->
<script type="text/javascript" src="application.js"></script>
<script type="text/javascript" src="js/Application.dashboard.js"></script>
<script type="text/javascript" src="js/jsfunction.js"></script>
<script type="text/javascript" src="js/reseller.js"></script>
</head>
<body>
<div id="dashboard">
</div>
</body>
</html>
Here is my application.js I am intialising here my dashboard grid, is it the right place to initialise ?
/*global Ext, Application */
Ext.BLANK_IMAGE_URL = './ext/resources/images/default/s.gif';
Ext.ns('Application');
// application main entry point
Ext.onReady(function() {
Ext.QuickTips.init();
var pg = new Application.DashBoardGrid();
// or using it's xtype
var win = new Ext.Window({
items:{xtype:'DashBoardGrid'}
});
// code here
}); // eo function onReady
// eof
Here is my Application.DashBoardGrid.js
My request to the api is going two times right now Why ?
I have a linkrenderer function for a column for rendering where should i put this function?
And Suggest Why My Grid is not Coming ?
Application.DashBoardGrid = Ext.extend(Ext.grid.GridPanel, {
border:false
,initComponent:function() {
var config = {
store:new Ext.data.JsonStore({
// store configs
autoDestroy: true,
autoLoad :true,
url: 'api/index.php?_command=getresellerscount',
storeId: 'getresellerscount',
// reader configs
root: 'cityarray',
idProperty: 'cityname',
fields: [
{name: 'cityname'},
{name: 'totfollowup'},
{name: 'totcallback'},
{name: 'totnotintrested'},
{name: 'totdealsclosed'},
{name: 'totcallsreceived'},
{name: 'totcallsentered'},
{name: 'totresellerregistered'},
{name: 'countiro'},
{name: 'irotransferred'},
{name: 'irodeferred'}
]
})
,columns: [
{
id :'cityname',
header : 'City Name',
width : 120,
sortable : true,
dataIndex: 'cityname'
},
{
id :'countiro',
header : ' Total Prospect',
width : 100,
sortable : true,
dataIndex: 'countiro'
},
{
id :'irotransferred',
header : 'Calls Transfered By IRO',
height : 50,
width : 100,
sortable : true,
dataIndex: 'irotransferred'
},
{
id :'irodeferred',
header : ' Calls Deferred By IRO',
width : 100,
sortable : true,
dataIndex: 'irodeferred'
},
{
id :'totcallsentered',
header : ' Total Calls Entered',
width : 100,
sortable : true,
dataIndex : 'totcallsentered'//,
//renderer : linkRenderer
},
{
id :'totfollowup',
header : ' Follow Up',
width : 100,
sortable : true,
dataIndex: 'totfollowup'
},
{
id :'totcallback',
header : ' Call Backs',
width : 100,
sortable : true,
dataIndex: 'totcallback'
},
{
id :'totnotintrested',
header : ' Not Interested',
width : 100,
sortable : true,
dataIndex: 'totnotintrested'
},
{
id :'totdealsclosed',
header : ' Deals Closed',
width : 100,
sortable : true,
dataIndex: 'totdealsclosed'
},
{
id :'totresellerregistered',
header : ' Reseller Registered',
width : 100,
sortable : true,
dataIndex: 'totresellerregistered'
}
]
,plugins:[]
,viewConfig:{forceFit:true}
,tbar:[]
,bbar:[]
,render:'dashboard'
,height: 350
,width: 1060
,title: 'Reseller Dashboard'
}; // eo config object
// apply config
Ext.apply(this, Ext.apply(this.initialConfig, config));
Application.DashBoardGrid.superclass.initComponent.apply(this, arguments);
} // eo function initComponent
,onRender:function() {
// this.store.load();
Application.DashBoardGrid.superclass.onRender.apply(this, arguments);
} // eo function onRender
});
Ext.reg('DashBoardGrid', Application.DashBoardGrid);
Json Response
{
"countothercities": "0",
"directreseller": "14",
"totalresellersregisteredfor8cities": 33,
"cityarray": [{
"cityname": "bangalore",
"totfollowup": "3",
"totcallback": "4",
"totnotintrested": "2",
"totdealsclosed": "0",
"totcallsreceived": "0",
"totcallsentered": "68",
"totresellerregistered": "6",
"countiro": "109",
"irotransferred": "83",
"irodeferred": "26"
}]
}
Please show your JSON response, or server code. So that we can answer better.
My request to the api is going two times right now Why ?
Obvious. Inside Ext.onReady()
You are creating instance of DashboardGrid. Call 1
You are asking Ext to create instance of DashboardGrid by passing xtype. Call 2
You are creating the grid twice. Do this instead.
Ext.onReady(function() {
Ext.QuickTips.init();
var win = new Ext.Window({
items:{xtype:'DashBoardGrid'}
});
// code here
}); // eo function onReady