jqGrid url not getting called with server side paging & sorting & postData: Form.searialize() in MVC 4 - asp.net-mvc-4

I am implementing server side paging & sorting for jqGrid in MVC 4. I am passing view model object as postData to jqGrid url action method. have a look at grid definition.
var isGridDefined = false;
$(document).ready(function () {
function DefineGrid(Year, Month) {
var mygrid = $("#RptUpload");
mygrid.jqGrid({
loadonce: false,
async: false,
datatype: 'json',
postData: { bReload: true, Year: Year, Month: Month },
url: '#Url.Action("DMEUploadDetailsList", "Reports")',
jsonReader: { repeatitems: false, root: "DataRows" },
colNames: ['#VirtuOxAdmin.DMEUploadDetails_Grid_RptUpload_OrderID',
'#VirtuOxAdmin.DMEUploadDetails_Grid_RptUpload_CompanyName',
'#VirtuOxAdmin.DMEUploadDetails_Grid_RptUpload_PatientID',
'#VirtuOxAdmin.DMEUploadDetails_Grid_RptUpload_PatientName',
"#VirtuOxAdmin.DMEUploadDetails_Grid_RptUpload_DOB",
'#VirtuOxAdmin.DMEUploadDetails_Grid_RptUpload_Insurance',
"#VirtuOxAdmin.DMEUploadDetails_Grid_RptUpload_UploadDate"
],
colModel: [
{ name: 'ReadingID', index: 'ReadingID', width: 55, fixed: true, sorttype: 'integer', align: 'center' },
{
name: 'CompanyName', index: 'CompanyName', align: 'center', width: 200,
cellattr: function (rowId, tv, rawObject, cm, rdata) { return 'style="white-space: normal!important;' },
},
{ name: 'PatientID', index: 'PatientID', width: 55, fixed: true, sorttype: 'integer', align: 'center' },
{
name: 'PatientName', index: 'PatientName', align: 'center', width: 200,
cellattr: function (rowId, tv, rawObject, cm, rdata) { return 'style="white-space: normal!important;' },
},
{
name: 'DOB', index: 'DOB', width: 80, fixed: true, sorttype: 'date', formatter: 'date', formatoptions: { srcformat: 'm/d/Y', newformat: 'm/d/Y' },
align: 'center'
},
{ name: 'InsuranceType', index: 'InsuranceType', align: 'center', width: 150, cellattr: function (rowId, tv, rawObject, cm, rdata) { return 'style="white-space: normal!important;' }, },
{
name: 'UploadDate', index: 'UploadDate', width: 80, fixed: true, sorttype: 'date', formatter: 'date', formatoptions: { srcformat: 'm/d/Y', newformat: 'm/d/Y' },
align: 'center'
}
],
rowNum: 20,
rowList: [20, 50, 100, 200],
pager: '#UploadPager',
caption: '#VirtuOxAdmin.DMEUploadDetails_Grid_RptUpload_Title',
viewrecords: true,
height: 'auto',
width: 770,
hidegrid: false,
shrinkToFit: true,
scrollOffset: 0,
headertitles: true,
loadError: function (xhr, status, error) {
alert(status + " " + error);
},
//onPaging: function (pgButton) {
// $("#RptUpload").jqGrid("setGridParam", { postData: { bReload: false } });
//},
loadCompete: function () {
$("#RptUpload").jqGrid("setGridParam", { datatype: 'json', postData: { bReload: false } });
}
});
mygrid.navGrid('#UploadPager', { edit: false, add: false, del: false, search: false, refresh: false });
isGridDefined = true;
}
$("#rptRefresh").click(function (e) {
e.preventDefault();
var Form = $("form[id='FrmDMEUploadDetails']");
Form.validate();
if (Form.valid()) {
RemoveValidatioMessages();
$("#gridContainer").show();
var Year = $("#Year").val();
var Month = $("#Month").val();
if (!isGridDefined)
DefineGrid(Year, Month);
else
$("#RptUpload").jqGrid("setGridParam", { datatype: "json", page: 1, postData: { bReload: true, Year: Year, Month: Month } }).trigger("reloadGrid");
}
else {
$("#RptUpload").clearGridData();
$("#gridContainer").hide();
}
$(".chzn-select-deselect").trigger("liszt:updated");
return false;
});
});
& my action method is as follows
public ActionResult DMEUploadDetailsList(bool bReload, string Year, string Month, string nd, int rows, int page, string sidx, string sord, string filters)
{
DataSet SearchResult = null;
List<ReportData> ResultRows = new List<ReportData>();
JQGridResult Result = new JQGridResult();
if (bReload)
{
SearchResult = DB.ExecuteDataset("ConnectionString", "pc_GetUploadDetail",
new SqlParameter("#Year", Year),
new SqlParameter("#Month", Month));
Common.SetSession(SearchResult, null, "DMEUploadByMonth");
}
else
SearchResult = SessionManager.GetSession().GetAttribute("DMEUploadByMonth") as DataSet;
if (SearchResult != null)
{
DataTable dtSearchResult = SearchResult.Tables[0];
# region Handle server side Filtering, sorting and paging
int totalRecords = dtSearchResult.Rows.Count; //before paging
int totalPages = (int)Math.Ceiling((decimal)totalRecords / (decimal)rows); //--- number of pages
int startIndex = ((page > 0 ? page - 1 : 0) * rows);
if (sidx != "")
{
dtSearchResult.DefaultView.Sort = sidx + " " + sord;
dtSearchResult = dtSearchResult.DefaultView.ToTable();
}
# endregion
for (int i = startIndex; i < dtSearchResult.Rows.Count; i++)
{
ResultRows.Add(new ReportData()
{
ReadingID = Convert.ToInt32(dtSearchResult.Rows[i][0]),
CompanyName = Convert.ToString(dtSearchResult.Rows[i][1]),
PatientID = Convert.ToInt32(dtSearchResult.Rows[i][2]),
PatientName = Convert.ToString(dtSearchResult.Rows[i][3]),
DOB = (dtSearchResult.Rows[i][4] != DBNull.Value ? Convert.ToDateTime(dtSearchResult.Rows[i][4]) : (DateTime?)null),
InsuranceType = Convert.ToString(dtSearchResult.Rows[i][5]),
UploadDate = (dtSearchResult.Rows[i][6] != DBNull.Value ? Convert.ToDateTime(dtSearchResult.Rows[i][6]) : (DateTime?)null)
});
if (ResultRows.Count == rows) break;
}
Result.DataRows = ResultRows;
Result.page = page;
Result.total = totalPages;
Result.records = totalRecords;
}
return Json(Result, JsonRequestBehavior.AllowGet);
}
The problem with current implementation is that my action method DMEUploadDetailsList is not getting called though view model object is getting passed to request successfuly.
& This implementation were working fine when used client side paging & sorting.
Please suggest me If I am missing anything or correct my mistakes to get server side paging & sorting working.
This grid is defined or reloaded on refresh button. Now what I want is to identify whether action method is called on refresh button click or paging & sorting operation?
[ Now I would like to describe the last two sentence of problem statement. It specifies that when my page is loaded grid is not defined. As soon as I select filter & clicks refresh button my grid is defined for first time & reloaded for subsequent clicks of refresh. If you go through the action method code you will see that i am trying to use bReload bit variable for, when it is true [in case of refresh button click] I would like to query data from SQL otherwise from dataset stored in session [in case of paging or sorting request]. Now If you looked at the postData parameter in definition or in reload call I am passing breload as true. Where as I am not aware of how can I override this parameter to false when user request for sorting & paging. Or else if there is any another simple way with which in action method I can get whether this request is of load data or paging & sorting.]

