Ich habe eine Seite, auf der der Benutzer ein Kontrollkästchen aktiviert. Basierend auf dem Kontrollkästchen führe ich einen Ajax-Aufruf durch und erhalte "Module" zurück. Dies ist eine unterschiedliche Menge von 0 bis 10 oder mehr. Die Sache ist, dass die Module im zweiten Schritt meiner Website angezeigt werden, der deaktiviert ist, bis der erste Schritt (das Aktivieren eines Kontrollkästchens) abgeschlossen ist.

In Schritt 2 steht ein Text mit der Aufschrift "Wählen Sie zuerst ein Paket in Schritt 1 aus, bevor Module angezeigt werden".

Ich möchte, dass es funktioniert: Wenn der Benutzer zum ersten Mal auf die Seite kommt und ein Kontrollkästchen aktiviert, wird der Text im zweiten Schritt ausgeblendet und die Module (abgerufen über Ajax und HTML, die in jQuery erstellt wurden) werden langsam eingeblendet. Nachdem ich in Schritt 1 ein anderes Paket geändert habe, möchte ich, dass die aktuell angezeigten Module ausgeblendet und die neuen wieder eingeblendet werden.

Ich weiß, wo mein Code schief geht (wenn ich immer wieder dieselbe Funktion showModules (data) aufrufe, aber ich weiß nicht, wie ich das beheben soll.

Mein HTML sieht so aus:

            <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>

Die jQuery sieht folgendermaßen aus:

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

Jedes Mal, wenn das Kontrollkästchen geändert wird, wird der Text aus den vorherigen Modulen sofort durch den Text aus den neuen Modulen ersetzt, bevor er ausgeblendet und nicht wieder eingeblendet wird.

BEARBEITEN : Erstellt eine funktionierende Geige!

2
Dennis 17 Apr. 2018 im 23:28

3 Antworten

Beste Antwort

Nur kleine Pannen in Ihrer Logik. Alles, was Sie tun mussten, war, die nächste Zeile zu kommentieren:

    // Animation complete.
    packageSelected = true;

    showModules(a); //<--THIS LINE
    $(".moduleholder").fadeIn(2500, function() {

    });

Und ändern

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

    $(".moduleholder").fadeIn(2500, function() {

    });
  });
}

Zum

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

    });
  });
}

Hör zu

HIH

1
Scaramouche 17 Apr. 2018 im 21:49

Dies sollte veranschaulichen, was Sie versuchen zu tun. Es geht nur um die Platzierung der Aufrufe fadeIn und fadeOut.

var details = {
    1: [{name: 'Stuff'}, {name: 'More Stuff'}],
    2: [{name: 'Foo'}, {name: 'Bar'}],
    3: [{name: 'Cheese'}, {name: 'Whine'}],
    4: [{name: 'Ball'}, {name: 'Bat'}]
}

$('input[name=package]').change(function(e) {
  var $this = $(this);

  $('.moduleholder').fadeOut(1000); // make sure we "fadeout" on change
  
  // simulate ajax call
    setTimeout(function() {
      var data = {};
      data.result = details[$this.val()];
      showModules(data);
  }, 1000);
});

function showModules(data) {
    var container = $('<div class="modulename" />');
    $.each( data.result, function( key, value ) {
        container.append($("<h2>"+value['name']+"</h2>"));
    });
    $('.moduleholder').html(container);
    $('.moduleholder').fadeIn(1000); // <--- add this here
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="package1">Package 1</label>
<input type="radio" name="package" value="1" id="package1"/>
<label for="package2">Package 2</label>
<input type="radio" name="package" value="2" id="package2"/>
<label for="package3">Package 3</label>
<input type="radio" name="package" value="3" id="package3"/>
<label for="package4">Package 4</label>
<input type="radio" name="package" value="4" id="package4"/>

<div>
  <p>Details of selected package</p>
  <div class="moduleholder" style="display: none; border: 1px solid black;"></div>
</div>
1
gforce301 17 Apr. 2018 im 21:18

Es ändert sich sofort, da Ihre Daten bereits festgelegt und sichtbar sind, wenn Sie sie mit showModules() erstellen. Sie sollten die Daten .hide() verwenden, nachdem Sie sie mit showModules() erstellt haben. Dann wird es fadeIn() schön, da es .hidden() vor Ihnen fadeIn() liegt. Schauen Sie sich das folgende Beispiel an.

Bearbeiten: Ok, ich hatte Recht, was falsch lief, aber ich habe mich bei der Platzierung von .hide() geirrt. Das Auskommentieren von $(".moduleholder").hide(); in der Anweisung else gibt wieder, wovon Sie gesprochen haben. Ich habe es in die Anweisung else verschoben. Ich habe auch das .promise() Ihres $( ".packagestep2fadeout" ).fadeOut() Anrufs entfernt.

var packageSelected = false;
$('input[name=package]').change(function(ev) {

  ev.preventDefault();
  $.ajax({
    url: "https://api.github.com/users/justinjmnz",
  }).done(function(data) {
    var div = $(".moduleholder");
    if (packageSelected) {
      div.fadeOut(1000, function() {
        showModules(data);
        // div.hide(); // Hide the data so it fades in nice: EDIT: Don't really need it here
        div.fadeIn(2500);
      });
    } else {
      $(".packagestep2fadeout").fadeOut(1000, function() { // Removed .promise()
        packageSelected = true;
        showModules(data);
        $(".moduleholder").hide(); // It's supposed to be here
        $(".moduleholder").fadeIn(2500);
      });
    }
  });
});

function showModules(data) {
  var container = $('<div class="modulename" />');
  $.each(data, function(key, value) {
    // console.log(key, value);
    container.append($("<p>Key: " + key + "</br>Value: " + value + "</p>"));
  });
  // Surprise at the bottom!
  container.append($("<img src=" + data.avatar_url + "</img>"));
  $('.moduleholder').html(container);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" name="package">
<p class="packagestep2fadeout">Selecteer eerst een pakket voor de overige beschikbare modules te bekijken.</p>
<div class="moduleholder">
</div>

In Ihrem Beispiel sieht es ungefähr so aus:

 $(".packagestep2fadeout").fadeOut(1000, function() { // Removed .promise()
    packageSelected = true;
    showModules(data);
    $(".moduleholder").hide(); // Added this guy
    $(".moduleholder").fadeIn(2500);
  });
1
Jimenemex 17 Apr. 2018 im 21:20