U
    }Ha??  ã                   @   sL  d dl mZ d dlmZ d dlmZ d dlmZmZm	Z	m
Z
 G dd„ dƒZG dd„ deƒZG d	d
„ d
eƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd „ d eƒZG d!d"„ d"ƒZG d#d$„ d$eƒZG d%d&„ d&eƒZd'S )(é    )ÚTemplate)Úrender_to_string)Úconditional_escape)Ú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 )Nú%s)Útemplate)ÚselfÚtemplate_packr   © r   ú7/tmp/pip-unpacked-wheel-rp2i33ek/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                   @   sR   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
f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 r   r   )r   r   Úvaluer   r   r   Ú__setitem__   s    zLayoutObject.__setitem__c                 C   s   | j |= d S r   r   r   r   r   r   Ú__delitem__   s    zLayoutObject.__delitem__c                 C   s
   t | jƒS r   )Úlenr   )r   r   r   r   Ú__len__   s    zLayoutObject.__len__c                 C   s2   d| j kr"t| j|ƒr"t| j|ƒS t | |¡S d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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']
            ]
        NT)ÚindexÚgreedy)Úget_layout_objectsÚstr)r   r'   r   r   r   Úget_field_names*   s    
zLayoutObject.get_field_namesc           
      O   sö   |  dd¡}|  dd¡}|  dd¡}g }|dk	rBt|tƒsB|g}n|dkrNg }t| jƒD ]˜\}}t||ƒr´t|ƒdkr˜|d tkr˜| ||g |g¡ n| ||g |jj	 
