API Docs for:
Show:

File: gallery-js/datatable-formatters.js

/**
 Define a "named" Column Formatters object and attach it to the Y.DataTable namespace.
 The named formatters are defined as a series of format strings that are typically used by the
 data formatting function Y.DataType.Number.format and Y.DataType.Date.format.

 The function [`namedFormatter`](#method_namedFormatter) is defined that can be used to call as a column formatter which
 formats the column cell using the [`formatStrings`](#property_formatStrings) object.

 This module includes an override of the [Y.DataTable.BodyView._createRowHTML](#method_Y.DataTable.BodyView._createRowHTML) method.
 Therefore implementers shouldn't call the `namedFormatter` method directly because the overridden method handles the call if the
 entered formatter string name is recognized.

 ###Usage
 The format string names can be used in a column configuration object as follows;

		var dt1 = new Y.DataTable({
            data: some_data,
            columns: [
                { key:"start_date", label:"Start", formatter:"fullDate" },
                { key:"end_date", label:"End", formatter:"default", 
                  formatOptions:{ type:'date', formatConfig:{ format:'%F' } } },
                { key:"qty", label:"Inventory Qty", formatter:"comma" },
                { key:"cost", label:"Carried Cost", formatter:"currency",
                  formatConfig:{ prefix:'£', thousandsSeparator:","} }
    	    ]
		}).render();

 ####Pre-Defined `formatStrings` settings; (specifically, Y.DataTable.Formatters.formatStrings)
 For "number" formatting, using [Y.DataType.Number](http://yuilibrary.com/yui/docs/api/classes/DataType.Number.html#method_format).

 <table><tr><th>string</th><th>Formatter Object</th><th>Formatted Example</th></tr>
 <tr><td>`general`</td><td>{ decimalPlaces:0 }</td><td>123457</td></tr>
 <tr><td>`general2`</td><td>{ decimalPlaces:2 }</td><td>123456.79</td></tr>
 <tr><td>`currency`</td><td>{ prefix:'$', decimalPlaces:0, thousandsSeparator:',' }</td><td>$ 123,457</td></tr>
 <tr><td>`currency2`</td><td>{ prefix:'$', decimalPlaces:2, thousandsSeparator:',' }</td><td>$ 123,456.78</td></tr>
 <tr><td>`currency3`</td><td>{ prefix:'$', decimalPlaces:3, thousandsSeparator:',' }</td><td>$ 123,457.789</td></tr>
 <tr><td>`comma`</td><td>{ decimalPlaces:0, thousandsSeparator:','}</td><td>123,457</td></tr>
 <tr><td>`comma2`</td><td>{ decimalPlaces:2, thousandsSeparator:','}</td><td>123,456.78</td></tr>
 <tr><td>`comma3`</td><td>{ decimalPlaces:3, thousandsSeparator:','}</td><td>123,457.789</td></tr>
 </table>

 For "date" formatting, using [Y.DataType.Date](http://yuilibrary.com/yui/docs/api/classes/DataType.Date.html#method_format).
 <br/>(Please refer to the Date.format method above for the proper use of "strftime" format strings)
 <table><tr><th>string</th><th>Formatter Object</th><th>Formatted Example</th></tr>
 <tr><td>`shortDate`</td><td>{ format:'%D' }</td><td>03/12/92</td></tr>
 <tr><td>`longDate`</td><td>{ format:'%m/%d/%Y' }</td><td>03/12/1992</td></tr>
 <tr><td>`fullDate`</td><td>{ format:'%B %e, %Y' }</td><td>March 12, 1992</td></tr>
 <tr><td>`isoDate`</td><td>{ format:'%F'}</td><td>1992-03-12</td></tr>
 <tr><td>`isoDateTime`</td><td>{ format:'%FT%T'}</td><td>1992-03-12T22:11:07</td></tr>
 </table>

 ####Replaceable Hash
 This utility can also replace the cell value with values from a data hash (i.e. JS simple object, consisting of key:value pairs).
 Access to this capability is by providing a `formatter` as any string not-recognizable in the `formatStrings` object
 **AND** by providing a `formatConfig` object (equal to the hash) in the column definition.

 ####User-Defined `formatStrings`
 Implementers may add their own "named" formatting strings for their own use-cases simply by adding more named formatters to
 the `formatStrings` object as;

	Y.DataTable.Formatters.formatStrings['myNumberFmtr'] = {
		type:'number',
		formatConfig:{ thousandsSeparator:'x', decimalPlaces:11 }
	};
	Y.DataTable.Formatters.formatStrings['myDateFmtr'] = {
		type:'date',
		formatConfig:{ format:{ "At the tone the TIME will be %T" }
	};


 @module gallery-datatable-formatters
 @class Y.DataTable.Formatters
 @extends DataTable
 @since 3.6.0
 **/
