2012-09-18 95 views
1

我正在組建一個Django網站,並且處於困境中。表格選擇多行並在動作之間進行選擇

該網站擁有大量的表格添加和編輯的數據,這是非常基本的,但是當它到達外鍵關係,我需要更多的選擇。假設我有一個已售出的類「產品」,並且對於數據庫中的所有產品,我想添加一個對象「維護」,「年費」或不包含的內容。

我可以簡單地做一個形式,有選擇,多領域的,在這裏我選擇我想要的產品,然後爲維護對象輸入參數的另一個領域。這可以正常添加,但是如果我想編輯/刪除/繪製關係/生成報告和類似的東西呢?

什麼,我的想法是,這將是巨大的,如果產品是在一個滾動的,排序,過濾表中列出(這些東西我都能應付自如)。這張表需要的是讓我能夠選擇行(這將是:對象)。我想要採取行動,然後爲各種功能提供多個提交按鈕。

提交按鈕,我可以處理,但我不知道如何使錶行可選。一些JavaScript,我收集?

我讀的地方,如果每行有一個隱藏的複選框綁對象主鍵,然後一個JavaScript可以在該行辦理的點擊和選擇/取消隱藏的複選框,並適當顏色的行。

另外,還有JQuery的「可選」,但這對我來說似乎很抽象。

這將是一個好方法嗎?建議?示例代碼?

回答

3

對,這花了很多工作,所以在這裏。

當我想創建一個使用資料表,而不是用戶輸入數據的一種形式,我用下面的類:

class TableRowForm(): 
    ''' 
    This form is special, because usually, forms include a range of inputs 
    to be filled out by the user. This form however, no inputs are filled in. The 
    form is given a queryset of objects and a list of field names, and with those, 
    a table is made. Each row in the table represents an object. clicking a row 
    will select the object. Multiple submit buttons can be given with various 
    functions. What these buttons have in common is that they all operate on the 
    selected objects, e.g. selecting three objects and pressing delete will delete 
    those three objects. The form is different in that it does not create new objects, 
    it manipulates already existing objects. 
    ''' 
    def __init__(self, queryset, fields): 
     if not fields: 
      raise Exception('A TableRowForm must be supplied both queryset and fields') 
     self.queryset = queryset 
     self.fields = fields 

    def __unicode__(self): 
     ''' 
     Builds the html table rows for the form. 
     ''' 
     if not self.queryset: return '<tr><td>No data...<td></tr>' 
     colcount = 0 
     res = "" 
     res += "<tr>" 
     for f in self.fields: 
      res += "<th>"+self.queryset[0]._meta.get_field_by_name(f)[0].verbose_name+"</th>" 
     res += "</tr>\n" 
     for obj in self.queryset: 
      res += '<tr onclick="selectRow(this)">' 
      res += '<td><input style="display:none;" type="checkbox" name="slct" id="%s" value="%s"/>'%(obj.pk,obj.pk) 

      vals = [getattr(obj, x) for x in self.fields] 
      colcount = len(vals) 
      for x in vals: 
       res += '%s</td><td>'%(str(x)) 
      res = res[:-4] 
      res += '</tr>\n' 
     res += '<tr><th colspan="%d"><span style="font-size:9pt;"><b>Selctable table:</b> Click a row to select it</span></th></tr>'%(colcount) 

     # Add the javascript that implements functionality 
     res += '''\ 
     <script> 
     // Allows for selectable tablerows in forms 
     function selectRow(row) 
     { 
      // Check/uncheck the checkbox 
      var chk = row.getElementsByTagName('input')[0]; 
      chk.checked = !chk.checked; 

      // Color the row in response to the checkbox's boolean value 
      if (chk.checked) { 
       row.style.backgroundColor = 'gray'; 
      } else { 
       row.style.backgroundColor = 'white'; 
      } 
     } 
     </script>''' 
     return res 

這裏做的事情是,它需要數據的查詢集和所需的列表字段進行顯示,然後使用提供的數據構建表,併爲每一行隱藏一個複選框。

構建表後,會附加一個javascript以幫助選擇複選框並相應地爲表格行着色。

創建這樣一種形式可能會去是這樣的:

trform = TableRowForm(queryset=Item.objects.all(), 
           fields=('serial', 
             'prod', 
             'discount', 
             'price', 
             'account', 
             'vat',)) 

當使用這種形式的模板,它應該像這樣

<form action="{% url bla.bla.bla %}" method="post"> 
<table> 
{{ form|safe }} 
</table> 
<input type="submit" name="testform" value="Test" /> 
</form> 

的過濾器來完成「|安全」確保HTML被解釋而不是僅僅寫成文本。

表變量不是自動進行的原因是,形式可能不是整個表本身,所以形式只能讓行的表。

穿上形式提交按鈕的name屬性是管理採取什麼行動,如果我們有一個以上的提交按鈕的好方法。人們可以想象在數據表上可以採取任意數量的動作。

if 'testform' in request.POST: 
     # These two lines fetch all the selected objects from the tablerow form 
     selections = request.POST.getlist('slct') 
     its = Item.objects.filter(pk__in=selections) 

本示例假定錶行形式所使用的對象類型是檔案:

最後,處理的形式的數據,當提交按鈕被命中,可以如下進行。 'slct'是自動給予表單中複選框的名稱。可以想象,通過允許從request.POST的實例創建表單,讓表單從POST數據中自動提取信息,但我還沒有得到那麼多,從而使這變得更加智能化。)

「請求。 POST.getlist('slct')「基本上獲取所有以'slct'命名的值並將它們放入列表中。在此之後,您可以通過查詢主鍵輕鬆檢索它們所代表的對象。

我希望這對除我以外的其他人有用。我爲我所取得的成績感到非常自豪:)

0

你不必創建自己的表單類 - 並在其中嵌入JavaScript。要做到這一點,正確的方法是使用form media,或者乾脆做如下:

{% for a in some_queryset %} 
    <tr> 
     <td><input type="checkbox" id="pk" name="pk" value={{ a.pk }} /></td> 
     <td>{{ a.name }}</td> 
    </tr> 
{% endfor %} 

# later on ... 

<input 
    type="submit" 
    name="action1" 
    value="Do Action 1" 
    id="action1_btn" class="btn btn-primary disabled" /> 
<input 
    type="submit" 
    name="action2" 
    value="Do Action 2" 
    id="action2_btn" 
    class="btn btn-danger disabled" /> 

# and other buttons... 

最後,該位的javascript:

<script type="text/javascript"> 
$('#pk').click(function() { 
    if ($('input[name="pk"]:checked').length > 0) 
    { 
    // more than one check box is checked 
    $("#action1_btn").removeClass('disabled'); 
    $("#action2_btn").removeClass('disabled'); 
    // other actions you want to do 

    } else { 

    // No check boxes are checked 
    $("#action1_btn").addClass('disabled'); 
    $("#action2_btn").addClass('disabled'); 
    } 
}); 
</script> 

這個腳本使按鈕只有當行檢查。

最後,django提供了formsets,它們完全符合您在這裏複製的內容。

+0

JavaScript在這裏有什麼不同?我在js不太棒:P – Eldamir