Skip to main content

Dynamic update for Django form.

Project description

Django Dynamic Form

Django Dynamic Form は、ユーザーによるフォームの入力、選択、変更などのイベントを検知し、 各フィールドの表示/非表示、有効/無効の切り替えや選択肢の変更などのフォームの最新化を行います。

Installation

  1. 'dynamic_form'INSTALLED_APPS に追加します。

    INSTALLED_APPS = [
        ...
        'dynamic_form',
    ]
    
  2. dynamic_form の URLconf をプロジェクトの urls.py に追加します。

    urlpatterns = [
        ...
        path('', include('dynamic_form.urls')),
    ]
    
  3. HTML に script タグを追加します。

    {% load static %}
    <script type="text/javascript" src="{% static 'dynamic_form/js/dynamic-form.js' %}"></script>
    

Quick start

  1. フォーム に DynamicFormMixin を継承させます。

    from django import forms
    from dynamic_form.forms import DynamicFormMixin
    
    
    class TestForm(DynamicFormMixin, forms.Form):
        ...
    
  2. settings.py にフォームへの.(ドット)区切りのモジュールパスと、フォームを一意に特定する文字列を定義します。

    DYNAMIC_FORM = {
        'FORM_KEYS': {
            'sample_app.forms.TestForm': 'test_form',
        },
    }
    
  3. フォーム最新化のトリガーとなるフィールドに、data 属性 data-ddf-trigger を追加します。 属性値にはイベントの種類を表すTriggerEventTypesクラスのメンバー値を指定します。 詳細はTriggerEventTypesをご覧ください。

    from dynamic_form.types import TriggerEventTypes
    
    
    class TestForm(DynamicFormMixin, forms.Form):
        age = forms.IntegerField(
            label='年齢',
            widget=forms.NumberInput(
                attrs={
                    'data-ddf-trigger': TriggerEventTypes.BLUR,
                }
            )
        )
    
  4. 表示/非表示、有効/無効の切り替えなど、フィールドに対する制御を定義します。 詳細はフィールド制御メソッドをご覧ください。

    class TestForm(DynamicFormMixin, forms.Form):
        age = forms.IntegerField(
            label='年齢',
            widget=forms.NumberInput(
                attrs={
                    'data-ddf-trigger': TriggerEventTypes.BLUR,
                }
            )
        )
        consent = forms.BooleanField(
            label='保護者同意',
            help_text='未成年の場合は保護者の同意が必要です。',
        )
    
        def is_hidden_consent(self):
            age = self.data.get('age', '')
            return int(age) >= 20 if age.isdigit() else True
    
  5. ビューでフォームを生成し、render_form() メソッドの戻り値をテンプレートに渡します。 テンプレートに渡された render_form() メソッドの戻り値をformタグで囲み、methodPOST にします。

    class TestView(TemplateView):
        template_name = 'test_view.html'
    
        def get(self, request, *args, **kwargs):
            form = TestForm()
            context = {
                'test_form': form.render_form(),
            }
            return self.render_to_response(context)
    

    test_view.html

    <form method="post">
        {% csrf_token %}
        {{ test_form }}
        <input type="submit" value="Submit" />
    </form>
    

Documentation

DynamicFormMixin

クラス変数

  • form_template

    フォームの表示はテンプレートファイルによりカスタマイズできます。 このテンプレートには form タグを含めません。 カスタマイズしたテンプレートファイルは form_template で指定します。

    class TestForm(DynamicFormMixin, forms.Form):
        form_template = 'sample_app/sample_form.html'
    

    sample_app/sample_form.html

    {% for field in form.visible_fields %}
        <div class="form-row">
            <div class="form-label">
                {{ field.label }}
            </div>
            <div class="form-field">
                {{ field }}
            </div>
            {% if field.errors %}
            <div class="form-error">
                {{ field.errors }}
            </div>
            {% endif %}
        </div>
    {% endfor %}
    
  • do_dynamic_validate

    フォーム最新化のときに、バリデーションを実施するかを指定します。 デフォルトは False です。

    class TestForm(DynamicFormMixin, forms.Form):
        do_dynamic_validate = True
    

フィールド制御メソッド

フィールド制御メソッドは、各フィールドの表示/非表示、有効/無効の切り替えや選択肢の変更などを制御します。 制御が必要なフィールドの、必要なメソッドのみを定義します。 フォームの入力内容は self.data からアクセスできますが、未入力のフィールドなど値が self.data に含まれない可能性を考慮する必要があります。

制御できる項目は以下のとおりです。

  • is_hidden_<field_name>()

    フィールドを非表示にするかの真偽値を返します。 True を返した場合、フィールドの requiredFalse に、 ウィジェットが django.forms.HiddenInput となります。

  • is_disabled_<field_name>()

    フィールドを無効にするかの真偽値を返します。 True を返した場合、フィールドの disabledTrue に、 requiredFalse となります。

  • is_required_<field_name>()

    フィールドを必須にするかの真偽値を返します。 True を返した場合、フィールドの requiredTrue となります。

  • set_queryset_<field_name>()

    フィールドに設定する queryset を返します。 ModelChoiceField に対して使用します。

    def set_queryset_task(self):
        selected_member = self.data.get('member')
        return Task.objects.filter(id=selected_member)
    
  • set_choices_<field_name>()

    フィールドに設定する choices を返します。 ChoiceField に対して使用します。

    def set_choices_fruits(self):
        return [
            (1, 'apple'),
            (2, 'banana'),
            (3, 'melon'),
        ]
    

TriggerEventTypes

TriggerEventTypesでは、フォーム最新化のトリガーとなるイベントを定義しています。 フィールドの data-ddf-trigger 属性の属性値に指定します。

  • BLUR

    フィールドから blur イベントが発生した場合にフォームを最新化します。

  • CHANGE

    フィールドから change イベントが発生した場合にフォームを最新化します。

  • CLICK

    フィールドから click イベントが発生した場合にフォームを最新化します。

  • DOUBLE_CLICK

    フィールドから dblclick イベントが発生した場合にフォームを最新化します。

  • INPUT

    フィールドから input イベントが発生した場合にフォームを最新化します。

  • KEY_UP

    フィールドから keyup イベントが発生した場合にフォームを最新化します。

  • KEY_DOWN

    フィールドから keydown イベントが発生した場合にフォームを最新化します。

  • SELECT

    フィールドから select イベントが発生した場合にフォームを最新化します。

Settings

Django Dynamic Form の設定は DYNAMIC_FORM という名前で指定します。

DYNAMIC_FORM = {
    'FORM_KEYS': {
        'sample_app.forms.TestForm': 'test_form',
    },
}
  • FORM_KEYS

    フォームへの.(ドット)区切りのモジュールパスと、フォームを一意に特定する文字列を定義します。 この文字列はHTML上に data-form-key 属性の属性値として設定されます。

    モジュールパスは __class__.__module____class__.__name__.(ドット)区切りで連結した文字列です。

Project details


Release history Release notifications | RSS feed

This version

0.1

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-dynamic-form-0.1.tar.gz (8.5 kB view hashes)

Uploaded Source

Built Distribution

django_dynamic_form-0.1-py3-none-any.whl (9.7 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page