Utwórz tabelę HTML, w której każdy TR jest formularzem

Próbuję stworzyć tabelę, w której każdy wiersz jest formularzem. Chcę, aby każde wejście było w innym podziale tabeli, ale nadal potrzebuję, na przykład, wszystkie pierwsze wejścia należą do tej samej głowicy tabeli i tak dalej.

To, co próbuję zrobić, to edytowalna siatka , mniej więcej to:

<table>
    <tr>
        <form method="GET" action="whatever">
            <td><input type="text"/></td>
            <td><input type="text"/></td>
        </form>
    </tr>
    <tr>
        <form method="GET" action="whatever">
            <td><input type="text"/></td>
            <td><input type="text"/></td>
        </form>
    </tr>
</table>

Ale widocznie nie mogę ustawić tagów w ten sposób (lub tak powiedział walidator w3c).

Jakiś dobry sposób na to?
Author: Brian Tompsett - 汤莱恩, 2010-10-27

10 answers

Jeśli chcesz mieć "edytowalną siatkę", tj. strukturę podobną do tabeli, która pozwala na przekształcenie dowolnego wiersza w Formularz, użyj CSS, który naśladuje układ znacznika tabeli: display:table, display:table-row, i display:table-cell.

Nie ma potrzeby owijania całego stołu w formularz i nie ma potrzeby tworzenia osobnego formularza i tabeli dla każdego widocznego wiersza tabeli.

Spróbuj zamiast tego:

<style>
DIV.table 
{
    display:table;
}
FORM.tr, DIV.tr
{
    display:table-row;
}
SPAN.td
{
    display:table-cell;
}
</style>
...
<div class="table">
    <form class="tr" method="post" action="blah.html">
        <span class="td"><input type="text"/></span>
        <span class="td"><input type="text"/></span>
    </form>
    <div class="tr">
        <span class="td">(cell data)</span>
        <span class="td">(cell data)</span>
    </div>
    ...
</div>

Problem z zawijaniem całej tabeli w Formularz polega na tym, że wszystkie elementy formularza będą wysyłane przy wysyłaniu (może to jest pożądany, ale prawdopodobnie nie). Metoda ta pozwala na zdefiniowanie formularza dla każdego "wiersza" i wysłanie tylko tego wiersza danych podczas przesyłania.

Problem z zawijaniem znacznika formularza wokół znacznika TR (lub TR wokół formularza) polega na tym, że jest to nieprawidłowy HTML. Formularz nadal będzie zezwalał na przesyłanie jak zwykle, ale w tym momencie DOM jest zepsuty. Uwaga: spróbuj uzyskać potomne Elementy formularza lub TR za pomocą JavaScript, może to prowadzić do nieoczekiwanych wyników.

Zauważ, że IE7 nie obsługuje tych stylów tabel CSS i IE8 będzie potrzebował deklaracji doctype, aby przejść do trybu "standards": (spróbuj tego lub czegoś równoważnego)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Każda inna przeglądarka obsługująca display: table, display:table-row I display: table-cell powinna wyświetlać tabelę danych css tak samo, jak w przypadku użycia tagów TABLE, TR i TD. Większość z nich tak.

Zauważ, że możesz również naśladować THEAD, TBODY, TFOOT, zawijając grupy wierszy w inny DIV z display: table-header-group, table-row-group oraz table-footer-group odpowiednio.

Uwaga: jedyną rzeczą, której nie można zrobić z tą metodą jest colspan.

Zobacz tę ilustrację: http://jsfiddle.net/ZRQPP/

 80
Author: Matthew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-05 11:44:26

Jeśli wszystkie te wiersze są ze sobą powiązane i musisz zmienić dane tabelaryczne ... dlaczego po prostu nie zawinąć całej tabeli w Formularz I zmienić GET na POST (chyba że wiesz, że nie będziesz wysyłać więcej niż maksymalna ilość danych, jaką może wysłać żądanie GET).

(oczywiście zakładając, że wszystkie dane trafią do tego samego miejsca.)

<form method="POST" action="your_action">
<table>
<tr>
<td><input type="text" name="r1c1" value="" /></td>
<!-- ... snip ... -->
</tr>
<!-- ... repeat as needed ... -->
</table>
</form>
 12
Author: Sean Vieira,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-27 17:52:19

Możesz mieć problemy z szerokością kolumn, ale możesz je ustawić jawnie.

<table>
  <tr>
    <td>
       <form>
         <table>
           <tr>
             <td></td> 
             <td></td> 
             <td></td> 
             <td></td> 
             <td></td> 
             <td></td> 
           </tr>
         </table>
       </form>
     </td>
    </tr>
  <tr>
    <td>
       <form>
         <table>
           <tr>
             <td></td> 
             <td></td> 
             <td></td> 
             <td></td> 
             <td></td> 
             <td></td> 
           </tr>
         </table>
       </form>
     </td>
    </tr>
  </table>

Możesz również rozważyć utworzenie pojedynczego formularza, a następnie za pomocą jQuery wybrać elementy formularza z żądanego wiersza, serializować je i przesłać jako formularz.

Zobacz: http://api.jquery.com/serialize/

