
^Q\C?                 @   s  d  d l  m Z d  d l m Z d  d l m Z d  d l m Z d  d l m	 Z	 m
 Z
 d  d l m Z m Z m Z m Z Gd d   d e  Z Gd	 d
   d
 e  Z Gd d   d e  Z Gd d   d e  Z Gd d   d e  Z Gd d   d e  Z Gd d   d e  Z Gd d   d e  Z Gd d   d e  Z Gd d   d e  Z Gd d   d e  Z Gd d   d e  Z Gd d    d  e  Z Gd! d"   d" e  Z Gd# d$   d$ e  Z Gd% d&   d& e  Z  Gd' d(   d( e   Z! d) S)*    )unicode_literals)Template)render_to_string)conditional_escape)string_types	text_type)TEMPLATE_PACKflatattget_template_packrender_fieldc               @   s   e  Z d  Z d d   Z d S)TemplateNameMixinc             C   s,   d |  j  k r |  j  | } n	 |  j  } | S)Nz%s)template)selftemplate_packr    r   F/var/www/dbchiro/venv/build/django-crispy-forms/crispy_forms/layout.pyget_template_name   s    	z#TemplateNameMixin.get_template_nameN)__name__
__module____qualname__r   r   r   r   r   r      s   r   c               @   sv   e  Z d  Z d d   Z d d   Z d d   Z d d   Z d	 d
   Z d d d  Z d d   Z	 e
 d d  Z d S)LayoutObjectc             C   s   |  j  | S)N)fields)r   slicer   r   r   __getitem__   s    zLayoutObject.__getitem__c             C   s   | |  j  | <d  S)N)r   )r   r   valuer   r   r   __setitem__   s    zLayoutObject.__setitem__c             C   s   |  j  | =d  S)N)r   )r   r   r   r   r   __delitem__   s    zLayoutObject.__delitem__c             C   s   t  |  j  S)N)lenr   )r   r   r   r   __len__"   s    zLayoutObject.__len__c             C   sE   d |  j  k r1 t |  j |  r1 t |  j |  St j |  |  Sd S)z
        This allows us to access self.fields list methods like append or insert, without
        having to declare them one by one
        r   N)__dict__hasattrr   getattrobject__getattribute__)r   namer   r   r   __getattr__%   s    !zLayoutObject.__getattr__Nc             C   s   |  j  t d d d d S)a  
        Returns a list of lists, those lists are named pointers. First parameter
        is the location of the field, second one the name of the field. Example::

            [
                [[0,1,2], 'field_name1'],
                [[0,3], 'field_name2']
            ]
        indexNgreedyT)get_layout_objectsr   )r   r&   r   r   r   get_field_names0   s    
zLayoutObject.get_field_namesc       
      O   sv  | j  d d  } | j  d d  } | j  d d  } g  } | d k	 rd t | t  rd | g } n | d k ry g  } n  x t |  j  D] \ } } t | |  rt |  d k r | d t k r | j | | g | g  q| j | | g | j j	 j
   g  n  t | d  r t |  | k  s3| r i | | g d 6| d 6| d 6}	 | | j | |	   } q q W| S)	a  
        Returns a list of lists pointing to layout objects of any type matching
        `LayoutClasses`::

            [
                [[0,1,2], 'div'],
                [[0,3], 'field_name']
            ]

        :param max_level: An integer that indicates max level depth to reach when
        traversing a layout.
        :param greedy: Boolean that indicates whether to be greedy. If set, max_level
        is skipped.
        r&   N	max_levelr   r'   F   r)   )pop
