Jquery UI对话框按钮触发多个点击事件

Jquery UI Dialog Buttons Firing Multiple click Events

本文关键字:事件 UI 对话框 按钮 Jquery      更新时间:2023-09-26

我正在为与UPS, USPS和FEDEX通信的客户端编写WP插件。USPS需要多个步骤,所以我使用一个UI对话框模态,我通过AJAX (PHP)动态添加内容。内容很棒,但似乎当我单击第一个对话框上的继续按钮时,它会触发所有连续的对话框按钮功能。我调用了一个函数来更改对话框内容,每个调用函数发送AJAX数据并为下一个对话框设置选项。我需要按钮来简单地完成其功能,并允许用户在下一个对话框中进行选择。虽然我一直在使用JQuery, JS和PHP相当长一段时间,但我对JQuery UI相当陌生。请参考下面我的代码。如有任何帮助,我将不胜感激。

"obj"是一个从PHP返回的对象,包含发货数据和dialog的html。

更新对话框内容

  show_dialog = function( title, html, options ) {      
    $( "#dialog" ).dialog({
        autoOpen: false,
    });
    $('#dialog').html( html );
    $('#dialog').dialog( 'option', 'title', title );
    $('#dialog').dialog( options );
    $('div.ui-dialog-buttonset button.ui-button span.ui-button-text').each(function() {
    $(this).html($(this).parent().attr('text'));})
}
地址验证函数
usps_address_check = function( obj ) {
    if( obj.VStatus === 'AddressMatch' ) {
            var title = obj.Title;
        var options = {
             resizable: false,
             width:800,
             modal:true,
             buttons: {
                  //when this button is clicked it fires the function in the next dialog below process shipment.
                 'Continue': function(event) {
                     if( $('#verified').attr('checked') ) {
                        data = {
                             action: 'usps_ajax',
                            call: 'check_rate',
                            post: $('#post_id').val(),
                         };
                        ajax_request( data );
                    } else {
                        $(this).dialog( 'option', 'title', "Please click the checkbox to confirm corrected address..." );
                     }
                },
                 Cancel: function() {
                    $(this).dialog( 'close' );
                 }
            }
         }
    }
    show_dialog( title, obj.StatusMessage, options );
    $('#dialog').dialog('open');
}

在USPS处理发货请求之前确认运费和选择服务附加项的功能

usps_confirm_rates = function( obj ) {
    var title = obj.Title;
    var html = obj.StatusMessage;
    var options = {
        resizable: true,
        width:800,
        height:800,
        modal:true,
        buttons: {
         //This function is fired when the button on the first modal above is clicked. 
            'Process Shipment': function() {
                data = {
                    action: 'usps_ajax',
                    call: 'process_shipment',
                    post: $('#post_id').val(),
                };
                ajax_request( data );
            },
            'Cancel': function(e) {
                $(this).dialog( 'close' );
            }
        }
    }
    show_dialog( title, html, options );
    var total_shipping = parseFloat( $('#total_shipping').text() );
    var customer_paid = parseFloat( $('#shipping_paid').text() );
    var total_addons = parseFloat( $('#total_addons').text() );
    var difference;
    $('.btn_addons').click( function(e) {
        var key = $(this).attr('id');
        $('#' + key + '_addon_options').slideToggle();
        $('.cb_addon_sel').change( function(e) {
            var addons = obj.AddOns;
            var thisCheck = $(this);
            var thisTable = $(this).closest('table').attr('id');
            var curr_addon = $(this).val();
            var addon_name = $("#" + curr_addon + "_name").text();
            var thisAddon = new Array();
            var price = get_price( thisTable, curr_addon );
            if( obj.AddOns[thisTable][curr_addon].ProhibitedWithAnyOf !== undefined ) {
                var prohibited = obj.AddOns[thisTable][curr_addon].ProhibitedWithAnyOf.AddOnTypeV5;
            }
            if( obj.AddOns[thisTable][curr_addon].RequiresAllOf !== undefined ) {
                var required = obj.AddOns[thisTable][curr_addon].RequiresAllOf.RequiresOneOf.AddOnTypeV5;
            }
            if($(this).attr('checked') ) {  
                total_addons += parseFloat( price );
                total_shipping += parseFloat( price );
                if( addons_selected[thisTable] === undefined ) 
                    addons_selected[thisTable] = new Array();
                addons_selected[thisTable].push( curr_addon );                          
                for( var p in prohibited ) {
                    if( typeof prohibited === 'object' )
                        element = prohibited[p];
                    else 
                        element = prohibited;
                    $('#' + thisTable + '_row_' + element).hide();
                    if( $('#' + thisTable + '_' + element).attr('checked') ) {
                        $('#' + thisTable + '_' + element).removeAttr('checked');
                    }
                }
                for( var r in required ) {
                    if( typeof required === 'object' )
                        element = required[r];
                    else 
                        element = required;
                    price = get_price( thisTable, element);
                    $('#' + thisTable + '_' + element).attr('checked', 'checked');
                    total_addons += parseFloat( price );
                    total_shipping += parseFloat( price );
                }
            } else {
                var name = addon_required( curr_addon, thisTable );
                if( typeof name === 'string' ) {
                    $('#' + curr_addon + '_info').text('Required when ' + name + ' is selected.');
                    $('#' + thisTable + '_' + curr_addon).attr('checked','checked');
                } else {    
                    total_addons -= parseFloat( price );
                    total_shipping -= parseFloat( price );
                    for( var p in prohibited ) {
                        if( typeof prohibited === 'object' )
                            element = prohibited[p];
                        else 
                            element = prohibited;
                        $('#' + thisTable + '_row_' + element).show();
                        //removeByValue( prohibited[p], prohibited );
                    }
                    for( var r in required ) {
                        if( typeof required === 'object' )
                            element = required[r];
                        else 
                            element = required;
                        price = get_price( thisTable, element);
                        $('#' + thisTable + '_' + element).attr('checked', 'checked');
                        $('#' + thisTable + '_' + element).removeAttr('checked');
                        $('#' + element + '_info').text('');
                        total_addons -= parseFloat( price );
                        total_shipping -= parseFloat( price );
                        //removeByValue( required[r], required );
                    }   
                    removeByValue( curr_addon, addons_selected[thisTable] );
                }
            }
            difference = customer_paid - total_shipping;
            $('#total_addons').text( total_addons.toFixed(2) );
            $('#total_shipping').text( total_shipping.toFixed(2) );
            $('#total_difference').text( difference.toFixed(2) );
        });
    });
    function addon_required( addon, box ) {
        if( typeof required === 'undefined' ) {
            return false;
        } else {
            for(var a in addons_selected[box]) {
                var reqs = obj.AddOns[box][addons_selected[box][a]].RequiresAllOf.RequiresOneOf.AddOnTypeV5;
                if( $.inArray(addon, reqs) == -1) {
                    return false;
                } else {
                    return $("#" + addons_selected[a] + "_name").text();
                }
            }
        }
    }
    function get_price( box, addon ) {
        if( obj.AddOns[box][addon].Amount === undefined ) {
            price = 0.00;
        } else {
            price = obj.AddOns[box][addon].Amount; 
        }   
        return price;
    }       
}