Ponadto istnieje wiele bardzo ładnych siatek wtyczki: http://www.google.com/search?q=jquery+grid&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a

 10
Author: Eli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-27 17:47:08

Jeśli używasz JavaScript i chcesz uniknąć zagnieżdżania tabel, Dołącz jQuery i wypróbuj następującą metodę.

Najpierw musisz nadać każdemu wierszowi unikalne id w ten sposób:

<table>
  <tr id="idrow1"><td> ADD AS MANY COLUMNS AS YOU LIKE  </td><td><button onclick="submitRowAsForm('idrow1')">SUBMIT ROW1</button></td></tr>
  <tr id="idrow2"><td> PUT INPUT FIELDS IN THE COLUMNS  </td><td><button onclick="submitRowAsForm('idrow2')">SUBMIT ROW2</button></td></tr>
  <tr id="idrow3"><td>ADD MORE THAN ONE INPUT PER COLUMN</td><td><button onclick="submitRowAsForm('idrow3')">SUBMIT ROW3</button></td></tr>
</table>

Następnie dołącz następującą funkcję w swoim JavaScript dla swojej strony.

<script>
function submitRowAsForm(idRow) {
  form = document.createElement("form"); // CREATE A NEW FORM TO DUMP ELEMENTS INTO FOR SUBMISSION
  form.method = "post"; // CHOOSE FORM SUBMISSION METHOD, "GET" OR "POST"
  form.action = ""; // TELL THE FORM WHAT PAGE TO SUBMIT TO
  $("#"+idRow+" td").children().each(function() { // GRAB ALL CHILD ELEMENTS OF <TD>'S IN THE ROW IDENTIFIED BY idRow, CLONE THEM, AND DUMP THEM IN OUR FORM
        if(this.type.substring(0,6) == "select") { // JQUERY DOESN'T CLONE <SELECT> ELEMENTS PROPERLY, SO HANDLE THAT
            input = document.createElement("input"); // CREATE AN ELEMENT TO COPY VALUES TO
            input.type = "hidden";
            input.name = this.name; // GIVE ELEMENT SAME NAME AS THE <SELECT>
            input.value = this.value; // ASSIGN THE VALUE FROM THE <SELECT>
            form.appendChild(input);
        } else { // IF IT'S NOT A SELECT ELEMENT, JUST CLONE IT.
            $(this).clone().appendTo(form);
        }

    });
  form.submit(); // NOW SUBMIT THE FORM THAT WE'VE JUST CREATED AND POPULATED
}
</script>
Co my tu zrobiliśmy? Nadaliśmy każdemu wierszowi unikalny identyfikator i uwzględniliśmy element w wierszu, który może wywołać przesłanie unikalnego identyfikatora tego wiersza. Gdy element zgłoszenia jest aktywowany, nowy formularz jest dynamicznie tworzony i konfigurowany. Następnie używając jQuery, klonujemy wszystkie elementy zawarte w <td> ' S wiersza, który nam przekazano i dołączamy klony do naszego dynamicznie tworzonego formularza. Na koniec składamy wspomniany formularz.
 9
Author: b_laoshi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-06 11:04:54

Jeśli wszystkie te wiersze są ze sobą powiązane i musisz zmienić dane tabelaryczne ... dlaczego po prostu nie zawinąć całą tabelę w formularzu I zmienić GET to POST(chyba że wiesz, że nie będziesz wysyłać więcej niż maksymalna ilość danych żądanie GET może wysłać).

Nie mogę zawinąć całej tabeli w postaci, ponieważ niektóre pola wejściowe każdego wiersza są input type = "file" i pliki mogą być duże. Gdy użytkownik przesyła formularz, chcę publikować tylko pola bieżącego wiersza, a nie wszystkie pola wszystkich wierszy, które mogą mieć niepotrzebne ogromne pliki, powodując wysyłanie formularza bardzo powoli.

Więc próbowałem niepoprawnego zagnieżdżania: TR / form i form / tr. Jednak działa tylko wtedy, gdy nie próbuje się dynamicznie dodawać nowych danych wejściowych do formularza. Dynamicznie dodawane dane wejściowe nie będą należeć do niepoprawnie zagnieżdżonego formularza, więc nie zostaną przesłane. (poprawne dane wejściowe formularza / tabeli są przesyłane dynamicznie).

Zagnieżdżanie div[display:table]/form/div[display:table-row]/div[display:table-cell] produkowane niejednorodne szerokości kolumn siatki. Udało mi się uzyskać jednolity układ, gdy zamieniłem div [display:table-row] na form[display: table-row]:

div.grid {
    display: table;
}

