recordset.js revision 732396f61c35735c33d8afc07abd55d3dba1f22c
* Retrieve a particular (or all) values from the object * @param field {string} (optional) The key to retrieve the value from. If not supplied, the entire object is returned. * @description Unique ID of the record instance * @description The object stored within the record instance * @submodule recordset-base * The Recordset utility provides a standard way for dealing with * a collection of similar objects. * Provides the base Recordset implementation, which can be extended to add * additional functionality, such as custom indexing. sorting, and filtering. * @param config {Object} Configuration object literal with initial attribute values * Publish default functions for events. Create the initial hash table. If this._items does not exist, then create it and set it to an empty array. The reason the conditional is needed is because of two scenarios: Instantiating new Y.Recordset() will not go into the setter of "records", and so it is necessary to create this._items in the initializer. Instantiating new Y.Recordset({records: [{...}]}) will call the setter of "records" and create this._items. In this case, we don't want that to be overwritten by []. //set up event listener to fire events when recordset is modified in anyway //Fires recordset changed event when any updates are made to the recordset //Fires appropriate hashTable methods on "add", "remove", "update" and "empty" events * Helper method called upon by add() - it is used to create a new record(s) in the recordset * @return {Y.Record} A Record instance. //index = (Lang.isNumber(index) && (index > -1)) ? index : len; //if records are to be added one at a time, push them in one at a time * Helper method called upon by remove() - it is used to remove record(s) from the recordset * Helper method called upon by empty() - it is used to empty the recordset * Helper method called upon by update() - it is used to update the recordset //--------------------------------------------- //--------------------------------------------- * Method called whenever "recordset:add" event is fired. It adds the new record(s) to the hashtable. * Method called whenever "recordset:remove" event is fired. It removes the record(s) from the recordset. * Method called whenever "recordset:update" event is fired. It updates the record(s) by adding the new ones and removing the overwritten ones. //deletes the object key that held on to an overwritten record and //creates an object key to hold on to the updated record * Method called whenever "recordset:empty" event is fired. It empties the hash table. * Sets up the hashtable with all the records currently in the recordset //If it is not an empty recordset - go through and set up the hash table. * Helper method - it takes an object bag and converts it to a Y.Record * @method _changeToRecord * @param obj {Object || Y.Record} Any objet literal or Y.Record instance * @return {Y.Record} A Record instance. //--------------------------------------------- //--------------------------------------------- * Event that is fired whenever the recordset is changed. Note that multiple simultaneous changes still fires this event once. * (ie: Adding multiple records via an array will only fire this event once at the completion of all the additions) * @method _recordSetUpdated this.
on([
'update',
'add',
'remove',
'empty'],
* Syncs up the private hash methods with their appropriate triggering events. //--------------------------------------------- //--------------------------------------------- * Returns the record with particular ID or index * @param i {String, Number} The ID of the record if a string, or the index if a number. * @return {Y.Record} An Y.Record instance return this.
get(
'table')[i];
* Returns the record at a particular index * @method getRecordByIndex * @param i {Number} Index at which the required record resides * @return {Y.Record} An Y.Record instance * Returns a range of records beginning at particular index * @method getRecordsByIndex * @param index {Number} Index at which the required record resides * @param range {Number} (Optional) Number of records to retrieve. The default is 1 * @return {Array} An array of Y.Record instances //Range cannot take on negative values * Returns the length of the recordset * @return {Number} Number of records in the recordset * Returns an array of values for a specified key in the recordset * @param index {Number} (optional) Index at which the required record resides * @return {Array} An array of values for the given key * Adds one or more Records to the RecordSet at the given index. If index is null, * then adds the Records to the end of the RecordSet. * @param oData {Y.Record, Object Literal, Array} A Y.Record instance, An object literal of data or an array of object literals * @param index {Number} (optional) Index at which to add the record(s) * @return {Y.Recordset} The updated recordset instance //Passing in array of object literals for oData * Removes one or more Records to the RecordSet at the given index. If index is null, * then removes a single Record from the end of the RecordSet. * @param index {Number} (optional) Index at which to remove the record(s) from * @param range {Number} (optional) Number of records to remove (including the one at the index) * @return {Y.Recordset} The updated recordset instance //Default is to only remove the last record - the length is always 1 greater than the last index //this._recordRemoved(remRecords, index); //return ({data: remRecords, index:index}); * @return {Y.Recordset} The updated recordset instance * Updates the recordset with the new records passed in. Overwrites existing records when updating the index with the new records. * @param data {Y.Record, Object Literal, Array} A Y.Record instance, An object literal of data or an array of object literals * @param index {Number} (optional) The index to start updating from. * @return {Y.Recordset} The updated recordset instance //Whatever is passed in, we are changing it to an array so that it can be easily iterated in the _defUpdateFn method * @description An array of records that the recordset is storing // give them a copy, not the internal object return new Y.
Array(
this.
_items);
//For allData passed in here, see if each instance is a Record. //If its not, change it to a record. //Then push it into the array. //This conditional statement handles creating empty recordsets //initialization of the attribute must be done before the first call to get('records') is made. //if lazyAdd were set to true, then instantiating using new Y.Recordset({records:[..]}) would * @description A hash table where the ID of the record is the key, and the record instance is the value. //Initially, create the hash table with all records currently in the recordset * @description The ID to use as the key in the hash table. //set to readonly true. If you want custom hash tables, you should use the recordset-indexer plugin. },
'@VERSION@' ,{
requires:[
'base',
'arraylist']});
YUI.
add(
'recordset-sort',
function(Y) {
* @submodule recordset-sort * Plugin that adds default and custom sorting functionality to the Recordset utility * @description The last properties used to sort. Consists of an object literal with the keys "field", "desc", and "sorter" * @attribute lastSortProperties * @description Default sort function to use if none is specified by the user. * Takes two records, the key to sort by, and whether sorting direction is descending or not (boolean). * If two records have the same value for a given key, the ID is used as the tie-breaker. * @attribute defaultSorter * @description A boolean telling if the recordset is in a sorted state. * @attribute defaultSorter * Sets up the default function to use when the "sort" event is fired. //Toggle the isSorted ATTR based on events. //Remove events dont affect isSorted, as they are just popped/sliced out * Method that all sort calls go through. * Sets up the lastSortProperties object with the details of the sort, and passes in parameters * to the "defaultSorter" or a custom specified sort function. this.
set(
'lastSortProperties', e);
//have to work directly with _items here - changing the recordset. * @param field {string} A key to sort by. * @param desc {boolean} True if you want sort order to be descending, false if you want sort order to be ascending * Resorts the recordset based on the last-used sort parameters (stored in 'lastSortProperties' ATTR) var p =
this.
get(
'lastSortProperties');
* Reverses the recordset calling the standard array.reverse() method. * Sorts the recordset based on the last-used sort parameters, but flips the order. (ie: Descending becomes ascending, and vice versa). var p =
this.
get(
'lastSortProperties');
//If a predefined field is not provided by which to sort by, throw an error },
'@VERSION@' ,{
requires:[
'recordset-base',
'arraysort',
'plugin']});
YUI.
add(
'recordset-filter',
function(Y) {
* @submodule recordset-filter * Plugin that provides the ability to filter through a recordset. * Uses the filter methods available on Y.Array (see arrayextras submodule) to filter the recordset. * Filter through the recordset with a custom filter function, or a key-value pair. * @param f {Function, String} A custom filter function or a string representing the key to filter by. * @param v {any} (optional) If a string is passed into f, this represents the value that key should take in order to be accepted by the filter. Do not pass in anything if 'f' is a custom function * @return recordset {Y.Recordset} A new filtered recordset instance //If a key-value pair is passed in, generate a custom function //TODO: PARENT CHILD RELATIONSHIP //return new host.constructor({records:arr}); * The inverse of filter. Executes the supplied function on each item. * Returns a new Recordset containing the items that the supplied * function returned *false* for. * @param {Function} f is the function to execute on each item. * @return {Y.Recordset} A new Recordset instance containing the items on which the supplied function * Iterates over the Recordset, returning a new Recordset of all the elements * that match the supplied regular expression * @param {pattern} pattern The regular expression to test against * @return {Y.Recordset} A Recordset instance containing all the items in the collection that * produce a match against the supplied regular expression. * If no items match, an empty Recordset instance is returned. //TODO: Add more pass-through methods to arrayextras },
'@VERSION@' ,{
requires:[
'recordset-base',
'plugin',
'array-extras']});
YUI.
add(
'recordset-indexer',
function(Y) {
* @submodule recordset-indexer * Plugin that provides the ability to store multiple custom hash tables referencing records in the recordset. * This utility does not support any collision handling. New hash table entries with a used key overwrite older ones. * @class RecordsetIndexer NAME:
"recordsetIndexer",
* @description Collection of all the hashTables created by the plugin. * The individual tables can be accessed by the key they are hashing against. //setup listeners on recordset events * Setup the hash table for a given key with all existing records in the recordset * @param key {string} A key to hash by. * @return obj {object} The created hash table //--------------------------------------------- //--------------------------------------------- * Updates all hash tables when a record is added to the recordset var tbl =
this.
get(
'hashTables');
//Go through every hashtable that is stored. //in each hashtable, look to see if the key is represented in the object being added. //if the object being added has a key which is being stored by hashtable v, add it into the table. * Updates all hash tables when a record is removed from the recordset var tbl =
this.
get(
'hashTables'),
//Go through every hashtable that is stored. //in each hashtable, look to see if the key is represented in the object being deleted. //if the hashtable has a key storing a record, and the key and the record both match the record being deleted, delete that row from the hashtable * Updates all hash tables when the recordset is updated (a combination of add and remove) //TODO: It will be more performant to create a new method rather than using _defAddHash, _defRemoveHash, due to the number of loops. See commented code. var tbl = this.get('hashTables'), reckey; Y.each(tbl, function(v, key) { Y.each(e.updated, function(o, i) { //delete record from hashtable if it has been overwritten reckey = o.getValue(key); //the undefined case is if more records are updated than currently exist in the recordset. if (e.overwritten[i] && (v[e.overwritten[i].getValue(key)] === e.overwritten[i])) { delete v[e.overwritten[i].getValue(key)]; // if (v[reckey] === o) { // //add the new updated record if it has a key that corresponds to a hash table // if (o.getValue(key)) { // v[o.getValue(key)] = o; //--------------------------------------------- //--------------------------------------------- * Creates a new hash table. * @param key {string} A key to hash by. * @return tbls[key] {object} The created hash table * Get a hash table that hashes records by a given key. * @param key {string} A key to hash by. * @return table {object} The created hash table return this.
get(
'hashTables')[
key];
},
'@VERSION@' ,{
requires:[
'recordset-base',
'plugin']});
YUI.
add(
'recordset',
function(Y){},
'@VERSION@' ,{
use:[
'recordset-base',
'recordset-sort',
'recordset-filter',
'recordset-indexer']});