From 18f29820f3f6cb4936143161f3eac51e8557eb4d Mon Sep 17 00:00:00 2001 From: vitalets <noginsk@rambler.ru> Date: Tue, 27 Nov 2012 13:25:42 +0400 Subject: [PATCH] many fixes for ie7+ compatibility --- src/editable-form/editable-form-bootstrap.js | 4 +- src/editable-form/editable-form-jqueryui.js | 6 +- src/editable-form/editable-form.css | 20 +- src/editable-form/editable-form.js | 247 ++++++++++--------- src/element/editable-element.js | 8 +- src/inputs/date/date.js | 2 +- src/inputs/dateui/dateui.js | 2 +- 7 files changed, 154 insertions(+), 135 deletions(-) diff --git a/src/editable-form/editable-form-bootstrap.js b/src/editable-form/editable-form-bootstrap.js index f6a5273..d55e3fd 100644 --- a/src/editable-form/editable-form-bootstrap.js +++ b/src/editable-form/editable-form-bootstrap.js @@ -14,8 +14,8 @@ Editableform based on Twitter Bootstrap }); //buttons - $.fn.editableform.buttons = '<button type="submit" class="btn btn-primary"><i class="icon-ok icon-white"></i></button>'+ - '<button type="button" class="btn clearfix"><i class="icon-ban-circle"></i></button>'; + $.fn.editableform.buttons = '<button type="submit" class="btn btn-primary editable-submit"><i class="icon-ok icon-white"></i></button>'+ + '<button type="button" class="btn editable-cancel"><i class="icon-ban-circle"></i></button>'; //error classes $.fn.editableform.errorGroupClass = 'error'; diff --git a/src/editable-form/editable-form-jqueryui.js b/src/editable-form/editable-form-jqueryui.js index c0b6683..b5983c8 100644 --- a/src/editable-form/editable-form-jqueryui.js +++ b/src/editable-form/editable-form-jqueryui.js @@ -8,12 +8,12 @@ Editableform based on jQuery UI this.$form = $($.fn.editableform.template); //buttons - this.$form.find('div.editable-buttons').append($.fn.editableform.buttons); - this.$form.find('button[type=submit]').button({ + this.$form.find('.editable-buttons').append($.fn.editableform.buttons); + this.$form.find('.editable-submit').button({ icons: { primary: "ui-icon-check" }, text: false }).removeAttr('title'); - this.$form.find('button[type=button]').button({ + this.$form.find('.editable-cancel').button({ icons: { primary: "ui-icon-cancel" }, text: false }).removeAttr('title'); diff --git a/src/editable-form/editable-form.css b/src/editable-form/editable-form.css index 446e3fa..f7acde3 100644 --- a/src/editable-form/editable-form.css +++ b/src/editable-form/editable-form.css @@ -9,15 +9,24 @@ .editable-buttons { display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */ + vertical-align: top; + margin-left: 7px; + /* display-inline emulation for IE7*/ + zoom: 1; + *display: inline; } .editable-input { vertical-align: top; display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */ width: auto; /* bootstrap-responsive has width: 100% that breakes layout */ + white-space: normal; /* reset white-space decalred in parent*/ + /* display-inline emulation for IE7*/ + zoom: 1; + *display: inline; } -.editable-buttons button { +.editable-buttons .editable-cancel { margin-left: 7px; } @@ -28,7 +37,8 @@ .editableform-loading { background: url('img/loading.gif') center center no-repeat; - height: 25px; + height: 25px; + width: auto; } .editable-inline .editableform-loading { @@ -39,7 +49,7 @@ max-width: 300px; padding-top: 3px; margin: 0; - clear: both; + width: auto; } .editable-error { @@ -57,8 +67,8 @@ } .editable-clear { - clear: both; - float: right; + clear: both; font-size: 0.9em; text-decoration: none; + text-align: right; } \ No newline at end of file diff --git a/src/editable-form/editable-form.js b/src/editable-form/editable-form.js index 8cf8bd2..ed0ac53 100644 --- a/src/editable-form/editable-form.js +++ b/src/editable-form/editable-form.js @@ -8,7 +8,7 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'. @uses textarea **/ (function ($) { - + var EditableForm = function (element, options) { this.options = $.extend({}, $.fn.editableform.defaults, options); this.$element = $(element); //div (usually), containing form. not form tag! @@ -19,7 +19,7 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'. constructor: EditableForm, initInput: function() { //called once var TypeConstructor, typeOptions; - + //create input of specified type if(typeof $.fn.editableform.types[this.options.type] === 'function') { TypeConstructor = $.fn.editableform.types[this.options.type]; @@ -34,7 +34,7 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'. }, initTemplate: function() { this.$form = $($.fn.editableform.template); - + //buttons this.$form.find('div.editable-buttons').append($.fn.editableform.buttons); }, @@ -47,54 +47,57 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'. this.$loading = $($.fn.editableform.loading); this.$element.empty().append(this.$loading); this.showLoading(); - + this.initTemplate(); - + /** Fired when rendering starts @event rendering @param {Object} event event object **/ this.$element.triggerHandler('rendering'); - + //render input $.when(this.input.render()) .then($.proxy(function () { //input this.$form.find('div.editable-input').append(this.input.$input); - - //clear link + + //"clear" link if(this.input.$clear) { - this.$form.find('div.editable-input').append(this.input.$clear); + this.$form.find('div.editable-input').append($('<div class="editable-clear">').append(this.input.$clear)); } - - //attach 'cancel' handler - this.$form.find('button[type=button]').click($.proxy(this.cancel, this)); + //append form to container this.$element.append(this.$form); + + //attach 'cancel' handler + this.$form.find('.editable-cancel').click($.proxy(this.cancel, this)); + // this.$form.find('.editable-buttons button').eq(1).click($.proxy(this.cancel, this)); + if(this.input.error) { this.error(this.input.error); - this.$form.find('button[type=submit]').attr('disabled', true); + this.$form.find('.editable-submit').attr('disabled', true); this.input.$input.attr('disabled', true); } else { this.error(false); this.input.$input.removeAttr('disabled'); - this.$form.find('button[type=submit]').removeAttr('disabled'); + this.$form.find('.editable-submit').removeAttr('disabled'); this.input.value2input(this.value); this.$form.submit($.proxy(this.submit, this)); } - + /** Fired when form is rendered @event rendered @param {Object} event event object **/ this.$element.triggerHandler('rendered'); - + this.showForm(); }, this)); }, - cancel: function() { + cancel: function() { /** Fired when form was cancelled by user @event cancel @@ -103,12 +106,18 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'. this.$element.triggerHandler('cancel'); }, showLoading: function() { - var fw, fh, iw, bh; - //set loading size equal to form + var w; if(this.$form) { + //set loading size equal to form this.$loading.width(this.$form.outerWidth()); this.$loading.height(this.$form.outerHeight()); this.$form.hide(); + } else { + //stretch loading to fill container width + w = this.$loading.parent().width(); + if(w) { + this.$loading.width(w); + } } this.$loading.show(); }, @@ -124,11 +133,11 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'. **/ this.$element.triggerHandler('show'); }, - + error: function(msg) { var $group = this.$form.find('.control-group'), - $block = this.$form.find('.editable-error-block'); - + $block = this.$form.find('.editable-error-block'); + if(msg === false) { $group.removeClass($.fn.editableform.errorGroupClass); $block.removeClass($.fn.editableform.errorBlockClass).empty().hide(); @@ -137,15 +146,15 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'. $block.addClass($.fn.editableform.errorBlockClass).text(msg).show(); } }, - + submit: function(e) { e.stopPropagation(); e.preventDefault(); var error, - //get value from input - newValue = this.input.input2value(), - newValueStr; + //get value from input + newValue = this.input.input2value(), + newValueStr; //validation if (error = this.validate(newValue)) { @@ -153,14 +162,14 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'. this.showForm(); return; } - + //value as string newValueStr = this.input.value2str(newValue); - + //if value not changed --> cancel /*jslint eqeq: true*/ if (newValueStr == this.input.value2str(this.value)) { - /*jslint eqeq: false*/ + /*jslint eqeq: false*/ this.cancel(); return; } @@ -175,36 +184,36 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'. this.showForm(); return; } - - //clear error message - this.error(false); - this.value = newValue; - /** - Fired when form is submitted - @event save - @param {Object} event event object - @param {Object} params additional params - @param {mixed} params.newValue submitted value - @param {Object} params.response ajax response - - @example - $('#form-div').on('save'), function(e, params){ - if(params.newValue === 'username') {...} - }); - **/ - this.$element.triggerHandler('save', {newValue: newValue, response: response}); + + //clear error message + this.error(false); + this.value = newValue; + /** + Fired when form is submitted + @event save + @param {Object} event event object + @param {Object} params additional params + @param {mixed} params.newValue submitted value + @param {Object} params.response ajax response + + @example + $('#form-div').on('save'), function(e, params){ + if(params.newValue === 'username') {...} + }); + **/ + this.$element.triggerHandler('save', {newValue: newValue, response: response}); }, this)) .fail($.proxy(function(xhr) { - this.error(typeof xhr === 'string' ? xhr : xhr.responseText || xhr.statusText || 'Unknown error!'); - this.showForm(); + this.error(typeof xhr === 'string' ? xhr : xhr.responseText || xhr.statusText || 'Unknown error!'); + this.showForm(); }, this)); }, save: function(value) { var pk = (typeof this.options.pk === 'function') ? this.options.pk.call(this) : this.options.pk, - send = !!(typeof this.options.url === 'function' || (this.options.url && ((this.options.send === 'always') || (this.options.send === 'auto' && pk)))), - params; - + send = !!(typeof this.options.url === 'function' || (this.options.url && ((this.options.send === 'always') || (this.options.send === 'auto' && pk)))), + params; + if (send) { //send to server this.showLoading(); @@ -214,7 +223,7 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'. value: value, pk: pk }; - + //additional params if(typeof this.options.params === 'function') { $.extend(params, this.options.params.call(this, params)); @@ -236,7 +245,7 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'. } } }, - + validate: function (value) { if (value === undefined) { value = this.value; @@ -245,38 +254,38 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'. return this.options.validate.call(this, value); } }, - - option: function(key, value) { - this.options[key] = value; - if(key === 'value') { - this.setValue(value); - } - }, - - setValue: function(value, convertStr) { - if(convertStr) { - this.value = this.input.str2value(value); - } else { - this.value = value; - } - } + + option: function(key, value) { + this.options[key] = value; + if(key === 'value') { + this.setValue(value); + } + }, + + setValue: function(value, convertStr) { + if(convertStr) { + this.value = this.input.str2value(value); + } else { + this.value = value; + } + } }; /* Initialize editableform. Applied to jQuery object. - + @method $().editableform(options) @params {Object} options @example - var $form = $('<div>').editableform({ - type: 'text', - name: 'username', - url: '/post', - value: 'vitaliy' - }); - - //to display form you should call 'render' method - $form.editableform('render'); + var $form = $('<div>').editableform({ + type: 'text', + name: 'username', + url: '/post', + value: 'vitaliy' + }); + + //to display form you should call 'render' method + $form.editableform('render'); */ $.fn.editableform = function (option) { var args = arguments; @@ -287,20 +296,20 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'. if (!data) { $this.data('editableform', (data = new EditableForm(this, options))); } - + if (typeof option === 'string') { //call method data[option].apply(data, Array.prototype.slice.call(args, 1)); } }); }; - + //keep link to constructor to allow inheritance $.fn.editableform.Constructor = EditableForm; //defaults $.fn.editableform.defaults = { /* see also defaults for input */ - + /** Type of input. Can be <code>text|textarea|select|date|checklist</code> @@ -318,12 +327,12 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'. @default null @example url: function(params) { - if(params.value === 'abc') { - var d = new $.Deferred; - return d.reject('field cannot be "abc"'); //returning error via deferred object - } else { - someModel.set(params.name, params.value); //save data in some js model - } + if(params.value === 'abc') { + var d = new $.Deferred; + return d.reject('field cannot be "abc"'); //returning error via deferred object + } else { + someModel.set(params.name, params.value); //save data in some js model + } } **/ url:null, @@ -331,7 +340,7 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'. Additional params for submit. Function can be used to calculate params dynamically @example params: function() { - return { a: 1 }; + return { a: 1 }; } @property params @@ -382,54 +391,54 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'. @default null @example validate: function(value) { - if($.trim(value) == '') { - return 'This field is required'; - } + if($.trim(value) == '') { + return 'This field is required'; + } } **/ validate: null, /** Success callback. Called when value successfully sent on server and response status = 200. Can be used to process json response. If this function returns string - means error occured and string is shown as error message. - + @property success @type function @default null @example success: function(response, newValue) { - if(!response.success) return response.msg; + if(!response.success) return response.msg; } **/ success: function(response, newValue) {} }; /* - Note: following params could redefined in engine: bootstrap or jqueryui: - Classes 'control-group' and 'editable-error-block' must always present! + Note: following params could redefined in engine: bootstrap or jqueryui: + Classes 'control-group' and 'editable-error-block' must always present! */ - $.fn.editableform.template = '<form class="form-inline editableform">'+ - '<div class="control-group">' + - '<div class="editable-input"></div><div class="editable-buttons"></div>'+ - '<div class="editable-error-block"></div>' + - '</div>' + - '</form>'; - - //loading div - $.fn.editableform.loading = '<div class="editableform-loading"></div>'; - - //buttons - $.fn.editableform.buttons = '<button type="submit">ok</button>'+ - '<button type="button">cancel</button>'; - - //error class attahced to control-group - $.fn.editableform.errorGroupClass = null; - - //error class attahced to editable-error-block - $.fn.editableform.errorBlockClass = 'editable-error'; + $.fn.editableform.template = '<form class="form-inline editableform">'+ + '<div class="control-group">' + + '<div><div class="editable-input"></div><div class="editable-buttons"></div></div>'+ + '<div class="editable-error-block"></div>' + + '</div>' + + '</form>'; - //input types - $.fn.editableform.types = {}; - //utils - $.fn.editableform.utils = {}; + //loading div + $.fn.editableform.loading = '<div class="editableform-loading"></div>'; + + //buttons + $.fn.editableform.buttons = '<button type="submit" class="editable-submit">ok</button>'+ + '<button type="button" class="editable-cancel">cancel</button>'; + + //error class attahced to control-group + $.fn.editableform.errorGroupClass = null; + + //error class attahced to editable-error-block + $.fn.editableform.errorBlockClass = 'editable-error'; + + //input types + $.fn.editableform.types = {}; + //utils + $.fn.editableform.utils = {}; }(window.jQuery)); \ No newline at end of file diff --git a/src/element/editable-element.js b/src/element/editable-element.js index fe581cd..f51afec 100644 --- a/src/element/editable-element.js +++ b/src/element/editable-element.js @@ -35,7 +35,7 @@ Makes editable any HTML element on the page. Applied as jQuery method. //create input of specified type. Input will be used for converting value, not in form if(typeof $.fn.editableform.types[this.options.type] === 'function') { TypeConstructor = $.fn.editableform.types[this.options.type]; - this.typeOptions = $.fn.editableform.utils.sliceObj(this.options, Object.keys(TypeConstructor.defaults)); + this.typeOptions = $.fn.editableform.utils.sliceObj(this.options, $.fn.editableform.utils.objectKeys(TypeConstructor.defaults)); this.input = new TypeConstructor(this.typeOptions); } else { $.error('Unknown type: '+ this.options.type); @@ -53,7 +53,7 @@ Makes editable any HTML element on the page. Applied as jQuery method. //attach handler to close any container on escape $(document).off('keyup.editable').on('keyup.editable', function (e) { if (e.which === 27) { - $('.editable-container').find('button[type=button]').click(); + $('.editable-container').find('.editable-cancel').click(); } }); @@ -65,7 +65,7 @@ Makes editable any HTML element on the page. Applied as jQuery method. return; } //close all other containers - $('.editable-container').find('button[type=button]').click(); + $('.editable-container').find('.editable-cancel').click(); }); //add 'editable' class @@ -229,7 +229,7 @@ Makes editable any HTML element on the page. Applied as jQuery method. } //hide all other editable containers. Required to work correctly with toggle = manual - $('.editable-container').find('button[type=button]').click(); + $('.editable-container').find('.editable-cancel').click(); //show container this.container.show(); diff --git a/src/inputs/date/date.js b/src/inputs/date/date.js index b16f57e..6490021 100644 --- a/src/inputs/date/date.js +++ b/src/inputs/date/date.js @@ -56,7 +56,7 @@ $(function(){ this.$input.datepicker(this.options.datepicker); if(this.options.clear) { - this.$clear = $('<a href="#">').addClass('editable-clear').html(this.options.clear).click($.proxy(function(e){ + this.$clear = $('<a href="#"></a>').html(this.options.clear).click($.proxy(function(e){ e.preventDefault(); e.stopPropagation(); this.clear(); diff --git a/src/inputs/dateui/dateui.js b/src/inputs/dateui/dateui.js index 986726a..5b39f27 100644 --- a/src/inputs/dateui/dateui.js +++ b/src/inputs/dateui/dateui.js @@ -54,7 +54,7 @@ $(function(){ this.$input.datepicker(this.options.datepicker); if(this.options.clear) { - this.$clear = $('<a href="#">').addClass('editable-clear').html(this.options.clear).click($.proxy(function(e){ + this.$clear = $('<a href="#"></a>').html(this.options.clear).click($.proxy(function(e){ e.preventDefault(); e.stopPropagation(); this.clear();