PluginProbe ʕ •ᴥ•ʔ
WooCommerce / 8.8.0-rc.1
WooCommerce v8.8.0-rc.1
10.9.1 10.9.0 10.9.0-rc.1 10.9.0-beta.2 10.9.0-beta.1 10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 7.8.0-beta.1 7.8.0-beta.2 7.8.0-rc.1 7.8.0-rc.2 7.8.1 7.8.2 7.8.3 7.8.4 7.9.0 7.9.0-beta.1 7.9.0-beta.2 7.9.0-rc.2 7.9.0-rc.3 7.9.1 7.9.2 8.0.0 8.0.0-beta.1 8.0.0-beta.2 8.0.0-rc.1 8.0.0-rc.2 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.1.0 8.1.0-beta.1 8.1.0-rc.1 8.1.0-rc.2 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 8.2.0-beta.1 8.2.0-rc.1 8.2.0-rc.2 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.3.0 8.3.0-beta.1 8.3.0-rc.1 8.3.0-rc.2 8.3.1 8.3.2 8.3.3 8.3.4 8.4.0 8.4.0-beta.1 8.4.0-rc.1 8.4.1 8.4.2 8.4.3 8.5.0 8.5.0-beta.1 8.5.0-rc.1 8.5.1 8.5.2 8.5.3 8.5.4 8.5.5 8.6.0 8.6.0-beta.1 8.6.0-rc.1 8.6.1 8.6.2 8.6.3 8.6.4 8.7.0 8.7.0-beta.1 8.7.0-beta.2 8.7.0-rc.1 8.7.1 8.7.2 8.7.3 8.8.0 8.8.0-beta.1 8.8.0-rc.1 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.8.6 8.8.7 8.9.0 8.9.0-beta.1 8.9.0-rc.1 8.9.1 8.9.2 8.9.3 8.9.4 8.9.5 9.0.0 9.0.0-beta.1 9.0.0-beta.2 9.0.0-rc.1 9.0.1 9.0.2 9.0.3 9.0.4 9.1.0 9.1.0-beta.1 9.1.0-rc.1 9.1.1 9.1.2 9.1.3 9.1.4 9.1.5 9.1.6 9.2.0 9.2.0-beta.1 9.2.0-rc.1 9.2.1 9.2.2 9.2.3 9.2.4 9.2.5 9.3.0 9.3.0-beta.1 9.3.0-rc.1 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.3.6 9.4.0 9.4.0-beta.1 9.4.0-beta.2 9.4.0-rc.1 9.4.0-rc.2 9.4.0-rc.3 9.4.0-rc.4 9.4.1 9.4.2 9.4.3 9.4.4 9.4.5 9.5.0 9.5.0-beta.1 9.5.0-beta.2 9.5.0-rc.1 9.5.1 9.5.2 9.5.3 9.5.4 9.6.0 9.6.0-beta.1 9.6.0-beta.2 9.6.0-rc.1 9.6.1 9.6.2 9.6.3 9.6.4 9.7.0 9.7.0-beta.1 9.7.0-rc.1 9.7.1 9.7.2 9.7.3 9.8.0 9.8.0-beta.1 9.8.0-rc.1 9.8.1 9.8.2 9.8.3 9.8.4 9.8.5 9.8.6 9.8.7 9.9.0 9.9.0-beta.1 9.9.0-rc.1 9.9.1 9.9.2 9.9.3 9.9.4 9.9.5 9.9.6 9.9.7 3.7.3 7.1.2 3.8.0 7.2.0 3.8.0-beta.1 7.2.0-beta.1 3.8.0-rc.1 7.2.0-beta.2 3.8.0-rc.2 7.2.0-rc.1 3.8.1 7.2.0-rc.2 3.8.2 7.2.1 3.8.3 7.2.2 3.9.0 7.2.3 3.9.0-beta.1 7.2.4 3.9.0-beta.2 7.3.0 3.9.0-rc.1 7.3.0-beta.1 3.9.0-rc.2 7.3.0-beta.2 3.9.0-rc.3 7.3.0-rc.1 3.9.0-rc.4 7.3.0-rc.2 3.9.1 7.3.1 3.9.2 7.4.0 3.9.3 7.4.0-beta.1 3.9.4 7.4.0-beta.2 3.9.5 7.4.0-rc.1 4.0.0 7.4.0-rc.2 4.0.0-beta.1 7.4.1 4.0.0-rc.1 7.4.2 4.0.0-rc.2 7.5.0 4.0.1 7.5.0-beta.1 4.0.2 7.5.0-beta.2 4.0.3 7.5.0-rc.1 4.0.4 7.5.1 4.1.0 7.5.2 4.1.0-beta.1 7.6.0 4.1.0-beta.2 7.6.0-beta.1 4.1.0-rc.1 7.6.0-beta.2 4.1.0-rc.2 7.6.0-rc.1 4.1.1 7.6.0-rc.2 4.1.2 7.6.0-rc.3 4.1.3 7.6.1 4.1.4 7.6.2 4.2.0 7.7.0 4.2.0-RC.1 7.7.0-beta.1 4.2.0-RC.2 7.7.0-beta.2 4.2.0-beta.1 7.7.0-rc.1 4.2.1 7.7.1 4.2.2 7.7.2 4.2.3 7.7.3 4.2.4 7.8.0 4.2.5 4.3.0 4.3.0-beta.1 4.3.0-rc.1 4.3.0-rc.2 4.3.0-rc.3 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.4.0 4.4.0-beta.1 4.4.0-rc.1 4.4.1 4.4.2 4.4.3 4.4.4 4.5.0 4.5.0-beta.1 4.5.0-rc.1 4.5.0-rc.3 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.6.0-beta.1 4.6.0-rc.1 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.7.0 4.7.0-beta.1 4.7.0-beta.2 4.7.0-rc.1 4.7.1 4.7.1-beta.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.0-beta.1 4.8.0-rc.1 4.8.0-rc.2 4.8.1 4.8.2 4.8.3 4.9.0 4.9.0-beta.1 4.9.0-rc.1 4.9.0-rc.2 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 5.0.0 5.0.0-beta.1 5.0.0-beta.2 5.0.0-rc.1 5.0.0-rc.2 5.0.0-rc.3 5.0.1 5.0.2 5.0.3 5.1.0 5.1.0-beta.1 5.1.0-rc.1 trunk 5.1.1 10.0.0 5.1.2 10.0.0-rc.1 5.1.3 10.0.0-rc.2 5.2.0 10.0.1 5.2.0-beta.1 10.0.2 5.2.0-rc.1 10.0.3 5.2.0-rc.2 10.0.4 5.2.1 10.0.5 5.2.2 10.0.6 5.2.3 10.1.0 5.2.4 10.1.0-rc.1 5.2.5 10.1.0-rc.2 5.3.0 10.1.0-rc.3 5.3.0-beta.1 10.1.0-rc.4 5.3.0-rc.1 10.1.1 5.3.0-rc.2 10.1.2 5.3.1 10.1.3 5.3.2 10.1.4 5.3.3 10.2.0 5.4.0 10.2.0-beta.1 5.4.0-beta.1 10.2.0-beta.2 5.4.0-rc.1 10.2.0-rc.1 5.4.1 10.2.1 5.4.2 10.2.2 5.4.3 10.2.3 5.4.4 10.2.4 5.4.5 10.3.0 5.5.0 10.3.0-beta.1 5.5.0-beta.1 10.3.0-beta.2 5.5.0-rc.1 10.3.0-rc.1 5.5.0-rc.2 10.3.0-rc.2 5.5.1 10.3.1 5.5.2 10.3.2 5.5.3 10.3.3 5.5.4 10.3.4 5.5.5 10.3.5 5.6.0 10.3.6 5.6.0-beta.1 10.3.7 5.6.0-rc.1 10.3.8 5.6.0-rc.2 10.4.0 5.6.1 10.4.0-beta.1 5.6.2 10.4.0-beta.2 5.6.3 10.4.0-rc.1 5.7.0 10.4.1 5.7.0-beta.1 10.4.2 5.7.0-rc.1 10.4.3 5.7.1 10.4.4 5.7.2 10.5.0 5.7.3 10.5.0-beta.1 5.8.0 10.5.0-beta.2 5.8.0-beta.1 10.5.0-rc.1 5.8.0-beta.2 10.5.0-rc.2 5.8.0-rc.1 10.5.0-rc.3 5.8.1 10.5.1 5.8.2 10.5.2 5.9.0 10.5.3 5.9.0-beta.1 10.6.0 5.9.0-rc.1 10.6.0-beta.1 5.9.0-rc.2 10.6.0-beta.2 5.9.1 10.6.0-rc.1 5.9.2 10.6.1 6.0.0 10.6.2 6.0.0-beta.1 10.7.0 6.0.0-rc.1 10.7.0-beta.1 6.0.1 10.7.0-beta.2 6.0.2 10.7.0-rc.1 6.1.0 3.0.0 6.1.0-beta.1 3.0.1 6.1.0-rc.1 3.0.2 6.1.0-rc.2 3.0.3 6.1.1 3.0.4 6.1.2 3.0.5 6.1.3 3.0.6 6.2.0 3.0.7 6.2.0-beta.1 3.0.8 6.2.0-rc.1 3.0.9 6.2.0-rc.2 3.1.0 6.2.1 3.1.1 6.2.2 3.1.2 6.2.3 3.2.0 6.3.0 3.2.1 6.3.0-beta.1 3.2.2 6.3.0-rc.1 3.2.3 6.3.0-rc.2 3.2.4 6.3.1 3.2.5 6.3.2 3.2.6 6.4.0 3.3.0 6.4.0-beta.1 3.3.1 6.4.0-rc.1 3.3.2 6.4.1 3.3.2-rc.1 6.4.2 3.3.3 6.5.0 3.3.4 6.5.0-beta.1 3.3.5 6.5.0-rc.1 3.3.6 6.5.0-rc.2 3.4.0 6.5.1 3.4.0-beta.1 6.5.2 3.4.0-rc.2 6.6.0 3.4.1 6.6.0-beta.1 3.4.2 6.6.0-rc.1 3.4.3 6.6.0-rc.2 3.4.4 6.6.1 3.4.5 6.6.2 3.4.6 6.7.0 3.4.7 6.7.0-beta.1 3.4.8 6.7.0-beta.2 3.5.0 6.7.0-rc.1 3.5.0-beta.1 6.7.1 3.5.0-rc.1 6.8.0 3.5.0-rc.2 6.8.0-beta.1 3.5.1 6.8.0-beta.2 3.5.10 6.8.0-rc.1 3.5.2 6.8.1 3.5.3 6.8.2 3.5.4 6.8.3 3.5.5 6.9.0 3.5.6 6.9.0-beta.1 3.5.7 6.9.0-beta.2 3.5.8 6.9.0-rc.1 3.5.9 6.9.1 3.6.0 6.9.2 3.6.0-beta.1 6.9.3 3.6.0-rc.1 6.9.4 3.6.0-rc.2 6.9.5 3.6.0-rc.3 7.0.0 3.6.1 7.0.0-beta.1 3.6.2 7.0.0-beta.2 3.6.3 7.0.0-beta.3 3.6.4 7.0.0-rc.1 3.6.5 7.0.0-rc.2 3.6.6 7.0.1 3.6.7 7.0.2 3.7.0 7.1.0 3.7.0-beta.1 7.1.0-beta.1 3.7.0-rc.1 7.1.0-beta.2 3.7.0-rc.2 7.1.0-rc.1 3.7.1 7.1.0-rc.2 3.7.2 7.1.1
woocommerce / assets / js / admin / wc-shipping-zone-methods.js
woocommerce / assets / js / admin Last commit date
api-keys.js 5 years ago api-keys.min.js 2 years ago backbone-modal.js 2 years ago backbone-modal.min.js 2 years ago marketplace-suggestions.js 4 years ago marketplace-suggestions.min.js 2 years ago meta-boxes-coupon.js 5 years ago meta-boxes-coupon.min.js 2 years ago meta-boxes-order.js 2 years ago meta-boxes-order.min.js 2 years ago meta-boxes-product-variation.js 2 years ago meta-boxes-product-variation.min.js 2 years ago meta-boxes-product.js 2 years ago meta-boxes-product.min.js 2 years ago meta-boxes.js 2 years ago meta-boxes.min.js 2 years ago network-orders.js 8 years ago network-orders.min.js 2 years ago order-attribution-admin.js 2 years ago order-attribution-admin.min.js 2 years ago product-editor.js 3 years ago product-editor.min.js 2 years ago product-ordering.js 3 years ago product-ordering.min.js 2 years ago quick-edit.js 4 years ago quick-edit.min.js 2 years ago reports.js 5 years ago reports.min.js 2 years ago settings-views-html-settings-tax.js 3 years ago settings-views-html-settings-tax.min.js 2 years ago settings.js 4 years ago settings.min.js 2 years ago system-status.js 3 years ago system-status.min.js 2 years ago term-ordering.js 4 years ago term-ordering.min.js 2 years ago users.js 5 years ago users.min.js 2 years ago wc-clipboard.js 5 years ago wc-clipboard.min.js 5 years ago wc-enhanced-select.js 2 years ago wc-enhanced-select.min.js 2 years ago wc-orders.js 3 years ago wc-orders.min.js 2 years ago wc-product-export.js 5 years ago wc-product-export.min.js 2 years ago wc-product-import.js 3 years ago wc-product-import.min.js 2 years ago wc-setup.js 5 years ago wc-setup.min.js 2 years ago wc-shipping-classes.js 2 years ago wc-shipping-classes.min.js 2 years ago wc-shipping-zone-methods.js 2 years ago wc-shipping-zone-methods.min.js 2 years ago wc-shipping-zones.js 2 years ago wc-shipping-zones.min.js 2 years ago wc-status-widget.js 3 years ago wc-status-widget.min.js 3 years ago woocommerce_admin.js 2 years ago woocommerce_admin.min.js 2 years ago
wc-shipping-zone-methods.js
734 lines
1 /* global shippingZoneMethodsLocalizeScript, ajaxurl */
2 ( function( $, data, wp, ajaxurl ) {
3 $( function() {
4 var $table = $( '.wc-shipping-zone-methods' ),
5 $tbody = $( '.wc-shipping-zone-method-rows' ),
6 $save_button = $( '.wc-shipping-zone-method-save' ),
7 $row_template = wp.template( 'wc-shipping-zone-method-row' ),
8 $blank_template = wp.template( 'wc-shipping-zone-method-row-blank' ),
9
10 // Backbone model
11 ShippingMethod = Backbone.Model.extend({
12 changes: {},
13 logChanges: function( changedRows ) {
14 var changes = this.changes || {};
15
16 _.each( changedRows.methods, function( row, id ) {
17 changes.methods = changes.methods || { methods : {} };
18 changes.methods[ id ] = _.extend( changes.methods[ id ] || { instance_id : id }, row );
19 } );
20
21 if ( typeof changedRows.zone_name !== 'undefined' ) {
22 changes.zone_name = changedRows.zone_name;
23 }
24
25 if ( typeof changedRows.zone_locations !== 'undefined' ) {
26 changes.zone_locations = changedRows.zone_locations;
27 }
28
29 if ( typeof changedRows.zone_postcodes !== 'undefined' ) {
30 changes.zone_postcodes = changedRows.zone_postcodes;
31 }
32
33 this.changes = changes;
34 this.trigger( 'change:methods' );
35 },
36 save: function() {
37 // Special handling for an empty 'zone_locations' array, which jQuery filters out during $.post().
38 var changes = _.clone( this.changes );
39 if ( _.has( changes, 'zone_locations' ) && _.isEmpty( changes.zone_locations ) ) {
40 changes.zone_locations = [''];
41 }
42
43 $.post(
44 ajaxurl + ( ajaxurl.indexOf( '?' ) > 0 ? '&' : '?' ) + 'action=woocommerce_shipping_zone_methods_save_changes',
45 {
46 wc_shipping_zones_nonce : data.wc_shipping_zones_nonce,
47 changes : changes,
48 zone_id : data.zone_id
49 },
50 this.onSaveResponse,
51 'json'
52 );
53 },
54 onSaveResponse: function( response, textStatus ) {
55 if ( 'success' === textStatus ) {
56 if ( response.success ) {
57 if ( response.data.zone_id !== data.zone_id ) {
58 data.zone_id = response.data.zone_id;
59 if ( window.history.pushState ) {
60 window.history.pushState(
61 {},
62 '',
63 'admin.php?page=wc-settings&tab=shipping&zone_id=' + response.data.zone_id
64 );
65 }
66 }
67 shippingMethod.set( 'methods', response.data.methods );
68 shippingMethod.trigger( 'change:methods' );
69 shippingMethod.changes = {};
70 shippingMethod.trigger( 'saved:methods' );
71
72 // Overrides the onbeforeunload callback added by settings.js.
73 window.onbeforeunload = null;
74 } else {
75 window.alert( data.strings.save_failed );
76 }
77 }
78 }
79 } ),
80
81 // Backbone view
82 ShippingMethodView = Backbone.View.extend({
83 rowTemplate: $row_template,
84 initialize: function() {
85 this.listenTo( this.model, 'change:methods', this.setUnloadConfirmation );
86 this.listenTo( this.model, 'saved:methods', this.clearUnloadConfirmation );
87 this.listenTo( this.model, 'saved:methods', this.render );
88 this.listenTo( this.model, 'rerender', this.render );
89 $tbody.on( 'change', { view: this }, this.updateModelOnChange );
90 $tbody.on( 'sortupdate', { view: this }, this.updateModelOnSort );
91 $( window ).on( 'beforeunload', { view: this }, this.unloadConfirmation );
92 $save_button.on( 'click', { view: this }, this.onSubmit );
93
94 $( document.body ).on(
95 'input change',
96 '#zone_name, #zone_locations, #zone_postcodes',
97 { view: this },
98 this.onUpdateZone
99 );
100 $( document.body ).on( 'click', '.wc-shipping-zone-method-settings', { view: this }, this.onConfigureShippingMethod );
101 $( document.body ).on( 'click', '.wc-shipping-zone-add-method', { view: this }, this.onAddShippingMethod );
102 $( document.body ).on( 'wc_backbone_modal_response', this.onConfigureShippingMethodSubmitted );
103 $( document.body ).on( 'wc_region_picker_update', this.onUpdateZoneRegionPicker );
104 $( document.body ).on( 'wc_backbone_modal_next_response', this.onAddShippingMethodSubmitted );
105 $( document.body ).on( 'wc_backbone_modal_before_remove', this.onCloseConfigureShippingMethod );
106 $( document.body ).on( 'wc_backbone_modal_back_response', this.onConfigureShippingMethodBack );
107 $( document.body ).on( 'change', '.wc-shipping-zone-method-selector select', this.onChangeShippingMethodSelector );
108 $( document.body ).on( 'click', '.wc-shipping-zone-postcodes-toggle', this.onTogglePostcodes );
109 $( document.body ).on( 'wc_backbone_modal_validation', { view: this }, this.validateFormArguments );
110 $( document.body ).on( 'wc_backbone_modal_loaded', { view: this }, this.onModalLoaded );
111 },
112 onUpdateZoneRegionPicker: function( event ) {
113 var value = event.detail,
114 attribute = 'zone_locations',
115 changes = {};
116
117 changes[ attribute ] = value;
118 shippingMethodView.model.set( attribute, value );
119 shippingMethodView.model.logChanges( changes );
120 },
121 onUpdateZone: function( event ) {
122 var view = event.data.view,
123 model = view.model,
124 value = $( this ).val(),
125 $target = $( event.target ),
126 attribute = $target.data( 'attribute' ),
127 changes = {};
128
129 event.preventDefault();
130
131 changes[ attribute ] = value;
132 model.set( attribute, value );
133 model.logChanges( changes );
134 view.render();
135 },
136 block: function() {
137 $( this.el ).block({
138 message: null,
139 overlayCSS: {
140 background: '#fff',
141 opacity: 0.6
142 }
143 });
144 },
145 unblock: function() {
146 $( this.el ).unblock();
147 },
148 render: function() {
149 var methods = _.indexBy( this.model.get( 'methods' ), 'instance_id' ),
150 zone_name = this.model.get( 'zone_name' ),
151 view = this;
152
153 // Set name.
154 $('.wc-shipping-zone-name').text( zone_name ? zone_name : data.strings.default_zone_name );
155
156 // Blank out the contents.
157 this.$el.empty();
158 this.unblock();
159
160 if ( _.size( methods ) ) {
161 // Sort methods
162 methods = _.sortBy( methods, function( method ) {
163 return parseInt( method.method_order, 10 );
164 } );
165
166 // Populate $tbody with the current methods
167 $.each( methods, function( id, rowData ) {
168 if ( 'yes' === rowData.enabled ) {
169 rowData.enabled_icon = '<span class="woocommerce-input-toggle woocommerce-input-toggle--enabled">' +
170 data.strings.yes +
171 '</span>';
172 } else {
173 rowData.enabled_icon = '<span class="woocommerce-input-toggle woocommerce-input-toggle--disabled">' +
174 data.strings.no +
175 '</span>';
176 }
177
178 view.$el.append( view.rowTemplate( rowData ) );
179
180 var $tr = view.$el.find( 'tr[data-id="' + rowData.instance_id + '"]');
181
182 if ( ! rowData.has_settings ) {
183 $tr
184 .find( '.wc-shipping-zone-method-title > a' )
185 .replaceWith('<span>' + $tr.find( '.wc-shipping-zone-method-title > a' ).text() + '</span>' );
186 var $del = $tr.find( '.wc-shipping-zone-method-delete' );
187 $tr.find( '.wc-shipping-zone-method-title .row-actions' ).empty().html($del);
188 }
189 } );
190
191 // Make the rows function
192 this.$el.find( '.wc-shipping-zone-method-delete' ).on( 'click', { view: this }, this.onDeleteRow );
193 this.$el.find( '.wc-shipping-zone-method-enabled a').on( 'click', { view: this }, this.onToggleEnabled );
194 } else {
195 view.$el.append( $blank_template );
196 }
197
198 this.initTooltips();
199 },
200 initTooltips: function() {
201 $( '#tiptip_holder' ).removeAttr( 'style' );
202 $( '#tiptip_arrow' ).removeAttr( 'style' );
203 $( '.tips' ).tipTip({ 'attribute': 'data-tip', 'fadeIn': 50, 'fadeOut': 50, 'delay': 50 });
204 },
205 onSubmit: function( event ) {
206 event.data.view.block();
207 event.data.view.model.save();
208 event.preventDefault();
209 },
210 onDeleteRow: function( event ) {
211 var view = event.data.view,
212 model = view.model,
213 methods = _.indexBy( model.get( 'methods' ), 'instance_id' ),
214 changes = {},
215 instance_id = $( this ).closest( 'tr' ).data( 'id' );
216
217 event.preventDefault();
218
219 if ( window.confirm( data.strings.delete_shipping_method_confirmation ) ) {
220 shippingMethodView.block();
221
222 // Add method to zone via ajax call
223 $.post( {
224 url: ajaxurl + ( ajaxurl.indexOf( '?' ) > 0 ? '&' : '?') + 'action=woocommerce_shipping_zone_remove_method',
225 data: {
226 wc_shipping_zones_nonce: data.wc_shipping_zones_nonce,
227 instance_id: instance_id,
228 zone_id: data.zone_id,
229 },
230 success: function( { data } ) {
231 delete methods[instance_id];
232 changes.methods = changes.methods || data.methods;
233 model.set('methods', methods);
234 model.logChanges( changes );
235 view.clearUnloadConfirmation();
236 view.render();
237 shippingMethodView.unblock();
238 },
239 error: function( jqXHR, textStatus, errorThrown ) {
240 window.alert( data.strings.remove_method_failed );
241 shippingMethodView.unblock();
242 },
243 dataType: 'json'
244 });
245 }
246 },
247 onToggleEnabled: function( event ) {
248 var view = event.data.view,
249 $target = $( event.target ),
250 model = view.model,
251 methods = _.indexBy( model.get( 'methods' ), 'instance_id' ),
252 instance_id = $target.closest( 'tr' ).data( 'id' ),
253 enabled = $target.closest( 'tr' ).data( 'enabled' ) === 'yes' ? 'no' : 'yes',
254 changes = {};
255
256 event.preventDefault();
257 methods[ instance_id ].enabled = enabled;
258 changes.methods = changes.methods || { methods : {} };
259 changes.methods[ instance_id ] = _.extend( changes.methods[ instance_id ] || {}, { enabled : enabled } );
260 model.set( 'methods', methods );
261 model.logChanges( changes );
262 view.render();
263 },
264 setUnloadConfirmation: function() {
265 this.needsUnloadConfirm = true;
266 $save_button.prop( 'disabled', false );
267 },
268 clearUnloadConfirmation: function() {
269 this.needsUnloadConfirm = false;
270 $save_button.attr( 'disabled', 'disabled' );
271 },
272 unloadConfirmation: function( event ) {
273 if ( event.data.view.needsUnloadConfirm ) {
274 event.returnValue = data.strings.unload_confirmation_msg;
275 window.event.returnValue = data.strings.unload_confirmation_msg;
276 return data.strings.unload_confirmation_msg;
277 }
278 },
279 updateModelOnChange: function( event ) {
280 var model = event.data.view.model,
281 $target = $( event.target ),
282 instance_id = $target.closest( 'tr' ).data( 'id' ),
283 attribute = $target.data( 'attribute' ),
284 value = $target.val(),
285 methods = _.indexBy( model.get( 'methods' ), 'instance_id' ),
286 changes = {};
287
288 if ( methods[ instance_id ][ attribute ] !== value ) {
289 changes.methods[ instance_id ] = {};
290 changes.methods[ instance_id ][ attribute ] = value;
291 methods[ instance_id ][ attribute ] = value;
292 }
293
294 model.logChanges( changes );
295 },
296 updateModelOnSort: function( event ) {
297 var view = event.data.view,
298 model = view.model,
299 methods = _.indexBy( model.get( 'methods' ), 'instance_id' ),
300 changes = {};
301
302 _.each( methods, function( method ) {
303 var old_position = parseInt( method.method_order, 10 );
304 var new_position = parseInt( $table.find( 'tr[data-id="' + method.instance_id + '"]').index() + 1, 10 );
305
306 if ( old_position !== new_position ) {
307 methods[ method.instance_id ].method_order = new_position;
308 changes.methods = changes.methods || { methods : {} };
309 changes.methods[ method.instance_id ] = _.extend(
310 changes.methods[ method.instance_id ] || {}, { method_order : new_position }
311 );
312 }
313 } );
314
315 if ( _.size( changes ) ) {
316 model.logChanges( changes );
317 }
318 },
319 onConfigureShippingMethod: function( event ) {
320 var instance_id = $( this ).closest( 'tr' ).data( 'id' ),
321 model = event.data.view.model,
322 methods = _.indexBy( model.get( 'methods' ), 'instance_id' ),
323 method = methods[ instance_id ];
324
325 // Only load modal if supported.
326 if ( ! method.settings_html ) {
327 return true;
328 }
329
330 event.preventDefault();
331
332 method.settings_html = shippingMethodView.reformatSettingsHTML( method.settings_html );
333
334 $( this ).WCBackboneModal({
335 template : 'wc-modal-shipping-method-settings',
336 variable : {
337 instance_id : instance_id,
338 method : method,
339 status : 'existing'
340 },
341 data : {
342 instance_id : instance_id,
343 method : method,
344 status : 'existing'
345 }
346 });
347
348 shippingMethodView.highlightOnFocus( '.wc-shipping-modal-price' );
349
350 $( document.body ).trigger( 'init_tooltips' );
351 },
352 onConfigureShippingMethodSubmitted: function( event, target, posted_data ) {
353 if ( 'wc-modal-shipping-method-settings' === target ) {
354 shippingMethodView.block();
355
356 // Save method settings via ajax call
357 $.post(
358 ajaxurl + ( ajaxurl.indexOf( '?' ) > 0 ? '&' : '?' ) + 'action=woocommerce_shipping_zone_methods_save_settings',
359 {
360 wc_shipping_zones_nonce : data.wc_shipping_zones_nonce,
361 instance_id : posted_data.instance_id,
362 data : posted_data
363 },
364 function( response, textStatus ) {
365 if ( 'success' === textStatus && response.success ) {
366 $( 'table.wc-shipping-zone-methods' ).parent().find( '#woocommerce_errors' ).remove();
367
368 // If there were errors, prepend the form.
369 if ( response.data.errors.length > 0 ) {
370 shippingMethodView.showErrors( response.data.errors );
371 }
372
373 // Method was saved. Re-render.
374 if ( _.size( shippingMethodView.model.changes ) ) {
375 shippingMethodView.model.save();
376 } else {
377 shippingMethodView.model.onSaveResponse( response, textStatus );
378 }
379 } else {
380 window.alert( data.strings.save_failed );
381 shippingMethodView.unblock();
382 }
383 },
384 'json'
385 );
386 }
387 },
388 onConfigureShippingMethodBack: function( event, target ) {
389 if ( 'wc-modal-shipping-method-settings' === target ) {
390 shippingMethodView.onAddShippingMethod( event );
391 }
392 },
393 showErrors: function( errors ) {
394 var error_html = '<div id="woocommerce_errors" class="error notice is-dismissible">';
395
396 $( errors ).each( function( index, value ) {
397 error_html = error_html + '<p>' + value + '</p>';
398 } );
399 error_html = error_html + '</div>';
400
401 $( 'table.wc-shipping-zone-methods' ).before( error_html );
402 },
403 highlightOnFocus: function( query ) {
404 const inputs = $( query );
405 inputs.focus( function() {
406 $( this ).select();
407 } );
408 },
409 onAddShippingMethod: function( event ) {
410 event.preventDefault();
411
412 $( this ).WCBackboneModal({
413 template : 'wc-modal-add-shipping-method',
414 variable : {
415 zone_id : data.zone_id
416 }
417 });
418
419 $( '.wc-shipping-zone-method-selector select' ).trigger( 'change' );
420
421 $('.wc-shipping-zone-method-input input').change( function() {
422 const selected = $('.wc-shipping-zone-method-input input:checked');
423 const id = selected.attr( 'id' );
424 const description = $( `#${ id }-description` );
425 const descriptions = $( '.wc-shipping-zone-method-input-help-text' );
426 descriptions.css( 'display', 'none' );
427 description.css( 'display', 'block' );
428 });
429 },
430 /**
431 * The settings HTML is controlled and built by the settings api, so in order to refactor the
432 * markup, it needs to be manipulated here.
433 */
434 reformatSettingsHTML: function( html ) {
435 const formattingFunctions = [
436 this.replaceHTMLTables,
437 this.moveAdvancedCostsHelpTip,
438 this.moveHTMLHelpTips,
439 this.addCurrencySymbol
440 ];
441
442 return formattingFunctions.reduce( ( formattedHTML, fn ) => {
443 return fn( formattedHTML );
444 }, html );
445 },
446 moveAdvancedCostsHelpTip: function( html ) {
447 const htmlContent = $( html );
448 const advancedCostsHelpTip = htmlContent.find( '#wc-shipping-advanced-costs-help-text' );
449 advancedCostsHelpTip.addClass( 'wc-shipping-zone-method-fields-help-text' );
450
451 const input = htmlContent.find( '#woocommerce_flat_rate_cost' );
452 const fieldset = input.closest( 'fieldset' );
453 advancedCostsHelpTip.appendTo( fieldset );
454
455 return htmlContent.prop( 'outerHTML' );
456 },
457 addCurrencySymbol: function( html ) {
458 if ( ! window.wc.ShippingCurrencyContext || ! window.wc.ShippingCurrencyNumberFormat ) {
459 return html;
460 }
461 const htmlContent = $( html );
462 const priceInputs = htmlContent.find( '.wc-shipping-modal-price' );
463 const config = window.wc.ShippingCurrencyContext.getCurrencyConfig();
464 const { symbol, symbolPosition } = config;
465
466 priceInputs.addClass( `wc-shipping-currency-size-${ symbol.length }` );
467 priceInputs.addClass( `wc-shipping-currency-position-${ symbolPosition }` );
468 priceInputs.before( `<div class="wc-shipping-zone-method-currency wc-shipping-currency-position-${ symbolPosition }">${ symbol }</div>` );
469
470 priceInputs.each( ( i ) => {
471 const priceInput = $( priceInputs[ i ] );
472 const value = priceInput.attr( 'value' );
473 const formattedValue = window.wc.ShippingCurrencyNumberFormat( config, value );
474 priceInput.attr( 'value', formattedValue );
475 } );
476
477 return htmlContent.prop( 'outerHTML' );
478 },
479 moveHTMLHelpTips: function( html ) {
480 // These help tips aren't moved.
481 const helpTipsToRetain = [ 'woocommerce_flat_rate_cost', 'woocommerce_flat_rate_no_class_cost', 'woocommerce_flat_rate_class_cost_' ];
482
483 const htmlContent = $( html );
484 const labels = htmlContent.find( 'label' );
485 labels.each( ( i ) => {
486 const label = $( labels[ i ] );
487 const helpTip = label.find( '.woocommerce-help-tip' );
488
489 if ( helpTip.length === 0 ) {
490 return;
491 }
492
493 const id = label.attr( 'for' );
494
495 if ( helpTipsToRetain.some( ( tip ) => id.includes( tip ) ) ) {
496 const helpTip = htmlContent.find( `label[for=${ id }] span.woocommerce-help-tip` );
497 helpTip.addClass( 'wc-shipping-visible-help-text' );
498 return;
499 }
500
501 // woocommerce_free_shipping_ignore_discounts gets a helpTip appended to its label. Otherwise, add the text as the last element in the fieldset.
502 if ( id === 'woocommerce_free_shipping_ignore_discounts' ) {
503 const input = htmlContent.find( `#${ id }` );
504 const fieldset = input.closest( 'fieldset' );
505 const inputLabel = fieldset.find( 'label' );
506 inputLabel.append( helpTip );
507 } else {
508 const text = helpTip.data( 'tip' );
509 const input = htmlContent.find( `#${ id }` );
510 const fieldset = input.closest( 'fieldset' );
511
512 if ( fieldset.length && fieldset.find( '.wc-shipping-zone-method-fields-help-text' ).length === 0 ) {
513 fieldset.append( `<div class="wc-shipping-zone-method-fields-help-text">${ text }</div>` );
514 }
515 }
516
517 // Coupon discounts doesn't get a title on Free Shipping.
518 if ( label.text().trim() === 'Coupons discounts' ) {
519 label.text( '' );
520 }
521
522 } );
523
524 return htmlContent.prop( 'outerHTML' );
525 },
526 replaceHTMLTables: function ( html ) {
527 // Wrap the html content in a div
528 const htmlContent = $( '<div>' + html + '</div>' );
529
530 // `<table class="form-table" />` elements added by the Settings API need to be removed.
531 // Modern browsers won't interpret other table elements like `td` not in a `table`, so
532 // Removing the `table` is sufficient.
533 const innerTables = htmlContent.find( 'table.form-table' );
534 innerTables.each( ( i ) => {
535 const table = $( innerTables[ i ] );
536 const div = $( '<div class="wc-shipping-zone-method-fields" />' );
537 div.html( table.html() );
538 table.replaceWith( div );
539 } );
540
541 return htmlContent.prop('outerHTML');
542 },
543 onAddShippingMethodSubmitted: function( event, target, posted_data, closeModal ) {
544 if ( 'wc-modal-add-shipping-method' === target ) {
545 shippingMethodView.block();
546
547 $('#btn-next').addClass( 'is-busy' );
548
549 // Add method to zone via ajax call
550 $.post( ajaxurl + ( ajaxurl.indexOf( '?' ) > 0 ? '&' : '?' ) + 'action=woocommerce_shipping_zone_add_method', {
551 wc_shipping_zones_nonce : data.wc_shipping_zones_nonce,
552 method_id : posted_data.add_method_id,
553 zone_id : data.zone_id
554 }, function( response, textStatus ) {
555 if ( 'success' === textStatus && response.success ) {
556 if ( response.data.zone_id !== data.zone_id ) {
557 data.zone_id = response.data.zone_id;
558 if ( window.history.pushState ) {
559 window.history.pushState(
560 {},
561 '',
562 'admin.php?page=wc-settings&tab=shipping&zone_id=' + response.data.zone_id
563 );
564 }
565 }
566
567 // Avoid triggering a rerender here because we don't want to show the method in the table in case merchant doesn't finish flow.
568
569 shippingMethodView.model.set( 'methods', response.data.methods );
570
571 // Close original modal
572 closeModal();
573 }
574 var instance_id = response.data.instance_id,
575 method = response.data.methods[ instance_id ];
576
577 shippingMethodView.unblock();
578
579 if ( method.settings_html ) {
580 method.settings_html = shippingMethodView.reformatSettingsHTML( method.settings_html );
581
582 // Pop up next modal
583 $( this ).WCBackboneModal({
584 template : 'wc-modal-shipping-method-settings',
585 variable : {
586 instance_id : instance_id,
587 method : method,
588 status : 'new'
589 },
590 data : {
591 instance_id : instance_id,
592 method : method,
593 status : 'new'
594 }
595 });
596
597 shippingMethodView.highlightOnFocus( '.wc-shipping-modal-price' );
598 } else {
599 shippingMethodView.model.trigger( 'change:methods' );
600 shippingMethodView.model.trigger( 'saved:methods' );
601 }
602
603 $( document.body ).trigger( 'init_tooltips' );
604 }, 'json' );
605 }
606 },
607 // Free Shipping has hidden field elements depending on data values.
608 possiblyHideFreeShippingRequirements: function( data ) {
609 if ( Object.keys( data ).includes( 'woocommerce_free_shipping_requires' ) ) {
610 const shouldHideRequirements = data.woocommerce_free_shipping_requires === null ||
611 data.woocommerce_free_shipping_requires === '' ||
612 data.woocommerce_free_shipping_requires === 'coupon';
613
614 const select = $( '#woocommerce_free_shipping_requires' );
615 const fieldset = select.closest( 'fieldset' );
616 const allOtherLabelElementsAfter = fieldset.nextAll( 'label' );
617 const allOtherFieldsetElementsAfter = fieldset.nextAll( 'fieldset' );
618
619 allOtherLabelElementsAfter.each( ( i ) => {
620 $( allOtherLabelElementsAfter[ i ] ).css( 'display', shouldHideRequirements ? 'none' : 'block' );
621 } );
622
623 allOtherFieldsetElementsAfter.each( ( i ) => {
624 $( allOtherFieldsetElementsAfter[ i ] ).css( 'display', shouldHideRequirements ? 'none' : 'block' );
625 } );
626 }
627 },
628 onModalLoaded: function( event, target ) {
629 if ( target === 'wc-modal-shipping-method-settings' ) {
630 const select = $( '#woocommerce_free_shipping_requires' );
631 if ( select.length > 0 ) {
632 event.data.view.possiblyHideFreeShippingRequirements( { woocommerce_free_shipping_requires: select.val() } );
633 }
634
635 event.data.view.possiblyAddShippingClassLink( event );
636 }
637 },
638 possiblyAddShippingClassLink: function( event ) {
639 const article = $( 'article.wc-modal-shipping-method-settings' );
640 const shippingClassesCount = article.data( 'shipping-classes-count' );
641 const status = article.data( 'status' );
642 const instance_id = article.data( 'id' );
643 const model = event.data.view.model;
644 const methods = _.indexBy( model.get( 'methods' ), 'instance_id' );
645 const method = methods[ instance_id ];
646
647 if ( method.id === 'flat_rate' && shippingClassesCount === 0 ) {
648 const link = article.find( '.wc-shipping-method-add-class-costs' );
649 link.css( 'display', 'block' );
650 }
651 },
652 validateFormArguments: function( event, target, data ) {
653 if ( target === 'wc-modal-add-shipping-method' ) {
654 if ( data.add_method_id ) {
655 const nextButton = document.getElementById( 'btn-next' );
656 nextButton.disabled = false;
657 nextButton.classList.remove( 'disabled' );
658 }
659 } else if ( target === 'wc-modal-shipping-method-settings' ) {
660 event.data.view.possiblyHideFreeShippingRequirements( data );
661 }
662 },
663 onCloseConfigureShippingMethod: function( event, target, post_data, addButtonCalled ) {
664 if ( target === 'wc-modal-shipping-method-settings' ) {
665 var btnData = $( '#btn-ok' ).data();
666
667 if ( ! addButtonCalled && btnData && btnData.status === 'new' ) {
668 shippingMethodView.block();
669
670 var view = shippingMethodView,
671 model = view.model,
672 methods = _.indexBy( model.get( 'methods' ), 'instance_id' ),
673 changes = {},
674 instance_id = post_data.instance_id;
675
676 // Remove method to zone via ajax call
677 $.post( {
678 url: ajaxurl + ( ajaxurl.indexOf( '?' ) > 0 ? '&' : '?') + 'action=woocommerce_shipping_zone_remove_method',
679 data: {
680 wc_shipping_zones_nonce: data.wc_shipping_zones_nonce,
681 instance_id: instance_id,
682 zone_id: data.zone_id,
683 },
684 success: function( { data } ) {
685 delete methods[instance_id];
686 changes.methods = changes.methods || data.methods;
687 model.set('methods', methods);
688 model.logChanges( changes );
689 view.clearUnloadConfirmation();
690 view.render();
691 shippingMethodView.unblock();
692 },
693 error: function( jqXHR, textStatus, errorThrown ) {
694 window.alert( data.strings.remove_method_failed );
695 shippingMethodView.unblock();
696 },
697 dataType: 'json'
698 });
699 }
700 }
701 },
702 onChangeShippingMethodSelector: function() {
703 var description = $( this ).find( 'option:selected' ).data( 'description' );
704 $( this ).parent().find( '.wc-shipping-zone-method-description' ).remove();
705 $( this ).after( '<div class="wc-shipping-zone-method-description">' + description + '</div>' );
706 },
707 onTogglePostcodes: function( event ) {
708 event.preventDefault();
709 var $tr = $( this ).closest( 'tr');
710 $tr.find( '.wc-shipping-zone-postcodes' ).show();
711 $tr.find( '.wc-shipping-zone-postcodes-toggle' ).hide();
712 }
713 } ),
714 shippingMethod = new ShippingMethod({
715 methods: data.methods,
716 zone_name: data.zone_name
717 } ),
718 shippingMethodView = new ShippingMethodView({
719 model: shippingMethod,
720 el: $tbody
721 } );
722
723 shippingMethodView.render();
724
725 $tbody.sortable({
726 items: 'tr',
727 cursor: 'move',
728 axis: 'y',
729 handle: 'td.wc-shipping-zone-method-sort',
730 scrollSensitivity: 40
731 });
732 });
733 })( jQuery, shippingZoneMethodsLocalizeScript, wp, ajaxurl );
734