bootstrap-editable-rails 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|