Related
I have following code using free-jqgrid. It loads correctly for the first time (Status is “Active” and Partner? is “Yes”). But when I do a sort or search, the values become incorrect(Status is “Retired” and Partner? is “No”).
Why the formatters are giving incorrect values? How to fix this?
SCRIPT
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/themes/start/jquery-ui.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/free-jqgrid/4.13.6/js/jquery.jqgrid.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/free-jqgrid/4.13.6/css/ui.jqgrid.min.css" rel="stylesheet" />
<script type="text/javascript">
function getCurrentPractice ()
{
return "Test";
}
function getGridCaption() {
return "<div style='font-size:15px; font-weight:bold; display:inline; padding-left:10px;'><span class='glyphicon glyphicon-check' style='margin-right:3px;font-size:14px;'></span>" + getCurrentPractice() + " " + "</div>" +
"<div style='float:right; padding-right:20px; padding-bottom:10px; display:inline;>" +
"<div style='float:right;width:550px; padding-bottom:20px;'>" +
"<input type='text' class='form-control' id='filter' placeholder='Search' style='width:250px; height:30px; float:right; ' />" +
" </div>" +
"</div>";
}
$(function () {
var currentPractice = "P";
var grid = $("#list2");
grid.jqGrid({
url: '/Home/GetProviders',
datatype: "json",
postData:
{
practiceName: function () { return currentPractice }
},
colNames: [
'Practice',
'ProviderID',
'Partner?',
'Status'
],
colModel: [
{ name: 'Practice', hidden: false },
{ name: 'ProviderID', hidden: false },
{
name: 'PartnerStatusText',
width: 70,
formatter: function (cellvalue, options, rowObject) {
var isPartner = rowObject.IsPartner;
return isPartner == true ? 'Yes' : 'No';
}
},
{
name: 'ActiveStatusText',
width: 70,
formatter: function (cellvalue, options, rowObject) {
var isActive = rowObject.IsActive;
return isActive == true ? 'Active' : 'Retired';
}
}
],
ignoreCase: true,
loadonce: true,
rowNum: 25,
rowList: [15, 25, 35, 50],
pager: '#pager2',
viewrecords: true,
sortable: true,
caption: getGridCaption(),
beforeSelectRow: function (rowid, e) {
//Avoid selection of row
return false;
},
loadComplete: function () {
}
});
grid.jqGrid('navGrid', '#pager2', { edit: false, add: false, del: false });
//Filter Toolbar
$("#advancedSearch").click(function () {
grid.jqGrid('filterToolbar', { stringResult: true, searchOnEnter: false, defaultSearch: "cn" });
});
//Top Search
$("#filter").on('keyup', function () {
var searchFiler = $("#filter").val(), f;
if (searchFiler.length === 0) {
grid[0].p.search = false;
$.extend(grid[0].p.postData, { filters: "" });
}
f = { groupOp: "OR", rules: [] };
f.rules.push({ field: "Practice", op: "cn", data: searchFiler });
grid[0].p.search = true;
$.extend(grid[0].p.postData, { filters: JSON.stringify(f) });
grid.trigger("reloadGrid", [{ page: 1, current: true }]);
});
});
</script>
</head>
HTML
<div style="float:left; border:1px solid red;">
<div id="divGrid" style="width: 680px; min-height: 50px; float: left; border: 1px solid silver;">
<table id="list2"></table>
<div id="pager2"></div>
</div>
</div>
Server Code
[AllowAnonymous]
public JsonResult GetProviders(string practiceName)
{
//System.Threading.Thread.Sleep(3000);
List<Provider> providers = new List<Provider>();
Provider p = new Provider();
p.Practice = "Test1";
p.ProviderID = 1;
p.IsActive = true;
p.IsPartner = true;
providers.Add(p);
Provider p2 = new Provider();
p2.Practice = "Test2";
p2.ProviderID = 2;
p2.IsActive = true;
p2.IsPartner = true;
providers.Add(p2);
return Json(providers, JsonRequestBehavior.AllowGet);
}
UPDATE
Thanks to Oleg, working demo can be found here - Fiddle . It uses "/echo/json/" service of JSFiddle to get data from server.
It uses sorttype and additionalProperties. This can be rewritten without additionalProperties - I need to do it when I get a chance to revisit this.
The problem seems be very easy. The data returned from the server contains properties Practice, ProviderID, IsActive and IsPartner. The properties are available in rowObject during initial loading. You use additionally loadonce: true option. Thus free jqGrid will try to save some data locally, but which one? jqGrid saves by default the properties which corresponds the names of columns: Practice, ProviderID, PartnerStatusText and ActiveStatusText, but jqGrid have no information that other properties IsActive and IsPartner need be saved too.
You can solve the problem in two alternative ways:
you rename the column names PartnerStatusText and ActiveStatusText to IsActive and IsPartner.
you add the option additionalProperties: ["IsActive", "IsPartner"] to inform jqGrid to read and save locally additional properties.
Moreover, I'd recommend you to use options.rowData instead of rowObject inside of custom formatter. You can skip the 3-d parameter and to use formatter: function (cellvalue, options) {...}.
The final remark: the current code of the custom formatter is very easy. You need to replace some input values (true and false) to another text. One can use formatter: "select" for the case:
colModel: [
{ name: "Practice" },
{ name: "ProviderID" },
{
name: "IsPartner",
width: 70,
formatter: "select",
formatoptions: { value: "false:No;true:Yes" }
},
{
name: "IsActive",
width: 70,
formatter: "select",
formatoptions: { value: "false:Retired;true:Active" }
}
],
See https://jsfiddle.net/c9fge9yk/1/
<script language="javascript" type="text/javascript" src="/SiteAssets/test%20js/jquery-1.8.2.js"></script>
<script language="javascript" type="text/javascript" src="/SiteAssets/JqLib/i18n/grid.locale-en.js"></script>
<script language="javascript" type="text/javascript" src="/SiteAssets/JqLib/jquery.jqGrid.min.js"></script>
<script language="javascript" type="text/javascript" src="/SiteAssets/JqLib/jquery.SPServices-0.7.2.min.js"></script>
<script language="javascript" type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/json2/20150503/json2.min.js"></script>
<link rel="stylesheet" href="/SiteAssets/styles/ui.jqgrid.css">
<link rel="stylesheet" href="/SiteAssets/styles/ui-lightness/jquery-ui-1.7.3.custom.css">
<script language="javascript" type="text/javascript">
$(document).ready(function() {
debugger;
jQuery("#list").jqGrid({
datatype: GetMyData,
colNames:["ID","Title","Description"],
colModel:[{name:'ID',index:'ID',align:'left',sortable: true,width:"1500px"},
{name:'Title',index:'Title',align:'left',sortable: true, width:"1500px"},
{name:'Description',index:'Description',align:'left',sortable:true, width:"1500px"},],
pager: true,
pager: '#pager',
pageinput: true,
rowNum: 5,
rowList: [5, 10, 20, 50, 100],
sortname: 'ID',
sortorder: "asc",
viewrecords: true,
autowidth: true,
emptyrecords: "No records to view",
loadonce: true,
loadtext: "Loading..."
});
jQuery("#list").jqGrid('navGrid', "#pager", { edit: false, add: false, del: false, search: true, refresh: true }); });
function GetMyData(){
var ex='e';
Query="<Query><Where><Or><Contains><FieldRef Name='Title'/><Value Type='Text'>"+ex+"</Value></Contains><Contains><FieldRef Name='Description' />"+"<Value Type='Text'>"+ex+"</Value></Contains></Or></Where></Query>";
var CAMLViewFields="<ViewFields><FieldRef Name='Title'/><FieldRef Name='Description'/> <FieldRef Name='ID'/></ViewFields>";
GetDataOnLoad(Query, CAMLViewFields);
}
function GetDataOnLoad(Query, CAMLViewFields) {
$().SPServices({
operation: "GetListItems",
async: false,
listName: "List1",
CAMLQuery:Query,
CAMLViewFields:CAMLViewFields ,
completefunc: processResult
});
}
function processResult(xData, status) {
var counter = 0;
var newJqData = "";
debugger;
$(xData.responseXML).SPFilterNode("z:row").each(function () {
var JqData;
if (counter == 0) {
JqData="{"+'"id"'+":"+'"'+$(this).attr("ows_ID")+'",'+'"cell"'+":["+'"'+$(this).attr("ows_ID")+'",'+ '"'+$(this).attr("ows_Title")+'",'+ '"'
+$(this).attr("ows_Description")+'"'+"]}";
newJqData = newJqData + JqData;
counter = counter + 1;
} else {
var JqData="{"+'"id"'+":"+'"'+$(this).attr("ows_ID")+'",'+'"cell"'+":["+'"'+$(this).attr("ows_ID")+'",'+ '"'+$(this).attr("ows_Title")+'",'
+ '"'+$(this).attr("ows_Description")+'"'+"]}";
newJqData = newJqData +","+ JqData;
counter = counter + 1;
}
});
FinalDataForGrid(newJqData, counter);
}
function FinalDataForGrid(jqData, resultCount) {
debugger;
dataFromList = jqData.substring(0, jqData.length - 1);
var currentValue = jQuery("#list").getGridParam('rowNum');
var totalPages = Math.ceil(resultCount / currentValue);
var PageNumber = jQuery("#list").getGridParam("page"); // Current page number selected in the selection box of the JqGrid
newStr = "{"+'"total":'+'"'+totalPages+'",'+'"page":'+'"'+PageNumber+'",'+'"records":'+'"'+resultCount+'",'+'"rows":['+dataFromList+ "}]}";
var thegrid = jQuery("#list")[0];
var obj=JSON.stringify(newStr);
thegrid.addJSONData(JSON.parse(newStr));
}
</script>
<table id="list" width="100%" ></table>
<div id="pager" style="text-align:center;"></div>
I want to display data from SharePoint List using CAML Query, SPServices and JQGrid.
The data gets binded to the grid, I can see Page 1 of 2 and View 1-5 of 10. But When I click on next button, then Page 2 of 2 shows and view 6-10 of 10 shows up but data doesnt change. I am new to jqgrid, faced many issues even to bind grid, all are resolved right now except for pagination.
I'm new to jqgrid and jquery, can someone please help me in disabling the cell when the date is null or empty or undefined?
Actually the json for some (rows,col) date data is there and for some it is not there.
I want to disable the cell in the row for which Date data is not available.
grid cell editing POC
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" type="text/css" href="/jqGrid/jquery-ui-1.11.4.custom/jquery-ui.css">
<link rel="stylesheet" type="text/css" href="/jqGrid/Guriddo_jqGrid_JS_5.0.1/css/ui.jqgrid.css">
<script type="text/ecmascript" src="/jqGrid/Guriddo_jqGrid_JS_5.0.1/js/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="/jqGrid/jquery-ui-1.11.4.custom/jquery-ui.min.js"></script>
<script type="text/javascript" src="/jqGrid/Guriddo_jqGrid_JS_5.0.1/js/i18n/grid.locale-en.js"></script>
<script type="text/javascript">
$.jgrid.useJSON = true;
</script>
<script type="text/javascript" src="/jqGrid/Guriddo_jqGrid_JS_5.0.1/src/jquery.jqGrid.js"></script>
<script type="text/javascript">
$(function () {
"use strict";
var grid = $("#tree");
var initDateWithButton = function (elem) {
var ids = grid.jqGrid('getDataIDs');
for (var i=0;i<ids.length;i++) {
var id=ids[i];
if (grid.jqGrid('getCell',id,'assignedDate') == null) {
grid.jqGrid('setCell',id,'assignedDate','','not-editable-cell');
}
if (grid.jqGrid('getCell',id,'assignedDate') == "") {
grid.jqGrid('setCell',id,'assignedDate','','not-editable-cell');
}
if (grid.jqGrid('getCell',id,'assignedDate') == undefined) {
grid.jqGrid('setCell',id,'assignedDate','','not-editable-cell');
}
}
if (/^\d+%$/.test(elem.style.width)) {
// remove % from the searching toolbar
elem.style.width = '';
}
// to be able to use 'showOn' option of datepicker in advance searching dialog
// or in the editing we have to use setTimeout
setTimeout(function () {
$(elem).datepicker({
dateFormat: 'dd-M-yy',
showOn: 'button',
changeYear: true,
changeMonth: true,
showWeek: false,
showButtonPanel: true,
buttonImage: 'http://rcban0015:10039/GridPOC/pages/calenderIcon.gif',
onClose: function (dateText, inst) {
inst.input.focus();
}
});
$(elem).next('button.ui-datepicker-trigger').button({
text: false,
position: "relative",
top: "4px"
});
}, 100);
},
dateTemplate = {align: 'center', sorttype: 'date', editable: true,
formatter: 'date', formatoptions: { newformat: 'd-M-Y' }, datefmt: 'd-M-Y',
editoptions: { dataInit: initDateWithButton, size: 11 },
searchoptions: {
sopt: ['eq', 'ne', 'lt', 'le', 'gt', 'ge'],
dataInit: initDateWithButton,
size: 11, // for the advanced searching dialog
attr: {size: 11} // for the searching toolbar
}},
lastSel;
jQuery('#tree').jqGrid({
url: '<%= webAppAccess.getBackchannelActionURL("actionListjqGridPagination",false) %>',
"colModel":[
{
"name":"course_id",
"index":"course_id",
"sorttype":"int",
"key":true,
"hidden":true,
"width":50
},{
"name":"courseName",
"index":"courseName",
"sorttype":"string",
"label":"courseName",
"width":200
},{
"name":"facility",
"index":"facility",
"label":"facility",
"width":200,
"align":"left"
},{
"name":"assignedDate",
"index":"assignedDate",
"label":"assignedDate",
"width":110,
"template": dateTemplate
},{
"name":"dueDate",
"index":"dueDate",
"label":"dueDate",
"width":110,
"template": dateTemplate
},
{
"name":"AssignmentStatus",
"index":"AssignmentStatus",
"label":"AssignmentStatus",
"width":50
},{
"name":"Action",
"index":"Action",
"label":"Action",
"width":50
},
{
"name":"lft",
"hidden":true
},{
"name":"rgt",
"hidden":true
},{
"name":"level",
"hidden":true
},{
"name":"uiicon",
"hidden":true
}
],
"jsonReader": { "repeatitems": false, "root": "employees.rows" },
"toolbar": [true, "top"],
"width":"1200",
"hoverrows":false,
"viewrecords":false,
"gridview":true,
"height":"auto",
"sortname":"lft",
"loadonce":true,
"rowNum": 2,
"rowList":[2,10,15],
"scrollrows":true,
// enable tree grid
"treeGrid":true,
// which column is expandable
"ExpandColumn":"courseName",
// datatype
"treedatatype":"json",
// the model used
"treeGridModel":"nested",
// configuration of the data comming from server
"treeReader":{
"left_field":"lft",
"right_field":"rgt",
"level_field":"level",
"leaf_field":"isLeaf",
"expanded_field":"expanded",
"loaded":"loaded",
// set the ui icon field froom data
"icon_field":"uiicon"
},
"sortorder":"asc",
"datatype":"json",
"pager":"#pager",
"cellEdit": true, // TRUE = turns on celledit for the grid.
"cellsubmit" : 'clientArray',
"editurl": 'clientArray'
});
$('#t_' +"tree")
.append($("<div><label for=\"globalSearchText\">Global search in grid for: </label><input id=\"globalSearchText\" type=\"text\"></input> <button id=\"globalSearch\" type=\"button\">Search</button></div>"));
$("#globalSearchText").keypress(function (e) {
var key = e.charCode || e.keyCode || 0;
if (key === $.ui.keyCode.ENTER) { // 13
$("#globalSearch").click();
}
});
$("#globalSearch").button({
icons: { primary: "ui-icon-search" },
text: false
}).click(function () {
var postData = jQuery('#tree').jqGrid("getGridParam", "postData"),
colModel = jQuery('#tree').jqGrid("getGridParam", "colModel"),
rules = [],
searchText = $("#globalSearchText").val(),
l = colModel.length,
i,
cm;
for (i = 0; i < l; i++) {
cm = colModel[i];
if (cm.search !== false && (cm.stype === undefined || cm.stype === "text")) {
rules.push({
field: cm.name,
op: "cn",
data: searchText
});
}
}
postData.filters = JSON.stringify({
groupOp: "OR",
rules: rules
});
jQuery('#tree').jqGrid("setGridParam", { search: true });
jQuery('#tree').trigger("reloadGrid", [{page: 1, current: true}]);
return false;
});
});
</script>
</head>
<body>
<table id="tree"><tr><td></td></tr></table>
<div id="pager"></div>
</body>
</html>
There are exist alternative fork of jqGrid: free jqGrid, which I develop since more as one year. It has the functionality, where one can define editable property of colModel as function, which can return true or false based on the cell or the row content. See the wiki article for more details.
Check if this How to disable editing for soe cells in row editing of JQGrid
helps, it seen it is a similar thing, You just need to add into your logic.
This is controller code:
using JQGird.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace JQGird.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
return View();
}
public JsonResult EmployeeDetail()
{
Database1Entities db = new Database1Entities();
var employeedata = db.Empployees.Select(data => new
{
data.Id,
data.Name,
data.Designation,
data.Address,
data.Salary
});
var jsondat = new
{
total = 1,
page = 1,
records = db.Empployees.ToList().Count,
rows = employeedata
};
return Json(jsondat, JsonRequestBehavior.AllowGet);
}
}
}
and this is view of index action method
#{
ViewBag.Title = "Index";
}
<header>
<script>
$(document).ready(function () {
$('#grid').jqGrid({
url: '/Home/EmployeeDetails',
datatype: 'json',
myType: 'GET',
colNames: ['Id', 'Name', 'Designation', 'Address', 'Salary'],
colModel: [
{ name: 'Id', index: 'Id' },
{ name: 'Name', index: 'Name' },
{ name: 'Designation', index: 'Designation' },
{ name: 'Address', index: 'Address' },
{ name: 'Salary', index: 'Salary' }
],
jsonReader: {
root: 'rows',
page: 'page',
total: 'total',
reocords: 'records',
id: '0',
repeatitems: false
},
pager: $('#pager'),
rowNum: 5,
rowList: [2, 5, 10],
width: 600,
viewrecords: true,
caption: 'Jqgrid MVC Tutorial'
});
});
</script>
<script src="~/Scripts/jquery.jqGrid.js"></script>
<script src="~/Scripts/jquery.jqGrid.min.js"></script>
<script src="~/Scripts/jquery-1.9.1.min.js"></script>
<script src="~/Scripts/i18n/grid.locale-en.js"></script>
<link href="~/Content/jquery.jqGrid/ui.jqgrid.css" rel="stylesheet" />
<link href="~/Content/themes/base/jquery-ui.css" rel="stylesheet" />
</header>
<h1>Records of employees</h1>
<div>
<table id="grid">
</table>
<div id="pager"></div>
</div>
When i run the application, i t only show data. I have also check that the Json data is coming successffully to the view but jqgrid is not working. What mistakes i am doing?
HTML of the page
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<link href="/Content/site.css" rel="stylesheet"/>
<script src="/Scripts/modernizr-2.5.3.js"></script>
</head>
<body>
<h1>Records of employees</h1>
<div>
<table id="grid">
</table>
<div id="pager"></div>
</div>
<script type="text/javascript">
$(document).ready(function () {
$('#grid').jqGrid({
url: '/Home/EmployeeDetail',
datatype: 'json',
//myType: 'GET',
loadonce: true,
colNames: ['Id', 'Name', 'Designation', 'Address', 'Salary'],
colModel: [
{ name: 'Id', index: 'Id' },
{ name: 'Name', index: 'Name' },
{ name: 'Designation', index: 'Designation' },
{ name: 'Address', index: 'Address' },
{ name: 'Salary', index: 'Salary' }
],
jsonReader: {
root: 'rows',
page: 'page',
total: 'total',
reocords: 'records',
id: '0',
repeatitems: false
},
pager: $('#pager'),
rowNum: 5,
rowList: [2, 5, 10],
width: 600,
viewrecords: true,
caption: 'Jqgrid MVC Tutorial'
});
});
</script>
<link href="/Content/jquery.jqGrid/ui.jqgrid.css" rel="stylesheet" />
<link href="/Content/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="/Scripts/jquery-1.9.1.min.js"></script>
<script src="/Scripts/i18n/grid.locale-en.js"></script>
<script src="/Scripts/jquery.jqGrid.min.js"></script>
<script src="/Scripts/jquery.jqGrid.js"></script>
</body>
</html>
The HTML page have wrong order of JavaScripts which you includes.
It's important to understand that jqGrid is jQuery plugin. So one have to include first jQuery and only then one can includes jqGrid JavaScript files.
In the same way you use $(document).ready(function () {...}); which contains $ and .ready defined by jQuery, but you use the code before you included jQuery file jquery-1.9.1.min.js.
The next error: you included both non-minimized jqGrid jquery.jqGrid.js and then minimized version of the same file jquery.jqGrid.min.js. It's wrong. You should include only one from the files.
One more problem could exist in the order of the main jqGrid file (jquery.jqGrid.min.js, jquery.jqGrid.js or jquery.jqGrid.src.js) and the corresponding locale file grid.locale-en.js. There are different requirements for different versions of jqGrid and different forks, but the recommended order which works in all versions of jqGrid is: first include locale file (like grid.locale-en.js) and then the main jqGrid file (like jquery.jqGrid.min.js).
you skipped <body>...</body> after </header>.
The code of EmployeeDetail action don't uses any parameters which jqGrid send. You don't implemented any paging and sorting in the server code. Instead of that you just return all data at once. You should use loadonce: true options in the case. jqGrid will load all the data and then it will use sorting, paging and filtering on the client side. I hope that you use jqGrid in version higher as 3.7 which implemented support of loadonce: true. If you use loadonce: true option then the total, page and records properties of the server response will be ignored. Thus you can reduce the code of the server side and use return Json(employeedata, JsonRequestBehavior.AllowGet); instead of return Json(jsondat, JsonRequestBehavior.AllowGet);.
There are no myType option, but there are exist mtype option which default value is 'GET'. So you should remove myType: 'GET' option which will be ignored by jqGrid.
Some options of jqGrid can depend from the version of jqGrid which you use. I would recommend you to use gridview: true, autoencode: true, height: "auto". I would recommend you to remove unneeded index properties from all columns defined in colModel. Instead of that you can add key: true option for Id column. It will inform jqGrid to use the values from the columns as the values of id attribute of the rows (id of <td> elements). The jsonReader can be removed or you can use jsonReader: { repeatitems: false } or jsonReader: { repeatitems: false, root: function (obj) { return obj; } }. If you use recent version of jqGrid then no jsonReader will be required.
I mentioned above multiple times about versions which you use. I would recommend you to update jQuery 1.9.1 which you use currently to jQuery 1.11.3 or 2.1.4. Moreover I would recommend you to use the latest version of free jqGrid which you can get either from NuGet (see here), used URLs from CDN (see the wiki article) or to download the latest sources from GitHub directly.
I am trying to code two filteringselects which should both change according to data entered into any of the forms.
So data entered into fs1 should trigger changes in fs2.
Data entered into fs2 should trigger changes in fs1.
I am in a spring environment which in my case means that the dojo code is in a jsp file and the filtering select fields are populated through a Controller class on the server side using #ModelAttribute annotations to make the data available as a variable in the jsp file.
I have the relation data on the Java side so it's available through the controller.
Here is what confuses me at the moment.
I am new to DOJO and the documentation on the DOJO support site is a little hard to grasp for me. I would like to see a conceptual list of what is needed to accopmplish and connect the separate stores of my filteringselects.
When there is a change in one of the filteringselects, how do I inform the controllerclass of the changes and send the data that remains in the filteringselect?
This question could also be read as: how can I call a method with input parameters that hold the data available in the edited filteringselect?
I suggest we work on this in two incremental parts:
Get the first FilteringSelect's onChange event working
Wire them up to use server data stores
The following code sample takes a Dojo Campus' codependent FilteringSelect example and simplifies it so that its data stores are local. It shows how to programmatically instantiate two FilteringSelects with the second being dependent on the first by an onChange event handler.
Can you please try running it and let me know if you get it working?
Once we get your first FilteringSelect triggering filtering on the second, I will edit to add an explanation on how to convert them to use server side data stores.
<html>
<head>
<title>Test File</title>
<link type="text/css" rel="stylesheet" href="dijit/themes/tundra/tundra.css"/>
</head>
<body class="tundra">
<label for="state">State:</label>
<input id="state">
<label for="city">City:</label>
<input id="city">
<script type="text/javascript" src="dojo/dojo.js"
djConfig="isDebug: true, parseOnLoad: true"></script>
<script type="text/javascript">
dojo.require("dijit.form.FilteringSelect");
dojo.require("dojo.data.ItemFileReadStore");
dojo.addOnLoad(function() {
var cityJson = {
label: 'name',
items: [{ name: 'Albany', state: 'NY' },
{ name: 'New York City', state: 'NY' },
{ name: 'Buffalo', state: 'NY' },
{ name: 'Austin', state: 'TX' },
{ name: 'Houston', state: 'TX' }]
};
var stateJson = {
identifier: 'abbreviation',
label: 'name',
items: [ { name: 'New York', abbreviation: 'NY' },
{ name: 'Texas', abbreviation: 'TX' } ]
};
new dijit.form.ComboBox({
store: new dojo.data.ItemFileReadStore({
data: cityJson
}),
autoComplete: true,
query: {
state: "*"
},
style: "width: 150px;",
required: true,
id: "city",
onChange: function(city) {
dijit.byId('state').attr('value', (dijit.byId('city').item || {
state: ''
}).state);
}
},
"city");
new dijit.form.FilteringSelect({
store: new dojo.data.ItemFileReadStore({
data: stateJson
}),
autoComplete: true,
style: "width: 150px;",
id: "state",
onChange: function(state) {
dijit.byId('city').query.state = state || "*";
}
},
"state");
});
</script>
</body>
</html>
in the namespace of the jsp:
xmlns:springform="http://www.springframework.org/tags/form"
sample form:
<springform:form action="#" >
<label for="country">Country:</label>
<springform:select id="country" path="country" items="${countryList}" itemLabel="country" itemValue="id"/>
<div id="citySelectDiv"></div>
</springform:form>
javascript code:
<script type="text/javascript">
<![CDATA[
dojo.require("dojo.parser");
dojo.require("dojo.data.ItemFileReadStore");
function countryChanged(dataFromServer){
//convert json to dojo filteringSelect options
var options = {
identifier: 'id',
label: 'city',
items: dataFromServer
};
var cityStore =new dojo.data.ItemFileReadStore({data : options});
// create Select widget, populating its options from the store
if (!dijit.byId("citySelectDiv")) {
//create city selction combo
new dijit.form.FilteringSelect({
name: "citySelectDiv",
store: cityStore,
searchAttr : "city",
}, "citySelectDiv");
}else{
//if already created the combo before
dijit.byId('citySelectDiv').set('value',null);
dijit.byId('citySelectDiv').store = cityStore;
}
}
Spring.addDecoration(new Spring.ElementDecoration({
elementId : "country",
widgetType : "dijit.form.FilteringSelect",
widgetAttrs : {
promptMessage: "Select a Country",
required : true,
onChange : function(){
var xhrArgs = {
url: "ajax/country/" +dijit.byId('country').get('value'),
handleAs: 'json',
load: function(dataFromServer) {
countryChanged(dataFromServer);
}
};
//make the ajax call
dojo.xhrGet(xhrArgs);
}
}
}));
Sample Controller method:
#ResponseBody
#RequestMapping("/ajax/country/{country}")
public List<City> clientSelection(#PathVariable("country") String country ) {
log.info("Country = {} ",country);
return cityService.findCitiesByCountry(country);
}