Merge branch 'release-1.3.0'
This commit is contained in:
commit
69a4ad5393
CHANGELOG.txtgrunt.jspackage.json
src
containers
editable-form
element
inputs-ext/address
inputs
test
@ -2,6 +2,21 @@ X-editable changelog
|
||||
=============================
|
||||
|
||||
|
||||
Version 1.3.0 Dec 10, 2012
|
||||
----------------------------
|
||||
[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)
|
||||
[bug] datepicker: error when click on arrows after clear date (vitalets)
|
||||
[enh] 'hidden' event: added possible value of reason param - 'nochange'. Occurs when form is submitted but value was not changed (vitalets)
|
||||
[enh] 'submit' method changed: error-callback's parameter simplified (vitalets)
|
||||
[enh] 'submit' method changed: now when response 200 OK it does not set pk automatically (vitalets)
|
||||
[enh] 'submit' method changed: removed dataType='json'. Use 'ajaxOptions' to specify dataType if needed (vitalets)
|
||||
[enh] removed default ajax dataType='json'. Use 'ajaxOptions' to specify dataType if needed (vitalets)
|
||||
[enh] select: do not show 'sourceError' in element during autotext execution (vitalets)
|
||||
|
||||
|
||||
Version 1.2.0 Dec 6, 2012
|
||||
----------------------------
|
||||
[enh #36] 'submit' method: added 'ajaxOptions' property to modify ajax request (vitalets)
|
||||
|
3
grunt.js
3
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
|
||||
|
@ -2,7 +2,7 @@
|
||||
"name": "X-editable",
|
||||
"title": "X-editable",
|
||||
"description": "In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery",
|
||||
"version": "1.2.0",
|
||||
"version": "1.3.0",
|
||||
"homepage": "http://github.com/vitalets/x-editable",
|
||||
"author": {
|
||||
"name": "Vitaliy Potapov",
|
||||
|
@ -8,7 +8,8 @@
|
||||
}
|
||||
|
||||
.editable-container.editable-inline {
|
||||
display: inline;
|
||||
/* display: inline; */ /* display: inline does not correctly work with show()/hide() in jquery <= 1.7.2 */
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
@ -80,9 +80,8 @@ Applied as jQuery method.
|
||||
.editableform(this.formOptions)
|
||||
.on({
|
||||
save: $.proxy(this.save, this),
|
||||
cancel: $.proxy(function(){
|
||||
this.hide('cancel');
|
||||
}, this),
|
||||
cancel: $.proxy(function(){ this.hide('cancel'); }, this),
|
||||
nochange: $.proxy(function(){ this.hide('nochange'); }, this),
|
||||
show: $.proxy(this.setPosition, this), //re-position container every time form is shown (occurs each time after loading state)
|
||||
rendering: $.proxy(this.setPosition, this), //this allows to place container correctly when loading shown
|
||||
rendered: $.proxy(function(){
|
||||
@ -146,7 +145,7 @@ Applied as jQuery method.
|
||||
/**
|
||||
Hides container with form
|
||||
@method hide()
|
||||
@param {string} reason Reason caused hiding. Can be <code>save|cancel|onblur|undefined (=manual)</code>
|
||||
@param {string} reason Reason caused hiding. Can be <code>save|cancel|onblur|nochange|undefined (=manual)</code>
|
||||
**/
|
||||
hide: function(reason) {
|
||||
if(!this.tip() || !this.tip().is(':visible') || !this.$element.hasClass('editable-open')) {
|
||||
@ -159,7 +158,7 @@ Applied as jQuery method.
|
||||
|
||||
@event hidden
|
||||
@param {object} event event object
|
||||
@param {string} reason Reason caused hiding. Can be <code>save|cancel|onblur|undefined (=manual)</code>
|
||||
@param {string} reason Reason caused hiding. Can be <code>save|cancel|onblur|nochange|undefined (=manual)</code>
|
||||
@example
|
||||
$('#username').on('hidden', function(e, reason) {
|
||||
if(reason === 'save' || reason === 'cancel') {
|
||||
|
@ -8,7 +8,8 @@
|
||||
//extend methods
|
||||
$.extend($.fn.editableContainer.Constructor.prototype, {
|
||||
containerName: 'popover',
|
||||
innerCss: '.popover-content p',
|
||||
//for compatibility with bootstrap <= 2.2.1 (content inserted into <p> instead of directly .popover-content)
|
||||
innerCss: $($.fn.popover.defaults.template).find('p').length ? '.popover-content p' : '.popover-content',
|
||||
|
||||
initContainer: function(){
|
||||
$.extend(this.containerOptions, {
|
||||
|
@ -53,6 +53,7 @@
|
||||
max-width: 300px;
|
||||
margin: 5px 0 0 0;
|
||||
width: auto;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
/*add padding for jquery ui*/
|
||||
|
@ -179,11 +179,16 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
|
||||
return;
|
||||
}
|
||||
|
||||
//if value not changed --> cancel
|
||||
//if value not changed --> trigger 'nochange' event and return
|
||||
/*jslint eqeq: true*/
|
||||
if (!this.options.savenochange && this.input.value2str(newValue) == this.input.value2str(this.value)) {
|
||||
/*jslint eqeq: false*/
|
||||
this.cancel();
|
||||
/**
|
||||
Fired when value not changed but form is submitted. Requires savenochange = false.
|
||||
@event nochange
|
||||
@param {Object} event event object
|
||||
**/
|
||||
this.$div.triggerHandler('nochange');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -259,7 +264,7 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
|
||||
|
||||
//additional params
|
||||
if(typeof this.options.params === 'function') {
|
||||
$.extend(params, this.options.params.call(this.options.scope, params));
|
||||
params = this.options.params.call(this.options.scope, params);
|
||||
} else {
|
||||
//try parse json in single quotes (from data-params attribute)
|
||||
this.options.params = $.fn.editableutils.tryParseJson(this.options.params, true);
|
||||
@ -273,8 +278,7 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
|
||||
return $.ajax($.extend({
|
||||
url : this.options.url,
|
||||
data : params,
|
||||
type : 'post',
|
||||
dataType: 'json'
|
||||
type : 'POST'
|
||||
}, this.options.ajaxOptions));
|
||||
}
|
||||
}
|
||||
@ -371,10 +375,13 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
|
||||
**/
|
||||
url:null,
|
||||
/**
|
||||
Additional params for submit. Function can be used to calculate params dynamically
|
||||
Additional params for submit. If defined as <code>object</code> - it is **appended** to original ajax data (pk, name and value).
|
||||
If defined as <code>function</code> - returned object **overwrites** original ajax data.
|
||||
@example
|
||||
params: function(params) {
|
||||
return { a: 1 };
|
||||
//originally params contain pk, name and value
|
||||
params.a = 1;
|
||||
return params;
|
||||
}
|
||||
|
||||
@property params
|
||||
@ -447,7 +454,7 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
|
||||
if(!response.success) return response.msg;
|
||||
}
|
||||
**/
|
||||
success: function(response, newValue) {},
|
||||
success: null,
|
||||
/**
|
||||
Additional options for ajax request.
|
||||
List of values: http://api.jquery.com/jQuery.ajax
|
||||
|
@ -250,9 +250,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
||||
value: this.value
|
||||
});
|
||||
this.$element.editableContainer(containerOptions);
|
||||
this.$element.on({
|
||||
save: $.proxy(this.save, this)
|
||||
});
|
||||
this.$element.on("save.internal", $.proxy(this.save, this));
|
||||
this.container = this.$element.data('editableContainer');
|
||||
} else if(this.container.tip().is(':visible')) {
|
||||
return;
|
||||
@ -422,16 +420,17 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
||||
return result;
|
||||
|
||||
/**
|
||||
This method collects values from several editable elements and submit them all to server.
|
||||
It is designed mainly for <a href="#newrecord">creating new records</a>.
|
||||
This method collects values from several editable elements and submit them all to server.
|
||||
Internally it runs client-side validation for all fields and submits only in case of success.
|
||||
See <a href="#newrecord">creating new records</a> for details.
|
||||
|
||||
@method submit(options)
|
||||
@param {object} options
|
||||
@param {object} options.url url to submit data
|
||||
@param {object} options.data additional data to submit
|
||||
@param {object} options.ajaxOptions additional ajax options
|
||||
@param {function} options.error(obj) error handler (called on both client-side and server-side validation errors)
|
||||
@param {function} options.success(obj) success handler
|
||||
@param {function} options.error(obj) error handler
|
||||
@param {function} options.success(obj,config) success handler
|
||||
@returns {Object} jQuery object
|
||||
**/
|
||||
case 'submit': //collects value, validate and submit to server for creating new record
|
||||
@ -449,22 +448,13 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
||||
$.ajax($.extend({
|
||||
url: config.url,
|
||||
data: values,
|
||||
type: 'POST',
|
||||
dataType: 'json'
|
||||
type: 'POST'
|
||||
}, config.ajaxOptions))
|
||||
.success(function(response) {
|
||||
//successful response
|
||||
if(typeof response === 'object' && response.id) {
|
||||
$elems.editable('option', 'pk', response.id);
|
||||
$elems.removeClass('editable-unsaved');
|
||||
if(typeof config.success === 'function') {
|
||||
config.success.apply($elems, arguments);
|
||||
}
|
||||
} else { //server-side validation error
|
||||
if(typeof config.error === 'function') {
|
||||
config.error.apply($elems, arguments);
|
||||
}
|
||||
}
|
||||
//successful response 200 OK
|
||||
if(typeof config.success === 'function') {
|
||||
config.success.call($elems, response, config);
|
||||
}
|
||||
})
|
||||
.error(function(){ //ajax error
|
||||
if(typeof config.error === 'function') {
|
||||
@ -473,7 +463,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
||||
});
|
||||
} else { //client-side validation error
|
||||
if(typeof config.error === 'function') {
|
||||
config.error.call($elems, {errors: errors});
|
||||
config.error.call($elems, errors);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
@ -577,4 +567,4 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
||||
display: null
|
||||
};
|
||||
|
||||
}(window.jQuery));
|
||||
}(window.jQuery));
|
||||
|
@ -3,7 +3,7 @@ Address editable input.
|
||||
Internally value stored as {city: "Moscow", street: "Lenina", building: "15"}
|
||||
|
||||
@class address
|
||||
@extends abstract
|
||||
@extends abstractinput
|
||||
@final
|
||||
@example
|
||||
<a href="#" id="address" data-type="address" data-pk="1">awesome</a>
|
||||
@ -26,14 +26,24 @@ $(function(){
|
||||
this.init('address', options, Address.defaults);
|
||||
};
|
||||
|
||||
$.fn.editableutils.inherit(Address, $.fn.editabletypes.abstract);
|
||||
//inherit from Abstract input
|
||||
$.fn.editableutils.inherit(Address, $.fn.editabletypes.abstractinput);
|
||||
|
||||
$.extend(Address.prototype, {
|
||||
render: function() {
|
||||
Address.superclass.render.call(this);
|
||||
},
|
||||
/**
|
||||
Renders input from tpl
|
||||
|
||||
@method render()
|
||||
**/
|
||||
render: function() {
|
||||
Address.superclass.render.call(this);
|
||||
},
|
||||
|
||||
//standard way to show value in element. Used only if display option not defined.
|
||||
/**
|
||||
Default method to show value in element. Can be overwritten by display option.
|
||||
|
||||
@method value2html(value, element)
|
||||
**/
|
||||
value2html: function(value, element) {
|
||||
if(!value) {
|
||||
$(element).empty();
|
||||
@ -43,12 +53,17 @@ $(function(){
|
||||
$(element).html(html);
|
||||
},
|
||||
|
||||
/**
|
||||
Gets value from element's html
|
||||
|
||||
@method html2value(html)
|
||||
**/
|
||||
html2value: function(html) {
|
||||
/*
|
||||
you may write parsing method to get value by element's html
|
||||
e.g. "Moscow, st. Lenina, bld. 15" => {city: "Moscow", street: "Lenina", building: "15"}
|
||||
but for complex structures I do not recommend do that.
|
||||
Better always set value directly via javascript, e.g.
|
||||
but for complex structures it's not recommended.
|
||||
Better set value directly via javascript, e.g.
|
||||
editable({
|
||||
value: {
|
||||
city: "Moscow",
|
||||
@ -60,10 +75,12 @@ $(function(){
|
||||
return null;
|
||||
},
|
||||
|
||||
/*
|
||||
converts value to string.
|
||||
/**
|
||||
Converts value to string.
|
||||
It is used in internal comparing (not for sending to server).
|
||||
*/
|
||||
|
||||
@method value2str(value)
|
||||
**/
|
||||
value2str: function(value) {
|
||||
var str = '';
|
||||
if(value) {
|
||||
@ -75,19 +92,35 @@ $(function(){
|
||||
},
|
||||
|
||||
/*
|
||||
this is mainly for parsing value defined in data-value attribute.
|
||||
If you will always set value by javascript, no need to overwrite it
|
||||
Converts string to value. Used for reading value from 'data-value' attribute.
|
||||
|
||||
@method str2value(str)
|
||||
*/
|
||||
str2value: function(str) {
|
||||
/*
|
||||
this is mainly for parsing value defined in data-value attribute.
|
||||
If you will always set value by javascript, no need to overwrite it
|
||||
*/
|
||||
return str;
|
||||
},
|
||||
|
||||
/**
|
||||
Sets value of input.
|
||||
|
||||
@method value2input(value)
|
||||
@param {mixed} value
|
||||
**/
|
||||
value2input: function(value) {
|
||||
this.$input.find('input[name="city"]').val(value.city);
|
||||
this.$input.find('input[name="street"]').val(value.street);
|
||||
this.$input.find('input[name="building"]').val(value.building);
|
||||
},
|
||||
|
||||
/**
|
||||
Returns value of input.
|
||||
|
||||
@method input2value()
|
||||
**/
|
||||
input2value: function() {
|
||||
return {
|
||||
city: this.$input.find('input[name="city"]').val(),
|
||||
@ -95,14 +128,31 @@ $(function(){
|
||||
building: this.$input.find('input[name="building"]').val()
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
Activates input: sets focus on the first field.
|
||||
|
||||
@method activate()
|
||||
**/
|
||||
activate: function() {
|
||||
//set focus on city
|
||||
this.$input.find('input[name="city"]').focus();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Attaches handler to submit form in case of 'showbuttons=false' mode
|
||||
|
||||
@method autosubmit()
|
||||
**/
|
||||
autosubmit: function() {
|
||||
this.$input.find('input[type="text"]').keydown(function (e) {
|
||||
if (e.which === 13) {
|
||||
$(this).closest('form').submit();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Address.defaults = $.extend({}, $.fn.editabletypes.abstract.defaults, {
|
||||
Address.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
|
||||
tpl: '<div><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><label><span>Building: </span><input type="text" name="building" class="input-mini"></label></div>',
|
||||
|
@ -1,17 +1,18 @@
|
||||
/**
|
||||
Abstract editable input class.
|
||||
To create your own input you should inherit from this class.
|
||||
AbstractInput - base class for all editable inputs.
|
||||
It defines interface to be implemented by any input type.
|
||||
To create your own input you can inherit from this class.
|
||||
|
||||
@class abstract
|
||||
@class abstractinput
|
||||
**/
|
||||
(function ($) {
|
||||
|
||||
//types
|
||||
$.fn.editabletypes = {};
|
||||
|
||||
var Abstract = function () { };
|
||||
var AbstractInput = function () { };
|
||||
|
||||
Abstract.prototype = {
|
||||
AbstractInput.prototype = {
|
||||
/**
|
||||
Initializes input
|
||||
|
||||
@ -26,7 +27,7 @@ To create your own input you should inherit from this class.
|
||||
},
|
||||
|
||||
/**
|
||||
Renders input. Can return jQuery deferred object.
|
||||
Renders input from tpl. Can return jQuery deferred object.
|
||||
|
||||
@method render()
|
||||
**/
|
||||
@ -64,7 +65,7 @@ To create your own input you should 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
|
||||
@ -150,7 +151,7 @@ To create your own input you should inherit from this class.
|
||||
}
|
||||
};
|
||||
|
||||
Abstract.defaults = {
|
||||
AbstractInput.defaults = {
|
||||
/**
|
||||
HTML template of input. Normally you should not change it.
|
||||
|
||||
@ -177,6 +178,6 @@ To create your own input you should inherit from this class.
|
||||
name: null
|
||||
};
|
||||
|
||||
$.extend($.fn.editabletypes, {abstract: Abstract});
|
||||
$.extend($.fn.editabletypes, {abstractinput: AbstractInput});
|
||||
|
||||
}(window.jQuery));
|
||||
}(window.jQuery));
|
||||
|
@ -286,7 +286,7 @@
|
||||
startMonth = this.startDate !== -Infinity ? this.startDate.getUTCMonth() : -Infinity,
|
||||
endYear = this.endDate !== Infinity ? this.endDate.getUTCFullYear() : Infinity,
|
||||
endMonth = this.endDate !== Infinity ? this.endDate.getUTCMonth() : Infinity,
|
||||
currentDate = this.date.valueOf(),
|
||||
currentDate = this.date && this.date.valueOf(),
|
||||
today = new Date();
|
||||
this.picker.find('.datepicker-days thead th:eq(1)')
|
||||
.text(dates[this.language].months[month]+' '+year);
|
||||
@ -321,7 +321,7 @@
|
||||
prevMonth.getUTCDate() == today.getDate()) {
|
||||
clsName += ' today';
|
||||
}
|
||||
if (prevMonth.valueOf() == currentDate) {
|
||||
if (currentDate && prevMonth.valueOf() == currentDate) {
|
||||
clsName += ' active';
|
||||
}
|
||||
if (prevMonth.valueOf() < this.startDate || prevMonth.valueOf() > this.endDate) {
|
||||
@ -334,14 +334,14 @@
|
||||
prevMonth.setUTCDate(prevMonth.getUTCDate()+1);
|
||||
}
|
||||
this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
|
||||
var currentYear = this.date.getUTCFullYear();
|
||||
var currentYear = this.date && this.date.getUTCFullYear();
|
||||
|
||||
var months = this.picker.find('.datepicker-months')
|
||||
.find('th:eq(1)')
|
||||
.text(year)
|
||||
.end()
|
||||
.find('span').removeClass('active');
|
||||
if (currentYear == year) {
|
||||
if (currentYear && currentYear == year) {
|
||||
months.eq(this.date.getUTCMonth()).addClass('active');
|
||||
}
|
||||
if (year < startYear || year > endYear) {
|
||||
|
@ -4,7 +4,7 @@ Description and examples: http://vitalets.github.com/bootstrap-datepicker.
|
||||
For localization you can include js file from here: https://github.com/eternicode/bootstrap-datepicker/tree/master/js/locales
|
||||
|
||||
@class date
|
||||
@extends abstract
|
||||
@extends abstractinput
|
||||
@final
|
||||
@example
|
||||
<a href="#" id="dob" data-type="date" data-pk="1" data-url="/post" data-original-title="Select date">15/05/1984</a>
|
||||
@ -48,7 +48,7 @@ $(function(){
|
||||
this.parsedViewFormat = this.dpg.parseFormat(this.options.viewformat);
|
||||
};
|
||||
|
||||
$.fn.editableutils.inherit(Date, $.fn.editabletypes.abstract);
|
||||
$.fn.editableutils.inherit(Date, $.fn.editabletypes.abstractinput);
|
||||
|
||||
$.extend(Date.prototype, {
|
||||
render: function () {
|
||||
@ -112,7 +112,7 @@ $(function(){
|
||||
|
||||
});
|
||||
|
||||
Date.defaults = $.extend({}, $.fn.editabletypes.abstract.defaults, {
|
||||
Date.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
|
||||
/**
|
||||
@property tpl
|
||||
@default <div></div>
|
||||
|
@ -4,7 +4,7 @@ Description and examples: http://jqueryui.com/datepicker.
|
||||
This input is also accessible as **date** type. Do not use it together with __bootstrap-datepicker__ as both apply <code>$().datepicker()</code> method.
|
||||
|
||||
@class dateui
|
||||
@extends abstract
|
||||
@extends abstractinput
|
||||
@final
|
||||
@example
|
||||
<a href="#" id="dob" data-type="date" data-pk="1" data-url="/post" data-original-title="Select date">15/05/1984</a>
|
||||
@ -46,7 +46,7 @@ $(function(){
|
||||
this.options.datepicker.dateFormat = this.options.datepicker.format;
|
||||
};
|
||||
|
||||
$.fn.editableutils.inherit(DateUI, $.fn.editabletypes.abstract);
|
||||
$.fn.editableutils.inherit(DateUI, $.fn.editabletypes.abstractinput);
|
||||
|
||||
$.extend(DateUI.prototype, {
|
||||
render: function () {
|
||||
@ -129,7 +129,7 @@ $(function(){
|
||||
|
||||
});
|
||||
|
||||
DateUI.defaults = $.extend({}, $.fn.editabletypes.abstract.defaults, {
|
||||
DateUI.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
|
||||
/**
|
||||
@property tpl
|
||||
@default <div></div>
|
||||
|
188
src/inputs/html5types.js
Normal file
188
src/inputs/html5types.js
Normal file
@ -0,0 +1,188 @@
|
||||
/**
|
||||
HTML5 input types.
|
||||
Following types are supported:
|
||||
|
||||
* password
|
||||
* email
|
||||
* url
|
||||
* tel
|
||||
* number
|
||||
* range
|
||||
|
||||
Learn more about html5 inputs:
|
||||
http://www.w3.org/wiki/HTML5_form_additions
|
||||
To check browser compatibility please see:
|
||||
https://developer.mozilla.org/en-US/docs/HTML/Element/Input
|
||||
|
||||
@class html5types
|
||||
@extends text
|
||||
@final
|
||||
@since 1.3.0
|
||||
@example
|
||||
<a href="#" id="email" data-type="email" data-pk="1">admin@example.com</a>
|
||||
<script>
|
||||
$(function(){
|
||||
$('#email').editable({
|
||||
url: '/post',
|
||||
title: 'Enter email'
|
||||
});
|
||||
});
|
||||
</script>
|
||||
**/
|
||||
|
||||
/**
|
||||
@property tpl
|
||||
@default depends on type
|
||||
**/
|
||||
|
||||
/*
|
||||
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: '<input type="password">'
|
||||
});
|
||||
$.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: '<input type="email">'
|
||||
});
|
||||
$.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: '<input type="url">'
|
||||
});
|
||||
$.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: '<input type="tel">'
|
||||
});
|
||||
$.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: '<input type="number">',
|
||||
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: '<input type="range"><output style="width: 30px; display: inline-block"></output>',
|
||||
inputclass: 'input-medium'
|
||||
});
|
||||
$.fn.editabletypes.range = Range;
|
||||
}(window.jQuery));
|
@ -2,7 +2,7 @@
|
||||
List - abstract class for inputs that have source option loaded from js array or via ajax
|
||||
|
||||
@class list
|
||||
@extends abstract
|
||||
@extends abstractinput
|
||||
**/
|
||||
(function ($) {
|
||||
|
||||
@ -10,7 +10,7 @@ List - abstract class for inputs that have source option loaded from js array or
|
||||
|
||||
};
|
||||
|
||||
$.fn.editableutils.inherit(List, $.fn.editabletypes.abstract);
|
||||
$.fn.editableutils.inherit(List, $.fn.editabletypes.abstractinput);
|
||||
|
||||
$.extend(List.prototype, {
|
||||
render: function () {
|
||||
@ -45,7 +45,7 @@ List - abstract class for inputs that have source option loaded from js array or
|
||||
}
|
||||
deferred.resolve();
|
||||
}, function () {
|
||||
List.superclass.value2html(this.options.sourceError, element);
|
||||
//do nothing with element
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
@ -237,7 +237,7 @@ List - abstract class for inputs that have source option loaded from js array or
|
||||
|
||||
});
|
||||
|
||||
List.defaults = $.extend({}, $.fn.editabletypes.abstract.defaults, {
|
||||
List.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
|
||||
/**
|
||||
Source data for list. If string - considered ajax url to load items. Otherwise should be an array.
|
||||
Array format is: <code>[{value: 1, text: "text"}, {...}]</code><br>
|
||||
|
@ -2,7 +2,7 @@
|
||||
Text input
|
||||
|
||||
@class text
|
||||
@extends abstract
|
||||
@extends abstractinput
|
||||
@final
|
||||
@example
|
||||
<a href="#" id="username" data-type="text" data-pk="1">awesome</a>
|
||||
@ -20,7 +20,7 @@ $(function(){
|
||||
this.init('text', options, Text.defaults);
|
||||
};
|
||||
|
||||
$.fn.editableutils.inherit(Text, $.fn.editabletypes.abstract);
|
||||
$.fn.editableutils.inherit(Text, $.fn.editabletypes.abstractinput);
|
||||
|
||||
$.extend(Text.prototype, {
|
||||
activate: function() {
|
||||
@ -31,7 +31,7 @@ $(function(){
|
||||
}
|
||||
});
|
||||
|
||||
Text.defaults = $.extend({}, $.fn.editabletypes.abstract.defaults, {
|
||||
Text.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
|
||||
/**
|
||||
@property tpl
|
||||
@default <input type="text">
|
||||
|
@ -2,7 +2,7 @@
|
||||
Textarea input
|
||||
|
||||
@class textarea
|
||||
@extends abstract
|
||||
@extends abstractinput
|
||||
@final
|
||||
@example
|
||||
<a href="#" id="comments" data-type="textarea" data-pk="1">awesome comment!</a>
|
||||
@ -21,7 +21,7 @@ $(function(){
|
||||
this.init('textarea', options, Textarea.defaults);
|
||||
};
|
||||
|
||||
$.fn.editableutils.inherit(Textarea, $.fn.editabletypes.abstract);
|
||||
$.fn.editableutils.inherit(Textarea, $.fn.editabletypes.abstractinput);
|
||||
|
||||
$.extend(Textarea.prototype, {
|
||||
render: function () {
|
||||
@ -66,7 +66,7 @@ $(function(){
|
||||
}
|
||||
});
|
||||
|
||||
Textarea.defaults = $.extend({}, $.fn.editabletypes.abstract.defaults, {
|
||||
Textarea.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
|
||||
/**
|
||||
@property tpl
|
||||
@default <textarea></textarea>
|
||||
@ -84,7 +84,7 @@ $(function(){
|
||||
@type string
|
||||
@default null
|
||||
**/
|
||||
placeholder: null
|
||||
placeholder: null
|
||||
});
|
||||
|
||||
$.fn.editabletypes.textarea = Textarea;
|
||||
|
1092
test/libs/bootstrap222/css/bootstrap-responsive.css
vendored
Normal file
1092
test/libs/bootstrap222/css/bootstrap-responsive.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
9
test/libs/bootstrap222/css/bootstrap-responsive.min.css
vendored
Normal file
9
test/libs/bootstrap222/css/bootstrap-responsive.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
6039
test/libs/bootstrap222/css/bootstrap.css
vendored
Normal file
6039
test/libs/bootstrap222/css/bootstrap.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
9
test/libs/bootstrap222/css/bootstrap.min.css
vendored
Normal file
9
test/libs/bootstrap222/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
test/libs/bootstrap222/img/glyphicons-halflings-white.png
Normal file
BIN
test/libs/bootstrap222/img/glyphicons-halflings-white.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 8.6 KiB |
BIN
test/libs/bootstrap222/img/glyphicons-halflings.png
Normal file
BIN
test/libs/bootstrap222/img/glyphicons-halflings.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 12 KiB |
2159
test/libs/bootstrap222/js/bootstrap.js
vendored
Normal file
2159
test/libs/bootstrap222/js/bootstrap.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
test/libs/bootstrap222/js/bootstrap.min.js
vendored
Normal file
6
test/libs/bootstrap222/js/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -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': {
|
||||
@ -145,7 +147,8 @@ define(function () {
|
||||
return {
|
||||
baseUrl: baseUrl,
|
||||
paths: {
|
||||
"bootstrap": "../test/libs/bootstrap221",
|
||||
// "bootstrap": "../test/libs/bootstrap221",
|
||||
"bootstrap": "../test/libs/bootstrap222",
|
||||
"jqueryui": "../test/libs/jquery-ui-1.9.1.custom",
|
||||
"poshytip": "../test/libs/poshytip",
|
||||
"test": "../test"
|
||||
|
39
test/main.js
39
test/main.js
@ -4,30 +4,41 @@ var jqver = decodeURIComponent((new RegExp('[?|&]' + 'jquery' + '=' + '([^&;]+?)
|
||||
|
||||
require(["loader", jqurl], function(loader) {
|
||||
|
||||
requirejs.config(loader.getConfig("../src"));
|
||||
var config = loader.getConfig("../src"),
|
||||
params = loader.getParams();
|
||||
|
||||
//add test specific dependencies
|
||||
config.shim['test/mocks'] = ['element/editable-element', 'test/libs/mockjax/jquery.mockjax'];
|
||||
|
||||
//as we need to keep order of tests, create shim dependencies automatically
|
||||
addTests(config);
|
||||
|
||||
requirejs.config(config);
|
||||
|
||||
require(['element/editable-element',
|
||||
'test/libs/mockjax/jquery.mockjax'
|
||||
],
|
||||
require(['test/unit/api'],
|
||||
function() {
|
||||
//disable effects
|
||||
$.fx.off = true;
|
||||
$.support.transition = false;
|
||||
|
||||
var params = loader.getParams();
|
||||
|
||||
require([
|
||||
QUnit.load();
|
||||
QUnit.start();
|
||||
});
|
||||
|
||||
function addTests(config) {
|
||||
var tests = [
|
||||
'test/mocks',
|
||||
'test/unit/common',
|
||||
'test/unit/text',
|
||||
'test/unit/textarea',
|
||||
'test/unit/select',
|
||||
'test/unit/checklist',
|
||||
'test/unit/api',
|
||||
(params.f === 'bootstrap') ? 'test/unit/date' : 'test/unit/dateui'
|
||||
], function() {
|
||||
QUnit.load();
|
||||
QUnit.start();
|
||||
});
|
||||
});
|
||||
(params.f === 'bootstrap') ? 'test/unit/date' : 'test/unit/dateui',
|
||||
'test/unit/api'
|
||||
];
|
||||
|
||||
for(var i=0; i<tests.length-1; i++) {
|
||||
config.shim[tests[i+1]] = [tests[i]];
|
||||
}
|
||||
}
|
||||
});
|
@ -57,7 +57,7 @@ $(function () {
|
||||
|
||||
});
|
||||
|
||||
// useful functions
|
||||
// usefull functions
|
||||
|
||||
function tip(e) {
|
||||
return e.data('editableContainer').tip();
|
||||
|
@ -79,8 +79,8 @@ $(function () {
|
||||
e.editable();
|
||||
});
|
||||
|
||||
asyncTest("events: shown / hidden (reason: cancel, onblur, manual)", function () {
|
||||
expect(11);
|
||||
asyncTest("events: shown / hidden (reason: cancel, onblur, nochange, manual)", function () {
|
||||
expect(15);
|
||||
var val = '1', test_reason,
|
||||
e = $('<a href="#" data-pk="1" data-type="select" data-url="post.php" data-name="text" data-value="'+val+'"></a>').appendTo(fx);
|
||||
|
||||
@ -113,6 +113,13 @@ $(function () {
|
||||
e.parent().click();
|
||||
ok(!p.is(':visible'), 'popover closed');
|
||||
|
||||
test_reason = 'nochange'
|
||||
e.click();
|
||||
p = tip(e);
|
||||
ok(p.is(':visible'), 'popover shown');
|
||||
p.find('form').submit(); //submit value without changes
|
||||
ok(!p.is(':visible'), 'popover closed');
|
||||
|
||||
test_reason = 'manual'
|
||||
e.click();
|
||||
p = tip(e);
|
||||
@ -152,9 +159,8 @@ $(function () {
|
||||
e.remove();
|
||||
start();
|
||||
}, timeout);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
test("show/hide/toggle methods", function () {
|
||||
var e = $('<a href="#" data-pk="1" data-url="post.php" data-name="text1">abc</a>').appendTo('#qunit-fixture').editable();
|
||||
e.editable('show');
|
||||
@ -212,16 +218,16 @@ $(function () {
|
||||
equal(e.text(), 'abcd', 'text set correctly (by object)');
|
||||
});
|
||||
|
||||
asyncTest("'submit' method: client and server validation", function () {
|
||||
asyncTest("'submit' method: client and server validation errors", function () {
|
||||
var ev1 = 'ev1',
|
||||
ev2 = 'ev2',
|
||||
e1v = 'e1v',
|
||||
e = $('<a href="#" class="new" data-type="text" data-url="post.php" data-name="text">'+ev1+'</a>').appendTo(fx).editable({
|
||||
e = $('<a href="#" class="new-val" data-type="text" data-url="post.php" data-name="text">'+ev1+'</a>').appendTo(fx).editable({
|
||||
validate: function(value) {
|
||||
if(value == ev1) return 'invalid';
|
||||
}
|
||||
}),
|
||||
e1 = $('<a href="#" class="new" data-type="text" data-name="text1">'+e1v+'</a>').appendTo(fx).editable();
|
||||
e1 = $('<a href="#" class="new-val" data-type="text" data-name="text1">'+e1v+'</a>').appendTo(fx).editable();
|
||||
|
||||
$.mockjax({
|
||||
url: 'new-error.php',
|
||||
@ -236,49 +242,71 @@ $(function () {
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
$(fx).find('.new').editable('submit', {
|
||||
|
||||
$.mockjax({
|
||||
url: 'new.php',
|
||||
error: function(data) {
|
||||
ok(data.errors, 'errors defined');
|
||||
equal(data.errors.text, 'invalid', 'client validation error ok');
|
||||
response: function(settings) {
|
||||
ok(false, 'should not submit to new.php');
|
||||
}
|
||||
});
|
||||
|
||||
$(fx).find('.new-val').editable('submit', {
|
||||
url: 'new.php',
|
||||
error: function(errors) {
|
||||
equal(errors.text, 'invalid', 'client validation error ok');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//change value to pass client side validation
|
||||
e.click();
|
||||
var p = tip(e);
|
||||
p.find('input[type=text]').val(ev2);
|
||||
p.find('button[type=submit]').click();
|
||||
|
||||
$(fx).find('.new').editable('submit', {
|
||||
$(fx).find('.new-val').editable('submit', {
|
||||
url: 'new-error.php',
|
||||
data: {a: 123},
|
||||
error: function(data) {
|
||||
equal(data.errors.text1, 'server-invalid', 'server validation error ok');
|
||||
e.remove();
|
||||
e1.remove();
|
||||
start();
|
||||
success: function(data, config) {
|
||||
ok(data.errors, 'errors received from server');
|
||||
ok(typeof config.error === 'function', 'config passed correctly');
|
||||
|
||||
if(data && data.id) {
|
||||
//success
|
||||
} else if(data && data.errors){
|
||||
config.error.call(this, data.errors); //call error from success
|
||||
}
|
||||
},
|
||||
error: function(errors) {
|
||||
equal(errors.text1, 'server-invalid', 'server validation error ok');
|
||||
},
|
||||
ajaxOptions: {
|
||||
type: 'PUT'
|
||||
type: 'PUT',
|
||||
dataType: 'json'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
e.remove();
|
||||
e1.remove();
|
||||
start();
|
||||
}, timeout);
|
||||
|
||||
});
|
||||
|
||||
|
||||
asyncTest("'submit' method: server error", function () {
|
||||
expect(2);
|
||||
var ev1 = 'ev1',
|
||||
e1v = 'e1v',
|
||||
e = $('<a href="#" class="new" data-type="text" data-url="post.php" data-name="text">'+ev1+'</a>').appendTo(fx).editable(),
|
||||
e1 = $('<a href="#" class="new" data-type="text" data-name="text1">'+e1v+'</a>').appendTo(fx).editable();
|
||||
e = $('<a href="#" class="new-err" data-type="text" data-url="post.php" data-name="text">'+ev1+'</a>').appendTo(fx).editable(),
|
||||
e1 = $('<a href="#" class="new-err" data-type="text" data-name="text1">'+e1v+'</a>').appendTo(fx).editable();
|
||||
|
||||
$(fx).find('.new').editable('submit', {
|
||||
$(fx).find('.new-err').editable('submit', {
|
||||
url: 'error.php',
|
||||
error: function(data) {
|
||||
ok(!data.errors, 'no client errors');
|
||||
equal(this[0], $(fx).find('.new-err')[0], 'success context ok');
|
||||
equal(this[1], $(fx).find('.new-err')[1], 'success context2 ok');
|
||||
|
||||
equal(data.status, 500, 'status 500 ok');
|
||||
equal(data.responseText, 'customtext', 'server error ok');
|
||||
|
||||
e.remove();
|
||||
@ -290,7 +318,6 @@ $(function () {
|
||||
});
|
||||
|
||||
asyncTest("'submit' method: success", function () {
|
||||
expect(7);
|
||||
var ev1 = 'ev1',
|
||||
e1v = 'e1v',
|
||||
pk = 123,
|
||||
@ -302,24 +329,23 @@ $(function () {
|
||||
response: function(settings) {
|
||||
equal(settings.data.text, ev1, 'first value ok');
|
||||
equal(settings.data.text1, e1v, 'second value ok');
|
||||
this.responseText = {id: pk};
|
||||
this.responseText = 'response-body';
|
||||
}
|
||||
});
|
||||
|
||||
$(fx).find('.new').editable('submit', {
|
||||
url: 'new-success.php',
|
||||
success: function(data) {
|
||||
equal(e.data('editable').options.pk, pk, 'pk1 ok');
|
||||
ok(!e.hasClass('editable-changed'), 'no "editable-changed" class');
|
||||
|
||||
equal(e1.data('editable').options.pk, pk, 'pk2 ok');
|
||||
ok(!e1.hasClass('editable-changed'), 'no "editable-changed" class');
|
||||
|
||||
equal(data.id, pk, 'server result id ok');
|
||||
equal(this[0], $(fx).find('.new')[0], 'success context ok');
|
||||
equal(this[1], $(fx).find('.new')[1], 'success context2 ok');
|
||||
equal(data, 'response-body', 'response body ok');
|
||||
|
||||
e.remove();
|
||||
e1.remove();
|
||||
start();
|
||||
},
|
||||
error: function(errors) {
|
||||
ok(false, 'error should not be called');
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -3,7 +3,8 @@ $(function () {
|
||||
module("checklist", {
|
||||
setup: function(){
|
||||
sfx = $('#qunit-fixture'),
|
||||
fx = $('#async-fixture');
|
||||
fx = $('#async-fixture');
|
||||
$.support.transition = false;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -444,6 +444,81 @@
|
||||
e.remove();
|
||||
start();
|
||||
}, timeout);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
asyncTest("should submit all required params", function () {
|
||||
var e = $('<a href="#" data-pk="1" data-url="post-resp.php">abc</a>').appendTo(fx).editable({
|
||||
name: 'username',
|
||||
params: {
|
||||
q: 2
|
||||
},
|
||||
ajaxOptions: {
|
||||
dataType: 'json'
|
||||
},
|
||||
success: function(resp) {
|
||||
equal(resp.dataType, 'json', 'dataType ok');
|
||||
equal(resp.data.pk, 1, 'pk ok');
|
||||
equal(resp.data.name, 'username', 'name ok');
|
||||
equal(resp.data.value, newText, 'value ok');
|
||||
equal(resp.data.q, 2, 'additional params ok');
|
||||
}
|
||||
}),
|
||||
newText = 'cd<e>;"'
|
||||
|
||||
e.click()
|
||||
var p = tip(e);
|
||||
|
||||
ok(p.find('input[type=text]').length, 'input exists')
|
||||
p.find('input').val(newText);
|
||||
p.find('form').submit();
|
||||
|
||||
setTimeout(function() {
|
||||
e.remove();
|
||||
start();
|
||||
}, timeout);
|
||||
|
||||
});
|
||||
|
||||
asyncTest("params as function", function () {
|
||||
var e = $('<a href="#" data-pk="1" data-url="post-params-func.php">abc</a>').appendTo(fx).editable({
|
||||
name: 'username',
|
||||
params: function(params) {
|
||||
ok(this === e[0], 'scope is ok');
|
||||
equal(params.pk, 1, 'params in func already have values (pk)');
|
||||
return $.extend(params, {q: 2, pk: 3});
|
||||
},
|
||||
ajaxOptions: {
|
||||
headers: {"myHeader": "123"}
|
||||
}
|
||||
}),
|
||||
newText = 'cd<e>;"'
|
||||
|
||||
$.mockjax({
|
||||
url: 'post-params-func.php',
|
||||
response: function(settings) {
|
||||
equal(settings.dataType, undefined, 'dataType undefined (correct)');
|
||||
equal(settings.data.pk, 3, 'pk ok');
|
||||
equal(settings.data.name, 'username', 'name ok');
|
||||
equal(settings.data.value, newText, 'value ok');
|
||||
equal(settings.data.q, 2, 'additional params ok');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
e.click()
|
||||
var p = tip(e);
|
||||
|
||||
ok(p.find('input[type=text]').length, 'input exists')
|
||||
p.find('input').val(newText);
|
||||
p.find('form').submit();
|
||||
|
||||
setTimeout(function() {
|
||||
e.remove();
|
||||
start();
|
||||
}, timeout);
|
||||
|
||||
});
|
||||
|
||||
|
||||
}(jQuery));
|
@ -6,6 +6,7 @@ $(function () {
|
||||
setup: function(){
|
||||
fx = $('#async-fixture');
|
||||
dpg = $.fn.datepicker.DPGlobal;
|
||||
$.support.transition = false;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -5,6 +5,7 @@ $(function () {
|
||||
module("dateui", {
|
||||
setup: function(){
|
||||
fx = $('#async-fixture');
|
||||
$.support.transition = false;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -295,12 +295,12 @@ $(function () {
|
||||
expect(4);
|
||||
|
||||
//clear cache
|
||||
$(document).removeData('groups.php-name1');
|
||||
$(document).removeData('groups-cache-sim.php-name1');
|
||||
|
||||
var req = 0;
|
||||
$.mockjax({
|
||||
url: 'groups-cache-sim.php',
|
||||
responseTime: 200,
|
||||
responseTime: 50,
|
||||
response: function() {
|
||||
req++;
|
||||
this.responseText = groups;
|
||||
@ -312,7 +312,6 @@ $(function () {
|
||||
e2 = $('<a href="#" data-type="select" data-pk="1" data-name="name1" data-value="3" data-url="post.php" data-source="groups-cache-sim.php"></a>').appendTo(fx).editable();
|
||||
|
||||
setTimeout(function() {
|
||||
|
||||
equal(req, 1, 'one request');
|
||||
equal(e.text(), groups[1], 'text1 correct');
|
||||
equal(e1.text(), groups[2], 'text2 correct');
|
||||
@ -330,7 +329,7 @@ $(function () {
|
||||
expect(4);
|
||||
|
||||
//clear cache
|
||||
$(document).removeData('groups.php-name1');
|
||||
$(document).removeData('groups-cache-sim-err.php-name1');
|
||||
|
||||
var req = 0;
|
||||
$.mockjax({
|
||||
@ -342,17 +341,16 @@ $(function () {
|
||||
}
|
||||
});
|
||||
|
||||
var e = $('<a href="#" data-type="select" data-pk="1" data-name="name1" data-value="1" data-autotext="always" data-url="post.php" data-source="groups-cache-sim-err.php">35</a>').appendTo(fx).editable(),
|
||||
e1 = $('<a href="#" data-type="select" data-pk="1" data-name="name1" data-value="2" data-autotext="always" data-url="post.php" data-source="groups-cache-sim-err.php">35</a>').appendTo(fx).editable(),
|
||||
e2 = $('<a href="#" data-type="select" data-pk="1" data-name="name1" data-value="3" data-autotext="always" data-url="post.php" data-source="groups-cache-sim-err.php">6456</a>').appendTo(fx).editable(),
|
||||
errText = $.fn.editabletypes.select.defaults.sourceError;
|
||||
var e = $('<a href="#" data-type="select" data-pk="1" data-name="name1" data-value="1" data-autotext="always" data-url="post.php" data-source="groups-cache-sim-err.php">11</a>').appendTo(fx).editable(),
|
||||
e1 = $('<a href="#" data-type="select" data-pk="1" data-name="name1" data-value="2" data-autotext="always" data-url="post.php" data-source="groups-cache-sim-err.php">22</a>').appendTo(fx).editable(),
|
||||
e2 = $('<a href="#" data-type="select" data-pk="1" data-name="name1" data-value="3" data-autotext="always" data-url="post.php" data-source="groups-cache-sim-err.php"></a>').appendTo(fx).editable();
|
||||
|
||||
setTimeout(function() {
|
||||
|
||||
equal(req, 1, 'one request');
|
||||
equal(e.text(), errText, 'text1 correct');
|
||||
equal(e1.text(), errText, 'text2 correct');
|
||||
equal(e2.text(), errText, 'text3 correct');
|
||||
equal(e.text(), '11', 'text1 correct');
|
||||
equal(e1.text(), '22', 'text2 correct');
|
||||
equal(e2.text(), $.fn.editable.defaults.emptytext, 'text3 correct');
|
||||
|
||||
e.remove();
|
||||
e1.remove();
|
||||
|
@ -211,71 +211,6 @@ $(function () {
|
||||
|
||||
});
|
||||
|
||||
|
||||
asyncTest("should submit all required params", function () {
|
||||
var e = $('<a href="#" data-pk="1" data-url="post-resp.php">abc</a>').appendTo(fx).editable({
|
||||
name: 'username',
|
||||
params: {
|
||||
q: 2
|
||||
},
|
||||
success: function(resp) {
|
||||
equal(resp.dataType, 'json', 'dataType ok');
|
||||
equal(resp.data.pk, 1, 'pk ok');
|
||||
equal(resp.data.name, 'username', 'name ok');
|
||||
equal(resp.data.value, newText, 'value ok');
|
||||
equal(resp.data.q, 2, 'additional params ok');
|
||||
}
|
||||
}),
|
||||
newText = 'cd<e>;"'
|
||||
|
||||
e.click()
|
||||
var p = tip(e);
|
||||
|
||||
ok(p.find('input[type=text]').length, 'input exists')
|
||||
p.find('input').val(newText);
|
||||
p.find('form').submit();
|
||||
|
||||
setTimeout(function() {
|
||||
e.remove();
|
||||
start();
|
||||
}, timeout);
|
||||
|
||||
});
|
||||
|
||||
asyncTest("params as function", function () {
|
||||
var e = $('<a href="#" data-pk="1" data-url="post-resp.php">abc</a>').appendTo(fx).editable({
|
||||
name: 'username',
|
||||
params: function(params) {
|
||||
ok(this === e[0], 'scope is ok');
|
||||
equal(params.pk, 1, 'params in func already have values (pk)');
|
||||
return { q: 2, pk: 3 };
|
||||
},
|
||||
success: function(resp) {
|
||||
equal(resp.dataType, 'json', 'dataType ok');
|
||||
equal(resp.data.pk, 3, 'pk ok');
|
||||
equal(resp.data.name, 'username', 'name ok');
|
||||
equal(resp.data.value, newText, 'value ok');
|
||||
equal(resp.data.q, 2, 'additional params ok');
|
||||
},
|
||||
ajaxOptions: {
|
||||
headers: {"myHeader": "123"}
|
||||
}
|
||||
}),
|
||||
newText = 'cd<e>;"'
|
||||
|
||||
e.click()
|
||||
var p = tip(e);
|
||||
|
||||
ok(p.find('input[type=text]').length, 'input exists')
|
||||
p.find('input').val(newText);
|
||||
p.find('form').submit();
|
||||
|
||||
setTimeout(function() {
|
||||
e.remove();
|
||||
start();
|
||||
}, timeout);
|
||||
|
||||
});
|
||||
|
||||
asyncTest("ajaxOptions", function () {
|
||||
var e = $('<a href="#" data-pk="1" data-url="post-options.php">abc</a>').appendTo(fx).editable({
|
||||
@ -503,6 +438,67 @@ $(function () {
|
||||
start();
|
||||
}, timeout);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
test("password", function () {
|
||||
var v = '123', v1 = '456';
|
||||
|
||||
var e = $('<a href="#" data-pk="1" data-name="name" data-value="'+v+'"></a>').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 = $('<a href="#" data-pk="1" data-name="name">'+v+'</a>').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');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user