Sorry, but I don't see any implementation of paging in your code. You calculate the number of records which need be skipped and save it in startIndex, but you don't use startIndex later. Your current code just get data from DataTable and returns all items of the table. You need to skip startIndex items. For example you can start for loop from i = startIndex instead of i = 0.
In general it would be more effective to construct SELECT statement in SqlCommand which uses TOP construct or use STORED PROCEDURE like described in the answer (see another answer too). In the way your server code will get from the SQL server only one page of data instead of fetching all records of data and returning only one page.
UPDATED: I would rewrite your client code to something like the following
$(document).ready(function () {
var templateDate = {
width: 80,
fixed: true,
sorttype: "date",
formatter: "date",
formatoptions: { srcformat: "m/d/Y", newformat: "m/d/Y" }
},
templateInt = { width: 55, fixed: true, sorttype: "integer" },
templateText = {
width: 200,
cellattr: function () {
return 'style="white-space: normal!important;'
}
},
mygrid = $("#RptUpload");
// create the grid without filling it (datatype: "local")
mygrid.jqGrid({
datatype: "local", // to revent initial loading of the grid
postData: {
bReload: true,
Year: function () { return $("#Year").val(); },
Month: function () { return $("#Month").val(); }
},
url: '#Url.Action("DMEUploadDetailsList", "Reports")',
jsonReader: { repeatitems: false, root: "DataRows" },
colNames: [ "#VirtuOxAdmin.DMEUploadDetails_Grid_RptUpload_OrderID",
"#VirtuOxAdmin.DMEUploadDetails_Grid_RptUpload_CompanyName",
"#VirtuOxAdmin.DMEUploadDetails_Grid_RptUpload_PatientID",
"#VirtuOxAdmin.DMEUploadDetails_Grid_RptUpload_PatientName",
"#VirtuOxAdmin.DMEUploadDetails_Grid_RptUpload_DOB",
"#VirtuOxAdmin.DMEUploadDetails_Grid_RptUpload_Insurance",
"#VirtuOxAdmin.DMEUploadDetails_Grid_RptUpload_UploadDate"
],
colModel: [
{ name: "ReadingID", template: templateInt },
{ name: "CompanyName", template: templateText },
{ name: "PatientID", template: templateInt },
{ name: "PatientName", template: templateText },
{ name: "DOB", template: templateDate },
{ name: "InsuranceType", width: 150, template: templateText },
{ name: "UploadDate", template: templateDate }
],
cmTemplate: { align: "center" },
rowNum: 20,
rowList: [20, 50, 100, 200],
pager: "#UploadPager",
caption: "#VirtuOxAdmin.DMEUploadDetails_Grid_RptUpload_Title",
viewrecords: true,
height: "auto",
width: 770,
hidegrid: false,
headertitles: true,
loadError: function (xhr, status, error) {
alert(status + " " + error);
}
});
mygrid.navGrid("#UploadPager",
{ edit: false, add: false, del: false, search: false, refresh: false });
mygrid.closest(".ui-jqgrid").hide(); // hide the grid
$("#rptRefresh").click(function (e) {
var Form = $("form[id=FrmDMEUploadDetails]");
e.preventDefault();
Form.validate();
if (Form.valid()) {
RemoveValidatioMessages();
mygrid.jqGrid("setGridParam", { datatype: "json" })
.trigger("reloadGrid", [{page: 1}])
.closest(".ui-jqgrid").show(); // show the grid;
} else {
mygrid.clearGridData();
mygrid.closest(".ui-jqgrid").hide(); // hide the grid
}
$(".chzn-select-deselect").trigger("liszt:updated");
return false;
});
});
The grid will be created with datatype: "local", so the url and postData will be ignored. After that it seems to me the usage of bReload property in postData and on the server side seems me unneeded. Nevertheless I included bReload still in the JavaScript code till you remove it from the server code.
Additionally I simplified the colModel by usage of column templates (cmTemplate option of jqGrid and template property of colModel). See the old answer for more information. I removed also some unneeded options of jqGrid which values are default (see "Default" column in the documentation of options).
About usage of new versions of STORED PROCEDURE (pc_GetUploadDetail in your code) you can consider to introduction new version (like pc_GetUploadDetailPaged) which supports more parameters. It will not break existing code which uses the old procedure, but you can still use sorting and paging of data on SQL Server instead of getting all query results to web server and implementing sorting and paging in C#.

