o
    em                     @   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	 d dl
mZ d dlmZ d dlmZmZmZ eG d	d
 d
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 ).    )	dataclass)List)Template)render_to_string)conditional_escape)
SafeString)slugify)TEMPLATE_PACKflatattrender_fieldc                   @   s"   e Zd ZU ee ed< eed< dS )Pointer	positionsnameN)__name__
__module____qualname__r   int__annotations__str r   r   T/var/www/html/humari/django-venv/lib/python3.10/site-packages/crispy_forms/layout.pyr      s   
 r   c                   @   s   e Zd Zdd ZdS )TemplateNameMixinc                 C   s"   d| j v r| j | }|S | j }|S )Nz%s)template)selftemplate_packr   r   r   r   get_template_name   s
   

z#TemplateNameMixin.get_template_nameN)r   r   r   r   r   r   r   r   r      s    r   c                   @   s\   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ddddZ	e
fddZdS )LayoutObjectc                 C   s
   | j | S Nfieldsr   slicer   r   r   __getitem__      
zLayoutObject.__getitem__c                 C   s   || j |< d S r   r   )r   r!   valuer   r   r   __setitem__!      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__'   r#   zLayoutObject.__len__c                 C   s.   d| j v rt| j|rt| j|S t| |S )z
        This allows us to access self.fields list methods like append or insert, without
        having to declare them one by one
        r   )__dict__hasattrr   getattrobject__getattribute__)r   r   r   r   r   __getattr__*   s   zLayoutObject.__getattr__Nc                 C   s   | j tdddS )a  
        Returns a list of Pointers. First parameter is the location of the
        field, second one the name of the field. Example::

            [
                Pointer([0,1,2], 'field_name1'),
                Pointer([0,3], 'field_name2'),
            ]
        NT)indexgreedy)get_layout_objectsr   )r   r0   r   r   r   get_field_names5   s   
zLayoutObject.get_field_namesr   Fr0   	max_levelr1   c          
      G   s   g }|durt |ts|g}n|du rg }t|dko |d tk}t| jD ]F\}}t ||rL|r=|t||g | n|t||g |jj	
  t|drlt||k sY|rl||g ||d}	||j|i |	 }q&|S )a  
        Returns a list of Pointers pointing to layout objects of any type matching
        `LayoutClasses`::

            [
                Pointer([0,1,2], 'div']),
                Pointer([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.
        N   r   r3   r4   )
isinstancelistr(   r   	enumerater   appendr   	__class__r   lowerr+   r2   )
r   r0   r5   r1   LayoutClassespointers	str_classilayout_object
new_kwargsr   r   r   r2   A   s    
zLayoutObject.get_layout_objectsc                    s$   t 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kwargsr   r   r   	<genexpr>i   s   & z3LayoutObject.get_rendered_fields.<locals>.<genexpr>)r   joinr   r   rH   rG   r   rI   r   rF   r   get_rendered_fieldsg   s   z LayoutObject.get_rendered_fieldsr   )r   r   r   r"   r%   r'   r)   r/   r3   r2   r	   rM   r   r   r   r   r      s    
&r   c                   @   $   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   )r8   r   )r   r   r   r   r   __init__   r&   zLayout.__init__c                 K   s   | j |||fi |S r   )rM   rL   r   r   r   render   s   zLayout.renderNr   r   r   __doc__rP   r	   rQ   r   r   r   r   rO   m   s    rO   c                   @   2   e Zd ZdZdZddddddZefddZdS )	ButtonHolderag  
    Layout object. It wraps fields in a <div class="buttonHolder">

    This is where you should put Layout objects that render to form buttons

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.

    Parameters
    ----------
    *fields : HTML or BaseInput
        The layout objects to render within the ``ButtonHolder``. It should
        only hold `HTML` and `BaseInput` inherited objects.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    template : str, optional
        Overrides the default template, if provided. By default None.

    Examples
    --------

    An example using ``ButtonHolder`` in your layout::

        ButtonHolder(
            HTML(<span style="display: hidden;">Information Saved</span>),
            Submit('Save', 'Save')
        )
    z%s/layout/buttonholder.htmlNcss_id	css_classr   c                G   s&   t || _|| _|| _|p| j| _d S r   )r8   r   rW   rX   r   )r   rW   rX   r   r   r   r   r   rP      s   