isinstancelist	enumerater   r   r   append	__class__r   lowerr    r(   )
r   ZLayoutClasseskwargsr&   r*   r'   Zpointersilayout_objectZ
new_kwargsr   r   r   r(   <   s"    	")'"zLayoutObject.get_layout_objectsc                s/   d j        f d d   |  j D  S)N c          	   3   s-   |  ]# } t  |     d    Vq d S)r   N)r   ).0field)contextform
form_styler3   r   r   r   	<genexpr>g   s   z3LayoutObject.get_rendered_fields.<locals>.<genexpr>)joinr   )r   r:   r;   r9   r   r3   r   )r9   r:   r;   r3   r   r   get_rendered_fieldse   s    z LayoutObject.get_rendered_fields)r   r   r   r   r   r   r   r%   r)   r(   r   r>   r   r   r   r   r      s   )r   c               @   s1   e  Z d  Z d Z d d   Z e d d  Z d S)Layouta  
    Form Layout. It is conformed by Layout objects: `Fieldset`, `Row`, `Column`, `MultiField`,
    `HTML`, `ButtonHolder`, `Button`, `Hidden`, `Reset`, `Submit` and fields. Form fields
    have to be strings.
    Layout objects `Fieldset`, `Row`, `Column`, `MultiField` and `ButtonHolder` can hold other
    Layout objects within. Though `ButtonHolder` should only hold `HTML` and BaseInput
    inherited classes: `Button`, `Hidden`, `Reset` and `Submit`.

    Example::

        helper.layout = Layout(
            Fieldset('Company data',
                'is_company'
            ),
            Fieldset(_('Contact details'),
                'email',
                Row('password1', 'password2'),
                'first_name',
                'last_name',
                HTML('<img src="/media/somepicture.jpg"/>'),
                'company'
            ),
            ButtonHolder(
                Submit('Save', 'Save', css_class='button white'),
            ),
        )
    c             G   s   t  |  |  _ d  S)N)r.   r   )r   r   r   r   r   __init__   s    zLayout.__init__c             K   s   |  j  | | | | |  S)N)r>   )r   r:   r;   r9   r   r3   r   r   r   render   s    zLayout.renderN)r   r   r   __doc__r@   r   rA   r   r   r   r   r?   l   s   r?   c               @   s7   e  Z d  Z d Z d Z d d   Z e d d  Z d S)ButtonHoldera  
    Layout object. It wraps fields in a <div class="buttonHolder">

    This is where you should put Layout objects that render to form buttons like Submit.
    It should only hold `HTML` and `BaseInput` inherited objects.

    Example::

        ButtonHolder(
            HTML(<span style="display: hidden;">Information Saved</span>),
            Submit('Save', 'Save')
        )
    z%s/layout/buttonholder.htmlc             O   sU   t  |  |  _ | j d d   |  _ | j d d   |  _ | j d |  j  |  _ d  S)N	css_classcss_idr   )r.   r   getrD   rE   r   )r   r   r3   r   r   r   r@      s    zButtonHolder.__init__c             K   sX   |  j  | | | | |  } |  j |  } | j i |  d 6| d 6 t | | j    S)NZbuttonholderfields_output)r>   r   updater   flatten)r   r:   r;   r9   r   r3   htmlr   r   r   r   rA      s    zButtonHolder.renderN)r   r   r   rB   r   r@   r   rA   r   r   r   r   rC      s   rC   c               @   s7   e  Z d  Z d Z d Z d d   Z e d d  Z d S)	BaseInputzI
    A base class to reduce the amount of code in the Input classes.
    z%s/layout/baseinput.htmlc             K   s   | |  _  | |  _ | j d d  |  _ i  |  _ d | k r[ |  j d | j d  7_ n  | j d |  j  |  _ t |  |  _ d  S)NrE   r6   rD   z %sr   )	r$   r   r,   idattrsfield_classesr   r	   
flat_attrs)r   r$   r   r3   r   r   r   r@      s    			zBaseInput.__init__c             K   sW   t  t |  j   j |  |  _ |  j |  } | j i |  d 6 t | | j    S)z
        Renders an `<input />` if container is used as a Layout object.
        Input button value can be a variable in context.
        input)r   r   r   rA   r   rH   r   rI   )r   r:   r;   r9   r   r3   r   r   r   r   rA      s    !zBaseInput.renderN)r   r   r   rB   r   r@   r   rA   r   r   r   r   rK      s   rK   c                   s.   e  Z d  Z d Z d Z   f d d   Z   S)Submitz
    Used to create a Submit button descriptor for the {% crispy %} template tag::

        submit = Submit('Search the Site', 'search this site')

    .. note:: The first argument is also slugified and turned into the id for the submit button.
    Zsubmitc                s;   t    d k r d n d |  _ t t |   j | |   d  S)Nuni_formzsubmit submitButtonzbtn btn-primary)r
   rN   superrQ   r@   )r   argsr3   )r1   r   r   r@      s    zSubmit.__init__)r   r   r   rB   
