bootstrap-x-editable-rails 1.4.0 → 1.4.1
Sign up to get free protection for your applications and to get access to all the features.
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
# X-editable for Rails
|
1
|
+
# X-editable 1.4.1 for Rails
|
2
2
|
|
3
3
|
[X-editable](https://github.com/vitalets/x-editable) is an in-place editing plugin with support for Twitter Bootstrap, jQuery UI or pure jQuery.
|
4
4
|
|
5
|
-
The `bootstrap-x-editable-rails` gem integrates `X-editable` with
|
5
|
+
The `bootstrap-x-editable-rails` gem integrates `X-editable` with Rails asset pipeline. This gem only supports the Bootstrap part of X-editable.
|
6
6
|
|
7
7
|
## Usage
|
8
8
|
|
@@ -31,3 +31,14 @@ Add to your `app/assets/javascripts/application.js`
|
|
31
31
|
Add to your `app/assets/stylesheets/application.css`
|
32
32
|
|
33
33
|
*= require bootstrap-editable
|
34
|
+
|
35
|
+
## Updating the gem
|
36
|
+
There are two rake tasks designed to ease the maintenance of this gem.
|
37
|
+
|
38
|
+
The `update` task pulls the latest X-editable code from github and places images, stylesheets and javascripts in the correct gem paths. It also changes background-image properties in the stylesheet to asset pipeline equivalents.
|
39
|
+
|
40
|
+
rake update
|
41
|
+
|
42
|
+
The `build` task is a simple wrapper for `gem build`
|
43
|
+
|
44
|
+
rake build
|
data/Rakefile
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
desc "Update"
|
2
|
+
task :update do
|
3
|
+
src_path = "x-editable-src"
|
4
|
+
dist_path = "#{src_path}/dist/bootstrap-editable"
|
5
|
+
|
6
|
+
system("rm -rf #{src_path}")
|
7
|
+
|
8
|
+
system("git clone https://github.com/vitalets/x-editable #{src_path}")
|
9
|
+
system("cd #{src_path} && npm install")
|
10
|
+
system("cd #{src_path} && grunt build")
|
11
|
+
|
12
|
+
system("cp #{dist_path}/img/clear.png vendor/assets/images/")
|
13
|
+
system("cp #{dist_path}/img/loading.gif vendor/assets/images/")
|
14
|
+
system("cp #{dist_path}/css/bootstrap-editable.css vendor/assets/stylesheets/bootstrap-editable.scss")
|
15
|
+
system("cp #{dist_path}/js/bootstrap-editable.js vendor/assets/javascripts/")
|
16
|
+
|
17
|
+
fixes
|
18
|
+
|
19
|
+
system("rm -rf x-editable-src")
|
20
|
+
end
|
21
|
+
|
22
|
+
def fixes
|
23
|
+
replace_string_in_file("vendor/assets/stylesheets/bootstrap-editable.scss", "url('../img/loading.gif')", "image-url('loading.gif')")
|
24
|
+
replace_string_in_file("vendor/assets/stylesheets/bootstrap-editable.scss", "url('../img/clear.png')", "image-url('clear.png')")
|
25
|
+
end
|
26
|
+
|
27
|
+
def replace_string_in_file(file, find, replace)
|
28
|
+
file_content = File.read(file)
|
29
|
+
|
30
|
+
File.open(file, "w") do |f|
|
31
|
+
f.puts file_content.gsub!(find, replace)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
desc "Build"
|
36
|
+
task "build" do
|
37
|
+
system("gem build bootstrap-x-editable-rails.gemspec")
|
38
|
+
end
|
Binary file
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/*! X-editable - v1.4.
|
1
|
+
/*! X-editable - v1.4.1
|
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 */
|
@@ -16,7 +16,7 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
|
|
16
16
|
|
17
17
|
var EditableForm = function (div, options) {
|
18
18
|
this.options = $.extend({}, $.fn.editableform.defaults, options);
|
19
|
-
this.$div = $(div); //div, containing form. Not form tag
|
19
|
+
this.$div = $(div); //div, containing form. Not form tag. Not editable-element.
|
20
20
|
if(!this.options.scope) {
|
21
21
|
this.options.scope = this;
|
22
22
|
}
|
@@ -30,6 +30,7 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
|
|
30
30
|
this.input = this.options.input;
|
31
31
|
|
32
32
|
//set initial value
|
33
|
+
//todo: may be add check: typeof str === 'string' ?
|
33
34
|
this.value = this.input.str2value(this.options.value);
|
34
35
|
},
|
35
36
|
initTemplate: function() {
|
@@ -232,6 +233,7 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
|
|
232
233
|
}
|
233
234
|
|
234
235
|
//if success callback returns object like {newValue: <something>} --> use that value instead of submitted
|
236
|
+
//it is usefull if you want to chnage value in url-function
|
235
237
|
if(res && typeof res === 'object' && res.hasOwnProperty('newValue')) {
|
236
238
|
newValue = res.newValue;
|
237
239
|
}
|
@@ -387,18 +389,25 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
|
|
387
389
|
type: 'text',
|
388
390
|
/**
|
389
391
|
Url for submit, e.g. <code>'/post'</code>
|
390
|
-
If function - it will be called instead of ajax. Function
|
392
|
+
If function - it will be called instead of ajax. Function should return deferred object to run fail/done callbacks.
|
391
393
|
|
392
394
|
@property url
|
393
395
|
@type string|function
|
394
396
|
@default null
|
395
397
|
@example
|
396
398
|
url: function(params) {
|
399
|
+
var d = new $.Deferred;
|
397
400
|
if(params.value === 'abc') {
|
398
|
-
var d = new $.Deferred;
|
399
401
|
return d.reject('error message'); //returning error via deferred object
|
400
402
|
} else {
|
401
|
-
|
403
|
+
//async saving data in js model
|
404
|
+
someModel.asyncSaveMethod({
|
405
|
+
...,
|
406
|
+
success: function(){
|
407
|
+
d.resolve();
|
408
|
+
}
|
409
|
+
});
|
410
|
+
return d.promise();
|
402
411
|
}
|
403
412
|
}
|
404
413
|
**/
|
@@ -689,21 +698,34 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
|
|
689
698
|
/*
|
690
699
|
returns array items from sourceData having value property equal or inArray of 'value'
|
691
700
|
*/
|
692
|
-
itemsByValue: function(value, sourceData) {
|
701
|
+
itemsByValue: function(value, sourceData, valueProp) {
|
693
702
|
if(!sourceData || value === null) {
|
694
703
|
return [];
|
695
704
|
}
|
696
705
|
|
697
|
-
|
698
|
-
if(!$.isArray(value)) {
|
699
|
-
value = [value];
|
700
|
-
}
|
706
|
+
valueProp = valueProp || 'value';
|
701
707
|
|
702
|
-
|
703
|
-
|
704
|
-
|
708
|
+
var isValArray = $.isArray(value),
|
709
|
+
result = [],
|
710
|
+
that = this;
|
711
|
+
|
712
|
+
$.each(sourceData, function(i, o) {
|
713
|
+
if(o.children) {
|
714
|
+
result = result.concat(that.itemsByValue(value, o.children));
|
715
|
+
} else {
|
716
|
+
/*jslint eqeq: true*/
|
717
|
+
if(isValArray) {
|
718
|
+
if($.grep(value, function(v){ return v == (o && typeof o === 'object' ? o[valueProp] : o); }).length) {
|
719
|
+
result.push(o);
|
720
|
+
}
|
721
|
+
} else {
|
722
|
+
if(value == (o && typeof o === 'object' ? o[valueProp] : o)) {
|
723
|
+
result.push(o);
|
724
|
+
}
|
725
|
+
}
|
726
|
+
/*jslint eqeq: false*/
|
727
|
+
}
|
705
728
|
});
|
706
|
-
/*jslint eqeq: false*/
|
707
729
|
|
708
730
|
return result;
|
709
731
|
},
|
@@ -785,8 +807,8 @@ Applied as jQuery method.
|
|
785
807
|
innerCss: null, //tbd in child class
|
786
808
|
init: function(element, options) {
|
787
809
|
this.$element = $(element);
|
788
|
-
//
|
789
|
-
this.options = $.extend({}, $.fn.editableContainer.defaults,
|
810
|
+
//since 1.4.1 container do not use data-* directly as they already merged into options.
|
811
|
+
this.options = $.extend({}, $.fn.editableContainer.defaults, options);
|
790
812
|
this.splitOptions();
|
791
813
|
|
792
814
|
//set scope of form callbacks to element
|
@@ -878,6 +900,7 @@ Applied as jQuery method.
|
|
878
900
|
cancel: $.proxy(function(){ this.hide('cancel'); }, this), //click on calcel button
|
879
901
|
show: $.proxy(this.setPosition, this), //re-position container every time form is shown (occurs each time after loading state)
|
880
902
|
rendering: $.proxy(this.setPosition, this), //this allows to place container correctly when loading shown
|
903
|
+
resize: $.proxy(this.setPosition, this), //this allows to re-position container when form size is changed
|
881
904
|
rendered: $.proxy(function(){
|
882
905
|
/**
|
883
906
|
Fired when container is shown and form is rendered (for select will wait for loading dropdown options)
|
@@ -1004,7 +1027,6 @@ Applied as jQuery method.
|
|
1004
1027
|
},
|
1005
1028
|
|
1006
1029
|
save: function(e, params) {
|
1007
|
-
this.hide('save');
|
1008
1030
|
/**
|
1009
1031
|
Fired when new value was submitted. You can use <code>$(this).data('editableContainer')</code> inside handler to access to editableContainer instance
|
1010
1032
|
|
@@ -1025,6 +1047,9 @@ Applied as jQuery method.
|
|
1025
1047
|
});
|
1026
1048
|
**/
|
1027
1049
|
this.$element.triggerHandler('save', params);
|
1050
|
+
|
1051
|
+
//hide must be after trigger, as saving value may require methods od plugin, applied to input
|
1052
|
+
this.hide('save');
|
1028
1053
|
},
|
1029
1054
|
|
1030
1055
|
/**
|
@@ -1255,12 +1280,14 @@ Applied as jQuery method.
|
|
1255
1280
|
innerHide: function () {
|
1256
1281
|
this.$tip.hide(this.options.anim, $.proxy(function() {
|
1257
1282
|
this.$element.show();
|
1258
|
-
this.
|
1283
|
+
this.innerDestroy();
|
1259
1284
|
}, this));
|
1260
1285
|
},
|
1261
1286
|
|
1262
1287
|
innerDestroy: function() {
|
1263
|
-
this.tip()
|
1288
|
+
if(this.tip()) {
|
1289
|
+
this.tip().empty().remove();
|
1290
|
+
}
|
1264
1291
|
}
|
1265
1292
|
});
|
1266
1293
|
|
@@ -1275,8 +1302,13 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1275
1302
|
|
1276
1303
|
var Editable = function (element, options) {
|
1277
1304
|
this.$element = $(element);
|
1278
|
-
|
1279
|
-
this.
|
1305
|
+
//data-* has more priority over js options: because dynamically created elements may change data-*
|
1306
|
+
this.options = $.extend({}, $.fn.editable.defaults, options, $.fn.editableutils.getConfigData(this.$element));
|
1307
|
+
if(this.options.selector) {
|
1308
|
+
this.initLive();
|
1309
|
+
} else {
|
1310
|
+
this.init();
|
1311
|
+
}
|
1280
1312
|
};
|
1281
1313
|
|
1282
1314
|
Editable.prototype = {
|
@@ -1319,8 +1351,10 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1319
1351
|
if(this.options.toggle !== 'manual') {
|
1320
1352
|
this.$element.addClass('editable-click');
|
1321
1353
|
this.$element.on(this.options.toggle + '.editable', $.proxy(function(e){
|
1354
|
+
//prevent following link
|
1322
1355
|
e.preventDefault();
|
1323
|
-
|
1356
|
+
|
1357
|
+
//stop propagation not required because in document click handler it checks event target
|
1324
1358
|
//e.stopPropagation();
|
1325
1359
|
|
1326
1360
|
if(this.options.toggle === 'mouseenter') {
|
@@ -1362,6 +1396,24 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1362
1396
|
}, this));
|
1363
1397
|
},
|
1364
1398
|
|
1399
|
+
/*
|
1400
|
+
Initializes parent element for live editables
|
1401
|
+
*/
|
1402
|
+
initLive: function() {
|
1403
|
+
//store selector
|
1404
|
+
var selector = this.options.selector;
|
1405
|
+
//modify options for child elements
|
1406
|
+
this.options.selector = false;
|
1407
|
+
this.options.autotext = 'never';
|
1408
|
+
//listen toggle events
|
1409
|
+
this.$element.on(this.options.toggle + '.editable', selector, $.proxy(function(e){
|
1410
|
+
var $target = $(e.target);
|
1411
|
+
if(!$target.data('editable')) {
|
1412
|
+
$target.editable(this.options).trigger(e);
|
1413
|
+
}
|
1414
|
+
}, this));
|
1415
|
+
},
|
1416
|
+
|
1365
1417
|
/*
|
1366
1418
|
Renders value into element's text.
|
1367
1419
|
Can call custom display method from options.
|
@@ -1375,8 +1427,8 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1375
1427
|
return;
|
1376
1428
|
}
|
1377
1429
|
|
1378
|
-
//if
|
1379
|
-
if(this.input.
|
1430
|
+
//if input has `value2htmlFinal` method, we pass callback in third param to be called when source is loaded
|
1431
|
+
if(this.input.value2htmlFinal) {
|
1380
1432
|
return this.input.value2html(this.value, this.$element[0], this.options.display, response);
|
1381
1433
|
//if display method defined --> use it
|
1382
1434
|
} else if(typeof this.options.display === 'function') {
|
@@ -1394,7 +1446,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1394
1446
|
enable: function() {
|
1395
1447
|
this.options.disabled = false;
|
1396
1448
|
this.$element.removeClass('editable-disabled');
|
1397
|
-
this.handleEmpty();
|
1449
|
+
this.handleEmpty(this.isEmpty);
|
1398
1450
|
if(this.options.toggle !== 'manual') {
|
1399
1451
|
if(this.$element.attr('tabindex') === '-1') {
|
1400
1452
|
this.$element.removeAttr('tabindex');
|
@@ -1410,7 +1462,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1410
1462
|
this.options.disabled = true;
|
1411
1463
|
this.hide();
|
1412
1464
|
this.$element.addClass('editable-disabled');
|
1413
|
-
this.handleEmpty();
|
1465
|
+
this.handleEmpty(this.isEmpty);
|
1414
1466
|
//do not stop focus on this element
|
1415
1467
|
this.$element.attr('tabindex', -1);
|
1416
1468
|
},
|
@@ -1471,27 +1523,33 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1471
1523
|
},
|
1472
1524
|
|
1473
1525
|
/*
|
1474
|
-
* set emptytext if element is empty
|
1526
|
+
* set emptytext if element is empty
|
1475
1527
|
*/
|
1476
|
-
handleEmpty: function () {
|
1528
|
+
handleEmpty: function (isEmpty) {
|
1477
1529
|
//do not handle empty if we do not display anything
|
1478
1530
|
if(this.options.display === false) {
|
1479
1531
|
return;
|
1480
1532
|
}
|
1481
1533
|
|
1482
|
-
|
1534
|
+
this.isEmpty = isEmpty !== undefined ? isEmpty : $.trim(this.$element.text()) === '';
|
1535
|
+
|
1483
1536
|
//emptytext shown only for enabled
|
1484
1537
|
if(!this.options.disabled) {
|
1485
|
-
if (
|
1486
|
-
this.$element.
|
1487
|
-
|
1488
|
-
|
1538
|
+
if (this.isEmpty) {
|
1539
|
+
this.$element.text(this.options.emptytext);
|
1540
|
+
if(this.options.emptyclass) {
|
1541
|
+
this.$element.addClass(this.options.emptyclass);
|
1542
|
+
}
|
1543
|
+
} else if(this.options.emptyclass) {
|
1544
|
+
this.$element.removeClass(this.options.emptyclass);
|
1489
1545
|
}
|
1490
1546
|
} else {
|
1491
1547
|
//below required if element disable property was changed
|
1492
|
-
if(this
|
1548
|
+
if(this.isEmpty) {
|
1493
1549
|
this.$element.empty();
|
1494
|
-
this
|
1550
|
+
if(this.options.emptyclass) {
|
1551
|
+
this.$element.removeClass(this.options.emptyclass);
|
1552
|
+
}
|
1495
1553
|
}
|
1496
1554
|
}
|
1497
1555
|
},
|
@@ -1513,6 +1571,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1513
1571
|
input: this.input //pass input to form (as it is already created)
|
1514
1572
|
});
|
1515
1573
|
this.$element.editableContainer(containerOptions);
|
1574
|
+
//listen `save` event
|
1516
1575
|
this.$element.on("save.internal", $.proxy(this.save, this));
|
1517
1576
|
this.container = this.$element.data('editableContainer');
|
1518
1577
|
} else if(this.container.tip().is(':visible')) {
|
@@ -1550,13 +1609,29 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1550
1609
|
* called when form was submitted
|
1551
1610
|
*/
|
1552
1611
|
save: function(e, params) {
|
1553
|
-
//
|
1554
|
-
if(
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1612
|
+
//mark element with unsaved class if needed
|
1613
|
+
if(this.options.unsavedclass) {
|
1614
|
+
/*
|
1615
|
+
Add unsaved css to element if:
|
1616
|
+
- url is not user's function
|
1617
|
+
- value was not sent to server
|
1618
|
+
- params.response === undefined, that means data was not sent
|
1619
|
+
- value changed
|
1620
|
+
*/
|
1621
|
+
var sent = false;
|
1622
|
+
sent = sent || typeof this.options.url === 'function';
|
1623
|
+
sent = sent || this.options.display === false;
|
1624
|
+
sent = sent || params.response !== undefined;
|
1625
|
+
sent = sent || (this.options.savenochange && this.input.value2str(this.value) !== this.input.value2str(params.newValue));
|
1626
|
+
|
1627
|
+
if(sent) {
|
1628
|
+
this.$element.removeClass(this.options.unsavedclass);
|
1629
|
+
} else {
|
1630
|
+
this.$element.addClass(this.options.unsavedclass);
|
1631
|
+
}
|
1558
1632
|
}
|
1559
1633
|
|
1634
|
+
//set new value
|
1560
1635
|
this.setValue(params.newValue, false, params.response);
|
1561
1636
|
|
1562
1637
|
/**
|
@@ -1648,7 +1723,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1648
1723
|
url: '/post',
|
1649
1724
|
pk: 1
|
1650
1725
|
});
|
1651
|
-
**/
|
1726
|
+
**/
|
1652
1727
|
$.fn.editable = function (option) {
|
1653
1728
|
//special API methods returning non-jquery object
|
1654
1729
|
var result = {}, args = arguments, datakey = 'editable';
|
@@ -1665,7 +1740,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1665
1740
|
username: "username is required",
|
1666
1741
|
fullname: "fullname should be minimum 3 letters length"
|
1667
1742
|
}
|
1668
|
-
**/
|
1743
|
+
**/
|
1669
1744
|
case 'validate':
|
1670
1745
|
this.each(function () {
|
1671
1746
|
var $this = $(this), data = $this.data(datakey), error;
|
@@ -1686,7 +1761,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1686
1761
|
username: "superuser",
|
1687
1762
|
fullname: "John"
|
1688
1763
|
}
|
1689
|
-
**/
|
1764
|
+
**/
|
1690
1765
|
case 'getValue':
|
1691
1766
|
this.each(function () {
|
1692
1767
|
var $this = $(this), data = $this.data(datakey);
|
@@ -1705,11 +1780,11 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1705
1780
|
@param {object} options
|
1706
1781
|
@param {object} options.url url to submit data
|
1707
1782
|
@param {object} options.data additional data to submit
|
1708
|
-
@param {object} options.ajaxOptions additional ajax options
|
1783
|
+
@param {object} options.ajaxOptions additional ajax options
|
1709
1784
|
@param {function} options.error(obj) error handler
|
1710
1785
|
@param {function} options.success(obj,config) success handler
|
1711
1786
|
@returns {Object} jQuery object
|
1712
|
-
**/
|
1787
|
+
**/
|
1713
1788
|
case 'submit': //collects value, validate and submit to server for creating new record
|
1714
1789
|
var config = arguments[1] || {},
|
1715
1790
|
$elems = this,
|
@@ -1860,7 +1935,51 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1860
1935
|
}
|
1861
1936
|
}
|
1862
1937
|
**/
|
1863
|
-
display: null
|
1938
|
+
display: null,
|
1939
|
+
/**
|
1940
|
+
Css class applied when editable text is empty.
|
1941
|
+
|
1942
|
+
@property emptyclass
|
1943
|
+
@type string
|
1944
|
+
@since 1.4.1
|
1945
|
+
@default editable-empty
|
1946
|
+
**/
|
1947
|
+
emptyclass: 'editable-empty',
|
1948
|
+
/**
|
1949
|
+
Css class applied when value was stored but not sent to server (`pk` is empty or `send = 'never'`).
|
1950
|
+
You may set it to `null` if you work with editables locally and submit them together.
|
1951
|
+
|
1952
|
+
@property unsavedclass
|
1953
|
+
@type string
|
1954
|
+
@since 1.4.1
|
1955
|
+
@default editable-unsaved
|
1956
|
+
**/
|
1957
|
+
unsavedclass: 'editable-unsaved',
|
1958
|
+
/**
|
1959
|
+
If a css selector is provided, editable will be delegated to the specified targets.
|
1960
|
+
Usefull for dynamically generated DOM elements.
|
1961
|
+
**Please note**, that delegated targets can't use `emptytext` and `autotext` options,
|
1962
|
+
as they are initialized after first click.
|
1963
|
+
|
1964
|
+
@property selector
|
1965
|
+
@type string
|
1966
|
+
@since 1.4.1
|
1967
|
+
@default null
|
1968
|
+
@example
|
1969
|
+
<div id="user">
|
1970
|
+
<a href="#" data-name="username" data-type="text" title="Username">awesome</a>
|
1971
|
+
<a href="#" data-name="group" data-type="select" data-source="/groups" data-value="1" title="Group">Operator</a>
|
1972
|
+
</div>
|
1973
|
+
|
1974
|
+
<script>
|
1975
|
+
$('#user').editable({
|
1976
|
+
selector: 'a',
|
1977
|
+
url: '/post',
|
1978
|
+
pk: 1
|
1979
|
+
});
|
1980
|
+
</script>
|
1981
|
+
**/
|
1982
|
+
selector: null
|
1864
1983
|
};
|
1865
1984
|
|
1866
1985
|
}(window.jQuery));
|
@@ -2053,15 +2172,7 @@ To create your own input you can inherit from this class.
|
|
2053
2172
|
@type string
|
2054
2173
|
@default input-medium
|
2055
2174
|
**/
|
2056
|
-
inputclass: 'input-medium'
|
2057
|
-
/**
|
2058
|
-
Name attribute of input
|
2059
|
-
|
2060
|
-
@property name
|
2061
|
-
@type string
|
2062
|
-
@default null
|
2063
|
-
**/
|
2064
|
-
name: null
|
2175
|
+
inputclass: 'input-medium'
|
2065
2176
|
};
|
2066
2177
|
|
2067
2178
|
$.extend($.fn.editabletypes, {abstractinput: AbstractInput});
|
@@ -2214,7 +2325,7 @@ List - abstract class for inputs that have source option loaded from js array or
|
|
2214
2325
|
}, this)
|
2215
2326
|
});
|
2216
2327
|
} else { //options as json/array/function
|
2217
|
-
if (
|
2328
|
+
if ($.isFunction(this.options.source)) {
|
2218
2329
|
this.sourceData = this.makeArray(this.options.source());
|
2219
2330
|
} else {
|
2220
2331
|
this.sourceData = this.makeArray(this.options.source);
|
@@ -2270,35 +2381,45 @@ List - abstract class for inputs that have source option loaded from js array or
|
|
2270
2381
|
* convert data to array suitable for sourceData, e.g. [{value: 1, text: 'abc'}, {...}]
|
2271
2382
|
*/
|
2272
2383
|
makeArray: function(data) {
|
2273
|
-
var count, obj, result = [],
|
2384
|
+
var count, obj, result = [], item, iterateItem;
|
2274
2385
|
if(!data || typeof data === 'string') {
|
2275
2386
|
return null;
|
2276
2387
|
}
|
2277
2388
|
|
2278
2389
|
if($.isArray(data)) { //array
|
2279
|
-
|
2390
|
+
/*
|
2391
|
+
function to iterate inside item of array if item is object.
|
2392
|
+
Caclulates count of keys in item and store in obj.
|
2393
|
+
*/
|
2394
|
+
iterateItem = function (k, v) {
|
2280
2395
|
obj = {value: k, text: v};
|
2281
2396
|
if(count++ >= 2) {
|
2282
|
-
return false;// exit each if
|
2397
|
+
return false;// exit from `each` if item has more than one key.
|
2283
2398
|
}
|
2284
2399
|
};
|
2285
2400
|
|
2286
2401
|
for(var i = 0; i < data.length; i++) {
|
2287
|
-
|
2288
|
-
|
2289
|
-
|
2290
|
-
|
2402
|
+
item = data[i];
|
2403
|
+
if(typeof item === 'object') {
|
2404
|
+
count = 0; //count of keys inside item
|
2405
|
+
$.each(item, iterateItem);
|
2406
|
+
//case: [{val1: 'text1'}, {val2: 'text2} ...]
|
2407
|
+
if(count === 1) {
|
2291
2408
|
result.push(obj);
|
2292
|
-
|
2293
|
-
|
2294
|
-
|
2295
|
-
|
2409
|
+
//case: [{value: 1, text: 'text1'}, {value: 2, text: 'text2'}, ...]
|
2410
|
+
} else if(count > 1) {
|
2411
|
+
//removed check of existance: item.hasOwnProperty('value') && item.hasOwnProperty('text')
|
2412
|
+
if(item.children) {
|
2413
|
+
item.children = this.makeArray(item.children);
|
2414
|
+
}
|
2415
|
+
result.push(item);
|
2296
2416
|
}
|
2297
2417
|
} else {
|
2298
|
-
|
2418
|
+
//case: ['text1', 'text2' ...]
|
2419
|
+
result.push({value: item, text: item});
|
2299
2420
|
}
|
2300
2421
|
}
|
2301
|
-
} else { //
|
2422
|
+
} else { //case: {val1: 'text1', val2: 'text2, ...}
|
2302
2423
|
$.each(data, function (k, v) {
|
2303
2424
|
result.push({value: k, text: v});
|
2304
2425
|
});
|
@@ -2321,12 +2442,16 @@ List - abstract class for inputs that have source option loaded from js array or
|
|
2321
2442
|
List.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
|
2322
2443
|
/**
|
2323
2444
|
Source data for list.
|
2324
|
-
If **array** - it should be in format: `[{value: 1, text: "text1"}, {...
|
2445
|
+
If **array** - it should be in format: `[{value: 1, text: "text1"}, {value: 2, text: "text2"}, ...]`
|
2325
2446
|
For compability, object format is also supported: `{"1": "text1", "2": "text2" ...}` but it does not guarantee elements order.
|
2326
2447
|
|
2327
2448
|
If **string** - considered ajax url to load items. In that case results will be cached for fields with the same source and name. See also `sourceCache` option.
|
2328
2449
|
|
2329
2450
|
If **function**, it should return data in format above (since 1.4.0).
|
2451
|
+
|
2452
|
+
Since 1.4.1 key `children` supported to render OPTGROUP (for **select** input only).
|
2453
|
+
`[{text: "group1", children: [{value: 1, text: "text1"}, {value: 2, text: "text2"}]}, ...]`
|
2454
|
+
|
2330
2455
|
|
2331
2456
|
@property source
|
2332
2457
|
@type string | array | object | function
|
@@ -2350,8 +2475,8 @@ List - abstract class for inputs that have source option loaded from js array or
|
|
2350
2475
|
**/
|
2351
2476
|
sourceError: 'Error when loading list',
|
2352
2477
|
/**
|
2353
|
-
if <code>true</code> and source is **string url** - results will be cached for fields with the same source
|
2354
|
-
Usefull for editable
|
2478
|
+
if <code>true</code> and source is **string url** - results will be cached for fields with the same source.
|
2479
|
+
Usefull for editable column in grid to prevent extra requests.
|
2355
2480
|
|
2356
2481
|
@property sourceCache
|
2357
2482
|
@type boolean
|
@@ -2415,10 +2540,7 @@ $(function(){
|
|
2415
2540
|
.keyup($.proxy(this.toggleClear, this))
|
2416
2541
|
.parent().css('position', 'relative');
|
2417
2542
|
|
2418
|
-
this.$clear.click($.proxy(
|
2419
|
-
this.$clear.hide();
|
2420
|
-
this.$input.val('').focus();
|
2421
|
-
}, this));
|
2543
|
+
this.$clear.click($.proxy(this.clear, this));
|
2422
2544
|
}
|
2423
2545
|
},
|
2424
2546
|
|
@@ -2443,12 +2565,17 @@ $(function(){
|
|
2443
2565
|
return;
|
2444
2566
|
}
|
2445
2567
|
|
2446
|
-
if(this.$input.val()) {
|
2568
|
+
if(this.$input.val().length) {
|
2447
2569
|
this.$clear.show();
|
2448
2570
|
} else {
|
2449
2571
|
this.$clear.hide();
|
2450
2572
|
}
|
2451
|
-
}
|
2573
|
+
},
|
2574
|
+
|
2575
|
+
clear: function() {
|
2576
|
+
this.$clear.hide();
|
2577
|
+
this.$input.val('').focus();
|
2578
|
+
}
|
2452
2579
|
});
|
2453
2580
|
|
2454
2581
|
Text.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
|
@@ -2622,14 +2749,21 @@ $(function(){
|
|
2622
2749
|
$.extend(Select.prototype, {
|
2623
2750
|
renderList: function() {
|
2624
2751
|
this.$input.empty();
|
2625
|
-
|
2626
|
-
if(!$.isArray(this.sourceData)) {
|
2627
|
-
return;
|
2628
|
-
}
|
2629
2752
|
|
2630
|
-
|
2631
|
-
|
2632
|
-
|
2753
|
+
var fillItems = function($el, data) {
|
2754
|
+
if($.isArray(data)) {
|
2755
|
+
for(var i=0; i<data.length; i++) {
|
2756
|
+
if(data[i].children) {
|
2757
|
+
$el.append(fillItems($('<optgroup>', {label: data[i].text}), data[i].children));
|
2758
|
+
} else {
|
2759
|
+
$el.append($('<option>', {value: data[i].value}).text(data[i].text));
|
2760
|
+
}
|
2761
|
+
}
|
2762
|
+
}
|
2763
|
+
return $el;
|
2764
|
+
};
|
2765
|
+
|
2766
|
+
fillItems(this.$input, this.sourceData);
|
2633
2767
|
|
2634
2768
|
this.setClass();
|
2635
2769
|
|
@@ -2714,8 +2848,7 @@ $(function(){
|
|
2714
2848
|
for(var i=0; i<this.sourceData.length; i++) {
|
2715
2849
|
$label = $('<label>').append($('<input>', {
|
2716
2850
|
type: 'checkbox',
|
2717
|
-
value: this.sourceData[i].value
|
2718
|
-
name: this.options.name
|
2851
|
+
value: this.sourceData[i].value
|
2719
2852
|
}))
|
2720
2853
|
.append($('<span>').text(' '+this.sourceData[i].text));
|
2721
2854
|
|
@@ -2744,7 +2877,7 @@ $(function(){
|
|
2744
2877
|
|
2745
2878
|
//set checked on required checkboxes
|
2746
2879
|
value2input: function(value) {
|
2747
|
-
this.$input.
|
2880
|
+
this.$input.prop('checked', false);
|
2748
2881
|
if($.isArray(value) && value.length) {
|
2749
2882
|
this.$input.each(function(i, el) {
|
2750
2883
|
var $el = $(el);
|
@@ -2753,7 +2886,7 @@ $(function(){
|
|
2753
2886
|
/*jslint eqeq: true*/
|
2754
2887
|
if($el.val() == val) {
|
2755
2888
|
/*jslint eqeq: false*/
|
2756
|
-
$el.
|
2889
|
+
$el.prop('checked', true);
|
2757
2890
|
}
|
2758
2891
|
});
|
2759
2892
|
});
|
@@ -2992,6 +3125,199 @@ Range (inherit from number)
|
|
2992
3125
|
$.fn.editabletypes.range = Range;
|
2993
3126
|
}(window.jQuery));
|
2994
3127
|
/**
|
3128
|
+
Select2 input. Based on amazing work of Igor Vaynberg https://github.com/ivaynberg/select2.
|
3129
|
+
Please see [original docs](http://ivaynberg.github.com/select2) for detailed description and options.
|
3130
|
+
You should manually include select2 distributive:
|
3131
|
+
|
3132
|
+
<link href="select2/select2.css" rel="stylesheet" type="text/css"></link>
|
3133
|
+
<script src="select2/select2.js"></script>
|
3134
|
+
|
3135
|
+
@class select2
|
3136
|
+
@extends abstractinput
|
3137
|
+
@since 1.4.1
|
3138
|
+
@final
|
3139
|
+
@example
|
3140
|
+
<a href="#" id="country" data-type="select2" data-pk="1" data-value="ru" data-url="/post" data-original-title="Select country"></a>
|
3141
|
+
<script>
|
3142
|
+
$(function(){
|
3143
|
+
$('#country').editable({
|
3144
|
+
source: [
|
3145
|
+
{id: 'gb', text: 'Great Britain'},
|
3146
|
+
{id: 'us', text: 'United States'},
|
3147
|
+
{id: 'ru', text: 'Russia'}
|
3148
|
+
],
|
3149
|
+
select2: {
|
3150
|
+
multiple: true
|
3151
|
+
}
|
3152
|
+
});
|
3153
|
+
});
|
3154
|
+
</script>
|
3155
|
+
**/
|
3156
|
+
(function ($) {
|
3157
|
+
|
3158
|
+
var Constructor = function (options) {
|
3159
|
+
this.init('select2', options, Constructor.defaults);
|
3160
|
+
|
3161
|
+
options.select2 = options.select2 || {};
|
3162
|
+
|
3163
|
+
var that = this,
|
3164
|
+
mixin = {
|
3165
|
+
placeholder: options.placeholder
|
3166
|
+
};
|
3167
|
+
|
3168
|
+
//detect whether it is multi-valued
|
3169
|
+
this.isMultiple = options.select2.tags || options.select2.multiple;
|
3170
|
+
|
3171
|
+
//if not `tags` mode, we need define init set data from source
|
3172
|
+
if(!options.select2.tags) {
|
3173
|
+
if(options.source) {
|
3174
|
+
mixin.data = options.source;
|
3175
|
+
}
|
3176
|
+
|
3177
|
+
//this function can be defaulted in seletc2. See https://github.com/ivaynberg/select2/issues/710
|
3178
|
+
mixin.initSelection = function (element, callback) {
|
3179
|
+
var val = that.str2value(element.val()),
|
3180
|
+
data = $.fn.editableutils.itemsByValue(val, mixin.data, 'id');
|
3181
|
+
|
3182
|
+
//for single-valued mode should not use array. Take first element instead.
|
3183
|
+
if($.isArray(data) && data.length && !that.isMultiple) {
|
3184
|
+
data = data[0];
|
3185
|
+
}
|
3186
|
+
|
3187
|
+
callback(data);
|
3188
|
+
};
|
3189
|
+
}
|
3190
|
+
|
3191
|
+
//overriding objects in config (as by default jQuery extend() is not recursive)
|
3192
|
+
this.options.select2 = $.extend({}, Constructor.defaults.select2, mixin, options.select2);
|
3193
|
+
};
|
3194
|
+
|
3195
|
+
$.fn.editableutils.inherit(Constructor, $.fn.editabletypes.abstractinput);
|
3196
|
+
|
3197
|
+
$.extend(Constructor.prototype, {
|
3198
|
+
render: function() {
|
3199
|
+
this.setClass();
|
3200
|
+
//apply select2
|
3201
|
+
this.$input.select2(this.options.select2);
|
3202
|
+
|
3203
|
+
//trigger resize of editableform to re-position container in multi-valued mode
|
3204
|
+
if(this.isMultiple) {
|
3205
|
+
this.$input.on('change', function() {
|
3206
|
+
$(this).closest('form').parent().triggerHandler('resize');
|
3207
|
+
});
|
3208
|
+
}
|
3209
|
+
|
3210
|
+
},
|
3211
|
+
|
3212
|
+
value2html: function(value, element) {
|
3213
|
+
var text = '', data;
|
3214
|
+
if(this.$input) { //when submitting form
|
3215
|
+
data = this.$input.select2('data');
|
3216
|
+
} else { //on init (autotext)
|
3217
|
+
//here select2 instance not created yet and data may be even not loaded.
|
3218
|
+
//we can check data/tags property of select config and if exist lookup text
|
3219
|
+
if(this.options.select2.tags) {
|
3220
|
+
data = value;
|
3221
|
+
} else if(this.options.select2.data) {
|
3222
|
+
data = $.fn.editableutils.itemsByValue(value, this.options.select2.data, 'id');
|
3223
|
+
}
|
3224
|
+
}
|
3225
|
+
|
3226
|
+
if($.isArray(data)) {
|
3227
|
+
//collect selected data and show with separator
|
3228
|
+
text = [];
|
3229
|
+
$.each(data, function(k, v){
|
3230
|
+
text.push(v && typeof v === 'object' ? v.text : v);
|
3231
|
+
});
|
3232
|
+
} else if(data) {
|
3233
|
+
text = data.text;
|
3234
|
+
}
|
3235
|
+
|
3236
|
+
text = $.isArray(text) ? text.join(this.options.viewseparator) : text;
|
3237
|
+
|
3238
|
+
$(element).text(text);
|
3239
|
+
},
|
3240
|
+
|
3241
|
+
html2value: function(html) {
|
3242
|
+
return this.options.select2.tags ? this.str2value(html, this.options.viewseparator) : null;
|
3243
|
+
},
|
3244
|
+
|
3245
|
+
value2input: function(value) {
|
3246
|
+
this.$input.val(value).trigger('change');
|
3247
|
+
},
|
3248
|
+
|
3249
|
+
input2value: function() {
|
3250
|
+
return this.$input.select2('val');
|
3251
|
+
},
|
3252
|
+
|
3253
|
+
str2value: function(str, separator) {
|
3254
|
+
if(typeof str !== 'string' || !this.isMultiple) {
|
3255
|
+
return str;
|
3256
|
+
}
|
3257
|
+
|
3258
|
+
separator = separator || this.options.select2.separator || $.fn.select2.defaults.separator;
|
3259
|
+
|
3260
|
+
var val, i, l;
|
3261
|
+
|
3262
|
+
if (str === null || str.length < 1) {
|
3263
|
+
return null;
|
3264
|
+
}
|
3265
|
+
val = str.split(separator);
|
3266
|
+
for (i = 0, l = val.length; i < l; i = i + 1) {
|
3267
|
+
val[i] = $.trim(val[i]);
|
3268
|
+
}
|
3269
|
+
|
3270
|
+
return val;
|
3271
|
+
}
|
3272
|
+
|
3273
|
+
});
|
3274
|
+
|
3275
|
+
Constructor.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
|
3276
|
+
/**
|
3277
|
+
@property tpl
|
3278
|
+
@default <input type="hidden">
|
3279
|
+
**/
|
3280
|
+
tpl:'<input type="hidden">',
|
3281
|
+
/**
|
3282
|
+
Configuration of select2. [Full list of options](http://ivaynberg.github.com/select2).
|
3283
|
+
|
3284
|
+
@property select2
|
3285
|
+
@type object
|
3286
|
+
@default null
|
3287
|
+
**/
|
3288
|
+
select2: null,
|
3289
|
+
/**
|
3290
|
+
Placeholder attribute of select
|
3291
|
+
|
3292
|
+
@property placeholder
|
3293
|
+
@type string
|
3294
|
+
@default null
|
3295
|
+
**/
|
3296
|
+
placeholder: null,
|
3297
|
+
/**
|
3298
|
+
Source data for select. It will be assigned to select2 `data` property and kept here just for convenience.
|
3299
|
+
Please note, that format is different from simple `select` input: use 'id' instead of 'value'.
|
3300
|
+
E.g. `[{id: 1, text: "text1"}, {id: 2, text: "text2"}, ...]`.
|
3301
|
+
|
3302
|
+
@property source
|
3303
|
+
@type array
|
3304
|
+
@default null
|
3305
|
+
**/
|
3306
|
+
source: null,
|
3307
|
+
/**
|
3308
|
+
Separator used to display tags.
|
3309
|
+
|
3310
|
+
@property viewseparator
|
3311
|
+
@type string
|
3312
|
+
@default ', '
|
3313
|
+
**/
|
3314
|
+
viewseparator: ', '
|
3315
|
+
});
|
3316
|
+
|
3317
|
+
$.fn.editabletypes.select2 = Constructor;
|
3318
|
+
|
3319
|
+
}(window.jQuery));
|
3320
|
+
/**
|
2995
3321
|
* Combodate - 1.0.1
|
2996
3322
|
* Dropdown date and time picker.
|
2997
3323
|
* Converts text input into dropdowns to pick day, month, year, hour, minute and second.
|
@@ -4934,3 +5260,225 @@ Automatically shown in inline mode.
|
|
4934
5260
|
$.fn.datepicker.DPGlobal = DPGlobal;
|
4935
5261
|
|
4936
5262
|
}( window.jQuery );
|
5263
|
+
|
5264
|
+
/**
|
5265
|
+
Typeahead input (bootstrap only). Based on Twitter Bootstrap [typeahead](http://twitter.github.com/bootstrap/javascript.html#typeahead).
|
5266
|
+
Depending on `source` format typeahead operates in two modes:
|
5267
|
+
|
5268
|
+
* **strings**:
|
5269
|
+
When `source` defined as array of strings, e.g. `['text1', 'text2', 'text3' ...]`.
|
5270
|
+
User can submit one of these strings or any text entered in input (even if it is not matching source).
|
5271
|
+
|
5272
|
+
* **objects**:
|
5273
|
+
When `source` defined as array of objects, e.g. `[{value: 1, text: "text1"}, {value: 2, text: "text2"}, ...]`.
|
5274
|
+
User can submit only values that are in source (otherwise `null` is submitted). This is more like *dropdown* behavior.
|
5275
|
+
|
5276
|
+
@class typeahead
|
5277
|
+
@extends list
|
5278
|
+
@since 1.4.1
|
5279
|
+
@final
|
5280
|
+
@example
|
5281
|
+
<a href="#" id="country" data-type="typeahead" data-pk="1" data-url="/post" data-original-title="Input country"></a>
|
5282
|
+
<script>
|
5283
|
+
$(function(){
|
5284
|
+
$('#country').editable({
|
5285
|
+
value: 'ru',
|
5286
|
+
source: [
|
5287
|
+
{value: 'gb', text: 'Great Britain'},
|
5288
|
+
{value: 'us', text: 'United States'},
|
5289
|
+
{value: 'ru', text: 'Russia'}
|
5290
|
+
]
|
5291
|
+
}
|
5292
|
+
});
|
5293
|
+
});
|
5294
|
+
</script>
|
5295
|
+
**/
|
5296
|
+
(function ($) {
|
5297
|
+
|
5298
|
+
var Constructor = function (options) {
|
5299
|
+
this.init('typeahead', options, Constructor.defaults);
|
5300
|
+
|
5301
|
+
//overriding objects in config (as by default jQuery extend() is not recursive)
|
5302
|
+
this.options.typeahead = $.extend({}, Constructor.defaults.typeahead, {
|
5303
|
+
//set default methods for typeahead to work with objects
|
5304
|
+
matcher: this.matcher,
|
5305
|
+
sorter: this.sorter,
|
5306
|
+
highlighter: this.highlighter,
|
5307
|
+
updater: this.updater
|
5308
|
+
}, options.typeahead);
|
5309
|
+
};
|
5310
|
+
|
5311
|
+
$.fn.editableutils.inherit(Constructor, $.fn.editabletypes.list);
|
5312
|
+
|
5313
|
+
$.extend(Constructor.prototype, {
|
5314
|
+
renderList: function() {
|
5315
|
+
this.$input = this.$tpl.is('input') ? this.$tpl : this.$tpl.find('input[type="text"]');
|
5316
|
+
|
5317
|
+
//set source of typeahead
|
5318
|
+
this.options.typeahead.source = this.sourceData;
|
5319
|
+
|
5320
|
+
//apply typeahead
|
5321
|
+
this.$input.typeahead(this.options.typeahead);
|
5322
|
+
|
5323
|
+
//attach own render method
|
5324
|
+
this.$input.data('typeahead').render = $.proxy(this.typeaheadRender, this.$input.data('typeahead'));
|
5325
|
+
|
5326
|
+
this.renderClear();
|
5327
|
+
this.setClass();
|
5328
|
+
this.setAttr('placeholder');
|
5329
|
+
},
|
5330
|
+
|
5331
|
+
value2htmlFinal: function(value, element) {
|
5332
|
+
if(this.getIsObjects()) {
|
5333
|
+
var items = $.fn.editableutils.itemsByValue(value, this.sourceData);
|
5334
|
+
$(element).text(items.length ? items[0].text : '');
|
5335
|
+
} else {
|
5336
|
+
$(element).text(value);
|
5337
|
+
}
|
5338
|
+
},
|
5339
|
+
|
5340
|
+
html2value: function (html) {
|
5341
|
+
return html ? html : null;
|
5342
|
+
},
|
5343
|
+
|
5344
|
+
value2input: function(value) {
|
5345
|
+
if(this.getIsObjects()) {
|
5346
|
+
var items = $.fn.editableutils.itemsByValue(value, this.sourceData);
|
5347
|
+
this.$input.data('value', value).val(items.length ? items[0].text : '');
|
5348
|
+
} else {
|
5349
|
+
this.$input.val(value);
|
5350
|
+
}
|
5351
|
+
},
|
5352
|
+
|
5353
|
+
input2value: function() {
|
5354
|
+
if(this.getIsObjects()) {
|
5355
|
+
var value = this.$input.data('value'),
|
5356
|
+
items = $.fn.editableutils.itemsByValue(value, this.sourceData);
|
5357
|
+
|
5358
|
+
if(items.length && items[0].text.toLowerCase() === this.$input.val().toLowerCase()) {
|
5359
|
+
return value;
|
5360
|
+
} else {
|
5361
|
+
return null; //entered string not found in source
|
5362
|
+
}
|
5363
|
+
} else {
|
5364
|
+
return this.$input.val();
|
5365
|
+
}
|
5366
|
+
},
|
5367
|
+
|
5368
|
+
/*
|
5369
|
+
if in sourceData values <> texts, typeahead in "objects" mode:
|
5370
|
+
user must pick some value from list, otherwise `null` returned.
|
5371
|
+
if all values == texts put typeahead in "strings" mode:
|
5372
|
+
anything what entered is submited.
|
5373
|
+
*/
|
5374
|
+
getIsObjects: function() {
|
5375
|
+
if(this.isObjects === undefined) {
|
5376
|
+
this.isObjects = false;
|
5377
|
+
for(var i=0; i<this.sourceData.length; i++) {
|
5378
|
+
if(this.sourceData[i].value !== this.sourceData[i].text) {
|
5379
|
+
this.isObjects = true;
|
5380
|
+
break;
|
5381
|
+
}
|
5382
|
+
}
|
5383
|
+
}
|
5384
|
+
return this.isObjects;
|
5385
|
+
},
|
5386
|
+
|
5387
|
+
/*
|
5388
|
+
Methods borrowed from text input
|
5389
|
+
*/
|
5390
|
+
activate: $.fn.editabletypes.text.prototype.activate,
|
5391
|
+
renderClear: $.fn.editabletypes.text.prototype.renderClear,
|
5392
|
+
postrender: $.fn.editabletypes.text.prototype.postrender,
|
5393
|
+
toggleClear: $.fn.editabletypes.text.prototype.toggleClear,
|
5394
|
+
clear: function() {
|
5395
|
+
$.fn.editabletypes.text.prototype.clear.call(this);
|
5396
|
+
this.$input.data('value', '');
|
5397
|
+
},
|
5398
|
+
|
5399
|
+
|
5400
|
+
/*
|
5401
|
+
Typeahead option methods used as defaults
|
5402
|
+
*/
|
5403
|
+
/*jshint eqeqeq:false, curly: false, laxcomma: true*/
|
5404
|
+
matcher: function (item) {
|
5405
|
+
return $.fn.typeahead.Constructor.prototype.matcher.call(this, item.text);
|
5406
|
+
},
|
5407
|
+
sorter: function (items) {
|
5408
|
+
var beginswith = []
|
5409
|
+
, caseSensitive = []
|
5410
|
+
, caseInsensitive = []
|
5411
|
+
, item
|
5412
|
+
, text;
|
5413
|
+
|
5414
|
+
while (item = items.shift()) {
|
5415
|
+
text = item.text;
|
5416
|
+
if (!text.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item);
|
5417
|
+
else if (~text.indexOf(this.query)) caseSensitive.push(item);
|
5418
|
+
else caseInsensitive.push(item);
|
5419
|
+
}
|
5420
|
+
|
5421
|
+
return beginswith.concat(caseSensitive, caseInsensitive);
|
5422
|
+
},
|
5423
|
+
highlighter: function (item) {
|
5424
|
+
return $.fn.typeahead.Constructor.prototype.highlighter.call(this, item.text);
|
5425
|
+
},
|
5426
|
+
updater: function (item) {
|
5427
|
+
item = this.$menu.find('.active').data('item');
|
5428
|
+
this.$element.data('value', item.value);
|
5429
|
+
return item.text;
|
5430
|
+
},
|
5431
|
+
|
5432
|
+
|
5433
|
+
/*
|
5434
|
+
Overwrite typeahead's render method to store objects.
|
5435
|
+
There are a lot of disscussion in bootstrap repo on this point and still no result.
|
5436
|
+
See https://github.com/twitter/bootstrap/issues/5967
|
5437
|
+
|
5438
|
+
This function just store item in via jQuery data() method instead of attr('data-value')
|
5439
|
+
*/
|
5440
|
+
typeaheadRender: function (items) {
|
5441
|
+
var that = this;
|
5442
|
+
|
5443
|
+
items = $(items).map(function (i, item) {
|
5444
|
+
// i = $(that.options.item).attr('data-value', item)
|
5445
|
+
i = $(that.options.item).data('item', item);
|
5446
|
+
i.find('a').html(that.highlighter(item));
|
5447
|
+
return i[0];
|
5448
|
+
});
|
5449
|
+
|
5450
|
+
items.first().addClass('active');
|
5451
|
+
this.$menu.html(items);
|
5452
|
+
return this;
|
5453
|
+
}
|
5454
|
+
/*jshint eqeqeq: true, curly: true, laxcomma: false*/
|
5455
|
+
|
5456
|
+
});
|
5457
|
+
|
5458
|
+
Constructor.defaults = $.extend({}, $.fn.editabletypes.list.defaults, {
|
5459
|
+
/**
|
5460
|
+
@property tpl
|
5461
|
+
@default <input type="text">
|
5462
|
+
**/
|
5463
|
+
tpl:'<input type="text">',
|
5464
|
+
/**
|
5465
|
+
Configuration of typeahead. [Full list of options](http://twitter.github.com/bootstrap/javascript.html#typeahead).
|
5466
|
+
|
5467
|
+
@property typeahead
|
5468
|
+
@type object
|
5469
|
+
@default null
|
5470
|
+
**/
|
5471
|
+
typeahead: null,
|
5472
|
+
/**
|
5473
|
+
Whether to show `clear` button
|
5474
|
+
|
5475
|
+
@property clear
|
5476
|
+
@type boolean
|
5477
|
+
@default true
|
5478
|
+
**/
|
5479
|
+
clear: true
|
5480
|
+
});
|
5481
|
+
|
5482
|
+
$.fn.editabletypes.typeahead = Constructor;
|
5483
|
+
|
5484
|
+
}(window.jQuery));
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/*! X-editable - v1.4.
|
1
|
+
/*! X-editable - v1.4.1
|
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 */
|
@@ -116,21 +116,6 @@
|
|
116
116
|
.editable-clear-x:hover {
|
117
117
|
opacity: 1;
|
118
118
|
}
|
119
|
-
|
120
|
-
/*
|
121
|
-
.editable-clear-x1 {
|
122
|
-
background: image-url('clear.png') center center no-repeat;
|
123
|
-
display: inline-block;
|
124
|
-
zoom: 1;
|
125
|
-
*display: inline;
|
126
|
-
width: 13px;
|
127
|
-
height: 13px;
|
128
|
-
vertical-align: middle;
|
129
|
-
position: relative;
|
130
|
-
margin-left: -20px;
|
131
|
-
}
|
132
|
-
*/
|
133
|
-
|
134
119
|
.editable-container {
|
135
120
|
max-width: none !important; /* without this rule poshytip/tooltip does not stretch */
|
136
121
|
}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bootstrap-x-editable-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-01-
|
12
|
+
date: 2013-01-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: railties
|
@@ -69,6 +69,7 @@ files:
|
|
69
69
|
- .gitignore
|
70
70
|
- Gemfile
|
71
71
|
- README.md
|
72
|
+
- Rakefile
|
72
73
|
- X-EDITABLE-LICENSE-MIT
|
73
74
|
- bootstrap-x-editable-rails.gemspec
|
74
75
|
- bootstrap-x-editable-rails.sublime-project
|
@@ -76,6 +77,7 @@ files:
|
|
76
77
|
- lib/bootstrap-x-editable-rails/engine.rb
|
77
78
|
- lib/bootstrap-x-editable-rails/railtie.rb
|
78
79
|
- lib/bootstrap-x-editable-rails/version.rb
|
80
|
+
- vendor/assets/images/clear.png
|
79
81
|
- vendor/assets/images/loading.gif
|
80
82
|
- vendor/assets/javascripts/bootstrap-editable-inline.js
|
81
83
|
- vendor/assets/javascripts/bootstrap-editable.js
|
@@ -94,7 +96,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
94
96
|
version: '0'
|
95
97
|
segments:
|
96
98
|
- 0
|
97
|
-
hash:
|
99
|
+
hash: 1222445192061243716
|
98
100
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
101
|
none: false
|
100
102
|
requirements:
|
@@ -103,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
103
105
|
version: '0'
|
104
106
|
segments:
|
105
107
|
- 0
|
106
|
-
hash:
|
108
|
+
hash: 1222445192061243716
|
107
109
|
requirements: []
|
108
110
|
rubyforge_project:
|
109
111
|
rubygems_version: 1.8.24
|