Breeze.js is a JavaScript library, that helps you manage data in rich client applications. With Breeze, data stored in a database can be queried and saved as complex object graphs, which can be shared across multiple screens of your JavaScript client.
In this tutorial you will learn how to use Breeze to query data from a remote data source and load it in jqxDataAdapter. Once loaded, the data can easily be displayed in widgets such as jqxGrid and jqxComboBox.
Before proceeding further with this tutorial, download Breeze from http://www.breezejs.com/documentation/download. Choose the Breeze 1.4.8 + .NET samples option. Extract the downloaded archive in a folder of your choice.
If you are new to Breeze, make sure you learn the basics by going through the Breeze tutorials.
We will base the example in this tutorial on one of the samples included in the
Breeze download package. Go to the Breeze folder (where you extracted the archive),
then go to Samples
→ Edmunds
. Open the solution
file Edmunds.sln
.
The Edmunds sample shows that Breeze can manage data from any HTTP source. The sample application reads the "Make" and "Model" data from the Edmunds.com Vehicle Information service and translates those data into Breeze entities. You can read more about it in the following page: http://www.breezejs.com/samples/edmunds.
Download jQWidgets
and extract the jqwidgets
folder from the package to Edmunds\Edmunds
,
where all the sample's files are located. Include the folder in the project.
Some of the Edmunds sample's functionalities are not needed for the purpose of this tutorial. That is why we are going to modify it and remove the unnecessary files. Here is the structure of the project after we have excluded the unneeded folders and scripts:
Note that the app
folder and the five script files in it were also
removed. We will, however, use some of the code in these scripts as they are essential
for the functionality of the application.
The next step is to create a new JavaScript file, containing the code for the initialization
of our Breeze EntityManager. Instances of the EntityManager contain and manage collections
of entities, either retrieved from a backend datastore or created on the client.
Add a new JavaScript File in the Scripts
folder and name it breezeEntityManager.js
.
Put the following code in the new script:
function entityManager() {// jsonResultsAdaptervar jsonResultsAdapter = new breeze.JsonResultsAdapter({name: "edmunds",extractResults: function (data) {var results = data.results;if (!results) throw new Error("Unable to resolve 'results' property");// Parse only the make and model typesreturn results && (results.makeHolder || results.modelHolder);},visitNode: function (node, parseContext, nodeContext) {// Make parserif (node.id && node.models) {// move 'node.models' links so 'models' can be empty arraynode.modelLinks = node.models;node.models = [];return { entityType: "Make" }}// Model parserelse if (node.id && node.makeId) {// move 'node.make' link so 'make' can be null referencenode.makeLink = node.make;node.make = null;// flatten styles and sizes as comma-separated stringsvar styles = node.categories && node.categories["Vehicle Style"];node.vehicleStyles = styles && styles.join(", ");var sizes = node.categories && node.categories["Vehicle Size"];node.vehicleSizes = sizes && sizes.join(", ");return { entityType: "Model" };}}});var DT = breeze.DataType;// initializes metadataStorefunction initialize(metadataStore) {metadataStore.addEntityType({shortName: "Make",namespace: "Edmunds",dataProperties: {id: { dataType: DT.Int64, isPartOfKey: true },name: { dataType: DT.String },niceName: { dataType: DT.String },modelLinks: { dataType: DT.Undefined }},navigationProperties: {models: {entityTypeName: "Model:#Edmunds", isScalar: false,associationName: "Make_Models"}}});metadataStore.addEntityType({shortName: "Model",namespace: "Edmunds",dataProperties: {id: { dataType: "String", isPartOfKey: true },makeId: { dataType: "Int64" },makeName: { dataType: "String" },makeNiceName: { dataType: "String" },name: { dataType: "String" },niceName: { dataType: "String" },vehicleStyles: { dataType: "String" },vehicleSizes: { dataType: "String" },categories: { dataType: "Undefined" }},navigationProperties: {make: {entityTypeName: "Make:#Edmunds", isScalar: true,associationName: "Make_Models", foreignKeyNames: ["makeId"]}}});};// initializes Breeze EntityManagervar serviceName = "http://api.edmunds.com/v1/api/";var ds = new breeze.DataService({serviceName: serviceName,hasServerMetadata: false,useJsonp: true,jsonResultsAdapter: jsonResultsAdapter});var manager = new breeze.EntityManager({ dataService: ds });initialize(manager.metadataStore);return manager;};
The function entityManager
initializes the Breeze JsonResultsAdapter
and the EntityManager itself (including its metadataStore). It returns the manager
for a later use.
The main section of our application will be in the file Index.html
.
Here is what its source code should look like after the needed modifications and
additions:
<!DOCTYPE html><html><head><title>Example of jQWidgets Integration with Breeze.js</title><link href="jqwidgets/styles/jqx.base.css" rel="stylesheet" type="text/css" /><script src="Scripts/jquery-1.11.1.min.js" type="text/javascript"></script><script src="Scripts/q.js" type="text/javascript"></script><script src="Scripts/breeze.debug.js" type="text/javascript"></script><script src="Scripts/breezeEntityManager.js" type="text/javascript"></script><script src="jqwidgets/jqx-all.js" type="text/javascript"></script><script type="text/javascript">$(document).ready(function () {// initializes the Breeze EntityManagervar manager = entityManager();// gets car makesfunction getMakes() {// vehicle/makerepository/findallvar parameters = makeParameters();var query = breeze.EntityQuery.from("vehicle/makerepository/findall").withParameters(parameters);manager.executeQuery(query).then(function (data) {var source = {datatype: "json",datafields: [{name: 'id'}, {name: 'name'}],localdata: data.results,async: false};var dataAdapter = new $.jqx.dataAdapter(source);$("#jqxComboBox").jqxComboBox({ source: dataAdapter, displayMember: "name", valueMember: "id" });}).fail(function (e) {alert(e);});};// gets car models, based on make idfunction getModels(makeId) {// vehicle/modelrepository/findbymakeid?makeid=xxxvar parameters = makeParameters({ makeid: makeId });var query = breeze.EntityQuery.from("vehicle/modelrepository/findbymakeid").withParameters(parameters);$("#jqxGrid").jqxGrid("showloadelement");return manager.executeQuery(query).then(function (data) {var newGridSource ={datatype: "array",datafields: [{ name: 'name' },{ name: 'vehicleStyles' },{ name: 'vehicleSizes' }],localdata: data.results};var newDataAdapter = new $.jqx.dataAdapter(newGridSource);$("#jqxGrid").jqxGrid("hideloadelement");$("#jqxGrid").jqxGrid({ source: newDataAdapter });}).fail(function (e) {alert(e);});};function makeParameters(addlParameters) {var parameters = {fmt: "json",api_key: "z35zpey2s8sbj4d3g3fxsqdx"// Edmund throttles to 4000 requests per API key// get your own key: http://developer.edmunds.com/apps/register};return breeze.core.extend(parameters, addlParameters);};// initializes jqxComboBox$("#jqxComboBox").jqxComboBox({ width: 200, height: 25, placeHolder: "Please select" });// loads the selected car make's models in the grid$("#jqxComboBox").on("select", function (event) {var args = event.args;if (args) {var item = args.item;var makeId = item.value;getModels(makeId);};});// gets all car makes and loads them in the comboboxgetMakes();// initializes jqxGridvar gridSource ={datatype: "array",datafields: [{ name: 'name' },{ name: 'vehicleStyles' },{ name: 'vehicleSizes' }]};var dataAdapter = new $.jqx.dataAdapter(gridSource);$("#jqxGrid").jqxGrid({width: 750,autoheight: true,source: dataAdapter,columnsresize: true,columns: [{ text: 'Name', datafield: 'name', width: 200 },{ text: 'Style', datafield: 'vehicleStyles' },{ text: 'Size', datafield: 'vehicleSizes', width: 200 }]});});</script></head><body><p>Select a car make:</p><div id="jqxComboBox"></div><p>Car models:</p><div id="jqxGrid"></div></body></html>
In our page, we have a jqxComboBox and jqxGrid instances. The combobox is populated
with car makes from the Edmunds.com Vehicle Information service via a Breeze query
(in the getMakes
function). When you select a make from the combobox,
the grid is dynamically loaded with car models, corresponding to the selected make
(this is realised in the getModels
function). Note that both widgets
are loaded through jqxDataAdapter.
You can download the complete solution from here or check out the example online from here: Example of jQWidgets Integration with Breeze.js.