/**
* The handlebars reference
* @external Handlebars
* @see {@link https://handlebarsjs.com/|Handlebars}
*/
/**
* The handlebars Template reference
* @external Handlebars-Template
* @see {@link https://handlebarsjs.com/|Handlebars}
*/
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(['underscore'], factory);
} else if (typeof exports === 'object') {
module.exports = factory(require('underscore'));
} else {
root.Torso = root.Torso || {};
root.Torso.Utils = root.Torso.Utils || {};
root.Torso.Utils.handlebarsUtils = factory(root._);
}
}(this, function(_) {
'use strict';
/**
* Extensions to handlebars helpers.
*
* Adds additonal helpers to {@link external:Handlebars}
*
* @function handlebarsUtils
* @param {external:Handlebars} Handlebars Add the helpers to this Handlebars object.
*
* @author ariel.wexler@vecna.com, kent.willis@vecna.com
*
* @see {@link HandlebarsHelper} for the added helpers.
* @see <a href="../annotated/modules/handlebarsUtils.html">handlebarsUtils Annotated Source</a>
*/
/** @namespace HandlebarsHelper */
return function(Handlebars) {
var FEEDBACK_KEY = 'feedback';
var MODEL_KEY = 'model';
/**
* Usage: {{labelFor 'fieldName' value="suffix"}}
*
* Generates: for="field-name-suffix"
*
* Usage: {{labelFor 'fieldName[x].sub' value="demo" x=123}}
*
* Generates: for="field-name-123_sub-demo"
*
* Usage: {{labelFor 'fieldName[bar].sub' value="demo" bar="abc"}}
*
* Generates: for="field-name_abc_sub-demo"
*
* @method HandlebarsHelper.labelFor
* @param {string} field The field name to convert to a compliant "for" attribute
* @param {Object} options The handlebars context. Always passed in as the final argument.
* @param {string} [option.hash.value] The value tacked on to the end of the field string (useful for radio and checkbox)
* @returns {string} Compliant HTML generating the "for" attribute
*/
Handlebars.registerHelper('labelFor', function(field, options) {
options = _.extend(options, {noValueAttr: true});
return Handlebars.helpers.formAttr(field, 'for', options);
});
/**
* Usage: {{bindModel 'fieldName' value='suffix'}}
*
* Generates: id="field-name-suffix" name="field-name" data-model="fieldName" data-feedback="fieldName" value="demo"
*
* Usage: {{bindModel 'fieldName[x].sub' value='demo' x=123}}
*
* Generates: data-model="fieldName[123].sub" data-feedback="fieldName[123].sub" name="field-name-123_sub"
* id="field-name-123_sub-demo" value="demo"
*
* Usage: {{bindModel 'fieldName[bar].sub' value='demo' bar='abc'}}
*
* Generates: data-model="fieldName.abc.sub" data-feedback="fieldName[abc].sub" name="field-name_abc_sub"
id="field-name_abc_sub-demo" value="demo"
*
* @method HandlebarsHelper.bindModel
* @param {string} field The field name to convert to compliant id, name, data-model, and data-feedback attributes
* @param {Object} options The handlebars context. Always passed in as the final argument.
* @param {string} [options.hash.value] The value tacked on to the end of the field string (useful for radio and checkbox)
* @returns {string} Compliant HTML generating the id, name, data-model, and data-feedback attributes
*/
Handlebars.registerHelper('bindModel', function(field, options) {
return Handlebars.helpers.formAttr(field, MODEL_KEY + ', ' + FEEDBACK_KEY + ', name, id', options);
});
/**
* Usage: {{feedback 'fieldName'}}
*
* Generates: data-feedback="fieldName"
*
* Usage: {{feedback 'fieldName[x].sub' value='demo' x=123}}
*
* Generates: data-feedback="fieldName[123].sub"
*
* Usage: {{feedback 'fieldName[bar].sub value='demo' bar='abc'}}
*
* Generates: data-feedback="fieldName[abc].sub"
*
* @method HandlebarsHelper.feedback
* @param {string} field The field name to convert to a compliant data-feedback attribute
* @param {Object} options The handlebars context. Always passed in as the final argument.
* @returns {string} Compliant HTML generating the data-feedback attribute
*/
Handlebars.registerHelper('feedback', function(field, options) {
options = _.extend(options, {noValueAttr: true});
return Handlebars.helpers.formAttr(field, FEEDBACK_KEY, options);
});
/**
* Usage: {{formAttr 'fieldName[x].sub' 'id, for' value='demo' x=123}}
*
* Generates: id="field-name-123_sub-demo" for="field-name-123_sub-demo" value="demo"
*
* Usage: {{feedback 'fieldName[bar].sub value='demo' bar='abc'}}
*
* Generates: id="field-name_abc_sub-demo" for="field-name_abc_sub-demo" value="demo"
*
* @method HandlebarsHelper.formAttr
* @param {string} field The field name to convert to a compliant data-feedback attribute
* @param {Object} options The handlebars context. Always passed in as the final argument.
* @param {string} [options.hash.value] The value tacked on to the end of the field string (useful for radio and checkbox)
* @param {boolean} [options.noValueAttr] when options.noValueAttr is set to true,
then it will not generate the "value" attribute in the DOM.
* @returns {string} Compliant HTML generating the data-feedback attribute
*/
Handlebars.registerHelper('formAttr', function(field, attrs, options) {
var i, attrName,
value = (options.hash ? options.hash.value : undefined),
res = Handlebars.helpers.injectFieldIndices(field, options.hash),
resWithArrayNotation = Handlebars.helpers.injectFieldIndices(field, options.hash, { forceArrayNotation: true }),
attributes = '';
attrs = attrs.split(',');
for (i = 0; i < attrs.length; i++) {
attrName = attrs[i].trim();
var attrEnd = (i === attrs.length - 1) ? '"' : '" ';
if (attrName === FEEDBACK_KEY) {