2016-02-26 77 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