1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
|
"""
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',
]
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"
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)
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, form_style, 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, form_style, context,
template_pack=template_pack)
)
buttons = render_to_string(template, {
'buttongroup': self,
'field_list': field_list,
})
return buttons
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'
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
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'
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
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'
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
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)
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK):
context['button_content'] = self.content
return super(ButtonElement, self).render(form, form_style, context,
template_pack)
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'
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'
|