x-editable-rails 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 69573b9d19da5508621bb001ce70a965119f1db6
4
- data.tar.gz: 9f88c437a7dce38761fd95f6f2252aa72349d058
3
+ metadata.gz: 3eb8f0f4f7d40565313f05708fe73abaeb438429
4
+ data.tar.gz: 01a513b8dbc3881ed6e6528638b632d042b0d61a
5
5
  SHA512:
6
- metadata.gz: 9b3a7a35c33960682fbb9a9ee376fdfaf03df325902b9677554c007ef6825f35f597112e8439f6ba085f2712fe40f3bfaaa28ee649cb98be0cafde79ec29e085
7
- data.tar.gz: 67884243ae8d543d92b46412ed460b9c44c452bf7c441f78cc7fb1ccad229b59fdf24c5ef0e0b8bd6e1f7de62adb3cb193547617c6b03dd7ac3ba48625acfd43
6
+ metadata.gz: 643633fb1a63c4f8f50555596ff9b9b9814804c1598076ce39ac10492927690f0a61922e25cb1201e8f66116fc890b01b6ed25c16eb05ba33adfd8de370a7ab0
7
+ data.tar.gz: 38f8fefcb625fce171347ca11800450ed5c9c77bc4d3c2da87dc2214ac44601aa38eab3412e492c7c4f6173d59561b0d04be8aafb6b7d785a9568f9fb67b016a
data/README.md CHANGED
@@ -23,12 +23,12 @@ Insert files to your application
23
23
  ```coffee
24
24
  #= require editable/bootstrap-editable
25
25
  ```
26
- You can choose between bootstrap-editable/jqueryui-editable/jquery-editable-poshytip
26
+ You can choose between bootstrap-editable/bootstrap2-editable/jqueryui-editable/jquery-editable-poshytip
27
27
 
28
28
  ```scss
29
29
  *= require editable/bootstrap-editable
30
30
  ```
31
- You can choose between bootstrap-editable/jqueryui-editable/jquery-editable
31
+ You can choose between bootstrap-editable/bootstrap2-editable/jqueryui-editable/jquery-editable
32
32
 
33
33
 
34
34
  You can also insert this file
@@ -93,9 +93,9 @@ If you want edit text with wysihtml5 editor, you need to load his dependencies
93
93
  For js
94
94
  ```coffee
95
95
  #= require editable/bootstrap-editable
96
- #= require editable/inputs-ext/bootstrap-wysihtml5/wysihtml5
97
- #= require editable/inputs-ext/bootstrap-wysihtml5/bootstrap-wysihtml5
98
96
  #= require editable/inputs-ext/wysihtml5
97
+ #= require editable/inputs-ext/bootstrap-wysihtml5
98
+ #= require editable/inputs-ext/wysihtml5-editable
99
99
  #= require editable/rails
100
100
  ```
101
101
 
@@ -1,7 +1,7 @@
1
1
  module X
2
2
  module Editable
3
3
  module Rails
4
- VERSION = "1.3.0"
4
+ VERSION = "1.4.0"
5
5
  end
6
6
  end
7
7
  end
