prepare 0.9; get_form_field_instances accepts two new optional two new optional arguments: form_entry and form_element_entries as well as **kwargs; minor fix in form wizards - forms in intermediate steps do receive updates from the submit_plugin_form_data of the plugins; fixed issue in the base_bulk_change_plugins function on django 1.10

This commit is contained in:
Artur Barseghyan 2016-10-24 01:09:13 +02:00
parent 586d61a21d
commit d0bbe214ae
68 changed files with 595 additions and 226 deletions

View file

@ -15,6 +15,23 @@ are used for versioning (schema follows below):
0.3.4 to 0.4).
- All backwards incompatible changes are mentioned in this document.
0.9
---
2016-10-24
Note, that this release contain minor backwards incompatible changes, that
may break your existing code (your data is left intact). If you have written
custom form element plugins you should update your code!
- The :method:`get_form_field_instances`
and :method:`_get_form_field_instances` of
the :class:`fobi.base.FormElementPlugin` both accept two new optional
arguments: `form_entry` and `form_element_entries` as well as **kwargs.
Make sure to update your custom plugins if you have written any.
- Minor fixes in the form wizards: forms in intermediate steps do receive
updates from the `submit_plugin_form_data` of the plugins.
- Fixed issue in the `base_bulk_change_plugins` function on Django 1.10.
0.8.10
------
2016-10-22

View file

@ -89,7 +89,7 @@ Roadmap
=======
Some of the upcoming/in-development features/improvements are:
- Integration with `django-rest-framework` (in version 0.9).
- Integration with `django-rest-framework` (in version 0.10).
See the `TODOS <https://raw.githubusercontent.com/barseghyanartur/django-fobi/master/TODOS.rst>`_
for the full list of planned-, pending- in-development- or to-be-implemented

View file

@ -1,7 +1,7 @@
Roadmap of upcoming releases
============================
0.9
---
0.10
----
yyyy-mm-ddd (upcoming).
This release contains minor backwards incompatible changes, related to the

View file

@ -36,7 +36,7 @@ Regarding the form wizards
issue in "Uncategorised".
- Rethink the new navigation of forms and form wizards.
- Add support for form wizard conditions.
- Fixed broken dependencies for docs.
+ Fixed broken dependencies for docs.
Roadmap
-------

View file

@ -21,12 +21,13 @@ class RadioInputPlugin(FormFieldPlugin):
group = _("Fields")
form = RadioInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
choices = get_select_field_choices(self.data.choices)
widget_attrs = {'class': theme.form_radio_element_html_class}
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -35,7 +36,7 @@ class RadioInputPlugin(FormFieldPlugin):
'widget': RadioSelect(attrs=widget_attrs),
}
return [(self.data.name, ChoiceField, kwargs)]
return [(self.data.name, ChoiceField, field_kwargs)]
def submit_plugin_form_data(self, form_entry, request, form):
"""Submit plugin form data/process.

View file

@ -22,13 +22,14 @@ class SelectModelObjectInputPlugin(FormFieldPlugin):
group = _("Fields")
form = SelectModelObjectInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
app_label, model_name = self.data.model.split('.')
model = models.get_model(app_label, model_name)
queryset = model._default_manager.all()
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -37,7 +38,7 @@ class SelectModelObjectInputPlugin(FormFieldPlugin):
'widget': Select(attrs={'class': theme.form_element_html_class}),
}
return [(self.data.name, ModelChoiceField, kwargs)]
return [(self.data.name, ModelChoiceField, field_kwargs)]
def submit_plugin_form_data(self, form_entry, request, form):
"""Submit plugin form data/process.

View file

@ -1,10 +1,15 @@
from fobi.constants import CALLBACK_FORM_VALID
from fobi.base import FormCallback, form_callback_registry
class SampleFooCallback(FormCallback):
"""SampleFooCallback."""
stage = CALLBACK_FORM_VALID
def callback(self, form_entry, request, form):
"""Callback."""
print("Great! Your form is valid!")
form_callback_registry.register(SampleFooCallback)

View file

@ -2,14 +2,17 @@ from fobi.base import form_element_plugin_widget_registry
from sample_textarea.widgets import BaseSampleTextareaPluginWidget
class SampleTextareaPluginWidget(BaseSampleTextareaPluginWidget):
theme_uid = 'sample_layout' # Theme for which the widget is loaded
"""SampleTextareaPluginWidget."""
theme_uid = 'sample_layout' # Theme for which the widget is loaded
media_js = [
'sample_layout/js/fobi.plugins.form_elements.sample_textarea.js',
]
]
media_css = [
'sample_layout/css/fobi.plugins.form_elements.sample_textarea.css',
]
]
form_element_plugin_widget_registry.register(SampleTextareaPluginWidget)

View file

