Source code for crispy_forms_foundation.layout.buttons
"""
References
* `Foundation 6 Button <https://get.foundation/sites/docs/button.html>`_;
* `Foundation 6 Button Group <https://get.foundation/sites/docs/button-group.html>`_;
""" # noqa: E501
from django.template.loader import render_to_string
from crispy_forms.utils import render_field, TEMPLATE_PACK
from crispy_forms import layout as crispy_forms_layout
__all__ = [
'ButtonHolder', 'ButtonHolderCallout', 'ButtonGroup',
'Button', 'Submit', 'Reset',
'InputButton', 'InputSubmit', 'InputReset',
'ButtonElement', 'ButtonSubmit', 'ButtonReset',
]
[docs]class ButtonHolder(crispy_forms_layout.ButtonHolder):
"""
It wraps fields in an element ``<div class="button-holder">``.
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:
.. code-block:: python
ButtonHolder(
HTML(<span style="display: hidden;">Information Saved</span>),
Submit('Save', 'Save')
)
"""
template = "%s/layout/buttonholder.html"
[docs]class ButtonHolderCallout(ButtonHolder):
"""
Act like ``ButtonHolder`` but add a ``callout`` class name on the main
``div``.
"""
def __init__(self, field, *args, **kwargs):
kwargs['css_class'] = kwargs.get('css_class', '')+' callout'
super().__init__(field, *args, **kwargs)
[docs]class ButtonGroup(crispy_forms_layout.LayoutObject):
"""
It wraps fields in an element ``<div class="button-group">``.
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:
.. code-block:: python
ButtonGroup(
Submit('Save', 'Save'),
Button('Cancel', 'Cancel'),
)
"""
template = "%s/layout/buttongroup.html"
def __init__(self, *fields, **kwargs):
self.fields = list(fields)
self.css_class = kwargs.get('css_class', None)
self.css_id = kwargs.get('css_id', None)
self.template = kwargs.get('template', self.template)
def render(self, form, context, template_pack=TEMPLATE_PACK):
field_list = []
template = self.get_template_name(template_pack)
for field in self.fields:
field_list.append(
render_field(field, form, context,
template_pack=template_pack)
)
buttons = render_to_string(template, {
'buttongroup': self,
'field_list': field_list,
})
return buttons
[docs]class InputButton(crispy_forms_layout.BaseInput):
"""
Used to create a Submit input descriptor for the {% crispy %} template tag:
.. code-block:: python
button = InputButton('Button 1', 'Press Me!')
.. note:: The first argument is also slugified and turned into the id for
the button.
"""
input_type = 'button'
field_classes = 'button'
[docs]class Button(InputButton):
"""
This is the old Button object that inherit from ``InputButton`` for
backward compatibility.
If you want to stand for an input button, you are invited to use
``InputButton`` instead to avoid problem when ``ButtonElement`` will
become the new ``Button`` object.
"""
pass
[docs]class InputSubmit(crispy_forms_layout.BaseInput):
"""
Used to create a Submit button descriptor for the {% crispy %} template
tag:
.. code-block:: python
submit = Submit('Search the Site', 'search this site')
"""
input_type = 'submit'
field_classes = 'submit button'
[docs]class Submit(InputSubmit):
"""
This is the old Button object that inherit from ``InputSubmit`` for
backward compatibility.
If you want to stand for an input button, you are invited to use
``InputSubmit`` instead to avoid problem when ``ButtonSubmit`` will
become the new ``Submit`` object.
"""
pass
[docs]class InputReset(crispy_forms_layout.BaseInput):
"""
Used to create a Reset button input descriptor for the ``{% crispy %}``
template tag:
.. code-block:: python
reset = Reset('Reset This Form', 'Revert Me!')
"""
input_type = 'reset'
field_classes = 'reset button'
[docs]class Reset(InputReset):
"""
This is the old Button object that inherit from ``InputReset`` for
backward compatibility.
If you want to stand for an input button, you are invited to use
``InputReset`` instead to avoid problem when ``ButtonReset`` will
become the new ``Reset`` object.
"""
pass
[docs]class ButtonElement(crispy_forms_layout.BaseInput):
"""
Contrary to ``Button``, ButtonElement purpose use a ``<button>`` element
to create a clickable form button and accept an argument to add free
content inside element.
Advantage of ``<button>`` is to accept almost any HTML content inside
element.
.. code-block:: python
button = ButtonElement('name', 'value',
content="<span>Press Me!</span>")
.. note::
* First argument is for ``name`` attribute and also turned into
the id for the button;
* Second argument is for ``value`` attribute and also for element
content if not given;
* Third argument is an optional named argument ``content``, if
given it will be appended inside element instead of ``value``.
Content string is marked as safe so you can put anything you
want;
"""
template = "%s/layout/basebutton.html"
input_type = 'button'
field_classes = 'button'
def __init__(self, field, *args, **kwargs):
self.content = kwargs.pop('content', None)
super(ButtonElement, self).__init__(field, *args, **kwargs)
[docs] def render(self, form, context, template_pack=TEMPLATE_PACK):
context['button_content'] = self.content
return super(ButtonElement, self).render(form, context,
template_pack)
[docs]class ButtonSubmit(ButtonElement):
"""
Create a submit button following the ``ButtonElement`` behaviors:
.. code-block:: python
button = ButtonSubmit('search', 'go-search',
content="<span>Search this site!</span>")
"""
input_type = 'submit'
field_classes = 'submit button'
[docs]class ButtonReset(ButtonElement):
"""
Create a reset button following the ``ButtonElement`` behaviors:
.. code-block:: python
button = ButtonReset('reset', 'revert'
content="<span>Revert Me!</span>")
"""
input_type = 'reset'
field_classes = 'reset button'