Y.DataTable.Formatters = {

    /**
     Object containing referenceable format strings
     @property formatStrings
     @public
     **/
    formatStrings: {

        general:   { type:'number', formatConfig:{ decimalPlaces:0 } },
        general2:  { type:'number', formatConfig:{ decimalPlaces:2 } },
        currency:  { type:'number', formatConfig:{ prefix:'$', decimalPlaces:0, thousandsSeparator:',' } },
        currency2: { type:'number', formatConfig:{ prefix:'$', decimalPlaces:2, thousandsSeparator:',' } },
        currency3: { type:'number', formatConfig:{ prefix:'$', decimalPlaces:3, thousandsSeparator:',' } },
        comma:     { type:'number', formatConfig:{ decimalPlaces:0, thousandsSeparator:','} },
        comma2:    { type:'number', formatConfig:{ decimalPlaces:2, thousandsSeparator:',' } },
        comma3:    { type:'number', formatConfig:{ decimalPlaces:3, thousandsSeparator:',' } },

        shortDate: { type:'date',  formatConfig:{ format:'%D' } },
        longDate:  { type:'date',  formatConfig:{ format:'%m/%d/%Y' } },
        fullDate:  { type:'date',  formatConfig:{ format:'%B %e, %Y' } },
        isoDate:   { type:'date',  formatConfig:{ format:'%F'} },
        isoDateTime:  { type:'date',  formatConfig:{ format:'%FT%T'} },

        'array' :  { type:'array', formatConfig:{ value:'value', text:'text'} },
        'object' : { type:'object', formatConfig:null },
        hash :     { type:'hash', formatConfig:null },

      //  link : { type:'html', formatConfig:{}},  // incomplete

        'default': {}

    },

    /**
     * Formatter function called that executes a standard "named" formatter defined by `fmtrName`.
     * The parameter `fmtrName` maps to a member of the "formatStrings" object, that includes a type
     * declaration and a formatConfig string to be substituted in the DataType.Number.format or Date.format
     * function.
     *
     * @method namedFormatter
     * @param {String} fmtrName Name of formatter object from "formatStrings", i.e. "currency2", "fullDate"
     * @param {Object} o The passed-in column formatter object
     * @return {Mixed} value
     */
    namedFormatter: function(fmtrName,o) {
        var fmtObj  =  Y.DataTable.Formatters.formatStrings[fmtrName] || null,
            fmtOptions = o.column.formatOptions || o.column.formatConfig,
            value   = o.value,
            fmtType,fmtConf,akey,aval,isStr,kl;

        //
        //  Pre-process the entered 'formatConfig' or 'formatOptions' column properties
        //
        fmtType = o.column.type || ( (fmtObj) ? fmtObj.type : null );
        if(!fmtType) {
            fmtType = (fmtOptions && fmtOptions.type) ? fmtOptions.type : null;
        }
        fmtConf = o.column.formatConfig || ( (fmtObj) ? fmtObj.formatConfig : null);

        //
        //  Switch over the formatter "type"
        //
        if(fmtType) {
            switch(fmtType) {
                case 'date':
                    value = Y.DataType.Date.format(o.value,fmtConf);
                    break;

                case 'number':
                    value = Y.DataType.Number.format(o.value,fmtConf);
                    break;

                case 'array':
                    akey = (fmtConf) ? fmtConf.value : 'value';
                    aval = (fmtConf) ? fmtConf.text : 'text';

                    Y.Array.each(fmtOptions,function(r){
                        if( r[akey] === o.value ) {
                            value = r[aval];
                        }
                    });
                    break;

                case 'object':
                case 'hash':
                    isStr = Y.Lang.isString(o.value);
                    Y.Object.each(fmtOptions,function(v,k){
                        kl = (isStr) ? k : (+k);
                        if( kl === o.value ) {
                            value = v;
                        }
                    });
                    break;

            }
        }

        return value;
    }


};