zButtonHolder.__init__c                 K   s>   | j |||fi |}| |}|| |d t|| S )N)buttonholderfields_output)rM   r   updater   flatten)r   rH   rG   r   rI   htmlr   r   r   r   rQ      s   
zButtonHolder.renderr   r   r   rS   r   rP   r	   rQ   r   r   r   r   rU      s
    %rU   c                   @   s6   e Zd ZdZdZdZddddddZefdd	ZdS )
	BaseInputa  
    A base class to reduce the amount of code in the Input classes.

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.
    field_classes: str
        CSS classes to be applied to the ``<input>``.

    Parameters
    ----------
    name : str
        The name attribute of the button.
    value : str
        The value attribute of the button.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to `flatatt` and converted into
        key="value", pairs. These attributes are added to the ``<input>``.
    z%s/layout/baseinput.htmlrC   NrV   c                K   sl   || _ || _|r|| _nt| j }| j d| | _i | _|r)|  jd| 7  _|p-| j| _t|| _	d S )Nz-id- )
r   r$   idr   
input_typeattrsfield_classesr   r
   
flat_attrs)r   r   r$   rW   rX   r   rI   slugr   r   r   rP      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$   rQ   r   r[   r   r\   )r   rH   rG   r   rI   r   r   r   r   rQ      s   
zBaseInput.render)	r   r   r   rS   r   rd   rP   r	   rQ   r   r   r   r   r_      s    r_   c                   @      e Zd ZdZdZdZdS )Submita  
    Used to create a Submit button descriptor for the {% crispy %} template tag.

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.
    field_classes: str
        CSS classes to be applied to the ``<input>``.
    input_type: str
        The ``type`` attribute of the ``<input>``.

    Parameters
    ----------
    name : str
        The name attribute of the button.
    value : str
        The value attribute of the button.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to `flatatt` and converted into
        key="value", pairs. These attributes are added to the ``<input>``.

    Examples
    --------
    Note: ``form`` arg to ``render()`` is not required for ``BaseInput``
    inherited objects.

    >>> submit = Submit('Search the Site', 'search this site')
    >>> submit.render("", "", Context())
    '<input type="submit" name="search-the-site" value="search this site" '
    'class="btn btn-primary" id="submit-id-search-the-site"/>'

    >>> submit = Submit('Search the Site', 'search this site', css_id="custom-id",
                         css_class="custom class", my_attr=True, data="my-data")
    >>> submit.render("", "", Context())
    '<input type="submit" name="search-the-site" value="search this site" '
    'class="btn btn-primary custom class" id="custom-id" data="my-data" my-attr/>'

    Usually you will not call the render method on the object directly. Instead
    add it to your ``Layout`` manually or use the `add_input` method::

        class ExampleForm(forms.Form):
        [...]
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.helper = FormHelper()
            self.helper.add_input(Submit('submit', 'Submit'))
    submitzbtn btn-primaryNr   r   r   rS   rb   rd   r   r   r   r   ri         ;ri   c                   @   rh   )Buttonai  
    Used to create a button descriptor for the {% crispy %} template tag.

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.
    field_classes: str
        CSS classes to be applied to the ``<input>``.
    input_type: str
        The ``type`` attribute of the ``<input>``.

    Parameters
    ----------
    name : str
        The name attribute of the button.
    value : str
        The value attribute of the button.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to `flatatt` and converted into
        key="value", pairs. These attributes are added to the ``<input>``.

    Examples
    --------
    Note: ``form`` arg to ``render()`` is not required for ``BaseInput``
    inherited objects.

    >>> button = Button('Button 1', 'Press Me!')
    >>> button.render("", "", Context())
    '<input type="button" name="button-1" value="Press Me!" '
    'class="btn" id="button-id-button-1"/>'

    >>> button = Button('Button 1', 'Press Me!', css_id="custom-id",
                         css_class="custom class", my_attr=True, data="my-data")
    >>> button.render("", "", Context())
    '<input type="button" name="button-1" value="Press Me!" '
    'class="btn custom class" id="custom-id" data="my-data" my-attr/>'

    Usually you will not call the render method on the object directly. Instead
    add it to your ``Layout`` manually or use the `add_input` method::

        class ExampleForm(forms.Form):
        [...]
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.helper = FormHelper()
            self.helper.add_input(Button('Button 1', 'Press Me!'))
    buttonbtnNrk   r   r   r   r   rm   G  rl   rm   c                   @   s   e Zd ZdZdZdZdS )Hiddena  
    Used to create a Hidden input descriptor for the {% crispy %} template tag.

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.
    field_classes: str
        CSS classes to be applied to the ``<input>``.
    input_type: str
        The ``type`` attribute of the ``<input>``.

    Parameters
    ----------
    name : str
        The name attribute of the button.
    value : str
        The value attribute of the button.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to `flatatt` and converted into
        key="value", pairs. These attributes are added to the ``<input>``.

    Examples
    --------
    Note: ``form`` arg to ``render()`` is not required for ``BaseInput``
    inherited objects.

    >>> hidden = Hidden("hidden", "hide-me")
    >>> hidden.render("", "", Context())
    '<input type="hidden" name="hidden" value="hide-me"/>'

    Usually you will not call the render method on the object directly. Instead
    add it to your ``Layout`` manually or use the `add_input` method::

        class ExampleForm(forms.Form):
        [...]
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.helper = FormHelper()
            self.helper.add_input(Hidden("hidden", "hide-me"))
    hiddenNrk   r   r   r   r   rp     s    4rp   c                   @   rh   )Reseta  
    Used to create a reset button descriptor for the {% crispy %} template tag.

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.
    field_classes: str
        CSS classes to be applied to the ``<input>``.
    input_type: str
        The ``type`` attribute of the ``<input>``.

    Parameters
    ----------
    name : str
        The name attribute of the button.
    value : str
        The value attribute of the button.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to `flatatt` and converted into
        key="value", pairs. These attributes are added to the ``<input>``.

    Examples
    --------
    Note: ``form`` arg to ``render()`` is not required for ``BaseInput``
    inherited objects.

    >>> reset = Reset('Reset This Form', 'Revert Me!')
    >>> reset.render("", "", Context())
    '<input type="reset" name="reset-this-form" value="Revert Me!" '
    'class="btn btn-inverse" id="reset-id-reset-this-form"/>'

    >>> reset = Reset('Reset This Form', 'Revert Me!', css_id="custom-id",
                         css_class="custom class", my_attr=True, data="my-data")
    >>> reset.render("", "", Context())
    '<input type="reset" name="reset-this-form" value="Revert Me!" '
    'class="btn btn-inverse custom class" id="custom-id" data="my-data" my-attr/>'

    Usually you will not call the render method on the object directly. Instead
    add it to your ``Layout`` manually manually or use the `add_input` method::

        class ExampleForm(forms.Form):
        [...]
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.helper = FormHelper()
            self.helper.add_input(Reset('Reset This Form', 'Revert Me!'))
    resetzbtn btn-inverseNrk   r   r   r   r   rr     rl   rr   c                   @   rT   )	Fieldseta  
    A layout object which wraps fields in a ``<fieldset>``

    Parameters
    ----------
    legend : str
        The content of the fieldset's ``<legend>``. This text is context
        aware, to bring this to life see the examples section.
    *fields : str | LayoutObject | HTML
        Any number of fields as positional arguments to be rendered within
        the ``<fieldset>``
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to ``flatatt`` and converted into
        key="value", pairs. These attributes are added to the ``<fieldset>``.

    Examples
    --------

    The Fieldset Layout object is added to your ``Layout`` for example::

        Fieldset("Text for the legend",
            "form_field_1",
            "form_field_2",
            css_id="my-fieldset-id",
            css_class="my-fieldset-class",
            data="my-data"
        )

    The above layout will be rendered as::

        '''
        <fieldset id="fieldset-id" class="my-fieldset-class" data="my-data">
           <legend>Text for the legend</legend>
           # form fields render here
        </fieldset>
        '''

    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.htmlN)rX   rW   r   c                O   s6   t || _|| _|| _|| _|p| j| _t|| _d S r   )r8   r   legendrX   rW   r   r
   re   )r   ru   rX   rW   r   r   rI   r   r   r   rP   :  s   
