'
+ ) : tagHTML;
};
// if there is no `canContain` or `cannotContain`, then the element is not a container.
@@ -261,388 +264,426 @@ me.decorateField = function(field, tagHTML){
// && (!y.canBeContainedBy || x in y.canBeContainedBy)
me.elementTypes = {
- 'page': {
- cannotContain: ['page'],
- render: function(el){}
- },
-
- 'section': {
- cannotContain: ['page'],
- isTab : false,
- render: function(el, values, isTabs){
- return (
- '' +
- (el.label ? '
' + t(el.label) + '
' : '') +
- (el.description ? '
' + el.description + '
' : '') +
- '
' +
- me.render_fields(el, values) +
- '
' +
- ''
- );
- }
- },
-
- // todo: allow for pre-rendered markup for the description, or other renderers (such as markdown)
- 'fieldset': {
- cannotContain: ['section', 'page'],
- render: function(el, values){
- if(!el.label) el.label = el.legend;
- return (
- ''
- );
- }
- },
-
- // special .. might also be used as a container (i.e., depending on what radio is active, elements 'under' it are active?)
- // special - have to share ids .. are part of a set - TODO - allow for more than one radio group (already done?)
- 'radios': { // it's a container because radios must belong to a 'set' .. also, sometimes a form uses radios kindof like tabs....
- canContain: ['option'],
- render: function(field, values){
- return me.elementTypes.fieldset.render(field, values);
- }
- },
-
- // special .. might also be used as a container (i.e., depending on whether a checkbox is checked, elements 'under' it are active?)
- 'checkboxes': {
- canContain: ['option'],
- render: function(field, values){
- return me.elementTypes.fieldset.render(field, values);
- }
- },
-
- 'select': { // it's a container because it contains options
- canContain: ['options','optgroup'],
- render: function(field, value){
-
- var tagOutput = '';
-
- return me.decorateField(field, tagOutput);
- }
- },
-
- 'optgroup': {
- canBeContainedBy: ['select'],
- canContain: ['option']
- },
-
- 'options': {
- canBeContainedBy: ['select'],
- canContain: ['option']
- },
-
- // an "option" can be an
or a radio or a checkbox.
- 'option': {
- canBeContainedBy: ['radios','checkboxes','select','optgroup'],
- // container determines render method.
- render: function(option, value, containerType){
- if(containerType == 'select'){
- var displayText = option.label || option;
- var optionValue = option.value || option;
- return (
- '
'
- + displayText
- + '
'
- );
- } else {
- return me.defaultTagRenderer(option, value);
- }
- }
- },
-
- // type: 'radio' should become type: option, and be in a {type: radios}
- 'radio': {
- render: me.defaultTagRenderer
- },
-
- // type: 'checkbox' should become type: option, and be in a {type: checkboxes}
- 'checkbox': {
- render: function(field, value, bare) {
-
- // Quickly flip values to true/false if on/off
- value = (value === "on" ? true : (value === "off" ? false : value));
-
- // Now set the checked variable
- var checked = (value ? true : (field.value ? true : (field.checked ? true : false)));
-
- var tagOutput = "";
-
- if(!field.readonly && !field.disabled){
- // Workaround for readonly/disabled fields (esp. checkboxes/radios) - add a hidden field with the value
- tagOutput += '';
- }
-
- tagOutput += '';
- }
- return bare ? tagOutput : me.decorateField(field, tagOutput);
- }
- },
-
- 'text': {
- render: me.defaultTagRenderer
- },
-
- 'textarea': {
- render: function(field, value){
- return me.decorateField(field, '');
- }
- },
-
- 'hidden': {
- render: me.defaultTagRenderer
- },
-
- 'password': { // can be special, if there is a 'verify'
- render: me.defaultTagRenderer
- },
-
- // might allow file to take a url
- 'file': {
- render: me.defaultTagRenderer
- },
-
- 'buttons': {
- canContain: ['submit','image','reset','button','link']
- },
-
- // buttons should only be able to be added to the 'action set'
- // button can be [submit, reset, cancel (a link), button (generic), link (generic)]
- // if form has pages, 'previous' and 'next' buttons should interpolate until the last page, 'submit'
- 'button': {
- render: me.defaultTagRenderer
- },
-
- 'submit': {
- render: me.defaultTagRenderer
- },
-
- 'image': {
- render: me.defaultTagRenderer
- },
-
- 'reset': {
- render: me.defaultTagRenderer
- },
-
- // a link is not really a form control, but is provided here for convenience
- // it also doesn't really make sense for it to have a value.
- // a link should have an href and text, and optionally, cls ('class'), id
- 'link': {
- render: function(field, value){
- var id = field.id || field.name;
- var text = field.text || field.value;
- return '' + text + '';
- }
- },
-
- 'readonlytext': {
- render: function(field, value, bare){
- var id = field.id || field.name;
- var text = field.text || field.value;
- var tagOutput = '
' + text + '
';
- return bare ? tagOutput : me.decorateField(field, tagOutput);
- }
- },
-
- 'date': {
- render: function(field, value, bare){
-
- if(!value) {
- value = new Date();
- }
-
- // TODO - use user's Locale
- var monthNames = calipso.date.regional[''].monthNamesShort;
-
- var tagOutput = '';
- for(var monthNameCounter=0; monthNameCounter<12; monthNameCounter++) {
- tagOutput += (
- '
' +
+ ''
+ );
+ }
+ },
+
+ // todo: allow for pre-rendered markup for the description, or other renderers (such as markdown)
+ 'fieldset': {
+ cannotContain: ['section', 'page'],
+ render: function (el, values)
+ {
+ if (!el.label)
+ {
+ el.label = el.legend;
+ }
+ return (
+ ''
+ );
+ }
+ },
+
+ // special .. might also be used as a container (i.e., depending on what radio is active, elements 'under' it are active?)
+ // special - have to share ids .. are part of a set - TODO - allow for more than one radio group (already done?)
+ 'radios': { // it's a container because radios must belong to a 'set' .. also, sometimes a form uses radios kindof like tabs....
+ canContain: ['option'],
+ render: function (field, values)
+ {
+ return me.elementTypes.fieldset.render(field, values);
+ }
+ },
+
+ // special .. might also be used as a container (i.e., depending on whether a checkbox is checked, elements 'under' it are active?)
+ 'checkboxes': {
+ canContain: ['option'],
+ render: function (field, values)
+ {
+ return me.elementTypes.fieldset.render(field, values);
+ }
+ },
+
+ 'select': { // it's a container because it contains options
+ canContain: ['options', 'optgroup'],
+ render: function (field, value)
+ {
+
+ var tagOutput = '';
+
+ return me.decorateField(field, tagOutput);
+ }
+ },
+
+ 'optgroup': {
+ canBeContainedBy: ['select'],
+ canContain: ['option']
+ },
+
+ 'options': {
+ canBeContainedBy: ['select'],
+ canContain: ['option']
+ },
+
+ // an "option" can be an
or a radio or a checkbox.
+ 'option': {
+ canBeContainedBy: ['radios', 'checkboxes', 'select', 'optgroup'],
+ // container determines render method.
+ render: function (option, value, containerType)
+ {
+ if (containerType == 'select')
+ {
+ var displayText = option.label || option;
+ var optionValue = option.value || option;
+ return (
+ '
'
+ + displayText
+ + '
'
+ );
+ }
+ else
+ {
+ return me.defaultTagRenderer(option, value);
+ }
+ }
+ },
+
+ // type: 'radio' should become type: option, and be in a {type: radios}
+ 'radio': {
+ render: me.defaultTagRenderer
+ },
+
+ // type: 'checkbox' should become type: option, and be in a {type: checkboxes}
+ 'checkbox': {
+ render: function (field, value, bare)
+ {
+
+ // Quickly flip values to true/false if on/off
+ value = (value === "on" ? true : (value === "off" ? false : value));
+
+ // Now set the checked variable
+ var checked = (value ? true : (field.value ? true : (field.checked ? true : false)));
+
+ var tagOutput = "";
+
+ if (!field.readonly && !field.disabled)
+ {
+ // Workaround for readonly/disabled fields (esp. checkboxes/radios) - add a hidden field with the value
+ tagOutput += '';
+ }
+
+ tagOutput += '';
+ }
+ return bare ? tagOutput : me.decorateField(field, tagOutput);
+ }
+ },
+
+ 'text': {
+ render: me.defaultTagRenderer
+ },
+
+ 'textarea': {
+ render: function (field, value)
+ {
+ return me.decorateField(field, '');
+ }
+ },
+
+ 'hidden': {
+ render: me.defaultTagRenderer
+ },
+
+ 'password': { // can be special, if there is a 'verify'
+ render: me.defaultTagRenderer
+ },
+
+ // might allow file to take a url
+ 'file': {
+ render: me.defaultTagRenderer
+ },
+
+ 'buttons': {
+ canContain: ['submit', 'image', 'reset', 'button', 'link']
+ },
+
+ // buttons should only be able to be added to the 'action set'
+ // button can be [submit, reset, cancel (a link), button (generic), link (generic)]
+ // if form has pages, 'previous' and 'next' buttons should interpolate until the last page, 'submit'
+ 'button': {
+ render: me.defaultTagRenderer
+ },
+
+ 'submit': {
+ render: me.defaultTagRenderer
+ },
+
+ 'image': {
+ render: me.defaultTagRenderer
+ },
+
+ 'reset': {
+ render: me.defaultTagRenderer
+ },
+
+ // a link is not really a form control, but is provided here for convenience
+ // it also doesn't really make sense for it to have a value.
+ // a link should have an href and text, and optionally, cls ('class'), id
+ 'link': {
+ render: function (field, value)
+ {
+ var id = field.id || field.name;
+ var text = field.text || field.value;
+ return '' + text + '';
+ }
+ },
+
+ 'readonlytext': {
+ render: function (field, value, bare)
+ {
+ var id = field.id || field.name;
+ var text = field.text || field.value;
+ var tagOutput = '
' + text + '
';
+ return bare ? tagOutput : me.decorateField(field, tagOutput);
+ }
+ },
+
+ 'date': {
+ render: function (field, value, bare)
+ {
+
+ if (!value)
+ {
+ value = new Date();
+ }
+
+ // TODO - use user's Locale
+ var monthNames = calipso.date.regional[''].monthNamesShort;
+
+ var tagOutput = '';
+ for (var monthNameCounter = 0;
+ monthNameCounter < 12;
+ monthNameCounter++)
+ {
+ tagOutput += (
+ '
'
+ + monthNames[monthNameCounter]
+ + '
'
+ );
+ }
+ tagOutput += '';
+
+ tagOutput += ' ';
+
+ tagOutput += ' 0) {
- calipso.silly("Saving form " + form.id + " in session.");
- req.session.forms = req.session.forms || {};
- req.session.forms[form.id] = form;
- req.session.save(next);
- } else {
- next();
- }
+function saveFormInSession(form, req, next)
+{
+
+ // If we have a form id and a session, save it
+ if (form.id && calipso.lib._.keys(req.session).length > 0)
+ {
+ calipso.silly("Saving form " + form.id + " in session.");
+ req.session.forms = req.session.forms || {};
+ req.session.forms[form.id] = form;
+ req.session.save(next);
+ }
+ else
+ {
+ next();
+ }
}
/**
* Deal with form tabs in jQuery UI style if required.
*/
-me.formTabs = function(sections) {
-
- if(!sections)
- return '';
-
- var tabOutput = '';
+me.formTabs = function (sections)
+{
+
+ if (!sections)
+ {
+ return '';
+ }
+
+ var tabOutput = '';
};
-
/**
* Render the initial form tag
*
* @param form
* @returns {String}
*/
-me.start_form = function(form) {
- return (
- '';
};
-
-
/**
* Render the form sections, iterating through and then rendering
* each of the fields within a section.
*/
-me.render_sections = function(form, values) {
-
- var self = this;
- var sections = form.sections;
-
- if(!sections)
- return '';
-
- var sectionOutput = '';
-
- sections.forEach(function(section) {
- sectionOutput += (
- '' +
- '
';
- return buttonsOutput;
+ return buttonsOutput;
};
-
-
/**
* Render the fields on a form
* @param fields
* @returns {String}
*/
-me.render_fields = function(fieldContainer, values) {
-
- var fields = fieldContainer.fields || fieldContainer.children;
- var self = this;
- var fieldOutput = '';
-
- if(!fields) {
- return '';
- }
-
- fields.forEach( function(field) {
-
- var value = '';
- var fieldName = field.name;
-
- // If we have a field name, lookup the value
- if(fieldName) {
- value = getValueForField(fieldName, values);
- }
-
- // if the 'field' is really just a container, pass the values on down
- // todo: consider adding a property 'isContainer'
- if(field.type == 'section' || field.type == 'fieldset'){
- value = values;
- }
-
- // field.tag was introduced to allow for