I solved my initial problem of jqGrid url not getting called by removing Form.serialize() as postData parameter in jqGrid definition & reload calles. This problem was not related to server side sorting & paging. This was caused due to my previous postData parameter definition as Form.serialize(). Instead I used pass individual parameters to the postData array.
My next problem was related to sorting & paging at server side. In which I want to fetch data from session dataset when user page through the grid or want to sort the grid data; otherwise reload new data by querying SQL server.
According to Oleg answer I must have adopted the simplified way of doing paging & sorting at SQL end instead of in c#. But I was not allowed to add new version of stored procedure as per Oleg suggestion. So I stick to use extra parameter in postData array named operCode like this in grid definition.
postData: {
operCode: "Reload",
Year: function () { return $("#Year").val(); },
InsuranceID: function () { return $("#InsuranceType").val(); },
CustomerID: function () { return $("#CompanyName").val(); }
},
Now I added onPaging & onSortCol event to override operCode postData parameter value like this
onPaging: function (pgButton) {
mygrid.jqGrid("setGridParam", { datatype: 'json', postData: { operCode: "Paging" } });
},
onSortCol: function (index, iCol, sortorder) {
mygrid.jqGrid("setGridParam", { datatype: 'json', postData: { operCode: "Sorting" } });
}
Now whenever user clicks refresh button operCode is sent as Reload, on paging as "Paging" & on sorting as "Sorting"
My server side action method code is as follows
public ActionResult DMEUploadDetails(string operCode, string Year, string Month, string nd, int rows, int page, string sidx, string sord, string filters)
{
DataSet SearchResult = null;
List<ReportData> ResultRows = new List<ReportData>();
JQGridResult Result = new JQGridResult();
if (operCode == "Reload")
{
SearchResult = DB.ExecuteDataset("ConnectionString", "pc_GetUploadDetail",
new SqlParameter("#Year", Year),
new SqlParameter("#Month", Month));
Common.SetSession(SearchResult, null, "POXMonthlyUploads");
}
else
SearchResult = (SessionManager.GetSession().GetAttribute("POXMonthlyUploads") as System.Web.UI.WebControls.GridView).DataSource as DataSet;
if (SearchResult != null)
{
DataTable dtSearchResult = SearchResult.Tables[0];
# region Handle server side Filtering, sorting and paging
int totalRecords = dtSearchResult.Rows.Count; //before paging
int totalPages = (int)Math.Ceiling((decimal)totalRecords / (decimal)rows); //--- number of pages
int startIndex = ((page > 0 ? page - 1 : 0) * rows);
if (sidx != "" && operCode == "Sorting")
{
dtSearchResult.DefaultView.Sort = sidx + " " + sord;
dtSearchResult = dtSearchResult.DefaultView.ToTable();
SearchResult.Tables.RemoveAt(0);
SearchResult.Tables.Add(dtSearchResult);
Common.SetSession(SearchResult, null, "POXMonthlyUploads");
}
# endregion
for (int i = startIndex; i < dtSearchResult.Rows.Count; i++)
{
ResultRows.Add(new ReportData()
{
//code to fill data to structure object
});
if (ResultRows.Count == rows) break;
}
Result.DataRows = ResultRows;
Result.page = page;
Result.total = totalPages;
Result.records = totalRecords;
}
return Json(Result, JsonRequestBehavior.AllowGet);
}
Very much Thanks to Oleg for giving me some extra knowledge about jqGrid & giving me good idea about server side paging & sorting.

