text x-clear button and new $tpl property in inputs, need tests

This commit is contained in:
vitalets
2013-01-05 16:23:58 +04:00
parent f6a7b26e1f
commit 5edc4bbfcb
15 changed files with 173 additions and 84 deletions

@ -88,4 +88,33 @@
font-size: 0.9em; font-size: 0.9em;
text-decoration: none; text-decoration: none;
text-align: right; text-align: right;
} }
.editable-clear-x {
background: url('../img/clear.png') center center no-repeat;
display: block;
width: 13px;
height: 13px;
position: absolute;
right: 7px;
opacity: 0.6;
z-index: 100;
}
.editable-clear-x:hover {
opacity: 1;
}
/*
.editable-clear-x1 {
background: url('../img/clear.png') center center no-repeat;
display: inline-block;
zoom: 1;
*display: inline;
width: 13px;
height: 13px;
vertical-align: middle;
position: relative;
margin-left: -20px;
}
*/

@ -64,8 +64,8 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
//render input //render input
$.when(this.input.render()) $.when(this.input.render())
.then($.proxy(function () { .then($.proxy(function () {
//input //insert input in form
this.$form.find('div.editable-input').append(this.input.$input); this.$form.find('div.editable-input').append(this.input.$tpl);
//automatically submit inputs when no buttons shown //automatically submit inputs when no buttons shown
if(!this.options.showbuttons) { if(!this.options.showbuttons) {
@ -73,9 +73,9 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
} }
//"clear" link //"clear" link
if(this.input.$clear) { // if(this.input.$clear) {
this.$form.find('div.editable-input').append($('<div class="editable-clear">').append(this.input.$clear)); // this.$form.find('div.editable-input').append($('<div class="editable-clear">').append(this.input.$clear));
} // }
//append form to container //append form to container
this.$div.append(this.$form); this.$div.append(this.$form);
@ -83,6 +83,11 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
//attach 'cancel' handler //attach 'cancel' handler
this.$form.find('.editable-cancel').click($.proxy(this.cancel, this)); this.$form.find('.editable-cancel').click($.proxy(this.cancel, this));
//call postrender to perform actions, required when input is in DOM
if(this.input.postrender) {
this.input.postrender();
}
if(this.input.error) { if(this.input.error) {
this.error(this.input.error); this.error(this.input.error);
this.$form.find('.editable-submit').attr('disabled', true); this.$form.find('.editable-submit').attr('disabled', true);

BIN
src/img/clear.png Normal file

Binary file not shown.

After

(image error) Size: 509 B

@ -153,11 +153,11 @@ $(function(){
}); });
Address.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, { Address.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
tpl: '<div><label><span>City: </span><input type="text" name="city" class="input-small"></label></div>'+ tpl: '<div class="editable-address"><label><span>City: </span><input type="text" name="city" class="input-small"></label></div>'+
'<div><label><span>Street: </span><input type="text" name="street" class="input-small"></label></div>'+ '<div class="editable-address"><label><span>Street: </span><input type="text" name="street" class="input-small"></label></div>'+
'<div><label><span>Building: </span><input type="text" name="building" class="input-mini"></label></div>', '<div class="editable-address"><label><span>Building: </span><input type="text" name="building" class="input-mini"></label></div>',
inputclass: 'editable-address' inputclass: ''
}); });
$.fn.editabletypes.address = Address; $.fn.editabletypes.address = Address;

@ -20,9 +20,10 @@ To create your own input you can inherit from this class.
**/ **/
init: function(type, options, defaults) { init: function(type, options, defaults) {
this.type = type; this.type = type;
this.options = $.extend({}, defaults, options); this.options = $.extend({}, defaults, options);
this.$input = null; this.$tpl = null; //whole tpl as jquery object
this.$clear = null; this.$input = null; //input as jquery object
this.$clear = null; //clear button
this.error = null; this.error = null;
}, },
@ -32,14 +33,8 @@ To create your own input you can inherit from this class.
@method render() @method render()
**/ **/
render: function() { render: function() {
this.$input = $(this.options.tpl); this.$tpl = $(this.options.tpl);
if(this.options.inputclass) { this.$input = this.$tpl;
this.$input.addClass(this.options.inputclass);
}
if (this.options.placeholder) {
this.$input.attr('placeholder', this.options.placeholder);
}
}, },
/** /**

@ -44,8 +44,13 @@ $(function(){
})) }))
.append($('<span>').text(' '+this.sourceData[i].text)); .append($('<span>').text(' '+this.sourceData[i].text));
$('<div>').append($label).appendTo(this.$input); $('<div>').append($label).appendTo(this.$tpl);
} }
this.$input = this.$tpl.find('input[type="checkbox"]');
if(this.options.inputclass) {
this.$input.addClass(this.options.inputclass);
}
}, },
value2str: function(value) { value2str: function(value) {
@ -66,10 +71,9 @@ $(function(){
//set checked on required checkboxes //set checked on required checkboxes
value2input: function(value) { value2input: function(value) {
var $checks = this.$input.find('input[type="checkbox"]'); this.$input.removeAttr('checked');
$checks.removeAttr('checked');
if($.isArray(value) && value.length) { if($.isArray(value) && value.length) {
$checks.each(function(i, el) { this.$input.each(function(i, el) {
var $el = $(el); var $el = $(el);
// cannot use $.inArray as it performs strict comparison // cannot use $.inArray as it performs strict comparison
$.each(value, function(j, val){ $.each(value, function(j, val){
@ -85,7 +89,7 @@ $(function(){
input2value: function() { input2value: function() {
var checked = []; var checked = [];
this.$input.find('input:checked').each(function(i, el) { this.$input.filter(':checked').each(function(i, el) {
checked.push($(el).val()); checked.push($(el).val());
}); });
return checked; return checked;
@ -105,11 +109,11 @@ $(function(){
}, },
activate: function() { activate: function() {
this.$input.find('input[type="checkbox"]').first().focus(); this.$input.first().focus();
}, },
autosubmit: function() { autosubmit: function() {
this.$input.find('input[type="checkbox"]').on('keydown', function(e){ this.$input.on('keydown', function(e){
if (e.which === 13) { if (e.which === 13) {
$(this).closest('form').submit(); $(this).closest('form').submit();
} }
@ -122,14 +126,14 @@ $(function(){
@property tpl @property tpl
@default <div></div> @default <div></div>
**/ **/
tpl:'<div></div>', tpl:'<div class="editable-checklist"></div>',
/** /**
@property inputclass @property inputclass
@type string @type string
@default editable-checklist @default
**/ **/
inputclass: 'editable-checklist', inputclass: '',
/** /**
Separator of values when reading from 'data-value' string Separator of values when reading from 'data-value' string

@ -60,14 +60,19 @@ $(function(){
render: function () { render: function () {
Date.superclass.render.call(this); Date.superclass.render.call(this);
this.$input.datepicker(this.options.datepicker); this.$input.datepicker(this.options.datepicker);
},
postrender: function() {
//"clear" link
if(this.options.clear) { if(this.options.clear) {
this.$clear = $('<a href="#"></a>').html(this.options.clear).click($.proxy(function(e){ this.$clear = $('<a href="#"></a>').html(this.options.clear).click($.proxy(function(e){
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
this.clear(); this.clear();
}, this)); }, this));
}
this.$tpl.parent().append($('<div class="editable-clear">').append(this.$clear));
}
}, },
value2html: function(value, element) { value2html: function(value, element) {
@ -123,12 +128,12 @@ $(function(){
@property tpl @property tpl
@default <div></div> @default <div></div>
**/ **/
tpl:'<div></div>', tpl:'<div class="editable-date well"></div>',
/** /**
@property inputclass @property inputclass
@default editable-date well @default
**/ **/
inputclass: 'editable-date well', inputclass: '',
/** /**
Format used for sending value to server. Also applied when converting date from <code>data-value</code> attribute.<br> Format used for sending value to server. Also applied when converting date from <code>data-value</code> attribute.<br>
Possible tokens are: <code>d, dd, m, mm, yy, yyyy</code> Possible tokens are: <code>d, dd, m, mm, yy, yyyy</code>

@ -14,44 +14,41 @@ Automatically shown in inline mode.
$.extend(DateField.prototype, { $.extend(DateField.prototype, {
render: function () { render: function () {
this.$input = $(this.options.tpl); this.$tpl = $(this.options.tpl);
this.$field = this.$input.find('input'); this.$input = this.$tpl.find('input');
if(this.options.inputclass) { if(this.options.inputclass) {
this.$field.addClass(this.options.inputclass); this.$input.addClass(this.options.inputclass);
} }
if (this.options.placeholder) { if (this.options.placeholder) {
this.$field.attr('placeholder', this.options.placeholder); this.$input.attr('placeholder', this.options.placeholder);
} }
this.$input.datepicker(this.options.datepicker); this.$tpl.datepicker(this.options.datepicker);
//need to disable original event handlers //need to disable original event handlers
this.$field.off('focus keydown'); this.$input.off('focus keydown');
//update value of datepicker //update value of datepicker
this.$field.keyup($.proxy(function(){ this.$input.keyup($.proxy(function(){
this.$input.removeData('date'); this.$tpl.removeData('date');
this.$input.datepicker('update'); this.$tpl.datepicker('update');
}, this)); }, this));
}, },
value2input: function(value) { value2input: function(value) {
this.$field.val(value ? this.dpg.formatDate(value, this.parsedViewFormat, this.options.datepicker.language) : ''); this.$input.val(value ? this.dpg.formatDate(value, this.parsedViewFormat, this.options.datepicker.language) : '');
this.$input.datepicker('update'); this.$tpl.datepicker('update');
}, },
input2value: function() { input2value: function() {
return this.html2value(this.$field.val()); return this.html2value(this.$input.val());
}, },
activate: function() { activate: function() {
if(this.$field.is(':visible')) { $.fn.editabletypes.text.prototype.activate.call(this);
this.$field.focus();
$.fn.editableutils.setCursorPosition(this.$field.get(0), this.$field.val().length);
}
}, },
autosubmit: function() { autosubmit: function() {
@ -64,12 +61,12 @@ Automatically shown in inline mode.
@property tpl @property tpl
@default @default
**/ **/
tpl:'<div class="input-append date"><input class="input-small" type="text"/><span class="add-on"><i class="icon-th"></i></span></div>', tpl:'<div class="input-append date"><input type="text"/><span class="add-on"><i class="icon-th"></i></span></div>',
/** /**
@property inputclass @property inputclass
@default '' @default 'input-small'
**/ **/
inputclass: '', inputclass: 'input-small',
/* datepicker config */ /* datepicker config */
datepicker: { datepicker: {

@ -52,15 +52,20 @@ $(function(){
render: function () { render: function () {
DateUI.superclass.render.call(this); DateUI.superclass.render.call(this);
this.$input.datepicker(this.options.datepicker); this.$input.datepicker(this.options.datepicker);
},
postrender: function() {
//"clear" link
if(this.options.clear) { if(this.options.clear) {
this.$clear = $('<a href="#"></a>').html(this.options.clear).click($.proxy(function(e){ this.$clear = $('<a href="#"></a>').html(this.options.clear).click($.proxy(function(e){
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
this.clear(); this.clear();
}, this)); }, this));
this.$tpl.parent().append($('<div class="editable-clear">').append(this.$clear));
} }
}, },
value2html: function(value, element) { value2html: function(value, element) {
var text = $.datepicker.formatDate(this.options.viewformat, value); var text = $.datepicker.formatDate(this.options.viewformat, value);
@ -134,12 +139,12 @@ $(function(){
@property tpl @property tpl
@default <div></div> @default <div></div>
**/ **/
tpl:'<div></div>', tpl:'<div class="editable-date"></div>',
/** /**
@property inputclass @property inputclass
@default 'editable-date' @default ''
**/ **/
inputclass: 'editable-date', inputclass: '',
/** /**
Format used for sending value to server. Also applied when converting date from <code>data-value</code> attribute.<br> Format used for sending value to server. Also applied when converting date from <code>data-value</code> attribute.<br>
Full list of tokens: http://docs.jquery.com/UI/Datepicker/formatDate Full list of tokens: http://docs.jquery.com/UI/Datepicker/formatDate

@ -14,9 +14,9 @@ Automatically shown in inline mode.
$.extend(DateUIField.prototype, { $.extend(DateUIField.prototype, {
render: function () { render: function () {
$.fn.editabletypes.dateui.superclass.render.call(this); this.$tpl = $(this.options.tpl);
this.$field = this.$input.find('input'); this.$input = this.$tpl.find('input');
this.$field.datepicker(this.options.datepicker); this.$input.datepicker(this.options.datepicker);
/* /*
if(this.options.clear) { if(this.options.clear) {
@ -30,18 +30,15 @@ Automatically shown in inline mode.
}, },
value2input: function(value) { value2input: function(value) {
this.$field.val($.datepicker.formatDate(this.options.viewformat, value)); this.$input.val($.datepicker.formatDate(this.options.viewformat, value));
}, },
input2value: function() { input2value: function() {
return this.html2value(this.$field.val()); return this.html2value(this.$input.val());
}, },
activate: function() { activate: function() {
if(this.$field.is(':visible')) { $.fn.editabletypes.text.prototype.activate.call(this);
this.$field.focus();
$.fn.editableutils.setCursorPosition(this.$field.get(0), this.$field.val().length);
}
}, },
autosubmit: function() { autosubmit: function() {

@ -155,29 +155,29 @@ Range (inherit from number)
$.fn.editableutils.inherit(Range, $.fn.editabletypes.number); $.fn.editableutils.inherit(Range, $.fn.editabletypes.number);
$.extend(Range.prototype, { $.extend(Range.prototype, {
render: function () { render: function () {
this.$input = $(this.options.tpl); this.$tpl = $(this.options.tpl);
var $slider = this.$input.filter('input'); this.$input = this.$tpl.filter('input');
if(this.options.inputclass) { if(this.options.inputclass) {
$slider.addClass(this.options.inputclass); this.$input.addClass(this.options.inputclass);
} }
if (this.options.min !== null) { if (this.options.min !== null) {
$slider.attr('min', this.options.min); this.$input.attr('min', this.options.min);
} }
if (this.options.max !== null) { if (this.options.max !== null) {
$slider.attr('max', this.options.max); this.$input.attr('max', this.options.max);
} }
if (this.options.step !== null) { if (this.options.step !== null) {
$slider.attr('step', this.options.step); this.$input.attr('step', this.options.step);
} }
$slider.on('input', function(){ this.$input.on('input', function(){
$(this).siblings('output').text($(this).val()); $(this).siblings('output').text($(this).val());
}); });
}, },
activate: function() { activate: function() {
this.$input.filter('input').focus(); this.$input.focus();
} }
}); });
Range.defaults = $.extend({}, $.fn.editabletypes.number.defaults, { Range.defaults = $.extend({}, $.fn.editabletypes.number.defaults, {

@ -14,8 +14,9 @@ List - abstract class for inputs that have source option loaded from js array or
$.extend(List.prototype, { $.extend(List.prototype, {
render: function () { render: function () {
List.superclass.render.call(this);
var deferred = $.Deferred(); var deferred = $.Deferred();
this.$tpl = $(this.options.tpl);
this.$input = this.$tpl; //will be set in renderList
this.error = null; this.error = null;
this.sourceData = null; this.sourceData = null;
this.prependData = null; this.prependData = null;

@ -35,9 +35,13 @@ $(function(){
} }
for(var i=0; i<this.sourceData.length; i++) { for(var i=0; i<this.sourceData.length; i++) {
this.$input.append($('<option>', {value: this.sourceData[i].value}).text(this.sourceData[i].text)); this.$tpl.append($('<option>', {value: this.sourceData[i].value}).text(this.sourceData[i].text));
} }
if(this.options.inputclass) {
this.$input.addClass(this.options.inputclass);
}
//enter submit //enter submit
this.$input.on('keydown.editable', function (e) { this.$input.on('keydown.editable', function (e) {
if (e.which === 13) { if (e.which === 13) {

@ -23,11 +23,56 @@ $(function(){
$.fn.editableutils.inherit(Text, $.fn.editabletypes.abstractinput); $.fn.editableutils.inherit(Text, $.fn.editabletypes.abstractinput);
$.extend(Text.prototype, { $.extend(Text.prototype, {
render: function() {
Text.superclass.render.call(this);
if (this.options.clear) {
this.$clear = $('<span class="editable-clear-x"></span>');
this.$tpl = $('<div style="position: relative">')
.append(this.$input)
.append(this.$clear);
}
if(this.options.inputclass) {
this.$input.addClass(this.options.inputclass);
}
if (this.options.placeholder) {
this.$input.attr('placeholder', this.options.placeholder);
}
},
postrender: function() {
if (this.options.clear) {
var h = this.$input.parent().height() || 20;
this.$clear.css('top', (h - this.$clear.outerHeight()) / 2);
this.$input.keyup($.proxy(this.toggleClear, this));
this.$clear.click($.proxy(function(){
this.$clear.hide();
this.$input.val('').focus();
}, this));
}
},
activate: function() { activate: function() {
if(this.$input.is(':visible')) { if(this.$input.is(':visible')) {
this.$input.focus(); this.$input.focus();
$.fn.editableutils.setCursorPosition(this.$input.get(0), this.$input.val().length); $.fn.editableutils.setCursorPosition(this.$input.get(0), this.$input.val().length);
if(this.options.clear) {
this.toggleClear();
}
} }
},
//show / hide clear button
toggleClear: function() {
if(!this.options.clear) return;
if(this.$input.val()) {
this.$clear.show();
} else {
this.$clear.hide();
}
} }
}); });
@ -44,7 +89,12 @@ $(function(){
@type string @type string
@default null @default null
**/ **/
placeholder: null placeholder: null,
/**
Whether to show clear button / link or not
**/
clear: true
}); });
$.fn.editabletypes.text = Text; $.fn.editabletypes.text = Text;

@ -67,10 +67,7 @@ $(function(){
}, },
activate: function() { activate: function() {
if(this.$input.is(':visible')) { $.fn.editabletypes.text.prototype.activate.call(this);
$.fn.editableutils.setCursorPosition(this.$input.get(0), this.$input.val().length);
this.$input.focus();
}
} }
}); });