#

# Example: Basic Recordset

The Recordset Utility provides a standard way for dealing with a collection of similar objects known as records. The `recordset-base` sub-module provides the base Recordset implementation.

This example demonstrates some standard ways to interact with the Recordset. Click on the buttons below to play around with a Recordset created with state information.

State | Population | Land Area
--- | --- | ---

A Recordset in its simplest form is a collection of records, where records can be considered to be object literals. Recordset allows the user to handle this collection of records with a consistent API.

Recordset-base provides an API for adding, removing and updating record(s). It also creates a hash table of all the records by their IDs, to allow for fast retrieval.

###### Records vs. Object Literals

You can interact with a Recordset instance by simply passing in object literals. Recordset will convert them into record instances under the hood. If you want the object literal back from the Recordset, simply use the `getValue` method on a record instance. Optionally, a string can be passed into the `getValue` method if you only want a specific property back. Not passing in an argument returns the entire object bag that the record is holding on to.

### Working with a Recordset

This section describes how to use the Recordset Utility in further detail. It contains the following subsections:

- Initializing a Recordset
- Adding Records
- Removing Records
- Updating Records
- Emptying a Recordset
- Using the Hash Table

#### Initializing a Recordset

    YUI().use("recordset-base", function(Y) {
        var data = [
    		{a:3, b:2, c:1},
    		{a:9, b:8, c:7},
    		{a:1, b:2, c:3}
    	],

    	//Recordset is created with the objects from the data array
    	myRecordset = new Y.Recordset({records: data}),

    	//Empty Recordsets can also be created
    	anEmptyRecordset = new Y.Recordset();

    });

#### Adding Records

Once initialized, the Recordset can be modified by CRUD methods provided by the API. Add single or multiple objects/records to the Recordset by calling the `add` method.

    YUI().use("recordst-base", function(Y) {
        var data = [
            {key:"a", label:"Column A"},
            {key:"b", label:"Column B"},
            {key:"c", label:"Column C"}
        ],

    	myRecordset = new Y.Recordset({records:data});

    	//Adding a single record to the end of a Recordset
    	myRecordset.add({key:"d", label:"Column D"});

    	//Adding multiple records at the 2nd index of the Recordset
    	myRecordset.add([
    		{key:"e", label:"Column E"},
    		{key:"f", label:"Column F"}
    	], 2);
    });

#### Removing Records

Similarly, items can also be removed from the Recordset using the `remove` method.

    YUI().use("recordset-base", function(Y) {
        var data = [
            {key:"a", label:"Column A"},
            {key:"b", label:"Column B"},
            {key:"c", label:"Column C"}
        ],

    	myRecordset = new Y.Recordset({records:data});

    	//removes the record stored at index 2 (in this case {key:"c", label:"Column C"} is removed)
    	myRecordset.remove(2);

    	//Removes 2 records starting at index zero
    	myRecordset.remove(0,2);
    });

#### Updating Records

You can overwrite existing records in the Recordset through the `update` method. This method takes 2 arguments, the first being an object/record or array of objects/records, and the second being the index at which to start the update process. When updating a Recordset, any records found within the index/indices that are to be updated will be overwritten. However, you can get an object bag with these overwritten records back if you hook onto the 'update' event.

    YUI().use("recordset-base", function(Y) {
        var data = [
            {key:"a", label:"Column A"},
            {key:"b", label:"Column B"},
            {key:"c", label:"Column C"}
        ],

    	myRecordset = new Y.Recordset({records:data});

    	//overwite the record at index 2 with the following record
    	myRecordset.update({key:"d", label:"Column D"}, 2);

    	//You can also update multiple records at a time.
    	//Here we are updating indices 0 and 1 of the Recordset with the corresponding two objects.
    	myRecordset.update([
    		{key:"e", label:"Column E"},
    		{key: "f", label: "Column F"}
    	], 0);
    });

#### Emptying a Recordset

Emptying the Recordset is easily done with the `empty` method.

    YUI().use("recordset-base", function(Y) {
        var data = [
            {key:"a", label:"Column A"},
            {key:"b", label:"Column B"},
            {key:"c", label:"Column C"}
        ],

    	myRecordset = new Y.Recordset({records:data});
    	myRecordset.empty();
    });

#### Using the Hash Table

The recordset-base submodule has a built-in hash table that hashes records by their IDs. IDs are set during initialization of each individual record and are stored as ATTRS. You should not modify the ID of a record, but you can access it by calling `myRecord.get('id')`.

Under the hood, the hash table is kept in sync with the Recordset by hooking onto the events that Recordset fires (namely 'add', 'remove', 'update', and 'empty'). The ID hash table is an easy way to retrieve records that will be needed often.

If you need hash tables that store records by keys other than IDs, refer to the RecordsetIndexer plugin.

    YUI().use("recordset-base", function(Y) {
        var data = [
            {key:"a", label:"Column A"},
            {key:"b", label:"Column B"},
            {key:"c", label:"Column C"}
        ],

    	myRecordset = new Y.Recordset({records:data});

    	//Store some IDs that I will need access to later
    	var record2_ID = myRecordset.getRecord(1).get('id'),
    	record3_ID = myRecordset.getRecord(2).get('id');

    	//Get Access to the Hash Table
    	var hashTable = myRecordset.get('table');

    	//Get Records back using IDs
    	var record2 = hashTable[record2_ID];
    	var record3 = hashTable[record3_ID];

    	//Remove Record from index 1 (record2)
    	myRecordset.remove(1);

    	hashTable[record2_ID]; //this will now be undefined as that record was removed.
    	hashTable[record3_ID]; //this still points to the correct record (record3)
    });

### Events

The Recordset Utility fires 5 custom events in addition attribute change events: 'add', 'remove', 'update', 'empty' and 'change'. 'change' in particular, is a high-level event that is fired after any modifications to the Recordset are made (ie: after 'add', 'remove', 'update', 'empty'). Details on these events are shown below.

Event | Payload
--- | ---
`add` | added: an array of new records that were added (can contain a single record) index: index that the addition started at
`remove` | removed: an array of records that were removed (can contain a single record) index: index that the removals started at range: range of records that were removed
`update` | updated: an array of records that updated (added to the Recordset) index: index that the updates started at range: range of records that were updated
`empty` | Empty object bag
`change` | type: The event that caused the change (ie: "recordset:add", "recordset:update") details:The payload of the event that caused the change. This object will have different keys, based on what `type` is. (ie: If `type` is "recordset:add", then `details` will contain the `added` and `index` keys.)

Refer to the API documentation to get a full list of events inherited by Recordset.