JPRukus75
JPRukus75

Reputation: 87

Hide existing <div> and show previous <div> in multi-branch form

I will start by telling you that this is my very first Javascript program from scratch. I am trying to make a back button that will go to the previously chosen div in a form (hide the current div and show the previous one the user chose).

The form has multiple paths to follow, paths within paths and not all selectors are buttons. There might be an onchange event or a radio button or even text input (text inputs have a next button to click).

I have had it working where it will hide the current div but show all previous chosen divs. It's now working where it hides the current div but shows nothing.

I have read a bunch of postings here and in other forums but have not found what I need yet. Any help would be greatly appreciated.

You can see the actual site here and I have put up a JSfiddle but for some reason I can't get it working there. Here is the code from the fiddle:

<div>
    <form>
        <div id="uno" class="showFirst">
            <button onclick="hideUno()">First Button</button>
        </div>
        <div id="dos" class="hideFirst">
            <button onclick="hideDos()">Second Button</button>
        </div>
        <div id="tres" class="hideFirst">
            <button onclick="hidetres()">Third Button</button>
        </div>
        <div id="quattro" class="hideFirst">
            <button onclick="hideQuattroUno()">Fourth Button</button>
            <button onclick="hideQuattroDos()">Fifth Button</button>
        </div>
        <div id="branchUno" class="hideFirst">
            <p>First Branch</p>
        </div>
        <div id="branchDos" class="hideFirst">
            <p>Second Branch</p>
        </div>
    </form>
    <button id="backButton" onclick="goToPrevious" class="hideFirst">Back</button>
</div>

.hideFirst {
    display: none;
}
function goToPrevious() {
    var current = $(".chosen").find(":visible");
    $(current).hide();
    $(current).prev(".chosen").show();
}

function hideUno() {
    $("#backButton").toggle();
    $("#uno").toggle();
    $("#uno").addClass("chosen");
    $("#dos").toggle();
}

function hideDos() {
    $("#dos").toggle();
    $("#dos").addClass("chosen");
    $("#tres").toggle();
}

function hideTres() {
    $("#tres").toggle();
    $("#tres").addClass("chosen");
    $("#quattro").toggle();
}

function hideQuattroUno() {
    $("#quattro").toggle();
    $("#quattro").addClass("chosen");
    $("#branchUno").toggle();
}

function hideQuattroDos() {
    $("#quattro").toggle();
    $("#quattro").addClass("chosen");
    $("#branchDos").toggle();
}

Here are a few of the questions I've reviewed here:

retain show / hide div on multistep form

Hide and Show div in same level

how to show previous div of clicked div in angular.js

show div and hide existing div if open with jQuery?

Show one div and hide the previous showing div

I realize it's not the cleanest code, but as I said this is my first and I am trying to cleanup as I go along and learn new things.

Upvotes: 1

Views: 1846

Answers (1)

Artur Filipiak
Artur Filipiak

Reputation: 9157

You could make a bit of automatization instead of creating onclick events for each button/select separately.

For "Back" functionality, I'd use an array to store elements "on the fly" at each step, instead of checking visibility later on.

I'll make it this way:

  • Remove CSS rule display:none for hideFirst class (elements will be hidden using jQuery).
  • Add an class to the buttons/selects/check-boxes/etc... as event inndicator.
  • Add data-next attribute (to store id of the element which should be shown on click/change)

HTML:

<div id="firstDiv" class="hideFirst">
    <button class="my-btn" data-next="#secondDiv" type="button">Show next<button>
</div>

<div id="secondDiv" class="hideFirst">
    <select class="my-select" data-next="#thirdDiv">
        <option>Helo World</option>
        ...
    </select>
</div>
...

Script:

$(document).ready(function(){

    // hide all 'hideFirst' elements, except the first one:
    $('.hideFirst:not(:first)').hide();
    // declare 'history' variable as an empty array (it will be used to store 'hideFirst' elements for 'Back' functionality):
    var history = [];

    // click event for the buttons :
    $('.my-btn').click(function(e){
        // as the button will submit the form if you're not using type="button" attribute, use this:
        e.preventDefault();
        showNext($(this));
    });

    // change event for selects :
    $('.my-select').change(function(){
        showNext($(this));
    });

    // Method used to show/hide elements :
    function showNext(el){
        // check if element has a 'data-next' attribute:
        if(el.data('next')){
            // hide all elements with 'hideFirst' class:
            $('.hideFirst').hide();
            // show 'Back' button:
            $('#backButton').show();
            // show the element which id has been stored in 'data-next' attribute:
            $(el.data('next')).show();
            // Push the parent element ('.hideFirst') into history array:
            history.push(el.closest('.hideFirst'));
        }
    }

    // click event for 'back' button:
    $('#backButton').click(function(){
        // hide all elements with 'hideFirst' class:
        $('.hideFirst').hide();
        // remove the last '.hideFirst' element from 'history' array and show() it:
        history.pop().show();
        // hide 'back' button if history array is empty:
        history.length || $(this).hide();
    }).hide(); // hide 'back' button on init

});

DEMO

Upvotes: 1

Related Questions