Django嵌套标签表格

时间:2016-02-26 03:09:10

标签: python django tabs nested

我创建了一个模板,它将以递归方式构建form / s的嵌套标签页。每个标签页都可以包含一个表单或另一个标签页,最多可达n级。

这是通过视图创建的,其中有序字典(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

在上文中,已经在结算地址和送货地址中发现了错误,我希望红色突出显示仍然保持上线到父标签,以便地址和个人资料标签都标记为“红色”。以类似的方式。

有人可以就最佳方式提出建议吗?

1 个答案:

答案 0 :(得分: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