Skip to content

Commit

Permalink
submit single field, fix vitalets#371
Browse files Browse the repository at this point in the history
  • Loading branch information
vitalets committed Nov 4, 2013
1 parent b3a73fe commit 00709fc
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 23 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ X-editable changelog

Version 1.5.1 wip
----------------------------
[enh #371] submit single field (vitalets)
[bug] select2: placeholder not shown if value initially empty (vitalets)
[enh #400] allow `validate` to change submitted value, also fix #354 (vitalets)
[enh #396] bs3 popover: placement `auto` (vitalets)
Expand Down
91 changes: 69 additions & 22 deletions src/element/editable-element.js
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,9 @@ Makes editable any HTML element on the page. Applied as jQuery method.
/**
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.
See <a href="#newrecord">creating new records</a> for details.
Since 1.5.1 `submit` can be applied to single element to send data programmatically. In that case
`url`, `success` and `error` is taken from initial options and you can just call `$('#username').editable('submit')`.
@method submit(options)
@param {object} options
Expand All @@ -581,31 +583,76 @@ Makes editable any HTML element on the page. Applied as jQuery method.
case 'submit': //collects value, validate and submit to server for creating new record
var config = arguments[1] || {},
$elems = this,
errors = this.editable('validate'),
values;
errors = this.editable('validate');

// validation ok
if($.isEmptyObject(errors)) {
values = this.editable('getValue');
if(config.data) {
$.extend(values, config.data);
var ajaxOptions = {};

// for single element use url, success etc from options
if($elems.length === 1) {
var editable = $elems.data('editable');
//standard params
var params = {
name: editable.options.name || '',
value: editable.input.value2submit(editable.value),
pk: (typeof editable.options.pk === 'function') ?
editable.options.pk.call(editable.options.scope) :
editable.options.pk
};

//additional params
if(typeof editable.options.params === 'function') {
params = editable.options.params.call(editable.options.scope, params);
} else {
//try parse json in single quotes (from data-params attribute)
editable.options.params = $.fn.editableutils.tryParseJson(editable.options.params, true);
$.extend(params, editable.options.params);
}

ajaxOptions = {
url: editable.options.url,
data: params,
type: 'POST'
};

// use success / error from options
config.success = config.success || editable.options.success;
config.error = config.error || editable.options.error;

// multiple elements
} else {
var values = this.editable('getValue');

ajaxOptions = {
url: config.url,
data: values,
type: 'POST'
};
}

$.ajax($.extend({
url: config.url,
data: values,
type: 'POST'
}, config.ajaxOptions))
.success(function(response) {
//successful response 200 OK
if(typeof config.success === 'function') {

// ajax success callabck (response 200 OK)
ajaxOptions.success = typeof config.success === 'function' ? function(response) {
config.success.call($elems, response, config);
}
})
.error(function(){ //ajax error
if(typeof config.error === 'function') {
config.error.apply($elems, arguments);
}
});
} : $.noop;

// ajax error callabck
ajaxOptions.error = typeof config.error === 'function' ? function() {
config.error.apply($elems, arguments);
} : $.noop;

// extend ajaxOptions
if(config.ajaxOptions) {
$.extend(ajaxOptions, config.ajaxOptions);
}

// extra data
if(config.data) {
$.extend(ajaxOptions.data, config.data);
}

// perform ajax request
$.ajax(ajaxOptions);
} else { //client-side validation error
if(typeof config.error === 'function') {
config.error.call($elems, errors);
Expand Down
53 changes: 52 additions & 1 deletion test/unit/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ $(function () {

});

asyncTest("'submit' method: success", function () {
asyncTest("'submit' method: success (multiple elems)", function () {
var ev1 = 'ev1',
e1v = 'e1v',
pk = 123,
Expand Down Expand Up @@ -403,6 +403,57 @@ $(function () {

});

asyncTest("'submit' method: success (single elem)", function () {
expect(5);

var ev1 = 'ev1',
pk = 123,
e = $('<a href="#" class="new" data-type="text" data-pk="'+pk+'" data-url="submit-single" data-name="text">'+ev1+'</a>').appendTo(fx).editable({
success: function(data) {
equal(data, 'response-body', 'response body ok');
}
});

$.mockjax({
url: 'submit-single',
response: function(settings) {
equal(settings.data.name, 'text', 'name ok');
equal(settings.data.pk, pk, 'pk ok');
equal(settings.data.value, ev1, 'value ok');
equal(settings.data.a, 1, 'extra data ok');
this.responseText = 'response-body';
}
});

$(fx).find('.new').editable('submit', {
data: {a: 1}
});

setTimeout(function() {
e.remove();
start();
}, timeout);

});

asyncTest("'submit' method: error (single elem)", function () {
expect(1);

var e = $('<a href="#" class="new" data-type="text" data-pk="123" data-url="error.php" data-name="text">text</a>').appendTo(fx).editable();

$(fx).find('.new').editable('submit', {
error: function() {
equal(this[0], e[0], 'error called in correct scope');
}
});

setTimeout(function() {
e.remove();
start();
}, timeout);

});


test("setValue method", function () {
var e = $('<a href="#" data-name="name" data-type="select" data-url="post.php"></a>').appendTo('#qunit-fixture').editable({
Expand Down

0 comments on commit 00709fc

Please sign in to comment.