PluginProbe ʕ •ᴥ•ʔ
Secure Custom Fields / 6.4.2
Secure Custom Fields v6.4.2
6.9.1 6.9.0 6.8.9 6.8.7 6.8.8 6.8.6 6.8.4 6.8.5 trunk 6.4.0-beta1 6.4.0-beta2 6.4.1 6.4.1-beta3 6.4.1-beta4 6.4.1-beta5 6.4.1-beta6 6.4.1-beta7 6.4.2 6.5.0 6.5.1 6.5.2 6.5.3 6.5.4 6.5.5 6.5.6 6.5.7 6.6.0 6.7.0 6.7.1 6.8.0 6.8.1 6.8.2 6.8.3
secure-custom-fields / assets / src / js / _acf-select2.js
secure-custom-fields / assets / src / js Last commit date
pro 1 year ago _acf-compatibility.js 1 year ago _acf-condition-types.js 1 year ago _acf-condition.js 1 year ago _acf-conditions.js 1 year ago _acf-field-accordion.js 1 year ago _acf-field-button-group.js 1 year ago _acf-field-checkbox.js 1 year ago _acf-field-color-picker.js 1 year ago _acf-field-date-picker.js 1 year ago _acf-field-date-time-picker.js 1 year ago _acf-field-file.js 1 year ago _acf-field-google-map.js 1 year ago _acf-field-icon-picker.js 1 year ago _acf-field-image.js 1 year ago _acf-field-link.js 1 year ago _acf-field-oembed.js 1 year ago _acf-field-page-link.js 1 year ago _acf-field-post-object.js 1 year ago _acf-field-radio.js 1 year ago _acf-field-range.js 1 year ago _acf-field-relationship.js 1 year ago _acf-field-select.js 1 year ago _acf-field-tab.js 1 year ago _acf-field-taxonomy.js 1 year ago _acf-field-time-picker.js 1 year ago _acf-field-true-false.js 1 year ago _acf-field-url.js 1 year ago _acf-field-user.js 1 year ago _acf-field-wysiwyg.js 1 year ago _acf-field.js 1 year ago _acf-fields.js 1 year ago _acf-helpers.js 1 year ago _acf-hooks.js 1 year ago _acf-internal-post-type.js 1 year ago _acf-media.js 1 year ago _acf-modal.js 1 year ago _acf-model.js 1 year ago _acf-notice.js 1 year ago _acf-panel.js 1 year ago _acf-popup.js 1 year ago _acf-postbox.js 1 year ago _acf-screen.js 1 year ago _acf-select2.js 1 year ago _acf-tinymce.js 1 year ago _acf-tooltip.js 1 year ago _acf-unload.js 1 year ago _acf-validation.js 1 year ago _acf.js 1 year ago _browse-fields-modal.js 1 year ago _field-group-compatibility.js 1 year ago _field-group-conditions.js 1 year ago _field-group-field.js 1 year ago _field-group-fields.js 1 year ago _field-group-locations.js 1 year ago _field-group-settings.js 1 year ago _field-group.js 1 year ago acf-escaped-html-notice.js 1 year ago acf-field-group.js 1 year ago acf-input.js 1 year ago acf-internal-post-type.js 1 year ago acf.js 1 year ago
_acf-select2.js
911 lines
1 ( function ( $, undefined ) {
2 /**
3 * acf.newSelect2
4 *
5 * description
6 *
7 * @date 13/1/18
8 * @since ACF 5.6.5
9 *
10 * @param type $var Description. Default.
11 * @return type Description.
12 */
13
14 acf.newSelect2 = function ( $select, props ) {
15 // defaults
16 props = acf.parseArgs( props, {
17 allowNull: false,
18 placeholder: '',
19 multiple: false,
20 field: false,
21 ajax: false,
22 ajaxAction: '',
23 ajaxData: function ( data ) {
24 return data;
25 },
26 ajaxResults: function ( json ) {
27 return json;
28 },
29 escapeMarkup: false,
30 templateSelection: false,
31 templateResult: false,
32 dropdownCssClass: '',
33 suppressFilters: false,
34 } );
35
36 // initialize
37 if ( getVersion() == 4 ) {
38 var select2 = new Select2_4( $select, props );
39 } else {
40 var select2 = new Select2_3( $select, props );
41 }
42
43 // actions
44 acf.doAction( 'new_select2', select2 );
45
46 // return
47 return select2;
48 };
49
50 /**
51 * getVersion
52 *
53 * description
54 *
55 * @date 13/1/18
56 * @since ACF 5.6.5
57 *
58 * @param type $var Description. Default.
59 * @return type Description.
60 */
61
62 function getVersion() {
63 // v4
64 if ( acf.isset( window, 'jQuery', 'fn', 'select2', 'amd' ) ) {
65 return 4;
66 }
67
68 // v3
69 if ( acf.isset( window, 'Select2' ) ) {
70 return 3;
71 }
72
73 // return
74 return false;
75 }
76
77 /**
78 * Select2
79 *
80 * description
81 *
82 * @date 13/1/18
83 * @since ACF 5.6.5
84 *
85 * @param type $var Description. Default.
86 * @return type Description.
87 */
88
89 var Select2 = acf.Model.extend( {
90 setup: function ( $select, props ) {
91 $.extend( this.data, props );
92 this.$el = $select;
93 },
94
95 initialize: function () {},
96
97 selectOption: function ( value ) {
98 var $option = this.getOption( value );
99 if ( ! $option.prop( 'selected' ) ) {
100 $option.prop( 'selected', true ).trigger( 'change' );
101 }
102 },
103
104 unselectOption: function ( value ) {
105 var $option = this.getOption( value );
106 if ( $option.prop( 'selected' ) ) {
107 $option.prop( 'selected', false ).trigger( 'change' );
108 }
109 },
110
111 getOption: function ( value ) {
112 return this.$( 'option[value="' + value + '"]' );
113 },
114
115 addOption: function ( option ) {
116 // defaults
117 option = acf.parseArgs( option, {
118 id: '',
119 text: '',
120 selected: false,
121 } );
122
123 // vars
124 var $option = this.getOption( option.id );
125
126 // append
127 if ( ! $option.length ) {
128 $option = $( '<option></option>' );
129 $option.html( option.text );
130 $option.attr( 'value', option.id );
131 $option.prop( 'selected', option.selected );
132 this.$el.append( $option );
133 }
134
135 // chain
136 return $option;
137 },
138
139 getValue: function () {
140 // vars
141 var val = [];
142 var $options = this.$el.find( 'option:selected' );
143
144 // bail early if no selected
145 if ( ! $options.exists() ) {
146 return val;
147 }
148
149 // sort by attribute
150 $options = $options.sort( function ( a, b ) {
151 return (
152 +a.getAttribute( 'data-i' ) - +b.getAttribute( 'data-i' )
153 );
154 } );
155
156 // loop
157 $options.each( function () {
158 var $el = $( this );
159 val.push( {
160 $el: $el,
161 id: $el.attr( 'value' ),
162 text: $el.text(),
163 } );
164 } );
165
166 // return
167 return val;
168 },
169
170 mergeOptions: function () {},
171
172 getChoices: function () {
173 // callback
174 var crawl = function ( $parent ) {
175 // vars
176 var choices = [];
177
178 // loop
179 $parent.children().each( function () {
180 // vars
181 var $child = $( this );
182
183 // optgroup
184 if ( $child.is( 'optgroup' ) ) {
185 choices.push( {
186 text: $child.attr( 'label' ),
187 children: crawl( $child ),
188 } );
189
190 // option
191 } else {
192 choices.push( {
193 id: $child.attr( 'value' ),
194 text: $child.text(),
195 } );
196 }
197 } );
198
199 // return
200 return choices;
201 };
202
203 // crawl
204 return crawl( this.$el );
205 },
206
207 getAjaxData: function ( params ) {
208 // vars
209 var ajaxData = {
210 action: this.get( 'ajaxAction' ),
211 s: params.term || '',
212 paged: params.page || 1,
213 };
214
215 // field helper
216 var field = this.get( 'field' );
217 if ( field ) {
218 ajaxData.field_key = field.get( 'key' );
219
220 if ( field.get( 'nonce' ) ) {
221 ajaxData.nonce = field.get( 'nonce' );
222 }
223
224 }
225
226 // callback
227 var callback = this.get( 'ajaxData' );
228 if ( callback ) {
229 ajaxData = callback.apply( this, [ ajaxData, params ] );
230 }
231
232 // filter
233 ajaxData = acf.applyFilters(
234 'select2_ajax_data',
235 ajaxData,
236 this.data,
237 this.$el,
238 field || false,
239 this
240 );
241
242 // return
243 return acf.prepareForAjax( ajaxData );
244 },
245
246 getAjaxResults: function ( json, params ) {
247 // defaults
248 json = acf.parseArgs( json, {
249 results: false,
250 more: false,
251 } );
252
253 // callback
254 var callback = this.get( 'ajaxResults' );
255 if ( callback ) {
256 json = callback.apply( this, [ json, params ] );
257 }
258
259 // filter
260 json = acf.applyFilters(
261 'select2_ajax_results',
262 json,
263 params,
264 this
265 );
266
267 // return
268 return json;
269 },
270
271 processAjaxResults: function ( json, params ) {
272 // vars
273 var json = this.getAjaxResults( json, params );
274
275 // change more to pagination
276 if ( json.more ) {
277 json.pagination = { more: true };
278 }
279
280 // merge together groups
281 setTimeout( $.proxy( this.mergeOptions, this ), 1 );
282
283 // return
284 return json;
285 },
286
287 destroy: function () {
288 // destroy via api
289 if ( this.$el.data( 'select2' ) ) {
290 this.$el.select2( 'destroy' );
291 }
292
293 // destory via HTML (duplicating HTML does not contain data)
294 this.$el.siblings( '.select2-container' ).remove();
295 },
296 } );
297
298 /**
299 * Select2_4
300 *
301 * description
302 *
303 * @date 13/1/18
304 * @since ACF 5.6.5
305 *
306 * @param type $var Description. Default.
307 * @return type Description.
308 */
309
310 var Select2_4 = Select2.extend( {
311 initialize: function () {
312 // vars
313 var $select = this.$el;
314 var options = {
315 width: '100%',
316 allowClear: this.get( 'allowNull' ),
317 placeholder: this.get( 'placeholder' ),
318 multiple: this.get( 'multiple' ),
319 escapeMarkup: this.get( 'escapeMarkup' ),
320 templateSelection: this.get( 'templateSelection' ),
321 templateResult: this.get( 'templateResult' ),
322 dropdownCssClass: this.get( 'dropdownCssClass' ),
323 suppressFilters: this.get( 'suppressFilters' ),
324 data: [],
325 };
326
327 // Clear empty templateSelections, templateResults, or dropdownCssClass.
328 if ( ! options.templateSelection ) {
329 delete options.templateSelection;
330 }
331 if ( ! options.templateResult ) {
332 delete options.templateResult;
333 }
334 if ( ! options.dropdownCssClass ) {
335 delete options.dropdownCssClass;
336 }
337
338 // Only use the template if SelectWoo is not loaded to work around https://github.com/woocommerce/woocommerce/pull/30473
339 if ( ! acf.isset( window, 'jQuery', 'fn', 'selectWoo' ) ) {
340 if ( ! options.templateSelection ) {
341 options.templateSelection = function ( selection ) {
342 var $selection = $(
343 '<span class="acf-selection"></span>'
344 );
345 $selection.html(
346 options.escapeMarkup( selection.text )
347 );
348 $selection.data( 'element', selection.element );
349 return $selection;
350 };
351 }
352 } else {
353 delete options.templateSelection;
354 delete options.templateResult;
355 }
356
357 // Use a default, filterable escapeMarkup if not provided.
358 if ( ! options.escapeMarkup ) {
359 options.escapeMarkup = function ( markup ) {
360 if ( typeof markup !== 'string' ) {
361 return markup;
362 }
363
364 if ( this.suppressFilters ) {
365 return acf.strEscape( markup );
366 }
367
368 return acf.applyFilters(
369 'select2_escape_markup',
370 acf.strEscape( markup ),
371 markup,
372 $select,
373 this.data,
374 field || false,
375 this
376 );
377 };
378 }
379
380 // multiple
381 if ( options.multiple ) {
382 // reorder options
383 this.getValue().map( function ( item ) {
384 item.$el.detach().appendTo( $select );
385 } );
386 }
387
388 // Temporarily remove conflicting attribute.
389 var attrAjax = $select.attr( 'data-ajax' );
390 if ( attrAjax !== undefined ) {
391 $select.removeData( 'ajax' );
392 $select.removeAttr( 'data-ajax' );
393 }
394
395 // ajax
396 if ( this.get( 'ajax' ) ) {
397 options.ajax = {
398 url: acf.get( 'ajaxurl' ),
399 delay: 250,
400 dataType: 'json',
401 type: 'post',
402 cache: false,
403 data: $.proxy( this.getAjaxData, this ),
404 processResults: $.proxy( this.processAjaxResults, this ),
405 };
406 }
407
408 // filter for 3rd party customization
409 if ( ! options.suppressFilters ) {
410 var field = this.get( 'field' );
411 options = acf.applyFilters(
412 'select2_args',
413 options,
414 $select,
415 this.data,
416 field || false,
417 this
418 );
419 }
420 // add select2
421 $select.select2( options );
422
423 // get container (Select2 v4 does not return this from constructor)
424 var $container = $select.next( '.select2-container' );
425
426 // multiple
427 if ( options.multiple ) {
428 // vars
429 var $ul = $container.find( 'ul' );
430
431 // sortable
432 $ul.sortable( {
433 stop: function ( e ) {
434 // loop
435 $ul.find( '.select2-selection__choice' ).each(
436 function () {
437 // Attempt to use .data if it exists (select2 version < 4.0.6) or use our template data instead.
438 if ( $( this ).data( 'data' ) ) {
439 var $option = $(
440 $( this ).data( 'data' ).element
441 );
442 } else {
443 var $option = $(
444 $( this )
445 .find( 'span.acf-selection' )
446 .data( 'element' )
447 );
448 }
449
450 // detach and re-append to end
451 $option.detach().appendTo( $select );
452 }
453 );
454
455 // trigger change on input (JS error if trigger on select)
456 $select.trigger( 'change' );
457 },
458 } );
459
460 // on select, move to end
461 $select.on(
462 'select2:select',
463 this.proxy( function ( e ) {
464 this.getOption( e.params.data.id )
465 .detach()
466 .appendTo( this.$el );
467 } )
468 );
469 }
470
471 // add handler to auto-focus searchbox (for jQuery 3.6)
472 $select.on( 'select2:open', () => {
473 $( '.select2-container--open .select2-search__field' )
474 .get( -1 )
475 .focus();
476 } );
477
478 // add class
479 $container.addClass( '-acf' );
480
481 // Add back temporarily removed attr.
482 if ( attrAjax !== undefined ) {
483 $select.attr( 'data-ajax', attrAjax );
484 }
485
486 // action for 3rd party customization
487 if ( ! options.suppressFilters ) {
488 acf.doAction(
489 'select2_init',
490 $select,
491 options,
492 this.data,
493 field || false,
494 this
495 );
496 }
497 },
498
499 mergeOptions: function () {
500 // vars
501 var $prevOptions = false;
502 var $prevGroup = false;
503
504 // loop
505 $( '.select2-results__option[role="group"]' ).each( function () {
506 // vars
507 var $options = $( this ).children( 'ul' );
508 var $group = $( this ).children( 'strong' );
509
510 // compare to previous
511 if ( $prevGroup && $prevGroup.text() === $group.text() ) {
512 $prevOptions.append( $options.children() );
513 $( this ).remove();
514 return;
515 }
516
517 // update vars
518 $prevOptions = $options;
519 $prevGroup = $group;
520 } );
521 },
522 } );
523
524 /**
525 * Select2_3
526 *
527 * description
528 *
529 * @date 13/1/18
530 * @since ACF 5.6.5
531 *
532 * @param type $var Description. Default.
533 * @return type Description.
534 */
535
536 var Select2_3 = Select2.extend( {
537 initialize: function () {
538 // vars
539 var $select = this.$el;
540 var value = this.getValue();
541 var multiple = this.get( 'multiple' );
542 var options = {
543 width: '100%',
544 allowClear: this.get( 'allowNull' ),
545 placeholder: this.get( 'placeholder' ),
546 separator: '||',
547 multiple: this.get( 'multiple' ),
548 data: this.getChoices(),
549 escapeMarkup: function ( string ) {
550 return acf.escHtml( string );
551 },
552 dropdownCss: {
553 'z-index': '999999999',
554 },
555 initSelection: function ( element, callback ) {
556 if ( multiple ) {
557 callback( value );
558 } else {
559 callback( value.shift() );
560 }
561 },
562 };
563 // get hidden input
564 var $input = $select.siblings( 'input' );
565 if ( ! $input.length ) {
566 $input = $( '<input type="hidden" />' );
567 $select.before( $input );
568 }
569
570 // set input value
571 inputValue = value
572 .map( function ( item ) {
573 return item.id;
574 } )
575 .join( '||' );
576 $input.val( inputValue );
577
578 // multiple
579 if ( options.multiple ) {
580 // reorder options
581 value.map( function ( item ) {
582 item.$el.detach().appendTo( $select );
583 } );
584 }
585
586 // remove blank option as we have a clear all button
587 if ( options.allowClear ) {
588 options.data = options.data.filter( function ( item ) {
589 return item.id !== '';
590 } );
591 }
592
593 // remove conflicting atts
594 $select.removeData( 'ajax' );
595 $select.removeAttr( 'data-ajax' );
596
597 // ajax
598 if ( this.get( 'ajax' ) ) {
599 options.ajax = {
600 url: acf.get( 'ajaxurl' ),
601 quietMillis: 250,
602 dataType: 'json',
603 type: 'post',
604 cache: false,
605 data: $.proxy( this.getAjaxData, this ),
606 results: $.proxy( this.processAjaxResults, this ),
607 };
608 }
609
610 // filter for 3rd party customization
611 var field = this.get( 'field' );
612 options = acf.applyFilters(
613 'select2_args',
614 options,
615 $select,
616 this.data,
617 field || false,
618 this
619 );
620
621 // add select2
622 $input.select2( options );
623
624 // get container
625 var $container = $input.select2( 'container' );
626
627 // helper to find this select's option
628 var getOption = $.proxy( this.getOption, this );
629
630 // multiple
631 if ( options.multiple ) {
632 // vars
633 var $ul = $container.find( 'ul' );
634
635 // sortable
636 $ul.sortable( {
637 stop: function () {
638 // loop
639 $ul.find( '.select2-search-choice' ).each( function () {
640 // vars
641 var data = $( this ).data( 'select2Data' );
642 var $option = getOption( data.id );
643
644 // detach and re-append to end
645 $option.detach().appendTo( $select );
646 } );
647
648 // trigger change on input (JS error if trigger on select)
649 $select.trigger( 'change' );
650 },
651 } );
652 }
653
654 // on select, create option and move to end
655 $input.on( 'select2-selecting', function ( e ) {
656 // vars
657 var item = e.choice;
658 var $option = getOption( item.id );
659
660 // create if doesn't exist
661 if ( ! $option.length ) {
662 $option = $(
663 '<option value="' +
664 item.id +
665 '">' +
666 item.text +
667 '</option>'
668 );
669 }
670
671 // detach and re-append to end
672 $option.detach().appendTo( $select );
673 } );
674
675 // add class
676 $container.addClass( '-acf' );
677
678 // action for 3rd party customization
679 acf.doAction(
680 'select2_init',
681 $select,
682 options,
683 this.data,
684 field || false,
685 this
686 );
687
688 // change
689 $input.on( 'change', function () {
690 var val = $input.val();
691 if ( val.indexOf( '||' ) ) {
692 val = val.split( '||' );
693 }
694 $select.val( val ).trigger( 'change' );
695 } );
696
697 // hide select
698 $select.hide();
699 },
700
701 mergeOptions: function () {
702 // vars
703 var $prevOptions = false;
704 var $prevGroup = false;
705
706 // loop
707 $( '#select2-drop .select2-result-with-children' ).each(
708 function () {
709 // vars
710 var $options = $( this ).children( 'ul' );
711 var $group = $( this ).children( '.select2-result-label' );
712
713 // compare to previous
714 if ( $prevGroup && $prevGroup.text() === $group.text() ) {
715 $prevGroup.append( $options.children() );
716 $( this ).remove();
717 return;
718 }
719
720 // update vars
721 $prevOptions = $options;
722 $prevGroup = $group;
723 }
724 );
725 },
726
727 getAjaxData: function ( term, page ) {
728 // create Select2 v4 params
729 var params = {
730 term: term,
731 page: page,
732 };
733
734 // filter
735 var field = this.get( 'field' );
736 params = acf.applyFilters(
737 'select2_ajax_data',
738 params,
739 this.data,
740 this.$el,
741 field || false,
742 this
743 );
744 // return
745 return Select2.prototype.getAjaxData.apply( this, [ params ] );
746 },
747 } );
748
749 // manager
750 var select2Manager = new acf.Model( {
751 priority: 5,
752 wait: 'prepare',
753 actions: {
754 duplicate: 'onDuplicate',
755 },
756 initialize: function () {
757 // vars
758 var locale = acf.get( 'locale' );
759 var rtl = acf.get( 'rtl' );
760 var l10n = acf.get( 'select2L10n' );
761 var version = getVersion();
762
763 // bail early if no l10n
764 if ( ! l10n ) {
765 return false;
766 }
767
768 // bail early if 'en'
769 if ( locale.indexOf( 'en' ) === 0 ) {
770 return false;
771 }
772
773 // initialize
774 if ( version == 4 ) {
775 this.addTranslations4();
776 } else if ( version == 3 ) {
777 this.addTranslations3();
778 }
779 },
780
781 addTranslations4: function () {
782 // vars
783 var l10n = acf.get( 'select2L10n' );
784 var locale = acf.get( 'locale' );
785
786 // modify local to match html[lang] attribute (used by Select2)
787 locale = locale.replace( '_', '-' );
788
789 // select2L10n
790 var select2L10n = {
791 errorLoading: function () {
792 return l10n.load_fail;
793 },
794 inputTooLong: function ( args ) {
795 var overChars = args.input.length - args.maximum;
796 if ( overChars > 1 ) {
797 return l10n.input_too_long_n.replace( '%d', overChars );
798 }
799 return l10n.input_too_long_1;
800 },
801 inputTooShort: function ( args ) {
802 var remainingChars = args.minimum - args.input.length;
803 if ( remainingChars > 1 ) {
804 return l10n.input_too_short_n.replace(
805 '%d',
806 remainingChars
807 );
808 }
809 return l10n.input_too_short_1;
810 },
811 loadingMore: function () {
812 return l10n.load_more;
813 },
814 maximumSelected: function ( args ) {
815 var maximum = args.maximum;
816 if ( maximum > 1 ) {
817 return l10n.selection_too_long_n.replace(
818 '%d',
819 maximum
820 );
821 }
822 return l10n.selection_too_long_1;
823 },
824 noResults: function () {
825 return l10n.matches_0;
826 },
827 searching: function () {
828 return l10n.searching;
829 },
830 };
831
832 // append
833 jQuery.fn.select2.amd.define(
834 'select2/i18n/' + locale,
835 [],
836 function () {
837 return select2L10n;
838 }
839 );
840 },
841
842 addTranslations3: function () {
843 // vars
844 var l10n = acf.get( 'select2L10n' );
845 var locale = acf.get( 'locale' );
846
847 // modify local to match html[lang] attribute (used by Select2)
848 locale = locale.replace( '_', '-' );
849
850 // select2L10n
851 var select2L10n = {
852 formatMatches: function ( matches ) {
853 if ( matches > 1 ) {
854 return l10n.matches_n.replace( '%d', matches );
855 }
856 return l10n.matches_1;
857 },
858 formatNoMatches: function () {
859 return l10n.matches_0;
860 },
861 formatAjaxError: function () {
862 return l10n.load_fail;
863 },
864 formatInputTooShort: function ( input, min ) {
865 var remainingChars = min - input.length;
866 if ( remainingChars > 1 ) {
867 return l10n.input_too_short_n.replace(
868 '%d',
869 remainingChars
870 );
871 }
872 return l10n.input_too_short_1;
873 },
874 formatInputTooLong: function ( input, max ) {
875 var overChars = input.length - max;
876 if ( overChars > 1 ) {
877 return l10n.input_too_long_n.replace( '%d', overChars );
878 }
879 return l10n.input_too_long_1;
880 },
881 formatSelectionTooBig: function ( maximum ) {
882 if ( maximum > 1 ) {
883 return l10n.selection_too_long_n.replace(
884 '%d',
885 maximum
886 );
887 }
888 return l10n.selection_too_long_1;
889 },
890 formatLoadMore: function () {
891 return l10n.load_more;
892 },
893 formatSearching: function () {
894 return l10n.searching;
895 },
896 };
897
898 // ensure locales exists
899 $.fn.select2.locales = $.fn.select2.locales || {};
900
901 // append
902 $.fn.select2.locales[ locale ] = select2L10n;
903 $.extend( $.fn.select2.defaults, select2L10n );
904 },
905
906 onDuplicate: function ( $el, $el2 ) {
907 $el2.find( '.select2-container' ).remove();
908 },
909 } );
910 } )( jQuery );
911