├── .github └── workflows │ ├── lint.yml │ └── tox.yml ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.rst ├── demo ├── db.sqlite3 ├── demo │ ├── __init__.py │ ├── forms.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── popups.py │ ├── settings.py │ ├── static │ │ └── img │ │ │ ├── man.png │ │ │ └── woman.png │ ├── templates │ │ ├── base.html │ │ ├── demo │ │ │ ├── demo_bootstrap_3.html │ │ │ ├── demo_bootstrap_4.html │ │ │ └── index.html │ │ └── popups │ │ │ ├── popup_color.html │ │ │ ├── popup_country.html │ │ │ └── popup_sex.html │ ├── urls.py │ ├── views.py │ └── wsgi.py ├── manage.py └── requirements.txt ├── django_popup_view_field ├── __init__.py ├── apps.py ├── exceptions.py ├── fields.py ├── locale │ └── pl │ │ └── LC_MESSAGES │ │ ├── django.mo │ │ ├── django.po │ │ ├── djangojs.mo │ │ └── djangojs.po ├── migrations │ └── __init__.py ├── registry.py ├── static │ └── django_popup_view_field │ │ └── js │ │ ├── django_popup_view_field_bootstrap3.js │ │ ├── django_popup_view_field_bootstrap3.min.js │ │ ├── django_popup_view_field_bootstrap4.js │ │ └── django_popup_view_field_bootstrap4.min.js ├── templates │ └── django_popup_view_field │ │ ├── popup_view_dialog_bootstrap3.html │ │ ├── popup_view_dialog_bootstrap4.html │ │ ├── popup_view_widget_bootstrap3.html │ │ ├── popup_view_widget_bootstrap4.html │ │ └── scripts_include.html ├── templatetags │ ├── __init__.py │ └── django_popup_view_field_tags.py ├── tests.py ├── tests │ ├── __init__.py │ ├── forms.py │ ├── popups.py │ ├── settings.py │ ├── templates │ │ ├── popups │ │ │ └── popup_1.html │ │ └── tests │ │ │ └── view_1.html │ ├── test_field.py │ ├── test_registry.py │ ├── test_templatetags.py │ ├── test_views.py │ ├── test_widgets.py │ ├── urls.py │ └── views.py ├── urls.py ├── views.py └── widgets.py ├── doc └── static │ ├── PopupViewModelField_example.png │ ├── advanced_example.png │ ├── scr1.png │ ├── scr2.png │ ├── scr3.png │ ├── scr4.png │ └── simple_example.png ├── requirements-dev.txt ├── run_flake.sh ├── run_test.py ├── setup.cfg ├── setup.py └── tox.ini /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint by Flake 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | strategy: 10 | max-parallel: 4 11 | matrix: 12 | python-version: [3.6,] 13 | 14 | steps: 15 | - uses: actions/checkout@v1 16 | - name: Set up Python ${{ matrix.python-version }} 17 | uses: actions/setup-python@v1 18 | with: 19 | python-version: ${{ matrix.python-version }} 20 | - name: Install dependencies 21 | run: | 22 | python -m pip install --upgrade pip 23 | pip install -r requirements-dev.txt 24 | - name: Lint with flake8 25 | run: | 26 | flake8 27 | -------------------------------------------------------------------------------- /.github/workflows/tox.yml: -------------------------------------------------------------------------------- 1 | name: Tests by Tox 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | strategy: 11 | matrix: 12 | python: [3.7] 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Setup Python 17 | uses: actions/setup-python@v1 18 | with: 19 | python-version: ${{ matrix.python }} 20 | - name: Install Tox 21 | run: pip install tox 22 | - name: Run Tox 23 | run: tox -r # Run tox using the version of Python in `PATH` 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # directories 2 | # ----------- 3 | __pycache__/ 4 | build/ 5 | dist/ 6 | .tox/ 7 | eggs/ 8 | .eggs/ 9 | .idea/ 10 | 11 | # extends 12 | # -------- 13 | *.pyc 14 | *.egg-info/ 15 | *.egg 16 | *.pot 17 | *.log 18 | *.sqlite3 19 | 20 | # files 21 | # ----- 22 | .cache 23 | .env 24 | pip-log.txt 25 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: python 3 | 4 | matrix: 5 | include: 6 | - { python: 2.7, env: TOXENV=py27-flake } 7 | - { python: 3.6, env: TOXENV=py36-flake } 8 | - { python: 2.7, env: TOXENV=py27-dj_1.9-bootstrap3_7.1-crispy_1.5-tests } 9 | - { python: 2.7, env: TOXENV=py27-dj_1.9-bootstrap3_7.1-crispy_1.6-tests } 10 | - { python: 2.7, env: TOXENV=py27-dj_1.9-bootstrap3_8.1-crispy_1.5-tests } 11 | - { python: 2.7, env: TOXENV=py27-dj_1.9-bootstrap3_8.1-crispy_1.6-tests } 12 | - { python: 2.7, env: TOXENV=py27-dj_1.9-bootstrap3_8.2-crispy_1.5-tests } 13 | - { python: 2.7, env: TOXENV=py27-dj_1.9-bootstrap3_8.2-crispy_1.6-tests } 14 | - { python: 3.6, env: TOXENV=py36-dj_1.9-bootstrap3_7.1-crispy_1.5-tests } 15 | - { python: 3.6, env: TOXENV=py36-dj_1.9-bootstrap3_7.1-crispy_1.6-tests } 16 | - { python: 3.6, env: TOXENV=py36-dj_1.9-bootstrap3_8.1-crispy_1.5-tests } 17 | - { python: 3.6, env: TOXENV=py36-dj_1.9-bootstrap3_8.1-crispy_1.6-tests } 18 | - { python: 3.6, env: TOXENV=py36-dj_1.9-bootstrap3_8.2-crispy_1.5-tests } 19 | - { python: 3.6, env: TOXENV=py36-dj_1.9-bootstrap3_8.2-crispy_1.6-tests } 20 | - { python: 2.7, env: TOXENV=py27-dj_1.10-bootstrap3_7.1-crispy_1.5-tests } 21 | - { python: 2.7, env: TOXENV=py27-dj_1.10-bootstrap3_7.1-crispy_1.6-tests } 22 | - { python: 2.7, env: TOXENV=py27-dj_1.10-bootstrap3_8.1-crispy_1.5-tests } 23 | - { python: 2.7, env: TOXENV=py27-dj_1.10-bootstrap3_8.1-crispy_1.6-tests } 24 | - { python: 2.7, env: TOXENV=py27-dj_1.10-bootstrap3_8.2-crispy_1.5-tests } 25 | - { python: 2.7, env: TOXENV=py27-dj_1.10-bootstrap3_8.2-crispy_1.6-tests } 26 | - { python: 3.6, env: TOXENV=py36-dj_1.10-bootstrap3_7.1-crispy_1.5-tests } 27 | - { python: 3.6, env: TOXENV=py36-dj_1.10-bootstrap3_7.1-crispy_1.6-tests } 28 | - { python: 3.6, env: TOXENV=py36-dj_1.10-bootstrap3_8.1-crispy_1.5-tests } 29 | - { python: 3.6, env: TOXENV=py36-dj_1.10-bootstrap3_8.1-crispy_1.6-tests } 30 | - { python: 3.6, env: TOXENV=py36-dj_1.10-bootstrap3_8.2-crispy_1.5-tests } 31 | - { python: 3.6, env: TOXENV=py36-dj_1.10-bootstrap3_8.2-crispy_1.6-tests } 32 | - { python: 2.7, env: TOXENV=py27-dj_1.11-bootstrap3_8.2-crispy_1.6-tests } 33 | - { python: 3.6, env: TOXENV=py36-dj_1.11-bootstrap3_8.2-crispy_1.6-tests } 34 | - { python: 3.6, env: TOXENV=py36-dj_2.0-latest_bootstraps-crispy_1.7-tests } 35 | - { python: 3.6, env: TOXENV=py36-dj_2.0-latest_bootstraps-crispy_1.8-tests } 36 | - { python: 3.6, env: TOXENV=py36-dj_2.0-latest_bootstraps-crispy_1.9-tests } 37 | - { python: 3.6, env: TOXENV=py36-dj_2.1-latest_bootstraps-crispy_1.7-tests } 38 | - { python: 3.6, env: TOXENV=py36-dj_2.1-latest_bootstraps-crispy_1.8-tests } 39 | - { python: 3.6, env: TOXENV=py36-dj_2.1-latest_bootstraps-crispy_1.9-tests } 40 | - { python: 3.6, env: TOXENV=py36-dj_2.2-latest_bootstraps-crispy_1.7-tests } 41 | - { python: 3.6, env: TOXENV=py36-dj_2.2-latest_bootstraps-crispy_1.8-tests } 42 | - { python: 3.6, env: TOXENV=py36-dj_2.2-latest_bootstraps-crispy_1.9-tests } 43 | - { python: 3.6, env: TOXENV=py36-dj_3.0-latest_bootstraps-crispy_1.8-tests } 44 | - { python: 3.6, env: TOXENV=py36-dj_3.0-latest_bootstraps-crispy_1.9-tests } 45 | 46 | install: 47 | - pip install tox>=2.5.0 48 | script: 49 | - tox 50 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG for django-popup-view-field 2 | 3 | ## 0.6.1 (2020-01-27) 4 | 5 | * Added support for Django 3.0 (demand django-crispy-forms >= 1.8.0 ) 6 | 7 | * Fixed javascript for bootstrap4. 8 | In script was used incorrectly `id` attribute of dialog element. 9 | Now `id` of `
` dialog for popup is different for bootstrap3 and bootstrap4. 10 | 11 | ## 0.6.0 (2020-01-23) 12 | 13 | * Added support for Django 2.2 14 | 15 | * Drop support for Django 1.8 16 | 17 | * Added support for bootstrap4 (testing only with Django >= 2.1) 18 | 19 | * Added setting DJANGO_POPUP_VIEW_FIELD_TEMPLATE_PACK 20 | 21 | * Templates for widgets was splitted to blocks 22 | (for easy customization). Now `PopupViewWidget` can use 23 | template for bootstrap3 or template for bootstrap4 24 | 25 | ## 0.5.0 (2019-04-17) 26 | 27 | * Support for Django 2.0 and 2.1 28 | 29 | * Added PopupViewModelField that returns a model instance instead of text 30 | 31 | ## 0.4.1 (2019-02-23) 32 | 33 | * Added `attrs` attribute to PopupViewField which is passed to the Widget 34 | 35 | ## 0.4.0 (2018-10-04) 36 | 37 | * Added `callback_data` attribute to PopupViewField (read more in README) 38 | 39 | ## 0.3.0 (2017-03-07) 40 | 41 | * Support for Django 1.11 42 | 43 | ## 0.2.0 (2017-02-20) 44 | 45 | * Remove PopupViewField from django_popup_view_field.__init__, 46 | now you must import PopupViewField from django_popup_view_field.fields 47 | 48 | * Sorting imports using isort 49 | 50 | * Checking the order of imports in the tox 51 | 52 | * Checking support for django-bootstrap3 v8.1.0 53 | 54 | * Added django-bootstrap3 v8.1.0 to tox 55 | 56 | * Adding version in django_popup_view_field.__init__ 57 | 58 | ## 0.1 (2016-12-27) 59 | 60 | * Initial version + tests + Travis CI 61 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 K2 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | django-popup-view-field 2 | ------------------------ 3 | 4 | .. image:: https://badge.fury.io/py/django-popup-view-field.svg 5 | :target: https://badge.fury.io/py/django-popup-view-field 6 | :alt: Latest PyPI version 7 | 8 | 9 | .. image:: https://travis-ci.org/djk2/django-popup-view-field.svg?branch=master 10 | :target: https://travis-ci.org/djk2/django-popup-view-field 11 | :alt: Travis CI 12 | 13 | 14 | .. image:: https://requires.io/github/djk2/django-popup-view-field/requirements.svg?branch=master 15 | :target: https://requires.io/github/djk2/django-popup-view-field/requirements/?branch=master 16 | :alt: Requirements Status 17 | 18 | 19 | Field and widget can render bootstrap dialog with content from django view. 20 | You can create normal django View and load this view in dialog for form field. 21 | 22 | - Support: 23 | 24 | * Python: 2.7, 3.6 25 | * Django: 1.9, 1.10, 1.11, 2.0, 2.1, 2.2, 3.0 26 | * django-crispy-forms 27 | * django-bootstrap3 28 | * django-bootstrap4 (!Only for Django >= 2.1) 29 | 30 | - Require: 31 | 32 | * Django 33 | * bootstrap3 or bootstrap4 34 | * JQuery 35 | 36 | - Recommended: 37 | 38 | * django-bootstrap3 or django-bootstrap4 39 | * django-crispy-forms 40 | 41 | - Locale: 42 | 43 | * EN - (english) 44 | * PL - (polish) 45 | 46 | - Tested on browsers: 47 | 48 | * OK - Chromium 79.0.3945.79 - Ubuntu 18.04 49 | * OK - Firefox 72.0.1 (64 bity) - Ubuntu 18.04 50 | * OK - Google Chrome 70.0 - Fedora 28 51 | * OK - Firefox 62.0.3 - Fedora 28 52 | * OK - Firefox 50.1.0 - Ubuntu 14.04 53 | * OK - Firefox 31.1 - CentOS 6.4 54 | * OK - Chromium 53.0 - Ubuntu 14.04 55 | * OK - Microsoft Edge 38 - Windows 10 56 | * OK - Internet Explorer 11.0 - Windows 10 57 | * OK - Internet Explorer 10.0 - Windows 7 58 | * OK - Internet Explorer 9.0 - Windows 7 59 | * ER - Internet Explorer <= 8 (no support "html()" for data-popup-view-value) 60 | 61 | 62 | Screenshots 63 | ------------ 64 | 65 | - Example: Form with several popup-view-fields 66 | 67 | .. image:: https://raw.githubusercontent.com/djk2/django-popup-view-field/master/doc/static/scr1.png 68 | :alt: Form with django-popup-view-fields 69 | 70 | - Example: Dialog for select sex 71 | 72 | .. image:: https://raw.githubusercontent.com/djk2/django-popup-view-field/master/doc/static/scr2.png 73 | :alt: Dialog for select sex 74 | 75 | - Example: Dialog for select color 76 | 77 | .. image:: https://raw.githubusercontent.com/djk2/django-popup-view-field/master/doc/static/scr3.png 78 | :alt: Dialog for select color 79 | 80 | - Example: Dialog with form 81 | 82 | .. image:: https://raw.githubusercontent.com/djk2/django-popup-view-field/master/doc/static/scr4.png 83 | :alt: Dialog with form 84 | 85 | 86 | Run demo 87 | --------- 88 | 1. Clone or download repository:: 89 | 90 | git clone https://github.com/djk2/django-popup-view-field.git 91 | 92 | 2. Create virtualenv or not (red more: http://docs.python-guide.org/en/latest/dev/virtualenvs/) 93 | 94 | 3. Install requirements for demo:: 95 | 96 | cd django-popup-view-field/demo 97 | 98 | pip install -r requirements.txt 99 | 100 | 4. Run developing web server:: 101 | 102 | python manage.py runserver 103 | 104 | 5. Run your browser and call url: 127.0.0.1:8000 :: 105 | 106 | firefox 127.0.0.1:8000 107 | 108 | 109 | Install 110 | -------- 111 | Install package - There are several solutions, choose your own 112 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 113 | 114 | 1. Install using pypi repository:: 115 | 116 | pip install django-popup-view-field 117 | 118 | 2. Install using pip + github repository url:: 119 | 120 | pip install git+https://github.com/djk2/django-popup-view-field.git 121 | 122 | 3. Install using pip + zip archive:: 123 | 124 | wget https://github.com/djk2/django-popup-view-field/archive/master.zip 125 | pip install master.zip 126 | 127 | 4. Clone or download application to your django project directory:: 128 | 129 | wget https://github.com/djk2/django-popup-view-field/archive/master.zip -O /tmp/master.zip 130 | unzip /tmp/master.zip -d /tmp/ 131 | cd my_project_dir 132 | cp -r /tmp/django-popup-view-field-master/django_popup_view_field/ ./ 133 | 134 | Add ``django_popup_view_field`` to your INSTALLED_APPS setting 135 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 136 | 137 | *settings.py* :: 138 | 139 | INSTALLED_APPS = [ 140 | ... 141 | 'bootstrap3', # If you use django-bootstrap3 142 | 'crispy_forms', # If you user django-crispy-forms 143 | 144 | 'django_popup_view_field', 145 | ... 146 | ] 147 | 148 | # If you want use bootstrap4 then uncomment 149 | # DJANGO_POPUP_VIEW_FIELD_TEMPLATE_PACK = 'bootstrap4' 150 | 151 | **Warning**: 152 | Is recommended use django-bootstrap3/django-bootstrap4 or django-crispy-forms 153 | to render forms and fields, but this is not necessary. 154 | You can still write django templates using pure CSS from bootstrap3/4. 155 | More information about bootstrap forms in here: http://getbootstrap.com/css/#forms 156 | 157 | 158 | Add the django_popup_view_field urls to your root url patterns 159 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 160 | *urls.py* :: 161 | 162 | urlpatterns = [ 163 | ... 164 | url( 165 | r'^django_popup_view_field/', 166 | include('django_popup_view_field.urls', namespace="django_popup_view_field") 167 | ), 168 | ] 169 | 170 | **Note**: 171 | The URL path can be whatever you want, 172 | but you must include 'django_popup_view_field.urls' with the 'django_popup_view_field' namespace. 173 | You may leave out the namespace in Django >= 1.9 174 | 175 | 176 | In your base template, add ``django_popup_view_field_javascript`` tag 177 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 178 | ``django_popup_view_field_javascript`` template tag load all required javascripts and 179 | template-scripts for application. 180 | Tag should be append before body close tag and after jQuery and Bootstrap scripts. 181 | 182 | *base.html* :: 183 | 184 | 185 | {% load django_popup_view_field_tags %} 186 | 187 | 188 | 189 | ... 190 | 191 | ... 192 | 193 | 194 | 195 | ... 196 | ... 197 | 198 | 199 | ... 200 | ... 201 | {% django_popup_view_field_javascript %} 202 | 203 | 204 | 205 | 206 | Settings 207 | ---------- 208 | 209 | DJANGO_POPUP_VIEW_FIELD_TEMPLATE_PACK 210 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 211 | Since version 0.6.0, django-popup-view-fields has built-in support for bootstrap4 also. 212 | To enable support for `bootstrap4` you have to set `DJANGO_POPUP_VIEW_FIELD_TEMPLATE_PACK` 213 | to "bootstrap4" value. 214 | 215 | * `bootstrap3` - this setting will be load javascript and html templates for bootstrap3. 216 | **This is a default value** 217 | 218 | * `bootstrap4` - this setting will be load javascript and html templates for bootstrap4. 219 | 220 | Value of DJANGO_POPUP_VIEW_FIELD_TEMPLATE_PACK is changing behavior 221 | of '{% django_popup_view_field_javascript %}' tag and `PopupViewWidget` class. 222 | Template `scripts_include.html` is using this flag to decide which template 223 | and javascript will be load. `PopupViewWidget` class is using this flag to decide 224 | which template for field should be load. 225 | 226 | 227 | Simple Example 228 | ------------------------ 229 | 230 | .. image:: https://raw.githubusercontent.com/djk2/django-popup-view-field/master/doc/static/simple_example.png 231 | :alt: Simple Example - screenshot 232 | 233 | 234 | Create PopupView 235 | ^^^^^^^^^^^^^^^^^ 236 | 237 | Html content rendered by this view will be loaded into bootstrap dialog. 238 | Create your popup view same as normal django view. 239 | 240 | | **Your popup view must be subclass of django.views.generic.View** 241 | 242 | *templates/myapp/popups/colors.html* :: 243 | 244 | 250 | 251 | If user click on the element with the attribute ``data-popup-view-value``, 252 | the value of this attribute will be set in form field and dialog will close. 253 | 254 | | 255 | 256 | If you want set content of element as value in form field, use ``html()`` for attribute:: 257 | 258 |
  • This text will be use :)
  • 259 | 260 | *popups.py* :: 261 | 262 | from django.views.generic import TemplateView 263 | from django_popup_view_field.registry import registry_popup_view 264 | 265 | class ColorsPopupView(TemplateView): 266 | template_name = 'myapp/popups/colors.html' 267 | 268 | # REGISTER IS IMPORTANT 269 | registry_popup_view.register(ColorsPopupView) 270 | 271 | Remember that you must register your popup view. 272 | After register you can run your popup view by call url:: 273 | 274 | ..../django_popup_view_field/ColorsPopupView 275 | 276 | In template you can get url to popup view using url tag:: 277 | 278 | {% url "django_popup_view_field:get_popup_view" 'ColorsPopupView' %} 279 | 280 | After register you can unregister your popup view:: 281 | 282 | registry_popup_view.unregister(ColorsPopupView) 283 | 284 | # or unregister by view name 285 | 286 | registry_popup_view.unregister_by_name('ColorsPopupView') 287 | 288 | You can also get popup view class by name:: 289 | 290 | view_class = registry_popup_view.get('ColorsPopupView') 291 | view_class.as_view() 292 | 293 | 294 | Create Form with PopupViewField 295 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 296 | *forms.py* :: 297 | 298 | from django import forms 299 | from django_popup_view_field.fields import PopupViewField 300 | from myapp.popups import ColorsPopupView 301 | 302 | class ColorForm(forms.Form): 303 | 304 | color = PopupViewField( 305 | view_class=ColorsPopupView, 306 | popup_dialog_title='What is your favorite color', 307 | attrs={'readonly': True}, 308 | required=True, 309 | help_text='be honest' 310 | ) 311 | 312 | **class PopupViewField(view_class, popup_dialog_title, *args, **kwargs)** 313 | 314 | * ``view_class`` - **required** - popup view class, view to render dialog content, must be subclass of django.views.generic.View 315 | * ``popup_dialog_title`` - **not required** - Title for dialog, default ``Popup Dialog: Select value`` 316 | * ``attrs`` - **not required** - provides attributes for Widget 317 | * ``args`` and ``kwargs`` are default for CharField 318 | 319 | 320 | Create typical FormView 321 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 322 | *views.py* :: 323 | 324 | from django.views.generic import FormView 325 | from myapp.forms import ColorForm 326 | from django.http import HttpResponse 327 | 328 | class ColorFormView(FormView): 329 | template_name = "myapp/color_form.html" 330 | form_class = ColorForm 331 | 332 | def form_valid(self, form): 333 | color = form.cleaned_data.get("color") 334 | return HttpResponse("Your color: {0}".format(color)) 335 | 336 | **Template using django-crispy-forms** 337 | 338 | *templates/myapp/color_form.html* :: 339 | 340 | {% extends "base.html" %} 341 | {% load crispy_forms_tags %} 342 | {% crispy form %} 343 | 344 | 345 | **Template using django-bootstrap3** 346 | 347 | *templates/myapp/color_form.html* :: 348 | 349 | {% extends "base.html" %} 350 | {% load bootstrap3 %} 351 | 352 |
    353 | {% csrf_token %} 354 | {% bootstrap_form form %} 355 | {% buttons %} 356 | 357 | {% endbuttons %} 358 |
    359 | 360 | **Template with pure bootstrap3 css (without django-bootstrap3 and crispy)** 361 | 362 | *templates/myapp/color_form.html* :: 363 | 364 | {% extends "base.html" %} 365 |
    366 |
    367 | 368 | {{ form.color }} 369 |
    370 | 371 |
    372 | 373 | 374 | callback_data attribute 375 | ------------------------ 376 | If you want pass extra parameters to your popup view, you should use `callback_data` 377 | attribute for PopupViewField. This argument should be dictionary or OrderedDict. 378 | This dictionary containing yours parameters will be encoded to ASCII text string and 379 | added to url address. In your popup view You can take this parameters from `request.GET`. 380 | 381 | *popups.py* :: 382 | 383 | from django.views.generic import View 384 | from django_popup_view_field.registry import registry_popup_view 385 | 386 | class FooPopupView(View): 387 | def get(self, request): 388 | print(request.GET['extra_param']) # --> will be "Foo Bar" 389 | print(request.GET['my_pk']) # --> will be 666 390 | .... 391 | 392 | # REGISTER IS IMPORTANT 393 | registry_popup_view.register(FooPopupView) 394 | 395 | *forms.py* :: 396 | 397 | from django import forms 398 | from django_popup_view_field.fields import PopupViewField 399 | 400 | class FooForm(forms.Form): 401 | 402 | some_field = PopupViewField( 403 | view_class=FooPopupView, 404 | callback_data={ 405 | 'extra_param': 'Foo Bar', 406 | 'my_pk': 666 407 | } 408 | ) 409 | 410 | 411 | 412 | Advanced Example 413 | ------------------------ 414 | 415 | Advanced Example use django-bootstrap3. 416 | Dialog is interactive, all links and forms will be send via Ajax and response will be loaded in dialog. 417 | 418 | .. image:: https://raw.githubusercontent.com/djk2/django-popup-view-field/master/doc/static/advanced_example.png 419 | :alt: Advanced Example - screenshot 420 | 421 | 422 | PopupView 423 | ^^^^^^^^^^ 424 | 425 | *templates/myapp/popups/alphabet.html* :: 426 | 427 |

    Select the first letter of your name

    428 | 429 | {% for char in alphabet %} 430 |
    431 | {{ char }} 432 |
    433 | {% if forloop.counter|divisibleby:"13" and forloop.counter > 0 %} 434 |

    435 | {% endif %} 436 | {% endfor %} 437 | 438 | {# Button to change order #} 439 | 441 | Reverse order 442 | 443 | 444 | *popups.py* :: 445 | 446 | from django.views.generic import TemplateView 447 | from django_popup_view_field.registry import registry_popup_view 448 | from string import ascii_uppercase 449 | 450 | class AlphabetPopupView(TemplateView): 451 | template_name = 'myapp/popups/alphabet.html' 452 | direction = 1 453 | 454 | def get_context_data(self, **kwargs): 455 | self.direction = int(self.request.GET.get("direction") or self.direction) 456 | alphabet = ascii_uppercase[::self.direction] 457 | ctx = super(AlphabetPopupView, self).get_context_data(**kwargs) 458 | ctx['alphabet'] = alphabet 459 | ctx['direction'] = self.direction * -1 460 | return ctx 461 | 462 | # REGISTER IS IMPORTANT 463 | registry_popup_view.register(AlphabetPopupView) 464 | 465 | 466 | Form with PopupViewField 467 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 468 | *forms.py* :: 469 | 470 | from django import forms 471 | from django_popup_view_field.fields import PopupViewField 472 | from myapp.popups import AlphabetPopupView 473 | 474 | class AlphabetForm(forms.Form): 475 | 476 | char = PopupViewField(view_class=AlphabetPopupView, required=True) 477 | 478 | View 479 | ^^^^^ 480 | 481 | *templates/myapp/alphabet.html* :: 482 | 483 | {% extends "base.html" %} 484 | {% load bootstrap3 %} 485 | 486 |
    487 | {% csrf_token %} 488 | {% bootstrap_form form %} 489 | {% buttons %} 490 | 491 | {% endbuttons %} 492 |
    493 | 494 | *views.py* :: 495 | 496 | from django.views.generic import FormView 497 | from myapp.forms import AlphabetForm 498 | from django.http import HttpResponse 499 | 500 | class AlphabetFormView(FormView): 501 | template_name = "myapp/alphabet.html" 502 | form_class = AlphabetForm 503 | 504 | def form_valid(self, form): 505 | char = form.cleaned_data.get("char") 506 | return HttpResponse("First letter of your name : {0}".format(char)) 507 | 508 | 509 | PopupViewModelField Example 510 | ----------------------------- 511 | ``PopupViewModelField`` allows you to send model objects through the form inheriting from ``ModelForm``. 512 | 513 | .. image:: https://raw.githubusercontent.com/djk2/django-popup-view-field/master/doc/static/PopupViewModelField_example.png 514 | :alt: PopupViewModelField Example - screenshot 515 | 516 | 517 | Model 518 | ^^^^^^^ 519 | *models.py* :: 520 | 521 | from django.db import models 522 | 523 | 524 | class Country(models.Model): 525 | code = models.CharField(max_length=2, primary_key=True) 526 | name = models.CharField(max_length=256) 527 | 528 | 529 | class ExampleUser(models.Model): 530 | first_name = models.CharField(max_length=30) 531 | last_name = models.CharField(max_length=30) 532 | country_code = models.ForeignKey(Country, on_delete=models.PROTECT) 533 | 534 | 535 | PopupView 536 | ^^^^^^^^^^ 537 | *templates/myapp/popups/country.html* :: 538 | 539 |