From d3164bb9e01e2d5c6164899b9ce786706be6ec9e Mon Sep 17 00:00:00 2001 From: Niko Date: Fri, 13 Dec 2013 02:28:07 +0100 Subject: [PATCH] clean up --- dist/jquery.jsForm-1.1.0.js | 2657 ------------------------------- dist/jquery.jsForm.1.1.0.min.js | 6 - 2 files changed, 2663 deletions(-) delete mode 100644 dist/jquery.jsForm-1.1.0.js delete mode 100644 dist/jquery.jsForm.1.1.0.min.js diff --git a/dist/jquery.jsForm-1.1.0.js b/dist/jquery.jsForm-1.1.0.js deleted file mode 100644 index 14ef3f7..0000000 --- a/dist/jquery.jsForm-1.1.0.js +++ /dev/null @@ -1,2657 +0,0 @@ -/** - * jquery.jsForm - * ------------- - * JsForm control for handling html UI with json objects - * @version 1.0 - * @class - * @author Niko Berger - * @license MIT License GPL - */ -;(function( $, window, undefined ){ - "use strict"; - - var JSFORM_INIT_FUNCTIONS = {}, // remember initialization functions - JSFORM_MAP = {}; // remember all forms - - - /** - * @param element {Node} the cotnainer node that should be converted to a jsForm - * @param options {object} the configuraton object - * @constructor - */ - function JsForm (element, options) { - var $this = $(element); - - // create the options - this.options = $.extend({}, { - /** - * enable form control rendering (if jsForm.controls is available) and validation - */ - controls: true, - /** - * the object used to fill/collect data - */ - data: null, - /** - * the prefix used to annotate theinput fields - */ - prefix: "data", - /** - * set to false to only validate visible fields. - * This is discouraged especially when you have tabs or similar elements in your form. - */ - validateHidden: true, - /** - * skip empty values when getting an object - */ - skipEmpty: false - }, options); - - // read prefix from dom - if($this.attr("data-prefix") && (this.options.prefix === "data" || this.options.prefix === "")) { - if($this.attr("data-prefix") !== "") { - this.options.prefix = $this.attr("data-prefix"); - } - } - - this.element = element; - - this._init(); - } - - /** - * init the portlet - load the config - * @private - */ - JsForm.prototype._init = function() { - // init the basic dom functionality - this._domInit(); - - // enable form controls - if(this.options.controls) { - if($.jsFormControls) { - $(this.element).jsFormControls(); - } else { - try { - if(typeof console !== "undefined") { - console.log("jquery.JsForm.controls not available!"); - } - } catch(ex) { - // ignore - } - } - } - - // fill/init with the first data - this._fill(this.element, this.options); - }; - - - /** - * init the dom. This can be called multiple times. - * this will also enable "add", "insert" and "delete" for collections - * @private - */ - JsForm.prototype._domInit = function() { - var form = $(this.element); - var that = this; - var prefix = this.options.prefix; - - // collection lists with buttons - that._initCollection(form, prefix); - // init conditionals - that._initConditional(form, prefix, this.options); - }; - - /** - * simple debug helper - * @param msg the message to pring - * @private - */ - JsForm.prototype._debug = function(msg) { - if(typeof console !== "undefined") { - console.log("JsForm: " + msg); - } - }; - - /** - * initialize conditionals. - * basic rule is: - * any dom element that has a conditional and either - * a data-show or data-hide attribute or a data-eval attribute - * - * @param form the base dom element - * @param prefix the prefix to check for - * @private - */ - JsForm.prototype._initConditional = function(form, prefix, options) { - var that = this; - var showEvaluator = function(ele, data, fields) { - // if any field has a value -> show - var show = false; - $.each(fields, function(){ - var value = that._getValueWithArrays(data, this); - if(!value || value === "" || value === 0 || value === -1) - return; - show = true; - // skip processing - return false; - }); - if(show) - ele.show(); - else - ele.hide(); - }, hideEvaluator = function(ele, data, fields) { - // if any field has a value -> hide - var show = false; - $.each(fields, function(){ - var value = that._getValueWithArrays(data, this); - if(!value || value === "" || value === 0 || value === -1) - return; - show = true; - // skip processing - return false; - }); - if(show) - ele.hide(); - else - ele.show(); - }; - - // remember the conditionals for faster dom access - this.conditionals = $(form).find(".conditional"); - - this.conditionals.each(function(){ - $(this).data().conditionalEval = []; - var fields = $(this).attr("data-show"); - if(fields && fields.length > 0) { - $(this).data().conditionalEval.push({ - func: showEvaluator, - field: fields.split(" ") - }); - } - fields = $(this).attr("data-hide"); - if(fields && fields.length > 0) { - $(this).data().conditionalEval.push({ - func: hideEvaluator, - field: fields.split(" ") - }); - } - fields = $(this).attr("data-eval"); - if(fields && fields.length > 0) { - // custom evaluator - if(options.conditionals[fields]) - $(this).data().conditionalEval.push({ - func: options.conditionals[fields] - }); - } - }); - }; - - /** - * evaluate conditionals on the form - * @param form the form to search for conditionals - * @param data the data - */ - JsForm.prototype._evaluateConditionals = function(form, data) { - this.conditionals.each(function(){ - var ele = $(this); - // go throguh all evaluation functions - $.each(ele.data().conditionalEval, function() { - this.func(ele, data, this.field); - }); - }); - }; - - /** - * initialize collections - * @param form the base dom element - * @param prefix the prefix to check for - * @private - */ - JsForm.prototype._initCollection = function(form, prefix) { - // all collections - var collectionMap = {}, - that = this; - $(form).data().collections = collectionMap; - - $(".collection", form).each(function() { - var colName = $(this).attr("data-field"); - // skip collections without a data-field mapping - if (!colName || colName.indexOf(prefix + ".") !== 0) { - return; - } - - var container = $(this); - - // remember the collection - var cols = collectionMap[colName]; - if(cols) { - cols.push(container); - } else { - collectionMap[colName] = [container]; - } - - //init the collection - that._initList(container); - - // after adding: check if we want reorder control - if(!container.hasClass("ui-sortable") && container.hasClass("sortable") && container.sortable) { - // get the config object - var config = container.attr("data-sortable"); - if(!config) { - config = {}; - } else { - config = JSON.parse(config); - } - - container.sortable(config); - container.on("sortstop", function( event, ui ) { - that._reorder(container); - }); - } - - }); - - $(".add", form).each(function(){ - var fieldName = $(this).attr("data-field"); - if(!fieldName) { - return; - } - - // only init once - if($(this).data("collections")) { - return; - } - - // add the collection - $(this).data().collections = collectionMap[fieldName]; - - $(this).click(function(ev){ - ev.preventDefault(); - - // search for a collection with that name - $.each($(this).data("collections"), function() { - var tmpl = $(this).data("template"); - // and has a template - if(tmpl) { - var line = tmpl.clone(true); - $(this).append(line); - $(line).addClass("POJO"); - $(line).data("pojo", {}); - - that._addCollectionControls(line); - - // trigger a callback - $(this).trigger("addCollection", [line, $(line).data().pojo]); - - // the new entry has as index the count of all "lines" - var idx = $(this).children(".POJO").length; - - // fill the line with data - that._fillData(line, $(line).data().pojo, fieldName.substring(fieldName.indexOf('.')+1), idx); - - // its possible to have "sub" collections - that._initCollection(line, fieldName.substring(fieldName.indexOf('.')+1)); - - // trigger a callback after the data has been rendered) - $(this).trigger("postAddCollection", [line, $(line).data().pojo]); - - - } - }); - }); - }); - - // insert: similar to add - but works with events - $(".insert", form).each(function(){ - var fieldName = $(this).attr("data-field"); - if(!fieldName) { - return; - } - - // only init once - if($(this).data("collections")) { - return; - } - - // remember the collections - $(this).data("collections", collectionMap[$(this).attr("data-field")]); - - $(this).on("insert", function(ev, pojo){ - if(!pojo) - pojo = $(this).data().pojo; - - // insert only works if there is a pojo - if(!pojo) { - return; - } - var beforeInsertCallback = $(this).data("beforeInsert"); - if(beforeInsertCallback && $.isFunction(beforeInsertCallback)) { - pojo = beforeInsertCallback(pojo); - - // insert only works if there is a pojo - if(!pojo) { - return; - } - } - - // search for a collection with that name - $.each($(this).data("collections"), function() { - var tmpl = $(this).data("template"); - // and has a template - if(tmpl) { - var line = tmpl.clone(true); - // mark that this is a pojo - line.addClass("POJO"); - // add the pojo - line.data().pojo = pojo; - - that._addCollectionControls(line); - - // its possible to have "sub" collections - that._initCollection(line); - - // trigger a callback - $(this).trigger("addCollection", [line, $(line).data().pojo]); - - // the new entry has as index the count of all "lines" - var idx = $(this).children(".POJO").length; - - // fill the "information" - that._fillData(line, pojo, fieldName.substring(fieldName.indexOf('.')+1), idx); - - $(this).append(line); - } - }); - - // empty field - $(this).val(""); - $(this).data().pojo = null; - $(this).focus(); - }); - }); - - // insert: helper button (triggers insert) - $(".insertAction", form).each(function(){ - var fieldName = $(this).attr("data-field"); - if(!fieldName) { - return; - } - - // only init once - if($(this).data("inserter")) { - return; - } - - // find the insert element for this data-field - var inserter = $(this).parent().find(".insert"); - if(!inserter) { - return; - } - - // remember the inserter - $(this).data("inserter", inserter); - - $(this).click(function(ev){ - ev.preventDefault(); - $(this).data("inserter").trigger("insert"); - return false; - }); - - }); - - $("input.object", form).each(function(){ - $(this).on("update", function(evt){ - var pojo = $(this).data().pojo; - if (pojo && $(this).attr("data-display")) { - $(this).val(that._renderObject(pojo, $(this).attr("data-display"))); - } - }); - }); - - // fileupload - $("input.blob", form).each(function(){ - // only available on input type file - if($(this).attr("type") !== "file") { - return; - } - - var blobInput = $(this); - - // bind on change - $(this).on("change", function(evt){ - - //get file name - var fileName = $(this).val().split(/\\/).pop(); - blobInput.data("name", fileName); - - var files = evt.target.files; // FileList object - // Loop through the FileList (and render image files as thumbnails.(skip for ie < 9) - if(files && files.length) { - $.each(files, function() { - var reader = new FileReader(); - - // closure to capture the file information - reader.onload = function(e) { - // get the result - blobInput.data("blob", e.target.result); - }; - - // Read in the image file as a data URL. - reader.readAsDataURL(this); - - $(this).trigger("fileChange"); - }); - } - }); - - - }); - - // manage - obsolete - $(".manage", form).each(function(){ - var fieldName = $(this).attr("data-field"); - if(!fieldName) { - return; - } - - // remember the collections - $(this).data("collections", collectionMap[fieldName]); - - // start the multi-select - $(this).click(function(){ - var dataService = $(this).attr("data-service"); - var collectionList = $(this).data("collections"); - - var btn = $(this); - var display = $(this).attr("data-display"); - if(display) { - display = display.split(","); - } - - DataUtils.run(dataService, function(data){ - var select = $(''); - select.data("collections", collectionList); - btn.data("select", select); - $.each(data, function(){ - var cur = this; - var optionDisplay = ""; - if(!display) { - optionDisplay = cur; - } else { - for(var j = 0; j < display.length; j++) { - optionDisplay += cur[display[j]] + " "; - } - } - var option = $(''); - // check if we need to "select" that option - $(collectionList).each(function() { - $(this).children().each(function(count, ele){ - if(cur.id === $(ele).data("pojo").id) { - option.prop("selected", "selected"); - } - }); - }); - select.append(option); - option.data("pojo", cur); - }); - - btn.after(select); - btn.hide(); - - select.multiselect({ - autoOpen: true, - open: function(){ - //reposition - $(this).multiselect("widget").css("top", $(select).next().offset().top); - $(this).multiselect("widget").css("left", $(select).next().offset().left); - // hide button - $(select).next().hide(); - }, - close: function(){ - btn.show(); - select.remove(); - $(this).multiselect("destroy"); - } - }).multiselectfilter().bind("multiselectclick multiselectcheckall multiselectuncheckall", - function( event, ui ){ - var checkedValues = $.map($(this).multiselect("getChecked"), function( input ){ - // we only get the same "value" - so check the option list for the correct pojo - return $("option[value='"+input.value+"']", select).data("pojo"); - }); - - // update collection - $.each($(select).data("collections"), function(){ - that._fillList($(this), checkedValues, fieldName); - }); - // reposition - btn.hide(); - $(select).next().show(); - $(this).multiselect("widget").css("top", $(select).next().offset().top); - $(this).multiselect("widget").css("left", $(select).next().offset().left); - $(select).next().hide(); - }); - }); - }); - }); - }; - - /** - * init a container that has a tempalate child (first child). - * @param container the contianer element - * @private - */ - JsForm.prototype._initList = function(container) { - // avoid double initialisation - if(container.data("template")) { - return; - } - - // get all children - var tmpl = container.children().detach(); - - // remove an id if there is one - tmpl.removeAttr("id"); - container.data("template", tmpl); - }; - - /** - * clear/reset a form. The prefix is normally predefined by init - * @param form the form - * @param prefix the optional prefix used to identify fields for this form - */ - JsForm.prototype._clear = function(form, prefix) { - // get the prefix from the form if not given - if(!prefix) { - prefix = this.options.prefix; - } - - $(form).removeData("pojo"); - $("input,select,textarea", form).each(function(){ - var name = $(this).attr("name"); - // empty name - ignore - if (!name || name.indexOf(prefix + ".") !== 0) { - return; - } - // cut away the prefix - name = name.substring((prefix+".").length); - // skip empty - if(name.length < 1) { - return; - } - - // remove all pojos - $(this).removeData("pojo"); - - if($(this).attr("type") === "checkbox") { - $(this).prop("checked", false); - } else { - $(this).val(""); - } - if($(this).hasClass("blob")) { - $(this).removeData("blob"); - } - // special type select box: select the FIRST child - if($(this).is("select")) { - $('option[selected="selected"]', this).removeAttr('selected'); - $('option:first', this).attr('selected', true); - - $(this).val($("option:first", this).val()).change(); - } - // trigger change - $(this).change(); - }); - - $(".collection", form).each(function() { - var fieldname = $(this).attr("data-field"); - // only collections with the correct prefix - if(!fieldname || fieldname.indexOf(prefix+".") !== 0) { - return; - } - // get rid of all - $(this).empty(); - }); - - }; - /** - * ceate a pojo from a form. Takes special data definition classes into account: - * - * @param start the element to start from (ie. the form or tr) - * @param pojo the pojo to write everything to - * @param prefix a prefix: only fields with the given prefix will be included in the pojo - * @private - */ - JsForm.prototype._createPojoFromInput = function (start, prefix, pojo) { - // check if we have an "original" pojo - var startObj = null; - var that = this; - - // get it from the starting dom element - if($(start).data("pojo")) { - startObj = $(start).data("pojo"); - } - - // if we have an object, use this as base and fill the pojo - if(startObj) { - $.extend(true, pojo, startObj); - } - - $(start).find("input,select,textarea,.jsobject").each(function(){ - var name = $(this).attr("data-name"); - if(!name) { - name = $(this).attr("name"); - } - - // empty name - ignore - if (!name) { - return; - } - - // skip grayed (=calculated) or transient fields - if($(this).hasClass("transient")) { - return; - } - - // must start with prefix - if(name.indexOf(prefix + ".") !== 0) { - return; - } - - $(this).trigger("validate", true); - - // cut away the prefix - name = name.substring((prefix+".").length); - - - var val = $(this).val(); - - // jsobject use the pojo data - if($(this).hasClass("jsobject")) { - val = $(this).data("pojo"); - } - - // ignore empty values when skipEmpty is set - if(that.options.skipEmpty && (!val || val === "" || val.trim() === "")) { - return; - } - - if($(this).hasClass("emptynull") && (!val || val === "" || val === "null" || val.trim() === "")) { // nullable fields do not send empty string - val = null; - } else if($(this).hasClass("object") || $(this).hasClass("POJO")) { - if($("option:selected", this).data() && $("option:selected", this).data().pojo) { - val = $("option:selected", this).data().pojo; - } else { - val = $(this).data("pojo"); - } - } else if($(this).hasClass("blob")) { // file upload blob - val = $(this).data("blob"); - } else - // set empty numbers or dates to null - if(val === "" && ($(this).hasClass("number") || $(this).hasClass("integer") || $(this).hasClass("dateFilter")|| $(this).hasClass("dateTimeFilter"))) { - val = null; - } - - // check for percentage: this is input / 100 - if ($(this).hasClass("percent")) { - val = that._getNumber(val); - if(isNaN(val)) { - val = 0; - } else { - val /= 100; - } - } - - if ($(this).hasClass("number") || $(this).hasClass("integer") || $(this).hasClass("currency")) { - val = that._getNumber(val); - if(isNaN(val)) { - val = 0; - } - } - else if($(this).attr("type") === "checkbox" || $(this).attr("type") === "CHECKBOX") { - val = $(this).is(':checked'); - } - else if($(this).hasClass("bool")) { - val = ($(this).val() === "true"); - } - - // handle simple collection - if(name.length < 1) { - pojo = val; - return false; - } - - // check if we have a . - if so split - if (name.indexOf(".") === -1) - { - pojo[name] = val; - } - else - { - var parts = name.split("."); - - var d0 = pojo[parts[0]]; - var d1, d2; - - // multiple parts: make sure its an object - if (!d0 || !$.isPlainObject(d0)) { - pojo[parts[0]] = {}; - d0 = pojo[parts[0]]; - } - - if (parts.length === 2) { - d0[parts[1]] = val; - } else if (parts.length === 3) { - d1 = d0[parts[1]]; - if(d1 === undefined) { - d1 = {}; - d0[parts[1]] = d1; - } - d1[parts[2]] = val; - } else if (parts.length === 4) - { - d1 = d0[parts[1]]; - d2 = d1[parts[2]]; - if(d2 === undefined) { - d2 = {}; - d1[parts[2]] = d2; - } - d1[parts[2]] = val; - d2[parts[3]] = val; - } - // more should not be necessary - } - }); - - return pojo; - }; - - - /** - * fill a dom subtree with data. - * - * @param parent the root of the subtree - * @param data the data - * @param prefix the prefix used to find fields - * @param idx the index - this is only used for collections - * @private - */ - JsForm.prototype._fillData = function (parent, data, prefix, idx) { - var that = this; - var $parent = $(parent); - - // locate all "fields" - $parent.find(".field").each(function() { - var name = $(this).data("name"); - if(!name) { - if(this.nodeName.toUpperCase() === 'A') { - name = $(this).attr("href"); - $(this).attr("href", "#"); - }else if(this.nodeName.toUpperCase() === 'IMG') { - name = $(this).attr("src"); - if(name.indexOf("#") === 0) { - name = name.substring(1); - } - $(this).attr("src", "#"); - }else { - name = $(this).text(); - } - $(this).data("name", name); - $(this).show(); - } - - if(!prefix || name.indexOf(prefix + ".") >= 0) { - var cname = name; - if (prefix) { - cname = cname.substring(prefix.length + 1); - } - var cdata = that._get(data, cname, false, idx); - - if(!cdata) { - cdata = ""; - } - - // check for percentage: this is value * 100 - if ($(this).hasClass("percent") && !isNaN(cdata)) { - cdata = 100 * Number(cdata); - } - - // format the string - if($.jsFormControls) - cdata = $.jsFormControls.Format.format(this, cdata); - - if(this.nodeName.toUpperCase() === 'A') { - $(this).attr("href", cdata); - } else if(this.nodeName.toUpperCase() === 'IMG') { - $(this).attr("src", cdata); - } - else if(this.nodeName.toUpperCase() === "DIV"){ - $(this).html(cdata); - } else { - $(this).text(cdata); - } - } - }); - - $("input, textarea", $parent).each(function() { - var name = $(this).attr("name"); - if(!name) { - return; - } - - // ignore file inputs - they cannot be "prefilled" - if($(this).attr("type") == "file") { - return; - } - - if(!prefix || name.indexOf(prefix + ".") >= 0) { - var cname = name; - if (prefix) { - cname = cname.substring(prefix.length + 1); - } - - var cdata = that._get(data, cname, false, idx); - - // check for percentage: this is value * 100 - if ($(this).hasClass("percent") && !isNaN(cdata)) { - cdata = 100 * Number(cdata); - } else if ($(this).hasClass("object")) { - $(this).data().pojo = cdata; - $(this).addClass("POJO"); - if($(this).attr("data-display")) { - cdata = that._renderObject(cdata, $(this).attr("data-display")); - } - } else if($.isPlainObject(cdata)) { - $(this).data().pojo = cdata; - $(this).addClass("POJO"); - cdata = that._renderObject(cdata, $(this).attr("data-display")); - } - - - if($(this).attr("type") === "checkbox") { - $(this).prop("checked", (cdata === true || cdata === "true")); - } else { - if(!cdata) { - cdata = ""; - } - - // format the string - if($.jsFormControls) - cdata = $.jsFormControls.Format.format(this, cdata); - - $(this).val(cdata); - } - - $(this).change(); - $(this).trigger("fill"); - } - }); - - $("select", $parent).each(function() { - var name = $(this).attr("name"); - if(!name) { - return; - } - - if(!prefix || name.indexOf(prefix + ".") >= 0) { - var cname = name; - if (prefix) { - cname = cname.substring(prefix.length + 1); - } - // remove "old" selected options - $(this).children("option").removeProp("selected"); - var pk = $(this).attr("data-key"); - if(!pk) { - pk = "id"; - } - - var value = that._get(data, cname, false, idx); - // try selecting based on the id - if (value[pk] || !isNaN(value[pk])) { - $(this).children("option[value='"+value[pk]+"']").prop("selected", "selected"); - // actually set the value and trigger the change - $(this).val(value[pk]).change(); - return; - } else if($(this).hasClass("bool")) { - value = value ? "true" : "false"; - } - - $(this).children("option[value='"+value+"']").prop("selected", "selected"); - $(this).val(value).change(); - $(this).trigger("fill"); - } - }); - }; - - /** - * ceate a pojo from a form. Takes special data definition classes into account: - * - * @param ignoreInvalid return a pojo, even if fields do not pass client side validation - * @return a new pojo - */ - JsForm.prototype.get = function(ignoreInvalid) { - var form = $(this.element); - var that = this; - var originalPojo = this.options.data; - var prefix = this.options.prefix; - - // get the pojo - var pojo = {}; - if(originalPojo && $.isPlainObject(originalPojo)) { - pojo = originalPojo; - } - - // fill the base - that._createPojoFromInput(form, prefix, pojo); - - // check for invalid fields - var invalid = false; - if(!this.options.validateHidden) { - form.find(".invalid").filter(":visible").each(function(){ - invalid = true; - $(this).focus(); - if(!ignoreInvalid) { - that._debug("Found invalid field: " + $(this).attr("name")); - } - return false; - }); - } else { - form.find(".invalid").each(function(){ - invalid = true; - $(this).focus(); - return false; - }); - } - - // get the collection - if(this._getCollection(form, prefix, pojo, ignoreInvalid)) { - invalid = true; - } - - if(!ignoreInvalid && invalid) { - return null; - } - - return pojo; - }; - - /** - * fill a pojo based on collections - * @param form {DOMElement} the base element to start looking for collections - * @param prefix {string} the prefix used - * @param pojo {object} the object to fill - * @param ignoreInvalid {boolean} if true the function will return as soon as an invalid field is found - * @return true if the colelction encountered an invalid field - */ - JsForm.prototype._getCollection = function(form, prefix, pojo, ignoreInvalid) { - var that = this; - // check for invalid fields - var invalid = false; - - form.find(".collection").each(function() { - if(!ignoreInvalid && invalid) { - return; - } - - var fieldname = $(this).attr("data-field"); - // only collections with the correct prefix - if(!fieldname || fieldname.indexOf(prefix+".") !== 0) { - return; - } - - fieldname = fieldname.substring((prefix+".").length); - if(fieldname.length < 1) { - return; - } - - var colParent = that._getParent(pojo, fieldname, true); - - // get only the last part - if(fieldname.indexOf('.') !== -1) { - fieldname = fieldname.substring(fieldname.lastIndexOf('.') + 1); - } - - // clear the collection - colParent[fieldname] = []; - - // go through all direct childs - each one is an element - $(this).children().each(function(){ - if(!ignoreInvalid && invalid) { - return; - } - - var ele = {}; - ele = that._createPojoFromInput($(this), fieldname, ele); - - // also collect sub-collections - that._getCollection($(this), fieldname, ele, ignoreInvalid); - - // check if the pojo is empty - if(!that._isEmpty(ele)) { - if($(".invalid", this).length > 0) { - invalid = true; - } - colParent[fieldname].push(ele); - } else { - $(".invalid", this).removeClass("invalid"); - } - }); - }); - - return invalid; - }; - - /** - * Get the data object used as a base for get(). - * Note that modifying this directly migh result into unwanted results - * when working with some functions that rely on this object. - * - * @returns the original data object - */ - JsForm.prototype.getData = function() { - // make srue we do have an object to work with - if(!this.options.data) { - this.options.data = {}; - } - return this.options.data; - }; - - /** - * uses form element and replaces them with "spans" that contain the actual content. - * the original "inputs" are hidden - * @param form the form - * @param enable true: switch inputs with spans, false: switch spans back, undefined: toggle - */ - JsForm.prototype.preventEditing = function(prevent) { - var $this = $(this.element); - - if(typeof prevent === "undefined") { - // get the disable from the form itself - prevent = $this.data("disabled")?false:true; - } else { - // already in that state - if(prevent === $this.data("disabled")) { - return; - } - } - - if (prevent) - { - $this.find("input, textarea").each(function() { - if ($(this).closest("span.form")[0]) - return; - if($(this).attr("type") == "hidden") - return; - var val = $(this).val(); - if (val === "null" || val === null || $(this).attr("type") === "submit") - val = ""; - if($(this).hasClass("trueFalse")) { - if($(this).is(':checked')) - val = 'X'; - else - val = ' '; - } - - // convert \n to brs - escape all other html - val = val.replace(//g, ">").replace(/\n/g, "
"); - var thespan = $(''+val+''); - if($(this).parent().hasClass("ui-wrapper")) - $(this).parent().hide().wrap(thespan); - else - $(this).hide().wrap(thespan); - }); - // selects are handled slightly different - $this.find("select").each(function() { - if ($(this).closest("span.form")[0]) - return; - - var val = $(this).children(":selected").html(); - if (val === "null" || val === null) - val = ""; - - var thespan = $(''+val+''); - - // toggle switches work a little different - if($(this).hasClass("ui-toggle-switch")) { - $(this).prev().hide().wrap(thespan); - } - else { - $(this).hide().wrap(thespan); - } - }); - } - else - { - $this.find("span.form").each(function() { - // remove text and then unwrap - var ele = $(this).children("input,select,textarea,.ui-wrapper,.ui-toggle-switch").show().detach(); - $(this).before(ele); - $(this).remove(); - }); - } - - $this.data("disabled", prevent); - }; - - /** - * validate a given form - * @return true if the form has no invalid fields, false otherwise - */ - JsForm.prototype.validate = function() { - // get the prefix from the form if not given - //var prefix = this.options.prefix; - - // validation - $(".required,.regexp,.date,.mandatory,.number,.validate,.integer", this.element).change(); - - // check for invalid fields - if($(".invalid", this.element).length > 0) { - return false; - } - - return true; - }; - - /** - * fill a form based on a pojo. - * @param form the form - * @param options the options used to fill - * @param prefix the optional prefix used to identify fields for this form - * @private - */ - JsForm.prototype._fill = function(form, options) { - - this._clear(form, options.prefix); - - $(form).addClass("POJO"); - $(form).data("pojo", options.data); - - // fill base - this._fillData(form, options.data, options.prefix); - this._fillCollection(form, options.data, options.prefix); - // (re-)evaluate all conditionals - this._evaluateConditionals(this.element, options.data); - }; - - /** - * @param container the container element - * @param data an array containing the the data - * @param prefix a prefix for each line of data - * @private - */ - JsForm.prototype._fillCollection = function(container, data, prefix) { - var that = this; - // fill collections - $(".collection", container).each(function() { - var container = $(this), - fieldname = $(this).attr("data-field"); - // only collections with the correct prefix - if(!data || !fieldname || fieldname.indexOf(prefix+".") !== 0) { - return; - } - - // data for the collection filling - var colData = null; - - var cname = fieldname; - // remove the prefix - if (prefix) { - cname = cname.substring(prefix.length + 1); - } - colData = that._get(data, cname); - - if(colData) { - // fill the collection - that._fillList(container, colData, cname); - } - }); - }; - - /** - * @param container the container element - * @param data an array containing the the data - * @param prefix a prefix for each line of data - * @param lineFunc function(line,cur) - can return false to skip the line - * @private - */ - JsForm.prototype._fillList = function(container, data, prefix, lineFunc) { - var tmpl = container.data("template"), - that = this; - if(!tmpl) { - return; - } - // clean out previous list - container.empty(); - - // not an array - if(!$.isArray(data)) { - return; - } - - // cut away any prefixes - only the fieldname is used - if(prefix.indexOf('.') !== -1) { - prefix = prefix.substring(prefix.lastIndexOf('.')+1); - } - - - // check if we need to sort the array - if($(container).hasClass("sort")) { - var sortField = $(container).attr("data-sort"); - if(sortField) { - switch($(container).attr("data-sorttype")) { - case 'alpha': - data.sort(); - break; - case 'alphainsensitiv': - data.sort(function(a,b){ - a = a[sortField]; - b = b[sortField]; - if(a) a = a.toLowerCase(); - if(b) b = b.toLowerCase(); - if(ab) - return 1; - return 0; - }); - break; - default: - data.sort(function(a,b){ - return a[sortField] - b[sortField]; - }); - } - // descending: reverse - if($(container).attr("data-sortdesc")) { - data.reverse(); - } - } - } - - if(!lineFunc) { - if($.isFunction(prefix)) { - lineFunc = prefix; - prefix = null; - } - } - - for(var i = 0; i < data.length; i++) { - var cur = data[i]; - var line = tmpl.clone(true); - // save current line - line.data().pojo = cur; - line.addClass("POJO"); - - if(lineFunc) { - if(lineFunc(line, cur) === false) { - continue; - } - } - - that._addCollectionControls(line); - - if(prefix) { - // fill data - including the index - that._fillData(line, cur, prefix, i+1); - // enable collection controls - that._initCollection(line, prefix); - // fill with data - that._fillCollection(line, cur, prefix); - } - container.append(line); - - } - }; - - /** - * add controls into a collection entry(i.e. delete) - * @param line the new collection - * @private - */ - JsForm.prototype._addCollectionControls = function(line) { - var that = this; - - // enable controls on the line - if($.jsFormControls) { - $(line).jsFormControls(); - } - - $(".delete", line).click(function(){ - var ele = $(this).closest(".POJO"); - // trigger a callback - $(this).closest(".collection").trigger("deleteCollection", [ele, $(ele).data().pojo]); - ele.remove(); - }); - $(".sortUp", line).click(function(){ - // check if there is an up - var ele = $(this).closest(".POJO"); - var prev = ele.prev(".POJO"); - if(prev.size() === 0) { - // no previous element - return - return; - } - ele.detach(); - prev.before(ele); - // reorder (if possible) - that._reorder(ele); - }); - $(".sortDown", line).click(function(){ - // check if there is a down - var ele = $(this).closest(".POJO"); - var next = ele.next(".POJO"); - if(next.size() === 0) { - // no next element - return - return; - } - ele.detach(); - next.after(ele); - // reorder (if possible) - that._reorder(ele); - }); - - // if collection is sortable: refresh it - var container = $(line).closest(".collection"); - if(container.hasClass("sortable")&& $(container).sortable) { - container.sortable("refresh"); - } - }; - - /** - * Reorder a collection (actually its fields) - * @param ele one element of the collection or the collection itself - * @private - */ - JsForm.prototype._reorder = function(ele) { - if(!ele.attr("data-sort")) { - ele = ele.closest(".collection"); - } - - // get the field to use for sorting - var sortField = $(ele).attr("data-sort"); - if(!sortField || ($(ele).attr("data-sorttype") && $(ele).attr("data-sorttype") !== "number") || - ($(ele).attr("data-sortdesc") && $(ele).attr("data-sortdesc") !== "false")) { - return; - } - - // go through each child and get the pojo - var prio = 0; - $.each($(ele).children(), function(){ - var data = $(this).data("pojo"); - // no data yet - add one - if(!data) { - data = {}; - $(this).data("pojo", data); - } - - data[sortField] = prio++; - }); - }; - - /** - * render an object based on a string. - * Note: comma is a special char and cannot be used! - * @param obj the object - * @param skin the string to render with (i.e. id, ":", test) - * @private - */ - JsForm.prototype._renderObject = function(obj, skin) { - if(!skin || !obj) - return ""; - var that = this; - var ret = ""; - $.each(skin.split(","), function(){ - var val = this.trim(); - if(val.indexOf("'") === 0 || val.indexOf('"') === 0) { - ret += val.substring(1, val.length - 1); - } else { - ret += that._get(obj, val); - } - }); - return ret; - }; - - /** - * Retrieve a value from a given object by using dot-notation - * @param obj the object to start with - * @param expr the child to get (dot notation) - * @param create set to true and non-existant levels will be created (always returns non-null) - * @param idx only filles when filling collection - can be access using $idx - * @private - */ - JsForm.prototype._get = function(obj, expr, create, idx) { - var ret, p, prm = "", i; - if(typeof expr === "function") { - return expr(obj); - } - if (!obj) { - return ""; - } - // reference the object itself - if(expr === "") - return obj; - - // reference to the index - if(expr === "$idx") - return idx; - - ret = obj[expr]; - if(!ret) { - try { - if(typeof expr === "string") { - prm = expr.split('.'); - } - - i = prm.length; - if(i) { - ret = obj; - while(ret && i--) { - p = prm.shift(); - // create the levels - if(create && !ret[p]) { - ret[p] = {}; - } - ret = ret[p]; - } - } - } catch(e) { /* ignore */ } - } - if(ret === null || ret === undefined) { - ret = ""; - } - // trim the return - if(ret.trim) { - return ret.trim(); - } - return ret; - }; - - /** - * Parse a dot notation that includes arrays - * http://stackoverflow.com/questions/13355278/javascript-how-to-convert-json-dot-string-into-object-reference - * @param obj - * @param path a dot notation path to search for. Use format parent[1].child - */ - JsForm.prototype._getValueWithArrays = function(obj, path) { - path = path.split('.'); - var arrayPattern = /(.*)\[(\d+)\]/; - for (var i = 1; i < path.length; i++) { - var match = arrayPattern.exec(path[i]); - try { - if (match) { - obj = obj[match[1]][parseInt(match[2], 10)]; - } else { - obj = obj[path[i]]; - } - } catch(e) { - console.log(path + " " + e); - } - } - - return obj; - }; - - /** - * get the "parent" object of a given dot-notation. this will not return the actual - * element given in the dot notation but itws parent (i.e.: when using a.b.c -> it will return b) - * @param obj the object to start with - * @param the child to get (dot notation) - * @param create set to true and non-existant levels will be created (always returns non-null) - * @private - */ - JsForm.prototype._getParent = function(obj, expr, create) { - if(expr.indexOf('.') === -1) - return obj; - - expr = expr.substring(0, expr.lastIndexOf('.')); - return this._get(obj, expr, create); - }; - - /** - * helper function to get the number of a value - * @param num the string - * @returns a number or null - * @private - */ - JsForm.prototype._getNumber = function(num) { - if (!num) { - return null; - } - - if($.format) - return $.format.number(num); - - // either we have , (for komma) or a . and at least 3 following numbers (not a round komma) - if(num.indexOf(",") != -1 || (num.length - num.indexOf('.') > 3)) - { - num = num.replace(/\./g, "").replace(",", "."); - } - return Number(num); - }; - - /** - * checks if a variable is empty. This will check array, and whole objects. If a json object - * only contains empty "elements" then it is considered as empty. - * Empty for a number is 0/-1 - * Empty for a boolena is false - * - * @param pojo the pojo to check - * @returns {Boolean} true if it is empty - * @private - */ - JsForm.prototype._isEmpty = function(pojo) { - // boolean false, null, undefined - if(!pojo) { - return true; - } - - // array - if($.isArray(pojo)) { - // zero length - if(pojo.length === 0) { - return true; - } - - // check each element - for(var i = 0; i < pojo.length; i++) { - if(!this._isEmpty()) { - return false; - } - } - return true; - } - // an object - if($.isPlainObject(pojo)) { - if($.isEmptyObject(pojo)) { - return true; - } - - for(var f in pojo){ - if(!this._isEmpty(pojo[f])) { - return false; - } - } - return true; - } - - // a number - if(!isNaN(pojo)) { - if (Number(pojo) === 0 || Number(pojo) === -1) { - return true; - } - return false; - } - - // a string - return (pojo === "" || pojo === " "); - }; - - /** - * compare a pojo with a form. Takes special data definition classes into account: - * - * @param start the element to start from (ie. the form or tr) - * @param pojo the pojo to write everything to - * @param prefix a prefix: only fields with the given prefix will be included in the pojo - * @private - */ - JsForm.prototype._pojoDifferFromInput = function (start, prefix, pojo) { - var differs = false; - $("input,select,textarea", start).each(function(){ - // skip if we found a dif - if(differs) { - return; - } - - var name = $(this).attr("name"); - // empty name - ignore - if (!name) { - return; - } - - // skip grayed (=calculated) or transient fields - if($(this).hasClass("transient")) { - return; - } - - // must start with prefix - if(name.indexOf(prefix + ".") !== 0) { - return; - } - - // cut away the prefix - name = name.substring((prefix+".").length); - - // skip empty - if(name.length < 1) { - return; - } - - var val = $(this).val(); - // set empty numbers to null - if(val === "" && ($(this).hasClass("number") || $(this).hasClass("dateFilter")|| $(this).hasClass("dateTimeFilter"))) { - val = null; - } - if ($(this).hasClass("number") || $(this).hasClass("currency")) { - val = that._getNumber(val); - if(isNaN(val)) { - val = 0; - } - } - if($(this).attr("type") === "checkbox" || $(this).attr("type") === "CHECKBOX") { - val = $(this).is(':checked'); - } - - // check if we have a . - if so split - if (name.indexOf(".") === -1) - { - // the vals differ - if(pojo[name] !== val) { - differs = true; - } - } - else - { - var parts = name.split("."); - - var d0 = pojo[parts[0]]; - var d1, d2; - - if (!d0) { - differs = true; - return; - } - - if (parts.length === 2) { - // the vals differ - if(d0[parts[1]] !== val) { - differs = true; - } - } else if (parts.length === 3) { - d1 = d0[parts[1]]; - // the vals differ - if(d1[parts[2]] !== val) { - differs = true; - } - } else if (parts.length === 4) - { - d1 = d0[parts[1]]; - d2 = d1[parts[2]]; - // the vals differ - if(d2[parts[3]] !== val) { - differs = true; - } - } - // more should not be necessary - } - }); - return differs; - }; - - /** - * Compares a pojo with form fields - * @param pojo the pojo to compare with - * @return true if any change between formfields and the pojo is found - */ - JsForm.prototype.equals = function(pojo) { - var that = this; - var form = this.element; - var prefix = this.options.prefix; - - // check the base - if(this._pojoDifferFromInput(form, prefix, pojo)) { - return false; - } - - var differs = false; - - // check for invalid fields - if($(".invalid", form).length > 0) { - return false; - } - - $(".collection", form).each(function() { - if(differs) { - return; - } - - var fieldname = $(this).attr("data-field"); - // only collections with the correct prefix - if(!fieldname || fieldname.indexOf(prefix+".") !== 0) { - return; - } - - fieldname = fieldname.substring((prefix+".").length); - if(fieldname.length < 1) { - return; - } - - var childCounter = 0; - // go through all direct childs - each one is an element - $(this).children().each(function(){ - if(differs) { - return; - } - - // check if we have more elements - if(childCounter >= pojo[fieldname].length) { - differs = true; - return; - } - - var ele = pojo[fieldname][childCounter++]; - if(that._pojoDifferFromInput($(this), fieldname, ele)) { - differs = true; - } - }); - - if(childCounter < pojo[fieldname].length) { - differs = true; - } - }); - - // we want to know if its equals -> return not - return !differs; - }; - - /** - * fill the form with data. - * - * @param data {object} the data - */ - JsForm.prototype.fill = function(pojo) { - // set the new data - this.options.data = pojo; - // fill everything - this._fill(this.element, this.options); - }; - - /** - * re-evaluate the conditionals in the form based on the given data. - * if no data is given, the form is serialized - * @param data {object} the data - */ - JsForm.prototype.applyConditions = function(pojo) { - // set the new data - if(!pojo) - pojo = this.get(true); - - // evaluate everything - this._evaluateConditionals(this.element, pojo); - }; - - /** - * reset a form with the last data, overwriting any changes. - */ - JsForm.prototype.reset = function() { - // clear first - this.clear(); - // fill everything - this._fill(this.element, this.options); - }; - - /** - * Clear all fields in a form - */ - JsForm.prototype.clear = function() { - // clear first - this._clear(this.element, this.options.prefix); - }; - - /** - * destroy the jsform and its resources. - * @private - */ - JsForm.prototype.destroy = function( ) { - return $(this.element).each(function(){ - $(window).unbind('.jsForm'); - $(this).removeData('jsForm'); - }); - }; - - // init and call methods - $.fn.jsForm = function ( method ) { - // Method calling logic - if ( typeof method === 'object' || ! method ) { - return this.each(function () { - if (!$(this).data('jsForm')) { - $(this).data('jsForm', new JsForm( this, method )); - } - }); - } else { - var args = Array.prototype.slice.call( arguments, 1 ), - jsForm; - // none found - if(this.length === 0) { - return null; - } - // only one - return directly - if(this.length === 1) { - jsForm = $(this).data('jsForm'); - if (jsForm) { - if(method.indexOf("_") !== 0 && jsForm[method]) { - var ret = jsForm[method].apply(jsForm, args); - return ret; - } - - $.error( 'Method ' + method + ' does not exist on jQuery.jsForm' ); - return false; - } - } - - return this.each(function () { - jsForm = $.data(this, 'jsForm'); - if (jsForm) { - if(method.indexOf("_") !== 0 && jsForm[method]) { - return jsForm[method].apply(jsForm, args); - } else { - $.error( 'Method ' + method + ' does not exist on jQuery.jsForm' ); - return false; - } - } - }); - } - }; - - /** - * global jsForm function for intialisation - */ - $.jsForm = function ( name, initFunc ) { - var jsForms = JSFORM_MAP[name]; - // initFunc is a function -> initialize - if($.isFunction(initFunc)) { - // call init if already initialized - if(jsForms) { - $.each(jsForms, function(){ - initFunc(this, $(this.element)); - }); - } - - // remember for future initializations - JSFORM_INIT_FUNCTIONS[name] = initFunc; - } else { - // call init if already initialized - if(jsForms) { - var method = initFunc; - var args = Array.prototype.slice.call( arguments, 2 ); - $.each(portlets, function(){ - this[method].apply(this, args); - }); - } - } - }; - -})( jQuery, window ); - -/** - * jquery.jsForm.controls - * ---------------------- - * UI Controls and Field validation - * @version 1.0 - * @class - * @author Niko Berger - * @license MIT License GPL - */ -;(function( $, window, undefined ){ - "use strict"; - - var JSFORM_INIT_FUNCTIONS = {}, // remember initialization functions - JSFORM_MAP = {}; // remember all forms - - /** - * handlebars extension (+simple date format) - */ - if(typeof Handlebars !== "undefined") { - Handlebars.registerHelper("currency", function(data){ - if(!data) - return "0"; - return $.jsFormControls.Format.currency(data); - }); - Handlebars.registerHelper("dec", function(data){ - if(!data) - return ""; - return $.jsFormControls.Format.decimal(data); - }); - Handlebars.registerHelper("percent", function(data){ - if(!data) - return "0"; - return $.jsFormControls.Format.decimal(data*100); - }); - Handlebars.registerHelper("date", function(data){ - if(!data) - return ""; - return $.jsFormControls.Format.date(data); - }); - Handlebars.registerHelper("time", function(data){ - if(!data) - return ""; - return $.jsFormControls.Format.time(data); - }); - Handlebars.registerHelper("datetime", function(data){ - if(!data) - return ""; - return $.jsFormControls.Format.dateTime(data); - }); - Handlebars.registerHelper("dateTime", function(data){ - if(!data) - return ""; - return $.jsFormControls.Format.dateTime(data); - }); - Handlebars.registerHelper("timespan", function(data){ - if(!data) - return ""; - return $.jsFormControls.Format.humanTime(data); - }); - Handlebars.registerHelper("byte", function(data){ - if(!data) - return ""; - return $.jsFormControls.Format.byte(data); - }); - } - - function JsFormControls(element) { - this.element = element; - - // init the dom functionality - this._domInit(); - } - - /** - * init the dom. This can be called multiple times. - * this will also enable "add", "insert" and "delete" for collections - * @private - */ - JsFormControls.prototype._domInit = function() { - var location = $(this.element); - - // validation - // check required (this is the first check) - location.find("input.mandatory,textarea.mandatory").on("keyup", function(){ - // check for "null" as value as well - if($(this).val().length > 0 && $(this).val() !== "null") { - $(this).addClass("valid").removeClass("invalid"); - } else { - $(this).removeClass("valid").addClass("invalid"); - } - }); - - location.find("input.mandatory,textarea.mandatory").on("change", function(){ - if($(this).hasClass("object")) { - if($(this).data().pojo) { - $(this).addClass("valid").removeClass("invalid"); - } else { - $(this).removeClass("valid").addClass("invalid"); - } - return; - } - // check for "null" as value as well - if($(this).val().length > 0 && $(this).val() !== "null") { - $(this).addClass("valid").removeClass("invalid"); - } else { - $(this).removeClass("valid").addClass("invalid"); - } - }).change(); - - location.find("select.mandatory").change(function(){ - // check for "null" as value as well - if($(this).val() !== null && $(this).val() !== "null" && $(this).val().length > 0) { - $(this).addClass("valid").removeClass("invalid"); - } else { - $(this).removeClass("valid").addClass("invalid"); - } - }).change(); - - // show datepicker for all inputs - location.find("input.date").each(function(){ - var format = $(this).attr("data-format"); - // only if jquery ui is available - if($(this).datepicker) { - if(format) - $(this).datepicker({dateFormat: format}); - else - $(this).datepicker(); - } - }); - - - // input validation (number) - var numberRegexp = new RegExp("^[0-9.,-]+$"); - location.find("input.number").keyup(function(){ - var val = $(this).val(); - if(val.length > 0) { - if($(this).hasClass("autoclean")) { - $(this).val(val.replace(/[^0-9.,-]/g, "")); - } - else { - if(numberRegexp.test($(this).val())) { - $(this).addClass("valid").removeClass("invalid"); - } else { - $(this).removeClass("valid").addClass("invalid"); - } - } - } - }).keyup(); - - var integerRegexp = new RegExp("^[0-9]+$"); - location.find("input.integer").keyup(function(){ - var val = $(this).val(); - if(val.length > 0) { - if($(this).hasClass("autoclean")) { - $(this).val(val.replace(/[^0-9]/g, "")); - } - else { - if(integerRegexp.test($(this).val())) { - $(this).addClass("valid").removeClass("invalid"); - } else { - $(this).removeClass("valid").addClass("invalid"); - } - } - } - }).keyup(); - - // regular expression - location.find("input.regexp").each(function(){ - if($(this).hasClass("autoclean")) { - $(this).data("regexp", new RegExp($(this).attr("data-regexp"), "g")); - } - else { - $(this).data("regexp", new RegExp($(this).attr("data-regexp"))); - } - - $(this).keyup(function(){ - var val = $(this).val(); - if(val.length > 0) { - var regexp = $(this).data("regexp"); - if($(this).hasClass("autoclean")) { - $(this).val(val.replace(regexp, "")); - } - else { - if(regexp.test($(this).val())) { - $(this).addClass("valid").removeClass("invalid"); - } else { - $(this).removeClass("valid").addClass("invalid"); - } - } - } else { - // if not mandatory: nothing is valid - if(!$(this).hasClass("mandatory")) { - $(this).removeClass("invalid").addClass("valid"); - } - } - }).keyup(); - $(this).change(function(){ - $(this).keyup(); - }); - }); - - /* rotatestate stontrol */ - location.find("input.rotatestate").each(function(){ - var states = $(this).attr("data-state-values"); - var defaultClass = $(this).attr("data-state-class"); - // no need to continue if there are no states - if(!states) { - return; - } - - try { - states = JSON.parse(states); - } catch (ex) { - // do not need to continue if we cannot parse the states - return; - } - - var stateControl = $(""); - if($(this).attr("title")) { - stateControl.attr("title", $(this).attr("title")); - } - if($(this).attr("data-state-style")) { - stateControl.attr("style", $(this).attr("data-state-style")); - } - stateControl.data("states", states); - stateControl.data("control", this); - stateControl.data("activeState", null); - $(this).data("control", stateControl); - if(defaultClass) { - stateControl.addClass(defaultClass); - } - - // click on the control starts rotating - stateControl.click(function(){ - var cState = $(this).data().activeState; - var cStates = $(this).data().states; - var control = $(this).data().control; - var newState = null; - - if(cState !== null) { - // go to the 'next' state - for(var i = 0; i < cStates.length; i++) { - if(cStates[i].value === cState.value) { - // last element - if(i === cStates.length - 1) { - newState = cStates[0]; - } else { - newState = cStates[i+1]; - } - break; - } - } - } else { - // no state yet - set the first entry as state - newState = cStates[0]; - } - - $(control).attr("value", newState.value); - // trigger change - $(control).change(); - }); - - // make sure to update state if the value is changed - $(this).change(function(){ - var control = $($(this).data().control); - var cState = control.data().activeState; - var cStates = control.data().states; - - if(cState !== null) { - // remove "old state" - control.removeClass(cState['class']); - } - - // add new State - var val = $(this).val(); - $.each(cStates, function(){ - if(this.value === val) { - control.data().activeState = this; - if(this.title) { - control.attr("title", this.title); - } - control.addClass(this['class']); - return false; - } - }); - }); - - // trigger initial state - $(this).change(); - $(this).after(stateControl); - $(this).hide(); - }); - }; - - - /** - * validate a given form - * @return true if the form has no invalid fields, false otherwise - */ - JsFormControls.prototype.validate = function() { - // validation - $(".required,.regexp,.date,.mandatory,.number,.validate", this.element).change(); - - // check for invalid fields - if($(".invalid", this.element).length > 0) { - return false; - } - - return true; - }; - - // init and call methods - $.fn.jsFormControls = function ( method ) { - // Method calling logic - if ( typeof method === 'object' || ! method ) { - return this.each(function () { - if (!$(this).data('jsFormControls')) { - $(this).data('jsFormControls', new JsFormControls( this, method )); - } - }); - } else { - var args = Array.prototype.slice.call( arguments, 1 ); - - // only one - return directly - if(this.length == 1) { - var jsFormControls = $(this).data('jsFormControls'); - if (jsFormControls) { - if(method.indexOf("_") !== 0 && jsFormControls[method]) { - var ret = jsFormControls[method].apply(jsFormControls, args); - return ret; - } - - $.error( 'Method ' + method + ' does not exist on jQuery.jsFormControls' ); - return false; - } - } - - return this.each(function () { - var jsFormControls = $.data(this, 'jsFormControls'); - if (jsFormControls) { - if(method.indexOf("_") !== 0 && jsFormControls[method]) { - return jsFormControls[method].apply(jsFormControls, args); - } else { - $.error( 'Method ' + method + ' does not exist on jQuery.jsFormControls' ); - return false; - } - } - }); - } - }; - - /** - * global jsForm function for intialisation - */ - $.jsFormControls = function ( name, initFunc ) { - var jsForms; - // initFunc is a function -> initialize - if($.isFunction(initFunc)) { - // call init if already initialized - jsForms = JSFORM_MAP[name]; - if(jsForms) { - $.each(jsForms, function(){ - initFunc(this, $(this.element)); - }); - } - - // remember for future initializations - JSFORM_INIT_FUNCTIONS[name] = initFunc; - } else { - // call init if already initialized - jsForms = JSFORM_MAP[name]; - if(jsForms) { - var method = initFunc; - var args = Array.prototype.slice.call( arguments, 2 ); - $.each(portlets, function(){ - this[method].apply(this, args); - }); - } - } - }; - - $.jsFormControls.Format = { - /** - * format a string based on teh classes in a dom element - */ - format: function(ele, cdata) { - if($(ele).hasClass("dateTime")) { - if(isNaN(cdata)) - return cdata; - return $.jsFormControls.Format.dateTime(cdata); - } if($(ele).hasClass("datetime")) { - if(isNaN(cdata)) - return cdata; - return $.jsFormControls.Format.dateTime(cdata); - } else if($(ele).hasClass("date")) { - if(isNaN(cdata)) - return cdata; - return $.jsFormControls.Format.date(cdata); - } else if($(ele).hasClass("currency")) { - return $.jsFormControls.Format.currency(cdata); - } else if($(ele).hasClass("byte")) { - if(isNaN(cdata)) - return cdata; - return $.jsFormControls.Format.byte(cdata); - } else if($(ele).hasClass("number")) { - return $.jsFormControls.Format.decimal(cdata); - } - - return cdata; - }, - - /** - * format boolean into an ui-icon - * @param value true or false - * @returns the ui-icon span - */ - checkBox: function(row, cell, value, columnDef, dataContext) { - // cleanup parameters (direct call vs. slickgrid) - if(typeof value === "undefined") { - value = row; - row = null; - } - - if(value) { - return ' '; - } else { - return ' '; - } - - return value; - }, - - - /** - * @private - */ - _getNumber: function(num) { - if (!num) { - return null; - } - - if($.format) - return $.format.number(num); - - // either we have , (for komma) or a . and at least 3 following numbers (not a rounden komma) - if(num.indexOf(",") !== -1 || (num.length - num.indexOf('.') > 3)) - { - num = num.replace(/\./g, "").replace(",", "."); - } - return Number(num); - }, - - - /** - * @private - */ - _pad: function(val) { - var o = (val < 10) ? "0" : ""; - o += val; - return o; - }, - - - byte: function(bytes) { - if (bytes === "" || !bytes || isNaN(bytes)) { - return bytes; - } - - var unit = 1024; - if (bytes < unit) return bytes + " B"; - var exp = Math.floor(Math.log(bytes) / Math.log(unit)); - var pre = "KMGTPE".charAt(exp-1) + "B"; - return Math.round(bytes*10 / Math.pow(unit, exp))/10 + pre; - }, - - /** - * @private - */ - decimal: function(num) { - if (num === "" || !num || isNaN(num)) { - return num; - } - - // default number format - var numberformat = { - format: "#,##0.###", - groupingSeparator: ",", - decimalSeparator: "." - }; - - if(typeof i18n !== "undefined") - numberformat = i18n.number; - if(typeof $(document).data().i18n !== "undefined") - numberformat = $(document).data().i18n.number; - - if($.format && numberformat) { - return $.format.number(num, numberformat); - } - - var comma = 0; - if (Math.abs(num - Math.floor(num)) > 0.001) { - comma = 2; - } - // convert to a nice number for display - var n = num, - c = isNaN(c = Math.abs(comma)) ? 2 : comma, - d = numberformat.decimalSeparator, // decimal d == undefined ? "," : d, - t = numberformat.groupingSeparator, // thousand: t == undefined ? "." : t, - i = parseInt(n = Math.abs( +n || 0).toFixed(c), 10) + "", - j = (j = i.length) > 3 ? j % 3 : 0; - return (num<0 ? "-" : "") + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : ""); - }, - - - /** - * @private - */ - currency: function(row, cell, cellvalue, columnDef, dataContext) { - // cleanup parameters (direct call vs. slickgrid) - if(!cellvalue || isNaN(cellvalue)) { - cellvalue = row; - row = null; - } - - if(!cellvalue) { - if(cell) { - return " "; - } - return ""; - } - - return $.jsFormControls.Format.decimal(cellvalue); - }, - - /** - * @private - */ - dateTime: function(row, cell, cellvalue, columnDef, dataContext) { - // cleanup parameters (direct call vs. slickgrid) - if(!cellvalue || isNaN(cellvalue)) { - cellvalue = row; - row = null; - } - - if(!cellvalue) { - if(cell) { - return " "; - } - return ""; - } - - return (this.date(cellvalue) + " " + this.time(cellvalue)); - }, - - /** - * @private - */ - date: function(row, cell, cellvalue, columnDef, dataContext) { - - // cleanup parameters (direct call vs. slickgrid) - if(!cellvalue || isNaN(cellvalue)) { - cellvalue = row; - row = null; - } - - if(!cellvalue) { - if(cell) { - return " "; - } - return ""; - } - - var d = new Date(); - d.setTime(cellvalue); - var year = d.getYear(); - if(year < 1900) { - year += 1900; - } - - // default number format - var dateformat = null; - - if(typeof i18n !== "undefined") - dateformat = i18n.date; - if(typeof $(document).data().i18n !== "undefined") - dateformat = $(document).data().i18n.date; - - if($.format) - return $.format.date(d, dateformat.shortDateFormat); - else - return this._pad(d.getDate()) + "." + this._pad((d.getMonth()+1)) + "." + this._pad(year); - }, - - /** - * @private - */ - time: function(row, cell, value, columnDef, dataContext) { - // cleanup parameters (direct call vs. slickgrid) - if(!value) { - value = row; - row = null; - } - - if(!value) { - if(cell) { - return " "; - } - return ""; - } - - var d = new Date(); - d.setTime(value); - if($.format) - return $.format.date(d, $(document).data().i18n.date.timeFormat); - else - return this._pad(d.getHours()) + ":" + this._pad(d.getMinutes()); // + ":" + pad(d.getSeconds()); don't need seconds - }, - - /** - * - * @param value a string value to format - * @param allowms true to allow komma (i.e. 00.00) - * @return something in the form of 00:00.00 - * @private - */ - timespan: function(row, cell, value, columnDef, dataContext, allowcomma) { - // cleanup parameters (direct call vs. slickgrid) - if(!value) { - value = row; - allowcomma = cell; - row = null; - cell = null; - } - - var tokens = value.split(":"); - // check each token - for(var i=0; i 0) { - out += h + "h "; - // ignore seconds and milliseconds if we have hours - s = 0; - value = 0; - } - if (m > 0) { - out += m + "m "; - // ignore milliseconds - value = 0; - } - if (s > 0) { - out += s + "s "; - value = 0; - } - - if (value > 0) { - out += value + "ms"; - } - // trim output - return out.trim(); - } - }; - -})( jQuery, window ); - - -/** - * @returns the trimmed string - */ -String.prototype.trim = function() { - return this.replace(/^\s+|\s+$/g, ""); -}; - -/* check start of a string */ -String.prototype.startsWith = function(str) { - if((this === null) || (this.length <= 0)) - return false; - if((str === null) || (str == "null") || (str.length <= 0)) - return false; - if(this.substr(0, str.length) == str) - return true; - return false; -}; - -/* check start of a string */ -String.prototype.startsWithIgnoreCase = function(str) { - if((this === null) || (this.length <= 0)) - return false; - if((str === null) || (str == "null") || (str.length <= 0)) - return false; - if(this.substr(0, str.length).toLowerCase() == str.toLowerCase()) - return true; - return false; -}; - -/* check end of a string */ -String.prototype.endsWith = function(str) { - if((this === null) || (this.length <= 0)) - return false; - if((str === null) || (str == "null") || (str.length <= 0) || (str.length > this.length)) - return false; - if(this.substr(this.length - str.length) == str) - return true; - return false; -}; \ No newline at end of file diff --git a/dist/jquery.jsForm.1.1.0.min.js b/dist/jquery.jsForm.1.1.0.min.js deleted file mode 100644 index 330d591..0000000 --- a/dist/jquery.jsForm.1.1.0.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * jQuery.jsForm v1.1.0 | (c) 2013 Niko Berger http://www.gargan.org/ - * Usage: https://github.com/corinis/jsForm - */ -(function(t,e,a){"use strict";function i(e,a){var i=t(e);this.options=t.extend({},{controls:!0,data:null,prefix:"data",validateHidden:!0,skipEmpty:!1},a),!i.attr("data-prefix")||"data"!==this.options.prefix&&""!==this.options.prefix||""!==i.attr("data-prefix")&&(this.options.prefix=i.attr("data-prefix")),this.element=e,this._init()}var s={},n={};i.prototype._init=function(){if(this._domInit(),this.options.controls)if(t.jsFormControls)t(this.element).jsFormControls();else try{"undefined"!=typeof console&&console.log("jquery.JsForm.controls not available!")}catch(e){}this._fill(this.element,this.options)},i.prototype._domInit=function(){var e=t(this.element),a=this,i=this.options.prefix;a._initCollection(e,i),a._initConditional(e,i,this.options)},i.prototype._debug=function(t){"undefined"!=typeof console&&console.log("JsForm: "+t)},i.prototype._initConditional=function(e,a,i){var s=this,n=function(e,a,i){var n=!1;t.each(i,function(){var t=s._getValueWithArrays(a,this);if(t&&""!==t&&0!==t&&-1!==t)return n=!0,!1}),n?e.show():e.hide()},r=function(e,a,i){var n=!1;t.each(i,function(){var t=s._getValueWithArrays(a,this);if(t&&""!==t&&0!==t&&-1!==t)return n=!0,!1}),n?e.hide():e.show()};this.conditionals=t(e).find(".conditional"),this.conditionals.each(function(){t(this).data().conditionalEval=[];var e=t(this).attr("data-show");e&&e.length>0&&t(this).data().conditionalEval.push({func:n,field:e.split(" ")}),e=t(this).attr("data-hide"),e&&e.length>0&&t(this).data().conditionalEval.push({func:r,field:e.split(" ")}),e=t(this).attr("data-eval"),e&&e.length>0&&i.conditionals[e]&&t(this).data().conditionalEval.push({func:i.conditionals[e]})})},i.prototype._evaluateConditionals=function(e,a){this.conditionals.each(function(){var e=t(this);t.each(e.data().conditionalEval,function(){this.func(e,a,this.field)})})},i.prototype._initCollection=function(e,a){var i={},s=this;t(e).data().collections=i,t(".collection",e).each(function(){var e=t(this).attr("data-field");if(e&&0===e.indexOf(a+".")){var n=t(this),r=i[e];if(r?r.push(n):i[e]=[n],s._initList(n),!n.hasClass("ui-sortable")&&n.hasClass("sortable")&&n.sortable){var o=n.attr("data-sortable");o=o?JSON.parse(o):{},n.sortable(o),n.on("sortstop",function(){s._reorder(n)})}}}),t(".add",e).each(function(){var e=t(this).attr("data-field");e&&(t(this).data("collections")||(t(this).data().collections=i[e],t(this).click(function(a){a.preventDefault(),t.each(t(this).data("collections"),function(){var a=t(this).data("template");if(a){var i=a.clone(!0);t(this).append(i),t(i).addClass("POJO"),t(i).data("pojo",{}),s._addCollectionControls(i),t(this).trigger("addCollection",[i,t(i).data().pojo]);var n=t(this).children(".POJO").length;s._fillData(i,t(i).data().pojo,e.substring(e.indexOf(".")+1),n),s._initCollection(i,e.substring(e.indexOf(".")+1)),t(this).trigger("postAddCollection",[i,t(i).data().pojo])}})})))}),t(".insert",e).each(function(){var e=t(this).attr("data-field");e&&(t(this).data("collections")||(t(this).data("collections",i[t(this).attr("data-field")]),t(this).on("insert",function(a,i){if(i||(i=t(this).data().pojo),i){var n=t(this).data("beforeInsert");n&&t.isFunction(n)&&!(i=n(i))||(t.each(t(this).data("collections"),function(){var a=t(this).data("template");if(a){var n=a.clone(!0);n.addClass("POJO"),n.data().pojo=i,s._addCollectionControls(n),s._initCollection(n),t(this).trigger("addCollection",[n,t(n).data().pojo]);var r=t(this).children(".POJO").length;s._fillData(n,i,e.substring(e.indexOf(".")+1),r),t(this).append(n)}}),t(this).val(""),t(this).data().pojo=null,t(this).focus())}})))}),t(".insertAction",e).each(function(){var e=t(this).attr("data-field");if(e&&!t(this).data("inserter")){var a=t(this).parent().find(".insert");a&&(t(this).data("inserter",a),t(this).click(function(e){return e.preventDefault(),t(this).data("inserter").trigger("insert"),!1}))}}),t("input.object",e).each(function(){t(this).on("update",function(){var e=t(this).data().pojo;e&&t(this).attr("data-display")&&t(this).val(s._renderObject(e,t(this).attr("data-display")))})}),t("input.blob",e).each(function(){if("file"===t(this).attr("type")){var e=t(this);t(this).on("change",function(a){var i=t(this).val().split(/\\/).pop();e.data("name",i);var s=a.target.files;s&&s.length&&t.each(s,function(){var a=new FileReader;a.onload=function(t){e.data("blob",t.target.result)},a.readAsDataURL(this),t(this).trigger("fileChange")})})}}),t(".manage",e).each(function(){var e=t(this).attr("data-field");e&&(t(this).data("collections",i[e]),t(this).click(function(){var a=t(this).attr("data-service"),i=t(this).data("collections"),n=t(this),r=t(this).attr("data-display");r&&(r=r.split(",")),DataUtils.run(a,function(a){var o=t('');o.data("collections",i),n.data("select",o),t.each(a,function(){var e=this,a="";if(r)for(var s=0;r.length>s;s++)a+=e[r[s]]+" ";else a=e;var n=t('");t(i).each(function(){t(this).children().each(function(a,i){e.id===t(i).data("pojo").id&&n.prop("selected","selected")})}),o.append(n),n.data("pojo",e)}),n.after(o),n.hide(),o.multiselect({autoOpen:!0,open:function(){t(this).multiselect("widget").css("top",t(o).next().offset().top),t(this).multiselect("widget").css("left",t(o).next().offset().left),t(o).next().hide()},close:function(){n.show(),o.remove(),t(this).multiselect("destroy")}}).multiselectfilter().bind("multiselectclick multiselectcheckall multiselectuncheckall",function(){var a=t.map(t(this).multiselect("getChecked"),function(e){return t("option[value='"+e.value+"']",o).data("pojo")});t.each(t(o).data("collections"),function(){s._fillList(t(this),a,e)}),n.hide(),t(o).next().show(),t(this).multiselect("widget").css("top",t(o).next().offset().top),t(this).multiselect("widget").css("left",t(o).next().offset().left),t(o).next().hide()})})}))})},i.prototype._initList=function(t){if(!t.data("template")){var e=t.children().detach();e.removeAttr("id"),t.data("template",e)}},i.prototype._clear=function(e,a){a||(a=this.options.prefix),t(e).removeData("pojo"),t("input,select,textarea",e).each(function(){var e=t(this).attr("name");e&&0===e.indexOf(a+".")&&(e=e.substring((a+".").length),1>e.length||(t(this).removeData("pojo"),"checkbox"===t(this).attr("type")?t(this).prop("checked",!1):t(this).val(""),t(this).hasClass("blob")&&t(this).removeData("blob"),t(this).is("select")&&(t('option[selected="selected"]',this).removeAttr("selected"),t("option:first",this).attr("selected",!0),t(this).val(t("option:first",this).val()).change()),t(this).change()))}),t(".collection",e).each(function(){var e=t(this).attr("data-field");e&&0===e.indexOf(a+".")&&t(this).empty()})},i.prototype._createPojoFromInput=function(e,i,s){var n=null,r=this;return t(e).data("pojo")&&(n=t(e).data("pojo")),n&&t.extend(!0,s,n),t(e).find("input,select,textarea,.jsobject").each(function(){var e=t(this).attr("data-name");if(e||(e=t(this).attr("name")),e&&!t(this).hasClass("transient")&&0===e.indexOf(i+".")){t(this).trigger("validate",!0),e=e.substring((i+".").length);var n=t(this).val();if(t(this).hasClass("jsobject")&&(n=t(this).data("pojo")),!r.options.skipEmpty||n&&""!==n&&""!==n.trim()){if(!t(this).hasClass("emptynull")||n&&""!==n&&"null"!==n&&""!==n.trim()?t(this).hasClass("object")||t(this).hasClass("POJO")?n=t("option:selected",this).data()&&t("option:selected",this).data().pojo?t("option:selected",this).data().pojo:t(this).data("pojo"):t(this).hasClass("blob")?n=t(this).data("blob"):""===n&&(t(this).hasClass("number")||t(this).hasClass("integer")||t(this).hasClass("dateFilter")||t(this).hasClass("dateTimeFilter"))&&(n=null):n=null,t(this).hasClass("percent")&&(n=r._getNumber(n),isNaN(n)?n=0:n/=100),t(this).hasClass("number")||t(this).hasClass("integer")||t(this).hasClass("currency")?(n=r._getNumber(n),isNaN(n)&&(n=0)):"checkbox"===t(this).attr("type")||"CHECKBOX"===t(this).attr("type")?n=t(this).is(":checked"):t(this).hasClass("bool")&&(n="true"===t(this).val()),1>e.length)return s=n,!1;if(-1===e.indexOf("."))s[e]=n;else{var o,l,h=e.split("."),d=s[h[0]];d&&t.isPlainObject(d)||(s[h[0]]={},d=s[h[0]]),2===h.length?d[h[1]]=n:3===h.length?(o=d[h[1]],o===a&&(o={},d[h[1]]=o),o[h[2]]=n):4===h.length&&(o=d[h[1]],l=o[h[2]],l===a&&(l={},o[h[2]]=l),o[h[2]]=n,l[h[3]]=n)}}}}),s},i.prototype._fillData=function(e,i,s,n){var r=this,o=t(e);o.find(".field").each(function(){var e=t(this).data("name");if(e||("A"===this.nodeName.toUpperCase()?(e=t(this).attr("href"),t(this).attr("href","#")):"IMG"===this.nodeName.toUpperCase()?(e=t(this).attr("src"),0===e.indexOf("#")&&(e=e.substring(1)),t(this).attr("src","#")):e=t(this).text(),t(this).data("name",e),t(this).show()),!s||e.indexOf(s+".")>=0){var a=e;s&&(a=a.substring(s.length+1));var o=r._get(i,a,!1,n);o||(o=""),t(this).hasClass("percent")&&!isNaN(o)&&(o=100*Number(o)),t.jsFormControls&&(o=t.jsFormControls.Format.format(this,o)),"A"===this.nodeName.toUpperCase()?t(this).attr("href",o):"IMG"===this.nodeName.toUpperCase()?t(this).attr("src",o):"DIV"===this.nodeName.toUpperCase()?t(this).html(o):t(this).text(o)}}),t("input, textarea",o).each(function(){var e=t(this).attr("name");if(e&&"file"!=t(this).attr("type")&&(!s||e.indexOf(s+".")>=0)){var a=e;s&&(a=a.substring(s.length+1));var o=r._get(i,a,!1,n);t(this).hasClass("percent")&&!isNaN(o)?o=100*Number(o):t(this).hasClass("object")?(t(this).data().pojo=o,t(this).addClass("POJO"),t(this).attr("data-display")&&(o=r._renderObject(o,t(this).attr("data-display")))):t.isPlainObject(o)&&(t(this).data().pojo=o,t(this).addClass("POJO"),o=r._renderObject(o,t(this).attr("data-display"))),"checkbox"===t(this).attr("type")?t(this).prop("checked",o===!0||"true"===o):(o||(o=""),t.jsFormControls&&(o=t.jsFormControls.Format.format(this,o)),t(this).val(o)),t(this).change(),t(this).trigger("fill")}}),t("select",o).each(function(){var e=t(this).attr("name");if(e&&(!s||e.indexOf(s+".")>=0)){var o=e;s&&(o=o.substring(s.length+1)),t(this).children("option").removeProp("selected");var l=t(this).attr("data-key");l||(l="id");var h=r._get(i,o,!1,n);if(h[l]||!isNaN(h[l]))return t(this).children("option[value='"+h[l]+"']").prop("selected","selected"),t(this).val(h[l]).change(),a;t(this).hasClass("bool")&&(h=h?"true":"false"),t(this).children("option[value='"+h+"']").prop("selected","selected"),t(this).val(h).change(),t(this).trigger("fill")}})},i.prototype.get=function(e){var a=t(this.element),i=this,s=this.options.data,n=this.options.prefix,r={};s&&t.isPlainObject(s)&&(r=s),i._createPojoFromInput(a,n,r);var o=!1;return this.options.validateHidden?a.find(".invalid").each(function(){return o=!0,t(this).focus(),!1}):a.find(".invalid").filter(":visible").each(function(){return o=!0,t(this).focus(),e||i._debug("Found invalid field: "+t(this).attr("name")),!1}),this._getCollection(a,n,r,e)&&(o=!0),!e&&o?null:r},i.prototype._getCollection=function(e,a,i,s){var n=this,r=!1;return e.find(".collection").each(function(){if(s||!r){var e=t(this).attr("data-field");if(e&&0===e.indexOf(a+".")&&(e=e.substring((a+".").length),!(1>e.length))){var o=n._getParent(i,e,!0);-1!==e.indexOf(".")&&(e=e.substring(e.lastIndexOf(".")+1)),o[e]=[],t(this).children().each(function(){if(s||!r){var a={};a=n._createPojoFromInput(t(this),e,a),n._getCollection(t(this),e,a,s),n._isEmpty(a)?t(".invalid",this).removeClass("invalid"):(t(".invalid",this).length>0&&(r=!0),o[e].push(a))}})}}}),r},i.prototype.getData=function(){return this.options.data||(this.options.data={}),this.options.data},i.prototype.preventEditing=function(e){var i=t(this.element);if(e===a)e=i.data("disabled")?!1:!0;else if(e===i.data("disabled"))return;e?(i.find("input, textarea").each(function(){if(!t(this).closest("span.form")[0]&&"hidden"!=t(this).attr("type")){var e=t(this).val();("null"===e||null===e||"submit"===t(this).attr("type"))&&(e=""),t(this).hasClass("trueFalse")&&(e=t(this).is(":checked")?"X":" "),e=e.replace(//g,">").replace(/\n/g,"
");var a=t(''+e+"");t(this).parent().hasClass("ui-wrapper")?t(this).parent().hide().wrap(a):t(this).hide().wrap(a)}}),i.find("select").each(function(){if(!t(this).closest("span.form")[0]){var e=t(this).children(":selected").html();("null"===e||null===e)&&(e="");var a=t(''+e+"");t(this).hasClass("ui-toggle-switch")?t(this).prev().hide().wrap(a):t(this).hide().wrap(a)}})):i.find("span.form").each(function(){var e=t(this).children("input,select,textarea,.ui-wrapper,.ui-toggle-switch").show().detach();t(this).before(e),t(this).remove()}),i.data("disabled",e)},i.prototype.validate=function(){return t(".required,.regexp,.date,.mandatory,.number,.validate,.integer",this.element).change(),t(".invalid",this.element).length>0?!1:!0},i.prototype._fill=function(e,a){this._clear(e,a.prefix),t(e).addClass("POJO"),t(e).data("pojo",a.data),this._fillData(e,a.data,a.prefix),this._fillCollection(e,a.data,a.prefix),this._evaluateConditionals(this.element,a.data)},i.prototype._fillCollection=function(e,a,i){var s=this;t(".collection",e).each(function(){var e=t(this),n=t(this).attr("data-field");if(a&&n&&0===n.indexOf(i+".")){var r=null,o=n;i&&(o=o.substring(i.length+1)),r=s._get(a,o),r&&s._fillList(e,r,o)}})},i.prototype._fillList=function(e,a,i,s){var n=e.data("template"),r=this;if(n&&(e.empty(),t.isArray(a))){if(-1!==i.indexOf(".")&&(i=i.substring(i.lastIndexOf(".")+1)),t(e).hasClass("sort")){var o=t(e).attr("data-sort");if(o){switch(t(e).attr("data-sorttype")){case"alpha":a.sort();break;case"alphainsensitiv":a.sort(function(t,e){return t=t[o],e=e[o],t&&(t=t.toLowerCase()),e&&(e=e.toLowerCase()),e>t?-1:t>e?1:0});break;default:a.sort(function(t,e){return t[o]-e[o]})}t(e).attr("data-sortdesc")&&a.reverse()}}s||t.isFunction(i)&&(s=i,i=null);for(var l=0;a.length>l;l++){var h=a[l],d=n.clone(!0);d.data().pojo=h,d.addClass("POJO"),s&&s(d,h)===!1||(r._addCollectionControls(d),i&&(r._fillData(d,h,i,l+1),r._initCollection(d,i),r._fillCollection(d,h,i)),e.append(d))}}},i.prototype._addCollectionControls=function(e){var a=this;t.jsFormControls&&t(e).jsFormControls(),t(".delete",e).click(function(){var e=t(this).closest(".POJO");t(this).closest(".collection").trigger("deleteCollection",[e,t(e).data().pojo]),e.remove()}),t(".sortUp",e).click(function(){var e=t(this).closest(".POJO"),i=e.prev(".POJO");0!==i.size()&&(e.detach(),i.before(e),a._reorder(e))}),t(".sortDown",e).click(function(){var e=t(this).closest(".POJO"),i=e.next(".POJO");0!==i.size()&&(e.detach(),i.after(e),a._reorder(e))});var i=t(e).closest(".collection");i.hasClass("sortable")&&t(i).sortable&&i.sortable("refresh")},i.prototype._reorder=function(e){e.attr("data-sort")||(e=e.closest(".collection"));var a=t(e).attr("data-sort");if(!(!a||t(e).attr("data-sorttype")&&"number"!==t(e).attr("data-sorttype")||t(e).attr("data-sortdesc")&&"false"!==t(e).attr("data-sortdesc"))){var i=0;t.each(t(e).children(),function(){var e=t(this).data("pojo");e||(e={},t(this).data("pojo",e)),e[a]=i++})}},i.prototype._renderObject=function(e,a){if(!a||!e)return"";var i=this,s="";return t.each(a.split(","),function(){var t=this.trim();s+=0===t.indexOf("'")||0===t.indexOf('"')?t.substring(1,t.length-1):i._get(e,t)}),s},i.prototype._get=function(t,e,i,s){var n,r,o,l="";if("function"==typeof e)return e(t);if(!t)return"";if(""===e)return t;if("$idx"===e)return s;if(n=t[e],!n)try{if("string"==typeof e&&(l=e.split(".")),o=l.length)for(n=t;n&&o--;)r=l.shift(),i&&!n[r]&&(n[r]={}),n=n[r]}catch(h){}return(null===n||n===a)&&(n=""),n.trim?n.trim():n},i.prototype._getValueWithArrays=function(t,e){e=e.split(".");for(var a=/(.*)\[(\d+)\]/,i=1;e.length>i;i++){var s=a.exec(e[i]);try{t=s?t[s[1]][parseInt(s[2],10)]:t[e[i]]}catch(n){console.log(e+" "+n)}}return t},i.prototype._getParent=function(t,e,a){return-1===e.indexOf(".")?t:(e=e.substring(0,e.lastIndexOf(".")),this._get(t,e,a))},i.prototype._getNumber=function(e){return e?t.format?t.format.number(e):((-1!=e.indexOf(",")||e.length-e.indexOf(".")>3)&&(e=e.replace(/\./g,"").replace(",",".")),Number(e)):null},i.prototype._isEmpty=function(e){if(!e)return!0;if(t.isArray(e)){if(0===e.length)return!0;for(var a=0;e.length>a;a++)if(!this._isEmpty())return!1;return!0}if(t.isPlainObject(e)){if(t.isEmptyObject(e))return!0;for(var i in e)if(!this._isEmpty(e[i]))return!1;return!0}return isNaN(e)?""===e||" "===e:0===Number(e)||-1===Number(e)?!0:!1},i.prototype._pojoDifferFromInput=function(e,i,s){var n=!1;return t("input,select,textarea",e).each(function(){if(!n){var e=t(this).attr("name");if(e&&!(t(this).hasClass("transient")||0!==e.indexOf(i+".")||(e=e.substring((i+".").length),1>e.length))){var r=t(this).val();if(""===r&&(t(this).hasClass("number")||t(this).hasClass("dateFilter")||t(this).hasClass("dateTimeFilter"))&&(r=null),(t(this).hasClass("number")||t(this).hasClass("currency"))&&(r=that._getNumber(r),isNaN(r)&&(r=0)),("checkbox"===t(this).attr("type")||"CHECKBOX"===t(this).attr("type"))&&(r=t(this).is(":checked")),-1===e.indexOf("."))s[e]!==r&&(n=!0);else{var o,l,h=e.split("."),d=s[h[0]];if(!d)return n=!0,a;2===h.length?d[h[1]]!==r&&(n=!0):3===h.length?(o=d[h[1]],o[h[2]]!==r&&(n=!0)):4===h.length&&(o=d[h[1]],l=o[h[2]],l[h[3]]!==r&&(n=!0))}}}}),n},i.prototype.equals=function(e){var i=this,s=this.element,n=this.options.prefix;if(this._pojoDifferFromInput(s,n,e))return!1;var r=!1;return t(".invalid",s).length>0?!1:(t(".collection",s).each(function(){if(!r){var s=t(this).attr("data-field");if(s&&0===s.indexOf(n+".")&&(s=s.substring((n+".").length),!(1>s.length))){var o=0;t(this).children().each(function(){if(!r){if(o>=e[s].length)return r=!0,a;var n=e[s][o++];i._pojoDifferFromInput(t(this),s,n)&&(r=!0)}}),e[s].length>o&&(r=!0)}}}),!r)},i.prototype.fill=function(t){this.options.data=t,this._fill(this.element,this.options)},i.prototype.applyConditions=function(t){t||(t=this.get(!0)),this._evaluateConditionals(this.element,t)},i.prototype.reset=function(){this.clear(),this._fill(this.element,this.options)},i.prototype.clear=function(){this._clear(this.element,this.options.prefix)},i.prototype.destroy=function(){return t(this.element).each(function(){t(e).unbind(".jsForm"),t(this).removeData("jsForm")})},t.fn.jsForm=function(e){if("object"!=typeof e&&e){var s,n=Array.prototype.slice.call(arguments,1);if(0===this.length)return null;if(1===this.length&&(s=t(this).data("jsForm"))){if(0!==e.indexOf("_")&&s[e]){var r=s[e].apply(s,n);return r}return t.error("Method "+e+" does not exist on jQuery.jsForm"),!1}return this.each(function(){return s=t.data(this,"jsForm"),s?0!==e.indexOf("_")&&s[e]?s[e].apply(s,n):(t.error("Method "+e+" does not exist on jQuery.jsForm"),!1):a})}return this.each(function(){t(this).data("jsForm")||t(this).data("jsForm",new i(this,e))})},t.jsForm=function(e,a){var i=n[e];if(t.isFunction(a))i&&t.each(i,function(){a(this,t(this.element))}),s[e]=a;else if(i){var r=a,o=Array.prototype.slice.call(arguments,2);t.each(portlets,function(){this[r].apply(this,o)})}}})(jQuery,window),function(t){"use strict";function e(t){this.element=t,this._domInit()}var a={},i={};"undefined"!=typeof Handlebars&&(Handlebars.registerHelper("currency",function(e){return e?t.jsFormControls.Format.currency(e):"0"}),Handlebars.registerHelper("dec",function(e){return e?t.jsFormControls.Format.decimal(e):""}),Handlebars.registerHelper("percent",function(e){return e?t.jsFormControls.Format.decimal(100*e):"0"}),Handlebars.registerHelper("date",function(e){return e?t.jsFormControls.Format.date(e):""}),Handlebars.registerHelper("time",function(e){return e?t.jsFormControls.Format.time(e):""}),Handlebars.registerHelper("datetime",function(e){return e?t.jsFormControls.Format.dateTime(e):""}),Handlebars.registerHelper("dateTime",function(e){return e?t.jsFormControls.Format.dateTime(e):""}),Handlebars.registerHelper("timespan",function(e){return e?t.jsFormControls.Format.humanTime(e):""}),Handlebars.registerHelper("byte",function(e){return e?t.jsFormControls.Format.byte(e):""})),e.prototype._domInit=function(){var e=t(this.element);e.find("input.mandatory,textarea.mandatory").on("keyup",function(){t(this).val().length>0&&"null"!==t(this).val()?t(this).addClass("valid").removeClass("invalid"):t(this).removeClass("valid").addClass("invalid")}),e.find("input.mandatory,textarea.mandatory").on("change",function(){return t(this).hasClass("object")?(t(this).data().pojo?t(this).addClass("valid").removeClass("invalid"):t(this).removeClass("valid").addClass("invalid"),undefined):(t(this).val().length>0&&"null"!==t(this).val()?t(this).addClass("valid").removeClass("invalid"):t(this).removeClass("valid").addClass("invalid"),undefined)}).change(),e.find("select.mandatory").change(function(){null!==t(this).val()&&"null"!==t(this).val()&&t(this).val().length>0?t(this).addClass("valid").removeClass("invalid"):t(this).removeClass("valid").addClass("invalid")}).change(),e.find("input.date").each(function(){var e=t(this).attr("data-format");t(this).datepicker&&(e?t(this).datepicker({dateFormat:e}):t(this).datepicker())});var a=RegExp("^[0-9.,-]+$");e.find("input.number").keyup(function(){var e=t(this).val();e.length>0&&(t(this).hasClass("autoclean")?t(this).val(e.replace(/[^0-9.,-]/g,"")):a.test(t(this).val())?t(this).addClass("valid").removeClass("invalid"):t(this).removeClass("valid").addClass("invalid"))}).keyup();var i=RegExp("^[0-9]+$");e.find("input.integer").keyup(function(){var e=t(this).val();e.length>0&&(t(this).hasClass("autoclean")?t(this).val(e.replace(/[^0-9]/g,"")):i.test(t(this).val())?t(this).addClass("valid").removeClass("invalid"):t(this).removeClass("valid").addClass("invalid"))}).keyup(),e.find("input.regexp").each(function(){t(this).hasClass("autoclean")?t(this).data("regexp",RegExp(t(this).attr("data-regexp"),"g")):t(this).data("regexp",RegExp(t(this).attr("data-regexp"))),t(this).keyup(function(){var e=t(this).val();if(e.length>0){var a=t(this).data("regexp");t(this).hasClass("autoclean")?t(this).val(e.replace(a,"")):a.test(t(this).val())?t(this).addClass("valid").removeClass("invalid"):t(this).removeClass("valid").addClass("invalid")}else t(this).hasClass("mandatory")||t(this).removeClass("invalid").addClass("valid")}).keyup(),t(this).change(function(){t(this).keyup()})}),e.find("input.rotatestate").each(function(){var e=t(this).attr("data-state-values"),a=t(this).attr("data-state-class");if(e){try{e=JSON.parse(e)}catch(i){return}var s=t("");t(this).attr("title")&&s.attr("title",t(this).attr("title")),t(this).attr("data-state-style")&&s.attr("style",t(this).attr("data-state-style")),s.data("states",e),s.data("control",this),s.data("activeState",null),t(this).data("control",s),a&&s.addClass(a),s.click(function(){var e=t(this).data().activeState,a=t(this).data().states,i=t(this).data().control,s=null;if(null!==e){for(var n=0;a.length>n;n++)if(a[n].value===e.value){s=n===a.length-1?a[0]:a[n+1];break}}else s=a[0];t(i).attr("value",s.value),t(i).change()}),t(this).change(function(){var e=t(t(this).data().control),a=e.data().activeState,i=e.data().states;null!==a&&e.removeClass(a["class"]);var s=t(this).val();t.each(i,function(){return this.value===s?(e.data().activeState=this,this.title&&e.attr("title",this.title),e.addClass(this["class"]),!1):undefined})}),t(this).change(),t(this).after(s),t(this).hide()}})},e.prototype.validate=function(){return t(".required,.regexp,.date,.mandatory,.number,.validate",this.element).change(),t(".invalid",this.element).length>0?!1:!0},t.fn.jsFormControls=function(a){if("object"!=typeof a&&a){var i=Array.prototype.slice.call(arguments,1);if(1==this.length){var s=t(this).data("jsFormControls");if(s){if(0!==a.indexOf("_")&&s[a]){var n=s[a].apply(s,i);return n}return t.error("Method "+a+" does not exist on jQuery.jsFormControls"),!1}}return this.each(function(){var e=t.data(this,"jsFormControls");return e?0!==a.indexOf("_")&&e[a]?e[a].apply(e,i):(t.error("Method "+a+" does not exist on jQuery.jsFormControls"),!1):undefined})}return this.each(function(){t(this).data("jsFormControls")||t(this).data("jsFormControls",new e(this,a))})},t.jsFormControls=function(e,s){var n;if(t.isFunction(s))n=i[e],n&&t.each(n,function(){s(this,t(this.element))}),a[e]=s;else if(n=i[e]){var r=s,o=Array.prototype.slice.call(arguments,2);t.each(portlets,function(){this[r].apply(this,o)})}},t.jsFormControls.Format={format:function(e,a){return t(e).hasClass("dateTime")?isNaN(a)?a:t.jsFormControls.Format.dateTime(a):t(e).hasClass("datetime")?isNaN(a)?a:t.jsFormControls.Format.dateTime(a):t(e).hasClass("date")?isNaN(a)?a:t.jsFormControls.Format.date(a):t(e).hasClass("currency")?t.jsFormControls.Format.currency(a):t(e).hasClass("byte")?isNaN(a)?a:t.jsFormControls.Format.byte(a):t(e).hasClass("number")?t.jsFormControls.Format.decimal(a):a},checkBox:function(t,e,a){return a===undefined&&(a=t,t=null),a?' ':' '},_getNumber:function(e){return e?t.format?t.format.number(e):((-1!==e.indexOf(",")||e.length-e.indexOf(".")>3)&&(e=e.replace(/\./g,"").replace(",",".")),Number(e)):null},_pad:function(t){var e=10>t?"0":"";return e+=t},"byte":function(t){if(""===t||!t||isNaN(t))return t;var e=1024;if(e>t)return t+" B";var a=Math.floor(Math.log(t)/Math.log(e)),i="KMGTPE".charAt(a-1)+"B";return Math.round(10*t/Math.pow(e,a))/10+i},decimal:function(e){if(""===e||!e||isNaN(e))return e;var a={format:"#,##0.###",groupingSeparator:",",decimalSeparator:"."};if("undefined"!=typeof i18n&&(a=i18n.number),t(document).data().i18n!==undefined&&(a=t(document).data().i18n.number),t.format&&a)return t.format.number(e,a);var i=0;Math.abs(e-Math.floor(e))>.001&&(i=2);var s=e,n=isNaN(n=Math.abs(i))?2:i,r=a.decimalSeparator,o=a.groupingSeparator,l=parseInt(s=Math.abs(+s||0).toFixed(n),10)+"",h=(h=l.length)>3?h%3:0;return(0>e?"-":"")+(h?l.substr(0,h)+o:"")+l.substr(h).replace(/(\d{3})(?=\d)/g,"$1"+o)+(n?r+Math.abs(s-l).toFixed(n).slice(2):"")},currency:function(e,a,i){return(!i||isNaN(i))&&(i=e,e=null),i?t.jsFormControls.Format.decimal(i):a?" ":""},dateTime:function(t,e,a){return(!a||isNaN(a))&&(a=t,t=null),a?this.date(a)+" "+this.time(a):e?" ":""},date:function(e,a,i){if((!i||isNaN(i))&&(i=e,e=null),!i)return a?" ":"";var s=new Date;s.setTime(i);var n=s.getYear();1900>n&&(n+=1900);var r=null;return"undefined"!=typeof i18n&&(r=i18n.date),t(document).data().i18n!==undefined&&(r=t(document).data().i18n.date),t.format?t.format.date(s,r.shortDateFormat):this._pad(s.getDate())+"."+this._pad(s.getMonth()+1)+"."+this._pad(n)},time:function(e,a,i){if(i||(i=e,e=null),!i)return a?" ":"";var s=new Date;return s.setTime(i),t.format?t.format.date(s,t(document).data().i18n.date.timeFormat):this._pad(s.getHours())+":"+this._pad(s.getMinutes())},timespan:function(t,e,a,i,s,n){a||(a=t,n=e,t=null,e=null);for(var r=a.split(":"),o=0;r.length>o;o++){var l=Number(r[o]);l&&"NaN"!==l||(l=0),r[o]=this._pad(l)}return 0>=r.length?"0:00":1==r.length?"0:"+this._pad(allowkomma?r[0]:Math.floor(r[0])):2==r.length?allowkomma?r[0]:Math.floor(r[0])+":"+this._pad(allowkomma?r[1]:Math.floor(r[1])):allowkomma?r[0]:Math.floor(r[0])+":"+this._pad(allowkomma?r[1]:Math.floor(r[1]))+":"+pad(allowkomma?r[2]:Math.floor(r[2]))},humanTime:function(t,e,a){if(a||(a=t,t=null),isNaN(a))return a&&0!==a.length?a:"-";var i=Math.floor(a/36e5);a-=36e5*i;var s=Math.floor(a/6e4);a-=6e4*s;var n=Math.floor(a/1e3);a-=1e3*n;var r="";return i>0&&(r+=i+"h ",n=0,a=0),s>0&&(r+=s+"m ",a=0),n>0&&(r+=n+"s ",a=0),a>0&&(r+=a+"ms"),r.trim()}}}(jQuery,window),String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")},String.prototype.startsWith=function(t){return null===this||0>=this.length?!1:null===t||"null"==t||0>=t.length?!1:this.substr(0,t.length)==t?!0:!1},String.prototype.startsWithIgnoreCase=function(t){return null===this||0>=this.length?!1:null===t||"null"==t||0>=t.length?!1:this.substr(0,t.length).toLowerCase()==t.toLowerCase()?!0:!1},String.prototype.endsWith=function(t){return null===this||0>=this.length?!1:null===t||"null"==t||0>=t.length||t.length>this.length?!1:this.substr(this.length-t.length)==t?!0:!1}; -//@ sourceMappingURL=dist/jquery.jsForm.min.map \ No newline at end of file