Related

How to change the columns collection set of a kendo TreeList dynamically?

Try to change the columns list dynamically via a query ...
When I construct the TreeList, I call for columns :
$("#treelist").kendoTreeList({
columns: AnalyseCenterSKUService.getKPIColumnList($scope)
If I return a simple array with the fields, it's working ..
If I call a $http.get (inside my getKPIColumnList(..) function) which add some columns to the existing array of columns, the TreeList is not constructed correctly.
Any suggestion will be really appreciated ! :)
EDIT 22-10-2019 09:00
Treelist init
$("#treelist").kendoTreeList({
columns: AnalyseCenterSKUService.getKPIColumnList($scope),
scrollable: true,
columnMenu : {
columns : true
},
height: "100%",
dataBound: function (e) {
ExpandAll();
},
dataSource: {
schema: {
model: {
id: "id",
parentId: "parentId",
fields: {
id: { type: "number" },
parentId: { type: "number", nullable: true },
fields: {
id: { type: "number" },
parentId: { type: "number", nullable: false }
}
}
}
},
transport: {
read: {
url: "/api/AnalyseCenter/GetWorkOrderTree/0",
dataType: "json"
}
}
}
The getKPIColumnList return an static array + some push with dynamic columns (from DB)
angular.module('AnalyseCenterDirectives')
.service ('AnalyseCenterSKUService', function ($http) {
var toReturn = [ {field: "Name", title: "Hiérachie SKU", width: "30%" }, ..., ..., .... ];
I try in this function to push DB result
return $http.get("/api/AnalyseCenter/GetWorkOrderHistorianAdditonalColumns?equipmentName=" + equipmentName)
.then(function (result) {
var data = result.data;
if (data && data !== 'undefined') {
var fromDB = data;
angular.forEach(fromDB, function (tag) {
var tagName = tag.replace(".","_");
toReturn.push({
field: tagName, title: tag, width: '10%',
attributes: { style: "text-align:right;"} })
})
The stored procedure GetWorkOrderHistorianAdditonalColumns returns a list of string (future column)
That is because ajax is async, that means your tree list is being initialized before the request finishes. A classic question for JavaScript newcomers. I suggest you take a while to read about ajax, like How does AJAX works for instance.
Back to your problem. You need to create your tree list inside the success callback(I can't give you a more complete solution since I don't know what you're doing inside your function or which framework you're using to open that ajax request) with the result data, which is probably your columns. Then it would work as if you're initializing it with arrays.

Using a custom Drop Down List field to set a value in a grid

I'm trying to use the Rally 2.1 SDK to set a custom data field (c_wsjf) in a grid. I have a custom drop down list that I want to check the value of (c_TimeCrticalitySizing).
I created c_TimeCrticalitySizing as a feature card field in my Rally workspace with different string values (such as "No decay"). Every drop down list value will set the custom field to a different integer. When I try to run the app in Rally I get this error:
"Uncaught TypeError: Cannot read property 'isModel' of undefined(…)"
I'm thinking the drop down list value may not be a string.
How would I check what the type of the drop down list value is?
How could I rewrite this code to correctly check the value of the drop down list so I can set my custom field to different integers?
Here's my code block for the complete app. I'm still trying to hook up a search bar so for now I directly call _onDataLoaded() from the launch() function.
// START OF APP CODE
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
featureStore: undefined,
featureGrid: undefined,
items: [ // pre-define the general layout of the app; the skeleton (ie. header, content, footer)
{
xtype: 'container', // this container lets us control the layout of the pulldowns; they'll be added below
itemId: 'widget-container',
layout: {
type: 'hbox', // 'horizontal' layout
align: 'stretch'
}
}
],
// Entry point of the app
launch: function() {
var me = this;
me._onDataLoaded();
},
_loadSearchBar: function() {
console.log('in loadsearchbar');
var me = this;
var searchComboBox = Ext.create('Rally.ui.combobox.SearchComboBox', {
itemId: 'search-combobox',
storeConfig: {
model: 'PortfolioItem/Feature'
},
listeners: {
ready: me._onDataLoaded,
select: me._onDataLoaded,
scope: me
}
});
// using 'me' here would add the combo box to the app, not the widget container
this.down('#widget-container').add(searchComboBox); // add the search field to the widget container <this>
},
// If adding more filters to the grid later, add them here
_getFilters: function(searchValue){
var searchFilter = Ext.create('Rally.data.wsapi.Filter', {
property: 'Search',
operation: '=',
value: searchValue
});
return searchFilter;
},
// Sets values once data from store is retrieved
_onDataLoaded: function() {
console.log('in ondataloaded');
var me = this;
// look up what the user input was from the search box
console.log("combobox: ", this.down('#search-combobox'));
//var typedSearch = this.down('#search-combobox').getRecord().get('_ref');
// search filter to apply
//var myFilters = this._getFilters(typedSearch);
// if the store exists, load new data
if (me.featureStore) {
//me.featureStore.setFilter(myFilters);
me.featureStore.load();
}
// if not, create it
else {
me.featureStore = Ext.create('Rally.data.wsapi.Store', {
model: 'PortfolioItem/Feature',
autoLoad: true,
listeners: {
load: me._createGrid,
scope: me
},
fetch: ['FormattedID', 'Name', 'TimeCriticality',
'RROEValue', 'UserBusinessValue', 'JobSize', 'c_TimeCriticalitySizing']
});
}
},
// create a grid with a custom store
_createGrid: function(store, data){
var me = this;
var records = _.map(data, function(record) {
//Calculations, etc.
console.log(record.get('c_TimeCriticalitySizing'));
var timecritsize = record.get('c_TimeCriticalitySizing');
//console.log(typeof timecritsize);
var mystr = "No decay";
var jobsize = record.get('JobSize');
var rroe = record.get('RROEValue');
var userval = record.get('UserBusinessValue');
var timecrit = record.get('TimeCriticality');
// Check that demoniator is not 0
if ( record.get('JobSize') > 0){
if (timecritsize === mystr){
var priorityScore = (timecrit + userval + rroe) / jobsize;
return Ext.apply({
c_wsjf: Math.round(priorityScore * 10) / 10
}, record.getData());
}
}
else{
return Ext.apply({
c_wsjf: 0
}, record.getData());
}
});
// Add the grid
me.add({
xtype: 'rallygrid',
showPagingToolbar: true,
showRowActionsColumn: true,
enableEditing: true,
store: Ext.create('Rally.data.custom.Store', {
data: records
}),
// Configure each column
columnCfgs: [
{
xtype: 'templatecolumn',
text: 'ID',
dataIndex: 'FormattedID',
width: 100,
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate')
},
{
text: 'WSJF Score',
dataIndex: 'c_wsjf',
width: 150
},
{
text: 'Name',
dataIndex: 'Name',
flex: 1,
width: 100
}
]
});
}
});
// END OF APP CODE
The app works great until I add the if (timecritsize === mystr) conditional.
I also use console.log() to check that I've set all values for timecritsize to "No decay"

implementing jTable MVC 4

I have following
****** controller ***********
namespace DLM.Controllers{
public class BooksController : Controller
{
private IRepositoryContainer _repository;
//
// GET: /Books/
public ActionResult Index()
{
return View();
}
[HttpPost]
public JsonResult ListBooks(int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = null)
{
try
{
//Get data from database
int bookCount = _repository.BookRepository.GetBooksCount();
List<Books> book = _repository.BookRepository.GetBooks(jtStartIndex, jtPageSize, jtSorting);
//Return result to jTable
return Json(new { Result = "OK", Records = book, TotalRecordCount = bookCount });
}
catch (Exception ex)
{
return Json(new { Result = "ERROR", Message = ex.Message });
}
}
***** ListBooks View ************
{
#Styles.Render("~/Scripts/jtable/jtable.2.3.0/themes/metro/darkgray/jtable.min.css")
<script src="/Scripts/jtable/jtable.2.3.0/jquery.jtable.min.js" type="text/javascript"></script>
<div id="BookTableContainer"></div>
<script type="text/javascript">
$(document).ready(function () {
$('#BookTableContainer').jtable({
title: 'The Student List',
paging: true, //Enable paging
pageSize: 10, //Set page size (default: 10)
sorting: true, //Enable sorting
defaultSorting: 'Book Title ASC', //Set default sorting
actions: {
listAction: '/Books/Index',
deleteAction: '/Books/DeleteBook',
updateAction: '/Books/UpdateBook',
createAction: '/Books/AddBook'
},
fields: {
BooksID: {
key: true,
create: false,
edit: false,
list: false
},
Code_No: {
title: 'Book Code',
width: '23%'
},
Title: {
title: 'Book Title',
list: false
},
Author: {
title: 'Author',
list: false
},
Page_No: {
title: 'Number of Pages',
width: '13%'
},
Y_of_P: {
title: 'Year of Publication',
width: '12%'
},
Language: {
title: 'Language',
width: '15%'
},
Subject: {
title: 'Subject',
list: false
},
Publisher: {
title: 'Publisher',
list: false
},
Keyword: {
title: 'Keywords',
type: 'textarea',
width: '12%',
sorting: false
}
}
});
//Load student list from server
$('#BookTableContainer').jtable('load');
});
</script>
}
ISSUE *****************
When I am trying to access /Books/ListBooks
There is an error The resource cannot be found.
Please help me out i am new to jTable and it's implementation.
Use ListBooks action instead of Index action in jtable listAction. Index action will be used to render the view and after the jquery will load the data from ListBooks
I think you are requesting /Books/Listbooks through browser URL. Browser by default uses get method to get data from server and you putted HttpPost DataAnnotation over the method thats why you are getting error so if you want output makes following two changes.
1)Remove HttpPost Data Annotation of ListBooks Method.
2)Add JsonRequestBehavior.AllowGet in return Json method as follows
return Json(new { Result = "OK", Records = book, TotalRecordCount = bookCount }, JsonRequestBehavior.AllowGet )
Now Your method will work Perfectly.

ExtJs3.4.0 to ExtJs4.1.1 upgrade issues

ExtJS4: I am having problems while upgrading my application ExtJs version from 3.4.0 to 4.1.1a.
My 3.4.0 version code:
this.jsonStore = new Ext.data.JsonStore({
proxy : new Ext.data.HttpProxy({
url: 'rs/environments',
disableCaching: true
}),
restful : true,
storeId : 'Environments',
idProperty: 'env',
fields : [
'ConnectionName', 'Type'
]
});
this.colmodel = new Ext.grid.ColumnModel({
defaults: {
align: 'center'
},
columns: [{
header: Accero.Locale.text.adminlogin.connectionsHeading,
width : 140,
dataIndex: 'ConnectionName'
},
{
header: Accero.Locale.text.adminlogin.connectionTypeHeader,
width : 120,
dataIndex: 'Type'
}]
});
config = Ext.apply({
enableHdMenu: false,
border : true,
stripeRows : true,
store : this.jsonStore,
view : new Ext.grid.GridView(),
header : false,
colModel : this.colmodel,
sm : new Ext.grid.RowSelectionModel({singleSelect: true}),
loadMask: {
msg: Accero.Locale.text.adminlogin.loadingmask
}
}, config);
I made below changes to make application work with ExtJs4.1.1:
var sm = new Ext.selection.CheckboxModel( {
listeners:{
selectionchange: function(selectionModel, selected, options){
// Must refresh the view after every selection
myGrid.getView().refresh();
// other code for this listener
}
}
});
var getSelectedSumFn = function(column){
return function(){
var records = myGrid.getSelectionModel().getSelection(),
result = 0;
Ext.each(records, function(record){
result += record.get(column) * 1;
});
return result;
};
}
var config = Ext.create('Ext.grid.Panel', {
autoScroll:true,
features: [{
ftype: 'summary'
}],
store: this.jsonStore,
defaults: { // defaults are applied to items, not the container
sortable:true
},
selModel: sm,
columns: [
{header: Accero.Locale.text.adminlogin.connectionsHeading, width: 140, dataIndex: 'ConnectionName'},
{header: Accero.Locale.text.adminlogin.connectionTypeHeader, width: 120, dataIndex: 'Type'}
],
loadMask: {
msg: Accero.Locale.text.adminlogin.loadingmask
},
viewConfig: {
stripeRows: true
}
}, config);
With these changes, I am getting the error at my local file 'ext-override.js' saying 'this.el is not defined'.
I debug the code and found that, in the current object this, there is no el object.
ext-override.js code:
(function() {
var originalInitValue = Ext.form.TextField.prototype.initValue;
Ext.override(Ext.form.TextField, {
initValue: function() {
originalInitValue.apply( this, arguments );
if (!isNaN(this.maxLength) && (this.maxLength *1) > 0 && (this.maxLength != Number.MAX_VALUE)) {
this.el.dom.maxLength = this.maxLength *1;
}
}
}
);
})();
Kindly suggest where am I going wrong?
Thanks in advance...
Seriously, use more lazy initialization! Your code is a hell of objects, all unstructured.
First of all, you can override and use the overridden method more easily with something like that (since 4.1)
Ext.override('My.Override.for.TextField', {
override : 'Ext.form.TextField',
initValue: function() {
this.callOverridden(arguments);
if (!isNaN(this.maxLength) && (this.maxLength *1) > 0 && (this.maxLength != Number.MAX_VALUE)) {
this.el.dom.maxLength = this.maxLength *1;
}
}
});
But: The method initValue is called in initField (and this in initComponent) so that you cannot have a reference to this.me because the component is actually not (fully) rendered.
So, this should help (not tested):
Ext.override('My.Override.for.TextField', {
override : 'Ext.form.TextField',
afterRender: function() {
this.callOverridden(arguments);
if (!isNaN(this.maxLength) && (this.maxLength *1) > 0 && (this.maxLength != Number.MAX_VALUE)) {
this.el.dom.maxLength = this.maxLength *1;
}
}
});
But I'm strongly recommend not to use such things within overrides. Make dedicated components which will improve code readibility.

how to set variable value from the server response extjs 4

forum member I am having one problem in setting the value of my view from the server response I am receiving
I am using the MVC architechture of the extjs 4. My store is loaded perfectly and my taskstore is defined as below
Ext.define('gantt.store.taskStore', {
extend: 'Gnt.data.TaskStore',
model: 'gantt.model.ResourceTask',
storeId: 'taskStore',
autoLoad : true,
autoSync : true,
proxy : {
type : 'ajax',
api: {
read: 'task/GetTask.action',
create: 'task/CreateTask.action',
destroy: 'task/DeleteTask.action',
update: 'task/UpdateTask.action'
},
writer : new Ext.data.JsonWriter({
//type : 'json',
root : 'taskdata',
encode : true,
writeAllFields : true
}),
reader : new Ext.data.JsonReader({
totalPropery: 'total',
successProperty : 'success',
idProperty : 'id',
type : 'json',
root: function (o) {
if (o.taskdata) {
return o.taskdata;
} else {
return o.children;
}
}
})
}
});
but what I want to do is that as soon as the store loaded I want to assign the server response data to one of the variable in my javascript.
I tried to add the value from the beforeload function of view, but not able to do so.
my view code is given as below
var result = Ext.JSON.decode('{"calendardata": [{"startdate": 1330281000000,"enddate": 1330284600000,"id": 3,"title": "mon"}],"total": 1,"success": true}');
//var start = new Date(2012, 2, 26),
//end = Sch.util.Date.add(start, Sch.util.Date.MONTH, 30);
var start_d = new Date(result.calendardata[0].startdate);
var end_d = new Date(result.calendardata[0].enddate);
var start = new Date(start_d.getFullYear(), start_d.getMonth(), start_d.getDate());
end = Sch.util.Date.add(start, Sch.util.Date.MONTH, 30);
console.log("YEAR ::"+start.getFullYear()+"MONTH ::"+start.getMonth()+"DAY ::"+start.getDate());
console.log("YEAR ::"+end.getFullYear()+"MONTH ::"+end.getMonth()+"DAY ::"+end.getDate());
//create the downloadframe at the init of your app
this.downloadFrame = Ext.getBody().createChild({
tag: 'iframe'
, cls: 'x-hidden'
, id: 'iframe'
, name: 'iframe'
});
//create the downloadform at the init of your app
this.downloadForm = Ext.getBody().createChild({
tag: 'form'
, cls: 'x-hidden'
, id: 'form'
, target: 'iframe'
});
var printableMilestoneTpl = new Gnt.template.Milestone({
prefix : 'foo',
printable : true,
imgSrc : 'resources/images/milestone.png'
});
var params = new Object();
Ext.define('gantt.view.projectmgt.projectGanttpanel', {
extend: "Gnt.panel.Gantt",
id: 'projectganttpanel',
alias: 'widget.projectganttpanel',
requires: [
'Gnt.plugin.TaskContextMenu',
'Gnt.column.StartDate',
'Gnt.column.EndDate',
'Gnt.column.Duration',
'Gnt.column.PercentDone',
'Gnt.column.ResourceAssignment',
'Sch.plugin.TreeCellEditing',
'Sch.plugin.Pan',
'gantt.store.taskStore',
'gantt.store.dependencyStore'
],
leftLabelField: 'Name',
loadMask: true,
//width: '100%',
// height: '98%',
startDate: start,
endDate: end,
multiSelect: true,
cascadeChanges: true,
viewPreset: 'weekAndDayLetter',
recalculateParents: false,
showTodayLine : true,
showBaseline : true,
initComponent: function() {
var me = this;
me.on({
scope: me,
beforeload: function(store,records,options) {
console.log('BEFORE LOAD YAAR panel'+records.params);
if(records.params['id'] != null)
{
return true;
}
else
{
return false;
}
}
});
TaskPriority = {
Low : 0,
Normal : 1,
High : 2
};
var taskStore = Ext.create('gantt.store.taskStore');
var dependencyStore = Ext.create('gantt.store.dependencyStore');
Ext.apply(me, {
taskStore: taskStore,
dependencyStore: dependencyStore,
// Add some extra functionality
plugins : [
Ext.create("Gnt.plugin.TaskContextMenu"),
Ext.create('Sch.plugin.TreeCellEditing', {
clicksToEdit: 1
}),
Ext.create('Gnt.plugin.Printable', {
printRenderer : function(task, tplData) {
if (task.isMilestone()) {
return;
} else if (task.isLeaf()) {
var availableWidth = tplData.width - 4,
progressWidth = Math.floor(availableWidth*task.get('PercentDone')/100);
return {
// Style borders to act as background/progressbar
progressBarStyle : Ext.String.format('width:{2}px;border-left:{0}px solid #7971E2;border-right:{1}px solid #E5ECF5;', progressWidth, availableWidth - progressWidth, availableWidth)
};
} else {
var availableWidth = tplData.width - 2,
progressWidth = Math.floor(availableWidth*task.get('PercentDone')/100);
return {
// Style borders to act as background/progressbar
progressBarStyle : Ext.String.format('width:{2}px;border-left:{0}px solid #FFF3A5;border-right:{1}px solid #FFBC00;', progressWidth, availableWidth - progressWidth, availableWidth)
};
}
},
beforePrint : function(sched) {
var v = sched.getSchedulingView();
this.oldRenderer = v.eventRenderer;
this.oldMilestoneTemplate = v.milestoneTemplate;
v.milestoneTemplate = printableMilestoneTpl;
v.eventRenderer = this.printRenderer;
},
afterPrint : function(sched) {
var v = sched.getSchedulingView();
v.eventRenderer = this.oldRenderer;
v.milestoneTemplate = this.oldMilestoneTemplate;
}
})
],
eventRenderer: function (task) {
var prioCls;
switch (task.get('Priority')) {
case TaskPriority.Low:
prioCls = 'sch-gantt-prio-low';
break;
case TaskPriority.Normal:
prioCls = 'sch-gantt-prio-normal';
break;
case TaskPriority.High:
prioCls = 'sch-gantt-prio-high';
break;
}
return {
cls: prioCls
};
},
// Setup your static columns
columns: [
{
xtype : 'treecolumn',
header: 'Tasks',
dataIndex: 'Name',
width: 150,
field: new Ext.form.TextField()
},
new Gnt.column.StartDate(),
new Gnt.column.Duration(),
new Gnt.column.PercentDone(),
{
header: 'Priority',
width: 50,
dataIndex: 'Priority',
renderer: function (v, m, r) {
switch (v) {
case TaskPriority.Low:
return 'Low';
case TaskPriority.Normal:
return 'Normal';
case TaskPriority.High:
return 'High';
}
}
},
{
xtype : 'booleancolumn',
width : 50,
header : 'Manual',
dataIndex : 'ManuallyScheduled',
field : {
xtype : 'combo',
store : [ 'true', 'false' ]
}
}
],
tooltipTpl: new Ext.XTemplate(
'<h4 class="tipHeader">{Name}</h4>',
'<table class="taskTip">',
'<tr><td>Start:</td> <td align="right">{[Ext.Date.format(values.StartDate, "y-m-d")]}</td></tr>',
'<tr><td>End:</td> <td align="right">{[Ext.Date.format(Ext.Date.add(values.EndDate, Ext.Date.MILLI, -1), "y-m-d")]}</td></tr>',
'<tr><td>Progress:</td><td align="right">{PercentDone}%</td></tr>',
'</table>'
).compile()
});
me.callParent(arguments);
}
});
the reason I am not able to set the value of variable I used to set it using static data. To set the static data I am using the below code
var result = Ext.JSON.decode('{"calendardata": [{"startdate": 1330281000000,"enddate": 1330284600000,"id": 3,"title": "mon"}],"total": 1,"success": true}');
var start_d = new Date(result.calendardata[0].startdate);
var end_d = new Date(result.calendardata[0].enddate);
var start = new Date(start_d.getFullYear(), start_d.getMonth(), start_d.getDate());
end = Sch.util.Date.add(start, Sch.util.Date.MONTH, 30);
but instead of this static data I want to set the start and end value as soon as the store loads and server response is received.
please suggest me some solution I can apply here.
I am receiving the jsondata as
{
"taskdata": [{
"startdate": 1330281000000,
"enddate": 1330284600000,
"id": 3,
"title": "mon"
}],
"total": 1,
"success": true
}
I am using extjs 4 with MVC architecture and JAVA as my server side technology.
First of all your question is kind of badly formulated. You have too much code and not really clear what are you trying to ask. In a future try to isolate a particular problem you're dealing with if you want to get quick and proper answer.
Second, load operation is asynchronous. You just specified store as 'autoLoad', but I don't see anywhere where you subscribe to its load event. Most likely your problem is trying to get something of the store while it's not yet loaded. Try to set autoLoad: false, load store manually and subscribe to its 'load' event to populate your view.