@@ -1,8 +1,7 @@
1
- /*! X-editable - v1.4.6
1
+ /*! X-editable - v1.5.0
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 */
5
-
6
5
  /**
7
6
  Form with single input element, two buttons and two states: normal/loading.
8
7
  Applied as jQuery method to DIV tag (not to form tag!). This is because form can be in loading state when spinner shown.
@@ -33,6 +32,9 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
33
32
  //set initial value
34
33
  //todo: may be add check: typeof str === 'string' ?
35
34
  this.value = this.input.str2value(this.options.value);
35
+
36
+ //prerender: get input.$input
37
+ this.input.prerender();
36
38
  },
37
39
  initTemplate: function() {
38
40
  this.$form = $($.fn.editableform.template);
@@ -80,9 +82,8 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
80
82
  this.initInput();
81
83
 
82
84
  //append input to form
83
- this.input.prerender();
84
85
  this.$form.find('div.editable-input').append(this.input.$tpl);
85
-
86
+
86
87
  //append form to container
87
88
  this.$div.append(this.$form);
88
89
 
@@ -620,6 +621,9 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
620
621
 
621
622
  //error class attached to editable-error-block
622
623
  $.fn.editableform.errorBlockClass = 'editable-error';
624
+
625
+ //engine
626
+ $.fn.editableform.engine = 'jquery';
623
627
  }(window.jQuery));
624
628
 
625
629
  /**
@@ -898,6 +902,8 @@ Applied as jQuery method.
898
902
  containerDataName: null, //object name in element's .data()
899
903
  innerCss: null, //tbd in child class
900
904
  containerClass: 'editable-container editable-popup', //css class applied to container element
905
+ defaults: {}, //container itself defaults
906
+
901
907
  init: function(element, options) {
902
908
  this.$element = $(element);
903
909
  //since 1.4.1 container do not use data-* directly as they already merged into options.
@@ -975,10 +981,9 @@ Applied as jQuery method.
975
981
  throw new Error(this.containerName + ' not found. Have you included corresponding js file?');
976
982
  }
977
983
 
978
- var cDef = $.fn[this.containerName].defaults;
979
984
  //keys defined in container defaults go to container, others go to form
980
985
  for(var k in this.options) {
981
- if(k in cDef) {
986
+ if(k in this.defaults) {
982
987
  this.containerOptions[k] = this.options[k];
983
988
  } else {
984
989
  this.formOptions[k] = this.options[k];
@@ -1727,13 +1732,12 @@ Makes editable any HTML element on the page. Applied as jQuery method.
1727
1732
  this.isEmpty = isEmpty;
1728
1733
  } else {
1729
1734
  //detect empty
1730
- if($.trim(this.$element.html()) === '') {
1731
- this.isEmpty = true;
1732
- } else if($.trim(this.$element.text()) !== '') {
1733
- this.isEmpty = false;
1735
+ //for some inputs we need more smart check
1736
+ //e.g. wysihtml5 may have <br>, <p></p>, <img>
1737
+ if(typeof(this.input.isEmpty) === 'function') {
1738
+ this.isEmpty = this.input.isEmpty(this.$element);
1734
1739
  } else {
1735
- //e.g. '<img>'
1736
- this.isEmpty = !this.$element.height() || !this.$element.width();
1740
+ this.isEmpty = $.trim(this.$element.html()) === '';
1737
1741
  }
1738
1742
  }
1739
1743
 
@@ -2249,7 +2253,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
2249
2253
  @since 1.4.5
2250
2254
  @default #FFFF80
2251
2255
  **/
2252
- highlight: '#FFFF80'
2256
+ highlight: '#FFFF80'
2253
2257
  };
2254
2258
 
2255
2259
  }(window.jQuery));
@@ -2308,7 +2312,7 @@ To create your own input you can inherit from this class.
2308
2312
  @param {DOMElement} element
2309
2313
  **/
2310
2314
  value2html: function(value, element) {
2311
- $(element).text($.trim(value));
2315
+ $(element)[this.options.escape ? 'text' : 'html']($.trim(value));
2312
2316
  },
2313
2317
 
2314
2318
  /**
@@ -2415,7 +2419,7 @@ To create your own input you can inherit from this class.
2415
2419
  },
2416
2420
 
2417
2421
  // -------- helper functions --------
2418
- setClass: function() {
2422
+ setClass: function() {
2419
2423
  if(this.options.inputclass) {
2420
2424
  this.$input.addClass(this.options.inputclass);
2421
2425
  }
@@ -2447,9 +2451,22 @@ To create your own input you can inherit from this class.
2447
2451
 
2448
2452
  @property inputclass
2449
2453
  @type string
2450
- @default input-medium
2454
+ @default null
2451
2455
  **/
2452
- inputclass: 'input-medium',
2456
+ inputclass: null,
2457
+
2458
+ /**
2459
+ If `true` - html will be escaped in content of element via $.text() method.
2460
+ If `false` - html will not be escaped, $.html() used.
2461
+ When you use own `display` function, this option obviosly has no effect.
2462
+
2463
+ @property escape
2464
+ @type boolean
2465
+ @since 1.5.0
2466
+ @default true
2467
+ **/
2468
+ escape: true,
2469
+
2453
2470
  //scope for external methods (e.g. source defined as function)
2454
2471
  //for internal use only
2455
2472
  scope: null,
@@ -2581,8 +2598,8 @@ List - abstract class for inputs that have source option loaded from js array or
2581
2598
  }
2582
2599
  }
2583
2600
 