input_typer@   r   r   )r1   r   rQ      s   rQ   c                   s.   e  Z d  Z d Z d Z   f d d   Z   S)Buttonz
    Used to create a Submit input descriptor for the {% crispy %} template tag::

        button = Button('Button 1', 'Press Me!')

    .. note:: The first argument is also slugified and turned into the id for the button.
    buttonc                s;   t    d k r d n d |  _ t t |   j | |   d  S)NrR   rW   Zbtn)r
   rN   rS   rV   r@   )r   rT   r3   )r1   r   r   r@      s    zButton.__init__)r   r   r   rB   rU   r@   r   r   )r1   r   rV      s   rV   c               @   s"   e  Z d  Z d Z d Z d Z d S)HiddenzU
    Used to create a Hidden input descriptor for the {% crispy %} template tag.
    hiddenN)r   r   r   rB   rU   rN   r   r   r   r   rX      s   rX   c                   s.   e  Z d  Z d Z d Z   f d d   Z   S)Resetz
    Used to create a Reset button input descriptor for the {% crispy %} template tag::

        reset = Reset('Reset This Form', 'Revert Me!')

    .. note:: The first argument is also slugified and turned into the id for the reset.
    resetc                s;   t    d k r d n d |  _ t t |   j | |   d  S)NrR   zreset resetButtonzbtn btn-inverse)r
   rN   rS   rZ   r@   )r   rT   r3   )r1   r   r   r@      s    zReset.__init__)r   r   r   rB   rU   r@   r   r   )r1   r   rZ      s   rZ   c               @   s7   e  Z d  Z d Z d Z d d   Z e d d  Z d S)Fieldseta  
    Layout object. It wraps fields in a <fieldset>

    Example::

        Fieldset("Text for the legend",
            'form_field_1',
            'form_field_2'
        )

    The first parameter is the text for the fieldset legend. This text is context aware,
    so you can do things like::

        Fieldset("Data for {{ user.username }}",
            'form_field_1',
            'form_field_2'
        )
    z%s/layout/fieldset.htmlc             O   sm   t  |  |  _ | |  _ | j d d  |  _ | j d d   |  _ | j d |  j  |  _ t |  |  _ d  S)NrD   r6   rE   r   )	r.   r   legendr,   rD   rE   r   r	   rO   )r   r]   r   r3   r   r   r   r@     s    	zFieldset.__init__c       	      K   s   |  j  | | | | |  } d } |  j rO d t t |  j   j |  } n  |  j |  } t | i |  d 6| d 6| d 6| d 6 S)Nr6   z%sfieldsetr]   r   r;   )r>   r]   r   r   rA   r   r   )	r   r:   r;   r9   r   r3   r   r]   r   r   r   r   rA     s    	%zFieldset.renderN)r   r   r   rB   r   r@   r   rA   r   r   r   r   r\     s   r\   c               @   s=   e  Z d  Z d Z d Z d Z d d   Z e d d  Z d S)	
MultiFieldz5 MultiField container. Renders to a MultiField <div> z%s/layout/multifield.htmlz%s/multifield.htmlc             O   s   t  |  |  _ | |  _ | j d d  |  _ | j d d  |  _ | j d d   |  _ | j d d   |  _ | j d |  j  |  _ | j d |  j	  |  _	 t
 |  |  _ d  S)	Nlabel_classZ
blockLabelrD   Z
ctrlHolderrE   	help_textr   field_template)r.   r   Z
label_htmlr,   r`   rD   rE   ra   r   rb   r	   rO   )r   labelr   r3   r   r   r   r@   1  s    	zMultiField.__init__c       
      K   s   | d rT xG t  d d   |  j    D]' } | | j k r& |  j d 7_ q& q& Wn  |  j | } |  j | | | | d | d |  j d |  | } |  j |  }	 | j i |  d 6| d	 6 t	 |	 | j
    S)
NZform_show_errorsc             S   s   |  d S)Nr+   r   )pointerr   r   r   <lambda>?  s    z#MultiField.render.<locals>.<lambda>z errorr   Z
labelclassr5   Z
multifieldrG   )mapr)   errorsrD   rb   r>   r`   r   rH   r   rI   )
r   r:   r;   r9   r   r3   r8   rb   rG   r   r   r   r   rA   <  s    
"	zMultiField.renderN)	r   r   r   rB   r   rb   r@   r   rA   r   r   r   r   r_   ,  s
   r_   c               @   s7   e  Z d  Z d Z d Z d d   Z e d d  Z d S)Divz
    Layout object. It wraps fields in a <div>

    You can set `css_id` for a DOM id and `css_class` for a DOM class. Example::

        Div('form_field_1', 'form_field_2', css_id='div-example', css_class='divs')
    z%s/layout/div.htmlc             O   s   t  |  |  _ t |  d  rI d | k rI |  j d | j d  7_ n  t |  d  sp | j d d   |  _ n  | j d d  |  _ | j d |  j  |  _ t |  |  _ d  S)NrD   z %srE   r6   r   )	r.   r   r    rD   r,   rE   r   r	   rO   )r   r   r3   r   r   r   r@   \  s    zDiv.__init__c             K   sE   |  j  | | | | |  } |  j |  } t | i |  d 6| d 6 S)Ndivr   )r>   r   r   )r   r:   r;   r9   r   r3   r   r   r   r   r   rA   h  s    z
