2016-04-05 13 views
0

Ich versuche, flexselect.js verwenden, um die Verwendung von Auswahlfeldern zu erleichtern und jquery.formset.js dynamisch neue Formset-Formulare hinzufügen.reintselect.js reinitialisieren nach dem Hinzufügen neuer Select-Steuerelemente mit Javascript

enter image description here

Ich mache Gebrauch von Inline-Formularsätze hier. Die oberste Zeile ist das Formular, während die Felder im grauen Feld und Formularsatz Formularfelder enthalten. Die Eingabefelder mit "-----------" sind Auswahlfelder, die flexselect.js in Eingabefelder konvertiert hat.

Alles funktioniert gut, bis ich ein neues Formset-Formular mit JQuery (jquery.formset.js) hinzufügen, indem Sie auf "Add Item" auf meiner Benutzeroberfläche klicken.

enter image description here

Eine neue Form von jquery.formset wie erwartet hinzugefügt wird, aber das erste Feld (die I rot markiert) durch flexselect.js, daher den Rohling, anstatt mit „nicht richtig eingelegt ist ------- ----- "wie die oben drauf (die ich gelb markiert). Wenn ich auf das Eingabefeld klicke, verlässt der Fokus das Eingabefeld und geht zu dem gelb hervorgehobenen Feld. Kurz gesagt, flexselect funktioniert nur bei Auswahlboxen, die beim ersten Start von flexselect vorhanden waren.

Kann mir jemand sagen, wie ich flexselect immer neu initialisieren, wenn ich ein neues Formset-Formular hinzufügen, so dass Flexselect aufhört, neu hinzugefügte Auswahlfelder zu ignorieren.

Ich füge einen entsprechenden Code unten:

<script type="text/javascript"> 

    jQuery(document).ready(function() { 
     // This initializes flexselect 
     $("select.flexselect").flexselect(); 

     // this initializes jquery.formset.js and is used for adding new formset forms 
     $(".inline.{{ posting_form.prefix }}").formset({ 
      prefix: "{{ posting_form.prefix }}", 
      addText: "Add item", 
      deleteText: "Remove", 
      added: function(){ // called when the formset form has been added 
       $('select.flexselect').flexselect(); 
       // maybe some more code here....... 
      }, 
     }); 
    }); 
</script> 

Antwort

0

fand ich eine Arbeitslösung für das obige Problem. Es hat damit zu tun, wie jquery.formset.js funktioniert. Für den Fall, dass jemand anderes diesen Stein trifft, hier ist, wie ich es repariert habe.

Wenn Sie auf "Element hinzufügen" klicken, kennt jquery.formset.js den Container, der Ihre anfänglich angezeigten Formset-Formulare enthält. Es folgt dann diesen Algorithmus:

  1. Klon eines der formset Formen
  2. Fügen Sie es zu dem DOM nach dem letzten formset Form Container
  3. neu berechnen und ändern id, name und andere Attribute
  4. etc

flexselect.js auf der anderen Seite funktioniert durch die Suche nach bestimmten select Tags im DOM und Hinzufügen von Daten zu ihnen.

Durch das Hinzufügen geklonter select s, die bereits zurück in das DOM manipuliert wurden, war das, was das unerwartete Verhalten verursachte.

Ich könnte mir keinen besseren Weg vorstellen, als den Quellcode von jquery.formset.js zu ändern. Ich änderte es so (beginnend bei Zeile 75):

$addBtn.click(function() { 
      var nextIndex = parseInt($('#id_' + options.prefix + '-TOTAL_FORMS').val()); 
      var row = $('.' + options.formCssClass + ':first').clone(true).get(0); 
      $(row).removeAttr('id').insertAfter($('.' + options.formCssClass + ':last')); 
      $(row).find('input,select,textarea,label').each(function() { 
       updateElementIndex(this, options.prefix, nextIndex); 
       // If this is a checkbox or radiobutton, set uncheck it. 
       // Fix for Issue 1, reported by Wilson.Andrew.J: 
       var elem = $(this); 
       if (elem.is('input:checkbox') || elem.is('input:radio')) { 
        elem.attr('checked', false); 
       } else { 
        elem.val(''); 
       } 
      }); 
      var formCount = nextIndex + 1; 
      $('#id_' + options.prefix + '-TOTAL_FORMS').val(formCount); 
      // If we've got more than one form, enable delete buttons: 
      if (formCount > 1) { $('a.' + options.deleteCssClass).show(); } 
      // If a post-add callback was supplied, call it with the added form: 
      if (options.added) options.added($(row)); 
      return false; 
     }); 

zu .....

$addBtn.click(function() { 
      var nextIndex = parseInt($('#id_' + options.prefix + '-TOTAL_FORMS').val()); 
      var row = $('.' + options.formCssClass + ':first').clone(true).get(0); 
      // formset.js does not know that the form has been manipulated by flexselect.js. By cloning the form as 
      // it is, it clones elements that have already had events and stuff attached to them. This is what 
      // causes the weird behavior with flexselect.js 

      // first we'll remove the class and style attributes 
      $(row).find('select.flexselect').last().removeAttr("class style"); 
      // next, remove the input field that was previously generated by flexselect 
      $(row).find('input.flexselect').remove(); 

      $(row).removeAttr('id').insertAfter($('.' + options.formCssClass + ':last')); 
      $(row).find('input,select,textarea,label').each(function() { 
       updateElementIndex(this, options.prefix, nextIndex); 
       // If this is a checkbox or radiobutton, set uncheck it. 
       // Fix for Issue 1, reported by Wilson.Andrew.J: 
       var elem = $(this); 
       if (elem.is('input:checkbox') || elem.is('input:radio')) { 
        elem.attr('checked', false); 
       } else { 
        elem.val(''); 
       } 
      }); 

      // At this point, formset.js has done most of the major lifting. We can now add the attributes that 
      // flexselect.js needs which is just a select with a CSS class called 'flexselect'. 
      $(row).find("select").attr("class", "flexselect"); 
      var formCount = nextIndex + 1; 
      $('#id_' + options.prefix + '-TOTAL_FORMS').val(formCount); 
      // If we've got more than one form, enable delete buttons: 
      if (formCount > 1) { $('a.' + options.deleteCssClass).show(); } 
      // If a post-add callback was supplied, call it with the added form: 
      if (options.added) options.added($(row)); 
      return false; 
     }); 

Und dann stellte ich die Initialisierung Code wie so:

<script type="text/javascript"> 
    jQuery(document).ready(function($) { 
     $("select.flexselect").flexselect(); 

     $(".inline.{{ posting_form.prefix }}").formset({ 
      prefix: "{{ posting_form.prefix }}", 
      addText: "Add item", 
      deleteText: "Remove", 
      added: function(){ 
       $('select.flexselect').last().removeData("flexselect"); 
       $('select.flexselect').flexselect(); 
      }, 
     }); 
    }); 
</script> 

Dies ist, wie ich es behoben. Hoffe es hilft jemand anderem.

Verwandte Themen