@ -6,7 +6,10 @@ from fobi.base import FormHandlerPlugin, form_handler_plugin_registry
from sample_mail.forms import SampleMailForm
class SampleMailHandlerPlugin(FormHandlerPlugin):
"""SampleMailHandlerPlugin."""
uid = "sample_mail"
name = _("Sample mail")
form = SampleMailForm
@ -17,14 +20,13 @@ class SampleMailHandlerPlugin(FormHandlerPlugin):
json.dumps(form.cleaned_data),
self.data.from_email,
[self.data.to_email],
fail_silently = True
)
fail_silently=True
)
def plugin_data_repr(self):
"""
Human readable representation of plugin data.
"""Human readable representation of plugin data.
:return string:
:return str:
"""
return self.data.__dict__

View file

@ -1,23 +1,28 @@
from django import forms
from fobi.base import FormFieldPlugin, form_element_plugin_registry
from sample_textarea.forms import SampleTextareaForm
from .forms import SampleTextareaForm
class SampleTextareaPlugin(FormFieldPlugin):
"""SampleTextareaPlugin."""
uid = "sample_textarea"
name = "Sample Textarea"
form = SampleTextareaForm
group = "Samples" # Group to which the plugin belongs to
group = "Samples" # Group to which the plugin belongs to
def get_form_field_instances(self, request=None):
kwargs = {
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
field_kwargs = {
'required': self.data.required,
'label': self.data.label,
'initial': self.data.initial,
'widget': forms.widgets.Textarea(attrs={})
'widget': forms.widgets.Textarea(attrs={})
}
return [(self.data.name, forms.CharField, kwargs),]
return [(self.data.name, forms.CharField, field_kwargs)]
form_element_plugin_registry.register(SampleTextareaPlugin)

View file

@ -2,7 +2,10 @@ from django import forms
from fobi.base import BasePluginForm
class SampleTextareaForm(forms.Form, BasePluginForm):
"""SampleTextareaForm."""
plugin_data_fields = [
("name", ""),
("label", ""),

View file

@ -1,6 +1,8 @@
from fobi.base import FormElementPluginWidget
class BaseSampleTextareaPluginWidget(FormElementPluginWidget):
"""BaseSampleTextareaPluginWidget."""
# Same as ``uid`` value of the ``SampleTextareaPlugin``.
plugin_uid = "sample_textarea"

View file

@ -204,7 +204,7 @@ for locale_dir in locale_dirs:
for f
in os.listdir(locale_dir)]
version = '0.8.10'
version = '0.9'
install_requires = []
# If certain version of Django is already installed, choose version agnostic

View file

@ -1,6 +1,6 @@
__title__ = 'django-fobi'
__version__ = '0.8.10'
__build__ = 0x000061
__version__ = '0.9'
__build__ = 0x000062
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'

View file

@ -3,13 +3,13 @@ from django.contrib import admin
from django.contrib import messages
from django.contrib.admin import helpers
from django.contrib.admin.views.decorators import staff_member_required
from django.shortcuts import render_to_response, redirect
from django.shortcuts import redirect
from django.template import RequestContext
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext_lazy as _
from django.utils.html import strip_tags
from nine.versions import DJANGO_LTE_1_5
from nine import versions
from .constants import ACTION_CHOICE_REPLACE
from .forms import (
@ -32,6 +32,11 @@ from .models import (
FormWizardHandlerEntry
)
if versions.DJANGO_GTE_1_10:
from django.shortcuts import render
else:
from django.shortcuts import render_to_response
__title__ = 'fobi.admin'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
@ -97,11 +102,15 @@ def base_bulk_change_plugins(PluginForm, named_url, modeladmin, request,
'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
'named_url': named_url,
}
return render_to_response(
'fobi/admin/bulk_change_plugins.html',
context,
context_instance=RequestContext(request)
)
template_name = 'fobi/admin/bulk_change_plugins.html'
if versions.DJANGO_GTE_1_10:
return render(request, template_name, context)
else:
return render_to_response(
template_name, context, context_instance=RequestContext(request)
)
def bulk_change_form_element_plugins(modeladmin, request, queryset):
@ -321,7 +330,7 @@ class FormElementEntryAdmin(admin.ModelAdmin):
def __queryset(self, request):
"""Internal method used in get_queryset or queryset methods."""
if DJANGO_LTE_1_5:
if versions.DJANGO_LTE_1_5:
queryset = super(FormElementEntryAdmin, self).queryset(request)
else:
queryset = super(FormElementEntryAdmin, self).get_queryset(request)
@ -329,7 +338,7 @@ class FormElementEntryAdmin(admin.ModelAdmin):
queryset = queryset.select_related('form_entry', 'form_fieldset_entry')
return queryset
get_queryset = __queryset
if DJANGO_LTE_1_5:
if versions.DJANGO_LTE_1_5:
queryset = __queryset
# admin.site.register(FormElementEntry, FormElementEntryAdmin)
@ -361,7 +370,7 @@ class FormHandlerEntryAdmin(admin.ModelAdmin):
def __queryset(self, request):
"""Internal method used in get_queryset or queryset methods."""
if DJANGO_LTE_1_5:
if versions.DJANGO_LTE_1_5:
queryset = super(FormHandlerEntryAdmin, self).queryset(request)
else:
queryset = super(FormHandlerEntryAdmin, self).get_queryset(request)
@ -369,7 +378,7 @@ class FormHandlerEntryAdmin(admin.ModelAdmin):
queryset = queryset.select_related('form_entry',)
return queryset
get_queryset = __queryset
if DJANGO_LTE_1_5:
if versions.DJANGO_LTE_1_5:
queryset = __queryset
# admin.site.register(FormHandlerEntry, FormHandlerEntryAdmin)
@ -412,7 +421,7 @@ class BasePluginModelAdmin(admin.ModelAdmin):
def __queryset(self, request):
"""Internal method used in get_queryset or queryset methods."""
if DJANGO_LTE_1_5:
if versions.DJANGO_LTE_1_5:
queryset = super(BasePluginModelAdmin, self).queryset(request)
else:
queryset = super(BasePluginModelAdmin, self).get_queryset(request)
@ -420,7 +429,7 @@ class BasePluginModelAdmin(admin.ModelAdmin):
queryset = queryset.prefetch_related('users', 'groups')
return queryset
get_queryset = __queryset
if DJANGO_LTE_1_5:
if versions.DJANGO_LTE_1_5:
queryset = __queryset
def _get_bulk_change_form_class(self):

View file

@ -1356,7 +1356,8 @@ class FormElementPlugin(BasePlugin):
def _get_form_field_instances(self, form_element_entry=None, origin=None,
kwargs_update_func=None, return_func=None,
extra={}, request=None):
extra={}, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances (internal method).
Used internally. Do not override this method. Gets the instances of
@ -1366,6 +1367,11 @@ class FormElementPlugin(BasePlugin):
:param string origin:
:param callable kwargs_update_func:
:param callable return_func:
:param dict extra:
:param django.http.HttpRequest request:
:param fobi.models.FormEntry form_entry:
:param django.db.models.QuerySet form_element_entries: Queryset of
:class:`fobi.models.FormElementEntry` instances.
:return list: List of Django form field instances.
"""
# For the moment, this piece of code has to be present here.
@ -1380,12 +1386,18 @@ class FormElementPlugin(BasePlugin):
# goes wrong. Otherwise - skip the element.
if DEBUG:
form_field_instances = self.get_form_field_instances(
request=request
request=request,
form_entry=form_entry,
form_element_entries=form_element_entries,
**kwargs
)
else:
try:
form_field_instances = self.get_form_field_instances(
request=request
request=request,
form_entry=form_entry,
form_element_entries=form_element_entries,
**kwargs
)
except AttributeError as e:
return []
@ -1462,10 +1474,14 @@ class FormElementPlugin(BasePlugin):
return processed_field_instances
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get the instances of form fields, that plugin contains.
:param django.http.HttpRequest request:
:param fobi.models.FormEntry form_entry:
:param django.db.models.QuerySet form_element_entries: Queryset of
:class:`fobi.models.FormElementEntry` instances.
:return list: List of Django form field instances.
:example:
@ -1530,12 +1546,17 @@ class FormElementPlugin(BasePlugin):
:param django.http.HttpRequest request:
:param django.forms.Form form:
"""
try:
if DEBUG:
return self.submit_plugin_form_data(
form_entry=form_entry, request=request, form=form
)
except Exception as e:
logger.debug(str(e))
else:
try:
return self.submit_plugin_form_data(
form_entry=form_entry, request=request, form=form
)
except Exception as e:
logger.debug(str(e))
def submit_plugin_form_data(self, form_entry, request, form):
"""Submit plugin form data.
@ -1895,6 +1916,15 @@ class BaseRegistry(object):
self._registry = {}
self._forced = []
@property
def registry(self):
"""Shortcut to self._registry."""
return self._registry
def items(self):
"""Shortcut to self._registry.items()."""
return self._registry.items()
def register(self, cls, force=False):
"""Registers the plugin in the registry.

View file

@ -55,7 +55,8 @@ class ContentImagePlugin(FormElementPlugin):
)
return self.get_cloned_plugin_data(update={'file': cloned_image})
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
width, height = self.data.size.split('x')
crop = get_crop_filter(self.data.fit_method)
@ -75,13 +76,13 @@ class ContentImagePlugin(FormElementPlugin):
}
rendered_image = render_to_string('content_image/render.html', context)
kwargs = {
field_kwargs = {
'initial': rendered_image,
'required': False,
'label': '',
}
return [(self.data.name, NoneField, kwargs)]
return [(self.data.name, NoneField, field_kwargs)]
form_element_plugin_registry.register(ContentImagePlugin)

View file

@ -33,15 +33,16 @@ class ContentTextPlugin(FormElementPlugin):
"""
self.data.name = "{0}_{1}".format(self.uid, uuid4())
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
kwargs = {
field_kwargs = {
'initial': "<p>{0}</p>".format(smart_str(self.data.text)),
'required': False,
'label': '',
}
return [(self.data.name, NoneField, kwargs)]
return [(self.data.name, NoneField, field_kwargs)]
form_element_plugin_registry.register(ContentTextPlugin)

View file

@ -34,11 +34,12 @@ class ContentVideoPlugin(FormElementPlugin):
"""
self.data.name = "{0}_{1}".format(self.uid, uuid4())
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
width, height = self.data.size.split('x')
kwargs = {
field_kwargs = {
'initial': '<div class="video-wrapper">{0}</div>'.format(
render_video(self.data.url, width, height)
),
@ -46,7 +47,7 @@ class ContentVideoPlugin(FormElementPlugin):
'label': '',
}
return [(self.data.name, NoneField, kwargs)]
return [(self.data.name, NoneField, field_kwargs)]
form_element_plugin_registry.register(ContentVideoPlugin)

View file

@ -22,16 +22,17 @@ class BooleanSelectPlugin(FormFieldPlugin):
group = _("Fields")
form = BooleanSelectForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
'required': self.data.required,
}
return [(self.data.name, BooleanField, kwargs)]
return [(self.data.name, BooleanField, field_kwargs)]
form_element_plugin_registry.register(BooleanSelectPlugin)

View file

@ -30,11 +30,12 @@ class CheckboxSelectMultipleInputPlugin(FormFieldPlugin):
group = _("Fields")
form = CheckboxSelectMultipleInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
choices = get_select_field_choices(self.data.choices)
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -45,7 +46,7 @@ class CheckboxSelectMultipleInputPlugin(FormFieldPlugin):
),
}
return [(self.data.name, MultipleChoiceField, kwargs)]
return [(self.data.name, MultipleChoiceField, field_kwargs)]
def submit_plugin_form_data(self, form_entry, request, form):
"""Submit plugin form data/process.

View file

@ -26,14 +26,15 @@ class DateInputPlugin(FormFieldPlugin):
group = _("Fields")
form = DateInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
widget_attrs = {
'class': theme.form_element_html_class,
'type': 'date',
}
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -44,7 +45,7 @@ class DateInputPlugin(FormFieldPlugin):
# if self.data.input_formats:
# kwargs['input_formats'] = self.data.input_formats
return [(self.data.name, DateField, kwargs)]
return [(self.data.name, DateField, field_kwargs)]
def submit_plugin_form_data(self, form_entry, request, form):
"""Submit plugin form data/process.

View file

@ -26,7 +26,8 @@ class DateDropDownInputPlugin(FormFieldPlugin):
group = _("Fields")
form = DateDropDownInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
widget_attrs = {
'class': theme.form_element_html_class,
@ -37,7 +38,7 @@ class DateDropDownInputPlugin(FormFieldPlugin):
if self.data.year_min and self.data.year_max:
years = range(self.data.year_min, self.data.year_max)
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -48,7 +49,7 @@ class DateDropDownInputPlugin(FormFieldPlugin):
# if self.data.input_formats:
# kwargs['input_formats'] = self.data.input_formats
return [(self.data.name, DateField, kwargs)]
return [(self.data.name, DateField, field_kwargs)]
form_element_plugin_registry.register(DateDropDownInputPlugin)

View file

@ -27,14 +27,15 @@ class DateTimeInputPlugin(FormFieldPlugin):
group = _("Fields")
form = DateTimeInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
widget_attrs = {
'class': theme.form_element_html_class,
'type': 'datetime',
}
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -45,7 +46,7 @@ class DateTimeInputPlugin(FormFieldPlugin):
# if self.data.input_formats:
# kwargs['input_formats'] = self.data.input_formats
return [(self.data.name, DateTimeField, kwargs)]
return [(self.data.name, DateTimeField, field_kwargs)]
def submit_plugin_form_data(self, form_entry, request, form):
"""Submit plugin form data/process.

View file

@ -27,36 +27,37 @@ class DecimalInputPlugin(FormFieldPlugin):
group = _("Fields")
form = DecimalInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
widget_attrs = {
'class': theme.form_element_html_class,
'type': 'number',
'placeholder': self.data.placeholder,
}
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
'required': self.data.required,
}
if self.data.max_value:
kwargs['max_value'] = self.data.max_value
field_kwargs['max_value'] = self.data.max_value
widget_attrs['max'] = self.data.max_value
if self.data.min_value:
kwargs['min_value'] = self.data.min_value
field_kwargs['min_value'] = self.data.min_value
widget_attrs['min'] = self.data.min_value
if self.data.max_digits:
kwargs['max_digits'] = self.data.max_digits
field_kwargs['max_digits'] = self.data.max_digits
widget_attrs['max'] = self.data.max_value
if self.data.decimal_places:
kwargs['decimal_places'] = self.data.decimal_places
field_kwargs['decimal_places'] = self.data.decimal_places
widget_attrs['min'] = self.data.min_value
kwargs['widget'] = NumberInput(attrs=widget_attrs)
field_kwargs['widget'] = NumberInput(attrs=widget_attrs)
return [(self.data.name, DecimalField, kwargs)]
return [(self.data.name, DecimalField, field_kwargs)]
form_element_plugin_registry.register(DecimalInputPlugin)