/**
 Override of method _createRowHTML from DataTable.BodyView extended to permit use of named
 formatter functions from Y.DataTable.Formatters.

 Additional functionality was added to facilitate using a template approach for {o.value} within
 the column, by using Y.Lang.sub (as fromTemplate) with the replacement object hash provided
 as column configuration "formatConfig" (o.column.formatConfig).

 @method Y.DataTable.BodyView._createRowHTML
 @param model
 @param index
 @param columns
 @return {*}
 @private
 **/
Y.DataTable.BodyView.prototype._createRowHTML = function (model, index, columns) {
    var Lang         = Y.Lang,
        isArray      = Lang.isArray,
        isNumber     = Lang.isNumber,
        isString     = Lang.isString,
        fromTemplate = Lang.sub,
        htmlEscape   = Y.Escape.html,
        toArray      = Y.Array,
        bind         = Y.bind,
        YObject      = Y.Object;

    var data     = model.toJSON(),
        clientId = model.get('clientId'),
        values   = {
            rowId   : this._getRowId(clientId),
            clientId: clientId,
            rowClass: (index % 2) ? this.CLASS_ODD : this.CLASS_EVEN
        },
        host = this.host || this,
        i, len, col, token, value, formatterData;

    for (i = 0, len = columns.length; i < len; ++i) {
        col   = columns[i];
        value = data[col.key];
        token = col._id || col.key;

        values[token + '-className'] = '';

        if (col.formatter) {
            formatterData = {
                value    : value,
                data     : data,
                column   : col,
                record   : model,
                className: '',
                rowClass : '',
                rowIndex : index
            };

            if (typeof col.formatter === 'string') {
                if (value !== undefined) {
                    // TODO: look for known formatters by string name

                // ADDED: by T. Smith, following for named formatters ... i.e. {key:'foo', formatter:'comma2' ...}
                    if ( Y.DataTable.Formatters.namedFormatter && Y.DataTable.Formatters.formatStrings[col.formatter] ) {
                        value = Y.DataTable.Formatters.namedFormatter.call(host,col.formatter,formatterData);
                    } else if ( col.formatConfig ) {    // do string replacement of values from col.formatConfig
                        value = fromTemplate("{" + value + "}", col.formatConfig );
                    } else {
                        value = fromTemplate(col.formatter, formatterData);
                    }
                }
            } else {
                // Formatters can either return a value
                value = col.formatter.call(host, formatterData);

                // or update the value property of the data obj passed
                if (value === undefined) {
                    value = formatterData.value;
                }

                values[token + '-className'] = formatterData.className;
                values.rowClass += ' ' + formatterData.rowClass;
            }
        }

        if (value === undefined || value === null || value === '') {
            value = col.emptyCellValue || '';
        }

        values[token] = col.allowHTML ? value : htmlEscape(value);

        values.rowClass = values.rowClass.replace(/\s+/g, ' ');
    }

    return fromTemplate(this._rowTemplate, values);
};