¡ g¡ t|dƒrXt|ƒ|k sÎ|rX||g ||d	œ}	||j||	Ž }qX|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+   )r'   r,   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)   6   s"    
zLayoutObject.get_layout_objectsc                    s"   d  ‡ ‡‡‡‡fdd„| jD ƒ¡S )NÚ c                 3   s(   | ] }t |ˆˆˆ fd ˆiˆ—ŽV  qdS )r   N)r   )Ú.0Úfield©ÚcontextÚformÚ
form_styler5   r   r   r   Ú	<genexpr>`   s   ÿz3LayoutObject.get_rendered_fields.<locals>.<genexpr>)Újoinr   ©r   r=   r>   r<   r   r5   r   r;   r   Úget_rendered_fields_   s    þz LayoutObject.get_rendered_fields)N)r   r   r   r   r   r   r   r&   r+   r)   r   rB   r   r   r   r   r      s   
)r   c                   @   s$   e Zd ZdZdd„ Zef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 r   )r0   r   )r   r   r   r   r   Ú__init__ƒ   s    zLayout.__init__c                 K   s   | j ||||f|ŽS r   )rB   rA   r   r   r   Úrender†   s    zLayout.renderN©r   r   r   Ú__doc__rD   r   rE   r   r   r   r   rC   f   s   rC   c                   @   s(   e Zd ZdZdZdd„ Zef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   s:   t |ƒ| _| dd ¡| _| dd ¡| _| d| j¡| _d S )NÚ	css_classÚcss_idr   )r0   r   ÚgetrI   rJ   r   ©r   r   r5   r   r   r   rD   ›   s    
zButtonHolder.__init__c                 K   s<   | j ||||f|Ž}|  |¡}| | |dœ¡ t|| ¡ ƒS )N)ZbuttonholderÚfields_output)rB   r   Úupdater   Úflatten)r   r=   r>   r<   r   r5   Úhtmlr   r   r   r   rE   ¡   s    
zButtonHolder.renderN©r   r   r   rG   r   rD   r   rE   r   r   r   r   rH   Š   s   rH   c                   @   s(   e Zd ZdZdZdd„ Zef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^   || _ || _| dd¡| _i | _d|kr@|  jd| d¡ 7  _| d| j¡| _t|ƒ| _d S )NrJ   r8   rI   ú %sr   )	r%   r   r.   ÚidÚattrsÚfield_classesr   r   Ú
flat_attrs)r   r%   r   r5   r   r   r   rD   ±   s    zBaseInput.__init__c                 K   s<   t t| jƒƒ |¡| _|  |¡}| d| i¡ t|| ¡ ƒ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   rE   r   rN   r   rO   )r   r=   r>   r<   r   r5   r   r   r   r   rE   ½   s    
zBaseInput.renderNrQ   r   r   r   r   rR   ª   s   rR   c                       s$   e Zd ZdZdZ‡ fdd„Z‡  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ƒ j||Ž d S )NÚuni_formzsubmit submitButtonzbtn btn-primary©r   rV   ÚsuperrD   ©r   Úargsr5   ©r3   r   r   rD   Ô   s    zSubmit.__init__©r   r   r   rG   Ú
input_typerD   Ú__classcell__r   r   r_   r   rY   É   s   rY   c                       s$   e Zd ZdZdZ‡ fdd„Z‡  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ƒ j||Ž d S )NrZ   rd   Zbtnr[   r]   r_   r   r   rD   ä   s    zButton.__init__r`   r   r   r_   r   rc   Ù   s   rc   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   rG   ra   rV   r   r   r   r   re   é   s   re   c                       s$   e Zd ZdZdZ‡ fdd„Z‡  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ƒ j||Ž d S )NrZ   zreset resetButtonzbtn btn-inverser[   r]   r_   r   r   rD   ý   s    zReset.__init__r`   r   r   r_   r   rg   ò   s   rg   c                   @   s(   e Zd ZdZdZdd„ Zef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   sJ   t |ƒ| _|| _| dd¡| _| dd ¡| _| d| j¡| _t|ƒ| _d S )NrI   r8   rJ   r   )	r0   r   Úlegendr.   rI   rJ   r   r   rW   )r   rj   r   r5   r   r   r   rD     s    
zFieldset.__init__c           	      K   sT   | j ||||f|Ž}d}| jr6dtt| jƒƒ |¡ }|  |¡}t|| |||dœƒS )Nr8   r
   )Úfieldsetrj   r   r>   )rB   rj   r   r*   rE   r   r   )	r   r=   r>   r<   r   r5   r   rj   r   r   r   r   rE      s    
 ÿzFieldset.renderNrQ   r   r   r   r   ri     s   ri   c                   @   s,   e Zd ZdZdZdZdd„ Zefdd„ZdS )	Ú
MultiFieldz3MultiField container. Renders to a MultiField <div>z%s/layout/multifield.htmlz%s/multifield.htmlc                 O   sv   t |ƒ| _|| _| dd¡| _| dd¡| _| dd ¡| _| dd ¡| _| d| j¡| _| d| j	¡| _	t
|ƒ| _d S )	NÚlabel_classZ
blockLabelrI   Z
ctrlHolderrJ   Ú	help_textr   Úfield_template)r0   r   Z
label_htmlr.   rm   rI   rJ   rn   r   ro   r   rW   )r   Úlabelr   r5   r   r   r   rD   3  s    
zMultiField.__init__c           
      K   sŒ   |d r8t dd„ |  ¡ ƒD ]}||jkr|  jd7  _q| j| }| j||||f|| j| dœ|—Ž}|  |¡}	| | |dœ¡ t	|	| 
¡ ƒS )NZform_show_errorsc                 S   s   | d S )Nr-   r   )Úpointerr   r   r   Ú<lambda>A  ó    z#MultiField.render.<locals>.<lambda>z error)r   Z
labelclassr7   )Z
multifieldrM   )Úmapr+   ÚerrorsrI   ro   rB   rm   r   rN   r   rO   )
r   r=   r>   r<   r   r5   r:   ro   rM   r   r   r   r   rE   >  s(    

üùø
zMultiField.renderN)	r   r   r   rG   r   ro   rD   r   rE   r   r   r   r   rl   -  s
   rl   c                   @   s(   e Zd ZdZdZdd„ Zef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   sx   t |ƒ| _t| dƒr4d|kr4|  jd| d¡ 7  _t| dƒsL| dd ¡| _| dd¡| _| d| j¡| _t|ƒ| _d S )NrI   rS   rJ   r8   r   )	r0   r   r!   rI   r.   rJ   r   r   rW   rL   r   r   r   rD   b  s    

zDiv.__init__c                 K   s.   | j ||||f|Ž}|  |¡}t|| |dœƒS )N)Údivr   )rB   r   r   )r   r=   r>   r<   r   r5   r   r   r   r   r   rE   n  s    
z
Div.renderNrQ   r   r   r   r   rv   W  s   rv   c                   @   s   e Zd ZdZdZd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')
    z%s/layout/row.htmlN©r   r   r   rG   r   r   r   r   r   rx   u  s   rx   c                   @   s   e Zd ZdZdZdS )ÚColumna{  
    Layout object. It wraps fields in a div so the wrapper can be used as a column. Example::

        Column('form_field_1', 'form_field_2')

    Depending on the template, css class associated to the div is formColumn, row, or nothing. For this last case, you
     must provide css classes. Example::

        Column('form_field_1', 'form_field_2', css_class='col-xs-6',)
    z%s/layout/column.htmlNry   r   r   r   r   rz     s   rz   c                   @   s$   e Zd ZdZdd„ Zef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 r   )rP   )r   rP   r   r   r   rD   ™  s    zHTML.__init__c                 K   s   t t| jƒƒ |¡S r   )r   r*   rP   rE   rA   r   r   r   rE   œ  s    zHTML.renderNrF   r   r   r   r   r{   Ž  s   
r{   c                   @   s*   e Zd ZdZdZdd„ Zedf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 ¡ | _d|krhd| jkrX| jd  d| d¡ 7  < n| d¡| jd< | dd ¡| _| d| j¡| _| j dd„ | 	¡ D ƒ¡ d S )	NrU   rI   ÚclassrS   Úwrapper_classr   c                 S   s"   i | ]\}}|  d d¡t|ƒ“qS )Ú_ú-)Úreplacer   )r9   ÚkÚvr   r   r   Ú
<dictcomp>¿  s     
 z"Field.__init__.<locals>.<dictcomp>)
r0   r   r!   rU   Úcopyr.   r~   r   rN   Úitemsr]   r   r   r   rD   ¬  s    


zField.__init__Nc                 K   sL   |d kri }t | dƒr | j|d< |  |¡}| j||||f|| j|dœ|—ŽS )Nr~   )r   rU   Úextra_context)r!   r~   r   rB   rU   )r   r=   r>   r<   r   r‡   r5   r   r   r   r   rE   Á  s"    


üùøzField.renderrQ   r   r   r   r   r|      s   	r|   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   s:   t |ƒ| _| di ¡| _| d| j¡| _| dd ¡| _d S )NrU   r   r~   )r0   r   r.   rU   r   r~   r]   r   r   r   rD   ç  s    
zMultiWidgetField.__init__N)r   r   r   rG   rD   r   r   r   r   rˆ   Õ  s   rˆ   N)Zdjango.templater   Zdjango.template.loaderr   Zdjango.utils.htmlr   Zcrispy_forms.utilsr   r   r   r   r	   r   rC   rH   rR   rY   rc   re   rg   ri   rl   rv   rx   rz   r{   r|   rˆ   r   r   r   r   Ú<module>   s(   
T$ 	+*
5