Neuigkeiten
  • Die modified eCommerce Shopsoftware ist kostenlos, aber nicht umsonst.
    Spenden
  • Damit wir die modified eCommerce Shopsoftware auch zukünftig kostenlos anbieten können:
    Spenden
  • Thema: ANLEITUNG: Attributsystem mit jQuery (vermeidet Speicher-Fehler beim Einsatz vieler Artikelmerkmale)

    DJ-Ready

    • Mitglied
    • Beiträge: 218
    • Geschlecht:
    Moin Moin

    Ich hatte grade in einem Kundeshop den "kleinen" Fehler dass Artikel Attribute nicht mehr gespeichert werden konnten. Nach kurzer Analyse war klar warum, jedes Attribut bzw. jede Checkbox in der Datei new_attributes.php wird per $_POST übergeben.
    Wenn ein Shop nun wirklich viele Artikel Attribute hat kann es sein dass der String einfach zu lang wird und somit quasi der Speichern Knopf nicht mehr funktioniert.

    .htaccess Lösung funktioniert dort nicht also hab ich auf die Schnelle einen kleinen Hotfix gebastelt damit der Knopf wieder funktioniert

    Beim drücken auf den neuen Speicher Button wird jetzt per jQuery jede Tabellenzeile mit nicht aktiver Checkbox aus der Seite entfernt - damit ist der zu übergebende $_POST String beim Speichern nur so lang wie er unbedingt sein muss und alles läuft seinen gewohnten Gang :)

    Geht sicherlich auch ohne jQuery aber es funktioniert und ich bin zu faul es umzuschreiben :P

    Also falls jemand das selbe Problem hat, hier ist der Fix:

    ACHTUNG: Veraltete Version! Eine überarbeitete Anleitung gibt es hier: Klick mich!
    ACHTUNG: Hier gibt es ein aktuelles Dateipaket für Shopversion 1.06: Klick mich!

    in admin/new_attributes.php vor den </head> Tag folgende Zeile einfügen:
    Code: PHP  [Auswählen]
    <!-- Ready hax -->
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>

    Und dann noch in admin/includes/modules/new_attributes_include.php ca. Zeile 182 bis 185
    Code: PHP  [Auswählen]
    <?php
    echo xtc_button(BUTTON_SAVE) . '&nbsp;';
    echo xtc_button_link(BUTTON_BACK, xtc_href_link(FILENAME_NEW_ATTRIBUTES, $param));
    ?>
    ersetzen mit:
    Code: PHP  [Auswählen]
            <!-- ready hax -->
            <script language="javascript">
            jQuery(document).ready(function($) {
                    // alert("ready");
                    $("#speichern_ready, #nur_auswahl_ready, #alle_ready").show();
                    $.extend($.expr[':'], {
                            unchecked: function (obj) {
                                    return ((obj.type == 'checkbox' || obj.type == 'radio') && !$(obj).is(':checked'));
                            }
                    });            
                    $("#nur_auswahl_ready").click(function() {
                            $("input:unchecked").parent().parent().hide(); 
                            $("#realsubmitbutton").click();
                    });            
                    $("#alle_ready").click(function() {
                            $("input:unchecked").parent().parent().show(); 
                            $("#realsubmitbutton").click();
                    });                    

                    $("#speichern_ready").click(function() {
                            $("input:unchecked").parent().parent().remove();       
                            $("#realsubmitbutton").click();
                    });            
            });
            </script>
            <div style="background-color: #e0ffd5; border: 1px solid #666;  bottom: 0; display: block;  left: 0; margin: 0; padding: 5px 20px; position: fixed; width: 100%; text-align:center;">
                    <a class="button"  id="speichern_ready" style="display:none;">Attribute speichern<a/>&emsp;
                    <a class="button" id="nur_auswahl_ready" style="display:none;">Nur aktive Attribute anzeigen<a/>&emsp;
                    <a class="button" id="alle_ready" style="display:none;" >Alle Attribute anzeigen <a/>&emsp;
                    <?php
                    // echo xtc_button(BUTTON_SAVE) . '&nbsp;';
                    echo xtc_button_link(BUTTON_BACK, xtc_href_link(FILENAME_NEW_ATTRIBUTES, $param));
                    ?>             
                   
            </div>
            <div style="display:none !important"><input type="submit" class="button" onclick="this.blur();" value="Speichern" id="realsubmitbutton" ></div>&nbsp;

    ACHTUNG: Veraltete Version! Eine überarbeitete Anleitung gibt es hier: Klick mich!
    ACHTUNG: Hier gibt es ein aktuelles Dateipaket für Shopversion 1.06: Klick mich!

    Jetzt gibts statt der "Speichern" und "Zurück" Buttons unter der Attribute Liste eine grünliche Zeile am unteren Bildschirmrand mit den neuen Buttons "Attribute speichern"  "Nur aktive Attribute anzeigen"  "Alle Attribute anzeigen" und "Zurück"

    Viel Spaß damit :)

    [EDIT Tomcraft 16.05.2014: Hier geht es zu einer überarbeiteten Anleitung von noRiddle & web0null.]
    [EDIT web28 23.01.2015: Hier geht es zu zum Dateipaket für Shopversion 1.06.]

    Linkback: https://www.modified-shop.org/forum/index.php?topic=23108.0

    Simon

    • Viel Schreiber
    • Beiträge: 1.360
    Respekt, das wird bestimmt einige freuen, die seit Monaten Probleme damit haben und auf Lösung warten.

     :thx:

    jannemann

    • modified Team
    • Beiträge: 6.289
    • Geschlecht:
    Hallo DJ-Ready,

    auch von meiner Seite ein herzliches Dankeschön fürs Teilen deiner Lösung mit uns!  :thumbs:

    Schöne Grüße,
    Jan

    noRiddle (revilonetz)

    • Experte
    • Beiträge: 13.724
    • Geschlecht:
    Hey DJ-Ready.
    Klasse Idee (und witziger Name wenn man an document.ready() denkt :-)).

    Nur eine Frage, wenn du erlaubst:
    Warum benutzt du nicht direkt

    Code: Javascript  [Auswählen]
    $('input:not(:checked)')

    oder

    Code: Javascript  [Auswählen]
    $('input').not(':checked') // nach Messungen in den meisten Browsern schneller

    Ist das extend mit einer neuen selector expression schneller ?

    Merci,
    noRiddle

    web0null

    • Experte
    • Beiträge: 1.998
    Frage?
    Heißt das praktisch dass im Original, auch die Werte in die DB geschrieben werden die gar nicht gecheckt sind, oder sollten die erst gar nicht als POST übergeben werden.

    Was muss erreicht werden?

    1. dass die nicht gecheckten Werte als POST übergeben werden, oder
    2. dass die nicht gecheckten Werte in die DB geschrieben werden.

    Soweit ich das verstanden habe, muss 1. erreicht werden, weil es ja an der POST Länge liegt, oder?

    noRiddle (revilonetz)

    • Experte
    • Beiträge: 13.724
    • Geschlecht:
    Hallo web0null,
    Verstehe deine Frage nicht.
    Die beiden Punkte 1. und 2. sind doch das gleiche.

    DJ-Ready will mit seinem Patch erreichen, daß nicht alle POST-Values übergeben werden sondern nur die die ausgewält sind, also die Checkbox "gechecked" haben.

    Ich frage mich aber gerade ob das überhaupt funktioniert.
    Nach meinen Recherchen werden POST-Values von manchen User-Agents auch dann übergeben, wenn die entsprechenden Elemente auf display:none stehen.
    (siehe z.B.: http://www.w3.org/TR/html401/interact/forms.html#successful-controls).

    Setzt man die entsprechenden Elemente hingegen auf disabled="disabled" , sollten Sie nicht übergeben werden, woran sich die modernen  Browser wohl auch halten.

    DJ-Ready's Code wäre ja aber leicht dahingehend umzuschreiben,
    wobei man aus Sicherheitsgründen vielleicht noch ein setTimeOut() mit einer Sekunde oder so vor den Submit setzen sollte damit auch wirklich alle nicht "gecheckten" inputs disabled sind.

    Gruß,
    noRiddle

    hedon02

    • Viel Schreiber
    • Beiträge: 618
    Er entfernt Sie ja nicht durch "display:none;" sondern durch:

    Code: Javascript  [Auswählen]
    $("#speichern_ready").click(function() {
                            $("input:unchecked").parent().parent().remove();        
                            $("#realsubmitbutton").click();
                    });    

    Gruesse

    noRiddle (revilonetz)

    • Experte
    • Beiträge: 13.724
    • Geschlecht:
    Äääh, ja, stimmt.
    Mir fiel nur das Ding mit hide() ins Auge, was ja display:none gleichkommt.

    Verstehe die Buttons in ihrer Relevanz und Relation aber dann nicht.
    Code: Javascript  [Auswählen]
               
    $("#nur_auswahl_ready").click(function() {
        $("input:unchecked").parent().parent().hide();
        $("#realsubmitbutton").click();
    });
    $("#alle_ready").click(function() {
        $("input:unchecked").parent().parent().show();
        $("#realsubmitbutton").click();
    });
    $("#speichern_ready").click(function() {
        $("input:unchecked").parent().parent().remove();
        $("#realsubmitbutton").click();
    });

    Da bei allen drei Buttons sofort submit getriggert wird, frage ich mich was denn dann der Button der mir ins Auge gefallen war, nämlich #nur_auswahl_ready, soll ?
    "Nur aktive Attribute anzeigen" ist ja unsinnig wenn ich doch alle mit POST absende.
    Will ich aber die nicht "gecheckten" nicht absenden, benutze ich ja Button 3.

    Gruß,
    noRiddle

    fishnet

    • Fördermitglied
    • Beiträge: 4.853
    • Geschlecht:
    Beim drücken auf den neuen Speicher Button wird jetzt per jQuery jede Tabellenzeile mit nicht aktiver Checkbox aus der Seite entfernt - damit ist der zu übergebende $_POST String beim Speichern nur so lang wie er unbedingt sein muss und alles läuft seinen gewohnten Gang :)
    Spaßeshalber in einem xtc 1.05 getestet.
    Attribute speichern - speichert die Attribute und kehrt zur Produktauflistung zurück. Auch wenn die Liste vorher lang angezeigt wurde.

    Nur aktive Attribute anzeigen - zeigt ganz kurz die Liste der aktiven Attribute an, speichert sie dann und kehrt zur Produktliste zurück.

    Alle Attribute anzeigen - speichert die Attribute und kehrt zur Produktauflistung zurück.

    wtf....?  :-?

    web0null

    • Experte
    • Beiträge: 1.998
    [...]
    Die beiden Punkte 1. und 2. sind doch das gleiche.
    [...]

    Na ja nicht ganz, aber ist ja egal, habe mich vielleicht auch etwas umständlich ausgedrückt.

    Aber wie du, fishnet, und "ich" erkannt haben, ist der Code etwas verwirrend, bzw. verstehe ich auch nicht warum bei jedem Button praktisch ein submit ausgeführt wird.

    Ich habe das jetzt mal auf die schnelle so gelöst.

    Code: PHP  [Auswählen]
    <script type="text/javascript">
            $(document).ready(function($) {
              $("#button_save, #view_attrib").show();
              var flag  = true;
              var input = $('input[type="checkbox"]').not(':checked').parent().parent();
              input.hide();
              $('#view_attrib').click(function() {
                if(flag){
                  input.show();
                  $(this).html('Nur aktive Attribute anzeigen');
                  $("#button_save").html('Alle Attribute speichern');
                  flag = false;
                }else{
                  input.hide();
                  $(this).html('Alle Attribute anzeigen');
                  $("#button_save").html('Aktive Attribute speichern');
                  flag = true;
                }
              });
              $("#button_save").click(function() {
                if(flag){input.remove();}
                $("#realsubmitbutton").click();
              });
            });
          </script>
          <div>
            <a class="button" id="button_save" style="display:none;">Aktive Attribute speichern<a/>&emsp;
            <a class="button" id="view_attrib" style="display:none;">Alle Attribute anzeigen<a/>&emsp;
            <?php
            // echo xtc_button(BUTTON_SAVE) . '&nbsp;';
            echo xtc_button_link(BUTTON_BACK, xtc_href_link(FILENAME_NEW_ATTRIBUTES, $param));
            ?>
          </div>
          <div style="display:none !important"><input type="submit" class="button" onclick="this.blur();" value="Speichern" id="realsubmitbutton" ></div>&nbsp;
     

    Habe es auf 2 Dynamische Buttons reduziert, testet das einmal. Es wird sozusagen nur das per POST übergeben was auch eingeblendet ist, und die Buttons ändern den Text so, dass es jeweils aktuell dazu passt.

    PS. @DJ-Ready, nichts für ungut, ist ne gute Idee, aber bei mir funktionierte dein Code nicht so richtig.

    Gruß Web0null

    noRiddle (revilonetz)

    • Experte
    • Beiträge: 13.724
    • Geschlecht:
    Hab's zwar nicht getestet,sieht nach Analyse aber sehr gut aus.
    Hab's nur mal übersichtlicher formatiert und als code xml gepostet,
    da sieht man die tags besser ;-):
    Code: XML  [Auswählen]
    <script type="text/javascript">
        $(document).ready(function($) {
            $("#button_save, #view_attrib").show();
            var flag  = true;
            var input = $('input[type="checkbox"]').not(':checked').parent().parent();
            input.hide();
            $('#view_attrib').click(function() {
                if(flag){
                    input.show();
                    $(this).html('Nur aktive Attribute anzeigen');
                    $("#button_save").html('Alle Attribute speichern');
                    flag = false;
                }else{
                    input.hide();
                    $(this).html('Alle Attribute anzeigen');
                    $("#button_save").html('Aktive Attribute speichern');
                    flag = true;
                }
            });
            $("#button_save").click(function() {
                if(flag){input.remove();}
                    $("#realsubmitbutton").click();
            });
        });
    </script>

    <div>
        <a class="button" id="button_save" style="display:none;">Aktive Attribute speichern<a/>&emsp;
        <a class="button" id="view_attrib" style="display:none;">Alle Attribute anzeigen<a/>&emsp;
        <?php
           // echo xtc_button(BUTTON_SAVE) . '&nbsp;';
           echo xtc_button_link(BUTTON_BACK, xtc_href_link(FILENAME_NEW_ATTRIBUTES, $param));
       ?>
    </div>
    <div style="display:none !important">
        <input type="submit" class="button" onclick="this.blur();" value="Speichern" id="realsubmitbutton" >
    </div>

    fishnet

    • Fördermitglied
    • Beiträge: 4.853
    • Geschlecht:
    cool, funktioniert einwandfrei  :-B

    noRiddle (revilonetz)

    • Experte
    • Beiträge: 13.724
    • Geschlecht:
    Na denne, danke DJ Ready für die Idee und vor allem web0null für die finale Lösung.
    Sowas gehört ja schon fast in 1.06, oder ? ...

    Gruß,
    noRiddle

    Simon

    • Viel Schreiber
    • Beiträge: 1.360
    Sowas gehört ja schon fast in 1.06, oder ? ...
    Jein, ist nur die halbe Miete.

    Es ist zwar ein Fix für das konkrete Problem von vielen Usern, aber viel besser wäre es, wenn man einen Attributmanager wie MODUL: XAJAX Attributmanager oder MODUL: Produkt-Bearbeitung mit jQuery Attribute-Manager (zusätzlich) integriert.
    Die derzeitige Verwaltung ist schon ziemlich umständlich. Alles was mit den Artikeln zu tun hat, sollte auch an einer zentralen Stelle verwaltet werden können.

    noRiddle (revilonetz)

    • Experte
    • Beiträge: 13.724
    • Geschlecht:
    Jau, aber da werden die Entwickler sich wahrscheinlich nicht so schnell zu bereiterklären.
    Es müsste ja ohnehin eine anständige Lagerverwaltung in den Shop, denn Attribute werden nicht aktualisiert wenn man z.B. aus einer Bestellung eines löscht oder ändert weil der Kunde das wünscht.
    Und, und das ist noch wichtiger, die Attribute müssen von der Gesamtstückzahl abhängen, bzw. umgekehrt, muß die Gesamtstückzahl von der Stückzahl der Attribute abhängen (Stichwort: Master-Slave o.ä.).

    Das wäre noch ein weiter Weg.
    Bis dahin ist die Lösung hier doch gut.

    Gruß,
    noRiddle
    Trade Republic - Provisionsfrei Aktien handeln
    11 Antworten
    6526 Aufrufe
    23. Mai 2010, 17:52:42 von mikeSo
    7 Antworten
    5840 Aufrufe
    31. Januar 2011, 13:24:40 von itnorden
    1 Antworten
    2730 Aufrufe
    09. November 2012, 15:39:14 von web0null