The following dojo.data stores are pre-packaged with Dojo:
| dojo.data.ItemFileReadStore | read-only store for JSON data |
| dojo.data.ItemFileWriteStore | read/write store for JSON data |
| dojox.data.CsvStore | read-only store for comma-separated variable (CSV) formatted data |
| dojox.data.OpmlStore | read-only store for Outline Processor Markup Language (OPML) |
| dojox.data.HtmlTableStore | read-only store for data kept in HTML-formatted tables |
| dojox.data.XmlStore | read/write store for basic XML data |
| dojox.data.FlickrStore | read store for queries on flickr.com, and a good example data store for web services |
| dojox.data.FlickrRestStore | read store for queries on flickr.com, and a good example data store for web services. More advanced version of FlickrStore |
| dojox.data.QueryReadStore | like ItemFileReadStore, read-only store for JSON data, but queries servers on each request |
| dojox.data.AtomReadStore | read store for Atom XML documents. |
Summary:
Dojo core provides a basic implementation of a read-only datastore, ItemFileReadStore. This store reads the JSON structured contents from an http endpoint (service or URL), or from an in-memory JavaScript object, and stores all the items in-memory for simple and quick access. ItemFileReadStore is designed to allow for flexibility in how it represents item hierarchy, references, and custom data types. It also provides options for which attribute can act as the unique identifier (for dojo.data.api.Identity), and which attribute can be used as a general label for an item. This store has an expectation that data is provided to in in a specific though very flexible, format. All of the examples on this page demonstrate the general format expected.
The following dojo.data APIs are implemented by ItemFileReadStore
JSON with References: The following geography example uses references (items referencing another item declared in the data):
{ 'identifier': 'name',
'label': 'name',
'items': [
{ 'name':'Africa', 'type':'continent',
'children':[{'_reference':'Egypt'}, {'_reference':'Kenya'}, {'_reference':'Sudan'}] },
{ 'name':'Egypt', 'type':'country' },
{ 'name':'Kenya', 'type':'country',
'children':[{'_reference':'Nairobi'}, {'_reference':'Mombasa'}] },
{ 'name':'Nairobi', 'type':'city' },
{ 'name':'Mombasa', 'type':'city' },
{ 'name':'Sudan', 'type':'country',
'children':{'_reference':'Khartoum'} },
{ 'name':'Khartoum', type:'city' },
{ 'name':'Asia', 'type':'continent',
'children':[{'_reference':'China'}, {'_reference':'India'}, {'_reference':'Russia'}, {'_reference':'Mongolia'}] },
{ 'name':'China', 'type':'country' },
{ 'name':'India', 'type':'country' },
{ 'name':'Russia', 'type':'country' },
{ 'name':'Mongolia', 'type':'country' },
{ 'name':'Australia', 'type':'continent', 'population':'21 million',
'children':{'_reference':'Commonwealth of Australia'}},
{ 'name':'Commonwealth of Australia', 'type':'country', 'population':'21 million'},
{ 'name':'Europe', 'type':'continent',
'children':[{'_reference':'Germany'}, {'_reference':'France'}, {'_reference':'Spain'}, {'_reference':'Italy'}] },
{ 'name':'Germany', 'type':'country' },
{ 'name':'France', 'type':'country' },
{ 'name':'Spain', 'type':'country' },
{ 'name':'Italy', 'type':'country' },
{ 'name':'North America', 'type':'continent',
'children':[{'_reference':'Mexico'}, {'_reference':'Canada'}, {'_reference':'United States of America'}] },
{ 'name':'Mexico', 'type':'country', 'population':'108 million', 'area':'1,972,550 sq km',
'children':[{'_reference':'Mexico City'}, {'_reference':'Guadalajara'}] },
{ 'name':'Mexico City', 'type':'city', 'population':'19 million', 'timezone':'-6 UTC'},
{ 'name':'Guadalajara', 'type':'city', 'population':'4 million', 'timezone':'-6 UTC' },
{ 'name':'Canada', 'type':'country', 'population':'33 million', 'area':'9,984,670 sq km',
'children':[{'_reference':'Ottawa'}, {'_reference':'Toronto'}] },
{ 'name':'Ottawa', 'type':'city', 'population':'0.9 million', 'timezone':'-5 UTC'},
{ 'name':'Toronto', 'type':'city', 'population':'2.5 million', 'timezone':'-5 UTC' },
{ 'name':'United States of America', 'type':'country' },
{ 'name':'South America', 'type':'continent',
'children':[{'_reference':'Brazil'}, {'_reference':'Argentina'}] },
{ 'name':'Brazil', 'type':'country', 'population':'186 million' },
{ 'name':'Argentina', 'type':'country', 'population':'40 million' }
]}
JSON with Hierarchy: The following geography example uses hierarchical items (items that contain definitions of other items):
{ 'identifier': 'name',
'items': [
{ 'name':'Africa', 'type':'continent', children:[
{ 'name':'Egypt', 'type':'country' },
{ 'name':'Kenya', 'type':'country', children:[
{ 'name':'Nairobi', 'type':'city' },
{ 'name':'Mombasa', 'type':'city' } ]
},
{ 'name':'Sudan', 'type':'country', 'children':
{ 'name':'Khartoum', 'type':'city' }
} ]
},
{ 'name':'Asia', 'type':'continent', 'children':[
{ 'name':'China', 'type':'country' },
{ 'name':'India', 'type':'country' },
{ 'name':'Russia', 'type':'country' },
{ 'name':'Mongolia', 'type':'country' } ]
},
{ 'name':'Australia', 'type':'continent', 'population':'21 million', 'children':
{ 'name':'Commonwealth of Australia', 'type':'country', 'population':'21 million'}
},
{ 'name':'Europe', 'type':'continent', 'children':[
{ 'name':'Germany', 'type':'country' },
{ 'name':'France', 'type':'country' },
{ 'name':'Spain', 'type':'country' },
{ 'name':'Italy', 'type':'country' } ]
},
{ 'name':'North America', 'type':'continent', 'children':[
{ 'name':'Mexico', 'type':'country', 'population':'108 million', 'area':'1,972,550 sq km', 'children':[
{ 'name':'Mexico City', 'type':'city', 'population':'19 million', 'timezone':'-6 UTC'},
{ 'name':'Guadalajara', 'type':'city', 'population':'4 million', 'timezone':'-6 UTC' } ]
},
{ 'name':'Canada', 'type':'country', 'population':'33 million', 'area':'9,984,670 sq km', 'children':[
{ 'name':'Ottawa', 'type':'city', 'population':'0.9 million', 'timezone':'-5 UTC'},
{ 'name':'Toronto', 'type':'city', 'population':'2.5 million', 'timezone':'-5 UTC' }]
},
{ 'name':'United States of America', 'type':'country' } ]
},
{ 'name':'South America', 'type':'continent', children:[
{ 'name':'Brazil', 'type':'country', 'population':'186 million' },
{ 'name':'Argentina', 'type':'country', 'population':'40 million' } ]
} ]
}
Custom Data Types: The following example uses custom data types (items with custom data types):
{ 'identifier': 'abbr',
'label': 'name',
'items': [
{ 'abbr':'ec', 'name':'Ecuador', 'capital':'Quito' },
{ 'abbr':'eg', 'name':'Egypt', 'capital':'Cairo' },
{ 'abbr':'sv', 'name':'El Salvador', 'capital':'San Salvador' },
{ 'abbr':'gq', 'name':'Equatorial Guinea', 'capital':'Malabo' },
{ 'abbr':'er',
'name':'Eritrea',
'capital':'Asmara',
'independence':{'_type':'Date', '_value':"1993-05-24T00:00:00Z"} // May 24, 1993 in ISO-8601 standard
},
{ 'abbr':'ee',
'name':'Estonia',
'capital':'Tallinn',
'independence':{'_type':'Date', '_value':"1991-08-20T00:00:00Z"} // August 20, 1991 in ISO-8601 standard
},
{ 'abbr':'et',
'name':'Ethiopia',
'capital':'Addis Ababa' }
]}
Note: For custom data types, ItemFileStore looks for attributes that have an object format value and contains the following two specific attributes:
_typetypeMap which constructor should be used to instantiate the custom data type._valueNOTE: The top level wrapper of the input for each of these examples is a JavaScript object. It has the following basic attributes that define the list of items that constitute the data and meta information about them:
The constructor for ItemFileReadStore takes the following possible parameters in its keyword arguments:
Custom data types are a way to specify how the store should interpret a value of an attribute on an 'item' when it is parsing and loading the store from the ItemFile format. The ItemFileReadStore has one built in custom data type; the 'Date' object. It, by default, maps attribute values of {_type: "Date" _value: "some ISO string"} to a new Date instance instead of treating that JS object as a child item with attributes of '_type' and '_value'. The ItemFileReadStore also allows users to define their own custom types so that they can control how the information in the ItemFile format is interpreted. There are a couple of ways to map custom data types. There is a simple mapping method and general purpose mapping method that are described in the following sections.
The direct constructor approach is the simplest way to map a type. This example assumes that the value stored in _value can be used as the parameter to the constructor for an object:
var typeMap = {
"Color": dojo.Color,
...
};
General purpose mapping is intended for cases where you cannot directly pass the value of _value into a constructor. A good example of this is how Date is mapped internally in ItemFileReadStore. This is used because ItemFileReadStore reads in the _value for a date as a serialized ISO string, which is not a format the general JavaScript Date object understands.
The following example shows the Date serialization load from an ISOString format:
var typeMap = {
"Date": {
type: Date,
deserialize: function(value){
return dojo.date.stamp.fromISOString(value);
}
}
};
The fetch method query syntax for ItemFileReadStore is simple and straightforward. It allows a list of attributes to match against in an AND fashion. For example, a query object that looks like the following example will locate all items that have attributes of those names that match both of those values:
{ foo:"bar", bit:"bite"}
Note that ItemFileReadStore supports the use of wild cards (multi-character * and single character ?) in its attribute value matching.
To find all items with attribute foo that start with bar, the query would be:
{ foo:"bar*"}
To find all items with attribute foo the value of which ends with ar and ignoring only the first character, the query would be:
{ foo:"?ar"}
NOTE: Other stores should follow the same semantics in defining queries for consistency.
For these examples, we'll assume a data source as defined by the example data format in this page unless otherwise specified.
var store = new dojo.data.ItemFileReadStore({url: "geography.json"});
var gotContinents = function(items, request){
for (var i = 0; i < items.length; i++){
var item = items[i];
console.log("Located continent: " + store.getLabel(item));
}
}
var request = store.fetch({query: {type:"continent"}, onComplete: gotContinents});
var store = new dojo.data.ItemFileReadStore({url: "geography.json"});
var gotNames= function(items, request){
for (var i = 0; i < items.length; i++){
var item = items[i];
console.log("Located name that started with A: " + store.getLabel(item));
}
}
var request = store.fetch({query: {name:"A*"}, queryOptions: {ignoreCase: true}, onComplete: gotNames});
var dataItems = {
identifier: 'name',
label: 'name',
items: [
{name: 'John Smith'},
{name: 'Bob Smith'},
{name: 'Nancy Smith}',
{name: 'John Doe'}
]
};
var store = new dojo.data.ItemFileReadStore({data: dataItems});
var gotNames= function(items, request){
for (var i = 0; i < items.length; i++){
var item = items[i];
console.log("Located name that started with J: " + store.getLabel(item));
}
}
var request = store.fetch({query: {name:"J*"}, queryOptions: {ignoreCase: true}, onComplete: gotNames});
For further examples refer to the Using Datastores section of the Dojo book or refer to the test cases for dojo.data provided in the tests sub-directory of your dojo distribution.
Dojo core provides the ItemFileWriteStore store as an extension to ItemFileReadStore that adds on the dojo.data.api.Write and dojo.data.api.Notification API support to ItemFileReadStore. It was specifically created as a separate class so that if you only need read capability, you do not incur the download penalty of the write and notification API support if you won't use it. If your application needs to write to the ItemFileStore instead of just Read, then ItemFileWriteStore is the store you should instantiate. The input data format is identical to ItemFileReadStore.
The following dojo.data APIs are implemented by ItemFileWriteStore
The constructor for ItemFileWriteStore takes the same parameters as ItemFileReadStore these are the following possible parameters in its keyword arguments:
The custom type mapping for the ItemFileWriteStore follows the same conventions as the ItemFileReadStore. The only caveat is, that for general purpose mappings, you must also provide a serialize function for mapping so the data can be rendered back out appropriately. For simple mapping, object.toString() is sufficient.
The direct constructor approach is the simplest way to map a type. This one assumes that the value stored in _value can be used as the parameter to the constructor for an object. When serializing this back to the ItemFileFormat, this assumes that object.toString() is sufficient for the _value value as shown in the following example:
var typeMap = {
"Color": dojo.Color,
...
};
The general purpose mapping is intended for cases in which you cannot directly pass the value of _value into a constructor. A good example of this is how Date is mapped internally in the ItemFileReadStore. This is used because ItemFileReadStore reads in the _value for a date as a serialized ISO string, which is not a format the general JavasScript Date object understands.
The following example shows date serialization and deserialization mapping:
var typeMap = {
"Date": {
type: Date,
deserialize: function(value){
return dojo.date.stamp.fromISOString(value);
},
serialize: function(object){
return dojo.date.stamp.toISOString(object);
}
}
};
The query syntax for ItemFileWriteStore is identical to the query syntax of ItemFileReadStore so see that section for more information.
For these examples, we'll assume a datasource as defined by the following example data:
{ identifier: 'abbr',
label: 'name',
items: [
{ abbr:'ec', name:'Ecuador', capital:'Quito' },
{ abbr:'eg', name:'Egypt', capital:'Cairo' },
{ abbr:'sv', name:'El Salvador', capital:'San Salvador' },
{ abbr:'gq', name:'Equatorial Guinea', capital:'Malabo' },
{ abbr:'er', name:'Eritrea', capital:'Asmara' },
{ abbr:'ee', name:'Estonia', capital:'Tallinn' },
{ abbr:'et', name:'Ethiopia', capital:'Addis Ababa' }
]}
var store = new dojo.data.ItemFileWriteStore({url: "countries.json"});
var usa = store.newItem({abbr: 'us', name: 'United States of America', capital: 'Washington DC'});
function saveDone(){
alert("Done saving.");
}
function saveFailed(){
alert("Save failed.");
}
store.save({onComplete: saveDone, onError: saveFailed});
The save method by itself only updates the in-memory copy. To write the store back to the server, you need to override the extension point "_saveCustom". In markup language, it'd look something like:
You could also extend ItemFileWriteStore using Dojo's inheritance facilities:
dojo.declare("CustomItemFileWriteStore", ItemFileWriteStore, {
_saveCustom: function(saveCompleteCallback, saveFailedCallback){
// xhrPost/xhrPut your data back to your server (convert it to the server format first if need be)
// 'this' keyword refers to the ItemFileWriteStore instance being extended
saveCompleteCallback();
}
});
For further examples refer to the Using Datastores section of the Dojo book or refer to the test cases for dojo.data provided in the tests sub-directory of your dojo distribution.
CsvStore is a simple read-only store provided by Dojo and contained in the DojoX project. CsvStore is a read interface that works with CSV formated data files. The CSV file format is commonly known to folks who work regularly with spread sheet data. Like ItemFileReadStore, CsvStore reads the contents from an http endpoint or a JavaScript Data object that contains CSV formatted data. The following is an example of a CSV data source:
Title, Year, Producer City of God, 2002, Katia Lund Rain,, Christine Jeffs 2001: A Space Odyssey, , Stanley Kubrick "This is a ""fake"" movie title", 1957, Sidney Lumet Alien, 1979 , Ridley Scott "The Sequel to ""Dances With Wolves.""", 1982, Ridley Scott "Caine Mutiny, The", 1954, "Dymtryk ""the King"", Edward"
Note that in the above data, the first row is always assumed to be the column names. Those are what get assigned as the attribute names for the CSV items. Each row in the CSV data is treated as a single item.
The following dojo.data APIs are implemented by CsvStore
The constructor for CsvStore takes three possible parameters in its keyword arguments as defined in the following list:
The fetch method query syntax for CsvStore is simple and straightforward. It allows a list of attributes to match against in an AND fashion, just like ItemFileReadStore. For example, a query object that looks like the following example will locate all items that have attributes of those names that match both of those values:
{ foo:"bar", bit:"bite"}
Note that CsvStore supports the use of wild cards (multi-character * and single character ?) in its attribute value matching.
To find all items with attribute foo that start with bar, the query would be:
{ foo:"bar*"}
To find all items with attribute foo the value of which ends with ar and ignoring only the first character, the query would be:
{ foo:"?ar"}
NOTE: Other stores should follow the same semantics in how it defines its queries for consistency.
Assume a data source as defined by the example data format in this page.
Ridley Scottvar store = new dojox.data.CsvStore({url: "movies.csv", label: "Title"});
var gotMovies = function(items, request){
for (var i = 0; i < items.length; i++){
var item = items[i];
console.log("Located movie: " + store.getLabel(item);
}
}
var request = store.fetch({query: {Producer:"Ridley Scott"}, onComplete: gotMovies});
var store = new dojo.data.ItemFileReadStore({url: "movies.csv", label: "Title"});
var gotTitles= function(items, request){
for (var i = 0; i < items.length; i++){
var item = items[i];
console.log("Located name that started with A: " + store.getLabel(item);
}
}
var request = store.fetch({query: {Title:"A*"}, queryOptions: {ignoreCase: true}, onComplete: gotTitles});
For further examples refer to the test cases provided in dojox.data.tests.
OpmlStore is a simple read-only store provided by Dojo and contained in the DojoX project. OpmlStore is a read interface to work with Opml formatted XML files. Similar to ItemFileReadStore, OpmlStore reads the contents from an http endpoint or a browser DOM object that contains Opml formatted data.
The following dojo.data APIs are implemented by OpmlStore
The following example shows an Opml data source:
geography.opml 2006-11-10 2006-11-13 Magellan, Ferdinand
Note: An item in OpmlStore is an entry. The atributes defined in the tag make up the attributes that are exposed for that item. Any child items (nested tags) are accessable using the special attribute children.
The constructor for OpmlStore takes the following possible parameters in its keyword args:
ags for it to be effective.The fetch method query syntax for OpmlStore is simple and straightforward. It allows a list of attributes to match against in an AND fashion, just like ItemFileReadStore. For example, the following query object locates all items that have attributes of those names that match both of those values:
{ foo:"bar", bit:"bite"}
Note that OpmlStore supports the use of wild cards (multi-character * and single character ?) in its attribute value matching.
To find all items with attribute foobar, the query would be:
{ foo:"bar*"}
To find all items with attribute foo that value ends with ar, and ignoring only the first character, the query would be:
{ foo:"?ar"}
NOTE: Other stores should follow the same semantics in defining queries for consistency.
For these examples, we'll assume a datasource as defined by the example data format in this page.
Avar store = new dojox.data.OpmlStore({url: "grography.xml", label: "Text"});
var gotContinents = function(items, request){
for (var i = 0; i < items.length; i++){
var item = items[i];
console.log("Located continent: " + store.getLabel(item);
}
}
var request = store.fetch({query: {text: "A*", type: "continent"}, onComplete: gotContinents});
A, case insensitivelyvar store = new dojox.data.OpmlStore({url: "grography.xml", label: "Text"});
var gotContinents = function(items, request){
for (var i = 0; i < items.length; i++){
var item = items[i];
console.log("Located continent: " + store.getLabel(item);
}
}
var request = store.fetch({query: {text: "a*", type: "continent"}, queryOptions: {ignoreCase: true}, onComplete: gotContinents});
For further examples refer to the test cases provided in dojox.data.tests.
Note: available from v1.1 and later
AtomReadStore parses and makes available data stored in Atom XML documents. Atom is a standard for transferring data via XML, similar to RSS but far more powerful.
The AtomReadStore loads a remote Atom XML document from the URL provided to it, and then makes its data available. It supports the following item attributes, mostly taken directly from the Atom specification.
To Be Completed
FlickrRestStore is an implementation of the dojo.data API provides access to the Flickr photo sharing site's REST API. Many advanced features are available, including tag search, sorting on numerous attributes, full text search, support for simultaneous clients, result caching and more.
Dojo has several examples of browser in-memory stores, such as dojo.data.ItemFileReadStore, dojox.data.CsvStore, and dojox.data.OmplStore. While these stores are useful and great examples of how data stores can be used to wrapper accessing data, they are not the only way data is served and processed. In many cases, data stores can wrapper external services. It is those services that perform the querying and filtering of data, and then provide only that as a subset back to the data store for presentation as items.
FlickrRestStore is one such store. The purpose of FlickrRestStore is to wrapper the public photo feed of the Flickr service. Then by simply using the FlickrRestStore store, as you would any data store in Dojo, you now have access to querying the vast repository of public photos made available by others on the Web. Look at http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/data/demos/demo... to see it in action, or look here for some example usages.
The following dojo.data APIs are implemented by FlickrRestStore
FlickrRestStore is built upon FlickrStore, a store which reads from Flickrs more simplistic public API. However, FlickrRestStore provides many more features:
Note: While this store wraps making calls to the Flickr service, as a user, you should still verify that you agree to the terms and conditions by which you are using the public Flickr photo service. Review their terms and conditions, and the API terms and conditions, here.
Another difference between FlickrRestStore and FlickrStore is that, due to the fact that FlickrRestStore works with the Flickr REST APIs, you will need to get a free API key from Flickr. You can do so at http://www.flickr.com/services/api/keys/apply/.
The Flickr service provides its data back in a wide variety of formats (for example, ATOM, RSS, and JSON) but FlickrRestStore only makes use of the JSON format. The following example shows a query that FlickrRestStore processes and the response:
Query the first three photos from a user:
URL: http://www.flickr.com/services/rest/?format=json&method=flickr.people.ge...
Response:
jsonFlickrApi({
"photos":{
"page":1,
"pages":98,
"perpage":3,
"total":"489",
"photo":[
{
"id":"1352049918",
"owner":"44153025@N00",
"secret":"5636009306",
"server":"1111",
"farm":2,
"title":"The Liffey Panorama",
"ispublic":1,
"isfriend":0,
"isfamily":0
},
{
"id":"1351120079",
"owner":"44153025@N00",
"secret":"880bf6a003",
"server":"1027",
"farm":2,
"title":"Many Hands make pretty flowers",
"ispublic":1,
"isfriend":0,
"isfamily":0
},
{
"id":"1322051485",
"owner":"44153025@N00",
"secret":"b7c529335d",
"server":"1110",
"farm":2,
"title":"Wok'n'Roll baby!",
"ispublic":1,
"isfriend":0,
"isfamily":0
}
]
},
"stat":"ok"}
)FlickrRestStore's role is to process the query parameters passed to the dojo.data.api.Read API and generate the appropriate service URL. It then processes the response from the service and handles accessing the items returned from the query. It also provides simple attribute access to all the values.
FlickrRestStore does not have any constructor parameters.
All items returned from FlickrRestStore have the following attributes that can be accessed using the dojo.data.api.Read API to retrieve data about the item:
The fetch method query syntax for FlickrRestStore is simple and straightforward. It allows the following attributes to be set and queried against:
start parameter is used. This is optional.If an attribute is not specified, the default is date-posted
. This is optional.
Note: Unlike many of the other example stores, the FlickrRestStore store cannot do wild-card matching of the attributes. This is because the Flickr public photo feed service cannot do it. In an ideal service implementation, the Flickr service would provide a mechanism by with to pass in wild cards as part of its query parameters.
The following example shows how you would query for the first ten images belonging to a single user, then emit the title, author, and image URL to the console:
var flickrRestStore = new dojox.data.FlickrRestStore();
function onBegin(totalCount, requestObj){
console.log("TOTAL IMAGE COUNT:" + totalCount);
}
function onItem(item, requestObj){
console.log("TITLE: " + flickrStore.getValue(item, "title");
console.log("AUTHOR: " + flickrStore.getValue(item, "author");
console.log("LINK: " + flickrStore.getValue(item, "link");
console.log("IMAGE URL: " + flickrStore.getValue(item, "imageUrl");
console.log("IMAGE URL Small: " + flickrStore.getValue(item, "imageUrlSmall");
console.log("IMAGE URL Medium: " + flickrStore.getValue(item, "imageUrlMedium");
console.log("IMAGE URL Thumbnail: " + flickrStore.getValue(item, "imageUrlThumb");
console.log("DATE TAKEN: " + flickrStore.getValue(item, "dateTaken");
console.log("DATE PUBLISHED: " + flickrStore.getValue(item, "datePublished");
}
function onComplete(items, request){
console.log("DONE!")
}
function onError(error, request){
console.log("FAILED!")
}
var request = {
query: {
userid: "44153025@N00",
apikey: "8c6803164dbc395fb7131c9d54843627"
},
onBegin: onBegin,
onItem: onItem,
onComplete: onComplete,
onError: onError
};
//Get ten photos from user "44153025@N00".
request.start = 0; //start at the beginning
request.count = 10; //Retrieve ten images
flickrRestStore.fetch(request);
//Get ten photos from user "44153025@N00",
//matching the tags volleyball or dublin.
request.start = 0; //start at the beginning
request.count = 10; //Retrieve ten images
request.query.tags = ["volleyball", "dublin"];
//This causes the search to match
//"volleyball" OR "dublin". To do an AND query,
//use request.query.tagmode = "all"
request.query.tagmode = "any";
flickrRestStore.fetch(request);
//Get fifty photos from user "44153025@N00",
//sorting descending on interestingness.
request.start = 0; //start at the beginning
request.count = 50; //Retrieve fifty images
request.query.tags = null; //delete the tags from the previous request
//The sort parameter is an array, as the
//dojo.data API specifies that a READ store should
//support multiple sort attributes.
//However, the Flickr API only supports a single
//sort parameter.
request.query.sort = [
{
//'attribute' could also be "date-taken" or "date-posted"
attribute: "interestingness",
descending: true
}
];
flickrRestStore.fetch(request);
//Get the second page of twenty photos from a given set
request.start = 20;
request.count = 20;
request.query.setid = "72157600959797470";
request.query.sort = null; //Clean up after the last request
flickrRestStore.fetch(request);
//Perform a full text search, retrieving 50 photos
request.start = 0;
request.count = 50;
//clean up after the previous request
request.query.setid = null;
//Finds all photos with "kinsale" in the title or description
request.query.text = "kinsale";
flickrRestStore.fetch(request);For further examples refer to the test cases provided in dojox/data/tests/stores/FlickrRestStore.js.
HtmlTableStore is a simple read-only store provided by Dojo and contained in the DojoX project. HtmlTableStore is a read interface to work with HTML tables with a generally set format. HTML tables are common ways for Web data to be displayed and they can be extremely useful as an alternate representation of data that is displayed in a charting or gauge widget. This store was created so that widgets, that can use dojo.data data stores, can read their input from HTML table data islands in the current page or in a remote page URL. This store implements both dojo.data.api.Read and dojo.data.api.Identity.
The following example shows an HTML table that this store can read:
Books2.html
| isbn | title | author |
|---|---|---|
| A9B57C | Title of 1 | Author of 1 |
| A9B57F | Title of 2 | Author of 2 |
| A9B577 | Title of 3 | Author of 3 |
| A9B574 | Title of 4 | Author of 4 |
| A9B5CC | Title of 5 | Author of 5 |
Note that the table rows in the
The constructor for
The fetch method query syntax for Note that To find all items with attribute To find all items with attribute NOTE: Other stores should follow the same semantics in defining queries for consistency. For these examples, we'll assume a data source as defined by the example data format in this page. For further examples, refer to the test cases provided in
The following dojo.data APIs are implemented by XmlStore
The following is an example of an XML document that this store can read: The constructor for The following functions can be over-ridden to alter save behavior, as described: The fetch method query syntax for Note that To find all items with attribute To find all items with attribute NOTE: Other stores should follow the same query definition semantics for consistency.
For these examples, we'll assume a data source as defined by the example data format in this page. For further examples see the test cases provided in Dojo has several examples of browser in-memory stores, such as Note: While this store wraps making calls to the Flickr service, as a user, you should still verify that you agree to the terms and conditions by which you are using the public flickr photo service. Review their terms and conditions, and the API terms and conditions. The Flickr service provides its data back in a wide variety of formats (for example, ATOM, RSS, and JSON) but Query (all pictures with tags Response:
All items returned from The fetch method query syntax for Note: Unlike all the other example stores, the The following example shows how you would query for all images with the For further examples refer to the test cases provided in New in 1.0, QueryReadStore is very similar to ItemReadStore. They both use JSON as their exchange format. The difference is in the way they query data. ItemReadStore makes one fetch from the server, and handles all sorting and filtering in the client. That's fine for hundreds of records, even thousands. But for hundreds of thousands of records or slow Internet connections, that's less feasible. QueryReadStore makes a request to the server for each sorting or query. This makes it ideal for large datasets with small windows of data, as in dijit.FilteringSelect. A dojo.data request follows a specific JSON format. As an example, suppose we have a FilteringSelect which looks up states. When the user presses "A", the dojo.data request is: Now we want to hand this off to the server. Odds are, your server doesn't recognize incoming JSON, and asking it to do so is too restrictive. Instead, most server queries follow a REST pattern like this: Fortunately, it's easy to translate between the two. You simply subclass QueryReadStore like this: We can place this file into a folder "custom" at the same level as the dojo, dijit and dojox directories of the distribution. (See Creating Your Own Modules for a discussion and alternatives. You can download QueryReadStore.php below (it's also in /dojox/data/tests/stores/QueryReadStore.php) to run this example on a PHP server. The server portion hands over a portion of the states that fits the query. The full client program: tag are the items. The tag is used for defining the attribute name for each column in the table row for an item.
Constructor Parameters
HtmlTableStore takes the following possible parameters in its keyword arguments:
id of the HTML tag that contains the table to read from, in either a remote page (if the URL was passed) or in the current HTML DOM if the url parameter is null. This is required.Query Syntax
HtmlTableStore is simple and straightforward. It allows for a list of attributes to match against in an AND fashion, just like ItemFileReadStore. For example, the following query object will locate all items that have attributes of those names that match both values:{ foo:"bar", bit:"bite"}
HtmlTableStore supports the use of wild cards (multi-character * and single character ?) in its attribute value matching.Examples
foo that start with bar, the query would be:{ foo:"bar*"}
foo that value ends with ar and ignoring only the first character, the query would be: { foo:"?ar"}
Usage Examples
Example 1: Query for all books that start with ISBN: A9B57
var store = new dojox.data.HtmlTableStore({tableId: "books2"});
var gotBooks = function(items, request){
for (var i = 0; i < items.length; i++){
var item = items[i];
console.log("Located book: " + store.getValue(item, "title"));
}
}
var request = store.fetch({query: {isbn:"A9B57*"}, onComplete: gotBooks});
Example 2: Query for all books that start with ISBN: A9B57 Case insensitively
var store = new dojox.data.HtmlTableStore({tableId: "books2"});
var gotBooks = function(items, request){
for (var i = 0; i < items.length; i++){
var item = items[i];
console.log("Located book: " + store.getValue(item, "title");
}
}
var request = store.fetch({query: {isbn:"a9b57*"}, queryOptions: {ignoreCase: true}, onComplete: gotBooks});
Further Examples
dojox.data.tests
.
dojox.data.XmlStore
XmlStore is a store provided by Dojo that is contained in the DojoX project. XmlStore is a read and write interface to basic XML data. XML is a common data interchange format and a store that can work with fairly generic XML documents is useful. The store is designed so that you can over-ride certain functions to get specific behaviors to occur when performing reads and saves.
Constructor Parameters
XmlStore takes the following possible parameters in its keyword arguments:
{"tag_name.item_attribute_name": "@xml_attribute_name", ...} This is optional. This is done so that attributes which are actual XML tag attributes (and not sub-tags of an XML tag), can be referenced.getLabel(). This is optional.Functions intended to be over-ridden to alter save behavior
Query Syntax
XmlStore is simple and straightforward. It allows for a list of attributes to match against in an AND fashion, just like ItemFileReadStore. For example, the following query object will locate all items that have attributes of those names that match both of those values:{ foo:"bar", bit:"bite"}
XmlStore supports the use of wild cards (multi-character * and single character ?) in its attribute value matching.Examples
foo that start with bar, the query would be:{ foo:"bar*"}
foo the value of which ends with ar and ignoring only the first character, the query would be:{ foo:"?ar"}
Usage Examples
Example 1: Query for all books that start with ISBN: A9B57
var store = new dojox.data.XmlStore({url: "books.xml", rootItem: "book"});
var gotBooks = function(items, request){
for (var i = 0; i < items.length; i++){
var item = items[i];
console.log("Located book: " + store.getValue(item, "title");
}
}
var request = store.fetch({query: {isbn:"A9B57*"}, onComplete: gotBooks});
Example 2: Query for all books that start with ISBN: A9B57 Case insensitively
var store = new dojox.data.XmlStore({url: "books.xml", rootItem: "book"});
var gotBooks = function(items, request){
for (var i = 0; i < items.length; i++){
var item = items[i];
console.log("Located book: " + store.getValue(item, "title");
}
}
var request = store.fetch({query: {isbn:"a9b57*"}, queryOptions: {ignoreCase: true}, onComplete: gotBooks});
Further Examples
dojox.data.tests.dojox.data.FlickrStore
dojo.data.ItemFileReadStore, dojox.data.CsvStore, and dojox.data.OmplStore. While these stores are useful and great examples of how data stores can be used to wrapper accessing data, they are not the only way data is served and processed. In many cases, data stores can wrapper external services. It is those services that perform the querying and filtering of data, and then provide only that as a subset back to the data store for presentation as items.FlickrStore is one such store. The purpose of FlickrStore is to wrapper the public photo feed of the Flickr service. Then by simply using the FlickrStore store, as you would any data store in Dojo, you now have access to querying the vast repository of public photos made available by others on the Web.FlickrStore only makes use of the JSON format. The following example shows a query that FlickrStore processes and the response:animals, foxes, and cute):http://api.flickr.com/services/feeds/photos_public.gne?tags=animals,bats,cute&format=json&tagmode=all
jsonFlickrFeed({
"title": "Photos from everyone tagged animals, foxes and cute",
"link": "http://www.flickr.com/photos/",
"description": "",
"modified": "2007-05-24T09:35:27Z",
"generator": "http://www.flickr.com/",
"items": [
{
"title": "Ceramic Figures",
"link": "http://www.flickr.com/photos/36362445@N00/511998141/",
"media": {"m":"http://farm1.static.flickr.com/228/511998141_7b8398c3eb_m.jpg"},
"date_taken": "2006-04-04T10:21:43-08:00",
"description": "<p><a href="http://www.flickr.com/people/36362445@N00/">travellingcharl</a> posted a photo:</p> <p><a href="http://www.flickr.com/photos/36362445@N00/511998141/" title="Ceramic Figures"><img src="http://farm1.static.flickr.com/228/511998141_7b8398c3eb_m.jpg" width="240" height="180" alt="Ceramic Figures" /></a></p> <p>Ceramic figurines inside the Shinto shrine.</p>",
"published": "2007-05-24T09:35:27Z",
"author": "nobody@flickr.com (travellingcharl)",
"tags": "cute animals japan ceramic geocaching coins toyko foxes naritatbstation3"
},
{
"title": "Red Fox pup",
"link": "http://www.flickr.com/photos/norwick/301289990/",
"media": {"m":"http://farm1.static.flickr.com/104/301289990_da7413890b_m.jpg"},
"date_taken": "2005-06-09T16:17:49-08:00",
"description": "<p><a href="http://www.flickr.com/people/norwick/">bluebird's</a> posted a photo:</p> <p><a href="http://www.flickr.com/photos/norwick/301289990/" title="Red Fox pup"><img src="http://farm1.static.flickr.com/104/301289990_da7413890b_m.jpg" width="240" height="180" alt="Red Fox pup" /></a></p> <p>Are you sure it's save to come out!</p>",
"published": "2006-11-19T22:14:47Z",
"author": "nobody@flickr.com (bluebird's)",
"tags": "wild summer canada cute nature beauty field animals landscape tiere scenery jung wilde sommer wildlife natur young feld felder adorable peaceful canadian alberta summertime prairie aussicht prairies landschaft foxes alert tier countrylife predators kanada redfox perky okotoks junger rotfuchs kanadische foxpups roterfuchs"
}
]
})
FlickrStore's role is to process the query parameters passed to the dojo.data.api.Read API and generate the appropriate service URL. It then processes the response from the service and handles accessing the items returned from the query. It also provides simple attribute access to all the values.Constructor Parameters
FlickrStore does not have any constructor parameters.Item Attributes
FlickrStore have the following attributes that can be accessed using the dojo.data.api.Read API to retrieve data about the item:
flickrStore.getValue(item, "tags") returns the first tag, flickrStore.getValues(item, "tags") returns all tags.Query Syntax
FlickrStore is simple and straightforward. It allows the following attributes to be set and queried against:
all or any and the default is any.FlickrStore store cannot do wild-card matching of the attributes. This is because the Flickr public photo feed service cannot do it. In an ideal service implementation, the Flickr service would provide a mechanism by with to pass in wild cards as part of its query parameters. Also, the Flickr public feed API limits the number of returned photos to a maximum of twenty.Usage Examples
3dny tag, then emit the title, author, and image URL to the console:var flickrStore = new FlickrStore();
function onItem(item, requestObj){
console.log("TITLE: " + flickrStore(item, "title");
console.log("AUTHOR: " + flickrStore(item, "author");
console.log("IMAGE URL: " + flickrStore(item, "imageUrl");
}
function onComplete(items, request){
console.log("DONE!")
}
function onError(error, request){
console.log("FAILED!")
}
//Get the photos tagged 3dny...
flickrStore.fetch({
query: {tags:"3dny"},
onItem: onItem,
onComplete: onComplete,
onError: onError
});
Further Examples
dojox/data/tests/stores/FlickrStore.js<.code>. In addition, there are demos using the FlickrStore store available in dojox/data/demos/.dojox.data.QueryReadStore (1.0)
Query Translation
{
query: {name: "A*"},
queryOptions: {ignoreCase: true},
sort: [{attribute:"name", descending:false}],
start: 0,
count: 10
}
states.php?q=A*
dojo.provide("custom.ComboBoxReadStore");
dojo.declare("custom.ComboBoxReadStore", dojox.data.QueryReadStore, {
fetch:function(request) {
request.serverQuery = {q:request.query.name};
// Call superclasses' fetch
return this.inherited("fetch", arguments);
}
});
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>QueryReadStore Demo</title>
<style type="text/css">
@import "http://o.aolcdn.com/dojo/1.0.0/dijit/themes/tundra/tundra.css";
@import "http://o.aolcdn.com/dojo/1.0.0/dojo/dojo.css"
</style>
<script type="text/javascript" src="http://o.aolcdn.com/dojo/1.0.0/dojo/dojo.xd.js"
djConfig="parseOnLoad: true"></script>
<script type="text/javascript">
dojo.require("dojo.parser");
dojo.require("dojox.data.QueryReadStore");
dojo.require("dijit.form.FilteringSelect");
dojo.require("custom.ComboBoxReadStore");
</script>
</head>
<body class="tundra">
<div dojoType="ComboBoxReadStore" jsId="store"
url="QueryReadStore.php"
requestMethod="get">
</div>
State: <input id="fs" dojoType="dijit.form.FilteringSelect" store="store" pageSize="5" />
</body></html>