div.grid > form {
    display: table-row;


div.grid > form > div {
    display: table-cell;
}
div.grid > form > div.head {
    text-align: center;
    font-weight: 800;
}

Aby układ był wyświetlany poprawnie w IE8:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
...
<meta http-equiv="X-UA-Compatible" content="IE=8, IE=9, IE=10" />

Próbka wyjścia:

<div class="grid" id="htmlrow_grid_item">
<form>
    <div class="head">Title</div>
    <div class="head">Price</div>
    <div class="head">Description</div>
    <div class="head">Images</div>
    <div class="head">Stock left</div>
    <div class="head">Action</div>
</form>
<form action="/index.php" enctype="multipart/form-data" method="post">
    <div title="Title"><input required="required" class="input_varchar" name="add_title" type="text" value="" /></div>

Byłoby jednak znacznie trudniej sprawić, by ten kod działał w IE6/7.

 4
Author: Dmitriy Sintsov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-23 06:25:20

Jeśli możesz używać javascript i ściśle wymagać go w internecie, można umieścić pola tekstowe, checkboxes i cokolwiek na każdym wierszu tabeli i na końcu każdego wiersza miejsce przycisk (lub link klasy rowSubmit) "Zapisz". Bez znacznika formy. Form than będzie symulowane przez JS i Ajax w ten sposób:

<script type="text/javascript">
$(document).ready(function(){
  $(".rowSubmit").click(function()
  {
     var form = '<form><table><tr>' + $(this).closest('tr').html() + '</tr></table></form>';
     var serialized = $(form).serialize(); 
     $.get('url2action', serialized, function(data){
       // ... can be empty
     }); 
   });
});        
</script>
Co o tym myślisz?

PS: jeśli napiszesz w jQuery to:

$("valid HTML string")
$(variableWithValidHtmlString)

Zostanie on zamieniony w obiekt jQuery i możesz z nim pracować tak, jak jesteś przyzwyczajony w jQuery.

 3
Author: Racky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-06 06:47:05

Tabele nie są do tego przeznaczone, dlaczego nie użyjesz <div> ' S i CSS?

 1
Author: Harmen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-27 17:36:48

Popieram sugestię Harmena. Alternatywnie można zawinąć tabelę w formularz i użyć javascript, aby przechwycić fokus wiersza i dostosować akcję formularza za pomocą javascript przed przesłaniem.

 1
Author: Prescott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-27 17:39:15

Miałem problem podobny do tego postawionego w pierwotnym pytaniu. Zaintrygowały mnie divy stylizowane na elementy tabeli (nie wiedziałem, że możesz to zrobić!) i dał sobie radę. Jednak moim rozwiązaniem było, aby moje tabele były owinięte w znaczniki, ale zmienić nazwę każdego wejścia i wybrać opcję, aby stać się kluczami tablicy, którą teraz analizuję, aby uzyskać każdy element w wybranym wierszu.

Oto jeden wiersz z tabeli. Zauważ, że key [4] jest renderowanym ID wiersza w bazie danych, z którego ten wiersz tabeli został pobrany:

<table>
  <tr>
    <td>DisabilityCategory</td>
    <td><input type="text" name="FormElem[4][ElemLabel]" value="Disabilities"></td>
    <td><select name="FormElem[4][Category]">
        <option value="1">General</option>
        <option value="3">Disability</option>
        <option value="4">Injury</option>
        <option value="2"selected>School</option>
        <option value="5">Veteran</option>
        <option value="10">Medical</option>
        <option value="9">Supports</option>
        <option value="7">Residential</option>
        <option value="8">Guardian</option>
        <option value="6">Criminal</option>
        <option value="11">Contacts</option>
      </select></td>
    <td>4</td>
    <td style="text-align:center;"><input type="text" name="FormElem[4][ElemSeq]" value="0" style="width:2.5em; text-align:center;"></td>
    <td>'ccpPartic'</td>
    <td><input type="text" name="FormElem[4][ElemType]" value="checkbox"></td>
    <td><input type="checkbox" name="FormElem[4][ElemRequired]"></td>
    <td><input type="text" name="FormElem[4][ElemLabelPrefix]" value=""></td>
    <td><input type="text" name="FormElem[4][ElemLabelPostfix]" value=""></td>
    <td><input type="text" name="FormElem[4][ElemLabelPosition]" value="before"></td>
    <td><input type="submit" name="submit[4]" value="Commit Changes"></td>
  </tr>
</table>

Następnie w PHP używam następującej metody do przechowywania w tablicy ($SelectedElem)każdego elementu w wierszu odpowiadającego przyciskowi wyślij. Używam print_r() Tylko do zilustrowania:

$SelectedElem = implode(",", array_keys($_POST['submit']));
print_r ($_POST['FormElem'][$SelectedElem]);

Być może brzmi to zawile, ale okazało się to dość proste i zachowało strukturę organizacyjną tabeli.

 1
Author: NotQuiteAPro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-29 02:02:17

To tak proste, jak nie używać tabeli dla znaczników, jak stwierdził Harmen. W końcu nie wyświetlasz danych, tylko je zbierasz.

Wezmę na przykład pytanie 23 tutaj: http://accessible.netscouts-ggmbh.eu/en/developer.html#fb1_22_5

Na papierze jest dobrze jak jest. Gdybyś miał wyświetlać wyniki, prawdopodobnie byłoby OK.
Ale możesz go zastąpić ... 4 akapity z etykietą I select (opcje będą nagłówkami pierwszej linii). Jeden akapit na wiersz, jest to o wiele prostsze.

 0
Author: FelipeAls,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-27 17:41:54