2584
- //loading sourceData from server
2585
- $.ajax({
2601
+ //ajaxOptions for source. Can be overwritten bt options.sourceOptions
2602
+ var ajaxOptions = $.extend({
2586
2603
  url: source,
2587
2604
  type: 'get',
2588
2605
  cache: false,
@@ -2617,7 +2634,11 @@ List - abstract class for inputs that have source option loaded from js array or
2617
2634
  $.each(cache.err_callbacks, function () { this.call(); });
2618
2635
  }
2619
2636
  }, this)
2620
- });
2637
+ }, this.options.sourceOptions);
2638
+
2639
+ //loading sourceData from server
2640
+ $.ajax(ajaxOptions);
2641
+
2621
2642
  } else { //options as json/array
2622
2643
  this.sourceData = this.makeArray(source);
2623
2644
 
@@ -2777,7 +2798,17 @@ List - abstract class for inputs that have source option loaded from js array or
2777
2798
  @default true
2778
2799
  @since 1.2.0
2779
2800
  **/
2780
- sourceCache: true
2801
+ sourceCache: true,
2802
+ /**
2803
+ Additional ajax options to be used in $.ajax() when loading list from server.
2804
+ Useful to send extra parameters (`data` key) or change request method (`type` key).
2805
+
2806
+ @property sourceOptions
2807
+ @type object|function
2808
+ @default null
2809
+ @since 1.5.0
2810
+ **/
2811
+ sourceOptions: null
2781
2812
  });
2782
2813
 
2783
2814
  $.fn.editabletypes.list = List;
@@ -3038,7 +3069,7 @@ Select (dropdown)
3038
3069
  @extends list
3039
3070
  @final
3040
3071
  @example
3041
- <a href="#" id="status" data-type="select" data-pk="1" data-url="/post" data-original-title="Select status"></a>
3072
+ <a href="#" id="status" data-type="select" data-pk="1" data-url="/post" data-title="Select status"></a>
3042
3073
  <script>
