2010-10-27 28 views
45

Tôi đang cố gắng tạo một bảng trong đó mỗi hàng là một biểu mẫu. Tôi muốn rằng mỗi đầu vào nằm trong một bộ phận bảng khác nhau, nhưng tôi vẫn cần ví dụ đó, tất cả các yếu tố đầu vào đầu tiên thuộc về cùng một đầu bảng và vân vân.Tạo bảng HTML trong đó mỗi TR là một FORM

Những gì tôi đang cố gắng làm là một lưới có thể chỉnh sửa, nhiều hơn hoặc ít này:

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

Nhưng dường như tôi không thể sắp xếp các thẻ theo cách đó (hoặc lâu hơn là những gì các validator w3c nói) .

Bất kỳ cách nào tốt để thực hiện việc này?

+3

http://www.hotdesign.com/seybold/ – Stephen

+0

lý do tại sao không loại bỏ các biểu mẫu và đã giải phóng bảng của bạn. –

+2

Như đã thảo luận trong các câu trả lời có vẻ như là một lựa chọn tốt hơn là sử dụng một số loại AJAX để làm điều này. Câu hỏi sau đây chứa một bộ sưu tập các plugin lưới jQuery sẽ cho phép bạn làm những gì bạn muốn; hy vọng bạn thấy điều này hữu ích. http://stackoverflow.com/questions/159025/jquery-grid-recommendations –

Trả lời

76

Nếu bạn muốn có một "lưới có thể chỉnh sửa", tức là một bảng như cấu trúc cho phép bạn thực hiện bất kỳ hàng một hình thức, việc sử dụng CSS mà bắt chước bố trí TABLE thẻ của: display:table, display:table-row, và display:table-cell.

Không cần phải quấn toàn bộ bảng của bạn trong một biểu mẫu và không cần phải tạo biểu mẫu và bảng riêng cho mỗi hàng rõ ràng của bảng.

Hãy thử điều này thay vì:

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

Vấn đề với gói toàn bộ TABLE trong một MẪU là bất kỳ và tất cả các yếu tố hình thức sẽ được gửi về nộp (có lẽ đó là mong muốn nhưng có lẽ không). Phương pháp này cho phép bạn xác định biểu mẫu cho mỗi "hàng" và chỉ gửi hàng dữ liệu đó khi gửi.

Sự cố khi gói thẻ FORM xung quanh thẻ TR (hoặc TR xung quanh MẪU) là HTML không hợp lệ. MẪU sẽ vẫn cho phép gửi như bình thường nhưng tại thời điểm này DOM bị hỏng. Lưu ý: Hãy thử lấy các phần tử con của MẪU của bạn hoặc TR với JavaScript, nó có thể dẫn đến kết quả không mong muốn.

Lưu ý rằng IE7 không hỗ trợ các kiểu bảng CSS và IE8 sẽ cần một tuyên bố DOCTYPE để có được nó thành "tiêu chuẩn" chế độ: (hãy thử một cái gì đó hay này tương đương)

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

Bất kỳ trình duyệt khác hỗ trợ hiển thị: bảng, hiển thị: table-row và display: table-cell sẽ hiển thị bảng dữ liệu css của bạn giống như nó nếu bạn đang sử dụng các thẻ TABLE, TR và TD. Hầu hết trong số họ làm.

Lưu ý rằng bạn cũng có thể bắt chước THEAD, TBODY, TFOOT bằng cách bao gồm các nhóm hàng của bạn trong một DIV khác với display: table-header-group, table-row-grouptable-footer-group tương ứng.

LƯU Ý: Điều duy nhất bạn không thể thực hiện với phương pháp này là colspan.

Check-out minh hoạ này: http://jsfiddle.net/ZRQPP/

+1

Cảm ơn! Điều này đã lưu ngày của tôi – eskatos

1

Bàn không có ý nghĩa cho điều này, tại sao bạn không sử dụng <div> và CSS?

+31

Bảng không có nghĩa là đại diện cho dữ liệu dạng bảng? Tôi đang cố gắng làm một mạng lưới có thể chỉnh sửa. – vtortola

+0

Tôi không chắc chắn một biểu mẫu được tính là dữ liệu. Nó chắc chắn sẽ không bao giờ xác nhận theo cách của bạn bởi vì có những giới hạn cụ thể về những gì các thẻ phải/có thể theo một thẻ

hoặc – Prescott

+1

@vtortola từ khóa là "dữ liệu". Trong ví dụ của bạn, bạn đang sử dụng nó để kiểm soát bố cục biểu mẫu đầu vào của bạn KHÔNG trình bày dữ liệu cho người dùng cuối. Có lẽ nếu bạn giải thích mục đích của bảng là gì, nó sẽ dễ dàng hơn để đề xuất một số lựa chọn thay thế. –

1

