diff --git a/assets/js/admin/wc-shipping-zones.js b/assets/js/admin/wc-shipping-zones.js index cb8c9c40520..a5cb90fcfe8 100644 --- a/assets/js/admin/wc-shipping-zones.js +++ b/assets/js/admin/wc-shipping-zones.js @@ -29,21 +29,29 @@ this.trigger( 'change:zones' ); }, discardChanges: function( id ) { - var changes = this.changes || {}, - position = null; + var changes = this.changes || {}, + set_position = null, + zones = _.indexBy( this.get( 'zones' ), 'zone_id' ); + // Find current set position if it has moved since last save if ( changes[ id ] && changes[ id ].zone_order !== undefined ) { - position = changes[ id ].zone_order; + set_position = changes[ id ].zone_order; } + // Delete all changes delete changes[ id ]; - if ( position !== null ) { - changes[ id ] = _.extend( changes[ id ] || {}, { zone_id : id, zone_order : position } ); + // If the position was set, and this zone does exist in DB, set the position again so the changes are not lost. + if ( set_position !== null && zones[ id ] && zones[ id ].zone_order !== set_position ) { + changes[ id ] = _.extend( changes[ id ] || {}, { zone_id : id, zone_order : set_position } ); } this.changes = changes; - this.trigger( 'change:zones' ); + + // No changes? Disable save button. + if ( 0 === _.size( this.changes ) ) { + shippingZoneView.clearUnloadConfirmation(); + } }, save: function() { if ( _.size( this.changes ) ) { @@ -120,7 +128,7 @@ view.$el.append( $blank_template ); } - view.initRows( zones ); + view.initRows(); }, renderRow: function( rowData ) { var view = this; @@ -131,11 +139,6 @@ var view = this; var $tr = view.$el.find( 'tr[data-id="' + rowData.zone_id + '"]'); - // Editing? - if ( rowData.editing ) { - $tr.addClass( 'editing' ); - } - // Select values in region select _.each( rowData.zone_locations, function( location ) { if ( 'string' === jQuery.type( location ) ) { @@ -173,20 +176,24 @@ // List shipping methods view.renderShippingMethods( rowData.zone_id, rowData.shipping_methods ); - }, - initRows: function( zones ) { - // Make the rows function - $table.find( '.view' ).show(); - $table.find( '.edit' ).hide(); - $table.find( '.wc-shipping-zone-save-changes-notice' ).hide(); - $table.find( '.wc-shipping-zone-edit' ).on( 'click', { view: this }, this.onEditRow ); - $table.find( '.wc-shipping-zone-cancel-edit' ).on( 'click', { view: this }, this.onCancelEditRow ); - $table.find( '.wc-shipping-zone-delete' ).on( 'click', { view: this }, this.onDeleteRow ); - $table.find( '.wc-shipping-zone-postcodes-toggle' ).on( 'click', { view: this }, this.onTogglePostcodes ); - $table.find( '.editing .wc-shipping-zone-edit' ).trigger( 'click' ); + // Make the row function + $tr.find( '.view' ).show(); + $tr.find( '.edit' ).hide(); + $tr.find( '.wc-shipping-zone-edit' ).on( 'click', { view: this }, this.onEditRow ); + $tr.find( '.wc-shipping-zone-cancel-edit' ).on( 'click', { view: this }, this.onCancelEditRow ); + $tr.find( '.wc-shipping-zone-delete' ).on( 'click', { view: this }, this.onDeleteRow ); + $tr.find( '.wc-shipping-zone-postcodes-toggle' ).on( 'click', { view: this }, this.onTogglePostcodes ); + + // Editing? + if ( true === rowData.editing ) { + $tr.addClass( 'editing' ); + $tr.find( '.wc-shipping-zone-edit' ).trigger( 'click' ); + } + }, + initRows: function() { // Stripe - if ( 0 === _.size( zones ) % 2 ) { + if ( 0 === ( $( 'tbody.wc-shipping-zone-rows tr' ).length % 2 ) ) { $table.find( 'tbody.wc-shipping-zone-rows' ).next( 'tbody' ).find( 'tr' ).addClass( 'odd' ); } else { $table.find( 'tbody.wc-shipping-zone-rows' ).next( 'tbody' ).find( 'tr' ).removeClass( 'odd' ); @@ -231,8 +238,9 @@ changes = {}, size = _.size( zones ), newRow = _.extend( {}, data.default_zone, { - zone_id: 'new-' + size + '-' + Date.now(), - editing: true + zone_id : 'new-' + size + '-' + Date.now(), + zone_name: data.strings.default_zone_name, + editing : true } ); newRow.zone_order = 1 + _.max( @@ -243,13 +251,11 @@ } ); - zones[ newRow.zone_id ] = newRow; changes[ newRow.zone_id ] = newRow; - model.set( 'zones', zones ); model.logChanges( changes ); view.renderRow( newRow ); - view.initRows( zones ); + view.initRows(); }, onTogglePostcodes: function( event ) { event.preventDefault(); @@ -280,35 +286,42 @@ event.preventDefault(); model.discardChanges( zone_id ); - // Remove row and re-render - row.after( view.rowTemplate( zones[ zone_id ] ) ); - row.remove(); + if ( zones[ zone_id ] ) { + zones[ zone_id ].editing = false; + row.after( view.rowTemplate( zones[ zone_id ] ) ); + view.initRow( zones[ zone_id ] ); + } - view.initRow( zones[ zone_id ] ); - view.initRows( zones ); + row.remove(); + view.initRows(); }, onDeleteRow: function( event ) { var view = event.data.view, model = view.model, zones = _.indexBy( model.get( 'zones' ), 'zone_id' ), changes = {}, + row = $( this ).closest('tr'), zone_id = $( this ).closest('tr').data('id'); event.preventDefault(); - delete zones[ zone_id ]; - changes[ zone_id ] = _.extend( changes[ zone_id ] || {}, { deleted : 'deleted' } ); - model.set( 'zones', zones ); - model.logChanges( changes ); - view.render(); + if ( zones[ zone_id ] ) { + delete zones[ zone_id ]; + changes[ zone_id ] = _.extend( changes[ zone_id ] || {}, { deleted : 'deleted' } ); + model.set( 'zones', zones ); + model.logChanges( changes ); + } + + row.remove(); + view.initRows(); }, setUnloadConfirmation: function() { this.needsUnloadConfirm = true; - $save_button.removeAttr( 'disabled' ); + $save_button.prop( 'disabled', false ); }, clearUnloadConfirmation: function() { this.needsUnloadConfirm = false; - $save_button.attr( 'disabled', 'disabled' ); + $save_button.prop( 'disabled', true ); }, unloadConfirmation: function( event ) { if ( event.data.view.needsUnloadConfirm ) { @@ -326,7 +339,7 @@ zones = _.indexBy( model.get( 'zones' ), 'zone_id' ), changes = {}; - if ( zones[ zone_id ][ attribute ] !== value ) { + if ( ! zones[ zone_id ] || zones[ zone_id ][ attribute ] !== value ) { changes[ zone_id ] = {}; changes[ zone_id ][ attribute ] = value; } @@ -334,17 +347,24 @@ model.logChanges( changes ); }, updateModelOnSort: function( event ) { - var view = event.data.view, - model = view.model, - zones = _.indexBy( model.get( 'zones' ), 'zone_id' ), - changes = {}; + var view = event.data.view, + model = view.model, + zones = _.indexBy( model.get( 'zones' ), 'zone_id' ), + rows = $( 'tbody.wc-shipping-zone-rows tr' ), + changes = {}; - _.each( zones, function( zone ) { - var old_position = parseInt( zone.zone_order, 10 ); - var new_position = parseInt( $table.find( 'tr[data-id="' + zone.zone_id + '"]').index(), 10 ); + // Update sorted row position + _.each( rows, function( row ) { + var zone_id = $( row ).data( 'id' ), + old_position = null, + new_position = parseInt( $( row ).index(), 10 ); + + if ( zones[ zone_id ] ) { + old_position = parseInt( zones[ zone_id ].zone_order, 10 ); + } if ( old_position !== new_position ) { - changes[ zone.zone_id ] = _.extend( changes[ zone.zone_id ] || {}, { zone_order : new_position } ); + changes[ zone_id ] = _.extend( changes[ zone_id ] || {}, { zone_order : new_position } ); } } ); diff --git a/assets/js/admin/wc-shipping-zones.min.js b/assets/js/admin/wc-shipping-zones.min.js index b47684cc54f..e89f2c3b156 100644 --- a/assets/js/admin/wc-shipping-zones.min.js +++ b/assets/js/admin/wc-shipping-zones.min.js @@ -1 +1 @@ -!function(a,b,c,d){a(function(){function e(){var a={formatMatches:function(a){return 1===a?wc_enhanced_select_params.i18n_matches_1:wc_enhanced_select_params.i18n_matches_n.replace("%qty%",a)},formatNoMatches:function(){return wc_enhanced_select_params.i18n_no_matches},formatAjaxError:function(){return wc_enhanced_select_params.i18n_ajax_error},formatInputTooShort:function(a,b){var c=b-a.length;return 1===c?wc_enhanced_select_params.i18n_input_too_short_1:wc_enhanced_select_params.i18n_input_too_short_n.replace("%qty%",c)},formatInputTooLong:function(a,b){var c=a.length-b;return 1===c?wc_enhanced_select_params.i18n_input_too_long_1:wc_enhanced_select_params.i18n_input_too_long_n.replace("%qty%",c)},formatSelectionTooBig:function(a){return 1===a?wc_enhanced_select_params.i18n_selection_too_long_1:wc_enhanced_select_params.i18n_selection_too_long_n.replace("%qty%",a)},formatLoadMore:function(){return wc_enhanced_select_params.i18n_load_more},formatSearching:function(){return wc_enhanced_select_params.i18n_searching}};return a}var f=a(".wc-shipping-zones"),g=a(".wc-shipping-zone-rows"),h=a(".wc-shipping-zone-save"),i=c.template("wc-shipping-zone-row"),j=c.template("wc-shipping-zone-row-blank"),k=a.extend({minimumResultsForSearch:10,allowClear:!!a(this).data("allow_clear"),placeholder:a(this).data("placeholder"),matcher:function(a,b,c){return b.toUpperCase().indexOf(a.toUpperCase())>=0||c.attr("alt").toUpperCase().indexOf(a.toUpperCase())>=0}},e()),l=Backbone.Model.extend({changes:{},logChanges:function(a){var b=this.changes||{};_.each(a,function(a,c){b[c]=_.extend(b[c]||{zone_id:c},a)}),this.changes=b,this.trigger("change:zones")},discardChanges:function(a){var b=this.changes||{},c=null;b[a]&&void 0!==b[a].zone_order&&(c=b[a].zone_order),delete b[a],null!==c&&(b[a]=_.extend(b[a]||{},{zone_id:a,zone_order:c})),this.changes=b,this.trigger("change:zones")},save:function(){_.size(this.changes)?a.post(d+(d.indexOf("?")>0?"&":"?")+"action=woocommerce_shipping_zones_save_changes",{wc_shipping_zones_nonce:b.wc_shipping_zones_nonce,changes:this.changes},this.onSaveResponse,"json"):n.trigger("saved:zones")},onSaveResponse:function(a,c){"success"===c&&(a.success?(n.set("zones",a.data.zones),n.trigger("change:zones"),n.changes={},n.trigger("saved:zones")):window.alert(b.strings.save_failed))}}),m=Backbone.View.extend({rowTemplate:i,initialize:function(){this.listenTo(this.model,"change:zones",this.setUnloadConfirmation),this.listenTo(this.model,"saved:zones",this.clearUnloadConfirmation),this.listenTo(this.model,"saved:zones",this.render),g.on("change",{view:this},this.updateModelOnChange),g.on("sortupdate",{view:this},this.updateModelOnSort),a(window).on("beforeunload",{view:this},this.unloadConfirmation),h.on("click",{view:this},this.onSubmit),a(document.body).on("click",".add_shipping_method:not(.disabled)",{view:this},this.onAddShippingMethod),a(document.body).on("click",".wc-shipping-zone-add",{view:this},this.onAddNewRow),a(document.body).on("click",".wc-shipping-zone-save-changes",{view:this},this.onSubmit),a(document.body).on("wc_backbone_modal_response",this.onAddShippingMethodSubmitted),a(document.body).on("change",".wc-shipping-zone-method-selector select",this.onChangeShippingMethodSelector)},block:function(){a(this.el).block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){a(this.el).unblock()},render:function(){var b=_.indexBy(this.model.get("zones"),"zone_id"),c=this;c.$el.empty(),c.unblock(),_.size(b)?(b=_.sortBy(b,function(a){return parseInt(a.zone_order,10)}),a.each(b,function(a,b){c.renderRow(b)})):c.$el.append(j),c.initRows(b)},renderRow:function(a){var b=this;b.$el.append(b.rowTemplate(a)),b.initRow(a)},initRow:function(a){var b=this,c=b.$el.find('tr[data-id="'+a.zone_id+'"]');a.editing&&c.addClass("editing"),_.each(a.zone_locations,function(a){if("string"===jQuery.type(a))c.find('option[value="'+a+'"]').prop("selected",!0);else if("postcode"===a.type){var b=c.find(".wc-shipping-zone-postcodes :input");b.val()?b.val(b.val()+"\n"+a.code):b.val(a.code),c.find(".wc-shipping-zone-postcodes").show(),c.find(".wc-shipping-zone-postcodes-toggle").hide()}else c.find('option[value="'+a.type+":"+a.code+'"]').prop("selected",!0)}),a.zone_postcodes&&_.each(a.zone_postcodes,function(a){var b=c.find(".wc-shipping-zone-postcodes :input");b.val()?b.val(b.val()+"\n"+a.code):b.val(a.code),c.find(".wc-shipping-zone-postcodes").show(),c.find(".wc-shipping-zone-postcodes-toggle").hide()}),b.renderShippingMethods(a.zone_id,a.shipping_methods)},initRows:function(b){f.find(".view").show(),f.find(".edit").hide(),f.find(".wc-shipping-zone-save-changes-notice").hide(),f.find(".wc-shipping-zone-edit").on("click",{view:this},this.onEditRow),f.find(".wc-shipping-zone-cancel-edit").on("click",{view:this},this.onCancelEditRow),f.find(".wc-shipping-zone-delete").on("click",{view:this},this.onDeleteRow),f.find(".wc-shipping-zone-postcodes-toggle").on("click",{view:this},this.onTogglePostcodes),f.find(".editing .wc-shipping-zone-edit").trigger("click"),0===_.size(b)%2?f.find("tbody.wc-shipping-zone-rows").next("tbody").find("tr").addClass("odd"):f.find("tbody.wc-shipping-zone-rows").next("tbody").find("tr").removeClass("odd"),a("#tiptip_holder").removeAttr("style"),a("#tiptip_arrow").removeAttr("style"),a(".tips").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:50})},renderShippingMethods:function(b,c){var d=a('.wc-shipping-zones tr[data-id="'+b+'"]'),e=d.find(".wc-shipping-zone-methods ul");e.find(".wc-shipping-zone-method").remove(),_.size(c)?_.each(c,function(a,b){var c="method_disabled";"yes"===a.enabled&&(c="method_enabled"),e.prepend('
'+b+"
"),a(this).closest("article").height(a(this).parent().height())}}),n=new l({zones:b.zones}),o=new m({model:n,el:g});o.render(),g.sortable({items:"tr",cursor:"move",axis:"y",handle:"td.wc-shipping-zone-sort",scrollSensitivity:40})})}(jQuery,shippingZonesLocalizeScript,wp,ajaxurl); \ No newline at end of file +!function(a,b,c,d){a(function(){function e(){var a={formatMatches:function(a){return 1===a?wc_enhanced_select_params.i18n_matches_1:wc_enhanced_select_params.i18n_matches_n.replace("%qty%",a)},formatNoMatches:function(){return wc_enhanced_select_params.i18n_no_matches},formatAjaxError:function(){return wc_enhanced_select_params.i18n_ajax_error},formatInputTooShort:function(a,b){var c=b-a.length;return 1===c?wc_enhanced_select_params.i18n_input_too_short_1:wc_enhanced_select_params.i18n_input_too_short_n.replace("%qty%",c)},formatInputTooLong:function(a,b){var c=a.length-b;return 1===c?wc_enhanced_select_params.i18n_input_too_long_1:wc_enhanced_select_params.i18n_input_too_long_n.replace("%qty%",c)},formatSelectionTooBig:function(a){return 1===a?wc_enhanced_select_params.i18n_selection_too_long_1:wc_enhanced_select_params.i18n_selection_too_long_n.replace("%qty%",a)},formatLoadMore:function(){return wc_enhanced_select_params.i18n_load_more},formatSearching:function(){return wc_enhanced_select_params.i18n_searching}};return a}var f=a(".wc-shipping-zones"),g=a(".wc-shipping-zone-rows"),h=a(".wc-shipping-zone-save"),i=c.template("wc-shipping-zone-row"),j=c.template("wc-shipping-zone-row-blank"),k=a.extend({minimumResultsForSearch:10,allowClear:!!a(this).data("allow_clear"),placeholder:a(this).data("placeholder"),matcher:function(a,b,c){return b.toUpperCase().indexOf(a.toUpperCase())>=0||c.attr("alt").toUpperCase().indexOf(a.toUpperCase())>=0}},e()),l=Backbone.Model.extend({changes:{},logChanges:function(a){var b=this.changes||{};_.each(a,function(a,c){b[c]=_.extend(b[c]||{zone_id:c},a)}),this.changes=b,this.trigger("change:zones")},discardChanges:function(a){var b=this.changes||{},c=null,d=_.indexBy(this.get("zones"),"zone_id");b[a]&&void 0!==b[a].zone_order&&(c=b[a].zone_order),delete b[a],null!==c&&d[a]&&d[a].zone_order!==c&&(b[a]=_.extend(b[a]||{},{zone_id:a,zone_order:c})),this.changes=b,0===_.size(this.changes)&&o.clearUnloadConfirmation()},save:function(){_.size(this.changes)?a.post(d+(d.indexOf("?")>0?"&":"?")+"action=woocommerce_shipping_zones_save_changes",{wc_shipping_zones_nonce:b.wc_shipping_zones_nonce,changes:this.changes},this.onSaveResponse,"json"):n.trigger("saved:zones")},onSaveResponse:function(a,c){"success"===c&&(a.success?(n.set("zones",a.data.zones),n.trigger("change:zones"),n.changes={},n.trigger("saved:zones")):window.alert(b.strings.save_failed))}}),m=Backbone.View.extend({rowTemplate:i,initialize:function(){this.listenTo(this.model,"change:zones",this.setUnloadConfirmation),this.listenTo(this.model,"saved:zones",this.clearUnloadConfirmation),this.listenTo(this.model,"saved:zones",this.render),g.on("change",{view:this},this.updateModelOnChange),g.on("sortupdate",{view:this},this.updateModelOnSort),a(window).on("beforeunload",{view:this},this.unloadConfirmation),h.on("click",{view:this},this.onSubmit),a(document.body).on("click",".add_shipping_method:not(.disabled)",{view:this},this.onAddShippingMethod),a(document.body).on("click",".wc-shipping-zone-add",{view:this},this.onAddNewRow),a(document.body).on("click",".wc-shipping-zone-save-changes",{view:this},this.onSubmit),a(document.body).on("wc_backbone_modal_response",this.onAddShippingMethodSubmitted),a(document.body).on("change",".wc-shipping-zone-method-selector select",this.onChangeShippingMethodSelector)},block:function(){a(this.el).block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){a(this.el).unblock()},render:function(){var b=_.indexBy(this.model.get("zones"),"zone_id"),c=this;c.$el.empty(),c.unblock(),_.size(b)?(b=_.sortBy(b,function(a){return parseInt(a.zone_order,10)}),a.each(b,function(a,b){c.renderRow(b)})):c.$el.append(j),c.initRows()},renderRow:function(a){var b=this;b.$el.append(b.rowTemplate(a)),b.initRow(a)},initRow:function(a){var b=this,c=b.$el.find('tr[data-id="'+a.zone_id+'"]');_.each(a.zone_locations,function(a){if("string"===jQuery.type(a))c.find('option[value="'+a+'"]').prop("selected",!0);else if("postcode"===a.type){var b=c.find(".wc-shipping-zone-postcodes :input");b.val()?b.val(b.val()+"\n"+a.code):b.val(a.code),c.find(".wc-shipping-zone-postcodes").show(),c.find(".wc-shipping-zone-postcodes-toggle").hide()}else c.find('option[value="'+a.type+":"+a.code+'"]').prop("selected",!0)}),a.zone_postcodes&&_.each(a.zone_postcodes,function(a){var b=c.find(".wc-shipping-zone-postcodes :input");b.val()?b.val(b.val()+"\n"+a.code):b.val(a.code),c.find(".wc-shipping-zone-postcodes").show(),c.find(".wc-shipping-zone-postcodes-toggle").hide()}),b.renderShippingMethods(a.zone_id,a.shipping_methods),c.find(".view").show(),c.find(".edit").hide(),c.find(".wc-shipping-zone-edit").on("click",{view:this},this.onEditRow),c.find(".wc-shipping-zone-cancel-edit").on("click",{view:this},this.onCancelEditRow),c.find(".wc-shipping-zone-delete").on("click",{view:this},this.onDeleteRow),c.find(".wc-shipping-zone-postcodes-toggle").on("click",{view:this},this.onTogglePostcodes),!0===a.editing&&(c.addClass("editing"),c.find(".wc-shipping-zone-edit").trigger("click"))},initRows:function(){0===a("tbody.wc-shipping-zone-rows tr").length%2?f.find("tbody.wc-shipping-zone-rows").next("tbody").find("tr").addClass("odd"):f.find("tbody.wc-shipping-zone-rows").next("tbody").find("tr").removeClass("odd"),a("#tiptip_holder").removeAttr("style"),a("#tiptip_arrow").removeAttr("style"),a(".tips").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:50})},renderShippingMethods:function(b,c){var d=a('.wc-shipping-zones tr[data-id="'+b+'"]'),e=d.find(".wc-shipping-zone-methods ul");e.find(".wc-shipping-zone-method").remove(),_.size(c)?_.each(c,function(a,b){var c="method_disabled";"yes"===a.enabled&&(c="method_enabled"),e.prepend(''+b+"
"),a(this).closest("article").height(a(this).parent().height())}}),n=new l({zones:b.zones}),o=new m({model:n,el:g});o.render(),g.sortable({items:"tr",cursor:"move",axis:"y",handle:"td.wc-shipping-zone-sort",scrollSensitivity:40})})}(jQuery,shippingZonesLocalizeScript,wp,ajaxurl); \ No newline at end of file diff --git a/includes/admin/settings/class-wc-settings-shipping.php b/includes/admin/settings/class-wc-settings-shipping.php index efdb07e3bb0..03625b391ca 100644 --- a/includes/admin/settings/class-wc-settings-shipping.php +++ b/includes/admin/settings/class-wc-settings-shipping.php @@ -241,6 +241,7 @@ class WC_Settings_Shipping extends WC_Settings_Page { 'strings' => array( 'unload_confirmation_msg' => __( 'Your changed data will be lost if you leave this page without saving.', 'woocommerce' ), 'save_failed' => __( 'Your changes were not saved. Please retry.', 'woocommerce' ), + 'default_zone_name' => __( 'Zone', 'woocommerce' ), ), ) ); wp_enqueue_script( 'wc-shipping-zones' ); diff --git a/includes/class-wc-shipping-zone.php b/includes/class-wc-shipping-zone.php index 8e6e82b588f..5f6a741f907 100644 --- a/includes/class-wc-shipping-zone.php +++ b/includes/class-wc-shipping-zone.php @@ -47,6 +47,8 @@ class WC_Shipping_Zone extends WC_Data { } elseif ( 0 === $zone ) { $this->set_zone_name( __( 'Rest of the World', 'woocommerce' ) ); $this->read_zone_locations( 0 ); + } else { + $this->set_zone_name( __( 'Zone', 'woocommerce' ) ); } }