javascript - 页面提交/重新加载时未保留下拉选项

标签 javascript php jquery jquery-chosen

所以我有一个结帐页面,其中收集了送货和帐单地址。国家和州选项使用 Chosen by Harvest 中的下拉框为每个国家提供不同的州列表。但是,提交后,页面会重新加载更新后的运费,并且在此过程中,所选状态将恢复为第一个选择(即阿拉斯加)。国家/地区选项被保留,但州/省/自治区选项生成方式中的某些因素导致州/省/市/自治区选项无法被保留。

这是相关的 JavaScript:

var GBSStates;
(function(j){
/*!
 * Simple JavaScript Inheritance
 * By John Resig http://ejohn.org/
 * MIT Licensed.
 *
 * Extended by Jonathon Byrd to include function hooks
 * https://gist.github.com/Jonathonbyrd/724083
 *
 * Don't forget your Shims!
 * https://github.com/kriskowal/es5-shim/blob/master
 */
(function(){var a=false,b=/xyz/.test(function(){xyz})?/\b_super\b/:/.*/;function c(h){var f=h,e={before:[],after:[]};function g(){var j=[].slice.call(arguments,0),k=0,l;for(k=0;!!e.before[k];k+=1){l=e.before[k];l.apply(this,j)}var m=f.apply(this,arguments);for(k=0;!!e.after[k];k++){l=e.after[k];l.apply(this,j)}return m}g.bind=function(i){if(typeof this!=="function"){throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable")}var m=Array.prototype.slice.call(arguments,1),l=this,j=function(){},k=function(){return l.apply(this instanceof j&&i?this:i,m.concat(Array.prototype.slice.call(arguments)))};j.prototype=this.prototype;k.prototype=new j();return k};g.addHook=function(j,i){if(e[j] instanceof Array){e[j].push(i)}else{throw (function(){var k=new Error("Invalid hook type");k.expected=Object.keys(e);k.got=j;return k}())}};return g}function d(f,e){if(typeof jQuery=="undefined"){return f}return jQuery.extend(true,e,f)}this._Class=function(){};_Class.extend=function(i){var g=this.prototype;a=true;var f=new this();a=false;for(var e in i){f[e]=typeof i[e]=="function"&&typeof g[e]=="function"&&b.test(i[e])?(function(j,k){return function(){var m=this._super;this._super=g[j];var l=k.apply(this,arguments);this._super=m;return l}})(e,i[e]):(typeof i[e]=="function"?c(i[e]):(typeof i[e]=="object"&&typeof g[e]=="object"?d(i[e],g[e]):i[e]))}function h(){if(!a&&this.init){this.init.apply(this,arguments)}}h.prototype=f;h.constructor=h;h.extend=c(arguments.callee);return h}})();Class=_Class.extend({defaults:{container:null},data:{},init:function(a){this.setOptions(a)},setOptions:function(c){var b=new Object();for(var a in this.defaults){b[a]=this.defaults[a]}for(var a in c){b[a]=c[a]}this.data=b;return this},set:function(b,a){this.data[b]=a},get:function(a,b){return typeof this.data[a]!="undefined"?this.data[a]:b},element:function(){return this.get("container")},rawElement:function(){return this.element().context},uid:function(){return this._uid().replace(/[/,'').replace(/]/,"").replace(/:/,"")},_uid:function(){if(this.element().attr("id")){return this.element().attr("id")}if(this.element().attr("name")){return this.element().attr("name")}var a="";if(this.element().context.form.id){a=this.element().context.form.id}if(!a&&this.element().context.form.name){a=this.element().context.form.name}return a+this.element().index()}});
GBSStates = Class.extend({
    defaults : {
            container : null,
            stateselect : '#gb_billing_zone',
            stateselectparent : null,
            hiddenstate : '#gb_billing_zone_text',
            hiddenstateparent : null,
            states : [],
            chosen : {
                allow_single_deselect: true,
                no_results_text: "Oops, nothing found!",
                width: '300px'
            }
    },

    // Initializing
    init: function(o)
    {
            this.setOptions(o);
            this.set('stateselect', j(this.get('stateselect')));
            this.set('stateselectparent', this.get('stateselect')
                    .closest('tr'));

            this.set('hiddenstate', j(this.get('hiddenstate')));
            this.set('hiddenstateparent', this.get('hiddenstate')
                    .closest('tr'));

            this.storeOriginal();
            this.addListeners();
            this.recreate();
    },

        // store the original select box
        storeOriginal: function()
        {
            var optgroups = {};
            j(this.get('stateselect')).find('optgroup').each(function(k,v){
                var options = {};
                j(this).find('option').each(function(k,v){
                    options[j(v).val()] = j(v).text();
                });
                optgroups[j(v).attr('label')] = options;
            });
            this.set('states', optgroups);

            // delete the original
            j(this.get('stateselect')).find('optgroup').remove();
        },

        // create the chosen select boxes and set the listeners
    addListeners: function()
    {
            this.get('stateselect').chosen(this.get('chosen'))
                    .change(this.update.bind(this));

            this.element().chosen(this.get('chosen'))
                    .change(this.recreate.bind(this));
    },


        update: function(e)
        {
            var chosenstate = j(e.currentTarget);
            this.get('hiddenstate').val( chosenstate.val() );
        },

        // recreate the state select boxes
        recreate: function()
        {
            var country = this.element().val();
            var states = this.get('states')[country];
            var stateselect = this.get('stateselect');

            if (states) { // enable chosen select box
                this.get('hiddenstate').val('');
                this.get('hiddenstateparent').hide();
                this.get('stateselectparent').show();

                stateselect.find('option').remove();
                j.each(states, function( k, v ){
                    // k is the key from opts, ex : value_1
                    // v is the value attributet to k, ex : value #1
                    j('<option />', { 
                        text : v,
                        value : k
                    }).appendTo( stateselect );
                });

                //stateselect.trigger("chosen:updated");
                stateselect.data("chosen").destroy().chosen(this.get('chosen'));

            } else { // enable text field
                this.get('hiddenstateparent').show();
                this.get('stateselectparent').hide();
            }
        }
});
j.fn.GBSStates = function(o){
    // initializing
    var args = arguments;
    var o = o || {'container':''};
    return this.each(function(){
        // load the saved object
        var api = j.data(this, 'GBSStates');
        // create and save the object if it does not exist
        if (!api) {
            o.container = j(this);
            api = new GBSStates(o);
            j.data(this, 'GBSStates', api);
        }
                if (typeof api[o] == 'function') {
                        if (args[0] == o) delete args[0];
                        api[o].bind(api);
                        var parameters = Array.prototype.slice.call(args, 1);
                        return api[o].apply(api,parameters);
               }
        return api;
    });
};
})(jQuery);

jQuery(document).ready(function() {
    jQuery('#gb_billing_country').GBSStates({
        stateselect : '#gb_billing_zone'
    });
    jQuery('#gb_shipping_country').GBSStates({
        stateselect : '#gb_shipping_zone',
        hiddenstate : '#gb_shipping_zone_text',
    });
});

不幸的是我没有写这个,而且我对 JavaScript 相当不熟悉,所以任何帮助将不胜感激!

哦,当我试图弄清楚发生了什么时,我发现了另一件事: 提交并更新税后查看页面源代码时,html 显示正确的状态为“已选择”,即使显示的是阿拉斯加:

<option value="WA" selected='selected'>Washington</option>

编辑:以下是一些使用上述 JavaScript 的相关 PHP 代码:

<?php 
/**
 * Function is activated by the gb_valid_process_payment_page filter
 * 
 * @param type $verify
 * @param Group_Buying_Checkouts $checkout
 * @return type
 */
function gbsstates_capture_state( $verify, Group_Buying_Checkouts $checkout )
{
    // set billing state
    $zone = isset($_POST['gb_billing_zone_text']) &&$_POST['gb_billing_zone_text']
            ?$_POST['gb_billing_zone_text']
            :(isset($_POST['gb_billing_zone'])?$_POST['gb_billing_zone']
            :$checkout->cache['billing']['zone']);
    $checkout->cache['billing']['zone'] = $zone;

    // set shipping state
    $zone = isset($_POST['gb_shipping_zone_text']) &&$_POST['gb_shipping_zone_text']
            ?$_POST['gb_shipping_zone_text']
            :(isset($_POST['gb_shipping_zone'])?$_POST['gb_shipping_zone']
            :$checkout->cache['shipping']['zone']);
    $checkout->cache['shipping']['zone'] = $zone;

    // pass through the verify boolean
    return $verify; 
}

/**
 * fired on gb_checkout_fields_billing action. it adds an additional hidden
 * field to the array
 * 
 * @param type $fields
 * @return array()
 */
function gbsstates_add_textfield_zone( $fields = array() )
{
    $fields['zone_text'] = array(
            'weight' => 13,
            'label' => __( 'State' ),
            'type' => 'text'
    );

    return $fields;
}

/**
 * Function upgrades the fields array
 * 
 * @param type $states
 */
function gbsstates_set_checkout_fields_array( $states = array(), $args = array() ){
    wp_enqueue_script(
        'gbsstates',
        plugins_url( '/js/states.js' , __DIR__ ),
        array( 'jquery' )
    );
    wp_enqueue_script(
        'chosen',
        plugins_url( '/js/chosen.jquery.min.js' , __DIR__ ),
        array( 'gbsstates' )
    );
    wp_enqueue_style(
        'chosen',
        plugins_url( '/css/chosen.css' , __DIR__ )
    );

    $states = gbsstates_statearray_minimal();
    if ( isset( $args['include_option_none'] ) && $args['include_option_none'] ) {
        $states = array( '' => array('' => $args['include_option_none'] ))
                            + $states;
    }
    return $states;
}

/**
 * This function returns an array of states
 * 
 * @return array()
 */
function gbsstates_statearray_minimal() { 
    return array(
        'US'                 => array(
            'AK'             => 'Alaska',
            'AL'             => 'Alabama',
            'AR'             => 'Arkansas',
            'AZ'             => 'Arizona',
            'CA'             => 'California',
            'CO'             => 'Colorado',
            'CT'             => 'Connecticut',
            'DC'             => 'District Of Columbia',
            'DE'             => 'Delaware',
            'FL'             => 'Florida',
            'GA'             => 'Georgia',
            'HI'             => 'Hawaii',
            'IA'             => 'Iowa',
            'ID'             => 'Idaho',
            'IL'             => 'Illinois',
            'IN'             => 'Indiana',
            'KS'             => 'Kansas',
            'KY'             => 'Kentucky',
            'LA'             => 'Louisiana',
            'MA'             => 'Massachusetts',
            'MD'             => 'Maryland',
            'ME'             => 'Maine',
            'MI'             => 'Michigan',
            'MN'             => 'Minnesota',
            'MO'             => 'Missouri',
            'MS'             => 'Mississippi',
            'MT'             => 'Montana',
            'NC'             => 'North Carolina',
            'ND'             => 'North Dakota',
            'NE'             => 'Nebraska',
            'NH'             => 'New Hampshire',
            'NJ'             => 'New Jersey',
            'NM'             => 'New Mexico',
            'NV'             => 'Nevada',
            'NY'             => 'New York',
            'OH'             => 'Ohio',
            'OK'             => 'Oklahoma',
            'OR'             => 'Oregon',
            'PA'             => 'Pennsylvania',
            'RI'             => 'Rhode Island',
            'SC'             => 'South Carolina',
            'SD'             => 'South Dakota',
            'TN'             => 'Tennessee',
            'TX'             => 'Texas',
            'UT'             => 'Utah',
            'VA'             => 'Virginia',
            'VT'             => 'Vermont',
            'WA'             => 'Washington',
            'WI'             => 'Wisconsin',
            'WV'             => 'West Virginia',
            'WY'             => 'Wyoming'
        )
    );
} 

最佳答案

当您重新加载页面时,所有表单都会被清除,这是正常的。有两种解决方案。

  1. 保存输入 您可以在页面重新加载之前使用 localstorage 保存输入值,而不是检查 localstorage 变量是否存在,如果存在,则将默认状态更改为该状态。

  2. 不要重新加载 您还可以(如果您的计算是在 JS 中完成的)在值发生变化时重新实时计算价格。然后你可以使用 jquery 例如来更改显示的价格。这是迄今为止最简单、最有效的方法。由于没有延迟,它还提供了更好的用户体验。

关于javascript - 页面提交/重新加载时未保留下拉选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25250359/

相关文章:

javascript - 使用 jquery/js 检查第二类是否打开或关闭的条件

javascript - jQuery fadeIn 动画显示数据

javascript - HTML5 数据属性将 null 和 undefined 转换为字符串

javascript - 过滤两个数组返回空白数组

javascript - 将 PHP 数组转换为 JavaScript

javascript - 如何更改 webpack 构建中的所有 href 和 src 路径?

PHP MySQL在$_REQUEST中提交动态字段、数组

javascript - cakephp中Js文件放在哪里

php - td Rowspan 之后的 html,下一列数据转到下一行

php - sql 字段值加一