Tôi đề nghị thứ hai về div của Harmen. Ngoài ra, bạn có thể bọc bảng trong một biểu mẫu và sử dụng javascript để nắm bắt tiêu điểm hàng và điều chỉnh hành động biểu mẫu qua javascript trước khi gửi.

10

Bạn có thể gặp sự cố với chiều rộng cột, nhưng bạn có thể đặt các vấn đề đó một cách rõ ràng.

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

Bạn có thể muốn cũng phải xem xét làm cho nó một hình thức duy nhất, và sau đó sử dụng jQuery để chọn các yếu tố hình thức từ hàng mà bạn muốn, serialize họ, và trình là hình thức.

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

Ngoài ra, có một số plugin lưới rất đẹp: 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

+11

chắc chắn trả lời câu hỏi - nhưng damn đó là xấu xí :) – Prescott

+0

Điều này thực sự khủng khiếp. – You

+7

Vâng, câu hỏi này có lẽ là một triệu chứng của việc làm một cái gì đó sai, nhưng có vẻ như chúng ta nên trả lời câu hỏi ngoài việc rách rưới trên đó. – Eli

0

nó đơn giản như không sử dụng một bảng cho đánh dấu, như đã nêu bởi Harmen. Bạn không hiển thị dữ liệu sau khi tất cả, bạn đang thu thập dữ liệu.

tôi sẽ lấy ví dụ các câu hỏi 23 ở đây: http://accessible.netscouts-ggmbh.eu/en/developer.html#fb1_22_5

Trên giấy tờ, rất tốt vì nó là. Nếu bạn phải hiển thị kết quả, nó có thể là OK.
Nhưng bạn có thể thay thế bằng ... 4 đoạn văn có nhãn và chọn (tùy chọn sẽ là tiêu đề của dòng đầu tiên). Một đoạn trên mỗi dòng, điều này đơn giản hơn rất nhiều.

+2

Tôi tin rằng một lưới thường hiển thị cả dữ liệu VÀ cho phép chỉnh sửa. – Eli

+0

Một bảng là những thứ phức tạp trong HTML. Một hình thức quá. Tôi sẽ không cố gắng chơi với cả hai khi có những giải pháp đơn giản hơn, đó là một công thức cho sự tồi tệ của cả hai thế giới. Và tôi không nói về một lưới (điều thị giác), có (hoặc phải là) 'display: table-cell;' cho rằng nhưng của bảng yếu tố với các ràng buộc của nó trong HTML. – FelipeAls

12

Nếu tất cả các hàng này có liên quan và bạn cần thay đổi dữ liệu bảng ... tại sao không chỉ quấn toàn bộ bảng trong biểu mẫu và thay đổi GET thành POST (trừ khi bạn biết rằng mình sẽ không gửi nhiều hơn số lượng dữ liệu tối đa mà yêu cầu GET có thể gửi).

(Đó là giả định, tất nhiên, rằng tất cả các dữ liệu được đi đến cùng một vị trí.)

<form method="POST" action="your_action"> 
<table> 
<tr> 
<td><input type="text" name="r1c1" value="" /></td> 
<!-- ... snip ... --> 
</tr> 
<!-- ... repeat as needed ... --> 
</table> 
</form> 
+1

Đây có lẽ là giải pháp tốt nhất. – Stephen

+1

Nếu tôi hiểu bạn một cách chính xác, bạn đang cố gắng tạo một DataGrid, cả hai để hiển thị dữ liệu hiện có và để cho phép chỉnh sửa/nhập dữ liệu. Việc đặt cược tốt nhất sẽ là sử dụng javascript để tạo và xây dựng DataGrid này - có * nhiều * cái tốt ngoài kia. –

4

Nếu tất cả những hàng có liên quan và bạn cần phải thay đổi các dữ liệu bảng .. Tại sao không chỉ quấn toàn bộ bảng trong một biểu mẫu và thay đổi GET thành POST (trừ khi bạn biết rằng bạn sẽ không gửi nhiều hơn số lượng dữ liệu tối đa mà một yêu cầu GET có thể gửi).

Tôi không thể quấn toàn bộ bảng trong biểu mẫu vì một số trường nhập của mỗi hàng là loại đầu vào = "tệp" và tệp có thể lớn.Khi người dùng gửi biểu mẫu, tôi chỉ muốn POST các trường của hàng hiện tại, không phải tất cả các trường của tất cả các hàng có thể có các tệp lớn không cần thiết, khiến biểu mẫu gửi rất chậm.

Vì vậy, tôi đã cố gắng lồng không đúng: tr/form và form/tr. Tuy nhiên, nó chỉ hoạt động khi một người không cố gắng thêm các đầu vào mới động vào biểu mẫu. Các đầu vào được thêm động sẽ không thuộc về dạng lồng nhau không chính xác, do đó sẽ không được gửi. (các biểu mẫu đầu vào động/bảng hợp lệ được gửi tốt).

