diff --git a/lib/form/form.js b/lib/form/form.js index 6c571c6be1e..f1d95c9c0b6 100644 --- a/lib/form/form.js +++ b/lib/form/form.js @@ -6,6 +6,535 @@ // Namespace for the form bits and bobs M.form = M.form || {}; +if (typeof M.form.dependencyManager === 'undefined') { + var dependencyManager = function() { + dependencyManager.superclass.constructor.apply(this, arguments); + }; + Y.extend(dependencyManager, Y.Base, { + _locks: null, + _hides: null, + _dirty: null, + _nameCollections: null, + _fileinputs: null, + + initializer: function() { + // Setup initial values for complex properties. + this._locks = {}; + this._hides = {}; + this._dirty = {}; + + // Setup event handlers. + Y.Object.each(this.get('dependencies'), function(value, i) { + var elements = this.elementsByName(i); + elements.each(function(node){ + var nodeName = node.get('nodeName').toUpperCase(); + if (nodeName == 'INPUT') { + if (node.getAttribute('type').match(/^(button|submit|radio|checkbox)$/)) { + node.on('click', this.updateEventDependencies, this); + } else { + node.on('blur', this.updateEventDependencies, this); + } + node.on('change', this.updateEventDependencies, this); + } else if (nodeName == 'SELECT') { + node.on('change', this.updateEventDependencies, this); + } else { + node.on('click', this.updateEventDependencies, this); + node.on('blur', this.updateEventDependencies, this); + node.on('change', this.updateEventDependencies, this); + } + }, this); + }, this); + + // Handle the reset button. + this.get('form').get('elements').each(function(input){ + if (input.getAttribute('type') == 'reset') { + input.on('click', function(){ + this.get('form').reset(); + this.updateAllDependencies(); + }, this); + } + }, this); + + this.updateAllDependencies(); + }, + + /** + * Initializes the mapping from element name to YUI NodeList + */ + initElementsByName: function() { + var names = {}; + + // Collect element names. + Y.Object.each(this.get('dependencies'), function(conditions, i) { + names[i] = new Y.NodeList(); + for (var condition in conditions) { + for (var value in conditions[condition]) { + for (var ei in conditions[condition][value]) { + names[conditions[condition][value][ei]] = new Y.NodeList(); + } + } + } + }); + + // Locate elements for each name. + this.get('form').get('elements').each(function(node){ + var name = node.getAttribute('name'); + if (({}).hasOwnProperty.call(names, name)) { + names[name].push(node); + } + }); + this._nameCollections = names; + }, + + /** + * Gets all elements in the form by their name and returns + * a YUI NodeList + * + * @param {string} name The form element name. + * @return {Y.NodeList} + */ + elementsByName: function(name) { + if (!this._nameCollections) { + this.initElementsByName(); + } + if (!({}).hasOwnProperty.call(this._nameCollections, name)) { + return new Y.NodeList(); + } + return this._nameCollections[name]; + }, + + /** + * Checks the dependencies the form has an makes any changes to the + * form that are required. + * + * Changes are made by functions title _dependency_{dependencytype} + * and more can easily be introduced by defining further functions. + * + * @param {EventFacade | null} e The event, if any. + * @param {string} name The form element name to check dependencies against. + */ + checkDependencies: function(e, dependon) { + var dependencies = this.get('dependencies'), + tohide = {}, + tolock = {}, + condition, value, lock, hide, + checkfunction, result, elements; + if (!({}).hasOwnProperty.call(dependencies, dependon)) { + return true; + } + elements = this.elementsByName(dependon); + for (condition in dependencies[dependon]) { + for (value in dependencies[dependon][condition]) { + checkfunction = '_dependency_'+condition; + if (Y.Lang.isFunction(this[checkfunction])) { + result = this[checkfunction].apply(this, [elements, value, e]); + } else { + result = this._dependency_default(elements, value, e); + } + lock = result.lock || false; + hide = result.hide || false; + for (var ei in dependencies[dependon][condition][value]) { + var eltolock = dependencies[dependon][condition][value][ei]; + if (({}).hasOwnProperty.call(tohide, eltolock)) { + tohide[eltolock] = tohide[eltolock] || hide; + } else { + tohide[eltolock] = hide; + } + + if (({}).hasOwnProperty.call(tolock, eltolock)) { + tolock[eltolock] = tolock[eltolock] || lock; + } else { + tolock[eltolock] = lock; + } + } + } + } + + for (var el in tolock) { + var needsupdate = false; + if (!({}).hasOwnProperty.call(this._locks, el)) { + this._locks[el] = {}; + } + if (({}).hasOwnProperty.call(tolock, el) && tolock[el]) { + if (!({}).hasOwnProperty.call(this._locks[el], dependon) || this._locks[el][dependon]) { + this._locks[el][dependon] = true; + needsupdate = true; + } + } else if (({}).hasOwnProperty.call(this._locks[el], dependon) && this._locks[el][dependon]) { + delete this._locks[el][dependon]; + needsupdate = true; + } + + if (!({}).hasOwnProperty.call(this._hides, el)) { + this._hides[el] = {}; + } + if (({}).hasOwnProperty.call(tohide, el) && tohide[el]) { + if (!({}).hasOwnProperty.call(this._hides[el], dependon) || this._hides[el][dependon]) { + this._hides[el][dependon] = true; + needsupdate = true; + } + } else if (({}).hasOwnProperty.call(this._hides[el], dependon) && this._hides[el][dependon]) { + delete this._hides[el][dependon]; + needsupdate = true; + } + + if (needsupdate) { + this._dirty[el] = true; + } + } + + return true; + }, + /** + * Update all dependencies in form + */ + updateAllDependencies: function() { + Y.Object.each(this.get('dependencies'), function(value, name) { + this.checkDependencies(null, name); + }, this); + + this.updateForm(); + }, + /** + * Update dependencies associated with event + * + * @param {Event} e The event. + */ + updateEventDependencies: function(e) { + var el = e.target.getAttribute('name'); + this.checkDependencies(e, el); + this.updateForm(); + }, + /** + * Flush pending changes to the form + */ + updateForm: function() { + var el; + for (el in this._dirty) { + if (({}).hasOwnProperty.call(this._locks, el)) { + this._disableElement(el, !Y.Object.isEmpty(this._locks[el])); + } + if (({}).hasOwnProperty.call(this._hides, el)) { + this._hideElement(el, !Y.Object.isEmpty(this._hides[el])); + } + } + + this._dirty = {}; + }, + /** + * Disables or enables all form elements with the given name + * + * @param {string} name The form element name. + * @param {boolean} disabled True to disable, false to enable. + */ + _disableElement: function(name, disabled) { + var els = this.elementsByName(name); + var filepicker = this.isFilePicker(name); + els.each(function(node){ + if (disabled) { + node.setAttribute('disabled', 'disabled'); + } else { + node.removeAttribute('disabled'); + } + + // Extra code to disable filepicker or filemanager form elements + if (filepicker) { + var fitem = node.ancestor('.fitem'); + if (fitem) { + if (disabled){ + fitem.addClass('disabled'); + } else { + fitem.removeClass('disabled'); + } + } + } + }); + }, + /** + * Hides or shows all form elements with the given name. + * + * @param {string} name The form element name. + * @param {boolean} disabled True to hide, false to show. + */ + _hideElement: function(name, hidden) { + var els = this.elementsByName(name); + els.each(function(node){ + var e = node.ancestor('.fitem'); + if (e) { + e.setStyles({ + display: (hidden)?'none':'' + }); + } + }); + }, + /** + * Is the form element inside a filepicker or filemanager? + * + * @param {string} el The form element name. + * @return {boolean} + */ + isFilePicker: function(el) { + if (!this._fileinputs) { + var fileinputs = {}; + var els = this.get('form').all('.fitem.fitem_ffilepicker input,.fitem.fitem_ffilemanager input'); + els.each(function(node){ + fileinputs[node.getAttribute('name')] = true; + }); + this._fileinputs = fileinputs; + } + + if (({}).hasOwnProperty.call(this._fileinputs, el)) { + return this._fileinputs[el] || false; + } + + return false; + }, + _dependency_notchecked: function(elements, value) { + var lock = false; + elements.each(function(){ + if (this.getAttribute('type').toLowerCase()=='hidden' && !this.siblings('input[type=checkbox][name="' + this.get('name') + '"]').isEmpty()) { + // This is the hidden input that is part of an advcheckbox. + return; + } + if (this.getAttribute('type').toLowerCase()=='radio' && this.get('value') != value) { + return; + } + lock = lock || !Y.Node.getDOMNode(this).checked; + }); + return { + lock: lock, + hide: false + }; + }, + _dependency_checked: function(elements, value) { + var lock = false; + elements.each(function(){ + if (this.getAttribute('type').toLowerCase()=='hidden' && !this.siblings('input[type=checkbox][name="' + this.get('name') + '"]').isEmpty()) { + // This is the hidden input that is part of an advcheckbox. + return; + } + if (this.getAttribute('type').toLowerCase()=='radio' && this.get('value') != value) { + return; + } + lock = lock || Y.Node.getDOMNode(this).checked; + }); + return { + lock: lock, + hide: false + }; + }, + _dependency_noitemselected: function(elements, value) { + var lock = false; + elements.each(function(){ + lock = lock || this.get('selectedIndex') == -1; + }); + return { + lock: lock, + hide: false + }; + }, + _dependency_eq: function(elements, value) { + var lock = false; + var hidden_val = false; + var options, v, selected, values; + elements.each(function(){ + if (this.getAttribute('type').toLowerCase()=='radio' && !Y.Node.getDOMNode(this).checked) { + return; + } else if (this.getAttribute('type').toLowerCase() == 'hidden' && !this.siblings('input[type=checkbox][name="' + this.get('name') + '"]').isEmpty()) { + // This is the hidden input that is part of an advcheckbox. + hidden_val = (this.get('value') == value); + return; + } else if (this.getAttribute('type').toLowerCase() == 'checkbox' && !Y.Node.getDOMNode(this).checked) { + lock = lock || hidden_val; + return; + } + if (this.getAttribute('class').toLowerCase() == 'filepickerhidden') { + // Check for filepicker status. + var elementname = this.getAttribute('name'); + if (elementname && M.form_filepicker.instances[elementname].fileadded) { + lock = false; + } else { + lock = true; + } + } else if (this.get('nodeName').toUpperCase() === 'SELECT' && this.get('multiple') === true) { + // Multiple selects can have one or more value assigned. A pipe (|) is used as a value separator + // when multiple values have to be selected at the same time. + values = value.split('|'); + selected = []; + options = this.get('options'); + options.each(function() { + if (this.get('selected')) { + selected[selected.length] = this.get('value'); + } + }); + if (selected.length > 0 && selected.length === values.length) { + for (var i in selected) { + v = selected[i]; + if (values.indexOf(v) > -1) { + lock = true; + } else { + lock = false; + return; + } + } + } else { + lock = false; + } + } else { + lock = lock || this.get('value') == value; + } + }); + return { + lock: lock, + hide: false + }; + }, + /** + * Lock the given field if the field value is in the given set of values. + * + * @param elements + * @param values + * @returns {{lock: boolean, hide: boolean}} + * @private + */ + _dependency_in: function(elements, values) { + // A pipe (|) is used as a value separator + // when multiple values have to be passed on at the same time. + values = values.split('|'); + var lock = false; + var hidden_val = false; + var options, v, selected, value; + elements.each(function(){ + if (this.getAttribute('type').toLowerCase()=='radio' && !Y.Node.getDOMNode(this).checked) { + return; + } else if (this.getAttribute('type').toLowerCase() == 'hidden' && !this.siblings('input[type=checkbox][name="' + this.get('name') + '"]').isEmpty()) { + // This is the hidden input that is part of an advcheckbox. + hidden_val = (values.indexOf(this.get('value')) > -1); + return; + } else if (this.getAttribute('type').toLowerCase() == 'checkbox' && !Y.Node.getDOMNode(this).checked) { + lock = lock || hidden_val; + return; + } + if (this.getAttribute('class').toLowerCase() == 'filepickerhidden') { + // Check for filepicker status. + var elementname = this.getAttribute('name'); + if (elementname && M.form_filepicker.instances[elementname].fileadded) { + lock = false; + } else { + lock = true; + } + } else if (this.get('nodeName').toUpperCase() === 'SELECT' && this.get('multiple') === true) { + // Multiple selects can have one or more value assigned. + selected = []; + options = this.get('options'); + options.each(function() { + if (this.get('selected')) { + selected[selected.length] = this.get('value'); + } + }); + if (selected.length > 0 && selected.length === values.length) { + for (var i in selected) { + v = selected[i]; + if (values.indexOf(v) > -1) { + lock = true; + } else { + lock = false; + return; + } + } + } else { + lock = false; + } + } else { + value = this.get('value'); + lock = lock || (values.indexOf(value) > -1); + } + }); + return { + lock: lock, + hide: false + }; + }, + _dependency_hide: function(elements, value) { + return { + lock: false, + hide: true + }; + }, + _dependency_default: function(elements, value, ev) { + var lock = false, + hidden_val = false, + values + ; + elements.each(function(){ + var selected; + if (this.getAttribute('type').toLowerCase()=='radio' && !Y.Node.getDOMNode(this).checked) { + return; + } else if (this.getAttribute('type').toLowerCase() == 'hidden' && !this.siblings('input[type=checkbox][name="' + this.get('name') + '"]').isEmpty()) { + // This is the hidden input that is part of an advcheckbox. + hidden_val = (this.get('value') != value); + return; + } else if (this.getAttribute('type').toLowerCase() == 'checkbox' && !Y.Node.getDOMNode(this).checked) { + lock = lock || hidden_val; + return; + } + //check for filepicker status + if (this.getAttribute('class').toLowerCase() == 'filepickerhidden') { + var elementname = this.getAttribute('name'); + if (elementname && M.form_filepicker.instances[elementname].fileadded) { + lock = true; + } else { + lock = false; + } + } else if (this.get('nodeName').toUpperCase() === 'SELECT' && this.get('multiple') === true) { + // Multiple selects can have one or more value assigned. A pipe (|) is used as a value separator + // when multiple values have to be selected at the same time. + values = value.split('|'); + this.get('options').each(function() { + if (this.get('selected')) { + selected[selected.length] = this.get('value'); + } + }); + if (selected.length > 0 && selected.length === values.length) { + for (var i in selected) { + if (values.indexOf(selected[i]) > -1) { + lock = false; + } else { + lock = true; + return; + } + } + } else { + lock = true; + } + } else { + lock = lock || this.get('value') != value; + } + }); + return { + lock: lock, + hide: false + }; + } + }, { + NAME: 'mform-dependency-manager', + ATTRS: { + form: { + setter: function(value) { + return Y.one('#' + value); + }, + value: null + }, + + dependencies: { + value: {} + } + } + }); + + M.form.dependencyManager = dependencyManager; +} + /** * Stores a list of the dependencyManager for each form on the page. */ @@ -34,507 +563,7 @@ M.form.initFormDependencies = function(Y, formid, dependencies) { } }; - // Define the dependency manager if it hasn't already been defined. - M.form.dependencyManager = M.form.dependencyManager || (function(){ - var dependencyManager = function(config) { - dependencyManager.superclass.constructor.apply(this, arguments); - }; - dependencyManager.prototype = { - _form : null, - _locks : [], - _hides : [], - _dirty : [], - _nameCollections : null, - _fileinputs : null, - initializer : function(config) { - var i = 0, nodeName; - this._form = Y.one('#'+formid); - for (i in dependencies) { - var elements = this.elementsByName(i); - if (elements.size() == 0) { - continue; - } - elements.each(function(node){ - nodeName = node.get('nodeName').toUpperCase(); - if (nodeName == 'INPUT') { - if (node.getAttribute('type').match(/^(button|submit|radio|checkbox)$/)) { - node.on('click', this.updateEventDependencies, this); - } else { - node.on('blur', this.updateEventDependencies, this); - } - node.on('change', this.updateEventDependencies, this); - } else if (nodeName == 'SELECT') { - node.on('change', this.updateEventDependencies, this); - } else { - node.on('click', this.updateEventDependencies, this); - node.on('blur', this.updateEventDependencies, this); - node.on('change', this.updateEventDependencies, this); - } - }, this); - } - this._form.get('elements').each(function(input){ - if (input.getAttribute('type')=='reset') { - input.on('click', function(){ - this._form.reset(); - this.updateAllDependencies(); - }, this); - } - }, this); - - return this.updateAllDependencies(); - }, - /** - * Initializes the mapping from element name to YUI NodeList - */ - initElementsByName : function() { - var names = []; - // Collect element names - for (var i in dependencies) { - names[i] = new Y.NodeList(); - for (var condition in dependencies[i]) { - for (var value in dependencies[i][condition]) { - for (var ei in dependencies[i][condition][value]) { - names[dependencies[i][condition][value][ei]] = new Y.NodeList(); - } - } - } - } - // Locate elements for each name - this._form.get('elements').each(function(node){ - var name = node.getAttribute('name'); - if (names[name]) { - names[name].push(node); - } - }); - this._nameCollections = names; - }, - /** - * Gets all elements in the form by their name and returns - * a YUI NodeList - * - * @param {string} name The form element name. - * @return {Y.NodeList} - */ - elementsByName : function(name) { - if (!this._nameCollections) { - this.initElementsByName(); - } - if (!this._nameCollections[name]) { - return new Y.NodeList(); - } - return this._nameCollections[name]; - }, - /** - * Checks the dependencies the form has an makes any changes to the - * form that are required. - * - * Changes are made by functions title _dependency_{dependencytype} - * and more can easily be introduced by defining further functions. - * - * @param {EventFacade | null} e The event, if any. - * @param {string} name The form element name to check dependencies against. - */ - checkDependencies : function(e, dependon) { - var tohide = [], - tolock = [], - condition, value, lock, hide, - checkfunction, result, elements; - if (!dependencies[dependon]) { - return true; - } - elements = this.elementsByName(dependon); - for (condition in dependencies[dependon]) { - for (value in dependencies[dependon][condition]) { - checkfunction = '_dependency_'+condition; - if (Y.Lang.isFunction(this[checkfunction])) { - result = this[checkfunction].apply(this, [elements, value, e]); - } else { - result = this._dependency_default(elements, value, e); - } - lock = result.lock || false; - hide = result.hide || false; - for (var ei in dependencies[dependon][condition][value]) { - var eltolock = dependencies[dependon][condition][value][ei]; - tohide[eltolock] = tohide[eltolock] || hide; - tolock[eltolock] = tolock[eltolock] || lock; - } - } - } - for (var el in tolock) { - var needsupdate = false; - if (tolock[el]) { - this._locks[el] = this._locks[el] || []; - if (!this._locks[el][dependon]) { - this._locks[el][dependon] = true; - needsupdate = true; - } - } else if (this._locks[el] && this._locks[el][dependon]) { - delete this._locks[el][dependon]; - needsupdate = true; - } - if (tohide[el]) { - this._hides[el] = this._hides[el] || []; - if (!this._hides[el][dependon]) { - this._hides[el][dependon] = true; - needsupdate = true; - } - } else if (this._hides[el] && this._hides[el][dependon]) { - delete this._hides[el][dependon]; - needsupdate = true; - } - if (needsupdate) { - this._dirty[el] = true; - } - } - return true; - }, - /** - * Update all dependencies in form - */ - updateAllDependencies : function() { - for (var el in dependencies) { - this.checkDependencies(null, el); - } - this.updateForm(); - }, - /** - * Update dependencies associated with event - * - * @param {Event} e The event. - */ - updateEventDependencies : function(e) { - var el = e.target.getAttribute('name'); - this.checkDependencies(e, el); - this.updateForm(); - }, - /** - * Flush pending changes to the form - */ - updateForm : function() { - for (var el in this._dirty) { - if (this._locks[el]) { - var locked = !this._isObjectEmpty(this._locks[el]); - this._disableElement(el, locked); - } - if (this._hides[el]) { - var hidden = !this._isObjectEmpty(this._hides[el]); - this._hideElement(el, hidden); - } - } - this._dirty = []; - }, - /** - * Disables or enables all form elements with the given name - * - * @param {string} name The form element name. - * @param {boolean} disabled True to disable, false to enable. - */ - _disableElement : function(name, disabled) { - var els = this.elementsByName(name); - var filepicker = this.isFilePicker(name); - els.each(function(node){ - if (disabled) { - node.setAttribute('disabled', 'disabled'); - } else { - node.removeAttribute('disabled'); - } - - // Extra code to disable filepicker or filemanager form elements - if (filepicker) { - var fitem = node.ancestor('.fitem'); - if (fitem) { - if (disabled){ - fitem.addClass('disabled'); - } else { - fitem.removeClass('disabled'); - } - } - } - }) - }, - /** - * Hides or shows all form elements with the given name. - * - * @param {string} name The form element name. - * @param {boolean} disabled True to hide, false to show. - */ - _hideElement : function(name, hidden) { - var els = this.elementsByName(name); - els.each(function(node){ - var e = node.ancestor('.fitem'); - if (e) { - e.setStyles({ - display : (hidden)?'none':'' - }) - } - }); - }, - /** - * Is the form element inside a filepicker or filemanager? - * - * @param {string} el The form element name. - * @return {boolean} - */ - isFilePicker : function(el) { - if (!this._fileinputs) { - var fileinputs = []; - var els = this._form.all('.fitem.fitem_ffilepicker input,.fitem.fitem_ffilemanager input'); - els.each(function(node){ - fileinputs[node.getAttribute('name')] = true; - }); - this._fileinputs = fileinputs; - } - return this._fileinputs[el] || false; - }, - /** - * Check if the object is empty - * - * @param {object} obj - * @return {boolean} - */ - _isObjectEmpty : function(obj) { - for(var prop in obj) { - if(obj.hasOwnProperty(prop)) - return false; - } - return true; - }, - _dependency_notchecked : function(elements, value) { - var lock = false; - elements.each(function(){ - if (this.getAttribute('type').toLowerCase()=='hidden' && !this.siblings('input[type=checkbox][name="' + this.get('name') + '"]').isEmpty()) { - // This is the hidden input that is part of an advcheckbox. - return; - } - if (this.getAttribute('type').toLowerCase()=='radio' && this.get('value') != value) { - return; - } - lock = lock || !Y.Node.getDOMNode(this).checked; - }); - return { - lock : lock, - hide : false - } - }, - _dependency_checked : function(elements, value) { - var lock = false; - elements.each(function(){ - if (this.getAttribute('type').toLowerCase()=='hidden' && !this.siblings('input[type=checkbox][name="' + this.get('name') + '"]').isEmpty()) { - // This is the hidden input that is part of an advcheckbox. - return; - } - if (this.getAttribute('type').toLowerCase()=='radio' && this.get('value') != value) { - return; - } - lock = lock || Y.Node.getDOMNode(this).checked; - }); - return { - lock : lock, - hide : false - } - }, - _dependency_noitemselected : function(elements, value) { - var lock = false; - elements.each(function(){ - lock = lock || this.get('selectedIndex') == -1; - }); - return { - lock : lock, - hide : false - } - }, - _dependency_eq : function(elements, value) { - var lock = false; - var hidden_val = false; - var options, v, selected, values; - elements.each(function(){ - if (this.getAttribute('type').toLowerCase()=='radio' && !Y.Node.getDOMNode(this).checked) { - return; - } else if (this.getAttribute('type').toLowerCase() == 'hidden' && !this.siblings('input[type=checkbox][name="' + this.get('name') + '"]').isEmpty()) { - // This is the hidden input that is part of an advcheckbox. - hidden_val = (this.get('value') == value); - return; - } else if (this.getAttribute('type').toLowerCase() == 'checkbox' && !Y.Node.getDOMNode(this).checked) { - lock = lock || hidden_val; - return; - } - if (this.getAttribute('class').toLowerCase() == 'filepickerhidden') { - // Check for filepicker status. - var elementname = this.getAttribute('name'); - if (elementname && M.form_filepicker.instances[elementname].fileadded) { - lock = false; - } else { - lock = true; - } - } else if (this.get('nodeName').toUpperCase() === 'SELECT' && this.get('multiple') === true) { - // Multiple selects can have one or more value assigned. A pipe (|) is used as a value separator - // when multiple values have to be selected at the same time. - values = value.split('|'); - selected = []; - options = this.get('options'); - options.each(function() { - if (this.get('selected')) { - selected[selected.length] = this.get('value'); - } - }); - if (selected.length > 0 && selected.length === values.length) { - for (var i in selected) { - v = selected[i]; - if (values.indexOf(v) > -1) { - lock = true; - } else { - lock = false; - return; - } - } - } else { - lock = false; - } - } else { - lock = lock || this.get('value') == value; - } - }); - return { - lock : lock, - hide : false - } - }, - /** - * Lock the given field if the field value is in the given set of values. - * - * @param elements - * @param values - * @returns {{lock: boolean, hide: boolean}} - * @private - */ - _dependency_in : function(elements, values) { - // A pipe (|) is used as a value separator - // when multiple values have to be passed on at the same time. - values = values.split('|'); - var lock = false; - var hidden_val = false; - var options, v, selected, value; - elements.each(function(){ - if (this.getAttribute('type').toLowerCase()=='radio' && !Y.Node.getDOMNode(this).checked) { - return; - } else if (this.getAttribute('type').toLowerCase() == 'hidden' && !this.siblings('input[type=checkbox][name="' + this.get('name') + '"]').isEmpty()) { - // This is the hidden input that is part of an advcheckbox. - hidden_val = (values.indexOf(this.get('value')) > -1); - return; - } else if (this.getAttribute('type').toLowerCase() == 'checkbox' && !Y.Node.getDOMNode(this).checked) { - lock = lock || hidden_val; - return; - } - if (this.getAttribute('class').toLowerCase() == 'filepickerhidden') { - // Check for filepicker status. - var elementname = this.getAttribute('name'); - if (elementname && M.form_filepicker.instances[elementname].fileadded) { - lock = false; - } else { - lock = true; - } - } else if (this.get('nodeName').toUpperCase() === 'SELECT' && this.get('multiple') === true) { - // Multiple selects can have one or more value assigned. - selected = []; - options = this.get('options'); - options.each(function() { - if (this.get('selected')) { - selected[selected.length] = this.get('value'); - } - }); - if (selected.length > 0 && selected.length === values.length) { - for (var i in selected) { - v = selected[i]; - if (values.indexOf(v) > -1) { - lock = true; - } else { - lock = false; - return; - } - } - } else { - lock = false; - } - } else { - value = this.get('value'); - lock = lock || (values.indexOf(value) > -1); - } - }); - return { - lock : lock, - hide : false - } - }, - _dependency_hide : function(elements, value) { - return { - lock : false, - hide : true - } - }, - _dependency_default : function(elements, value, ev) { - var lock = false; - var hidden_val = false; - elements.each(function(){ - if (this.getAttribute('type').toLowerCase()=='radio' && !Y.Node.getDOMNode(this).checked) { - return; - } else if (this.getAttribute('type').toLowerCase() == 'hidden' && !this.siblings('input[type=checkbox][name="' + this.get('name') + '"]').isEmpty()) { - // This is the hidden input that is part of an advcheckbox. - hidden_val = (this.get('value') != value); - return; - } else if (this.getAttribute('type').toLowerCase() == 'checkbox' && !Y.Node.getDOMNode(this).checked) { - lock = lock || hidden_val; - return; - } - //check for filepicker status - if (this.getAttribute('class').toLowerCase() == 'filepickerhidden') { - var elementname = this.getAttribute('name'); - if (elementname && M.form_filepicker.instances[elementname].fileadded) { - lock = true; - } else { - lock = false; - } - } else if (this.get('nodeName').toUpperCase() === 'SELECT' && this.get('multiple') === true) { - // Multiple selects can have one or more value assigned. A pipe (|) is used as a value separator - // when multiple values have to be selected at the same time. - values = value.split('|'); - selected = []; - options = this.get('options'); - options.each(function() { - if (this.get('selected')) { - selected[selected.length] = this.get('value'); - } - }); - if (selected.length > 0 && selected.length === values.length) { - for (var i in selected) { - v = selected[i]; - if (values.indexOf(v) > -1) { - lock = false; - } else { - lock = true; - return; - } - } - } else { - lock = true; - } - } else { - lock = lock || this.get('value') != value; - } - }); - return { - lock : lock, - hide : false - } - } - }; - Y.extend(dependencyManager, Y.Base, dependencyManager.prototype, { - NAME : 'mform-dependency-manager' - }); - - return dependencyManager; - })(); - - M.form.dependencyManagers[formid] = new M.form.dependencyManager(); + M.form.dependencyManagers[formid] = new M.form.dependencyManager({form: formid, dependencies: dependencies}); return M.form.dependencyManagers[formid]; };