所以我无法直接解决这个问题,所以我自己创建了一个解决方案。我没有使用对话框按钮作为导航,而是将控制按钮添加到php中的对话框内容中。然后我通过Jquery直接访问它们。

公共函数verify_address($authenticator) {
$order = $this->order;

    $params = array(
        'Authenticator' => $authenticator,
        'Address' => array(
            'FullName'  => $order->shipping_first_name . ' ' . $order->shipping_last_name,
            'Company'   => $order->shipping_company,
            'Address1'  => $order->shipping_address_1,
            'Address2'  => $order->shipping_address_2, 
            'City'      => $order->shipping_city,
            'State'     => $order->shipping_state,
            'Zipccode'  => $order->shipping_postcode,
            'Country'   => $order->shipping_country
        ),
    );
    $check = $this->stamps->CleanseAddress( $params );
    $this->xml_response['Call'] = 'VerifyAddress';
    if( ! $check->AddressMatch ) {
        if( $check->CityStateZipOK ) {
            $this->xml_response['ResponseStatusCode'] = 1;
            $this->xml_response['VStatus'] = 'CityStateZipOK';
            $this->xml_response['StatusMessage'] = 'The street address could not be verified; however, the City, State, & ZipCode are valid. Click continue to use this address or cancel.';    
        }
        $this->xml_response['ResponseStatusCode'] = 0;
        $this->xml_response['VStatus'] = 'InvalidAddress';
        $this->xml_response['StatusMessage'] = 'invalid address. Please verify address and resubmit.';
    } else {
        $message  = '<span id="usps_error"></span></br>';
        $message .= "The address was matched. Please review updated address below and click continue to proceed.";
        $message .= '<table><tr><td><input type="checkbox" id="verified" value="true" /></td>';
        $message .= '<td>' . $check->Address->FullName . '</br>';
        $message .= $check->Address->Address1 . '</br>';
        $message .= count( $check->Address->Address2 ) < 0 ? $check->Address->Address2 . '</br>' : '';
        $message .= $check->Address->City . ', ' . $check->Address->State . ' ' . $check->Address->ZIPCode . '-' . $check->Address->ZIPCodeAddOn . '</td></tr><table>';
        //Added html button here for navigation purposes. This can be accessed by its ID in Js after it is added to the dialog box.
        $message .= '</br></br><div><button class="dialog_nav" id="btn_continue">Continue</button></div>';
        $this->xml_response['ResponseStatusCode'] = 1;
        $this->xml_response['VStatus'] = 'AddressMatch';
        $this->xml_response['StatusMessage'] = $message;
        $this->xml_response['Authenticator'] = $check->Authenticator;
        $this->xml_response['Method'] = 'USPS';
        $this->xml_response['Title'] = 'Step 1: Address Verfication';
    }
    if( is_soap_fault( $check ) ) {
        $this->xml_response = handle_errors( $check );  
    }
    return $this->xml_response;
}

然后在JS中我可以通过jQuery访问按钮。

 usps_address_check = function( obj ) {
    if( obj.VStatus === 'AddressMatch' ) {
        var title = obj.Title;
        var options = {
            resizable: false,
            width:800,
            modal:true,
            buttons: {
                //Cancel button functions correctly
                'Cancel': function() {
                    $(this).dialog( 'close' );
                }
            }
        }
    show_dialog( title, obj.StatusMessage, options );
    $('#dialog').dialog('open');
            //Button is accessed here and is code is only executed once. 
        $('#btn_continue').click( function(e) {
            if( $('#verified').attr('checked') ) {
                data = {
                    action: 'usps_ajax',
                    call: 'check_rate',
                    post: $('#post_id').val(),
                };
                ajax_request( data );
            } else {
                $('#usps_error').text("Please click the checkbox to confirm corrected address, and click continue to proceed." ).css('color','red');
            }
        });
    }
}

仍在寻找更好的解决方案,但现在可以了