zFieldset.__init__c                 K   sV   | j |||fi |}| jrtt| j|}ntd}| |}t|| ||dS )NrC   )fieldsetru   r   )rM   ru   r   r   rQ   r   r   r   )r   rH   rG   r   rI   r   ru   r   r   r   r   rQ   B  s   
zFieldset.renderr^   r   r   r   r   rt      s
    7rt   c                   @   s<   e Zd ZdZdZdZdddddddddZefdd	ZdS )

MultiFielda  
    MultiField container for Bootstrap3. Renders to a MultiField <div>.

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.
    field_template: str
        The template which fields will be rendered with.

    Parameters
    ----------
    label: str
        The label for the multifield.
    *fields: str
        The fields to be rendered within the multifield.
    label_class: str, optional
        CSS classes to be added to the multifield label. By default None.
    help_text: str, optional
        Help text will be available in the context of the multifield template.
        This is unused in the bootstrap3 template provided. By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    css_id : str, optional
        A DOM id for the layout object which will be added to the wrapping
        ``<div>`` if provided. By default None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    field_template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to ``flatatt`` and converted into
        key="value", pairs. These attributes are added to the wrapping
        ``<div>``.

    z%s/layout/multifield.htmlz%s/multifield.htmlN)label_class	help_textrX   rW   r   field_templatec          
      O   sV   t || _|| _|pd| _|pd| _|| _|| _|p| j| _|p"| j| _t	|	| _
