2016-02-26 88 views
1

我已經創建了一個模板,它將以遞歸方式構建form/s的嵌套選項卡頁面。每個標籤頁可以包含一個表單或另一個標籤頁,最多可達n層。Django嵌套選項卡表格

這是通過視圖創建的,其中有序字典(form_dict)通過上下文傳遞。如果節點包含另一個有序字典,則代碼如下所示:

在文件窗體/ snippets/form_dict.html form_dict中進行迭代,並呈現窗體(forms/snippets/form_standalone.html)或再次調用自身

形式/片段/ form_dict.html

{% load sekizai_tags %} 
{% if form_dict %} 
    {% if not level or not tier %} 
     {% include "forms/snippets/form_dict.html" with form_dict=form_dict level='Tab' tier='0' %} 
    {% else %} 
     {% with tier=tier|add:1 %} 
      <ul class="nav nav-tabs nav-tabs-{{tier}}" {%ifequal tier 0 %}id="myTab"{% endifequal %}> 
       {% for key,form in form_dict.items %} 
        {% with counter=forloop.counter|stringformat:"s" %} 
         {% with newLevel=''|add:level|add:'-'|add:counter %} 
          <li class="{% ifequal forloop.counter 1 %}active{% endifequal %}"> 
           <a href="#{{newLevel}}" data-toggle="tab" {% if form.errors %}class="has-error"{% endif %}>{{key}}</a> 
          </li> 
         {% endwith %} 
        {% endwith %} 
       {% endfor %} 
      </ul> 
      <div class="tab-content tab-content-{{tier}}"> 
       {% for k,v in form_dict.items %} 
        {% with counter=forloop.counter|stringformat:"s" %} 
         {% with newLevel=''|add:level|add:'-'|add:counter %} 
          <div class="tab-pane {% ifequal forloop.counter 1 %}active{% endifequal %}" id="{{newLevel}}"> 
           {% if v.items %} 
            {% include "forms/snippets/form_dict.html" with form_dict=v level=newLevel tier=tier %} 
           {% else %} 
            {% include "forms/snippets/form_standalone.html" with form=v heading=k %} 
           {% endif %}  
          </div> 
         {% endwith %} 
        {% endwith %} 
       {% endfor %} 
       {% ifequal tier 1 %} 
        {% addtoblock 'js' %} 
         <script type='text/javascript'> 
          $('.nav-tabs li a').click(function(e) { history.pushState(null, null, $(this).attr('href'));}); 
          var hash = location.hash.split('?')[0]; 
          if(hash) { 
           var $link = $('[href=' + hash + ']'); 
           var parents = $link.parents('.tab-pane').get(); 
           $(parents.reverse()).each(function() { 
            $('[href=#' + this.id + ']').tab('show') ; 
           }); 
           $link.tab('show'); 
           jQuery(window).load(function(){ 
            jQuery("html,body").animate({scrollTop:0},1); 
           }); 
          } 
         </script> 
        {% endaddtoblock %} 
       {% endifequal %} 
      </div> 
     {% endwith %} 
    {% endif %} 
{% endif %} 

一切正常,當提交檢測到錯誤,除了,我想改變標籤的顏色,以反映該選項卡下的一種形式有驗證問題。在下面的代碼:

<a href="#{{newLevel}}" data-toggle="tab" {% if form.errors %}class="has-error"{% endif %}>{{key}}</a> 

這具有識別的標籤的效果(參見下圖),但是,它僅突出了葉片 - 我想要在同一類還分配給父選項卡以及

Example

在上面的,錯誤已在兩者的帳單和發貨地址來標識,我想紅色高亮堅持上線於母公司的標籤了,所以這兩個地址和資料標籤標註爲「紅色'以類似的方式。

有人可以提供一個建議,以最好的方式來做到這一點?

回答

0

不知道這是最好的解決方案,但它的工作原理:

我重載OrderedDict,以創建一個屬性errors,因此它可以被稱爲如果它是一個形式。

class MyOrderedDict(OrderedDict): 
    def __init(self): 
     super(OrderedDict,self).__init__() 
    @property 
    def errors(self): 
     return any([v.errors if hasattr(v,'errors') else False for k,v in self.items()]) 

所以views.py,該heirachy是建立這樣的事情,比如:

#Dictionary in Order of Assignment 
    fd      = MyOrderedDict(): #ROOT 
    d       = MyOrderedDict() #CHILD 
    d['Basic']    = formProfile 
    d['Phone']    = formClient 
    add = MyOrderedDict() #CHILD 
    add['Billing Address'] = formAddressBilling 
    add['Shipping Address'] = formAddressShipping 
    d['Addresses']   = add 
    fd['Profile']    = d 
    d2 = MyOrderedDict() 
    d2['Some Form']   = formSomeForm 
    fd['Information']   = d2 

return render_to_response('forms/generic_form.html', 
      dict( base_template = "forms/base.html", 
        form_dict  = fd), 
      context_instance=RequestContext(request) 

這將產生所需的輸出,這意味着無論哪個選項卡用戶當前具有焦點,他/她可以容易地識別在不成功提交時需要調查哪些標籤。

Output