View file

@ -27,7 +27,8 @@ class EmailInputPlugin(FormFieldPlugin):
group = _("Fields")
form = EmailInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
widget_attrs = {
'class': theme.form_element_html_class,
@ -35,7 +36,7 @@ class EmailInputPlugin(FormFieldPlugin):
'placeholder': self.data.placeholder,
}
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -43,9 +44,9 @@ class EmailInputPlugin(FormFieldPlugin):
'widget': TextInput(attrs=widget_attrs),
}
if self.data.max_length:
kwargs['max_length'] = self.data.max_length
field_kwargs['max_length'] = self.data.max_length
return [(self.data.name, EmailField, kwargs)]
return [(self.data.name, EmailField, field_kwargs)]
# For backwards compatibility

View file

@ -27,9 +27,10 @@ class FileInputPlugin(FormFieldPlugin):
group = _("Fields")
form = FileInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -37,9 +38,9 @@ class FileInputPlugin(FormFieldPlugin):
'widget': ClearableFileInput(attrs={}),
}
if self.data.max_length:
kwargs['max_length'] = self.data.max_length
field_kwargs['max_length'] = self.data.max_length
return [(self.data.name, FileField, kwargs)]
return [(self.data.name, FileField, field_kwargs)]
def submit_plugin_form_data(self, form_entry, request, form):
"""Submit plugin form data/process file upload.

View file

@ -25,29 +25,30 @@ class FloatInputPlugin(FormFieldPlugin):
group = _("Fields")
form = FloatInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
widget_attrs = {
'class': theme.form_element_html_class,
'type': 'number',
'placeholder': self.data.placeholder,
}
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
'required': self.data.required,
}
if self.data.max_value:
kwargs['max_value'] = self.data.max_value
field_kwargs['max_value'] = self.data.max_value
widget_attrs['max'] = self.data.max_value
if self.data.min_value:
kwargs['min_value'] = self.data.min_value
field_kwargs['min_value'] = self.data.min_value
widget_attrs['min'] = self.data.min_value
kwargs['widget'] = NumberInput(attrs=widget_attrs)
field_kwargs['widget'] = NumberInput(attrs=widget_attrs)
return [(self.data.name, FloatField, kwargs)]
return [(self.data.name, FloatField, field_kwargs)]
form_element_plugin_registry.register(FloatInputPlugin)

View file

@ -26,9 +26,10 @@ class HiddenInputPlugin(FormFieldPlugin):
form = HiddenInputForm
is_hidden = True
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
kwargs = {
field_kwargs = {
'label': self.data.label,
'initial': self.data.initial,
'required': self.data.required,
@ -37,9 +38,9 @@ class HiddenInputPlugin(FormFieldPlugin):
),
}
if self.data.max_length:
kwargs['max_length'] = self.data.max_length
field_kwargs['max_length'] = self.data.max_length
return [(self.data.name, CharField, kwargs)]
return [(self.data.name, CharField, field_kwargs)]
# return [(self.data.name, (CharField, TextInput), kwargs)]

View file

@ -25,7 +25,8 @@ class InputPlugin(FormFieldPlugin):
group = _("Fields")
form = InputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
widget_attrs = {
'class': theme.form_element_html_class,
@ -71,7 +72,7 @@ class InputPlugin(FormFieldPlugin):
'reset',):
widget_attrs.update({'value': self.data.label})
kwargs = {
field_kwargs = {
'label': self.data.label
if self.data.type_value not in ('submit', 'button', 'reset',)
else '',
@ -83,7 +84,7 @@ class InputPlugin(FormFieldPlugin):
# if self.data.max_length:
# kwargs['max_length'] = self.data.max_length
return [(self.data.name, Field, kwargs)]
return [(self.data.name, Field, field_kwargs)]
form_element_plugin_registry.register(InputPlugin)

View file

@ -25,29 +25,30 @@ class IntegerInputPlugin(FormFieldPlugin):
group = _("Fields")
form = IntegerInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
widget_attrs = {
'class': theme.form_element_html_class,
'type': 'number',
'placeholder': self.data.placeholder,
}
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
'required': self.data.required,
}
if self.data.max_value:
kwargs['max_value'] = self.data.max_value
field_kwargs['max_value'] = self.data.max_value
widget_attrs['max'] = self.data.max_value
if self.data.min_value:
kwargs['min_value'] = self.data.min_value
field_kwargs['min_value'] = self.data.min_value
widget_attrs['min'] = self.data.min_value
kwargs['widget'] = NumberInput(attrs=widget_attrs)
field_kwargs['widget'] = NumberInput(attrs=widget_attrs)
return [(self.data.name, IntegerField, kwargs)]
return [(self.data.name, IntegerField, field_kwargs)]
form_element_plugin_registry.register(IntegerInputPlugin)

View file

@ -27,14 +27,15 @@ class IPAddressInputPlugin(FormFieldPlugin):
group = _("Fields")
form = IPAddressInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
widget_attrs = {
'class': theme.form_element_html_class,
'placeholder': self.data.placeholder,
}
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -42,9 +43,9 @@ class IPAddressInputPlugin(FormFieldPlugin):
'widget': TextInput(attrs=widget_attrs),
}
if self.data.max_length:
kwargs['max_length'] = self.data.max_length
field_kwargs['max_length'] = self.data.max_length
return [(self.data.name, GenericIPAddressField, kwargs)]
return [(self.data.name, GenericIPAddressField, field_kwargs)]
form_element_plugin_registry.register(IPAddressInputPlugin)

View file

@ -25,9 +25,10 @@ class NullBooleanSelectPlugin(FormFieldPlugin):
group = _("Fields")
form = NullBooleanSelectForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -37,7 +38,7 @@ class NullBooleanSelectPlugin(FormFieldPlugin):
),
}
return [(self.data.name, NullBooleanField, kwargs)]
return [(self.data.name, NullBooleanField, field_kwargs)]
form_element_plugin_registry.register(NullBooleanSelectPlugin)

View file

@ -25,14 +25,15 @@ class PasswordInputPlugin(FormFieldPlugin):
group = _("Fields")
form = PasswordInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
widget_attrs = {
'class': theme.form_element_html_class,
'placeholder': self.data.placeholder,
}
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -40,9 +41,9 @@ class PasswordInputPlugin(FormFieldPlugin):
'widget': PasswordInput(attrs=widget_attrs),
}
if self.data.max_length:
kwargs['max_length'] = self.data.max_length
field_kwargs['max_length'] = self.data.max_length
return [(self.data.name, CharField, kwargs)]
return [(self.data.name, CharField, field_kwargs)]
form_element_plugin_registry.register(PasswordInputPlugin)

View file

@ -30,12 +30,13 @@ class RadioInputPlugin(FormFieldPlugin):
group = _("Fields")
form = RadioInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
choices = get_select_field_choices(self.data.choices)
widget_attrs = {'class': theme.form_radio_element_html_class}
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -44,7 +45,7 @@ class RadioInputPlugin(FormFieldPlugin):
'widget': RadioSelect(attrs=widget_attrs),
}
return [(self.data.name, ChoiceField, kwargs)]
return [(self.data.name, ChoiceField, field_kwargs)]
def submit_plugin_form_data(self, form_entry, request, form):
"""Submit plugin form data/process.

