jQWidgets Forums
jQuery UI Widgets › Forums › Lists › ComboBox › Chained (Dependent) Combobox with XML data
Tagged: Chained Dependent XML
This topic contains 7 replies, has 2 voices, and was last updated by solveQueries 11 years, 6 months ago.
-
Author
-
I have the following XML for CountriesStatesCities
<root> <country> <countryId>8</countryId> <countryName>Antarctica</countryName> <state> <city> <cityId>12976</cityId> <cityName>Molodesjnaja</cityName> </city> <city> <cityId>15188</cityId> <cityName>Reading</cityName> </city> <stateId>4761</stateId> <stateName>Enderby Land</stateName> </state> <state> <city> <cityId>14699</cityId> <cityName>McMurdo Station</cityName> </city> <stateId>4763</stateId> <stateName>Ross Island</stateName> </state> </country> ....</root>
I have the following code for the dependent Country State City comboboxes:
<script type="text/javascript"> $(document).ready(function () { var url = "CountryStateCity.xml"; var sourceCountries = { datatype: "xml", datafields: [ { name: 'countryId', type: 'int' }, { name: 'countryName', type: 'string' } , { name: 'stateId', map: 'state>stateId', type: 'int' }, { name: 'stateName', map: 'state>stateName', type: 'string' }, { name: 'cityId', map: 'state>city>cityId', type: 'int' }, { name: 'cityName', map: 'state>city>cityName', type: 'string' } ], root: "root", record: "country", url: url, async: false }; var dataAdapterCountries = new $.jqx.dataAdapter(sourceCountries, { async: false }); // states to display var statesToDisplay = new Array(); // Create a jqxComboBox $("#jqxcombobox1").jqxComboBox({ source: dataAdapterCountries, displayMember: "countryName", valueMember: "countryId", width: '200px', height: '25px', dropDownHeight: '200px' }); $('#jqxcombobox1').bind('select', function (event) { var selectedCountryId = event.args.item.value; //alert("Label: "+event.args.item.label+"\nValue: "+event.args.item.value+"\nIndex: "+event.args.item.index); var statesAdapter = new $.jqx.dataAdapter(sourceCountries, { autoBind: true, beforeLoadComplete: function (records) { var data = new Array(); /*var StateIDToDisplay = new Array(); var StateNameToDisplay = new Array();*/ // update the loaded records. Dynamically add StateName and StateID fields. for (var i = 0; i < records.length; i++) { var countryRecord = records[i]; if(countryRecord.countryId == selectedCountryId) { //alert(records[i]); //statesToDisplay [countryRecord.stateName] = countryRecord.stateId; countryRecord.StateIDToDisplay = countryRecord.stateId; countryRecord.StateNameToDisplay = countryRecord.stateName; data.push(countryRecord); /*StateIDToDisplay = countryRecord.stateId; StateNameToDisplay = countryRecord.stateName;*/ } } return data; } }); $("#jqxcombobox2").jqxComboBox({ source: statesAdapter, width: '200px', displayMember: "StateNameToDisplay", valueMember: "StateIDToDisplay", height: '25px', disabled: false }); }); }); </script></head><body> <div id='content'> <div style="float: left;" id='jqxcombobox1'> </div> <div style="float: left;" id="jqxcombobox2"> </div> <div style="float: left;" id="jqxcombobox3"> </div> </div></body></html>
My problem here is on selecting a country, all the states pertaining to that country is being populated on a single row. I think the dataAdapter represents all the child elements as a single entity.
So is there any other way to access each sub-element of the entity i.e. one by one?Hi solveQueries,
To process the “states” you will have to point to the “state” records when you define the “source” object’s “record” member.
Example:
<!DOCTYPE html><html lang="en"><head> <meta name="keywords" content="jQuery jqxComboBox, List, ListBox, Popup List, jqxDropDownList, jqxListBox, List Widget, ListBox Widget, DropDownList Widget" /> <meta name="description" content="The jqxDropDownList represents a widget that contains a list of selectable items." /> <title id='Description'>In this demo the jqxComboBox is bound to XML data.</title> <link rel="stylesheet" href="../../jqwidgets/styles/jqx.base.css" type="text/css" /> <script type="text/javascript" src="../../scripts/jquery-1.10.2.min.js"></script> <script type="text/javascript" src="../../scripts/demos.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxcore.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxdata.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxbuttons.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxscrollbar.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxlistbox.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxcombobox.js"></script></head><body> <div id='content'> <script type="text/javascript"> $(document).ready(function () { var url = "text.xml"; var sourceCountries = { datatype: "xml", datafields: [ { name: 'stateId', map: 'stateId', type: 'int' }, { name: 'stateName', map: 'stateName', type: 'string' }, { name: 'cityId', map: 'city>cityId', type: 'int' }, { name: 'cityName', map: 'city>cityName', type: 'string' } ], root: "root", record: "country>state", url: url, async: false }; var dataAdapterCountries = new $.jqx.dataAdapter(sourceCountries, { async: false }); $("#jqxWidget").jqxComboBox({ selectedIndex: 0, source: dataAdapterCountries, displayMember: "stateName", valueMember: "stateId", width: 200, height: 25 }); }); </script> <div id='jqxWidget'> </div> <div style="font-size: 12px; font-family: Verdana;" id="selectionlog"></div> </div></body></html>
Here’s the sample file I tested with:
<root> <country> <countryId>8</countryId> <countryName>Antarctica</countryName> <state> <city> <cityId>12976</cityId> <cityName>Molodesjnaja</cityName> </city> <city> <cityId>15188</cityId> <cityName>Reading</cityName> </city> <stateId>4761</stateId> <stateName>Enderby Land</stateName> </state> <state> <city> <cityId>14699</cityId> <cityName>McMurdo Station</cityName> </city> <stateId>4763</stateId> <stateName>Ross Island</stateName> </state> </country> <country> <countryId>9</countryId> <countryName>Antarctica 2</countryName> <state> <city> <cityId>12976</cityId> <cityName>Molodesjnaja 2</cityName> </city> <city> <cityId>15188</cityId> <cityName>Reading</cityName> </city> <stateId>4761</stateId> <stateName>Enderby Land 2</stateName> </state> <state> <city> <cityId>14699</cityId> <cityName>McMurdo Station 2</cityName> </city> <stateId>4763</stateId> <stateName>Ross Island 2</stateName> </state> </country></root>
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.comHi Peter,
After pointing to the “state” records, I am not able to get the element to compare the selected countryId with the XML so that I could display the proper states within a country.
Below is the code snippet used on the above XML:
<script type="text/javascript"> $(document).ready(function () { var url = "CountryStateCity.xml"; var sourceCountries = { datatype: "xml", datafields: [ { name: 'countryId', type: 'int' }, { name: 'countryName', type: 'string' } , { name: 'stateId', map: 'state>stateId', type: 'int' }, { name: 'stateName', map: 'state>stateName', type: 'string' } ], root: "root", record: "country", url: url, async: false }; var sourceStates = { datatype: "xml", datafields: [ { name: 'countryId', type: 'int' }, { name: 'countryName', type: 'string' } , { name: 'stateId', map: 'state>stateId', type: 'int' }, { name: 'stateName', map: 'state>stateName', type: 'string' }, { name: 'cityId', map: 'state>city>cityId', type: 'int' }, { name: 'cityName', map: 'state>city>cityName', type: 'string' } ], root: "root", record: "country>state", url: url, async: false }; var dataAdapterCountries = new $.jqx.dataAdapter(sourceCountries, { async: false }); // states to display var statesToDisplay = new Array(); // Create a jqxComboBox $("#jqxcombobox1").jqxComboBox({ source: dataAdapterCountries, displayMember: "countryName", valueMember: "countryId", placeHolder: "Select Country...", width: '200px', height: '25px', dropDownHeight: '200px' }); $('#jqxcombobox1').bind('select', function (event) { var selectedCountryId = event.args.item.value; var dataAdapterStates = new $.jqx.dataAdapter(sourceStates, { autoBind: true, beforeLoadComplete: function (records) { var data = new Array(); for (var i = 0; i < records.length; i++) { var countryRecord = records[i]; if(countryRecord.countryId == selectedCountryId) { countryRecord.StateIDToDisplay = countryRecord.stateId; countryRecord.StateNameToDisplay = countryRecord.stateName; data.push(countryRecord); } } return data; } }); $("#jqxcombobox2").jqxComboBox({ source: dataAdapterStates, width: '200px', displayMember: "StateNameToDisplay", valueMember: "StateIDToDisplay", placeHolder: "Select State...",height: '25px', disabled: false }); }); }); </script></head><body> <div id='content'> <div style="float: left;" id='jqxcombobox1'> </div> <div style="float: left;" id="jqxcombobox2"> </div> <div style="float: left;" id="jqxcombobox3"> </div> </div></body></html>
On this line
if(countryRecord.countryId == selectedCountryId)
I am not able to get the countryId from dataAdapterStates.
Need some help to display the states contained in a particular country.
Hi solveQueries,
The sample I sent you shows how to get the “States” in your XML and nothing else. “countryID” and “countryName” should not be part of the “sourceStates ” object.
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.comHi Peter,
I agree with your point, but as I said in my first post I want a chained ComboBox and I guess the only way to do this is by above method. So could you help me generate a chained combo-box.
Thanks!
Hi solveQueries,
According to me, you will have to do some custom processing in the downloadComplete callback of the first dataAdapter. There you will get the Raw data downloaded from the XML. By doing that you should be able to get the required records for displaying into the ComboBoxes.
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.comHi Peter,
Ok. Trying out downloadComplete callback way. Will inform when its done
Hi Peter,
Below is code I used to achieve chained ComboBox. I have used the jQuery GET method to read the xml & store the data in an variable. But here I am reading the XML twice, once through jQuery GET method & second through dataAdapterCountries.
<script type="text/javascript"> $(document).ready(function () { var url = "CountryStateCity.xml"; var all_data = null; $.get(url, function(data) { // get the countryStateCity.xml file all_data = data; // save the data for future use }, 'xml'); // specify what format the request will return - XML var sourceCountries = { datatype: "xml", datafields: [ { name: 'countryId', type: 'int' }, { name: 'countryName', type: 'string' } ], root: "root", record: "country", url: url, async: false }; var dataAdapterCountries = new $.jqx.dataAdapter(sourceCountries, { async: false }); // Create a COUNTRY jqxComboBox $("#jqxcombobox1").jqxComboBox({ source: dataAdapterCountries, displayMember: "countryName", valueMember: "countryId", placeHolder: "Select Country...", width: '200px', height: '25px', dropDownHeight: '200px' }); $("#jqxcombobox2").jqxComboBox({ disabled: true, placeHolder: "Select State..." }); $("#jqxcombobox3").jqxComboBox({ disabled: true, placeHolder: "Select City..." }); $('#jqxcombobox1').bind('select', function (event) { var statesToDisplay = new Array(); var selectedCountryId = event.args.item.value; i=0; $('country', all_data).filter(function() { // get all countries from xml return selectedCountryId == $(this).find("countryId").text(); }).find('state').each(function() { var row = {}; row['stateName'] = $(this).find("stateName").text(); row['stateId'] = $(this).find("stateId").text(); statesToDisplay[i] = row; i++; }); var stateSource = { datatype: "array", datafields: [ { name: 'stateName', type: 'string'}, { name: 'stateId', type: 'int'} ], localdata: statesToDisplay }; var dataAdapterStates = new jQuery.jqx.dataAdapter(stateSource, { async: false }); $("#jqxcombobox2").jqxComboBox({ source: dataAdapterStates, width: '200px', displayMember: "stateName", valueMember: "stateId", placeHolder: "Select State...", height: '25px', disabled: false }); }); $('#jqxcombobox2').bind('select', function (event) { var citiesToDisplay = new Array(); var selectedStateId = event.args.item.value; i=0; $('state', all_data).filter(function() { // get all states from xml return selectedStateId == $(this).find("stateId").text(); }).find('city').each(function() { var row = {}; row['cityName'] = $(this).find("cityName").text(); row['cityId'] = $(this).find("cityId").text(); citiesToDisplay[i] = row; i++; }); var citySource = { datatype: "array", datafields: [ { name: 'cityName', type: 'string'}, { name: 'cityId', type: 'int'} ], localdata: citiesToDisplay }; var dataAdapterCities = new jQuery.jqx.dataAdapter(citySource, { async: false }); $("#jqxcombobox3").jqxComboBox({ source: dataAdapterCities, width: '200px', displayMember: "cityName", valueMember: "cityId", placeHolder: "Select City...", height: '25px', disabled: false }); }); }); </script></head><body> <div id='content'> <div style="float: left;" id='jqxcombobox1'> </div> <div style="float: left;" id="jqxcombobox2"> </div> <div style="float: left;" id="jqxcombobox3"> </div> </div></body></html>
Is there a more efficient way to read that XML only once & do all the processing thereafter, since the size of the XML being used by me is 4.5 MB which is too large to read twice?
-
AuthorPosts
You must be logged in to reply to this topic.