bootstrap-editable-rails 0.0.4 → 0.0.5
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.
- data/README.md +17 -0
- data/bootstrap-editable-rails.gemspec +1 -1
- data/lib/bootstrap-editable-rails/version.rb +1 -1
- data/vendor/assets/javascripts/bootstrap-editable.js +312 -85
- data/vendor/assets/javascripts/bootstrap-editable.min.js +2 -2
- data/vendor/assets/stylesheets/bootstrap-editable.css +20 -1
- metadata +6 -6
data/README.md
CHANGED
@@ -89,6 +89,23 @@ def update
|
|
89
89
|
end
|
90
90
|
```
|
91
91
|
|
92
|
+
#### Known issue
|
93
|
+
|
94
|
+
The scaffold above will not work with jQuery 1.9.0 (included in jquery-rails 2.2.0) because of jQuery's bug.
|
95
|
+
|
96
|
+
https://github.com/jquery/jquery/pull/1142
|
97
|
+
|
98
|
+
To avoid it, you can do one of the following (and so on).
|
99
|
+
|
100
|
+
1. Respond with some value, not empty
|
101
|
+
|
102
|
+
`format.json { render json: @post } # 200 OK`
|
103
|
+
|
104
|
+
2. Not use jQuery 1.9.0
|
105
|
+
|
106
|
+
`gem 'jquery-rails', '2.1.4'` in Gemfile
|
107
|
+
|
108
|
+
|
92
109
|
|
93
110
|
## Contributing
|
94
111
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/*! X-editable - v1.4.
|
1
|
+
/*! X-editable - v1.4.3
|
2
2
|
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
|
3
3
|
* http://github.com/vitalets/x-editable
|
4
4
|
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */
|
@@ -494,7 +494,7 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
|
|
494
494
|
**/
|
495
495
|
success: null,
|
496
496
|
/**
|
497
|
-
Additional options for ajax request.
|
497
|
+
Additional options for submit ajax request.
|
498
498
|
List of values: http://api.jquery.com/jQuery.ajax
|
499
499
|
|
500
500
|
@property ajaxOptions
|
@@ -711,7 +711,7 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
|
|
711
711
|
|
712
712
|
$.each(sourceData, function(i, o) {
|
713
713
|
if(o.children) {
|
714
|
-
result = result.concat(that.itemsByValue(value, o.children));
|
714
|
+
result = result.concat(that.itemsByValue(value, o.children, valueProp));
|
715
715
|
} else {
|
716
716
|
/*jslint eqeq: true*/
|
717
717
|
if(isValArray) {
|
@@ -831,7 +831,8 @@ Applied as jQuery method.
|
|
831
831
|
}
|
832
832
|
});
|
833
833
|
|
834
|
-
//close containers when click outside
|
834
|
+
//close containers when click outside
|
835
|
+
//(mousedown could be better than click, it closes everything also on drag drop)
|
835
836
|
$(document).on('click.editable', function(e) {
|
836
837
|
var $target = $(e.target), i,
|
837
838
|
exclude_classes = ['.editable-container',
|
@@ -880,7 +881,7 @@ Applied as jQuery method.
|
|
880
881
|
|
881
882
|
/* returns container object */
|
882
883
|
container: function() {
|
883
|
-
return this.$element.data(this.containerName);
|
884
|
+
return this.$element.data(this.containerDataName || this.containerName);
|
884
885
|
},
|
885
886
|
|
886
887
|
call: function() {
|
@@ -909,8 +910,8 @@ Applied as jQuery method.
|
|
909
910
|
@param {Object} event event object
|
910
911
|
@example
|
911
912
|
$('#username').on('shown', function() {
|
912
|
-
|
913
|
-
|
913
|
+
var editable = $(this).data('editable');
|
914
|
+
editable.input.$input.val('overwriting value of input..');
|
914
915
|
});
|
915
916
|
**/
|
916
917
|
this.$element.triggerHandler('shown');
|
@@ -1211,9 +1212,9 @@ Applied as jQuery method.
|
|
1211
1212
|
Animation speed (inline mode)
|
1212
1213
|
@property anim
|
1213
1214
|
@type string
|
1214
|
-
@default
|
1215
|
+
@default false
|
1215
1216
|
**/
|
1216
|
-
anim:
|
1217
|
+
anim: false,
|
1217
1218
|
|
1218
1219
|
/**
|
1219
1220
|
Mode of editable, can be `popup` or `inline`
|
@@ -1320,7 +1321,9 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1320
1321
|
//name
|
1321
1322
|
this.options.name = this.options.name || this.$element.attr('id');
|
1322
1323
|
|
1323
|
-
//create input of specified type. Input
|
1324
|
+
//create input of specified type. Input needed already here to convert value for initial display (e.g. show text by id for select)
|
1325
|
+
//also we set scope option to have access to element inside input specific callbacks (e. g. source as function)
|
1326
|
+
this.options.scope = this.$element[0];
|
1324
1327
|
this.input = $.fn.editableutils.createInput(this.options);
|
1325
1328
|
if(!this.input) {
|
1326
1329
|
return;
|
@@ -1371,9 +1374,19 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1371
1374
|
}
|
1372
1375
|
|
1373
1376
|
//check conditions for autotext:
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
+
switch(this.options.autotext) {
|
1378
|
+
case 'always':
|
1379
|
+
doAutotext = true;
|
1380
|
+
break;
|
1381
|
+
case 'auto':
|
1382
|
+
//if element text is empty and value is defined and value not generated by text --> run autotext
|
1383
|
+
doAutotext = !$.trim(this.$element.text()).length && this.value !== null && this.value !== undefined && !isValueByText;
|
1384
|
+
break;
|
1385
|
+
default:
|
1386
|
+
doAutotext = false;
|
1387
|
+
}
|
1388
|
+
|
1389
|
+
//depending on autotext run render() or just finilize init
|
1377
1390
|
$.when(doAutotext ? this.render() : true).then($.proxy(function() {
|
1378
1391
|
if(this.options.disabled) {
|
1379
1392
|
this.disable();
|
@@ -1409,6 +1422,11 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1409
1422
|
this.$element.on(this.options.toggle + '.editable', selector, $.proxy(function(e){
|
1410
1423
|
var $target = $(e.target);
|
1411
1424
|
if(!$target.data('editable')) {
|
1425
|
+
//if delegated element initially empty, we need to clear it's text (that was manually set to `empty` by user)
|
1426
|
+
//see https://github.com/vitalets/x-editable/issues/137
|
1427
|
+
if($target.hasClass(this.options.emptyclass)) {
|
1428
|
+
$target.empty();
|
1429
|
+
}
|
1412
1430
|
$target.editable(this.options).trigger(e);
|
1413
1431
|
}
|
1414
1432
|
}, this));
|
@@ -1530,7 +1548,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1530
1548
|
if(this.options.display === false) {
|
1531
1549
|
return;
|
1532
1550
|
}
|
1533
|
-
|
1551
|
+
|
1534
1552
|
this.isEmpty = isEmpty !== undefined ? isEmpty : $.trim(this.$element.text()) === '';
|
1535
1553
|
|
1536
1554
|
//emptytext shown only for enabled
|
@@ -1751,11 +1769,14 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1751
1769
|
return result;
|
1752
1770
|
|
1753
1771
|
/**
|
1754
|
-
Returns current values of editable elements.
|
1772
|
+
Returns current values of editable elements.
|
1773
|
+
Note that it returns an **object** with name-value pairs, not a value itself. It allows to get data from several elements.
|
1774
|
+
If value of some editable is `null` or `undefined` it is excluded from result object.
|
1775
|
+
|
1755
1776
|
@method getValue()
|
1756
1777
|
@returns {Object} object of element names and values
|
1757
1778
|
@example
|
1758
|
-
$('#username, #fullname').editable('
|
1779
|
+
$('#username, #fullname').editable('getValue');
|
1759
1780
|
// possible result:
|
1760
1781
|
{
|
1761
1782
|
username: "superuser",
|
@@ -1892,8 +1913,20 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1892
1913
|
**/
|
1893
1914
|
autotext: 'auto',
|
1894
1915
|
/**
|
1895
|
-
Initial value of input. If not set, taken from element's text.
|
1896
|
-
|
1916
|
+
Initial value of input. If not set, taken from element's text.
|
1917
|
+
Note, that if element's text is empty - text is automatically generated from value and can be customized (see `autotext` option).
|
1918
|
+
For example, to display currency sign:
|
1919
|
+
@example
|
1920
|
+
<a id="price" data-type="text" data-value="100"></a>
|
1921
|
+
<script>
|
1922
|
+
$('#price').editable({
|
1923
|
+
...
|
1924
|
+
display: function(value) {
|
1925
|
+
$(this).text(value + '$');
|
1926
|
+
}
|
1927
|
+
})
|
1928
|
+
</script>
|
1929
|
+
|
1897
1930
|
@property value
|
1898
1931
|
@type mixed
|
1899
1932
|
@default element's text
|
@@ -1904,12 +1937,12 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1904
1937
|
If `null`, default input's display used.
|
1905
1938
|
If `false`, no displaying methods will be called, element's text will never change.
|
1906
1939
|
Runs under element's scope.
|
1907
|
-
|
1940
|
+
_**Parameters:**_
|
1908
1941
|
|
1909
1942
|
* `value` current value to be displayed
|
1910
1943
|
* `response` server response (if display called after ajax submit), since 1.4.0
|
1911
1944
|
|
1912
|
-
For
|
1945
|
+
For _inputs with source_ (select, checklist) parameters are different:
|
1913
1946
|
|
1914
1947
|
* `value` current value to be displayed
|
1915
1948
|
* `sourceData` array of items for current input (e.g. dropdown items)
|
@@ -1956,10 +1989,12 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1956
1989
|
**/
|
1957
1990
|
unsavedclass: 'editable-unsaved',
|
1958
1991
|
/**
|
1959
|
-
If
|
1992
|
+
If selector is provided, editable will be delegated to the specified targets.
|
1960
1993
|
Usefull for dynamically generated DOM elements.
|
1961
|
-
**Please note**, that delegated targets can't
|
1962
|
-
as they
|
1994
|
+
**Please note**, that delegated targets can't be initialized with `emptytext` and `autotext` options,
|
1995
|
+
as they actually become editable only after first click.
|
1996
|
+
You should manually set class `editable-click` to these elements.
|
1997
|
+
Also, if element originally empty you should add class `editable-empty`, set `data-value=""` and write emptytext into element:
|
1963
1998
|
|
1964
1999
|
@property selector
|
1965
2000
|
@type string
|
@@ -1967,8 +2002,10 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1967
2002
|
@default null
|
1968
2003
|
@example
|
1969
2004
|
<div id="user">
|
1970
|
-
|
1971
|
-
<a href="#" data-name="
|
2005
|
+
<!-- empty -->
|
2006
|
+
<a href="#" data-name="username" data-type="text" class="editable-click editable-empty" data-value="" title="Username">Empty</a>
|
2007
|
+
<!-- non-empty -->
|
2008
|
+
<a href="#" data-name="group" data-type="select" data-source="/groups" data-value="1" class="editable-click" title="Group">Operator</a>
|
1972
2009
|
</div>
|
1973
2010
|
|
1974
2011
|
<script>
|
@@ -2145,7 +2182,7 @@ To create your own input you can inherit from this class.
|
|
2145
2182
|
},
|
2146
2183
|
|
2147
2184
|
setAttr: function(attr) {
|
2148
|
-
if (this.options[attr]) {
|
2185
|
+
if (this.options[attr] !== undefined && this.options[attr] !== null) {
|
2149
2186
|
this.$input.attr(attr, this.options[attr]);
|
2150
2187
|
}
|
2151
2188
|
},
|
@@ -2172,7 +2209,10 @@ To create your own input you can inherit from this class.
|
|
2172
2209
|
@type string
|
2173
2210
|
@default input-medium
|
2174
2211
|
**/
|
2175
|
-
inputclass: 'input-medium'
|
2212
|
+
inputclass: 'input-medium',
|
2213
|
+
//scope for external methods (e.g. source defined as function)
|
2214
|
+
//for internal use only
|
2215
|
+
scope: null
|
2176
2216
|
};
|
2177
2217
|
|
2178
2218
|
$.extend($.fn.editabletypes, {abstractinput: AbstractInput});
|
@@ -2251,12 +2291,19 @@ List - abstract class for inputs that have source option loaded from js array or
|
|
2251
2291
|
error.call(this);
|
2252
2292
|
return;
|
2253
2293
|
}
|
2294
|
+
|
2295
|
+
var source = this.options.source;
|
2296
|
+
|
2297
|
+
//run source if it function
|
2298
|
+
if ($.isFunction(source)) {
|
2299
|
+
source = source.call(this.options.scope);
|
2300
|
+
}
|
2254
2301
|
|
2255
2302
|
//loading from url
|
2256
|
-
if (typeof
|
2303
|
+
if (typeof source === 'string') {
|
2257
2304
|
//try to get from cache
|
2258
2305
|
if(this.options.sourceCache) {
|
2259
|
-
var cacheID =
|
2306
|
+
var cacheID = source,
|
2260
2307
|
cache;
|
2261
2308
|
|
2262
2309
|
if (!$(document).data(cacheID)) {
|
@@ -2289,7 +2336,7 @@ List - abstract class for inputs that have source option loaded from js array or
|
|
2289
2336
|
|
2290
2337
|
//loading sourceData from server
|
2291
2338
|
$.ajax({
|
2292
|
-
url:
|
2339
|
+
url: source,
|
2293
2340
|
type: 'get',
|
2294
2341
|
cache: false,
|
2295
2342
|
dataType: 'json',
|
@@ -2324,12 +2371,8 @@ List - abstract class for inputs that have source option loaded from js array or
|
|
2324
2371
|
}
|
2325
2372
|
}, this)
|
2326
2373
|
});
|
2327
|
-
} else { //options as json/array
|
2328
|
-
|
2329
|
-
this.sourceData = this.makeArray(this.options.source());
|
2330
|
-
} else {
|
2331
|
-
this.sourceData = this.makeArray(this.options.source);
|
2332
|
-
}
|
2374
|
+
} else { //options as json/array
|
2375
|
+
this.sourceData = this.makeArray(source);
|
2333
2376
|
|
2334
2377
|
if($.isArray(this.sourceData)) {
|
2335
2378
|
this.doPrepend();
|
@@ -2346,16 +2389,20 @@ List - abstract class for inputs that have source option loaded from js array or
|
|
2346
2389
|
}
|
2347
2390
|
|
2348
2391
|
if(!$.isArray(this.prependData)) {
|
2392
|
+
//run prepend if it is function (once)
|
2393
|
+
if ($.isFunction(this.options.prepend)) {
|
2394
|
+
this.options.prepend = this.options.prepend.call(this.options.scope);
|
2395
|
+
}
|
2396
|
+
|
2349
2397
|
//try parse json in single quotes
|
2350
2398
|
this.options.prepend = $.fn.editableutils.tryParseJson(this.options.prepend, true);
|
2399
|
+
|
2400
|
+
//convert prepend from string to object
|
2351
2401
|
if (typeof this.options.prepend === 'string') {
|
2352
2402
|
this.options.prepend = {'': this.options.prepend};
|
2353
|
-
}
|
2354
|
-
if (typeof this.options.prepend === 'function') {
|
2355
|
-
this.prependData = this.makeArray(this.options.prepend());
|
2356
|
-
} else {
|
2357
|
-
this.prependData = this.makeArray(this.options.prepend);
|
2358
2403
|
}
|
2404
|
+
|
2405
|
+
this.prependData = this.makeArray(this.options.prepend);
|
2359
2406
|
}
|
2360
2407
|
|
2361
2408
|
if($.isArray(this.prependData) && $.isArray(this.sourceData)) {
|
@@ -2536,8 +2583,20 @@ $(function(){
|
|
2536
2583
|
if (this.options.clear) {
|
2537
2584
|
this.$clear = $('<span class="editable-clear-x"></span>');
|
2538
2585
|
this.$input.after(this.$clear)
|
2539
|
-
.css('padding-right',
|
2540
|
-
.keyup($.proxy(
|
2586
|
+
.css('padding-right', 24)
|
2587
|
+
.keyup($.proxy(function(e) {
|
2588
|
+
//arrows, enter, tab, etc
|
2589
|
+
if(~$.inArray(e.keyCode, [40,38,9,13,27])) {
|
2590
|
+
return;
|
2591
|
+
}
|
2592
|
+
|
2593
|
+
clearTimeout(this.t);
|
2594
|
+
var that = this;
|
2595
|
+
this.t = setTimeout(function() {
|
2596
|
+
that.toggleClear(e);
|
2597
|
+
}, 100);
|
2598
|
+
|
2599
|
+
}, this))
|
2541
2600
|
.parent().css('position', 'relative');
|
2542
2601
|
|
2543
2602
|
this.$clear.click($.proxy(this.clear, this));
|
@@ -2555,19 +2614,24 @@ $(function(){
|
|
2555
2614
|
delta = 3;
|
2556
2615
|
}
|
2557
2616
|
|
2558
|
-
this.$clear.css({
|
2617
|
+
this.$clear.css({bottom: delta, right: delta});
|
2559
2618
|
}
|
2560
2619
|
},
|
2561
2620
|
|
2562
2621
|
//show / hide clear button
|
2563
|
-
toggleClear: function() {
|
2622
|
+
toggleClear: function(e) {
|
2564
2623
|
if(!this.$clear) {
|
2565
2624
|
return;
|
2566
2625
|
}
|
2567
2626
|
|
2568
|
-
|
2627
|
+
var len = this.$input.val().length,
|
2628
|
+
visible = this.$clear.is(':visible');
|
2629
|
+
|
2630
|
+
if(len && !visible) {
|
2569
2631
|
this.$clear.show();
|
2570
|
-
}
|
2632
|
+
}
|
2633
|
+
|
2634
|
+
if(!len && visible) {
|
2571
2635
|
this.$clear.hide();
|
2572
2636
|
}
|
2573
2637
|
},
|
@@ -2733,7 +2797,6 @@ $(function(){
|
|
2733
2797
|
{value: 2, text: 'Blocked'},
|
2734
2798
|
{value: 3, text: 'Deleted'}
|
2735
2799
|
]
|
2736
|
-
}
|
2737
2800
|
});
|
2738
2801
|
});
|
2739
2802
|
</script>
|
@@ -2803,7 +2866,8 @@ $(function(){
|
|
2803
2866
|
|
2804
2867
|
$.fn.editabletypes.select = Select;
|
2805
2868
|
|
2806
|
-
}(window.jQuery));
|
2869
|
+
}(window.jQuery));
|
2870
|
+
|
2807
2871
|
/**
|
2808
2872
|
List of checkboxes.
|
2809
2873
|
Internally value stored as javascript array of values.
|
@@ -2822,7 +2886,6 @@ $(function(){
|
|
2822
2886
|
{value: 2, text: 'option2'},
|
2823
2887
|
{value: 3, text: 'option3'}
|
2824
2888
|
]
|
2825
|
-
}
|
2826
2889
|
});
|
2827
2890
|
});
|
2828
2891
|
</script>
|
@@ -3132,6 +3195,9 @@ You should manually include select2 distributive:
|
|
3132
3195
|
<link href="select2/select2.css" rel="stylesheet" type="text/css"></link>
|
3133
3196
|
<script src="select2/select2.js"></script>
|
3134
3197
|
|
3198
|
+
**Note:** currently `ajax` source for select2 is not supported, as it's not possible to load it in closed select2 state.
|
3199
|
+
The solution is to load source manually and assign statically.
|
3200
|
+
|
3135
3201
|
@class select2
|
3136
3202
|
@extends abstractinput
|
3137
3203
|
@since 1.4.1
|
@@ -3161,14 +3227,14 @@ $(function(){
|
|
3161
3227
|
options.select2 = options.select2 || {};
|
3162
3228
|
|
3163
3229
|
var that = this,
|
3164
|
-
mixin = {
|
3230
|
+
mixin = { //mixin to select2 options
|
3165
3231
|
placeholder: options.placeholder
|
3166
3232
|
};
|
3167
3233
|
|
3168
3234
|
//detect whether it is multi-valued
|
3169
3235
|
this.isMultiple = options.select2.tags || options.select2.multiple;
|
3170
3236
|
|
3171
|
-
//if not `tags` mode, we need define
|
3237
|
+
//if not `tags` mode, we need define initSelection to set data from source
|
3172
3238
|
if(!options.select2.tags) {
|
3173
3239
|
if(options.source) {
|
3174
3240
|
mixin.data = options.source;
|
@@ -3176,6 +3242,23 @@ $(function(){
|
|
3176
3242
|
|
3177
3243
|
//this function can be defaulted in seletc2. See https://github.com/ivaynberg/select2/issues/710
|
3178
3244
|
mixin.initSelection = function (element, callback) {
|
3245
|
+
//temp: try update results
|
3246
|
+
/*
|
3247
|
+
if(options.select2 && options.select2.ajax) {
|
3248
|
+
console.log('attached');
|
3249
|
+
var original = $(element).data('select2').postprocessResults;
|
3250
|
+
console.log(original);
|
3251
|
+
$(element).data('select2').postprocessResults = function(data, initial) {
|
3252
|
+
console.log('postprocess');
|
3253
|
+
// this.element.triggerHandler('loaded', [data]);
|
3254
|
+
original.apply(this, arguments);
|
3255
|
+
}
|
3256
|
+
|
3257
|
+
// $(element).on('loaded', function(){console.log('loaded');});
|
3258
|
+
$(element).data('select2').updateResults(true);
|
3259
|
+
}
|
3260
|
+
*/
|
3261
|
+
|
3179
3262
|
var val = that.str2value(element.val()),
|
3180
3263
|
data = $.fn.editableutils.itemsByValue(val, mixin.data, 'id');
|
3181
3264
|
|
@@ -3200,18 +3283,30 @@ $(function(){
|
|
3200
3283
|
//apply select2
|
3201
3284
|
this.$input.select2(this.options.select2);
|
3202
3285
|
|
3286
|
+
//when data is loaded via ajax, we need to know when it's done
|
3287
|
+
if('ajax' in this.options.select2) {
|
3288
|
+
/*
|
3289
|
+
console.log('attached');
|
3290
|
+
var original = this.$input.data('select2').postprocessResults;
|
3291
|
+
this.$input.data('select2').postprocessResults = function(data, initial) {
|
3292
|
+
this.element.triggerHandler('loaded', [data]);
|
3293
|
+
original.apply(this, arguments);
|
3294
|
+
}
|
3295
|
+
*/
|
3296
|
+
}
|
3297
|
+
|
3298
|
+
|
3203
3299
|
//trigger resize of editableform to re-position container in multi-valued mode
|
3204
3300
|
if(this.isMultiple) {
|
3205
3301
|
this.$input.on('change', function() {
|
3206
3302
|
$(this).closest('form').parent().triggerHandler('resize');
|
3207
3303
|
});
|
3208
|
-
}
|
3209
|
-
|
3210
|
-
},
|
3304
|
+
}
|
3305
|
+
},
|
3211
3306
|
|
3212
3307
|
value2html: function(value, element) {
|
3213
3308
|
var text = '', data;
|
3214
|
-
if(this.$input) { //when submitting form
|
3309
|
+
if(this.$input) { //called when submitting form and select2 already exists
|
3215
3310
|
data = this.$input.select2('data');
|
3216
3311
|
} else { //on init (autotext)
|
3217
3312
|
//here select2 instance not created yet and data may be even not loaded.
|
@@ -3220,6 +3315,8 @@ $(function(){
|
|
3220
3315
|
data = value;
|
3221
3316
|
} else if(this.options.select2.data) {
|
3222
3317
|
data = $.fn.editableutils.itemsByValue(value, this.options.select2.data, 'id');
|
3318
|
+
} else {
|
3319
|
+
//if('ajax' in this.options.select2) {
|
3223
3320
|
}
|
3224
3321
|
}
|
3225
3322
|
|
@@ -3243,7 +3340,7 @@ $(function(){
|
|
3243
3340
|
},
|
3244
3341
|
|
3245
3342
|
value2input: function(value) {
|
3246
|
-
this.$input.val(value).trigger('change');
|
3343
|
+
this.$input.val(value).trigger('change', true); //second argument needed to separate initial change from user's click (for autosubmit)
|
3247
3344
|
},
|
3248
3345
|
|
3249
3346
|
input2value: function() {
|
@@ -3268,7 +3365,15 @@ $(function(){
|
|
3268
3365
|
}
|
3269
3366
|
|
3270
3367
|
return val;
|
3271
|
-
}
|
3368
|
+
},
|
3369
|
+
|
3370
|
+
autosubmit: function() {
|
3371
|
+
this.$input.on('change', function(e, isInitial){
|
3372
|
+
if(!isInitial) {
|
3373
|
+
$(this).closest('form').submit();
|
3374
|
+
}
|
3375
|
+
});
|
3376
|
+
}
|
3272
3377
|
|
3273
3378
|
});
|
3274
3379
|
|
@@ -3318,7 +3423,7 @@ $(function(){
|
|
3318
3423
|
|
3319
3424
|
}(window.jQuery));
|
3320
3425
|
/**
|
3321
|
-
* Combodate - 1.0.
|
3426
|
+
* Combodate - 1.0.2
|
3322
3427
|
* Dropdown date and time picker.
|
3323
3428
|
* Converts text input into dropdowns to pick day, month, year, hour, minute and second.
|
3324
3429
|
* Uses momentjs as datetime library http://momentjs.com.
|
@@ -3421,9 +3526,13 @@ $(function(){
|
|
3421
3526
|
Initialize items of combos. Handles `firstItem` option
|
3422
3527
|
*/
|
3423
3528
|
initItems: function(key) {
|
3424
|
-
var values = []
|
3529
|
+
var values = [],
|
3530
|
+
relTime;
|
3531
|
+
|
3425
3532
|
if(this.options.firstItem === 'name') {
|
3426
|
-
|
3533
|
+
//need both to suuport moment ver < 2 and >= 2
|
3534
|
+
relTime = moment.relativeTime || moment.langData()._relativeTime;
|
3535
|
+
var header = typeof relTime[key] === 'function' ? relTime[key](1, true, key, false) : relTime[key];
|
3427
3536
|
//take last entry (see momentjs lang files structure)
|
3428
3537
|
header = header.split(' ').reverse()[0];
|
3429
3538
|
values.push(['', header]);
|
@@ -3469,9 +3578,9 @@ $(function(){
|
|
3469
3578
|
|
3470
3579
|
for(i=0; i<=11; i++) {
|
3471
3580
|
if(longNames) {
|
3472
|
-
name = moment.
|
3581
|
+
name = moment().month(i).format('MMMM');
|
3473
3582
|
} else if(shortNames) {
|
3474
|
-
name = moment.
|
3583
|
+
name = moment().month(i).format('MMM');
|
3475
3584
|
} else if(twoDigit) {
|
3476
3585
|
name = this.leadZero(i+1);
|
3477
3586
|
} else {
|
@@ -3717,7 +3826,7 @@ $(function(){
|
|
3717
3826
|
}(window.jQuery));
|
3718
3827
|
/**
|
3719
3828
|
Combodate input - dropdown date and time picker.
|
3720
|
-
Based on [combodate](http://vitalets.github.com/combodate) plugin. To use it you should manually include [momentjs](http://momentjs.com).
|
3829
|
+
Based on [combodate](http://vitalets.github.com/combodate) plugin (included). To use it you should manually include [momentjs](http://momentjs.com).
|
3721
3830
|
|
3722
3831
|
<script src="js/moment.min.js"></script>
|
3723
3832
|
|
@@ -3765,6 +3874,9 @@ $(function(){
|
|
3765
3874
|
this.options.viewformat = this.options.format;
|
3766
3875
|
}
|
3767
3876
|
|
3877
|
+
//try parse combodate config defined as json string in data-combodate
|
3878
|
+
options.combodate = $.fn.editableutils.tryParseJson(options.combodate, true);
|
3879
|
+
|
3768
3880
|
//overriding combodate config (as by default jQuery extend() is not recursive)
|
3769
3881
|
this.options.combodate = $.extend({}, Constructor.defaults.combodate, options.combodate, {
|
3770
3882
|
format: this.options.format,
|
@@ -4149,12 +4261,24 @@ $(function(){
|
|
4149
4261
|
},
|
4150
4262
|
|
4151
4263
|
autosubmit: function() {
|
4264
|
+
this.$input.on('mouseup', '.day', function(e){
|
4265
|
+
if($(e.currentTarget).is('.old') || $(e.currentTarget).is('.new')) {
|
4266
|
+
return;
|
4267
|
+
}
|
4268
|
+
var $form = $(this).closest('form');
|
4269
|
+
setTimeout(function() {
|
4270
|
+
$form.submit();
|
4271
|
+
}, 200);
|
4272
|
+
});
|
4273
|
+
//changedate is not suitable as it triggered when showing datepicker. see #149
|
4274
|
+
/*
|
4152
4275
|
this.$input.on('changeDate', function(e){
|
4153
4276
|
var $form = $(this).closest('form');
|
4154
4277
|
setTimeout(function() {
|
4155
4278
|
$form.submit();
|
4156
4279
|
}, 200);
|
4157
4280
|
});
|
4281
|
+
*/
|
4158
4282
|
}
|
4159
4283
|
|
4160
4284
|
});
|
@@ -4197,12 +4321,14 @@ $(function(){
|
|
4197
4321
|
@default {
|
4198
4322
|
weekStart: 0,
|
4199
4323
|
startView: 0,
|
4324
|
+
minViewMode: 0,
|
4200
4325
|
autoclose: false
|
4201
4326
|
}
|
4202
4327
|
**/
|
4203
4328
|
datepicker:{
|
4204
4329
|
weekStart: 0,
|
4205
4330
|
startView: 0,
|
4331
|
+
minViewMode: 0,
|
4206
4332
|
autoclose: false
|
4207
4333
|
},
|
4208
4334
|
/**
|
@@ -4291,6 +4417,7 @@ Automatically shown in inline mode.
|
|
4291
4417
|
datepicker: {
|
4292
4418
|
weekStart: 0,
|
4293
4419
|
startView: 0,
|
4420
|
+
minViewMode: 0,
|
4294
4421
|
autoclose: true
|
4295
4422
|
}
|
4296
4423
|
});
|
@@ -4335,9 +4462,10 @@ Automatically shown in inline mode.
|
|
4335
4462
|
|
4336
4463
|
this.element = $(element);
|
4337
4464
|
this.language = options.language||this.element.data('date-language')||"en";
|
4465
|
+
this.language = this.language in dates ? this.language : this.language.split('-')[0]; //Check if "de-DE" style date is available, if not language should fallback to 2 letter code eg "de"
|
4338
4466
|
this.language = this.language in dates ? this.language : "en";
|
4339
4467
|
this.isRTL = dates[this.language].rtl||false;
|
4340
|
-
this.format = DPGlobal.parseFormat(options.format||this.element.data('date-format')||'mm/dd/yyyy');
|
4468
|
+
this.format = DPGlobal.parseFormat(options.format||this.element.data('date-format')||dates[this.language].format||'mm/dd/yyyy');
|
4341
4469
|
this.isInline = false;
|
4342
4470
|
this.isInput = this.element.is('input');
|
4343
4471
|
this.component = this.element.is('.date') ? this.element.find('.add-on') : false;
|
@@ -4353,7 +4481,7 @@ Automatically shown in inline mode.
|
|
4353
4481
|
} else if ('dateForceParse' in this.element.data()) {
|
4354
4482
|
this.forceParse = this.element.data('date-force-parse');
|
4355
4483
|
}
|
4356
|
-
|
4484
|
+
|
4357
4485
|
|
4358
4486
|
this.picker = $(DPGlobal.template)
|
4359
4487
|
.appendTo(this.isInline ? this.element : 'body')
|
@@ -4374,7 +4502,7 @@ Automatically shown in inline mode.
|
|
4374
4502
|
}
|
4375
4503
|
$(document).on('mousedown', function (e) {
|
4376
4504
|
// Clicked outside the datepicker, hide it
|
4377
|
-
if ($(e.target).closest('.datepicker').length === 0) {
|
4505
|
+
if ($(e.target).closest('.datepicker.datepicker-inline, .datepicker.datepicker-dropdown').length === 0) {
|
4378
4506
|
that.hide();
|
4379
4507
|
}
|
4380
4508
|
});
|
@@ -4405,9 +4533,38 @@ Automatically shown in inline mode.
|
|
4405
4533
|
break;
|
4406
4534
|
}
|
4407
4535
|
|
4536
|
+
this.minViewMode = options.minViewMode||this.element.data('date-min-view-mode')||0;
|
4537
|
+
if (typeof this.minViewMode === 'string') {
|
4538
|
+
switch (this.minViewMode) {
|
4539
|
+
case 'months':
|
4540
|
+
this.minViewMode = 1;
|
4541
|
+
break;
|
4542
|
+
case 'years':
|
4543
|
+
this.minViewMode = 2;
|
4544
|
+
break;
|
4545
|
+
default:
|
4546
|
+
this.minViewMode = 0;
|
4547
|
+
break;
|
4548
|
+
}
|
4549
|
+
}
|
4550
|
+
|
4551
|
+
this.viewMode = this.startViewMode = Math.max(this.startViewMode, this.minViewMode);
|
4552
|
+
|
4408
4553
|
this.todayBtn = (options.todayBtn||this.element.data('date-today-btn')||false);
|
4409
4554
|
this.todayHighlight = (options.todayHighlight||this.element.data('date-today-highlight')||false);
|
4410
4555
|
|
4556
|
+
this.calendarWeeks = false;
|
4557
|
+
if ('calendarWeeks' in options) {
|
4558
|
+
this.calendarWeeks = options.calendarWeeks;
|
4559
|
+
} else if ('dateCalendarWeeks' in this.element.data()) {
|
4560
|
+
this.calendarWeeks = this.element.data('date-calendar-weeks');
|
4561
|
+
}
|
4562
|
+
if (this.calendarWeeks)
|
4563
|
+
this.picker.find('tfoot th.today')
|
4564
|
+
.attr('colspan', function(i, val){
|
4565
|
+
return parseInt(val) + 1;
|
4566
|
+
});
|
4567
|
+
|
4411
4568
|
this.weekStart = ((options.weekStart||this.element.data('date-weekstart')||dates[this.language].weekStart||0) % 7);
|
4412
4569
|
this.weekEnd = ((this.weekStart + 6) % 7);
|
4413
4570
|
this.startDate = -Infinity;
|
@@ -4497,6 +4654,7 @@ Automatically shown in inline mode.
|
|
4497
4654
|
|
4498
4655
|
hide: function(e){
|
4499
4656
|
if(this.isInline) return;
|
4657
|
+
if (!this.picker.is(':visible')) return;
|
4500
4658
|
this.picker.hide();
|
4501
4659
|
$(window).off('resize', this.place);
|
4502
4660
|
this.viewMode = this.startViewMode;
|
@@ -4618,7 +4776,6 @@ Automatically shown in inline mode.
|
|
4618
4776
|
|
4619
4777
|
if(fromArgs) this.setValue();
|
4620
4778
|
|
4621
|
-
var oldViewDate = this.viewDate;
|
4622
4779
|
if (this.date < this.startDate) {
|
4623
4780
|
this.viewDate = new Date(this.startDate);
|
4624
4781
|
} else if (this.date > this.endDate) {
|
@@ -4626,19 +4783,17 @@ Automatically shown in inline mode.
|
|
4626
4783
|
} else {
|
4627
4784
|
this.viewDate = new Date(this.date);
|
4628
4785
|
}
|
4629
|
-
|
4630
|
-
if (oldViewDate && oldViewDate.getTime() != this.viewDate.getTime()){
|
4631
|
-
this.element.trigger({
|
4632
|
-
type: 'changeDate',
|
4633
|
-
date: this.viewDate
|
4634
|
-
});
|
4635
|
-
}
|
4636
4786
|
this.fill();
|
4637
4787
|
},
|
4638
4788
|
|
4639
4789
|
fillDow: function(){
|
4640
4790
|
var dowCnt = this.weekStart,
|
4641
4791
|
html = '<tr>';
|
4792
|
+
if(this.calendarWeeks){
|
4793
|
+
var cell = '<th class="cw"> </th>';
|
4794
|
+
html += cell;
|
4795
|
+
this.picker.find('.datepicker-days thead tr:first-child').prepend(cell);
|
4796
|
+
}
|
4642
4797
|
while (dowCnt < this.weekStart + 7) {
|
4643
4798
|
html += '<th class="dow">'+dates[this.language].daysMin[(dowCnt++)%7]+'</th>';
|
4644
4799
|
}
|
@@ -4665,7 +4820,7 @@ Automatically shown in inline mode.
|
|
4665
4820
|
endMonth = this.endDate !== Infinity ? this.endDate.getUTCMonth() : Infinity,
|
4666
4821
|
currentDate = this.date && this.date.valueOf(),
|
4667
4822
|
today = new Date();
|
4668
|
-
this.picker.find('.datepicker-days thead th
|
4823
|
+
this.picker.find('.datepicker-days thead th.switch')
|
4669
4824
|
.text(dates[this.language].months[month]+' '+year);
|
4670
4825
|
this.picker.find('tfoot th.today')
|
4671
4826
|
.text(dates[this.language].today)
|
@@ -4684,6 +4839,21 @@ Automatically shown in inline mode.
|
|
4684
4839
|
while(prevMonth.valueOf() < nextMonth) {
|
4685
4840
|
if (prevMonth.getUTCDay() == this.weekStart) {
|
4686
4841
|
html.push('<tr>');
|
4842
|
+
if(this.calendarWeeks){
|
4843
|
+
// ISO 8601: First week contains first thursday.
|
4844
|
+
// ISO also states week starts on Monday, but we can be more abstract here.
|
4845
|
+
var
|
4846
|
+
// Start of current week: based on weekstart/current date
|
4847
|
+
ws = new Date(+prevMonth + (this.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),
|
4848
|
+
// Thursday of this week
|
4849
|
+
th = new Date(+ws + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),
|
4850
|
+
// First Thursday of year, year from thursday
|
4851
|
+
yth = new Date(+(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay())%7*864e5),
|
4852
|
+
// Calendar week: ms between thursdays, div ms per day, div 7 days
|
4853
|
+
calWeek = (th - yth) / 864e5 / 7 + 1;
|
4854
|
+
html.push('<td class="cw">'+ calWeek +'</td>');
|
4855
|
+
|
4856
|
+
}
|
4687
4857
|
}
|
4688
4858
|
clsName = '';
|
4689
4859
|
if (prevMonth.getUTCFullYear() < year || (prevMonth.getUTCFullYear() == year && prevMonth.getUTCMonth() < month)) {
|
@@ -4819,19 +4989,29 @@ Automatically shown in inline mode.
|
|
4819
4989
|
if (!target.is('.disabled')) {
|
4820
4990
|
this.viewDate.setUTCDate(1);
|
4821
4991
|
if (target.is('.month')) {
|
4992
|
+
var day = 1;
|
4822
4993
|
var month = target.parent().find('span').index(target);
|
4994
|
+
var year = this.viewDate.getUTCFullYear();
|
4823
4995
|
this.viewDate.setUTCMonth(month);
|
4824
4996
|
this.element.trigger({
|
4825
4997
|
type: 'changeMonth',
|
4826
4998
|
date: this.viewDate
|
4827
4999
|
});
|
5000
|
+
if ( this.minViewMode == 1 ) {
|
5001
|
+
this._setDate(UTCDate(year, month, day,0,0,0,0));
|
5002
|
+
}
|
4828
5003
|
} else {
|
4829
5004
|
var year = parseInt(target.text(), 10)||0;
|
5005
|
+
var day = 1;
|
5006
|
+
var month = 0;
|
4830
5007
|
this.viewDate.setUTCFullYear(year);
|
4831
5008
|
this.element.trigger({
|
4832
5009
|
type: 'changeYear',
|
4833
5010
|
date: this.viewDate
|
4834
5011
|
});
|
5012
|
+
if ( this.minViewMode == 2 ) {
|
5013
|
+
this._setDate(UTCDate(year, month, day,0,0,0,0));
|
5014
|
+
}
|
4835
5015
|
}
|
4836
5016
|
this.showMode(-1);
|
4837
5017
|
this.fill();
|
@@ -5028,7 +5208,7 @@ Automatically shown in inline mode.
|
|
5028
5208
|
|
5029
5209
|
showMode: function(dir) {
|
5030
5210
|
if (dir) {
|
5031
|
-
this.viewMode = Math.max(
|
5211
|
+
this.viewMode = Math.max(this.minViewMode, Math.min(2, this.viewMode + dir));
|
5032
5212
|
}
|
5033
5213
|
/*
|
5034
5214
|
vitalets: fixing bug of very special conditions:
|
@@ -5288,7 +5468,6 @@ $(function(){
|
|
5288
5468
|
{value: 'us', text: 'United States'},
|
5289
5469
|
{value: 'ru', text: 'Russia'}
|
5290
5470
|
]
|
5291
|
-
}
|
5292
5471
|
});
|
5293
5472
|
});
|
5294
5473
|
</script>
|
@@ -5320,8 +5499,11 @@ $(function(){
|
|
5320
5499
|
//apply typeahead
|
5321
5500
|
this.$input.typeahead(this.options.typeahead);
|
5322
5501
|
|
5323
|
-
//
|
5324
|
-
|
5502
|
+
//patch some methods in typeahead
|
5503
|
+
var ta = this.$input.data('typeahead');
|
5504
|
+
ta.render = $.proxy(this.typeaheadRender, ta);
|
5505
|
+
ta.select = $.proxy(this.typeaheadSelect, ta);
|
5506
|
+
ta.move = $.proxy(this.typeaheadMove, ta);
|
5325
5507
|
|
5326
5508
|
this.renderClear();
|
5327
5509
|
this.setClass();
|
@@ -5400,7 +5582,7 @@ $(function(){
|
|
5400
5582
|
/*
|
5401
5583
|
Typeahead option methods used as defaults
|
5402
5584
|
*/
|
5403
|
-
/*jshint eqeqeq:false, curly: false, laxcomma: true*/
|
5585
|
+
/*jshint eqeqeq:false, curly: false, laxcomma: true, asi: true*/
|
5404
5586
|
matcher: function (item) {
|
5405
5587
|
return $.fn.typeahead.Constructor.prototype.matcher.call(this, item.text);
|
5406
5588
|
},
|
@@ -5424,7 +5606,6 @@ $(function(){
|
|
5424
5606
|
return $.fn.typeahead.Constructor.prototype.highlighter.call(this, item.text);
|
5425
5607
|
},
|
5426
5608
|
updater: function (item) {
|
5427
|
-
item = this.$menu.find('.active').data('item');
|
5428
5609
|
this.$element.data('value', item.value);
|
5429
5610
|
return item.text;
|
5430
5611
|
},
|
@@ -5435,7 +5616,7 @@ $(function(){
|
|
5435
5616
|
There are a lot of disscussion in bootstrap repo on this point and still no result.
|
5436
5617
|
See https://github.com/twitter/bootstrap/issues/5967
|
5437
5618
|
|
5438
|
-
This function just store item
|
5619
|
+
This function just store item via jQuery data() method instead of attr('data-value')
|
5439
5620
|
*/
|
5440
5621
|
typeaheadRender: function (items) {
|
5441
5622
|
var that = this;
|
@@ -5447,11 +5628,57 @@ $(function(){
|
|
5447
5628
|
return i[0];
|
5448
5629
|
});
|
5449
5630
|
|
5450
|
-
|
5631
|
+
//add option to disable autoselect of first line
|
5632
|
+
//see https://github.com/twitter/bootstrap/pull/4164
|
5633
|
+
if (this.options.autoSelect) {
|
5634
|
+
items.first().addClass('active');
|
5635
|
+
}
|
5451
5636
|
this.$menu.html(items);
|
5452
5637
|
return this;
|
5638
|
+
},
|
5639
|
+
|
5640
|
+
//add option to disable autoselect of first line
|
5641
|
+
//see https://github.com/twitter/bootstrap/pull/4164
|
5642
|
+
typeaheadSelect: function () {
|
5643
|
+
var val = this.$menu.find('.active').data('item')
|
5644
|
+
if(this.options.autoSelect || val){
|
5645
|
+
this.$element
|
5646
|
+
.val(this.updater(val))
|
5647
|
+
.change()
|
5648
|
+
}
|
5649
|
+
return this.hide()
|
5650
|
+
},
|
5651
|
+
|
5652
|
+
/*
|
5653
|
+
if autoSelect = false and nothing matched we need extra press onEnter that is not convinient.
|
5654
|
+
This patch fixes it.
|
5655
|
+
*/
|
5656
|
+
typeaheadMove: function (e) {
|
5657
|
+
if (!this.shown) return
|
5658
|
+
|
5659
|
+
switch(e.keyCode) {
|
5660
|
+
case 9: // tab
|
5661
|
+
case 13: // enter
|
5662
|
+
case 27: // escape
|
5663
|
+
if (!this.$menu.find('.active').length) return
|
5664
|
+
e.preventDefault()
|
5665
|
+
break
|
5666
|
+
|
5667
|
+
case 38: // up arrow
|
5668
|
+
e.preventDefault()
|
5669
|
+
this.prev()
|
5670
|
+
break
|
5671
|
+
|
5672
|
+
case 40: // down arrow
|
5673
|
+
e.preventDefault()
|
5674
|
+
this.next()
|
5675
|
+
break
|
5676
|
+
}
|
5677
|
+
|
5678
|
+
e.stopPropagation()
|
5453
5679
|
}
|
5454
|
-
|
5680
|
+
|
5681
|
+
/*jshint eqeqeq: true, curly: true, laxcomma: false, asi: false*/
|
5455
5682
|
|
5456
5683
|
});
|
5457
5684
|
|