2015-03-10 19 views
6

Questo è il mio primo post su questo sito, quindi spero che mi piaccia. Sto cercando di creare un modulo HTML/PHP e utilizzare una piccola porzione di Javascript per aggiungere righe aggiuntive a una tabella quando si fa clic su un pulsante e incrementare l'ID per i due campi.Javascript Aggiungi riga alla tabella HTML e ID dell'incremento

Il pulsante funziona aggiungendo le righe ma non sembra che incrementa l'ID, basta usare lo stesso ID della riga precedente. Spero che qualcuno possa aiutare?

$(window).load(function(){ 
 
     var table = $('#productanddates')[0]; 
 

 
    var newIDSuffix = 2; 
 
    $(table).delegate('#button2', 'click', function() { 
 
     var thisRow = $(this).closest('tr')[0]; 
 

 
     var cloned = $(thisRow).clone(); 
 
     cloned.find('input, select').each(function() { 
 
      var id = $(this).attr('id'); 
 
      id = id.substring(0, id.length - 1) + newIDSuffix; 
 
      $(this).attr('id', id); 
 
     }); 
 

 
     cloned.insertAfter(thisRow).find('input:date').val(''); 
 

 
     newIDSuffix++; 
 
    }); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
<div class="blue-bar ta-l"> 
 
    <div class="container"> 
 
     <h1>Submit Your Insurance Renewal Date(s)</h1> 
 
    </div> 
 
</div> 
 
<div class="grey-bar"> 
 
    <div class="container"> 
 
     <div class="rounded-box"> 
 
      <div> 
 
       <label for="name">Name</label> 
 
       <input type="text" id="name" name="name" autocomplete="off" required /> 
 
      </div> 
 
      <div> 
 
       <label for="name">Renewal Dates</label> 
 
      </div> 
 
      <table width="100%" border="0" cellspacing="0" cellpadding="5" id="productanddates" class="border"> 
 
        <tr> 
 
         <td> 
 
          <select name="insurance_type1" id="insurance_type1"> 
 
           <option></option> 
 
           <option>Car</option> 
 
           <option>Home</option> 
 
           <option>Van</option> 
 
           <option>Business</option> 
 
           <option>GAP</option> 
 
           <option>Travel</option> 
 
          </select> 
 
         </td> 
 
         <td> 
 
          <input type="date" name="renewal_date1" id="renewal_date1" /> 
 
         </td> 
 
         <td> 
 
          <input type="button" name="button2" id="button2" value="+" /> 
 
         </td> 
 
        </tr> 
 
      </table> 
 
      <div> 
 
       <label for="telephone_number">Contact Number</label> 
 
       <input type="tel" id="telephone_number" name="telephone_number" pattern="\d{11}" autocomplete="off" required /> 
 
      </div> 
 
      <div> 
 
       <label for="email">Email Address</label> 
 
       <input type="email" id="email" name="email" autocomplete="off" required /> 
 
      </div> 
 
      <div> 
 
       <input name="submit" type="submit" value="Submit" class="btn"> 
 
      </div> 
 
     </div>

+1

per HTML dinamico come questo è meglio imparare ad usare le classi e DOM attraversa invece di preoccuparsi di avere bisogno di identità a tutti. Mostra il codice che dipende dagli ID – charlietfl

+0

Sembra funzionare in questo jsFiddle - http://jsfiddle.net/g7116c49/ cambiando '.find ('input: date')' a '.find ('input.date') 'e aggiungendo' class = "date" 'al proprio input di data. – Sean

+0

Hai provato a mettere una dichiarazione di 'newIDSuffix' in JavaScript globale invece che nella funzione' $ (window) .load'? – yW0K5o

risposta

1

Sono andato avanti e ho preso una pugnalata a una versione più pulita di quello che penso tu stia cercando di realizzare. Vado a piedi attraverso i principali aggiornamenti:

  1. Aggiornato il pulsante id e name da "Button2" a "button1" - ho pensato che si vorrebbe mantenere gli indici in sincronia attraverso gli ingressi in ogni riga .
  2. Modifica $(window).load(function() { a $("document").ready(function() { - Mentre funzionerà, il primo attenderà fino al termine del caricamento di tutte le immagini, mentre il secondo funzionerà quando il DOM avrà completato la costruzione. A meno che non si desideri VERAMENTE che le immagini vengano caricate per prime, si consiglia di $("document").ready(), per l'attivazione più rapida del codice.
  3. Rimozione dei riferimenti [0] - il motivo principale per utilizzare [0] dopo una raccolta di selezione jQuery è quello di fare riferimento alla versione DOM dell'elemento selezionato jQuery, in modo da noi una "vanilla" JavaScript metodo su di esso. In tutti i casi, si stava re-rewapping le variabili in $(...), che ha appena convertito l'elemento DOM in un oggetto jQuery, in modo che non fosse necessario eseguire un ulteriore passaggio.
  4. Modificato il metodo .delegate() su .on() - come notato da Howard Renollet, questo è il metodo corretto da utilizzare per le versioni moderne di jQuery.Tieni presente che i parametri "evento" e "target" hanno invertito i posti in on, da dove si trovavano in delegate.
  5. cambiato il target dell'evento #button2-:button - questo farà in modo che tutti i pulsanti nelle nuove righe vi permetterà anche di aggiungere altre righe, non solo il primo.
  6. È stato cambiato il target clone dalla riga su cui è stato fatto clic sull'ultima riga della tabella - ciò consente di mantenere la numerazione delle righe coerente e in ordine crescente. La riga clonata sarà sempre l'ultima, indipendentemente da quale sia stato cliccato, e la nuova riga verrà sempre posizionata alla fine, dopo di essa.
  7. Modificato l'indicizzazione per utilizzare l'indice della riga precedente come base per la nuova riga e utilizzare un'espressione regolare per determinarlo - con la tabella ordinata ora, è sempre possibile contare sull'ultima riga per ottenere l'indice più alto . Utilizzando l'espressione regolare /^(.+)(\d+)$/i, è possibile dividere il valore dell'indice in "tutto prima dell'indice" e "l'indice (cioè, su o più numeri, alla fine del valore)". Quindi, è sufficiente incrementare l'indice di 1 e ricollegarlo, per il nuovo valore. L'utilizzo dell'approccio regex consente anche di adattarsi facilmente, non ci sono mai più di 9 righe (cioè indici a due cifre).
  8. un aggiornamento della id e name attributi per ogni ingresso - ho pensato che si vorrebbe i id e name attributi per essere lo stesso per ogni singolo elemento, in base alla fila iniziale, e, si stava aggiornando solo il id nel tuo codice, che avrebbe causato problemi durante l'invio dei dati.
  9. modificato $("input:date") a $("input[type='date']) - come sottolineato da Mouser, questo era in realtà il motivo principale per cui il codice non funzionava, inizialmente. Tutte le altre modifiche ti aiuteranno ad evitare ulteriori problemi in futuro o sono semplicemente cambiamenti legati alla "qualità del codice".

Così. . . quelli erano gli aggiornamenti principali. :) Fammi sapere se ho frainteso quello che stavi cercando di fare o se hai qualche domanda.

$("document").ready(function() { 
 
\t $('#productanddates').on('click', ':button', function() { 
 
\t \t var lastRow = $(this).closest('table').find("tr:last-child"); 
 

 
\t \t var cloned = lastRow.clone(); 
 
\t \t cloned.find('input, select').each(function() { 
 
\t \t \t var id = $(this).attr('id'); 
 
\t \t \t 
 
\t \t \t var regIdMatch = /^(.+)(\d+)$/; 
 
\t \t \t var aIdParts = id.match(regIdMatch); 
 
\t \t \t var newId = aIdParts[1] + (parseInt(aIdParts[2], 10) + 1); 
 

 
\t \t \t $(this).attr('id', newId); 
 
\t \t \t $(this).attr('name', newId); 
 
\t \t }); 
 

 
\t \t cloned.find("input[type='date']").val(''); 
 
\t \t cloned.insertAfter(lastRow); 
 
\t }); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
<div class="blue-bar ta-l"> 
 
    <div class="container"> 
 
     <h1>Submit Your Insurance Renewal Date(s)</h1> 
 
    </div> 
 
</div> 
 
<div class="grey-bar"> 
 
    <div class="container"> 
 
     <div class="rounded-box"> 
 
      <div> 
 
       <label for="name">Name</label> 
 
       <input type="text" id="name" name="name" autocomplete="off" required /> 
 
      </div> 
 
      <div> 
 
       <label for="name">Renewal Dates</label> 
 
      </div> 
 
      <table width="100%" border="0" cellspacing="0" cellpadding="5" id="productanddates" class="border"> 
 
        <tr> 
 
         <td> 
 
          <select name="insurance_type1" id="insurance_type1"> 
 
           <option></option> 
 
           <option>Car</option> 
 
           <option>Home</option> 
 
           <option>Van</option> 
 
           <option>Business</option> 
 
           <option>GAP</option> 
 
           <option>Travel</option> 
 
          </select> 
 
         </td> 
 
         <td> 
 
          <input type="date" name="renewal_date1" id="renewal_date1" /> 
 
         </td> 
 
         <td> 
 
          <input type="button" name="button1" id="button1" value="+" /> 
 
         </td> 
 
        </tr> 
 
      </table> 
 
      <div> 
 
       <label for="telephone_number">Contact Number</label> 
 
       <input type="tel" id="telephone_number" name="telephone_number" pattern="\d{11}" autocomplete="off" required /> 
 
      </div> 
 
      <div> 
 
       <label for="email">Email Address</label> 
 
       <input type="email" id="email" name="email" autocomplete="off" required /> 
 
      </div> 
 
      <div> 
 
       <input name="submit" type="submit" value="Submit" class="btn"> 
 
      </div> 
 
     </div>

+0

E ora hai intenzione di accusarlo di "1 milione di dollari" ** \ * metti il ​​mignolo alla bocca \ *** – Mouser

+0

LOL. . . gli ha dato un buon colpo. . . ho pensato che l'avrei aiutato un po '. ;) – talemyn

+0

@talemyn, signore, sono il mio eroe. Non posso ringraziarti abbastanza per questo, funziona perfettamente ed è esattamente quello che sto cercando di ottenere. –

2
cloned.insertAfter(thisRow).find('input:date').val(''); 

Questa linea non è corretto. Lancia un errore invalid selector.

è necessario cambiare a:

cloned.insertAfter(thisRow).find('input[type="date"]').val(''); 

jQuery in realtà non sostenere il :INPUT-TYPE format nei selettori, ma non i nuovi tipi di input HTML5 (ancora): in modo da utilizzare input[type="date"] qui è il modo corretto per il momento di scegliere un elemento con un tipo HTML5. Si prega di notare le quotazioni intorno al valore. Se si desidera selezionare un attributo con un determinato valore.

Una panoramica dei selettori dei selettori di css qui: W3schools.

Poiché questa riga genera un errore, il tuo newIDSuffix non viene mai aggiornato, perché lo script si arresta alla riga precedente a causa dell'errore di script.


@Charlietfl solleva un valido punto di imparare di più su classi e DOM traversal. Tuttavia questo non risolverà questo codice. O spiega perché il tuo codice non funziona. Tuttavia è un buon consiglio.

+2

Se corretta, la risposta è un po 'fuorviante nella spiegazione. jQuery supporta effettivamente il formato ': INPUT-TYPE' nei selettori, ma non i nuovi tipi di input HTML5 (ancora): http://api.jquery.com/category/selectors/form-selectors/ Aveva provato ad aggiornare il pulsante nel modulo, ad esempio, '.find (" input: button ")' o anche '.find (": button ")' avrebbe funzionato bene. Mentre sono correlati, i selettori css e i selettori jQuery hanno alcune differenze. – talemyn

+0

@talemyn, grazie per l'aggiornamento. Aggiornato la mia risposta per abbinare il tuo commento quindi è tecnicamente corretto. – Mouser

0
cloned.insertAfter(thisRow).find('input[type="date"]').val(''); 
+1

Benvenuti in Stack Overflow! Sebbene questo codice possa rispondere alla domanda, fornire un contesto aggiuntivo sul perché e/o su come questo codice risponde alla domanda migliora il suo valore a lungo termine. – NathanOliver

Problemi correlati