View file

@ -2,8 +2,7 @@ from django.conf import settings
from . import defaults
__title__ = 'fobi.contrib.plugins.form_elements.fields.' \
'range_select.conf'
__title__ = 'fobi.contrib.plugins.form_elements.fields.range_select.conf'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'

View file

@ -1,5 +1,4 @@
__title__ = 'fobi.contrib.plugins.form_elements.fields.' \
'range_select.defaults'
__title__ = 'fobi.contrib.plugins.form_elements.fields.range_select.defaults'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'

View file

@ -8,8 +8,8 @@ from . import UID
from .forms import RangeSelectInputForm
from .settings import INITIAL, MAX_VALUE, MIN_VALUE, STEP
__title__ = 'fobi.contrib.plugins.form_elements.fields.' \
'range_select.fobi_form_elements'
__title__ = 'fobi.contrib.plugins.form_elements.fields.range_select.' \
'fobi_form_elements'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'
@ -19,14 +19,15 @@ theme = get_theme(request=None, as_instance=True)
class RangeSelectInputPlugin(FormFieldPlugin):
"""Percentage field plugin."""
"""Range select input plugin."""
uid = UID
name = _("Range select")
group = _("Fields")
form = RangeSelectInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
initial = self.data.initial if self.data.initial else INITIAL
max_value = self.data.max_value if self.data.max_value else MAX_VALUE
@ -36,7 +37,7 @@ class RangeSelectInputPlugin(FormFieldPlugin):
_choices = range(min_value, max_value, step)
choices = zip(_choices, _choices)
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': initial,
@ -45,7 +46,7 @@ class RangeSelectInputPlugin(FormFieldPlugin):
'widget': Select(attrs={'class': theme.form_element_html_class}),
}
return [(self.data.name, ChoiceField, kwargs)]
return [(self.data.name, ChoiceField, field_kwargs)]
form_element_plugin_registry.register(RangeSelectInputPlugin)