3043
3074
  $(function(){
3044
3075
  $('#status').editable({
@@ -3105,7 +3136,8 @@ $(function(){
3105
3136
  text = items[0].text;
3106
3137
  }
3107
3138
 
3108
- $(element).text(text);
3139
+ //$(element).text(text);
3140
+ $.fn.editabletypes.abstractinput.prototype.value2html.call(this, text, element);
3109
3141
  },
3110
3142
 
3111
3143
  autosubmit: function() {
@@ -3135,7 +3167,7 @@ Internally value stored as javascript array of values.
3135
3167
  @extends list
3136
3168
  @final
3137
3169
  @example
3138
- <a href="#" id="options" data-type="checklist" data-pk="1" data-url="/post" data-original-title="Select options"></a>
3170
+ <a href="#" id="options" data-type="checklist" data-pk="1" data-url="/post" data-title="Select options"></a>
3139
3171
  <script>
3140
3172
  $(function(){
3141
3173
  $('#options').editable({
@@ -3229,10 +3261,14 @@ $(function(){
3229
3261
  //collect text of checked boxes
3230
3262
  value2htmlFinal: function(value, element) {
3231
3263
  var html = [],
3232
- checked = $.fn.editableutils.itemsByValue(value, this.sourceData);
3264
+ checked = $.fn.editableutils.itemsByValue(value, this.sourceData),
3265
+ escape = this.options.escape;
3233
3266
 
3234
3267
  if(checked.length) {
3235
- $.each(checked, function(i, v) { html.push($.fn.editableutils.escape(v.text)); });
3268
+ $.each(checked, function(i, v) {
3269
+ var text = escape ? $.fn.editableutils.escape(v.text) : v.text;
3270
+ html.push(text);
3271
+ });
3236
3272
  $(element).html(html.join('<br>'));
3237
3273
  } else {
3238
3274
  $(element).empty();
@@ -3502,7 +3538,7 @@ Time
3502
3538
  /**
3503
3539
  Select2 input. Based on amazing work of Igor Vaynberg https://github.com/ivaynberg/select2.
3504
3540
  Please see [original select2 docs](http://ivaynberg.github.com/select2) for detailed description and options.
3505
- Compatible **select2 version is 3.4.1**!
3541
+
3506
3542
  You should manually download and include select2 distributive:
3507
3543
 
3508
3544
  <link href="select2/select2.css" rel="stylesheet" type="text/css"></link>
@@ -3643,9 +3679,11 @@ $(function(){
3643
3679
  $.extend(Constructor.prototype, {
3644
3680
  render: function() {
3645
3681
  this.setClass();
3646
-
3647
- //apply select2
3648
- this.$input.select2(this.options.select2);
3682
+
3683
+ //can not apply select2 here as it calls initSelection
3684
+ //over input that does not have correct value yet.
3685
+ //apply select2 only in value2input
3686
+ //this.$input.select2(this.options.select2);
3649
3687
 
3650
3688
  //when data is loaded via ajax, we need to know when it's done to populate listData
3651
3689
  if(this.isRemote) {
@@ -3673,7 +3711,8 @@ $(function(){
3673
3711
  } else if(this.sourceData) {
3674
3712
  data = $.fn.editableutils.itemsByValue(value, this.sourceData, this.idFunc);
3675
3713
  } else {
3676
- //can not get list of possible values (e.g. autotext for select2 with ajax source)
3714
+ //can not get list of possible values
3715
+ //(e.g. autotext for select2 with ajax source)
3677
3716
  }
3678
3717
 
3679
3718
  //data may be array (when multiple values allowed)
@@ -3689,7 +3728,8 @@ $(function(){
3689
3728
 
3690
3729
  text = $.isArray(text) ? text.join(this.options.viewseparator) : text;
3691
3730
 
3692
- $(element).text(text);
3731
+ //$(element).text(text);
3732
+ Constructor.superclass.value2html.call(this, text, element);
3693
3733
  },
3694
3734
 
3695
3735
  html2value: function(html) {
@@ -3708,8 +3748,14 @@ $(function(){
3708
3748
  }
3709
3749
  */
3710
3750
 
3711
- //for remote source just set value, text is updated by initSelection
3712
- this.$input.val(value).trigger('change', true); //second argument needed to separate initial change from user's click (for autosubmit)
3751
+ //for remote source just set value, text is updated by initSelection
3752
+ if(!this.$input.data('select2')) {
3753
+ this.$input.val(value);
3754
+ this.$input.select2(this.options.select2);
3755
+ } else {
3756
+ //second argument needed to separate initial change from user's click (for autosubmit)
3757
+ this.$input.val(value).trigger('change', true);
3758
+ }
3713
3759
 
3714
3760
  //if remote source AND no user's initSelection provided --> try to use element's text
3715
3761
  if(this.isRemote && !this.isMultiple && !this.options.select2.initSelection) {
@@ -3717,7 +3763,7 @@ $(function(){
3717
3763
  customText = this.options.select2.formatSelection;
3718
3764
  if(!customId && !customText) {
3719
3765
  var data = {id: value, text: $(this.options.scope).text()};
3720
- this.$input.select2('data', data);
3766
+ this.$input.select2('data', data);
3721
3767
  }
3722
3768
  }
3723
3769
  },
@@ -3806,7 +3852,7 @@ $(function(){
3806
3852
  E.g. `[{id: 1, text: "text1"}, {id: 2, text: "text2"}, ...]`.
3807
3853
 
3808
3854
  @property source
3809
- @type array
3855
+ @type array|string|function
3810
3856
  @default null
3811
3857
  **/
3812
3858
  source: null,
@@ -3817,7 +3863,7 @@ $(function(){
3817
3863
  @type string
3818
3864
  @default ', '
3819
3865
  **/
3820
- viewseparator: ', '
3866
+ viewseparator: ', '
3821
3867
  });
3822
3868
 
3823
3869
  $.fn.editabletypes.select2 = Constructor;
@@ -4297,7 +4343,7 @@ Internally value stored as `momentjs` object.
4297
4343
  @final
4298
4344
  @since 1.4.0
4299
4345
  @example
4300
- <a href="#" id="dob" data-type="combodate" data-pk="1" data-url="/post" data-value="1984-05-15" data-original-title="Select date"></a>
4346
+ <a href="#" id="dob" data-type="combodate" data-pk="1" data-url="/post" data-value="1984-05-15" data-title="Select date"></a>
4301
4347
  <script>
4302
4348
  $(function(){
4303
4349
  $('#dob').editable({
@@ -4343,7 +4389,14 @@ $(function(){
4343
4389
  $.extend(Constructor.prototype, {
4344
4390
  render: function () {
4345
4391
  this.$input.combodate(this.options.combodate);
4392
+
4393
+ if($.fn.editableform.engine === 'bs3') {
4394
+ this.$input.siblings().find('select').addClass('form-control');
4395
+ }
4346
4396
 
4397
+ if(this.options.inputclass) {
4398
+ this.$input.siblings().find('select').addClass(this.options.inputclass);
4399
+ }
4347
4400
  //"clear" link
4348
4401
  /*
4349
4402
  if(this.options.clear) {
@@ -4360,7 +4413,8 @@ $(function(){
4360
4413
 
4361
4414
  value2html: function(value, element) {
4362
4415
  var text = value ? value.format(this.options.viewformat) : '';
4363
- $(element).text(text);
4416
+ //$(element).text(text);
4417
+ Constructor.superclass.value2html.call(this, text, element);
4364
4418
  },
4365
4419
 
4366
4420
  html2value: function(html) {
@@ -4468,29 +4522,71 @@ $(function(){
4468
4522
  }(window.jQuery));
4469
4523
 
4470
4524
  /*
4471
- Editableform based on Twitter Bootstrap
4525
+ Editableform based on Twitter Bootstrap 3
4472
4526
  */
4473
4527
  (function ($) {
4474
4528
  "use strict";
4475
4529
 
4530
+ //store parent methods
4531
+ var pInitInput = $.fn.editableform.Constructor.prototype.initInput;
4532
+
4476
4533
  $.extend($.fn.editableform.Constructor.prototype, {
4477
- initTemplate: function() {
4534
+ initTemplate: function() {
4478
4535
  this.$form = $($.fn.editableform.template);
4536
+ this.$form.find('.control-group').addClass('form-group');
4479
4537
  this.$form.find('.editable-error-block').addClass('help-block');
4480
- }
4538
+ },
4539
+ initInput: function() {
4540
+ pInitInput.apply(this);
4541
+
4542
+ //for bs3 set default class `input-sm` to standard inputs
4543
+ var emptyInputClass = this.input.options.inputclass === null || this.input.options.inputclass === false;
4544
+ var defaultClass = 'input-sm';
4545
+
4546
+ //bs3 add `form-control` class to standard inputs
4547
+ var stdtypes = 'text,select,textarea,password,email,url,tel,number,range,time,typeaheadjs'.split(',');
4548
+ if(~$.inArray(this.input.type, stdtypes)) {
4549
+ this.input.$input.addClass('form-control');
4550
+ if(emptyInputClass) {
4551
+ this.input.options.inputclass = defaultClass;
4552
+ this.input.$input.addClass(defaultClass);
4553
+ }
4554
+ }
4555
+
4556
+ //apply bs3 size class also to buttons (to fit size of control)
4557
+ var $btn = this.$form.find('.editable-buttons');
4558
+ var classes = emptyInputClass ? [defaultClass] : this.input.options.inputclass.split(' ');
4559
+ for(var i=0; i<classes.length; i++) {
4560
+ // `btn-sm` is default now
4561
+ /*
4562
+ if(classes[i].toLowerCase() === 'input-sm') {
4563
+ $btn.find('button').addClass('btn-sm');
4564
+ }
4565
+ */
4566
+ if(classes[i].toLowerCase() === 'input-lg') {
4567
+ $btn.find('button').removeClass('btn-sm').addClass('btn-lg');
4568
+ }
4569
+ }
4570
+ }
4481
4571
  });
4482
4572
 
4483
4573
  //buttons
4484
- $.fn.editableform.buttons = '<button type="submit" class="btn btn-primary editable-submit"><i class="icon-ok icon-white"></i></button>'+
4485
- '<button type="button" class="btn editable-cancel"><i class="icon-remove"></i></button>';
4574
+ $.fn.editableform.buttons =
4575
+ '<button type="submit" class="btn btn-primary btn-sm editable-submit">'+
4576
+ '<i class="glyphicon glyphicon-ok"></i>'+
4577
+ '</button>'+
4578
+ '<button type="button" class="btn btn-default btn-sm editable-cancel">'+
4579
+ '<i class="glyphicon glyphicon-remove"></i>'+
4580
+ '</button>';
4486
4581
 
4487
4582
  //error classes
4488
- $.fn.editableform.errorGroupClass = 'error';
4489
- $.fn.editableform.errorBlockClass = null;
4490
-
4583
+ $.fn.editableform.errorGroupClass = 'has-error';
4584
+ $.fn.editableform.errorBlockClass = null;
4585
+ //engine
4586
+ $.fn.editableform.engine = 'bs3';
4491
4587
  }(window.jQuery));
4492
4588
  /**
4493
- * Editable Popover
4589
+ * Editable Popover3 (for Bootstrap 3)
4494
4590
  * ---------------------
4495
4591
  * requires bootstrap-popover.js
4496
4592
  */
@@ -4500,15 +4596,16 @@ Editableform based on Twitter Bootstrap
4500
4596
  //extend methods
4501
4597
  $.extend($.fn.editableContainer.Popup.prototype, {
4502
4598
  containerName: 'popover',
4503
- //for compatibility with bootstrap <= 2.2.1 (content inserted into <p> instead of directly .popover-content)
4504
- innerCss: $.fn.popover && $($.fn.popover.defaults.template).find('p').length ? '.popover-content p' : '.popover-content',
4599
+ containerDataName: 'bs.popover',
4600
+ innerCss: '.popover-content',
4601
+ defaults: $.fn.popover.Constructor.DEFAULTS,
4505
4602
 
4506
4603
  initContainer: function(){
4507
4604
  $.extend(this.containerOptions, {
4508
4605
  trigger: 'manual',
4509
4606
  selector: false,
4510
4607
  content: ' ',
4511
- template: $.fn.popover.defaults.template
4608
+ template: this.defaults.template
4512
4609
  });
4513
4610
 
4514
4611
  //as template property is used in inputs, hide it from popover
@@ -4548,10 +4645,11 @@ Editableform based on Twitter Bootstrap
4548
4645
  /**
4549
4646
  * move popover to new position. This function mainly copied from bootstrap-popover.
4550
4647
  */
4551
- /*jshint laxcomma: true*/
4648
+ /*jshint laxcomma: true, eqeqeq: false*/
4552
4649
  setPosition: function () {
4553
4650
 
4554
- (function() {
4651
+ (function() {
4652
+ /*
4555
4653
  var $tip = this.tip()
4556
4654
  , inside
4557
4655
  , pos
@@ -4661,9 +4759,27 @@ Editableform based on Twitter Bootstrap
4661
4759
  .offset(tp)
4662
4760
  .addClass(placement)
4663
4761
  .addClass('in');
4762
+ */
4763
+
4764
+
4765
+ var $tip = this.tip();
4766
+
4767
+ var placement = typeof this.options.placement == 'function' ?
4768
+ this.options.placement.call(this, $tip[0], this.$element[0]) :
4769
+ this.options.placement;
4770
+
4771
+
4772
+ var pos = this.getPosition();
4773
+ var actualWidth = $tip[0].offsetWidth;
4774
+ var actualHeight = $tip[0].offsetHeight;
4775
+ var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight);
4776
+
4777
+ this.applyPlacement(calculatedOffset, placement);
4778
+
4779
+
4664
4780
 
4665
4781
  }).call(this.container());
4666
- /*jshint laxcomma: false*/
4782
+ /*jshint laxcomma: false, eqeqeq: true*/
4667
4783
  }
4668
4784
  });
4669
4785
 
@@ -5935,7 +6051,7 @@ Since 1.4.0 date has different appearance in **popup** and **inline** modes.
5935
6051
  @extends abstractinput
5936
6052
  @final
5937
6053
  @example
5938
- <a href="#" id="dob" data-type="date" data-pk="1" data-url="/post" data-original-title="Select date">15/05/1984</a>
6054
+ <a href="#" id="dob" data-type="date" data-pk="1" data-url="/post" data-title="Select date">15/05/1984</a>
5939
6055
  <script>
5940
6056
  $(function(){
5941
6057
  $('#dob').editable({
@@ -6011,7 +6127,7 @@ $(function(){
6011
6127
 
6012
6128
  value2html: function(value, element) {
6013
6129
  var text = value ? this.dpg.formatDate(value, this.parsedViewFormat, this.options.datepicker.language) : '';
6014
- Date.superclass.value2html(text, element);
6130
+ Date.superclass.value2html.call(this, text, element);
6015
6131
  },
6016
6132
 
6017
6133
  html2value: function(html) {
@@ -6333,7 +6449,7 @@ $(function(){
6333
6449
  //formatDate works with UTCDate!
6334
6450
  var text = value ? this.dpg.formatDate(this.toUTC(value), this.parsedViewFormat, this.options.datetimepicker.language, this.options.formatType) : '';
6335
6451
  if(element) {
6336
- DateTime.superclass.value2html(text, element);
6452
+ DateTime.superclass.value2html.call(this, text, element);
6337
6453
  } else {
6338
6454
  return text;
6339
6455
  }
@@ -6555,273 +6671,4 @@ Automatically shown in inline mode.
6555
6671
 
6556
6672
  $.fn.editabletypes.datetimefield = DateTimeField;
6557
6673
 
6558
- }(window.jQuery));
6559
- /**
6560
- Typeahead input (bootstrap only). Based on Twitter Bootstrap [typeahead](http://twitter.github.com/bootstrap/javascript.html#typeahead).
6561
- Depending on `source` format typeahead operates in two modes:
6562
-
6563
- * **strings**:
6564
- When `source` defined as array of strings, e.g. `['text1', 'text2', 'text3' ...]`.
6565
- User can submit one of these strings or any text entered in input (even if it is not matching source).
6566
-
6567
- * **objects**:
6568
- When `source` defined as array of objects, e.g. `[{value: 1, text: "text1"}, {value: 2, text: "text2"}, ...]`.
6569
- User can submit only values that are in source (otherwise `null` is submitted). This is more like *dropdown* behavior.
6570
-
6571
- @class typeahead
6572
- @extends list
6573
- @since 1.4.1
6574
- @final
6575
- @example
6576
- <a href="#" id="country" data-type="typeahead" data-pk="1" data-url="/post" data-original-title="Input country"></a>
6577
- <script>
6578
- $(function(){
6579
- $('#country').editable({
6580
- value: 'ru',
6581
- source: [
6582
- {value: 'gb', text: 'Great Britain'},
6583
- {value: 'us', text: 'United States'},
6584
- {value: 'ru', text: 'Russia'}
6585
- ]
6586
- });
6587
- });
6588
- </script>
6589
- **/
6590
- (function ($) {
6591
- "use strict";
6592
-
6593
- var Constructor = function (options) {
6594
- this.init('typeahead', options, Constructor.defaults);
6595
-
6596
- //overriding objects in config (as by default jQuery extend() is not recursive)
6597
- this.options.typeahead = $.extend({}, Constructor.defaults.typeahead, {
6598
- //set default methods for typeahead to work with objects
6599
- matcher: this.matcher,
6600
- sorter: this.sorter,
6601
- highlighter: this.highlighter,
6602
- updater: this.updater
6603
- }, options.typeahead);
6604
- };
6605
-
6606
- $.fn.editableutils.inherit(Constructor, $.fn.editabletypes.list);
6607
-
6608
- $.extend(Constructor.prototype, {
6609
- renderList: function() {
6610
- this.$input = this.$tpl.is('input') ? this.$tpl : this.$tpl.find('input[type="text"]');
6611
-
6612
- //set source of typeahead
6613
- this.options.typeahead.source = this.sourceData;
6614
-
6615
- //apply typeahead
6616
- this.$input.typeahead(this.options.typeahead);
6617
-
6618
- //patch some methods in typeahead
6619
- var ta = this.$input.data('typeahead');
6620
- ta.render = $.proxy(this.typeaheadRender, ta);
6621
- ta.select = $.proxy(this.typeaheadSelect, ta);
6622
- ta.move = $.proxy(this.typeaheadMove, ta);
6623
-
6624
- this.renderClear();
6625
- this.setClass();
6626
- this.setAttr('placeholder');
6627
- },
6628
-
6629
- value2htmlFinal: function(value, element) {
6630
- if(this.getIsObjects()) {
6631
- var items = $.fn.editableutils.itemsByValue(value, this.sourceData);
6632
- $(element).text(items.length ? items[0].text : '');
6633
- } else {
6634
- $(element).text(value);
6635
- }
6636
- },
6637
-
6638
- html2value: function (html) {
6639
- return html ? html : null;
6640
- },
6641
-
6642
- value2input: function(value) {
6643
- if(this.getIsObjects()) {
6644
- var items = $.fn.editableutils.itemsByValue(value, this.sourceData);
6645
- this.$input.data('value', value).val(items.length ? items[0].text : '');
6646
- } else {
6647
- this.$input.val(value);
6648
- }
6649
- },
6650
-
6651
- input2value: function() {
6652
- if(this.getIsObjects()) {
6653
- var value = this.$input.data('value'),
6654
- items = $.fn.editableutils.itemsByValue(value, this.sourceData);
6655
-
6656
- if(items.length && items[0].text.toLowerCase() === this.$input.val().toLowerCase()) {
6657
- return value;
6658
- } else {
6659
- return null; //entered string not found in source
6660
- }
6661
- } else {
6662
- return this.$input.val();
6663
- }
6664
- },
6665
-
6666
- /*
6667
- if in sourceData values <> texts, typeahead in "objects" mode:
6668
- user must pick some value from list, otherwise `null` returned.
6669
- if all values == texts put typeahead in "strings" mode:
6670
- anything what entered is submited.
6671
- */
6672
- getIsObjects: function() {
6673
- if(this.isObjects === undefined) {
6674
- this.isObjects = false;
6675
- for(var i=0; i<this.sourceData.length; i++) {
6676
- if(this.sourceData[i].value !== this.sourceData[i].text) {
6677
- this.isObjects = true;
6678
- break;
6679
- }
6680
- }
6681
- }
6682
- return this.isObjects;
6683
- },
6684
-
6685
- /*
6686
- Methods borrowed from text input
6687
- */
6688
- activate: $.fn.editabletypes.text.prototype.activate,
6689
- renderClear: $.fn.editabletypes.text.prototype.renderClear,
6690
- postrender: $.fn.editabletypes.text.prototype.postrender,
6691
- toggleClear: $.fn.editabletypes.text.prototype.toggleClear,
6692
- clear: function() {
6693
- $.fn.editabletypes.text.prototype.clear.call(this);
6694
- this.$input.data('value', '');
6695
- },
6696
-
6697
-
6698
- /*
6699
- Typeahead option methods used as defaults
6700
- */
6701
- /*jshint eqeqeq:false, curly: false, laxcomma: true, asi: true*/
6702
- matcher: function (item) {
6703
- return $.fn.typeahead.Constructor.prototype.matcher.call(this, item.text);
6704
- },
6705
- sorter: function (items) {
6706
- var beginswith = []
6707
- , caseSensitive = []
6708
- , caseInsensitive = []
6709
- , item
6710
- , text;
6711
-
6712
- while (item = items.shift()) {
6713
- text = item.text;
6714
- if (!text.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item);
6715
- else if (~text.indexOf(this.query)) caseSensitive.push(item);
6716
- else caseInsensitive.push(item);
6717
- }
6718
-
6719
- return beginswith.concat(caseSensitive, caseInsensitive);
6720
- },
6721
- highlighter: function (item) {
6722
- return $.fn.typeahead.Constructor.prototype.highlighter.call(this, item.text);
6723
- },
6724
- updater: function (item) {
6725
- this.$element.data('value', item.value);
6726
- return item.text;
6727
- },
6728
-
6729
-
6730
- /*
6731
- Overwrite typeahead's render method to store objects.
6732
- There are a lot of disscussion in bootstrap repo on this point and still no result.
6733
- See https://github.com/twitter/bootstrap/issues/5967
6734
-
6735
- This function just store item via jQuery data() method instead of attr('data-value')
6736
- */
6737
- typeaheadRender: function (items) {
6738
- var that = this;
6739
-
6740
- items = $(items).map(function (i, item) {
6741
- // i = $(that.options.item).attr('data-value', item)
6742
- i = $(that.options.item).data('item', item);
6743
- i.find('a').html(that.highlighter(item));
6744
- return i[0];
6745
- });
6746
-
6747
- //add option to disable autoselect of first line
6748
- //see https://github.com/twitter/bootstrap/pull/4164
6749
- if (this.options.autoSelect) {
6750
- items.first().addClass('active');
6751
- }
6752
- this.$menu.html(items);
6753
- return this;
6754
- },
6755
-
6756
- //add option to disable autoselect of first line
6757
- //see https://github.com/twitter/bootstrap/pull/4164
6758
- typeaheadSelect: function () {
6759
- var val = this.$menu.find('.active').data('item')
6760
- if(this.options.autoSelect || val){
6761
- this.$element
6762
- .val(this.updater(val))
6763
- .change()
6764
- }
6765
- return this.hide()
6766
- },
6767
-
6768
- /*
6769
- if autoSelect = false and nothing matched we need extra press onEnter that is not convinient.
6770
- This patch fixes it.
6771
- */
6772
- typeaheadMove: function (e) {
6773
- if (!this.shown) return
6774
-
6775
- switch(e.keyCode) {
6776
- case 9: // tab
6777
- case 13: // enter
6778
- case 27: // escape
6779
- if (!this.$menu.find('.active').length) return
6780
- e.preventDefault()
6781
- break
6782
-
6783
- case 38: // up arrow
6784
- e.preventDefault()
6785
- this.prev()
6786
- break
6787
-
6788
- case 40: // down arrow
6789
- e.preventDefault()
6790
- this.next()
6791
- break
6792
- }
6793
-
6794
- e.stopPropagation()
6795
- }
6796
-
6797
- /*jshint eqeqeq: true, curly: true, laxcomma: false, asi: false*/
6798
-
6799
- });
6800
-
6801
- Constructor.defaults = $.extend({}, $.fn.editabletypes.list.defaults, {
6802
- /**
6803
- @property tpl
6804
- @default <input type="text">
6805
- **/
6806
- tpl:'<input type="text">',
6807
- /**
6808
- Configuration of typeahead. [Full list of options](http://twitter.github.com/bootstrap/javascript.html#typeahead).
6809
-
6810
- @property typeahead
6811
- @type object
6812
- @default null
6813
- **/
6814
- typeahead: null,
6815
- /**
6816
- Whether to show `clear` button
6817
-
6818
- @property clear
6819
- @type boolean
6820
- @default true
6821
- **/
6822
- clear: true
6823
- });
6824
-
6825
- $.fn.editabletypes.typeahead = Constructor;
6826
-
6827
6674
  }(window.jQuery));