wc-enhanced-select.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*global wc_enhanced_select_params */
  2. jQuery( function( $ ) {
  3. function getEnhancedSelectFormatString() {
  4. return {
  5. 'language': {
  6. errorLoading: function() {
  7. // Workaround for https://github.com/select2/select2/issues/4355 instead of i18n_ajax_error.
  8. return wc_enhanced_select_params.i18n_searching;
  9. },
  10. inputTooLong: function( args ) {
  11. var overChars = args.input.length - args.maximum;
  12. if ( 1 === overChars ) {
  13. return wc_enhanced_select_params.i18n_input_too_long_1;
  14. }
  15. return wc_enhanced_select_params.i18n_input_too_long_n.replace( '%qty%', overChars );
  16. },
  17. inputTooShort: function( args ) {
  18. var remainingChars = args.minimum - args.input.length;
  19. if ( 1 === remainingChars ) {
  20. return wc_enhanced_select_params.i18n_input_too_short_1;
  21. }
  22. return wc_enhanced_select_params.i18n_input_too_short_n.replace( '%qty%', remainingChars );
  23. },
  24. loadingMore: function() {
  25. return wc_enhanced_select_params.i18n_load_more;
  26. },
  27. maximumSelected: function( args ) {
  28. if ( args.maximum === 1 ) {
  29. return wc_enhanced_select_params.i18n_selection_too_long_1;
  30. }
  31. return wc_enhanced_select_params.i18n_selection_too_long_n.replace( '%qty%', args.maximum );
  32. },
  33. noResults: function() {
  34. return wc_enhanced_select_params.i18n_no_matches;
  35. },
  36. searching: function() {
  37. return wc_enhanced_select_params.i18n_searching;
  38. }
  39. }
  40. };
  41. }
  42. try {
  43. $( document.body )
  44. .on( 'wc-enhanced-select-init', function() {
  45. // Regular select boxes
  46. $( ':input.wc-enhanced-select, :input.chosen_select' ).filter( ':not(.enhanced)' ).each( function() {
  47. var select2_args = $.extend({
  48. minimumResultsForSearch: 10,
  49. allowClear: $( this ).data( 'allow_clear' ) ? true : false,
  50. placeholder: $( this ).data( 'placeholder' )
  51. }, getEnhancedSelectFormatString() );
  52. $( this ).selectWoo( select2_args ).addClass( 'enhanced' );
  53. });
  54. $( ':input.wc-enhanced-select-nostd, :input.chosen_select_nostd' ).filter( ':not(.enhanced)' ).each( function() {
  55. var select2_args = $.extend({
  56. minimumResultsForSearch: 10,
  57. allowClear: true,
  58. placeholder: $( this ).data( 'placeholder' )
  59. }, getEnhancedSelectFormatString() );
  60. $( this ).selectWoo( select2_args ).addClass( 'enhanced' );
  61. });
  62. // Ajax product search box
  63. $( ':input.wc-product-search' ).filter( ':not(.enhanced)' ).each( function() {
  64. var select2_args = {
  65. allowClear: $( this ).data( 'allow_clear' ) ? true : false,
  66. placeholder: $( this ).data( 'placeholder' ),
  67. minimumInputLength: $( this ).data( 'minimum_input_length' ) ? $( this ).data( 'minimum_input_length' ) : '3',
  68. escapeMarkup: function( m ) {
  69. return m;
  70. },
  71. ajax: {
  72. url: wc_enhanced_select_params.ajax_url,
  73. dataType: 'json',
  74. delay: 250,
  75. data: function( params ) {
  76. return {
  77. term: params.term,
  78. action: $( this ).data( 'action' ) || 'woocommerce_json_search_products_and_variations',
  79. security: wc_enhanced_select_params.search_products_nonce,
  80. exclude: $( this ).data( 'exclude' ),
  81. include: $( this ).data( 'include' ),
  82. limit: $( this ).data( 'limit' )
  83. };
  84. },
  85. processResults: function( data ) {
  86. var terms = [];
  87. if ( data ) {
  88. $.each( data, function( id, text ) {
  89. terms.push( { id: id, text: text } );
  90. });
  91. }
  92. return {
  93. results: terms
  94. };
  95. },
  96. cache: true
  97. }
  98. };
  99. select2_args = $.extend( select2_args, getEnhancedSelectFormatString() );
  100. $( this ).selectWoo( select2_args ).addClass( 'enhanced' );
  101. if ( $( this ).data( 'sortable' ) ) {
  102. var $select = $(this);
  103. var $list = $( this ).next( '.select2-container' ).find( 'ul.select2-selection__rendered' );
  104. $list.sortable({
  105. placeholder : 'ui-state-highlight select2-selection__choice',
  106. forcePlaceholderSize: true,
  107. items : 'li:not(.select2-search__field)',
  108. tolerance : 'pointer',
  109. stop: function() {
  110. $( $list.find( '.select2-selection__choice' ).get().reverse() ).each( function() {
  111. var id = $( this ).data( 'data' ).id;
  112. var option = $select.find( 'option[value="' + id + '"]' )[0];
  113. $select.prepend( option );
  114. } );
  115. }
  116. });
  117. // Keep multiselects ordered alphabetically if they are not sortable.
  118. } else if ( $( this ).prop( 'multiple' ) ) {
  119. $( this ).on( 'change', function(){
  120. var $children = $( this ).children();
  121. $children.sort(function(a, b){
  122. var atext = a.text.toLowerCase();
  123. var btext = b.text.toLowerCase();
  124. if ( atext > btext ) {
  125. return 1;
  126. }
  127. if ( atext < btext ) {
  128. return -1;
  129. }
  130. return 0;
  131. });
  132. $( this ).html( $children );
  133. });
  134. }
  135. });
  136. // Ajax customer search boxes
  137. $( ':input.wc-customer-search' ).filter( ':not(.enhanced)' ).each( function() {
  138. var select2_args = {
  139. allowClear: $( this ).data( 'allow_clear' ) ? true : false,
  140. placeholder: $( this ).data( 'placeholder' ),
  141. minimumInputLength: $( this ).data( 'minimum_input_length' ) ? $( this ).data( 'minimum_input_length' ) : '1',
  142. escapeMarkup: function( m ) {
  143. return m;
  144. },
  145. ajax: {
  146. url: wc_enhanced_select_params.ajax_url,
  147. dataType: 'json',
  148. delay: 1000,
  149. data: function( params ) {
  150. return {
  151. term: params.term,
  152. action: 'woocommerce_json_search_customers',
  153. security: wc_enhanced_select_params.search_customers_nonce,
  154. exclude: $( this ).data( 'exclude' )
  155. };
  156. },
  157. processResults: function( data ) {
  158. var terms = [];
  159. if ( data ) {
  160. $.each( data, function( id, text ) {
  161. terms.push({
  162. id: id,
  163. text: text
  164. });
  165. });
  166. }
  167. return {
  168. results: terms
  169. };
  170. },
  171. cache: true
  172. }
  173. };
  174. select2_args = $.extend( select2_args, getEnhancedSelectFormatString() );
  175. $( this ).selectWoo( select2_args ).addClass( 'enhanced' );
  176. if ( $( this ).data( 'sortable' ) ) {
  177. var $select = $(this);
  178. var $list = $( this ).next( '.select2-container' ).find( 'ul.select2-selection__rendered' );
  179. $list.sortable({
  180. placeholder : 'ui-state-highlight select2-selection__choice',
  181. forcePlaceholderSize: true,
  182. items : 'li:not(.select2-search__field)',
  183. tolerance : 'pointer',
  184. stop: function() {
  185. $( $list.find( '.select2-selection__choice' ).get().reverse() ).each( function() {
  186. var id = $( this ).data( 'data' ).id;
  187. var option = $select.find( 'option[value="' + id + '"]' )[0];
  188. $select.prepend( option );
  189. } );
  190. }
  191. });
  192. }
  193. });
  194. // Ajax category search boxes
  195. $( ':input.wc-category-search' ).filter( ':not(.enhanced)' ).each( function() {
  196. var select2_args = $.extend( {
  197. allowClear : $( this ).data( 'allow_clear' ) ? true : false,
  198. placeholder : $( this ).data( 'placeholder' ),
  199. minimumInputLength: $( this ).data( 'minimum_input_length' ) ? $( this ).data( 'minimum_input_length' ) : 3,
  200. escapeMarkup : function( m ) {
  201. return m;
  202. },
  203. ajax: {
  204. url: wc_enhanced_select_params.ajax_url,
  205. dataType: 'json',
  206. delay: 250,
  207. data: function( params ) {
  208. return {
  209. term: params.term,
  210. action: 'woocommerce_json_search_categories',
  211. security: wc_enhanced_select_params.search_categories_nonce
  212. };
  213. },
  214. processResults: function( data ) {
  215. var terms = [];
  216. if ( data ) {
  217. $.each( data, function( id, term ) {
  218. terms.push({
  219. id: term.slug,
  220. text: term.formatted_name
  221. });
  222. });
  223. }
  224. return {
  225. results: terms
  226. };
  227. },
  228. cache: true
  229. }
  230. }, getEnhancedSelectFormatString() );
  231. $( this ).selectWoo( select2_args ).addClass( 'enhanced' );
  232. });
  233. })
  234. // WooCommerce Backbone Modal
  235. .on( 'wc_backbone_modal_before_remove', function() {
  236. $( '.wc-enhanced-select, :input.wc-product-search, :input.wc-customer-search' ).filter( '.select2-hidden-accessible' ).selectWoo( 'close' );
  237. })
  238. .trigger( 'wc-enhanced-select-init' );
  239. $( 'html' ).on( 'click', function( event ) {
  240. if ( this === event.target ) {
  241. $( '.wc-enhanced-select, :input.wc-product-search, :input.wc-customer-search' ).filter( '.select2-hidden-accessible' ).selectWoo( 'close' );
  242. }
  243. } );
  244. } catch( err ) {
  245. // If select2 failed (conflict?) log the error but don't stop other scripts breaking.
  246. window.console.log( err );
  247. }
  248. });