Search code examples
javascriptjquerytwitter-bootstrapcallbackbootstrap-modal

Bootstrap generic modal with callbacks


I've replace my JS Confirm function with a bootstrap modal, this modal is async so I also had to change my code and add callbacks.

What I'm trying to is:

Pseudo Code

if `simApp["con1"]` then show first modal with 2 buttons
    if return is clicked -> close modal.
    if continue is clicked -> open second modal
        if return is clicked -> close modal
        if submit is clicked -> submit form (not included in code)
else open second modal
    if return is clicked -> close modal
    if submit is clicked -> submit form (not included in code)

This is all very simple when you don't use callbacks, which I'm fairly new to.

So this is what I did, its NOT working, I guess it has something to do with the generic use of the modal. - JSFIDDLE

HTML

<div class="modal fade" id="generalModalTwoButtons" role="dialog">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header bg-primary">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                 <h4 class="modal-title"></h4>

            </div>
            <div class="modal-body"></div>
            <div class="modal-footer">
                <button type="button" id="btn-return" class="btn btn-primary" data-dismiss="modal"></button>
                <button type="button" id="btn-submit" class="btn btn-primary" data-dismiss="modal"></button>
            </div>
        </div>
    </div>
</div>
<button id="go">GO</button>

JS

simApp = {};
simApp["con1"] = true;  //in this code I hard-coded the conditions to ture
simApp["arr"] = [1];

$("#go").click(function () {
    if (simApp["con1"] && simApp["arr"].length < 5) {
        var msg = '<p>msg1</p>';

        updateGeneralTwoButtonsModal('#a94442', 'header1', msg, 'Return', 'Continue', function (result) {
            if (result === true) {
                confirmBeforeSubmit(submitFormApproved);
            }
        });
    } else {
        confirmBeforeSubmit(submitFormApproved)
    }
});

function submitFormApproved(result) {
    if (result === true) {
        console.warn("submitted");
    }
}

function confirmBeforeSubmit(callback) {
    var msg = '<p>msg2</p>';
    if (simApp["con1"]) msg = '<p>msg2-changed</p>';

    updateGeneralTwoButtonsModal('#31708f', 'header2', msg, 'Return', 'Submit', callback);
}

function updateGeneralTwoButtonsModal(color, title, body, btnReturn, btnSubmit, callback) {
    var confirm = $('#generalModalTwoButtons');
    confirm.find('.modal-header').css('color', color);
    confirm.find('.modal-title').text(title);
    confirm.find('.modal-body').html(body);
    confirm.modal('show');

    confirm.find('#btn-return').html(btnReturn).off('click').click(function () {
        confirm.modal('hide');
        callback(false);
    });
    confirm.find('#btn-submit').html(btnSubmit).off('click').click(function () {
        confirm.modal('hide');
        callback(true);
    });

}

Any idea what I did wrong?

P.S - for learning purposes I would like to avoid using promises on this solution.


Solution

  • Here you go, the main problem I found was the fact that you don't block the propagation of the click event which automatically closes the modals. I added the event handler stopPropagation in the event of the continue/submit button.

    simApp = {};
    simApp["con1"] = true;
    simApp["arr"] = [1];
    
    $("#go").click(function () {
        if (simApp["con1"] && simApp["arr"].length < 5) {
            var msg = '<p>msg1</p>';
    
            updateGeneralTwoButtonsModal('#a94442', 'header1', msg, 'Return', 'Continue', function (result) {
                if (result === true) {
                    confirmBeforeSubmit(submitFormApproved);
                }
            });
        } else {
            confirmBeforeSubmit(submitFormApproved)
        }
    });
    
    function submitFormApproved(result) {
        if (result === true) {
            console.warn("submitted");
        }
    }
    
    function confirmBeforeSubmit(callback) {
        var msg = '<p>msg2</p>';
        if (simApp["con1"]) msg = '<p>msg2-changed</p>';
    
        updateGeneralTwoButtonsModal('#31708f', 'header2', msg, 'Return', 'Submit', callback);
    }
    
    
    function updateGeneralTwoButtonsModal(color, title, body, btnReturn, btnSubmit, callback) {
        var confirm = $('#generalModalTwoButtons');
        confirm.find('.modal-header').css('color', color);
        confirm.find('.modal-title').text(title);
        confirm.find('.modal-body').html(body);
        confirm.modal('show')
        
    
        confirm.find('#btn-return').html(btnReturn).off('click').click(function () {
            confirm.modal('hide');
            
            callback(false);
        });
        confirm.find('#btn-submit').html(btnSubmit).off('click').click(function (event) {
            event.preventDefault();
            event.stopPropagation();
            if(btnSubmit != "Continue") {
            	confirm.modal('hide');
            }
            callback(true);
        });
    
    }
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <div class="modal fade" id="generalModalTwoButtons" role="dialog">
        <div class="modal-dialog modal-lg">
            <div class="modal-content">
                <div class="modal-header bg-primary">
                    <button type="button" class="close" data-dismiss="modal">&times;</button>
                     <h4 class="modal-title"></h4>
    
                </div>
                <div class="modal-body"></div>
                <div class="modal-footer">
                    <button type="button" id="btn-return" class="btn btn-primary" data-dismiss="modal"></button>
                    <button type="button" id="btn-submit" class="btn btn-primary" data-dismiss="modal"></button>
                </div>
            </div>
        </div>
    </div>
    <button id="go">GO</button>