Big changeover to JS templating for the table.
Switching over to building the table with JS — wp.template. We are now using the same JS template for existing rows and newly generated rows on the fly — this should simplify things moving forward. I’ve also started building stuff in an external JS file rather than straight on the page. Will continue migrating things to it and localizing as needed. Saved ( 2 * displayed tax rates - 1 ) db queries per page load by doing the locations all in one query and then parceling them out in php. More coming.
This commit is contained in:
parent
f0656e7e38
commit
729e6c924c
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Used by woocommerce/includes/admin/settings/views/html-settings-tax.php
|
||||
*/
|
||||
|
||||
(function($, data, wp){
|
||||
var rowTemplate = wp.template( 'tax-table-row' ),
|
||||
$ratesTbody = $('#rates');
|
||||
|
||||
$(function() {
|
||||
$ratesTbody.innerHTML = '';
|
||||
$.each( data.rates, function ( id, rowData ) {
|
||||
$ratesTbody.append( rowTemplate( rowData ) );
|
||||
} );
|
||||
});
|
||||
})(jQuery, htmlSettingsTaxLocalizeScript, wp);
|
|
@ -2,155 +2,71 @@
|
|||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
global $wpdb;
|
||||
|
||||
// Get all the rates and locations. Snagging all at once should significantly cut down on the number of queries.
|
||||
$rates = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM `{$wpdb->prefix}woocommerce_tax_rates` WHERE `tax_rate_class` = %s ORDER BY `tax_rate_order`;", sanitize_title( $current_class ) ) );
|
||||
$locations = $wpdb->get_results( "SELECT * FROM `{$wpdb->prefix}woocommerce_tax_rate_locations`" );
|
||||
|
||||
// Set the rates keys equal to their ids.
|
||||
$rates = array_combine( wp_list_pluck( $rates, 'tax_rate_id' ), $rates );
|
||||
|
||||
// Drop the locations into the rates array.
|
||||
foreach ( $locations as $location ) {
|
||||
if ( ! isset( $rates[ $location->tax_rate_id ]->{$location->location_type} ) ) {
|
||||
$rates[ $location->tax_rate_id ]->{$location->location_type} = array();
|
||||
}
|
||||
$rates[ $location->tax_rate_id ]->{$location->location_type}[] = $location->location_code;
|
||||
}
|
||||
|
||||
// Localize and enqueue our js.
|
||||
wp_register_script( 'htmlSettingsTaxLocalizeScript', WC()->plugin_url() . '/assets/js/admin/settings_views_html-settings-tax.js', array( 'jquery', 'wp-util' ), WC_VERSION );
|
||||
wp_localize_script( 'htmlSettingsTaxLocalizeScript', 'htmlSettingsTaxLocalizeScript', array(
|
||||
'current_class' => $current_class,
|
||||
'rates' => $rates,
|
||||
'page' => $page,
|
||||
'limit' => $limit,
|
||||
'strings' => array(
|
||||
|
||||
),
|
||||
) );
|
||||
wp_enqueue_script( 'htmlSettingsTaxLocalizeScript' );
|
||||
|
||||
?>
|
||||
<h3><?php printf( __( 'Tax Rates for the "%s" Class', 'woocommerce' ), $current_class ? esc_html( $current_class ) : __( 'Standard', 'woocommerce' ) ); ?></h3>
|
||||
<p><?php printf( __( 'Define tax rates for countries and states below. <a href="%s">See here</a> for available alpha-2 country codes.', 'woocommerce' ), 'http://en.wikipedia.org/wiki/ISO_3166-1#Current_codes' ); ?></p>
|
||||
|
||||
<input type="search" class="tax-search" placeholder="<?php esc_attr_e( 'Search…', 'woocommerce' ); ?>" />
|
||||
<p class="num-results-found"></p>
|
||||
|
||||
<script>
|
||||
(function($){
|
||||
function processTaxRateSearch() {
|
||||
var searchText = this.value.toLowerCase(),
|
||||
$table = $('table.wc_tax_rates'),
|
||||
$rows = $table.find('tbody tr' ),
|
||||
results = 0;
|
||||
|
||||
if ( 0 === searchText.length ) {
|
||||
$rows.removeClass('search-result-match');
|
||||
$('.num-results-found' ).text('');
|
||||
return;
|
||||
}
|
||||
$rows.each(function(){
|
||||
var rowText = $(this).find(':input').map( function(){ return this.value; } ).get().join(' ');
|
||||
if ( -1 !== rowText.toLowerCase().indexOf( searchText.toLowerCase() ) ) {
|
||||
$(this).toggleClass( 'search-result-match', true );
|
||||
results++;
|
||||
} else {
|
||||
$(this).toggleClass( 'search-result-match', false );
|
||||
}
|
||||
});
|
||||
$('.num-results-found').text( ('<?php echo esc_js( __( '%d results found.', 'woocommerce' ) ); ?>').replace( '%d', results ) );
|
||||
|
||||
}
|
||||
$('.tax-search' ).on( 'keyup search', processTaxRateSearch );
|
||||
})(jQuery);
|
||||
</script>
|
||||
<style>
|
||||
tr.search-result-match input {
|
||||
background-color: yellow !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<table class="wc_tax_rates wc_input_table sortable widefat">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="sort"> </th>
|
||||
|
||||
<th width="8%"><?php _e( 'Country Code', 'woocommerce' ); ?> <span class="tips" data-tip="<?php esc_attr_e('A 2 digit country code, e.g. US. Leave blank to apply to all.', 'woocommerce'); ?>">[?]</span></th>
|
||||
|
||||
<th width="8%"><?php _e( 'State Code', 'woocommerce' ); ?> <span class="tips" data-tip="<?php esc_attr_e('A 2 digit state code, e.g. AL. Leave blank to apply to all.', 'woocommerce'); ?>">[?]</span></th>
|
||||
|
||||
<th><?php _e( 'ZIP/Postcode', 'woocommerce' ); ?> <span class="tips" data-tip="<?php esc_attr_e('Postcode for this rule. Semi-colon (;) separate multiple values. Leave blank to apply to all areas. Wildcards (*) can be used. Ranges for numeric postcodes (e.g. 12345-12350) will be expanded into individual postcodes.', 'woocommerce'); ?>">[?]</span></th>
|
||||
|
||||
<th><?php _e( 'City', 'woocommerce' ); ?> <span class="tips" data-tip="<?php esc_attr_e('Cities for this rule. Semi-colon (;) separate multiple values. Leave blank to apply to all cities.', 'woocommerce'); ?>">[?]</span></th>
|
||||
|
||||
<th width="8%"><?php _e( 'Rate %', 'woocommerce' ); ?> <span class="tips" data-tip="<?php esc_attr_e( 'Enter a tax rate (percentage) to 4 decimal places.', 'woocommerce' ); ?>">[?]</span></th>
|
||||
|
||||
<th width="8%"><?php _e( 'Tax Name', 'woocommerce' ); ?> <span class="tips" data-tip="<?php esc_attr_e('Enter a name for this tax rate.', 'woocommerce'); ?>">[?]</span></th>
|
||||
|
||||
<th width="8%"><?php _e( 'Priority', 'woocommerce' ); ?> <span class="tips" data-tip="<?php esc_attr_e('Choose a priority for this tax rate. Only 1 matching rate per priority will be used. To define multiple tax rates for a single area you need to specify a different priority per rate.', 'woocommerce'); ?>">[?]</span></th>
|
||||
|
||||
<th width="8%"><?php _e( 'Compound', 'woocommerce' ); ?> <span class="tips" data-tip="<?php esc_attr_e('Choose whether or not this is a compound rate. Compound tax rates are applied on top of other tax rates.', 'woocommerce'); ?>">[?]</span></th>
|
||||
|
||||
<th width="8%"><?php _e( 'Shipping', 'woocommerce' ); ?> <span class="tips" data-tip="<?php esc_attr_e('Choose whether or not this tax rate also gets applied to shipping.', 'woocommerce'); ?>">[?]</span></th>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="rates">
|
||||
<?php
|
||||
$rates = $wpdb->get_results( $wpdb->prepare(
|
||||
"SELECT * FROM {$wpdb->prefix}woocommerce_tax_rates
|
||||
WHERE tax_rate_class = %s
|
||||
ORDER BY tax_rate_order
|
||||
LIMIT %d, %d
|
||||
" ,
|
||||
sanitize_title( $current_class ),
|
||||
( $page - 1 ) * $limit,
|
||||
$limit
|
||||
) );
|
||||
|
||||
foreach ( $rates as $rate ) {
|
||||
?>
|
||||
<tr class="tips" data-tip="<?php echo __( 'Tax rate ID', 'woocommerce' ) . ': ' . $rate->tax_rate_id; ?>">
|
||||
<td class="sort"><input type="hidden" class="remove_tax_rate" name="remove_tax_rate[<?php echo $rate->tax_rate_id ?>]" value="0" /></td>
|
||||
|
||||
<td class="country" width="8%">
|
||||
<input type="text" value="<?php echo esc_attr( $rate->tax_rate_country ) ?>" placeholder="*" name="tax_rate_country[<?php echo $rate->tax_rate_id ?>]" class="wc_input_country_iso" />
|
||||
</td>
|
||||
|
||||
<td class="state" width="8%">
|
||||
<input type="text" value="<?php echo esc_attr( $rate->tax_rate_state ) ?>" placeholder="*" name="tax_rate_state[<?php echo $rate->tax_rate_id ?>]" />
|
||||
</td>
|
||||
|
||||
<td class="postcode">
|
||||
<input type="text" value="<?php
|
||||
$locations = $wpdb->get_col( $wpdb->prepare( "SELECT location_code FROM {$wpdb->prefix}woocommerce_tax_rate_locations WHERE location_type='postcode' AND tax_rate_id = %d ORDER BY location_code", $rate->tax_rate_id ) );
|
||||
|
||||
echo esc_attr( implode( '; ', $locations ) );
|
||||
?>" placeholder="*" data-name="tax_rate_postcode[<?php echo $rate->tax_rate_id ?>]" />
|
||||
</td>
|
||||
|
||||
<td class="city">
|
||||
<input type="text" value="<?php
|
||||
$locations = $wpdb->get_col( $wpdb->prepare( "SELECT location_code FROM {$wpdb->prefix}woocommerce_tax_rate_locations WHERE location_type='city' AND tax_rate_id = %d ORDER BY location_code", $rate->tax_rate_id ) );
|
||||
echo esc_attr( implode( '; ', $locations ) );
|
||||
?>" placeholder="*" data-name="tax_rate_city[<?php echo $rate->tax_rate_id ?>]" />
|
||||
</td>
|
||||
|
||||
<td class="rate" width="8%">
|
||||
<input type="number" step="any" min="0" value="<?php echo esc_attr( $rate->tax_rate ) ?>" placeholder="0" name="tax_rate[<?php echo $rate->tax_rate_id ?>]" />
|
||||
</td>
|
||||
|
||||
<td class="name" width="8%">
|
||||
<input type="text" value="<?php echo esc_attr( $rate->tax_rate_name ) ?>" name="tax_rate_name[<?php echo $rate->tax_rate_id ?>]" />
|
||||
</td>
|
||||
|
||||
<td class="priority" width="8%">
|
||||
<input type="number" step="1" min="1" value="<?php echo esc_attr( $rate->tax_rate_priority ) ?>" name="tax_rate_priority[<?php echo $rate->tax_rate_id ?>]" />
|
||||
</td>
|
||||
|
||||
<td class="compound" width="8%">
|
||||
<input type="checkbox" class="checkbox" name="tax_rate_compound[<?php echo $rate->tax_rate_id ?>]" <?php checked( $rate->tax_rate_compound, '1' ); ?> />
|
||||
</td>
|
||||
|
||||
<td class="apply_to_shipping" width="8%">
|
||||
<input type="checkbox" class="checkbox" name="tax_rate_shipping[<?php echo $rate->tax_rate_id ?>]" <?php checked($rate->tax_rate_shipping, '1' ); ?> />
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th colspan="10">
|
||||
<a href="#" class="button plus insert"><?php _e( 'Insert row', 'woocommerce' ); ?></a>
|
||||
<a href="#" class="button minus remove_tax_rates"><?php _e( 'Remove selected row(s)', 'woocommerce' ); ?></a>
|
||||
|
||||
<div class="pagination">
|
||||
<?php
|
||||
echo str_replace( 'page-numbers', 'page-numbers button', paginate_links( array(
|
||||
'base' => esc_url_raw( add_query_arg( 'p', '%#%', remove_query_arg( 'p' ) ) ),
|
||||
'format' => '',
|
||||
'add_args' => '',
|
||||
'type' => 'plain',
|
||||
'prev_text' => '«',
|
||||
'next_text' => '»',
|
||||
'current' => $page,
|
||||
'total' => ceil( absint( $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(tax_rate_id) FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_class = %s;", sanitize_title( $current_class ) ) ) ) / $limit )
|
||||
) ) );
|
||||
echo str_replace( 'page-numbers', 'page-numbers button', paginate_links( array(
|
||||
'base' => esc_url_raw( add_query_arg( 'p', '%#%', remove_query_arg( 'p' ) ) ),
|
||||
'format' => '',
|
||||
'add_args' => '',
|
||||
'type' => 'plain',
|
||||
'prev_text' => '«',
|
||||
'next_text' => '»',
|
||||
'current' => $page,
|
||||
'total' => ceil( absint( $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(tax_rate_id) FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_class = %s;", sanitize_title( $current_class ) ) ) ) / $limit )
|
||||
) ) );
|
||||
?>
|
||||
</div>
|
||||
|
||||
|
@ -159,7 +75,56 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
<tbody id="rates">
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<script type="text/html" id="tmpl-tax-table-row">
|
||||
<tr class="tips" data-tip="<?php echo esc_attr( sprintf( __( 'Tax rate ID: %s', 'woocommerce' ), '{{ data.tax_rate_id }}' ) ); ?>">
|
||||
<td class="sort">
|
||||
<# if ( ! data.new ) { #>
|
||||
<input type="hidden" class="remove_tax_rate" name="remove_tax_rate[{{ data.tax_rate_id }}]" value="0" />
|
||||
<# } #>
|
||||
</td>
|
||||
|
||||
<td class="country">
|
||||
<input type="text" value="{{ data.tax_rate_country }}" placeholder="*" name="tax_rate_country[{{ data.tax_rate_id }}]" class="wc_input_country_iso" />
|
||||
</td>
|
||||
|
||||
<td class="state">
|
||||
<input type="text" value="{{ data.tax_rate_state }}" placeholder="*" name="tax_rate_state[{{ data.tax_rate_id }}]" />
|
||||
</td>
|
||||
|
||||
<td class="postcode">
|
||||
<input type="text" value="<# if ( data.postcode ) print( data.postcode.join( '; ' ) ); #>" placeholder="*" data-name="tax_rate_postcode[{{ data.tax_rate_id }}]" />
|
||||
</td>
|
||||
|
||||
<td class="city">
|
||||
<input type="text" value="<# if ( data.city ) print( data.city.join( '; ' ) ); #>" placeholder="*" data-name="tax_rate_city[{{ data.tax_rate_id }}]" />
|
||||
</td>
|
||||
|
||||
<td class="rate">
|
||||
<input type="number" step="any" min="0" value="{{ data.tax_rate }}" placeholder="0" name="tax_rate[{{ data.tax_rate_id }}]" />
|
||||
</td>
|
||||
|
||||
<td class="name">
|
||||
<input type="text" value="{{ data.tax_rate_name }}" name="tax_rate_name[{{ data.tax_rate_id }}]" />
|
||||
</td>
|
||||
|
||||
<td class="priority">
|
||||
<input type="number" step="1" min="1" value="{{ data.tax_rate_priority }}" name="tax_rate_priority[{{ data.tax_rate_id }}]" />
|
||||
</td>
|
||||
|
||||
<td class="compound">
|
||||
<input type="checkbox" class="checkbox" name="tax_rate_compound[{{ data.tax_rate_id }}]" <# if ( 1 === data.tax_rate_compound ) { #> checked="checked" <# } #> />
|
||||
</td>
|
||||
|
||||
<td class="apply_to_shipping">
|
||||
<input type="checkbox" class="checkbox" name="tax_rate_shipping[{{ data.tax_rate_id }}]" <# if ( 1 === data.tax_rate_shipping ) { #> checked="checked" <# } #> />
|
||||
</td>
|
||||
</tr>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
jQuery( function() {
|
||||
jQuery('.wc_tax_rates .remove_tax_rates').click(function() {
|
||||
|
@ -231,36 +196,12 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
jQuery('.wc_tax_rates .insert').click(function() {
|
||||
var $tbody = jQuery('.wc_tax_rates').find('tbody');
|
||||
var size = $tbody.find('tr').size();
|
||||
var code = '<tr class="new">\
|
||||
<td class="sort"></td>\
|
||||
<td class="country" width="8%">\
|
||||
<input type="text" placeholder="*" name="tax_rate_country[new-' + size + ']" class="wc_input_country_iso" />\
|
||||
</td>\
|
||||
<td class="state" width="8%">\
|
||||
<input type="text" placeholder="*" name="tax_rate_state[new-' + size + ']" />\
|
||||
</td>\
|
||||
<td class="postcode">\
|
||||
<input type="text" placeholder="*" name="tax_rate_postcode[new-' + size + ']" />\
|
||||
</td>\
|
||||
<td class="city">\
|
||||
<input type="text" placeholder="*" name="tax_rate_city[new-' + size + ']" />\
|
||||
</td>\
|
||||
<td class="rate" width="8%">\
|
||||
<input type="number" step="any" min="0" placeholder="0" name="tax_rate[new-' + size + ']" />\
|
||||
</td>\
|
||||
<td class="name" width="8%">\
|
||||
<input type="text" name="tax_rate_name[new-' + size + ']" />\
|
||||
</td>\
|
||||
<td class="priority" width="8%">\
|
||||
<input type="number" step="1" min="1" value="1" name="tax_rate_priority[new-' + size + ']" />\
|
||||
</td>\
|
||||
<td class="compound" width="8%">\
|
||||
<input type="checkbox" class="checkbox" name="tax_rate_compound[new-' + size + ']" />\
|
||||
</td>\
|
||||
<td class="apply_to_shipping" width="8%">\
|
||||
<input type="checkbox" class="checkbox" name="tax_rate_shipping[new-' + size + ']" checked="checked" />\
|
||||
</td>\
|
||||
</tr>';
|
||||
var code = wp.template( 'tax-table-row' )( {
|
||||
tax_rate_id : 'new-' + size,
|
||||
tax_rate_priority : 1,
|
||||
tax_rate_shipping : 1,
|
||||
new : true
|
||||
} );
|
||||
|
||||
if ( $tbody.find('tr.current').size() > 0 ) {
|
||||
$tbody.find('tr.current').after( code );
|
||||
|
|
Loading…
Reference in New Issue