Div.renderN)r   r   r   rB   r   r@   r   rA   r   r   r   r   rh   R  s   rh   c                   s(   e  Z d  Z d Z   f d d   Z   S)Rowz
    Layout object. It wraps fields in a div whose default class is "formRow". Example::

        Row('form_field_1', 'form_field_2', 'form_field_3')
    c                s;   t    d k r d n d |  _ t t |   j | |   d  S)NrR   ZformRowrow)r
   rD   rS   rj   r@   )r   rT   r3   )r1   r   r   r@   v  s    zRow.__init__)r   r   r   rB   r@   r   r   )r1   r   rj   o  s   rj   c               @   s   e  Z d  Z d Z d Z d S)Columnz
    Layout object. It wraps fields in a div whose default class is "formColumn". Example::

        Column('form_field_1', 'form_field_2')
    Z
formColumnN)r   r   r   rB   rD   r   r   r   r   rl   {  s   rl   c               @   s1   e  Z d  Z d Z d d   Z e d d  Z d S)HTMLa#  
    Layout object. It can contain pure HTML and it has access to the whole
    context of the page where the form is being rendered.

    Examples::

        HTML("{% if saved %}Data saved{% endif %}")
        HTML('<input type="hidden" name="{{ step_field }}" value="{{ step0 }}" />')
    c             C   s   | |  _  d  S)N)rJ   )r   rJ   r   r   r   r@     s    zHTML.__init__c             K   s   t  t |  j   j |  S)N)r   r   rJ   rA   )r   r:   r;   r9   r   r3   r   r   r   rA     s    zHTML.renderN)r   r   r   rB   r@   r   rA   r   r   r   r   rm     s   	rm   c               @   s:   e  Z d  Z d Z d Z d d   Z e d d d  Z d S)Fielda%  
    Layout object, It contains one field name, and you can add attributes to it easily.
    For setting class attributes, you need to use `css_class`, as `class` is a Python keyword.

    Example::

        Field('field_name', style="color: #333;", css_class="whatever", id="field_name")
    z%s/field.htmlc             O   s   t  |  |  _ t |  d  s* i  |  _ n |  j j   |  _ d | k r d |  j k rx |  j d d | j d  7<q | j d  |  j d <n  | j d d   |  _ | j d |  j  |  _ |  j j t	 d d   | j
   D   d  S)	NrM   rD   classz %swrapper_classr   c             S   s4   g  |  ]* \ } } | j  d  d  t |  f  q S)_-)replacer   )r7   kvr   r   r   
<listcomp>  s   	 z"Field.__init__.<locals>.<listcomp>)r.   r   r    rM   copyr,   rp   r   rH   dictitems)r   rT   r3   r   r   r   r@     s    !zField.__init__Nc             K   sq   | d  k r i  } n  t  |  d  r4 |  j | d <n  |  j |  } |  j | | | | d | d |  j d | | S)Nrp   r   rM   extra_context)r    rp   r   r>   rM   )r   r:   r;   r9   r   rz   r3   r   r   r   r   rA     s    	zField.render)r   r   r   rB   r   r@   r   rA   r   r   r   r   rn     s   rn   c               @   s"   e  Z d  Z d Z d d   Z d S)MultiWidgetFielda  
    Layout object. For fields with :class:`~django.forms.MultiWidget` as `widget`, you can pass
    additional attributes to each widget.

    Example::

        MultiWidgetField(
            'multiwidget_field_name',
            attrs=(
                {'style': 'width: 30px;'},
                {'class': 'second_widget_class'}
            ),
        )

    .. note:: To override widget's css class use ``class`` not ``css_class``.
    c             O   sU   t  |  |  _ | j d i   |  _ | j d |  j  |  _ | j d d   |  _ d  S)NrM   r   rp   )r.   r   r,   rM   r   rp   )r   rT   r3   r   r   r   r@     s    zMultiWidgetField.__init__N)r   r   r   rB   r@   r   r   r   r   r{     s   r{   N)"
__future__r   Zdjango.templater   Zdjango.template.loaderr   Zdjango.utils.htmlr   Zcrispy_forms.compatibilityr   r   Zcrispy_forms.utilsr   r	   r
   r   r"   r   r   r?   rC   rK   rQ   rV   rX   rZ   r\   r_   rh   rj   rl   rm   rn   r{   r   r   r   r   <module>   s,   "T#+&	/