View file

@ -1,7 +1,6 @@
from .conf import get_setting
__title__ = 'fobi.contrib.plugins.form_elements.fields.' \
'range_select.settings'
__title__ = 'fobi.contrib.plugins.form_elements.fields.range_select.settings'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'

View file

@ -27,14 +27,15 @@ class RegexInputPlugin(FormFieldPlugin):
group = _("Fields")
form = RegexInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
widget_attrs = {
'class': theme.form_element_html_class,
'placeholder': self.data.placeholder,
}
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'regex': self.data.regex,
@ -44,9 +45,9 @@ class RegexInputPlugin(FormFieldPlugin):
}
if self.data.max_length:
kwargs['max_length'] = self.data.max_length
field_kwargs['max_length'] = self.data.max_length
return [(self.data.name, RegexField, kwargs)]
return [(self.data.name, RegexField, field_kwargs)]
form_element_plugin_registry.register(RegexInputPlugin)

View file

@ -30,11 +30,12 @@ class SelectInputPlugin(FormFieldPlugin):
group = _("Fields")
form = SelectInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
choices = get_select_field_choices(self.data.choices)
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -43,7 +44,7 @@ class SelectInputPlugin(FormFieldPlugin):
'widget': Select(attrs={'class': theme.form_element_html_class}),
}
return [(self.data.name, ChoiceField, kwargs)]
return [(self.data.name, ChoiceField, field_kwargs)]
def submit_plugin_form_data(self, form_entry, request, form):
"""Submit plugin form data/process.

View file

@ -43,13 +43,14 @@ class SelectModelObjectInputPlugin(FormFieldPlugin):
group = _("Fields")
form = SelectModelObjectInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
app_label, model_name = get_app_label_and_model_name(self.data.model)
model = get_model(app_label, model_name)
queryset = model._default_manager.all()
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -58,7 +59,7 @@ class SelectModelObjectInputPlugin(FormFieldPlugin):
'widget': Select(attrs={'class': theme.form_element_html_class}),
}
return [(self.data.name, ModelChoiceField, kwargs)]
return [(self.data.name, ModelChoiceField, field_kwargs)]
def submit_plugin_form_data(self, form_entry, request, form):
"""Submit plugin form data/process.

View file

@ -44,13 +44,14 @@ class SelectMPTTModelObjectInputPlugin(FormFieldPlugin):
group = _("Fields")
form = SelectMPTTModelObjectInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
app_label, model_name = get_app_label_and_model_name(self.data.model)
model = get_model(app_label, model_name)
queryset = model._default_manager.all()
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -59,7 +60,7 @@ class SelectMPTTModelObjectInputPlugin(FormFieldPlugin):
'widget': Select(attrs={'class': theme.form_element_html_class}),
}
return [(self.data.name, TreeNodeChoiceField, kwargs)]
return [(self.data.name, TreeNodeChoiceField, field_kwargs)]
def submit_plugin_form_data(self, form_entry, request, form):
"""Submit plugin form data/process.

View file

@ -30,11 +30,12 @@ class SelectMultipleInputPlugin(FormFieldPlugin):
group = _("Fields")
form = SelectMultipleInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
choices = get_select_field_choices(self.data.choices)
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -45,7 +46,7 @@ class SelectMultipleInputPlugin(FormFieldPlugin):
),
}
return [(self.data.name, MultipleChoiceField, kwargs)]
return [(self.data.name, MultipleChoiceField, field_kwargs)]
def submit_plugin_form_data(self, form_entry, request, form):
"""

View file

@ -44,13 +44,14 @@ class SelectMultipleModelObjectsInputPlugin(FormFieldPlugin):
group = _("Fields")
form = SelectMultipleModelObjectsInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
app_label, model_name = get_app_label_and_model_name(self.data.model)
model = get_model(app_label, model_name)
queryset = model._default_manager.all()
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -61,7 +62,7 @@ class SelectMultipleModelObjectsInputPlugin(FormFieldPlugin):
),
}
return [(self.data.name, ModelMultipleChoiceField, kwargs)]
return [(self.data.name, ModelMultipleChoiceField, field_kwargs)]
def submit_plugin_form_data(self, form_entry, request, form):
"""

View file

@ -45,13 +45,14 @@ class SelectMultipleMPTTModelObjectsInputPlugin(FormFieldPlugin):
group = _("Fields")
form = SelectMultipleMPTTModelObjectsInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
app_label, model_name = get_app_label_and_model_name(self.data.model)
model = get_model(app_label, model_name)
queryset = model._default_manager.all()
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -62,7 +63,7 @@ class SelectMultipleMPTTModelObjectsInputPlugin(FormFieldPlugin):
),
}
return [(self.data.name, TreeNodeMultipleChoiceField, kwargs)]
return [(self.data.name, TreeNodeMultipleChoiceField, field_kwargs)]
def submit_plugin_form_data(self, form_entry, request, form):
"""Submit plugin form data/process.

View file