Nesting div [display: table]/form/div [display: table-row]/div [display: table-cell] tạo ra độ rộng không đồng nhất của cột lưới. Tôi quản lý để có được bố trí thống nhất khi tôi thay div [display: table-hàng] để tạo thành [display: table-hàng]:

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

Đối với cách bố trí sẽ được hiển thị một cách chính xác trong 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" /> 

Mẫu đầu ra:

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

Sẽ khó hơn nhiều khi làm cho mã này hoạt động trong IE6/7.

3

Nếu bạn có thể sử dụng javascript và yêu cầu nghiêm ngặt trên web của mình, bạn có thể đặt hộp văn bản, hộp kiểm và bất kỳ thứ gì trên mỗi hàng của bảng và ở cuối mỗi nút địa điểm hàng (hoặc liên kết của class rowSubmit) "save" . Không có bất kỳ thẻ FORM nào. Biểu mẫu sẽ được mô phỏng bởi JS và Ajax như sau:

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

Bạn nghĩ sao?

PS: Nếu bạn viết trong jQuery này:

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

Nó sẽ được biến thành đối tượng jQuery và bạn có thể làm việc với nó như bạn đang sử dụng để trong jQuery.

+0

PS: Nếu hàng được thêm động bởi javascript, sự kiện "nhấp" sẽ không hoạt động nếu được xác định như được hiển thị. Trong trường hợp đó xác định sự kiện bằng jQuery.live() hoặc jQuery.on() – Racky

9

Nếu sử dụng JavaScript là một lựa chọn và bạn muốn tránh bàn làm tổ, bao gồm jQuery và thử phương pháp sau đây.

Trước tiên, bạn sẽ phải cung cấp cho mỗi hàng một id duy nhất như vậy:

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

Sau đó, bao gồm các chức năng sau đây trong JavaScript cho trang của bạn.

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

Vậy chúng ta đã làm gì ở đây? Chúng tôi đã cung cấp cho mỗi hàng một id duy nhất và bao gồm một phần tử trong hàng có thể kích hoạt việc gửi mã định danh duy nhất của hàng đó. Khi phần tử gửi được kích hoạt, một biểu mẫu mới được tạo và thiết lập động. Sau đó, bằng cách sử dụng jQuery, chúng tôi sao chép tất cả các phần tử có trong hàng của chúng tôi mà chúng tôi đã được thông qua và nối các bản sao vào biểu mẫu được tạo động của chúng tôi. Cuối cùng, chúng tôi gửi mẫu đã nói.

+0

Tôi đã thử cách tiếp cận này nhưng tôi đang sử dụng các yêu cầu ajax vì vậy bây giờ tất cả các hàng này được thêm vào ở cuối bảng của tôi. Đang cố gắng tìm ra cách để giấu chúng. – rii

+0

Đề xuất tốt! Để mã này hoạt động trong FireFox, tôi phải thêm 'form.style.display =" none "; document.body.appendChild (form); 'ngay trước form.submit(); Và đảm bảo sử dụng cùng một id idRow thay vì id. – ISQ

+0

Câu trả lời thú vị. Đã lưu tôi ngày. –

1

Tôi gặp sự cố tương tự như vấn đề đặt ra trong câu hỏi ban đầu. Tôi đã bị hấp dẫn bởi các div được tạo kiểu như các yếu tố bảng (không biết bạn có thể làm điều đó!) Và cho nó một chạy. Tuy nhiên, giải pháp của tôi là giữ cho các bảng của tôi được bọc trong các thẻ, nhưng đổi tên mỗi đầu vào và chọn tùy chọn để trở thành các khóa của mảng, mà bây giờ tôi đang phân tích cú pháp để lấy từng phần tử trong hàng đã chọn.

Đây là một hàng duy nhất từ ​​bảng. Lưu ý quan trọng mà [4] là ID render của hàng trong cơ sở dữ liệu mà từ đó dòng của bảng này đã được lấy ra:

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

Sau đó, trong PHP, Tôi đang sử dụng các phương pháp sau đây để lưu trữ trong một mảng ($ SelectedElem) mỗi phần tử trong hàng tương ứng với nút gửi. Tôi đang sử dụng print_r() chỉ để minh họa:

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

Có lẽ điều này nghe có vẻ phức tạp, nhưng nó hóa ra là khá đơn giản, và nó được bảo quản cơ cấu tổ chức của bảng.

+0

Hạn chế với phương pháp này là tự động điền sẽ giữ danh sách riêng biệt cho mỗi hàng, có thể không phải là vấn đề lớn, chỉ gây nhầm lẫn cho người dùng cuối. Ngoài ra, việc gửi hàng loạt các hàng có thể thổi post_max_limit của máy chủ, trong PHP nghĩa là nó sẽ ném dữ liệu đi. Đó có thể là vấn đề nghiêm trọng nếu giao diện của bạn cho phép người dùng thêm hàng vào bảng. –

Các vấn đề liên quan