Search code examples
javascriptjqueryhtmlfade

Show hide created html in jquery based on checkbox


I have a page where the user selects a checkbox, based on the checkbox I perform an ajax call and get 'modules' returned. These are a varying amount, from 0 to 10 or more. The thing is that the modules show up in the second step of my website, which is disabled until the first step (the checking of a checkbox) is done.

I have a text in step 2 saying "Select a package in step 1 first before modules show up".

The way I want it to work is: If the user comes on the page for the first time and checks a checkbox, the text in the second step fades out and the modules (retrieved via ajax and html created in jQuery) fade in slowly. After changing another package in step 1, I want the currently shown modules to fade out, and the new ones to fade in again.

I know where my code goes wrong (when I keep calling the same showModules(data) function, but I do not know how to fix it.

My HTML looks like this:

            <h3>Stap 1: Kies een lidmaatschap</h3>
            <div class="row">
                <?php
                $columnsize = floor((12 /  count($allpackages)));
                foreach ($allpackages as $package) {
                    echo "<div class='col-md-$columnsize'>";
                    echo "<h4>$package->name</h4>";
                    echo "<p>$package->short_description</p>";
                    echo "<p>De volgende modules zitten in het pakket:</p>";
                    echo "<p><ul>";
                    foreach ($package->modules as $module) {
                        echo "<li>$module->name</li>";
                    }
                    echo "</ul></p>";
                    echo "<p>Prijs: $package->price_eur €/jaar + $package->suborg_price_eur €/jaar per deelorganisatie</p>";
                    echo "<input type=\"radio\" name=\"package\" class=\"radiobtnpackage\" value='$package->package_id' required>";
                    echo "</div>";
                }
                ?>
            </div>
            <h3>Stap 2: Kies extra modules (optioneel)</h3>
            <div class="modulegrid">
                <p class="packagestep2fadeout">Selecteer eerst een pakket voor de overige beschikbare modules te bekijken.</p>
                <div class="moduleholder" style="display: none;">aaaaaaa</div>
            </div>

The jQuery looks like this:

var packageSelected = false;
    $('input[name=package]').change(function(ev){
        var ajaxPackageOptions = {
            type: 'POST',
            url: baseUrl + 'pricing/modules/getModuleById',
            dataType: 'json'
        };

        var packageData = {
            "packageid": $( 'input[name=package]:checked' ).val()
        };

        var optionsPackages = $.extend({}, ajaxPackageOptions, {
            data: packageData
        });

        ev.preventDefault();

        // ajax done & fail
        $.ajax(optionsPackages).done(function (data) {
            if (!$.isEmptyObject(data.result)) {
                //console.log(data.result);
                //console.log(packageSelected);
                showModules(data);
                if (packageSelected) {
                    $( ".moduleholder" ).fadeOut( 1000, function() {
                        showModules(data.result);
                        $( ".moduleholder" ).fadeIn( 2500, function() {

                        });
                    });
                } else {
                    //First time a package is selected we need to fade out the first text
                    $( ".packagestep2fadeout" ).fadeOut( 1000).promise().done(function() {
                        // Animation complete.
                        packageSelected = true;
                        showModules(data);
                        $( ".moduleholder" ).fadeIn( 2500, function() {

                        });
                    });
                }
            } else {
                //Geen modules beschikbaar tonen
            }
        }).fail(function (xhr, status, error) {
            //TODO: show error notification
            //alert('TODO: show error notification');
        });
    });

    function showModules(data) {
        //console.log(data);
        var container = $('<div class="modulename" />');
        $.each( data.result, function( key, value ) {
            container.append($("<h2>"+value['name']+"</h2>"));
        });
        $('.moduleholder').html(container);
    }

Everytime the checkbox is changed, the text from the previous modules is immediately replaced by the text from the new ones, before fading out and not in again.

EDIT: created a working fiddle!


Solution

  • Merely small glitches in your logic, all you needed to do was uncomment next line:

        // Animation complete.
        packageSelected = true;
    
        showModules(a); //<--THIS LINE
        $(".moduleholder").fadeIn(2500, function() {
    
        });
    

    and change

    showModules(a);
    if (packageSelected) {
      $(".moduleholder").fadeOut(1000, function() {
        //showModules(data.result);
    
        $(".moduleholder").fadeIn(2500, function() {
    
        });
      });
    }
    

    for

    if (packageSelected) {
      $(".moduleholder").fadeOut(1000, function() {
        //showModules(data.result);
        showModules(a);
        $(".moduleholder").fadeIn(2500, function() {
    
        });
      });
    }
    

    check it out

    HIH