@ -30,11 +30,12 @@ class SelectMultipleWithMaxInputPlugin(FormFieldPlugin):
group = _("Fields")
form = SelectMultipleWithMaxInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
choices = get_select_field_choices(self.data.choices)
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -46,9 +47,9 @@ class SelectMultipleWithMaxInputPlugin(FormFieldPlugin):
}
if self.data.max_choices:
kwargs['max_choices'] = self.data.max_choices
field_kwargs['max_choices'] = self.data.max_choices
return [(self.data.name, MultipleChoiceWithMaxField, kwargs)]
return [(self.data.name, MultipleChoiceWithMaxField, field_kwargs)]
def submit_plugin_form_data(self, form_entry, request, form):
"""Submit plugin form data/process.

View file

@ -2,8 +2,7 @@ from django.conf import settings
from . import defaults
__title__ = 'fobi.contrib.plugins.form_elements.fields.' \
'slider.conf'
__title__ = 'fobi.contrib.plugins.form_elements.fields.slider.conf'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'

View file

@ -1,5 +1,4 @@
__title__ = 'fobi.contrib.plugins.form_elements.fields.' \
'slider.defaults'
__title__ = 'fobi.contrib.plugins.form_elements.fields.slider.defaults'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'

View file

@ -18,8 +18,8 @@ from .constants import (
from .forms import SliderInputForm
from .settings import INITIAL, MAX_VALUE, MIN_VALUE, STEP
__title__ = 'fobi.contrib.plugins.form_elements.fields.' \
'slider_percentage.fobi_form_elements'
__title__ = 'fobi.contrib.plugins.form_elements.fields.slider.' \
'fobi_form_elements'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'
@ -37,7 +37,8 @@ class SliderInputPlugin(FormFieldPlugin):
form = SliderInputForm
html_classes = ['slider']
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
initial = self.data.initial if self.data.initial else INITIAL
max_value = self.data.max_value if self.data.max_value else MAX_VALUE
@ -150,7 +151,7 @@ class SliderInputPlugin(FormFieldPlugin):
'append_html': mark_safe(''.join(append_html_list)),
})
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': initial,
@ -159,7 +160,7 @@ class SliderInputPlugin(FormFieldPlugin):
'widget': RichSelect(**widget_kwargs),
}
return [(self.data.name, ChoiceField, kwargs)]
return [(self.data.name, ChoiceField, field_kwargs)]
form_element_plugin_registry.register(SliderInputPlugin)

View file

@ -28,11 +28,12 @@ theme = get_theme(request=None, as_instance=True)
class SliderInputForm(forms.Form, BaseFormFieldPluginForm):
"""Form for ``SliderPercentageInputPlugin``."""
"""Form for ``SliderInputPlugin``."""
plugin_data_fields = [
("label", ""),
("name", ""),
("initial", INITIAL),
("min_value", MIN_VALUE),
("max_value", MAX_VALUE),
("step", STEP),
@ -44,7 +45,6 @@ class SliderInputForm(forms.Form, BaseFormFieldPluginForm):
("label_end", ""),
# ("custom_ticks", ""),
("help_text", ""),
("initial", INITIAL),
("required", False)
]
@ -62,6 +62,16 @@ class SliderInputForm(forms.Form, BaseFormFieldPluginForm):
attrs={'class': theme.form_element_html_class}
)
)
initial = forms.IntegerField(
label=_("Initial"),
required=False,
widget=forms.widgets.TextInput(
attrs={'class': theme.form_element_html_class}
),
min_value=MIN_VALUE,
max_value=MAX_VALUE,
initial=INITIAL
)
min_value = forms.IntegerField(
label=_("Min value"),
required=True,
@ -165,16 +175,6 @@ class SliderInputForm(forms.Form, BaseFormFieldPluginForm):
attrs={'class': theme.form_element_html_class}
)
)
initial = forms.IntegerField(
label=_("Initial"),
required=False,
widget=forms.widgets.TextInput(
attrs={'class': theme.form_element_html_class}
),
min_value=MIN_VALUE,
max_value=MAX_VALUE,
initial=INITIAL
)
required = forms.BooleanField(
label=_("Required"),
required=False,

View file

@ -1,7 +1,6 @@
from .conf import get_setting
__title__ = 'fobi.contrib.plugins.form_elements.fields.' \
'slider.settings'
__title__ = 'fobi.contrib.plugins.form_elements.fields.slider.settings'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'

View file

@ -4,8 +4,7 @@ from fobi.base import FormElementPluginWidget
from . import UID
__title__ = 'fobi.contrib.plugins.form_elements.fields.slider.' \
'widgets'
__title__ = 'fobi.contrib.plugins.form_elements.fields.slider.widgets'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'

View file

@ -24,14 +24,15 @@ class SlugInputPlugin(FormFieldPlugin):
group = _("Fields")
form = SlugInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
widget_attrs = {
'class': theme.form_element_html_class,
'placeholder': self.data.placeholder,
}
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -39,9 +40,9 @@ class SlugInputPlugin(FormFieldPlugin):
'widget': TextInput(attrs=widget_attrs),
}
if self.data.max_length:
kwargs['max_length'] = self.data.max_length
field_kwargs['max_length'] = self.data.max_length
return [(self.data.name, SlugField, kwargs)]
return [(self.data.name, SlugField, field_kwargs)]
form_element_plugin_registry.register(SlugInputPlugin)

View file

@ -24,14 +24,15 @@ class TextInputPlugin(FormFieldPlugin):
group = _("Fields")
form = TextInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
widget_attrs = {
'class': theme.form_element_html_class,
'placeholder': self.data.placeholder,
}
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -39,9 +40,9 @@ class TextInputPlugin(FormFieldPlugin):
'widget': TextInput(attrs=widget_attrs),
}
if self.data.max_length:
kwargs['max_length'] = self.data.max_length
field_kwargs['max_length'] = self.data.max_length
return [(self.data.name, CharField, kwargs)]
return [(self.data.name, CharField, field_kwargs)]
form_element_plugin_registry.register(TextInputPlugin)

View file

@ -25,13 +25,14 @@ class TextareaPlugin(FormFieldPlugin):
group = _("Fields")
form = TextareaForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
widget_attrs = {
'class': theme.form_element_html_class,
'placeholder': self.data.placeholder,
}
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -39,7 +40,7 @@ class TextareaPlugin(FormFieldPlugin):
'widget': Textarea(attrs=widget_attrs)
}
return [(self.data.name, CharField, kwargs)]
return [(self.data.name, CharField, field_kwargs)]
form_element_plugin_registry.register(TextareaPlugin)

View file

@ -27,14 +27,15 @@ class TimeInputPlugin(FormFieldPlugin):
group = _("Fields")
form = TimeInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
widget_attrs = {
'class': theme.form_element_html_class,
'type': 'time',
}
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -45,7 +46,7 @@ class TimeInputPlugin(FormFieldPlugin):
# if self.data.input_formats:
# kwargs['input_formats'] = self.data.input_formats
return [(self.data.name, TimeField, kwargs)]
return [(self.data.name, TimeField, field_kwargs)]
def submit_plugin_form_data(self, form_entry, request, form):
"""Submit plugin form data/process.

View file

@ -34,7 +34,8 @@ class URLInputPlugin(FormFieldPlugin):
group = _("Fields")
form = URLInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
widget_attrs = {
'class': theme.form_element_html_class,
@ -42,7 +43,7 @@ class URLInputPlugin(FormFieldPlugin):
'placeholder': self.data.placeholder,
}
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
@ -50,9 +51,9 @@ class URLInputPlugin(FormFieldPlugin):
'widget': URLInput(attrs=widget_attrs),
}
if self.data.max_length:
kwargs['max_length'] = self.data.max_length
field_kwargs['max_length'] = self.data.max_length
return [(self.data.name, URLField, kwargs)]
return [(self.data.name, URLField, field_kwargs)]
form_element_plugin_registry.register(URLInputPlugin)

View file

