diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index c1d8d75..13df5c5 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -4,6 +4,7 @@ X-editable changelog
Version 1.3.0 wip
----------------------------
+[enh] added html5 inputs support: password, email, url, tel, number, range (vitalets)
[bug #43] fix for bootstrap 2.2.2 (vitalets)
[enh #41] 'abstract' class renamed to 'abstractinput' as abstract is reserved word (vitalets)
[enh #40] 'params' option defined as function overwrites original ajax data instead of appending (vitalets)
diff --git a/grunt.js b/grunt.js
index e7427c9..07c2d72 100644
--- a/grunt.js
+++ b/grunt.js
@@ -42,7 +42,8 @@ function getFiles() {
inputs+'text.js',
inputs+'textarea.js',
inputs+'select.js',
- inputs+'checklist.js'
+ inputs+'checklist.js',
+ inputs+'html5types.js'
];
//common css files
diff --git a/src/inputs/abstract.js b/src/inputs/abstract.js
index 9c4581b..22fd989 100644
--- a/src/inputs/abstract.js
+++ b/src/inputs/abstract.js
@@ -65,7 +65,7 @@ To create your own input you can inherit from this class.
},
/**
- Converts value to string (for comparering)
+ Converts value to string (for internal compare). For submitting to server used value2submit().
@method value2str(value)
@param {mixed} value
diff --git a/src/inputs/html5types.js b/src/inputs/html5types.js
new file mode 100644
index 0000000..73ac47a
--- /dev/null
+++ b/src/inputs/html5types.js
@@ -0,0 +1,180 @@
+/**
+HTML5 input types.
+Following types are supported:
+- password
+- email
+- url
+- tel
+- number
+- range
+
+To check browser compatibility please see:
+http://www.wufoo.com/html5/
+
+@class html5types
+@extends text
+@final
+@example
+admin@example.com
+
+**/
+
+
+/*
+Password
+*/
+(function ($) {
+ var Password = function (options) {
+ this.init('password', options, Password.defaults);
+ };
+ $.fn.editableutils.inherit(Password, $.fn.editabletypes.text);
+ $.extend(Password.prototype, {
+ //do not display password, show '[hidden]' instead
+ value2html: function(value, element) {
+ if(value) {
+ $(element).text('[hidden]');
+ } else {
+ $(element).empty();
+ }
+ },
+ //as password not displayed, should not set value by html
+ html2value: function(html) {
+ return null;
+ }
+ });
+ Password.defaults = $.extend({}, $.fn.editabletypes.text.defaults, {
+ tpl: ''
+ });
+ $.fn.editabletypes.password = Password;
+}(window.jQuery));
+
+
+/*
+Email
+*/
+(function ($) {
+ var Email = function (options) {
+ this.init('email', options, Email.defaults);
+ };
+ $.fn.editableutils.inherit(Email, $.fn.editabletypes.text);
+ Email.defaults = $.extend({}, $.fn.editabletypes.text.defaults, {
+ tpl: ''
+ });
+ $.fn.editabletypes.email = Email;
+}(window.jQuery));
+
+
+/*
+Url
+*/
+(function ($) {
+ var Url = function (options) {
+ this.init('url', options, Url.defaults);
+ };
+ $.fn.editableutils.inherit(Url, $.fn.editabletypes.text);
+ Url.defaults = $.extend({}, $.fn.editabletypes.text.defaults, {
+ tpl: ''
+ });
+ $.fn.editabletypes.url = Url;
+}(window.jQuery));
+
+
+/*
+Tel
+*/
+(function ($) {
+ var Tel = function (options) {
+ this.init('tel', options, Tel.defaults);
+ };
+ $.fn.editableutils.inherit(Tel, $.fn.editabletypes.text);
+ Tel.defaults = $.extend({}, $.fn.editabletypes.text.defaults, {
+ tpl: ''
+ });
+ $.fn.editabletypes.tel = Tel;
+}(window.jQuery));
+
+
+/*
+Number
+*/
+(function ($) {
+ var NumberInput = function (options) {
+ this.init('number', options, NumberInput.defaults);
+ };
+ $.fn.editableutils.inherit(NumberInput, $.fn.editabletypes.text);
+ $.extend(NumberInput.prototype, {
+ render: function () {
+ NumberInput.superclass.render.call(this);
+
+ if (this.options.min !== null) {
+ this.$input.attr('min', this.options.min);
+ }
+
+ if (this.options.max !== null) {
+ this.$input.attr('max', this.options.max);
+ }
+
+ if (this.options.step !== null) {
+ this.$input.attr('step', this.options.step);
+ }
+ }
+ });
+ NumberInput.defaults = $.extend({}, $.fn.editabletypes.text.defaults, {
+ tpl: '',
+ inputclass: 'input-mini',
+ min: null,
+ max: null,
+ step: null
+ });
+ $.fn.editabletypes.number = NumberInput;
+}(window.jQuery));
+
+
+/*
+Range (inherit from number)
+*/
+(function ($) {
+ var Range = function (options) {
+ this.init('range', options, Range.defaults);
+ };
+ $.fn.editableutils.inherit(Range, $.fn.editabletypes.number);
+ $.extend(Range.prototype, {
+ render: function () {
+ this.$input = $(this.options.tpl);
+ var $slider = this.$input.filter('input');
+ if(this.options.inputclass) {
+ $slider.addClass(this.options.inputclass);
+ }
+ if (this.options.min !== null) {
+ $slider.attr('min', this.options.min);
+ }
+
+ if (this.options.max !== null) {
+ $slider.attr('max', this.options.max);
+ }
+
+ if (this.options.step !== null) {
+ $slider.attr('step', this.options.step);
+ }
+
+ $slider.on('input', function(){
+ $(this).siblings('output').text($(this).val());
+ });
+ },
+ activate: function() {
+ this.$input.filter('input').focus();
+ }
+ });
+ Range.defaults = $.extend({}, $.fn.editabletypes.number.defaults, {
+ tpl: '',
+ inputclass: 'input-medium'
+ });
+ $.fn.editabletypes.range = Range;
+}(window.jQuery));
\ No newline at end of file
diff --git a/src/inputs/textarea.js b/src/inputs/textarea.js
index 72e431f..6a853b3 100644
--- a/src/inputs/textarea.js
+++ b/src/inputs/textarea.js
@@ -84,7 +84,7 @@ $(function(){
@type string
@default null
**/
- placeholder: null
+ placeholder: null
});
$.fn.editabletypes.textarea = Textarea;
diff --git a/test/loader.js b/test/loader.js
index d961fa4..5ec827a 100644
--- a/test/loader.js
+++ b/test/loader.js
@@ -33,6 +33,7 @@ define(function () {
'inputs/textarea',
'inputs/select',
'inputs/checklist',
+ 'inputs/html5types',
'inputs-ext/address/address'],
init: function(require) {
loadCss(require.toUrl("./editable-form.css"));
@@ -44,6 +45,7 @@ define(function () {
'inputs/text': ['inputs/abstract'],
'inputs/textarea': ['inputs/abstract'],
'inputs/abstract': ['editable-form/editable-form-utils'],
+ 'inputs/html5types': ['inputs/text'],
//bootstrap
'bootstrap/js/bootstrap': {
diff --git a/test/unit/text.js b/test/unit/text.js
index e8e81fe..17d692c 100644
--- a/test/unit/text.js
+++ b/test/unit/text.js
@@ -438,6 +438,67 @@ $(function () {
start();
}, timeout);
- });
+ });
+
+ test("password", function () {
+ var v = '123', v1 = '456';
+
+ var e = $('').appendTo('#qunit-fixture').editable({
+ type: 'password',
+ url: function(params) {
+ equal(params.value, v1, 'submitted value correct');
+ }
+ });
+
+ equal(e.text(), '[hidden]', 'text is hidden');
+
+ e.click()
+ var p = tip(e);
+ ok(p.is(':visible'), 'popover visible');
+ var $input = p.find('input[type="password"]');
+ ok($input.length, 'input exists');
+ equal($input.val(), v, 'input contains correct value');
+ $input.val(v1);
+ p.find('form').submit();
+
+ ok(!p.is(':visible'), 'popover closed');
+ equal(e.data('editable').value, v1, 'new value saved to value');
+ equal(e.text(), '[hidden]', 'new text shown');
+ });
+
+
+ test("html5 types", function () {
+
+ var types = ['email', 'url', 'tel', 'number', 'range'],
+ v = '12',
+ v1 = '45';
+
+ expect(8*types.length);
+
+ for(var i = 0; i< types.length; i++) {
+ var e = $(''+v+'').appendTo('#qunit-fixture').editable({
+ type: types[i],
+ url: function(params) {
+ equal(params.value, v1, 'submitted value correct');
+ }
+ });
+
+ equal(e.data('editable').value, v, 'value correct');
+
+ e.click()
+ var p = tip(e);
+ ok(p.is(':visible'), 'popover visible');
+ var $input = p.find('input[type='+types[i]+']');
+ ok($input.length, 'input exists');
+ equal($input.val(), v, 'input contain correct value');
+ $input.val(v1);
+ p.find('form').submit();
+
+ ok(!p.is(':visible'), 'popover closed');
+ equal(e.data('editable').value, v1, 'new value saved to value');
+ equal(e.text(), v1, 'new text shown');
+ }
+
+ });
});
\ No newline at end of file