Question

I am working on a WP plugin for a client that communicates with UPS, USPS and FEDEX. USPS requires multiple steps so I am using a UI Dialog Modal in which I add content dynamically via AJAX (PHP). The content is great, but it seems that when I click the continue button on the first dialog it fires all successive dialog button functions. I have a function that I call to change dialog content, and each calling function sends AJAX data and sets the options for the next dialog. I need the button to simply complete its function and allow the user to make selections on the next dialog. While I have been using JQuery, JS and PHP for quite sometime I am fairly new to jQuery UI. Please see my code below for reference. Any help on this would be greatly appreciated.

"obj" is an object returned from PHP containing shippment data and html for dialog.

Function for updating dialog content

  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'));})
}

Function for address validation

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');
}

Function for confirming shipping rates and selecting service addons prior to processing shipment request with 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;
    }       

}
Was it helpful?

Solution

So I was unable to fix the issue directly, so I created a workaround per se. Instead of using the dialog buttons as navigation, I added control buttons to the dialog content in php. I then access them directly via Jquery. See example below.

public function 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;
}

Then in JS I can access the button via 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');
            }
        });
    }
}

Still looking for a better solution, but this will work for now.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top