d S )N
blockLabel
ctrlHolder)r8   r   
label_htmlrx   rX   rW   ry   r   rz   r
   re   )
r   labelrx   ry   rX   rW   r   rz   r   rI   r   r   r   rP   y  s   


zMultiField.__init__c           	      K   s   |d rdd |   D D ]}||jv r|  jd7  _q| j| }| j|||f|| j| d|}| |}|| |d t||	 S )Nform_show_errorsc                 s   s    | ]}|j V  qd S r   )r   )rD   pointerr   r   r   rJ     s    z$MultiField.render.<locals>.<genexpr>z error)r   
labelclassrA   )
multifieldrZ   )
r3   errorsrX   rz   rM   rx   r   r[   r   r\   )	r   rH   rG   r   rI   rE   rz   rZ   r   r   r   r   rQ     s(   



zMultiField.render)	r   r   r   rS   r   rz   rP   r	   rQ   r   r   r   r   rw   N  s    'rw   c                   @   s6   e Zd ZdZdZdZddddddZefddZdS )	Diva  
    Layout object. It wraps fields in a ``<div>``.

    Attributes
    ----------
    template : str
        The default template which this Layout Object will be rendered
        with.
    css_class : str, optional
        CSS classes to be applied to the ``<div>``. By default None.

    Parameters
    ----------
    *fields : str, LayoutObject
        Any number of fields as positional arguments to be rendered within
        the ``<div>``.
    css_id : str, optional
        A DOM id for the layout object which will be added to the ``<div>`` if
        provided. By default None.
    css_class : str, optional
        Additional CSS classes to be applied in addition to those declared by
        the class itself. By default None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to ``flatatt`` and converted into
        key="value", pairs. These attributes are added to the ``<div>``.

    Examples
    --------

    In your ``Layout`` you can::

        Div(
            'form_field_1',
            'form_field_2',
            css_id='div-example',
            css_class='divs',
        )

    It is also possible to nest Layout Objects within a Div::

        Div(
            Div(
                Field('form_field', css_class='field-class'),
                css_class='div-class',
            ),
            Div('form_field_2', css_class='div-class'),
        )
    z%s/layout/div.htmlNrV   c                O   sT   t || _| jr|r|  jd| 7  _n|r|| _|| _|p!| j| _t|| _d S )Nr`   )r8   r   rX   rW   r   r
   re   )r   rW   rX   r   r   rI   r   r   r   rP     s   

zDiv.__init__c                 K   s0   | j |||fi |}| |}t|| |dS )N)divr   )rM   r   r   )r   rH   rG   r   rI   r   r   r   r   r   rQ     s   
z
Div.render)	r   r   r   rS   r   rX   rP   r	   rQ   r   r   r   r   r     s    3r   c                   @      e Zd ZdZdZdS )Rowa  
    Layout object. It wraps fields in a ``<div>`` and the template adds the
    appropriate class to render the contents in a row. e.g. ``form-row`` when
    using the Bootstrap4 template pack.

    Attributes
    ----------
    template : str
        The default template which this Layout Object will be rendered
        with.
    css_class : str, optional
        CSS classes to be applied to the ``<div>``. By default None.

    Parameters
    ----------
    *fields : str, LayoutObject
        Any number of fields as positional arguments to be rendered within
        the ``<div>``.
    css_id : str, optional
        A DOM id for the layout object which will be added to the ``<div>`` if
        provided. By default None.
    css_class : str, optional
        Additional CSS classes to be applied in addition to those declared by
        the class itself. By default None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to ``flatatt`` and converted into
        key="value", pairs. These attributes are added to the ``<div>``.

    Examples
    --------

    In your ``Layout`` you can::

        Row('form_field_1', 'form_field_2', css_id='row-example')

    It is also possible to nest Layout Objects within a Row::

        Row(
            Div(
                Field('form_field', css_class='field-class'),
                css_class='div-class',
            ),
            Div('form_field_2', css_class='div-class'),
        )
    z%s/layout/row.htmlNr   r   r   rS   r   r   r   r   r   r     s    0r   c                   @   r   )Columna  
    Layout object. It wraps fields in a ``<div>`` and the template adds the
    appropriate class to render the contents in a column. e.g. ``col-md`` when
    using the Bootstrap4 template pack.

    Attributes
    ----------
    template : str
        The default template which this Layout Object will be rendered
        with.
    css_class : str, optional
        CSS classes to be applied to the ``<div>``. By default None.

    Parameters
    ----------
    *fields : str, LayoutObject
        Any number of fields as positional arguments to be rendered within
        the ``<div>``.
    css_id : str, optional
        A DOM id for the layout object which will be added to the ``<div>`` if
        provided. By default None.
    css_class : str, optional
        Additional CSS classes to be applied in addition to those declared by
        the class itself. If using the Bootstrap4 template pack the default
        ``col-md`` is removed if this string contins another ``col-`` class.
        By default None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to ``flatatt`` and converted into
        key="value", pairs. These attributes are added to the ``<div>``.

    Examples
    --------

    In your ``Layout`` you can::

        Column('form_field_1', 'form_field_2', css_id='col-example')

    It is also possible to nest Layout Objects within a Row::

        Div(
            Column(
                Field('form_field', css_class='field-class'),
                css_class='col-sm,
            ),
            Column('form_field_2', css_class='col-sm'),
        )
    z%s/layout/column.htmlNr   r   r   r   r   r   %  s    2r   c                   @   rN   )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   )r]   )r   r]   r   r   r   rP   f  r#   zHTML.__init__c                 K   s   t t| j|S r   )r   r   r]   rQ   rL   r   r   r   rQ   i  s   zHTML.renderNrR   r   r   r   r   r   [  s    
r   c                   @   s8   e Zd ZdZdZi ZddddddZedfddZdS )	Fielda  
    A Layout object, usually containing one field name, where you can add
    attributes to it easily.

    Attributes
    ----------
    template : str
        The default template which this Layout Object will be rendered
        with.
    attrs : dict
        Attributes to be applied to the field. These are converted into html
        attributes. e.g. ``data_id: 'test'`` in the attrs dict will become
        ``data-id='test'`` on the field's ``<input>``.

    Parameters
    ----------
    *fields : str
        Usually a single field, but can be any number of fields, to be rendered
        with the same attributes applied.
    css_class : str, optional
        CSS classes to be applied to the field. These are added to any classes
        included in the ``attrs`` dict. By default ``None``.
    wrapper_class: str, optional
        CSS classes to be used when rendering the Field. This class is usually
        applied to the ``<div>`` which wraps the Field's ``<label>`` and
        ``<input>`` tags. By default ``None``.
    template : str, optional
        Overrides the default template, if provided. By default ``None``.
    **kwargs : dict, optional
        Additional attributes are converted into key="value", pairs. These
        attributes are added to the ``<div>``.

    Examples
    --------

    Example::

        Field('field_name', style="color: #333;", css_class="whatever", id="field_name")
    z%s/field.htmlN)rX   wrapper_classr   c                O   sx   t || _| j | _|r$d| jv r| jd  d| 7  < n|| jd< || _|p+| j| _| jdd | D  d S )Nclassr`   c                 S   s"   i | ]\}}| d dt|qS )_-)replacer   )rD   kvr   r   r   
