many fixes for ie7+ compatibility

This commit is contained in:
vitalets 2012-11-27 13:25:42 +04:00
parent 1e757b833f
commit 18f29820f3
7 changed files with 154 additions and 135 deletions

@ -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';

@ -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');

@ -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;
}

@ -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 = $('&lt;div&gt;').editableform({
type: 'text',
name: 'username',
url: '/post',
value: 'vitaliy'
});
//to display form you should call 'render' method
$form.editableform('render');
var $form = $('&lt;div&gt;').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));

@ -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();

@ -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();

@ -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();