x-editable-rails 1.5.1 → 1.5.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +17 -13
- data/lib/x-editable-rails/version.rb +2 -2
- data/lib/x-editable-rails/view_helpers.rb +66 -41
- data/vendor/assets/javascripts/editable/bootstrap-editable.js +336 -203
- data/vendor/assets/javascripts/editable/bootstrap2-editable.js +308 -202
- data/vendor/assets/javascripts/editable/inputs-ext/wysihtml5-editable.js +9 -1
- data/vendor/assets/javascripts/editable/jquery-editable-poshytip.js +315 -202
- data/vendor/assets/javascripts/editable/jqueryui-editable.js +316 -203
- data/vendor/assets/javascripts/editable/rails/editable_form.js.coffee +14 -18
- data/vendor/assets/javascripts/editable/rails/error_handling.js.coffee +4 -0
- data/vendor/assets/javascripts/editable/rails.js.coffee +2 -1
- data/vendor/assets/stylesheets/editable/bootstrap-editable.scss +25 -25
- data/vendor/assets/stylesheets/editable/bootstrap2-editable.scss +25 -25
- metadata +19 -32
- /data/vendor/assets/stylesheets/editable/inputs-ext/{bootstrap-typehead.css → bootstrap-typeahead.css} +0 -0
@@ -1,7 +1,7 @@
|
|
1
|
-
/*! X-editable - v1.5.
|
2
|
-
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
|
3
|
-
* http://github.com/vitalets/x-editable
|
4
|
-
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */
|
1
|
+
/*! X-editable - v1.5.1
|
2
|
+
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
|
3
|
+
* http://github.com/vitalets/x-editable
|
4
|
+
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */
|
5
5
|
/**
|
6
6
|
Form with single input element, two buttons and two states: normal/loading.
|
7
7
|
Applied as jQuery method to DIV tag (not to form tag!). This is because form can be in loading state when spinner shown.
|
@@ -185,7 +185,7 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
|
|
185
185
|
} else {
|
186
186
|
//convert newline to <br> for more pretty error display
|
187
187
|
if(msg) {
|
188
|
-
lines = msg.split(
|
188
|
+
lines = (''+msg).split('\n');
|
189
189
|
for (var i = 0; i < lines.length; i++) {
|
190
190
|
lines[i] = $('<div>').text(lines[i]).html();
|
191
191
|
}
|
@@ -200,11 +200,21 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
|
|
200
200
|
e.stopPropagation();
|
201
201
|
e.preventDefault();
|
202
202
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
//validation
|
207
|
-
if
|
203
|
+
//get new value from input
|
204
|
+
var newValue = this.input.input2value();
|
205
|
+
|
206
|
+
//validation: if validate returns string or truthy value - means error
|
207
|
+
//if returns object like {newValue: '...'} => submitted value is reassigned to it
|
208
|
+
var error = this.validate(newValue);
|
209
|
+
if ($.type(error) === 'object' && error.newValue !== undefined) {
|
210
|
+
newValue = error.newValue;
|
211
|
+
this.input.value2input(newValue);
|
212
|
+
if(typeof error.msg === 'string') {
|
213
|
+
this.error(error.msg);
|
214
|
+
this.showForm();
|
215
|
+
return;
|
216
|
+
}
|
217
|
+
} else if (error) {
|
208
218
|
this.error(error);
|
209
219
|
this.showForm();
|
210
220
|
return;
|
@@ -503,6 +513,8 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
|
|
503
513
|
send: 'auto',
|
504
514
|
/**
|
505
515
|
Function for client-side validation. If returns string - means validation not passed and string showed as error.
|
516
|
+
Since 1.5.1 you can modify submitted value by returning object from `validate`:
|
517
|
+
`{newValue: '...'}` or `{newValue: '...', msg: '...'}`
|
506
518
|
|
507
519
|
@property validate
|
508
520
|
@type function
|
@@ -625,7 +637,7 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
|
|
625
637
|
//engine
|
626
638
|
$.fn.editableform.engine = 'jquery';
|
627
639
|
}(window.jQuery));
|
628
|
-
|
640
|
+
|
629
641
|
/**
|
630
642
|
* EditableForm utilites
|
631
643
|
*/
|
@@ -875,7 +887,7 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
|
|
875
887
|
|
876
888
|
};
|
877
889
|
}(window.jQuery));
|
878
|
-
|
890
|
+
|
879
891
|
/**
|
880
892
|
Attaches stand-alone container with editable-form to HTML element. Element is used only for positioning, value is not stored anywhere.<br>
|
881
893
|
This method applied internally in <code>$().editable()</code>. You should subscribe on it's events (save / cancel) to get profit of it.<br>
|
@@ -1391,7 +1403,7 @@ Applied as jQuery method.
|
|
1391
1403
|
};
|
1392
1404
|
|
1393
1405
|
}(window.jQuery));
|
1394
|
-
|
1406
|
+
|
1395
1407
|
/**
|
1396
1408
|
* Editable Inline
|
1397
1409
|
* ---------------------
|
@@ -1445,7 +1457,7 @@ Applied as jQuery method.
|
|
1445
1457
|
}
|
1446
1458
|
});
|
1447
1459
|
|
1448
|
-
}(window.jQuery));
|
1460
|
+
}(window.jQuery));
|
1449
1461
|
/**
|
1450
1462
|
Makes editable any HTML element on the page. Applied as jQuery method.
|
1451
1463
|
|
@@ -2015,7 +2027,9 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
2015
2027
|
/**
|
2016
2028
|
This method collects values from several editable elements and submit them all to server.
|
2017
2029
|
Internally it runs client-side validation for all fields and submits only in case of success.
|
2018
|
-
See <a href="#newrecord">creating new records</a> for details.
|
2030
|
+
See <a href="#newrecord">creating new records</a> for details.
|
2031
|
+
Since 1.5.1 `submit` can be applied to single element to send data programmatically. In that case
|
2032
|
+
`url`, `success` and `error` is taken from initial options and you can just call `$('#username').editable('submit')`.
|
2019
2033
|
|
2020
2034
|
@method submit(options)
|
2021
2035
|
@param {object} options
|
@@ -2029,31 +2043,76 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
2029
2043
|
case 'submit': //collects value, validate and submit to server for creating new record
|
2030
2044
|
var config = arguments[1] || {},
|
2031
2045
|
$elems = this,
|
2032
|
-
errors = this.editable('validate')
|
2033
|
-
values;
|
2046
|
+
errors = this.editable('validate');
|
2034
2047
|
|
2048
|
+
// validation ok
|
2035
2049
|
if($.isEmptyObject(errors)) {
|
2036
|
-
|
2037
|
-
|
2038
|
-
|
2050
|
+
var ajaxOptions = {};
|
2051
|
+
|
2052
|
+
// for single element use url, success etc from options
|
2053
|
+
if($elems.length === 1) {
|
2054
|
+
var editable = $elems.data('editable');
|
2055
|
+
//standard params
|
2056
|
+
var params = {
|
2057
|
+
name: editable.options.name || '',
|
2058
|
+
value: editable.input.value2submit(editable.value),
|
2059
|
+
pk: (typeof editable.options.pk === 'function') ?
|
2060
|
+
editable.options.pk.call(editable.options.scope) :
|
2061
|
+
editable.options.pk
|
2062
|
+
};
|
2063
|
+
|
2064
|
+
//additional params
|
2065
|
+
if(typeof editable.options.params === 'function') {
|
2066
|
+
params = editable.options.params.call(editable.options.scope, params);
|
2067
|
+
} else {
|
2068
|
+
//try parse json in single quotes (from data-params attribute)
|
2069
|
+
editable.options.params = $.fn.editableutils.tryParseJson(editable.options.params, true);
|
2070
|
+
$.extend(params, editable.options.params);
|
2071
|
+
}
|
2072
|
+
|
2073
|
+
ajaxOptions = {
|
2074
|
+
url: editable.options.url,
|
2075
|
+
data: params,
|
2076
|
+
type: 'POST'
|
2077
|
+
};
|
2078
|
+
|
2079
|
+
// use success / error from options
|
2080
|
+
config.success = config.success || editable.options.success;
|
2081
|
+
config.error = config.error || editable.options.error;
|
2082
|
+
|
2083
|
+
// multiple elements
|
2084
|
+
} else {
|
2085
|
+
var values = this.editable('getValue');
|
2086
|
+
|
2087
|
+
ajaxOptions = {
|
2088
|
+
url: config.url,
|
2089
|
+
data: values,
|
2090
|
+
type: 'POST'
|
2091
|
+
};
|
2039
2092
|
}
|
2040
|
-
|
2041
|
-
|
2042
|
-
|
2043
|
-
data: values,
|
2044
|
-
type: 'POST'
|
2045
|
-
}, config.ajaxOptions))
|
2046
|
-
.success(function(response) {
|
2047
|
-
//successful response 200 OK
|
2048
|
-
if(typeof config.success === 'function') {
|
2093
|
+
|
2094
|
+
// ajax success callabck (response 200 OK)
|
2095
|
+
ajaxOptions.success = typeof config.success === 'function' ? function(response) {
|
2049
2096
|
config.success.call($elems, response, config);
|
2050
|
-
}
|
2051
|
-
|
2052
|
-
|
2053
|
-
|
2054
|
-
|
2055
|
-
}
|
2056
|
-
|
2097
|
+
} : $.noop;
|
2098
|
+
|
2099
|
+
// ajax error callabck
|
2100
|
+
ajaxOptions.error = typeof config.error === 'function' ? function() {
|
2101
|
+
config.error.apply($elems, arguments);
|
2102
|
+
} : $.noop;
|
2103
|
+
|
2104
|
+
// extend ajaxOptions
|
2105
|
+
if(config.ajaxOptions) {
|
2106
|
+
$.extend(ajaxOptions, config.ajaxOptions);
|
2107
|
+
}
|
2108
|
+
|
2109
|
+
// extra data
|
2110
|
+
if(config.data) {
|
2111
|
+
$.extend(ajaxOptions.data, config.data);
|
2112
|
+
}
|
2113
|
+
|
2114
|
+
// perform ajax request
|
2115
|
+
$.ajax(ajaxOptions);
|
2057
2116
|
} else { //client-side validation error
|
2058
2117
|
if(typeof config.error === 'function') {
|
2059
2118
|
config.error.call($elems, errors);
|
@@ -2257,7 +2316,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
2257
2316
|
};
|
2258
2317
|
|
2259
2318
|
}(window.jQuery));
|
2260
|
-
|
2319
|
+
|
2261
2320
|
/**
|
2262
2321
|
AbstractInput - base class for all editable inputs.
|
2263
2322
|
It defines interface to be implemented by any input type.
|
@@ -2478,7 +2537,7 @@ To create your own input you can inherit from this class.
|
|
2478
2537
|
$.extend($.fn.editabletypes, {abstractinput: AbstractInput});
|
2479
2538
|
|
2480
2539
|
}(window.jQuery));
|
2481
|
-
|
2540
|
+
|
2482
2541
|
/**
|
2483
2542
|
List - abstract class for inputs that have source option loaded from js array or via ajax
|
2484
2543
|
|
@@ -2814,7 +2873,7 @@ List - abstract class for inputs that have source option loaded from js array or
|
|
2814
2873
|
$.fn.editabletypes.list = List;
|
2815
2874
|
|
2816
2875
|
}(window.jQuery));
|
2817
|
-
|
2876
|
+
|
2818
2877
|
/**
|
2819
2878
|
Text input
|
2820
2879
|
|
@@ -2949,7 +3008,7 @@ $(function(){
|
|
2949
3008
|
$.fn.editabletypes.text = Text;
|
2950
3009
|
|
2951
3010
|
}(window.jQuery));
|
2952
|
-
|
3011
|
+
|
2953
3012
|
/**
|
2954
3013
|
Textarea input
|
2955
3014
|
|
@@ -3061,7 +3120,7 @@ $(function(){
|
|
3061
3120
|
$.fn.editabletypes.textarea = Textarea;
|
3062
3121
|
|
3063
3122
|
}(window.jQuery));
|
3064
|
-
|
3123
|
+
|
3065
3124
|
/**
|
3066
3125
|
Select (dropdown)
|
3067
3126
|
|
@@ -3158,7 +3217,7 @@ $(function(){
|
|
3158
3217
|
$.fn.editabletypes.select = Select;
|
3159
3218
|
|
3160
3219
|
}(window.jQuery));
|
3161
|
-
|
3220
|
+
|
3162
3221
|
/**
|
3163
3222
|
List of checkboxes.
|
3164
3223
|
Internally value stored as javascript array of values.
|
@@ -3315,7 +3374,7 @@ $(function(){
|
|
3315
3374
|
$.fn.editabletypes.checklist = Checklist;
|
3316
3375
|
|
3317
3376
|
}(window.jQuery));
|
3318
|
-
|
3377
|
+
|
3319
3378
|
/**
|
3320
3379
|
HTML5 input types.
|
3321
3380
|
Following types are supported:
|
@@ -3534,7 +3593,7 @@ Time
|
|
3534
3593
|
});
|
3535
3594
|
$.fn.editabletypes.time = Time;
|
3536
3595
|
}(window.jQuery));
|
3537
|
-
|
3596
|
+
|
3538
3597
|
/**
|
3539
3598
|
Select2 input. Based on amazing work of Igor Vaynberg https://github.com/ivaynberg/select2.
|
3540
3599
|
Please see [original select2 docs](http://ivaynberg.github.com/select2) for detailed description and options.
|
@@ -3575,7 +3634,11 @@ $(function(){
|
|
3575
3634
|
});
|
3576
3635
|
//remote source (simple)
|
3577
3636
|
$('#country').editable({
|
3578
|
-
source: '/getCountries'
|
3637
|
+
source: '/getCountries',
|
3638
|
+
select2: {
|
3639
|
+
placeholder: 'Select Country',
|
3640
|
+
minimumInputLength: 1
|
3641
|
+
}
|
3579
3642
|
});
|
3580
3643
|
//remote source (advanced)
|
3581
3644
|
$('#country').editable({
|
@@ -3651,14 +3714,14 @@ $(function(){
|
|
3651
3714
|
options.select2.data = this.sourceData;
|
3652
3715
|
}
|
3653
3716
|
}
|
3654
|
-
|
3717
|
+
|
3655
3718
|
//overriding objects in config (as by default jQuery extend() is not recursive)
|
3656
3719
|
this.options.select2 = $.extend({}, Constructor.defaults.select2, options.select2);
|
3657
|
-
|
3720
|
+
|
3658
3721
|
//detect whether it is multi-valued
|
3659
3722
|
this.isMultiple = this.options.select2.tags || this.options.select2.multiple;
|
3660
3723
|
this.isRemote = ('ajax' in this.options.select2);
|
3661
|
-
|
3724
|
+
|
3662
3725
|
//store function returning ID of item
|
3663
3726
|
//should be here as used inautotext for local source
|
3664
3727
|
this.idFunc = this.options.select2.id;
|
@@ -3666,12 +3729,12 @@ $(function(){
|
|
3666
3729
|
var idKey = this.idFunc || 'id';
|
3667
3730
|
this.idFunc = function (e) { return e[idKey]; };
|
3668
3731
|
}
|
3669
|
-
|
3732
|
+
|
3670
3733
|
//store function that renders text in select2
|
3671
|
-
this.formatSelection = this.options.select2.formatSelection;
|
3734
|
+
this.formatSelection = this.options.select2.formatSelection;
|
3672
3735
|
if (typeof(this.formatSelection) !== "function") {
|
3673
3736
|
this.formatSelection = function (e) { return e.text; };
|
3674
|
-
}
|
3737
|
+
}
|
3675
3738
|
};
|
3676
3739
|
|
3677
3740
|
$.fn.editableutils.inherit(Constructor, $.fn.editabletypes.abstractinput);
|
@@ -3693,61 +3756,55 @@ $(function(){
|
|
3693
3756
|
}, this));
|
3694
3757
|
}
|
3695
3758
|
|
3696
|
-
//trigger resize of editableform to re-position container in multi-valued mode
|
3759
|
+
//trigger resize of editableform to re-position container in multi-valued mode
|
3697
3760
|
if(this.isMultiple) {
|
3698
3761
|
this.$input.on('change', function() {
|
3699
3762
|
$(this).closest('form').parent().triggerHandler('resize');
|
3700
|
-
});
|
3763
|
+
});
|
3701
3764
|
}
|
3702
3765
|
},
|
3703
|
-
|
3766
|
+
|
3704
3767
|
value2html: function(value, element) {
|
3705
3768
|
var text = '', data,
|
3706
3769
|
that = this;
|
3707
|
-
|
3770
|
+
|
3708
3771
|
if(this.options.select2.tags) { //in tags mode just assign value
|
3709
3772
|
data = value;
|
3710
|
-
//data = $.fn.editableutils.itemsByValue(value, this.options.select2.tags, this.idFunc);
|
3773
|
+
//data = $.fn.editableutils.itemsByValue(value, this.options.select2.tags, this.idFunc);
|
3711
3774
|
} else if(this.sourceData) {
|
3712
3775
|
data = $.fn.editableutils.itemsByValue(value, this.sourceData, this.idFunc);
|
3713
3776
|
} else {
|
3714
3777
|
//can not get list of possible values
|
3715
|
-
//(e.g. autotext for select2 with ajax source)
|
3778
|
+
//(e.g. autotext for select2 with ajax source)
|
3716
3779
|
}
|
3717
|
-
|
3718
|
-
//data may be array (when multiple values allowed)
|
3780
|
+
|
3781
|
+
//data may be array (when multiple values allowed)
|
3719
3782
|
if($.isArray(data)) {
|
3720
3783
|
//collect selected data and show with separator
|
3721
3784
|
text = [];
|
3722
3785
|
$.each(data, function(k, v){
|
3723
|
-
text.push(v && typeof v === 'object' ? that.formatSelection(v) : v);
|
3724
|
-
});
|
3786
|
+
text.push(v && typeof v === 'object' ? that.formatSelection(v) : v);
|
3787
|
+
});
|
3725
3788
|
} else if(data) {
|
3726
|
-
text = that.formatSelection(data);
|
3789
|
+
text = that.formatSelection(data);
|
3727
3790
|
}
|
3728
3791
|
|
3729
3792
|
text = $.isArray(text) ? text.join(this.options.viewseparator) : text;
|
3730
3793
|
|
3731
3794
|
//$(element).text(text);
|
3732
3795
|
Constructor.superclass.value2html.call(this, text, element);
|
3733
|
-
},
|
3734
|
-
|
3796
|
+
},
|
3797
|
+
|
3735
3798
|
html2value: function(html) {
|
3736
3799
|
return this.options.select2.tags ? this.str2value(html, this.options.viewseparator) : null;
|
3737
|
-
},
|
3738
|
-
|
3800
|
+
},
|
3801
|
+
|
3739
3802
|
value2input: function(value) {
|
3740
|
-
//
|
3741
|
-
|
3742
|
-
|
3743
|
-
|
3744
|
-
|
3745
|
-
this.$input.select2('data', items[0]);
|
3746
|
-
return;
|
3747
|
-
}
|
3748
|
-
}
|
3749
|
-
*/
|
3750
|
-
|
3803
|
+
// if value array => join it anyway
|
3804
|
+
if($.isArray(value)) {
|
3805
|
+
value = value.join(this.getSeparator());
|
3806
|
+
}
|
3807
|
+
|
3751
3808
|
//for remote source just set value, text is updated by initSelection
|
3752
3809
|
if(!this.$input.data('select2')) {
|
3753
3810
|
this.$input.val(value);
|
@@ -3755,15 +3812,27 @@ $(function(){
|
|
3755
3812
|
} else {
|
3756
3813
|
//second argument needed to separate initial change from user's click (for autosubmit)
|
3757
3814
|
this.$input.val(value).trigger('change', true);
|
3815
|
+
|
3816
|
+
//Uncaught Error: cannot call val() if initSelection() is not defined
|
3817
|
+
//this.$input.select2('val', value);
|
3758
3818
|
}
|
3759
|
-
|
3760
|
-
//if remote source AND no user's initSelection provided -->
|
3819
|
+
|
3820
|
+
// if defined remote source AND no multiple mode AND no user's initSelection provided -->
|
3821
|
+
// we should somehow get text for provided id.
|
3822
|
+
// The solution is to use element's text as text for that id (exclude empty)
|
3761
3823
|
if(this.isRemote && !this.isMultiple && !this.options.select2.initSelection) {
|
3824
|
+
// customId and customText are methods to extract `id` and `text` from data object
|
3825
|
+
// we can use this workaround only if user did not define these methods
|
3826
|
+
// otherwise we cant construct data object
|
3762
3827
|
var customId = this.options.select2.id,
|
3763
3828
|
customText = this.options.select2.formatSelection;
|
3764
|
-
|
3765
|
-
|
3766
|
-
this
|
3829
|
+
|
3830
|
+
if(!customId && !customText) {
|
3831
|
+
var $el = $(this.options.scope);
|
3832
|
+
if (!$el.data('editable').isEmpty) {
|
3833
|
+
var data = {id: value, text: $el.text()};
|
3834
|
+
this.$input.select2('data', data);
|
3835
|
+
}
|
3767
3836
|
}
|
3768
3837
|
}
|
3769
3838
|
},
|
@@ -3776,11 +3845,11 @@ $(function(){
|
|
3776
3845
|
if(typeof str !== 'string' || !this.isMultiple) {
|
3777
3846
|
return str;
|
3778
3847
|
}
|
3779
|
-
|
3780
|
-
separator = separator || this.
|
3781
|
-
|
3848
|
+
|
3849
|
+
separator = separator || this.getSeparator();
|
3850
|
+
|
3782
3851
|
var val, i, l;
|
3783
|
-
|
3852
|
+
|
3784
3853
|
if (str === null || str.length < 1) {
|
3785
3854
|
return null;
|
3786
3855
|
}
|
@@ -3788,10 +3857,10 @@ $(function(){
|
|
3788
3857
|
for (i = 0, l = val.length; i < l; i = i + 1) {
|
3789
3858
|
val[i] = $.trim(val[i]);
|
3790
3859
|
}
|
3791
|
-
|
3860
|
+
|
3792
3861
|
return val;
|
3793
3862
|
},
|
3794
|
-
|
3863
|
+
|
3795
3864
|
autosubmit: function() {
|
3796
3865
|
this.$input.on('change', function(e, isInitial){
|
3797
3866
|
if(!isInitial) {
|
@@ -3799,7 +3868,11 @@ $(function(){
|
|
3799
3868
|
}
|
3800
3869
|
});
|
3801
3870
|
},
|
3802
|
-
|
3871
|
+
|
3872
|
+
getSeparator: function() {
|
3873
|
+
return this.options.select2.separator || $.fn.select2.defaults.separator;
|
3874
|
+
},
|
3875
|
+
|
3803
3876
|
/*
|
3804
3877
|
Converts source from x-editable format: {value: 1, text: "1"} to
|
3805
3878
|
select2 format: {id: 1, text: "1"}
|
@@ -3813,26 +3886,26 @@ $(function(){
|
|
3813
3886
|
}
|
3814
3887
|
}
|
3815
3888
|
}
|
3816
|
-
return source;
|
3889
|
+
return source;
|
3817
3890
|
},
|
3818
3891
|
|
3819
3892
|
destroy: function() {
|
3820
3893
|
if(this.$input.data('select2')) {
|
3821
3894
|
this.$input.select2('destroy');
|
3822
3895
|
}
|
3823
|
-
}
|
3896
|
+
}
|
3824
3897
|
|
3825
|
-
});
|
3898
|
+
});
|
3826
3899
|
|
3827
3900
|
Constructor.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
|
3828
3901
|
/**
|
3829
3902
|
@property tpl
|
3830
3903
|
@default <input type="hidden">
|
3831
|
-
**/
|
3904
|
+
**/
|
3832
3905
|
tpl:'<input type="hidden">',
|
3833
3906
|
/**
|
3834
3907
|
Configuration of select2. [Full list of options](http://ivaynberg.github.com/select2).
|
3835
|
-
|
3908
|
+
|
3836
3909
|
@property select2
|
3837
3910
|
@type object
|
3838
3911
|
@default null
|
@@ -3844,21 +3917,21 @@ $(function(){
|
|
3844
3917
|
@property placeholder
|
3845
3918
|
@type string
|
3846
3919
|
@default null
|
3847
|
-
**/
|
3920
|
+
**/
|
3848
3921
|
placeholder: null,
|
3849
3922
|
/**
|
3850
3923
|
Source data for select. It will be assigned to select2 `data` property and kept here just for convenience.
|
3851
3924
|
Please note, that format is different from simple `select` input: use 'id' instead of 'value'.
|
3852
|
-
E.g. `[{id: 1, text: "text1"}, {id: 2, text: "text2"}, ...]`.
|
3853
|
-
|
3925
|
+
E.g. `[{id: 1, text: "text1"}, {id: 2, text: "text2"}, ...]`.
|
3926
|
+
|
3854
3927
|
@property source
|
3855
3928
|
@type array|string|function
|
3856
3929
|
@default null
|
3857
3930
|
**/
|
3858
3931
|
source: null,
|
3859
3932
|
/**
|
3860
|
-
Separator used to display tags.
|
3861
|
-
|
3933
|
+
Separator used to display tags.
|
3934
|
+
|
3862
3935
|
@property viewseparator
|
3863
3936
|
@type string
|
3864
3937
|
@default ', '
|
@@ -3866,16 +3939,16 @@ $(function(){
|
|
3866
3939
|
viewseparator: ', '
|
3867
3940
|
});
|
3868
3941
|
|
3869
|
-
$.fn.editabletypes.select2 = Constructor;
|
3870
|
-
|
3942
|
+
$.fn.editabletypes.select2 = Constructor;
|
3943
|
+
|
3871
3944
|
}(window.jQuery));
|
3872
|
-
|
3945
|
+
|
3873
3946
|
/**
|
3874
|
-
* Combodate - 1.0.
|
3947
|
+
* Combodate - 1.0.5
|
3875
3948
|
* Dropdown date and time picker.
|
3876
3949
|
* Converts text input into dropdowns to pick day, month, year, hour, minute and second.
|
3877
3950
|
* Uses momentjs as datetime library http://momentjs.com.
|
3878
|
-
* For
|
3951
|
+
* For i18n include corresponding file from https://github.com/timrwood/moment/tree/master/lang
|
3879
3952
|
*
|
3880
3953
|
* Confusion at noon and midnight - see http://en.wikipedia.org/wiki/12-hour_clock#Confusion_at_noon_and_midnight
|
3881
3954
|
* In combodate:
|
@@ -3922,16 +3995,22 @@ $(function(){
|
|
3922
3995
|
this.initCombos();
|
3923
3996
|
|
3924
3997
|
//update original input on change
|
3925
|
-
this.$widget.on('change', 'select', $.proxy(function(){
|
3926
|
-
this.$element.val(this.getValue());
|
3998
|
+
this.$widget.on('change', 'select', $.proxy(function(e) {
|
3999
|
+
this.$element.val(this.getValue()).change();
|
4000
|
+
// update days count if month or year changes
|
4001
|
+
if (this.options.smartDays) {
|
4002
|
+
if ($(e.target).is('.month') || $(e.target).is('.year')) {
|
4003
|
+
this.fillCombo('day');
|
4004
|
+
}
|
4005
|
+
}
|
3927
4006
|
}, this));
|
3928
4007
|
|
3929
4008
|
this.$widget.find('select').css('width', 'auto');
|
3930
4009
|
|
3931
|
-
//hide original input and insert widget
|
4010
|
+
// hide original input and insert widget
|
3932
4011
|
this.$element.hide().after(this.$widget);
|
3933
4012
|
|
3934
|
-
//set initial value
|
4013
|
+
// set initial value
|
3935
4014
|
this.setValue(this.$element.val() || this.options.value);
|
3936
4015
|
},
|
3937
4016
|
|
@@ -3968,22 +4047,41 @@ $(function(){
|
|
3968
4047
|
Initialize combos that presents in template
|
3969
4048
|
*/
|
3970
4049
|
initCombos: function() {
|
3971
|
-
var
|
3972
|
-
|
3973
|
-
|
3974
|
-
|
3975
|
-
|
3976
|
-
|
3977
|
-
|
3978
|
-
that['$'+k].html(that.renderItems(items));
|
3979
|
-
}
|
3980
|
-
});
|
4050
|
+
for (var k in this.map) {
|
4051
|
+
var $c = this.$widget.find('.'+k);
|
4052
|
+
// set properties like this.$day, this.$month etc.
|
4053
|
+
this['$'+k] = $c.length ? $c : null;
|
4054
|
+
// fill with items
|
4055
|
+
this.fillCombo(k);
|
4056
|
+
}
|
3981
4057
|
},
|
3982
|
-
|
4058
|
+
|
4059
|
+
/*
|
4060
|
+
Fill combo with items
|
4061
|
+
*/
|
4062
|
+
fillCombo: function(k) {
|
4063
|
+
var $combo = this['$'+k];
|
4064
|
+
if (!$combo) {
|
4065
|
+
return;
|
4066
|
+
}
|
4067
|
+
|
4068
|
+
// define method name to fill items, e.g `fillDays`
|
4069
|
+
var f = 'fill' + k.charAt(0).toUpperCase() + k.slice(1);
|
4070
|
+
var items = this[f]();
|
4071
|
+
var value = $combo.val();
|
4072
|
+
|
4073
|
+
$combo.empty();
|
4074
|
+
for(var i=0; i<items.length; i++) {
|
4075
|
+
$combo.append('<option value="'+items[i][0]+'">'+items[i][1]+'</option>');
|
4076
|
+
}
|
4077
|
+
|
4078
|
+
$combo.val(value);
|
4079
|
+
},
|
4080
|
+
|
3983
4081
|
/*
|
3984
4082
|
Initialize items of combos. Handles `firstItem` option
|
3985
4083
|
*/
|
3986
|
-
|
4084
|
+
fillCommon: function(key) {
|
3987
4085
|
var values = [],
|
3988
4086
|
relTime;
|
3989
4087
|
|
@@ -3998,27 +4096,29 @@ $(function(){
|
|
3998
4096
|
values.push(['', '']);
|
3999
4097
|
}
|
4000
4098
|
return values;
|
4001
|
-
},
|
4002
|
-
|
4003
|
-
/*
|
4004
|
-
render items to string of <option> tags
|
4005
|
-
*/
|
4006
|
-
renderItems: function(items) {
|
4007
|
-
var str = [];
|
4008
|
-
for(var i=0; i<items.length; i++) {
|
4009
|
-
str.push('<option value="'+items[i][0]+'">'+items[i][1]+'</option>');
|
4010
|
-
}
|
4011
|
-
return str.join("\n");
|
4012
|
-
},
|
4099
|
+
},
|
4100
|
+
|
4013
4101
|
|
4014
4102
|
/*
|
4015
4103
|
fill day
|
4016
4104
|
*/
|
4017
4105
|
fillDay: function() {
|
4018
|
-
var items = this.
|
4019
|
-
twoDigit = this.options.template.indexOf('DD') !== -1
|
4020
|
-
|
4021
|
-
|
4106
|
+
var items = this.fillCommon('d'), name, i,
|
4107
|
+
twoDigit = this.options.template.indexOf('DD') !== -1,
|
4108
|
+
daysCount = 31;
|
4109
|
+
|
4110
|
+
// detect days count (depends on month and year)
|
4111
|
+
// originally https://github.com/vitalets/combodate/pull/7
|
4112
|
+
if (this.options.smartDays && this.$month && this.$year) {
|
4113
|
+
var month = parseInt(this.$month.val(), 10);
|
4114
|
+
var year = parseInt(this.$year.val(), 10);
|
4115
|
+
|
4116
|
+
if (!isNaN(month) && !isNaN(year)) {
|
4117
|
+
daysCount = moment([year, month]).daysInMonth();
|
4118
|
+
}
|
4119
|
+
}
|
4120
|
+
|
4121
|
+
for (i = 1; i <= daysCount; i++) {
|
4022
4122
|
name = twoDigit ? this.leadZero(i) : i;
|
4023
4123
|
items.push([i, name]);
|
4024
4124
|
}
|
@@ -4029,7 +4129,7 @@ $(function(){
|
|
4029
4129
|
fill month
|
4030
4130
|
*/
|
4031
4131
|
fillMonth: function() {
|
4032
|
-
var items = this.
|
4132
|
+
var items = this.fillCommon('M'), name, i,
|
4033
4133
|
longNames = this.options.template.indexOf('MMMM') !== -1,
|
4034
4134
|
shortNames = this.options.template.indexOf('MMM') !== -1,
|
4035
4135
|
twoDigit = this.options.template.indexOf('MM') !== -1;
|
@@ -4062,7 +4162,7 @@ $(function(){
|
|
4062
4162
|
items[this.options.yearDescending ? 'push' : 'unshift']([i, name]);
|
4063
4163
|
}
|
4064
4164
|
|
4065
|
-
items = this.
|
4165
|
+
items = this.fillCommon('y').concat(items);
|
4066
4166
|
|
4067
4167
|
return items;
|
4068
4168
|
},
|
@@ -4071,7 +4171,7 @@ $(function(){
|
|
4071
4171
|
fill hour
|
4072
4172
|
*/
|
4073
4173
|
fillHour: function() {
|
4074
|
-
var items = this.
|
4174
|
+
var items = this.fillCommon('h'), name, i,
|
4075
4175
|
h12 = this.options.template.indexOf('h') !== -1,
|
4076
4176
|
h24 = this.options.template.indexOf('H') !== -1,
|
4077
4177
|
twoDigit = this.options.template.toLowerCase().indexOf('hh') !== -1,
|
@@ -4089,7 +4189,7 @@ $(function(){
|
|
4089
4189
|
fill minute
|
4090
4190
|
*/
|
4091
4191
|
fillMinute: function() {
|
4092
|
-
var items = this.
|
4192
|
+
var items = this.fillCommon('m'), name, i,
|
4093
4193
|
twoDigit = this.options.template.indexOf('mm') !== -1;
|
4094
4194
|
|
4095
4195
|
for(i=0; i<=59; i+= this.options.minuteStep) {
|
@@ -4103,7 +4203,7 @@ $(function(){
|
|
4103
4203
|
fill second
|
4104
4204
|
*/
|
4105
4205
|
fillSecond: function() {
|
4106
|
-
var items = this.
|
4206
|
+
var items = this.fillCommon('s'), name, i,
|
4107
4207
|
twoDigit = this.options.template.indexOf('ss') !== -1;
|
4108
4208
|
|
4109
4209
|
for(i=0; i<=59; i+= this.options.secondStep) {
|
@@ -4125,7 +4225,7 @@ $(function(){
|
|
4125
4225
|
];
|
4126
4226
|
return items;
|
4127
4227
|
},
|
4128
|
-
|
4228
|
+
|
4129
4229
|
/*
|
4130
4230
|
Returns current date value from combos.
|
4131
4231
|
If format not specified - `options.format` used.
|
@@ -4188,63 +4288,68 @@ $(function(){
|
|
4188
4288
|
that = this,
|
4189
4289
|
values = {};
|
4190
4290
|
|
4191
|
-
|
4192
|
-
|
4193
|
-
|
4194
|
-
|
4195
|
-
|
4196
|
-
|
4197
|
-
|
4198
|
-
|
4199
|
-
|
4200
|
-
|
4201
|
-
|
4202
|
-
|
4203
|
-
|
4204
|
-
|
4205
|
-
|
4291
|
+
//function to find nearest value in select options
|
4292
|
+
function getNearest($select, value) {
|
4293
|
+
var delta = {};
|
4294
|
+
$select.children('option').each(function(i, opt){
|
4295
|
+
var optValue = $(opt).attr('value'),
|
4296
|
+
distance;
|
4297
|
+
|
4298
|
+
if(optValue === '') return;
|
4299
|
+
distance = Math.abs(optValue - value);
|
4300
|
+
if(typeof delta.distance === 'undefined' || distance < delta.distance) {
|
4301
|
+
delta = {value: optValue, distance: distance};
|
4302
|
+
}
|
4303
|
+
});
|
4304
|
+
return delta.value;
|
4305
|
+
}
|
4206
4306
|
|
4207
4307
|
if(dt.isValid()) {
|
4208
|
-
|
4209
|
-
|
4210
|
-
|
4211
|
-
|
4212
|
-
|
4213
|
-
|
4214
|
-
|
4308
|
+
//read values from date object
|
4309
|
+
$.each(this.map, function(k, v) {
|
4310
|
+
if(k === 'ampm') {
|
4311
|
+
return;
|
4312
|
+
}
|
4313
|
+
values[k] = dt[v[1]]();
|
4314
|
+
});
|
4215
4315
|
|
4216
|
-
|
4217
|
-
|
4218
|
-
|
4219
|
-
|
4220
|
-
|
4221
|
-
|
4222
|
-
|
4223
|
-
|
4224
|
-
|
4225
|
-
|
4226
|
-
|
4227
|
-
|
4228
|
-
|
4229
|
-
|
4316
|
+
if(this.$ampm) {
|
4317
|
+
//12:00 pm --> 12:00 (24-h format, midday), 12:00 am --> 00:00 (24-h format, midnight, start of day)
|
4318
|
+
if(values.hour >= 12) {
|
4319
|
+
values.ampm = 'pm';
|
4320
|
+
if(values.hour > 12) {
|
4321
|
+
values.hour -= 12;
|
4322
|
+
}
|
4323
|
+
} else {
|
4324
|
+
values.ampm = 'am';
|
4325
|
+
if(values.hour === 0) {
|
4326
|
+
values.hour = 12;
|
4327
|
+
}
|
4328
|
+
}
|
4329
|
+
}
|
4230
4330
|
|
4231
|
-
|
4232
|
-
|
4233
|
-
|
4331
|
+
$.each(values, function(k, v) {
|
4332
|
+
//call val() for each existing combo, e.g. this.$hour.val()
|
4333
|
+
if(that['$'+k]) {
|
4234
4334
|
|
4235
|
-
|
4236
|
-
|
4237
|
-
|
4335
|
+
if(k === 'minute' && that.options.minuteStep > 1 && that.options.roundTime) {
|
4336
|
+
v = getNearest(that['$'+k], v);
|
4337
|
+
}
|
4238
4338
|
|
4239
|
-
|
4240
|
-
|
4241
|
-
|
4339
|
+
if(k === 'second' && that.options.secondStep > 1 && that.options.roundTime) {
|
4340
|
+
v = getNearest(that['$'+k], v);
|
4341
|
+
}
|
4242
4342
|
|
4243
|
-
|
4244
|
-
|
4245
|
-
|
4343
|
+
that['$'+k].val(v);
|
4344
|
+
}
|
4345
|
+
});
|
4346
|
+
|
4347
|
+
// update days count
|
4348
|
+
if (this.options.smartDays) {
|
4349
|
+
this.fillCombo('day');
|
4350
|
+
}
|
4246
4351
|
|
4247
|
-
this.$element.val(dt.format(this.options.format));
|
4352
|
+
this.$element.val(dt.format(this.options.format)).change();
|
4248
4353
|
}
|
4249
4354
|
},
|
4250
4355
|
|
@@ -4319,10 +4424,11 @@ $(function(){
|
|
4319
4424
|
secondStep: 1,
|
4320
4425
|
firstItem: 'empty', //'name', 'empty', 'none'
|
4321
4426
|
errorClass: null,
|
4322
|
-
roundTime: true //whether to round minutes and seconds if step > 1
|
4427
|
+
roundTime: true, // whether to round minutes and seconds if step > 1
|
4428
|
+
smartDays: false // whether days in combo depend on selected month: 31, 30, 28
|
4323
4429
|
};
|
4324
4430
|
|
4325
|
-
}(window.jQuery));
|
4431
|
+
}(window.jQuery));
|
4326
4432
|
/**
|
4327
4433
|
Combodate input - dropdown date and time picker.
|
4328
4434
|
Based on [combodate](http://vitalets.github.com/combodate) plugin (included). To use it you should manually include [momentjs](http://momentjs.com).
|
@@ -4520,7 +4626,7 @@ $(function(){
|
|
4520
4626
|
$.fn.editabletypes.combodate = Constructor;
|
4521
4627
|
|
4522
4628
|
}(window.jQuery));
|
4523
|
-
|
4629
|
+
|
4524
4630
|
/*
|
4525
4631
|
Editableform based on jQuery UI
|
4526
4632
|
*/
|
@@ -4552,7 +4658,7 @@ Editableform based on jQuery UI
|
|
4552
4658
|
//engine
|
4553
4659
|
$.fn.editableform.engine = 'jquery-ui';
|
4554
4660
|
|
4555
|
-
}(window.jQuery));
|
4661
|
+
}(window.jQuery));
|
4556
4662
|
/**
|
4557
4663
|
* Editable jQuery UI Tooltip
|
4558
4664
|
* ---------------------
|
@@ -4674,7 +4780,7 @@ Editableform based on jQuery UI
|
|
4674
4780
|
});
|
4675
4781
|
|
4676
4782
|
}(window.jQuery));
|
4677
|
-
|
4783
|
+
|
4678
4784
|
/**
|
4679
4785
|
jQuery UI Datepicker.
|
4680
4786
|
Description and examples: http://jqueryui.com/datepicker.
|
@@ -4796,15 +4902,22 @@ $(function(){
|
|
4796
4902
|
|
4797
4903
|
clear: function() {
|
4798
4904
|
this.$input.datepicker('setDate', null);
|
4905
|
+
// submit automatically whe that are no buttons
|
4906
|
+
if(this.isAutosubmit) {
|
4907
|
+
this.submit();
|
4908
|
+
}
|
4799
4909
|
},
|
4800
4910
|
|
4801
4911
|
autosubmit: function() {
|
4802
|
-
this
|
4803
|
-
|
4804
|
-
|
4805
|
-
|
4806
|
-
|
4807
|
-
|
4912
|
+
this.isAutosubmit = true;
|
4913
|
+
this.$input.on('mouseup', 'table.ui-datepicker-calendar a.ui-state-default', $.proxy(this.submit, this));
|
4914
|
+
},
|
4915
|
+
|
4916
|
+
submit: function() {
|
4917
|
+
var $form = this.$input.closest('form');
|
4918
|
+
setTimeout(function() {
|
4919
|
+
$form.submit();
|
4920
|
+
}, 200);
|
4808
4921
|
}
|
4809
4922
|
|
4810
4923
|
});
|
@@ -4871,7 +4984,7 @@ $(function(){
|
|
4871
4984
|
$.fn.editabletypes.dateui = DateUI;
|
4872
4985
|
|
4873
4986
|
}(window.jQuery));
|
4874
|
-
|
4987
|
+
|
4875
4988
|
/**
|
4876
4989
|
jQuery UI datefield input - modification for inline mode.
|
4877
4990
|
Shows normal <input type="text"> and binds popup datepicker.
|