python - Django Nested Tab Form -
i have created template recursively build nested tab pages of form/s. each tab page can contain form, or tab page, n levels deep.
this created via view, ordered dictionary (form_dict
) passed via context. in file forms/snippets/form_dict.html form_dict
iterated over, , either renders form (forms/snippets/form_standalone.html) or calls again, if node contains ordered dictionary, code has been provided below:
forms/snippets/form_dict.html
{% load sekizai_tags %} {% if form_dict %} {% if not level or not tier %} {% include "forms/snippets/form_dict.html" form_dict=form_dict level='tab' tier='0' %} {% else %} {% tier=tier|add:1 %} <ul class="nav nav-tabs nav-tabs-{{tier}}" {%ifequal tier 0 %}id="mytab"{% endifequal %}> {% key,form in form_dict.items %} {% counter=forloop.counter|stringformat:"s" %} {% 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}}"> {% k,v in form_dict.items %} {% counter=forloop.counter|stringformat:"s" %} {% 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" form_dict=v level=newlevel tier=tier %} {% else %} {% include "forms/snippets/form_standalone.html" 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 %}
everything works expected, except when error detected @ submission, want change colour of tabs reflect form under tab has problem validating. in below code:
<a href="#{{newlevel}}" data-toggle="tab" {% if form.errors %}class="has-error"{% endif %}>{{key}}</a>
this has effect of identifying tab (see image below), however, highlights leaf tab -- want assign same class parent tabs well
in above, errors have been identified in both billing , shipping addresses, red highlighting persist upline parent tabs too, both addresses , profile tabs marked 'red' in similar fashion.
can offer suggestion on best way this?
not sure if best solution, works:
i overloaded ordereddict, create property errors
, can called if form.
class myordereddict(ordereddict): def __init(self): super(ordereddict,self).__init__() @property def errors(self): return any([v.errors if hasattr(v,'errors') else false k,v in self.items()])
so in views.py, heirachy build this, instance:
#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)
this produces desired output, meaning no matter tab user has focus, he/she can readily identify tabs need investigated upon unsuccessful submission.
Comments
Post a Comment