| @@ -38,14 +38,37 @@ | ||
| 38 | 38 | if ($.fn.select2) { |
| 39 | 39 | $('select[multiple="multiple"]').each(function() { |
| 40 | 40 | if (!$(this).hasClass('select2-hidden-accessible')) { |
| 41 | 41 | |
| 42 | - $(this).select2({ | |
| 42 | + var $field = $(this); | |
| 43 | + var fieldLabel = $.trim($('label[for="' + $field.attr('id') + '"]').first().text()) | |
| 44 | + || $field.attr('placeholder') | |
| 45 | + || 'Select options'; | |
| 46 | + | |
| 47 | + $field.select2({ | |
| 43 | 48 | width: '100%', |
| 44 | - placeholder: $(this).attr('placeholder') || 'Select options', | |
| 49 | + placeholder: $field.attr('placeholder') || 'Select options', | |
| 45 | 50 | closeOnSelect: false, |
| 46 | 51 | allowClear: true |
| 47 | 52 | }); |
| 53 | + | |
| 54 | + // Name the search box Select2 builds for itself. Select2 4.0.13 | |
| 55 | + // renders `.select2-search__field` with no label and no aria-label, | |
| 56 | + // so a screen reader announces it as an unnamed text field. On a | |
| 57 | + // multiselect that box lives inside the selection control and is | |
| 58 | + // present from the moment Select2 initialises — not only while the | |
| 59 | + // dropdown is open — so it is labelled here, and again on open to | |
| 60 | + // cover the search field Select2 renders into the dropdown itself. | |
| 61 | + var labelSearchFields = function ($root) { | |
| 62 | + $root.find('.select2-search__field') | |
| 63 | + .filter(function () { return !this.getAttribute('aria-label'); }) | |
| 64 | + .attr('aria-label', fieldLabel); | |
| 65 | + }; | |
| 66 | + | |
| 67 | + labelSearchFields($field.next('.select2-container')); | |
| 68 | + $field.on('select2:open', function () { | |
| 69 | + labelSearchFields($('.select2-container--open')); | |
| 70 | + }); | |
| 48 | 71 | } |
| 49 | 72 | }); |
| 50 | 73 | } |
| 51 | 74 | } |
| @@ -97,8 +120,45 @@ | ||
| 97 | 120 | settingsDiv.removeClass('hidden'); |
| 98 | 121 | } else { |
| 99 | 122 | settingsDiv.addClass('hidden'); |
| 100 | 123 | } |
| 124 | + }); | |
| 125 | + | |
| 126 | + // Offline payment methods the merchant adds (ACH, wire, …). Adding or | |
| 127 | + // removing one registers a gateway, so the page reloads to show it. | |
| 128 | + var offlineNonce = (typeof easyInvoiceSettings !== 'undefined' && easyInvoiceSettings.nonce) ? easyInvoiceSettings.nonce : ''; | |
| 129 | + var offlineAjax = (typeof easyInvoiceSettings !== 'undefined' && easyInvoiceSettings.ajaxurl) ? easyInvoiceSettings.ajaxurl : (window.ajaxurl || ''); | |
| 130 | + var toast = function (type, message) { | |
| 131 | + if (typeof EasyInvoiceToast !== 'undefined' && EasyInvoiceToast[type]) { EasyInvoiceToast[type](message); } else if (message) { window.alert(message); } | |
| 132 | + }; | |
| 133 | + $('#ei-offline-add-btn').on('click', function () { | |
| 134 | + var $btn = $(this), title = $.trim($('#ei-offline-add-title').val() || ''); | |
| 135 | + if (!title) { toast('error', 'Give the payment method a name.'); $('#ei-offline-add-title').focus(); return; } | |
| 136 | + $btn.prop('disabled', true); | |
| 137 | + $.post(offlineAjax, { action: 'easy_invoice_add_offline_method', nonce: offlineNonce, title: title }) | |
| 138 | + .done(function (r) { | |
| 139 | + if (r && r.success) { | |
| 140 | + toast('success', r.data && r.data.message ? r.data.message : 'Payment method added.'); | |
| 141 | + var url = new URL(window.location.href); url.searchParams.set('section', 'payment'); url.hash = ''; | |
| 142 | + setTimeout(function () { window.location.href = url.toString() + '#gateway-enable-' + (r.data && r.data.id ? r.data.id : ''); }, 600); | |
| 143 | + } else { | |
| 144 | + toast('error', r && r.data && r.data.message ? r.data.message : 'The payment method could not be added.'); | |
| 145 | + $btn.prop('disabled', false); | |
| 146 | + } | |
| 147 | + }) | |
| 148 | + .fail(function () { toast('error', 'The payment method could not be added.'); $btn.prop('disabled', false); }); | |
| 149 | + }); | |
| 150 | + $('#ei-offline-add-title').on('keydown', function (e) { if (e.key === 'Enter') { e.preventDefault(); $('#ei-offline-add-btn').trigger('click'); } }); | |
| 151 | + $('#settings-form').on('click', '.ei-offline-remove', function () { | |
| 152 | + var $btn = $(this), id = $btn.data('method-id'), name = $btn.data('method-title') || id; | |
| 153 | + if (!window.confirm('Remove "' + name + '" from the payment methods you offer? Payments already recorded keep it.')) { return; } | |
| 154 | + $btn.prop('disabled', true); | |
| 155 | + $.post(offlineAjax, { action: 'easy_invoice_remove_offline_method', nonce: offlineNonce, id: id }) | |
| 156 | + .done(function (r) { | |
| 157 | + if (r && r.success) { toast('success', r.data && r.data.message ? r.data.message : 'Payment method removed.'); setTimeout(function () { window.location.reload(); }, 600); } | |
| 158 | + else { toast('error', r && r.data && r.data.message ? r.data.message : 'The payment method could not be removed.'); $btn.prop('disabled', false); } | |
| 159 | + }) | |
| 160 | + .fail(function () { toast('error', 'The payment method could not be removed.'); $btn.prop('disabled', false); }); | |
| 101 | 161 | }); |
| 102 | 162 | |
| 103 | 163 | // Initialize gateway settings visibility on page load |
| 104 | 164 | $('.gateway-enable-checkbox').each(function() { |