@ -79,14 +79,15 @@ class CaptchaInputPlugin(FormElementPlugin):
group = _("Security")
form = CaptchaInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
widget_attrs = {
'class': theme.form_element_html_class,
# 'placeholder': self.data.placeholder,
}
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
# 'initial': self.data.initial,
@ -94,7 +95,7 @@ class CaptchaInputPlugin(FormElementPlugin):
'widget': CaptchaTextInput(attrs=widget_attrs),
}
return [(self.data.name, CaptchaField, kwargs)]
return [(self.data.name, CaptchaField, field_kwargs)]
# Register only if safe to use.

View file

@ -28,10 +28,11 @@ class HoneypotInputPlugin(FormElementPlugin):
form = HoneypotInputForm
is_hidden = True
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
kwargs = {
field_kwargs = {
'label': self.data.label,
'initial': self.data.initial,
# 'help_text': self.data.help_text,
@ -42,10 +43,10 @@ class HoneypotInputPlugin(FormElementPlugin):
}
if self.data.max_length:
kwargs['max_length'] = self.data.max_length
field_kwargs['max_length'] = self.data.max_length
# return [(self.data.name, (HoneypotField, TextInput), kwargs)]
return [(self.data.name, HoneypotField, kwargs)]
return [(self.data.name, HoneypotField, field_kwargs)]
form_element_plugin_registry.register(HoneypotInputPlugin)

View file

@ -81,14 +81,15 @@ class ReCaptchaInputPlugin(FormElementPlugin):
group = _("Security")
form = ReCaptchaInputForm
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
widget_attrs = {
'class': theme.form_element_html_class,
# 'placeholder': self.data.placeholder,
}
kwargs = {
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
# 'initial': self.data.initial,
@ -96,7 +97,7 @@ class ReCaptchaInputPlugin(FormElementPlugin):
'widget': ReCaptchaWidget(attrs=widget_attrs),
}
return [(self.data.name, ReCaptchaField, kwargs)]
return [(self.data.name, ReCaptchaField, field_kwargs)]
# Register only if safe to use.

View file

@ -30,9 +30,10 @@ class DummyPlugin(FormElementPlugin):
"""
self.data.name = "{0}_{1}".format(self.uid, uuid4())
def get_form_field_instances(self, request=None):
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
kwargs = {
field_kwargs = {
'initial': "<p>{0}</p>".format(
safe_text(ugettext("Dummy content"))
),
@ -40,10 +41,7 @@ class DummyPlugin(FormElementPlugin):
'label': '',
}
form_field_instances = []
form_field_instances.append((self.data.name, NoneField, kwargs))
return form_field_instances
return[(self.data.name, NoneField, field_kwargs)]
form_element_plugin_registry.register(DummyPlugin)

View file

@ -41,7 +41,8 @@ __all__ = (
def assemble_form_class(form_entry, base_class=BaseForm, request=None,
origin=None, origin_kwargs_update_func=None,
origin_return_func=None, form_element_entries=None):
origin_return_func=None, form_element_entries=None,
get_form_field_instances_kwargs={}):
"""Assemble a form class by given entry.
:param form_entry:
@ -52,6 +53,8 @@ def assemble_form_class(form_entry, base_class=BaseForm, request=None,
:param callable origin_return_func:
:param iterable form_element_entries: If given, used instead of
``form_entry.formelemententry_set.all`` (no additional database hit).
:param dict get_form_field_instances_kwargs: To be passed as **kwargs to
the :method:`get_form_field_instances_kwargs`.
"""
if form_element_entries is None:
form_element_entries = form_entry.formelemententry_set.all()
@ -85,7 +88,10 @@ def assemble_form_class(form_entry, base_class=BaseForm, request=None,
kwargs_update_func=origin_kwargs_update_func,
return_func=origin_return_func,
extra={'counter': creation_counter},
request=request
request=request,
form_entry=form_entry,
form_element_entries=form_element_entries,
**get_form_field_instances_kwargs
)
for form_field_name, form_field_instance \
in plugin_form_field_instances:

View file

@ -55,6 +55,9 @@ __all__ = (
'get_model_name_for_object',
'get_registered_models',
'get_select_field_choices',
'get_wizard_form_field_value_from_post',
'get_wizard_form_field_value_from_request',
'get_wizard_form_field_value_from_session',
'handle_uploaded_file',
'iterable_to_dict',
'JSONDataExporter',
@ -73,6 +76,8 @@ __all__ = (
logger = logging.getLogger(__name__)
# DEBUG = not True
# *****************************************************************************
# *****************************************************************************
# ********************************** General **********************************
@ -680,3 +685,170 @@ def get_form_element_entries_for_form_wizard_entry(form_wizard_entry):
.form_entry \
.formelemententry_set.all()[:]
return form_element_entries
def get_wizard_form_field_value_from_session(request,
wizard_view_name,
form_key,
field_name,
fail_silently=True):
"""Get wizard form field value from session.
This is what we could have:
>>> request.session['wizard_form_wizard_view']['step_data']
>>> {
>>> 'slider-form': {
>>> 'csrfmiddlewaretoken': ['DhINThGTgQ50e2lDnGG4nYrG0a'],
>>> 'slider-form-test_slider': ['14'],
>>> 'form_wizard_view-current_step': ['slider-form'],
>>> 'slider-form-test_email': ['user@example.com']
>>> }
>>> }
Note, that we know nothing about the types here, type conversion should
be done manually. The values returned are strings always.
:param django.http.HttpRequest request:
:param str wizard_view_name:
:param str form_key: Typically, this would be the step name (form slug).
:param str field_name: Field name.
:param bool fail_silently: If set to True, no errors raised.
:return str: Since everything in session is stored as string.
"""
# Field name in the session contains the form key
session_field_name = "{0}-{1}".format(form_key, field_name)
if not fail_silently:
return request.session[wizard_view_name]['step_data'][form_key][
session_field_name][0]
else:
try:
return request.session[wizard_view_name]['step_data'][form_key][
session_field_name][0]
except (KeyError, IndexError) as err:
logger.error(err)
return None
def get_wizard_form_field_value_from_post(request,
wizard_view_name,
form_key,
field_name,
fail_silently=True):
"""Get wizard form field value from POST.
This is what we could have:
>>> request.POST
>>> {
>>> 'csrfmiddlewaretoken': ['kEprTL218a8HNcC02QefNNnF'],
>>> 'slider-form-test_slider': ['14'],
>>> 'form_wizard_view-current_step': ['slider-form'],
>>> 'slider-form-test_email': ['user@example.com']
>>> }
Note, that we know nothing about the types here, type conversion should
be done manually. The values returned are strings always.
:param django.http.HttpRequest request:
:param str wizard_view_name:
:param str form_key: Typically, this would be the step name (form slug).
:param str field_name: Field name.
:param bool fail_silently: If set to True, no errors raised.
:return str: Since everything in session is stored as string.
"""
# Field name in the POST contains the form key
form_field_name = "{0}-{1}".format(form_key, field_name)
# current_step_name = "{0}-{1}".format(wizard_view_name, form_key)
if not fail_silently:
# if not (current_step_name in request.POST and
# request.POST[current_step_name] == form_key):
# return None
return request.POST[form_field_name]
else:
try:
# if not (current_step_name in request.POST and
# request.POST[current_step_name] == form_key):
# return None
return request.POST[form_field_name]
except (KeyError, IndexError) as err:
logger.error(err)
return None
def get_wizard_form_field_value_from_request(request,
wizard_view_name,
form_key,
field_name,
fail_silently=True,
session_priority=False):
"""Get wizard form field value from request.
Note, that we know nothing about the types here, type conversion should
be done manually. The values returned are strings always.
:param django.http.HttpRequest request:
:param str wizard_view_name:
:param str form_key: Typically, this would be the step name (form slug).
:param str field_name: Field name.
:param bool fail_silently: If set to True, no errors raised.
:param bool session_priority: If set to True, first try to read from
session.
:return str: Since everything in session is stored as string.
"""
if session_priority:
# First try session
value = get_wizard_form_field_value_from_session(
request,
wizard_view_name,
form_key,
field_name,
fail_silently
)
if value is not None:
return value
# Then try POST
if 'POST' == request.method:
value = get_wizard_form_field_value_from_post(
request,
wizard_view_name,
form_key,
field_name,
fail_silently
)
else:
# First try POST
if 'POST' == request.method:
value = get_wizard_form_field_value_from_post(
request,
wizard_view_name,
form_key,
field_name,
fail_silently
)
if value is not None:
return value
# Then try session
value = get_wizard_form_field_value_from_session(
request,
wizard_view_name,
form_key,
field_name,
fail_silently
)
return value

View file

@ -42,6 +42,7 @@ __all__ = (
logger = logging.getLogger(__name__)
TIMEOUT = 4
LONG_TIMEOUT = 8
WAIT = False
WAIT_FOR = 0
@ -384,7 +385,7 @@ class BaseFobiBrowserBuldDynamicFormsTest(LiveServerTestCase):
logger.debug(form_element_name)
# Wait until the fobi page opens with the form element in.
WebDriverWait(self.selenium, timeout=TIMEOUT).until(
WebDriverWait(self.selenium, timeout=LONG_TIMEOUT).until(
lambda driver: driver.find_element_by_xpath(
"""//div[contains(text(), 'The form element plugin "{0}" was deleted successfully.') and contains(@class, "alert-info")]""".format(
form_element_name

View file

@ -513,8 +513,8 @@ def get_assembled_form(form_entry, request=None):
:return django.forms.Form:
"""
# TODO
FormClass = assemble_form_class(form_entry, request=request)
form = FormClass()
form_cls = assemble_form_class(form_entry, request=request)
form = form_cls()
return form

View file

@ -14,6 +14,7 @@ from django.contrib.auth.decorators import login_required, permission_required
from django.core.exceptions import ObjectDoesNotExist
from django.core.files.storage import FileSystemStorage
from django.core.urlresolvers import reverse
from django.forms import ValidationError
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import redirect
from django.template import RequestContext
@ -85,6 +86,11 @@ if versions.DJANGO_GTE_1_10:
else:
from django.shortcuts import render_to_response
if versions.DJANGO_GTE_1_8:
from formtools.wizard.forms import ManagementForm
else:
from django.contrib.formtools.wizard.forms import ManagementForm
__title__ = 'fobi.views'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
@ -1433,7 +1439,10 @@ class FormWizardView(DynamicSessionWizardView):
form_cls = assemble_form_class(
form_entry,
request=request,
form_element_entries=form_element_entries
form_element_entries=form_element_entries,
get_form_field_instances_kwargs={
'form_wizard_entry': form_wizard_entry,
}
)
form_list.append(
@ -1458,6 +1467,75 @@ class FormWizardView(DynamicSessionWizardView):
'fobi_theme': theme,
}
def post(self, *args, **kwargs):
"""POST requests.
This method handles POST requests.
The wizard will render either the current step (if form validation
wasn't successful), the next step (if the current step was stored
successful) or the done view (if no more steps are available)
"""
# Look for a wizard_goto_step element in the posted data which
# contains a valid step name. If one was found, render the requested
# form. (This makes stepping back a lot easier).
wizard_goto_step = self.request.POST.get('wizard_goto_step', None)
if wizard_goto_step and wizard_goto_step in self.get_form_list():
return self.render_goto_step(wizard_goto_step)
# Check if form was refreshed
management_form = ManagementForm(self.request.POST, prefix=self.prefix)
if not management_form.is_valid():
raise ValidationError(
_('ManagementForm data is missing or has been tampered.'),
code='missing_management_form',
)
form_current_step = management_form.cleaned_data['current_step']
if (form_current_step != self.steps.current and
self.storage.current_step is not None):
# form refreshed, change current step
self.storage.current_step = form_current_step
# get the form for the current step
form = self.get_form(data=self.request.POST, files=self.request.FILES)
# and try to validate
if form.is_valid():
# Get current form entry
form_entry = self.form_entry_mapping[self.steps.current]
# Fire plugin processors
form = submit_plugin_form_data(form_entry=form_entry,
request=self.request, form=form)
# Form wizards make use of form.data instead of form.cleaned_data.
# Therefore, we update the form.data with values from
# form.cleaned_data.
wizard_field_pattern = "{0}-{1}"
# We can't update values of a `MultiValueDict`, which `QueryDict`
# is, using `update` method. That's why we do it one by one.
for field_key, field_value in form.cleaned_data.items():
wizard_form_key = wizard_field_pattern.format(
self.steps.current,
field_key
)
form.data[wizard_form_key] = field_value
# if the form is valid, store the cleaned data and files.
self.storage.set_step_data(self.steps.current,
self.process_step(form))
self.storage.set_step_files(self.steps.current,
self.process_step_files(form))
# check if the current step is the last step
if self.steps.current == self.steps.last:
# no more steps, render done view
return self.render_done(form, **kwargs)
else:
# proceed to the next step
return self.render_next_step(form)
return self.render(form)
def render_done(self, form, **kwargs):
"""Render done.

View file

@ -3,7 +3,6 @@ from django.utils.html import format_html
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
# Safe import of ``NumberInput``
try:
from django.forms.widgets import NumberInput
@ -63,20 +62,27 @@ class RichSelect(Select):
"""
def __init__(self, attrs=None, choices=(), prepend_html=None,
append_html=None):
append_html=None, override_name=None):
"""Constructor.
:param dict attrs:
:param tuple choices:
:param str prepend_html:
:param str append_html:
:param str override_name:
"""
self.prepend_html = prepend_html if prepend_html else ""
self.append_html = append_html if append_html else ""
self.override_name = override_name \
if override_name is not None \
else None
super(RichSelect, self).__init__(attrs=attrs, choices=choices)
def render(self, name, value, attrs=None):
"""Renders the element, having prepended and appended extra parts."""
if self.override_name is not None:
name = self.override_name
rendered_select = super(RichSelect, self).render(
name=name,
value=value,