/** * EditableForm utilites */ (function ($) { //utils $.fn.editableutils = { /** * classic JS inheritance function */ inherit: function (Child, Parent) { var F = function() { }; F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; Child.superclass = Parent.prototype; }, /** * set caret position in input * see http://stackoverflow.com/questions/499126/jquery-set-cursor-position-in-text-area */ setCursorPosition: function(elem, pos) { if (elem.setSelectionRange) { elem.setSelectionRange(pos, pos); } else if (elem.createTextRange) { var range = elem.createTextRange(); range.collapse(true); range.moveEnd('character', pos); range.moveStart('character', pos); range.select(); } }, /** * function to parse JSON in *single* quotes. (jquery automatically parse only double quotes) * That allows such code as: <a data-source="{'a': 'b', 'c': 'd'}"> * safe = true --> means no exception will be thrown * for details see http://stackoverflow.com/questions/7410348/how-to-set-json-format-to-html5-data-attributes-in-the-jquery */ tryParseJson: function(s, safe) { if (typeof s === 'string' && s.length && s.match(/^[\{\[].*[\}\]]$/)) { if (safe) { try { /*jslint evil: true*/ s = (new Function('return ' + s))(); /*jslint evil: false*/ } catch (e) {} finally { return s; } } else { /*jslint evil: true*/ s = (new Function('return ' + s))(); /*jslint evil: false*/ } } return s; }, /** * slice object by specified keys */ sliceObj: function(obj, keys, caseSensitive /* default: false */) { var key, keyLower, newObj = {}; if (!$.isArray(keys) || !keys.length) { return newObj; } for (var i = 0; i < keys.length; i++) { key = keys[i]; if (obj.hasOwnProperty(key)) { newObj[key] = obj[key]; } if(caseSensitive === true) { continue; } //when getting data-* attributes via $.data() it's converted to lowercase. //details: http://stackoverflow.com/questions/7602565/using-data-attributes-with-jquery //workaround is code below. keyLower = key.toLowerCase(); if (obj.hasOwnProperty(keyLower)) { newObj[key] = obj[keyLower]; } } return newObj; }, /** * exclude complex objects from $.data() before pass to config */ getConfigData: function($element) { var data = {}; $.each($element.data(), function(k, v) { if(typeof v !== 'object' || (v && typeof v === 'object' && v.constructor === Object)) { data[k] = v; } }); return data; }, objectKeys: function(o) { if (Object.keys) { return Object.keys(o); } else { if (o !== Object(o)) { throw new TypeError('Object.keys called on a non-object'); } var k=[], p; for (p in o) { if (Object.prototype.hasOwnProperty.call(o,p)) { k.push(p); } } return k; } }, /** method to escape html. **/ escape: function(str) { return $('<div>').text(str).html(); }, /* returns array items from sourceData having value property equal or inArray of 'value' */ itemsByValue: function(value, sourceData) { if(!sourceData || value === null) { return []; } //convert to array if(!$.isArray(value)) { value = [value]; } /*jslint eqeq: true*/ var result = $.grep(sourceData, function(o){ return $.grep(value, function(v){ return v == o.value; }).length; }); /*jslint eqeq: false*/ return result; }, /* Returns input by options: type, mode. */ createInput: function(options) { var TypeConstructor, typeOptions, input, type = options.type; //`date` is some kind of virtual type that is transformed to one of exact types //depending on mode and core lib if(type === 'date') { //inline if(options.mode === 'inline') { if($.fn.editabletypes.datefield) { type = 'datefield'; } else if($.fn.editabletypes.dateuifield) { type = 'dateuifield'; } //popup } else { if($.fn.editabletypes.date) { type = 'date'; } else if($.fn.editabletypes.dateui) { type = 'dateui'; } } } //change wysihtml5 to textarea for jquery UI and plain versions if(type === 'wysihtml5' && !$.fn.editabletypes[type]) { type = 'textarea'; } //create input of specified type. Input will be used for converting value, not in form if(typeof $.fn.editabletypes[type] === 'function') { TypeConstructor = $.fn.editabletypes[type]; typeOptions = this.sliceObj(options, this.objectKeys(TypeConstructor.defaults)); input = new TypeConstructor(typeOptions); return input; } else { $.error('Unknown type: '+ type); return false; } } }; }(window.jQuery));