<dictcomp>  s   " z"Field.__init__.<locals>.<dictcomp>)r8   r   rc   copyr   r   r[   items)r   rX   r   r   r   rI   r   r   r   rP     s   


zField.__init__c                 K   sF   |d u ri }| j r| j |d< | |}| j|||f|| j|d|S )Nr   )r   rc   extra_context)r   r   rM   rc   )r   rH   rG   r   r   rI   r   r   r   r   rQ     s    

zField.render)	r   r   r   rS   r   rc   rP   r	   rQ   r   r   r   r   r   m  s    (r   c                   @   s"   e Zd ZdZdddd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.

    Attributes
    ----------
    template : str
        The default template which this Layout Object will be rendered
        with.

    Parameters
    ----------
    *fields : str
        Usually a single field, but can be any number of fields, to be rendered
        with the same attributes applied.
    attrs : str, optional
        Additional attrs to be added to each widget. These are added to any
        classes included in the ``attrs`` dict. By default ``None``.
    wrapper_class: str, optional
        CSS classes to be used when rendering the Field. This class is usually
        applied to the ``<div>`` which wraps the Field's ``<label>`` and
        ``<input>`` tags. By default ``None``.
    template : str, optional
        Overrides the default template, if provided. By default ``None``.

    Examples
    --------

    Example::

        MultiWidgetField(
            'multiwidget_field_name',
            attrs=(
                {'style': 'width: 30px;'},
                {'class': 'second_widget_class'}
            ),
        )
    N)rc   r   r   c                G   s*   t || _|pi | _|p| j| _|| _d S r   )r8   r   rc   r   r   )r   rc   r   r   r   r   r   r   rP     s   


zMultiWidgetField.__init__)r   r   r   rS   rP   r   r   r   r   r     s    'r   N)$dataclassesr   typingr   django.templater   django.template.loaderr   django.utils.htmlr   django.utils.safestringr   django.utils.textr   crispy_forms.utilsr	   r
   r   r   r   r   rO   rU   r_   ri   rm   rp   rr   rt   rw   r   r   r   r   r   r   r   r   r   r   <module>   s6    
P$7?@@9@NYJ46P