Question

I have some jQ logic that relies on Bootstrap's .collapse events 'shown' and 'hidden' and inside of one of the collapsible elements is a table that has collapsible rows. When a row in the sub-collapse is shown or hidden it is firing the parent Div's shown/hidden events as well.

Everything in #carriers is returned by the API. Here is a sample of what is returned:

<div class="alert alert-success">
    <h4>Quote ID</h4>
    Write your Quote ID on your Bill of Lading to ensure propper billing. <br />
    <em>Your Quote ID is: <strong>QID-107</strong> </em>
</div>

<span class="hide" id="ctsi_query_id">331</span>

<table class="table table-condensed table-bordered">

    <thead>

        <tr class="center-text">

            <th>Carrier</th>
            <th>Transit</th>
            <th>Rated</th>
            <th class="benchmark">Benchmark</th>
            <th>True Cost</th>
        </tr>
    </thead>
    <tbody>         
        <tr class="cell-dark" >
            <td class="btn-collapse" data-target="#row_CTI1">ABC Dummy Transit(ABCD)</td>
            <td>6 - Days</td>
            <td>
                                        $97.46
                                </td>
            <td class="benchmark">
                                        $128.88
                                </td>
            <td>

                    $113.17


            </td>
            <td> <input type="radio" name="carrier" value="CTI1" /> </td>

        </tr>

        <tr>

            <td colspan="7">

                <div class="row">

                    <div class="span10 collapse" id="row_CTI1">

                        <div class="span2">

                            <strong>Carrier Contact:</strong>

                        </div>

                        <div class="span2">

                            N/A

                        </div>

                        <div class="span4 offset1">

                                                                <div class="row">

                                    <div class="span2">

                                        <strong>Freight Charges</strong>

                                    </div>

                                    <div class="span2 ">

                                        $84.75

                                    </div>

                                </div>

                                <div class="row">

                                    <div class="span2">

                                        <strong>Fuel Charges</strong>

                                    </div>

                                    <div class="span2">

                                        $12.71

                                    </div>

                                </div>

                                <div class="row">

                                    <div class="span2">

                                        <strong>Rated Total</strong>

                                    </div>

                                    <div class="span2">

                                        $97.46

                                    </div>

                                </div>

                                                                <div class="row">

                                    <div class="span2">

                                        <strong>Benchmark</strong>

                                    </div>

                                    <div class="span2">

                                        $128.88

                                    </div>

                                </div>

                                                                <div class="row">

                                    <div class="span2">

                                        <strong> Savings </strong>

                                    </div>

                                    <div class="span2">

                                        $31.42

                                    </div>

                                </div>

                            <div class="row">

                                <div class="span5">

                                    <div class="center-text"><strong> Accessorial Charges </strong></div>


                                </div>

                            </div>

                            <div class="row">

                                <div class="span2">

                                    <strong> Accessorial Totals </strong>

                                </div>

                                <div class="span2 ">

                                    $0.00

                                </div>

                            </div>
                                                              <div class="row">

                                    <div class="span2">

                                        <strong> True Cost </strong>

                                    </div>

                                    <div class="span2 ">

                                        $113.17

                                    </div>

                                </div>

                        </div>

                    </div>

                </div>

            </td>

        </tr>
    </tbody>
</table>

Here is the section HTML:

<div class="row">

    <div class="span10">

        <h3 class="heading" data-toggle="collapse" data-target="#carrierSelect">Carriers</h3>

        <div class="bg-light collapse in bg-light" id="carrierSelect">

            <div class="row spacer-top spacer-bottom">

                <div class="span2 offset8">
                    <a href="#" class="btn btn-primary" id="findCarriers">Get Quote</a>
                </div>

            </div>

            <div class="row spacer-bottom collapse" id="carrierLoad">
                <div class="span2 offset4"><img class="center-block" src="view/img/load.gif" /></div>
            </div>

            <div class="row">

                <div class="span10 bg-x-light collapse in spacer-top" id="carriers">

                </div>

            </div>

        </div>

    </div>

</div>

And here is the jQuery:

//does the actual collapsing
$('.btn-collapse').live('click', function(event){

    var target = $(this).attr('data-target');

    $(target).collapse('toggle')

    event.stopPropagation();

    return false;

});

//these two should stop the propagation, but don't
$('#carriers').find('.collapse').live('hidden', function(event){
    event.stopPropagation();
    return false;
});

$('#carriers').find('.collapse').live('shown', function(event){
    event.stopPropagation();
    return false;
});

//this is the work-horse function, it does all the important stuff
function processLCCRequest(callback){

        var data = new Object();

        data.general = {
            'code': $('#warehouse').val(),
            'shipper': $('#shipper_zip').val(),
            'consignee': $('#consignee_zip').val(),
            'shipment_type': $('#direction').val(),
            'total_weight': $('#total_weight').text(),
        };

        data.accessorials = [];

        $('#accessorials').find('input:checkbox:checked').each(function(acc_index){

            data.accessorials.push($(this).val());

        });

        data.units = [{
            'num_of': ($('#total_pallets').val().length > 0) ? $('#total_pallets').val() : 1,
            'type': 'pallet',
            'weight': 0
        }];

        data.products = [];

        $('#items tr').each(function(index){

            var weight = parseFloat($(this).find('.weight').val(), 10);

            if(isNaN(weight)) {
                //setError('Empty Fields', 'At least one `weight` field was left empty.', 'warning');
                return; //same as continue here. Go figure.
            }

            data.products.push({
                'pieces': 1,
                'weight': parseFloat($(this).find('.weight').val(), 10),
                'class': parseInt($(this).find('.class').val(), 10)
            }); 

        });

        var company = $('#company').val();

        if(company != undefined) {
            company = "&d=" + company;
        } else {
            company = '';
        }

        $.post('index.php?p=api&r=html&c=ctsi&m=quote' + company, data, function(resp){
            try {

                var json = $.parseJSON(resp);
                handleMessages(json);

            } catch(err) {

                $('#carriers').html(resp);

            }

        });

        callback();

        return false;

    };

    //This starts the chain reaction by showing the Loading GIF
    $('#findCarriers').click(function(){
        $('#carrierLoad').collapse('show')
        return false;
    });

    //When the loading image is shown, hide the carrier display
    $('#carrierLoad').on('shown', function(){
        $('#carriers').collapse('hide');
    });

    //when the carriers are hidden, call the main function, 
    //pass the hide command for the loading GIF as the callback
    $('#carriers').on('hidden', function(){
        processLCCRequest(function(){
            $('#carrierLoad').collapse('hide');
        });
    });

    //When the loading GIF is hidden, show the carrier display
    //also, move the page to the top of the carrier display
    $('#carrierLoad').on('hidden', function(){
        alert('hey there');
        $('#carriers').collapse('show');
        $('html, body').animate({
                scrollTop: $("#carriers").offset().top
            }, 1000
        );
    });
Was it helpful?

Solution

$.live() happens after everything has already bubbled to the top since it binds to the document. Changing the .live() to the following resolved the issue:

$('#carriers').on("hidden", '.collapse', function(event){
    event.stopPropagation();
    return false;
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top