django-crispy-formset-modal 0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- django-crispy-formset-modal-0.1/LICENSE +21 -0
- django-crispy-formset-modal-0.1/MANIFEST.in +3 -0
- django-crispy-formset-modal-0.1/PKG-INFO +138 -0
- django-crispy-formset-modal-0.1/README.md +110 -0
- django-crispy-formset-modal-0.1/crispy_formset_modal/__init__.py +17 -0
- django-crispy-formset-modal-0.1/crispy_formset_modal/helper.py +7 -0
- django-crispy-formset-modal-0.1/crispy_formset_modal/layout.py +133 -0
- django-crispy-formset-modal-0.1/crispy_formset_modal/locale/es/LC_MESSAGES/django.po +39 -0
- django-crispy-formset-modal-0.1/crispy_formset_modal/locale/es/LC_MESSAGES/djangojs.po +27 -0
- django-crispy-formset-modal-0.1/crispy_formset_modal/static/crispy_formset_modal/js/crispy-formset-modal.min.js +2 -0
- django-crispy-formset-modal-0.1/crispy_formset_modal/static/crispy_formset_modal/js/crispy-formset-modal.min.js.map +1 -0
- django-crispy-formset-modal-0.1/crispy_formset_modal/templates/crispy_formset_modal/bootstrap4/form.html +20 -0
- django-crispy-formset-modal-0.1/crispy_formset_modal/templates/crispy_formset_modal/bootstrap4/modal.html +22 -0
- django-crispy-formset-modal-0.1/crispy_formset_modal/templates/crispy_formset_modal/bootstrap4/table.html +72 -0
- django-crispy-formset-modal-0.1/crispy_formset_modal/templates/crispy_formset_modal/bootstrap5/form.html +20 -0
- django-crispy-formset-modal-0.1/crispy_formset_modal/templates/crispy_formset_modal/bootstrap5/modal.html +21 -0
- django-crispy-formset-modal-0.1/crispy_formset_modal/templates/crispy_formset_modal/bootstrap5/table.html +72 -0
- django-crispy-formset-modal-0.1/crispy_formset_modal/templates/crispy_formset_modal/bulma/form.html +22 -0
- django-crispy-formset-modal-0.1/crispy_formset_modal/templates/crispy_formset_modal/bulma/modal.html +19 -0
- django-crispy-formset-modal-0.1/crispy_formset_modal/templates/crispy_formset_modal/bulma/table.html +72 -0
- django-crispy-formset-modal-0.1/crispy_formset_modal/templates/crispy_formset_modal/tailwind/form.html +20 -0
- django-crispy-formset-modal-0.1/crispy_formset_modal/templates/crispy_formset_modal/tailwind/modal.html +23 -0
- django-crispy-formset-modal-0.1/crispy_formset_modal/templates/crispy_formset_modal/tailwind/table.html +80 -0
- django-crispy-formset-modal-0.1/crispy_formset_modal/templatetags/formset_modal_tags.py +58 -0
- django-crispy-formset-modal-0.1/django_crispy_formset_modal.egg-info/PKG-INFO +138 -0
- django-crispy-formset-modal-0.1/django_crispy_formset_modal.egg-info/SOURCES.txt +30 -0
- django-crispy-formset-modal-0.1/django_crispy_formset_modal.egg-info/dependency_links.txt +1 -0
- django-crispy-formset-modal-0.1/django_crispy_formset_modal.egg-info/requires.txt +1 -0
- django-crispy-formset-modal-0.1/django_crispy_formset_modal.egg-info/top_level.txt +1 -0
- django-crispy-formset-modal-0.1/setup.cfg +18 -0
- django-crispy-formset-modal-0.1/setup.py +36 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Blas Isaias Fernández
|
|
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.
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: django-crispy-formset-modal
|
|
3
|
+
Version: 0.1
|
|
4
|
+
Summary: Django app that provides an easy way to manage and manipulate formsets using modals with Django Crispy Forms.
|
|
5
|
+
Home-page: https://github.com/blasferna/django-crispy-formset-modal
|
|
6
|
+
Author: Blas Fernandez
|
|
7
|
+
Author-email: blasferna@gmail.com
|
|
8
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
9
|
+
Classifier: Framework :: Django
|
|
10
|
+
Classifier: Framework :: Django :: 3.2
|
|
11
|
+
Classifier: Framework :: Django :: 4.0
|
|
12
|
+
Classifier: Framework :: Django :: 4.1
|
|
13
|
+
Classifier: Framework :: Django :: 4.2
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Natural Language :: English
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Classifier: Programming Language :: Python
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
25
|
+
Requires-Python: >=3.7
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
|
|
29
|
+
# django-crispy-formset-modal
|
|
30
|
+
|
|
31
|
+
Reusable Django app that provides an easy way to manage and manipulate formsets using modals with Django Crispy Forms. It enables you to dynamically add, edit, and delete formsets on the frontend.
|
|
32
|
+
|
|
33
|
+

|
|
34
|
+
|
|
35
|
+
## Features
|
|
36
|
+
|
|
37
|
+
* Dynamic formset operations: Add, edit, and delete formsets dynamically in a modal on the frontend.
|
|
38
|
+
* Generates an HTML table according to the layout definition, allowing you to determine which fields to display as columns.
|
|
39
|
+
* Provides the option to define which numeric fields will be used for a totalizer at the footer of the corresponding field's column.
|
|
40
|
+
* Enables mass deletion of records from the HTML table, thanks to the generation of a selection column with checkboxes that can be selected individually or collectively to delete multiple records at once.
|
|
41
|
+
* Offers support for various templates packs, including [Bootstrap 4](https://github.com/django-crispy-forms/crispy-bootstrap4), [Bootstrap 5](https://github.com/django-crispy-forms/crispy-bootstrap5), [Tailwind](https://github.com/django-crispy-forms/crispy-tailwind), and [Bulma](https://github.com/ckrybus/crispy-bulma).
|
|
42
|
+
|
|
43
|
+
## Dependencies
|
|
44
|
+
|
|
45
|
+
* [Django Crispy Forms](https://github.com/django-crispy-forms/django-crispy-forms): Django Crispy Formset Modal relies on Django Crispy Forms for form rendering
|
|
46
|
+
* [Django Extra Views](https://github.com/AndrewIngram/django-extra-views): For handling views with formsets.
|
|
47
|
+
* jQuery: Used to enable dynamic functionality.
|
|
48
|
+
## Installation
|
|
49
|
+
|
|
50
|
+
1. Install the package using pip:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
pip install django-crispy-formset-modal
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
2. Add `crispy_formset_modal` to your `INSTALLED_APPS` in `settings.py`:
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
INSTALLED_APPS = [
|
|
60
|
+
...
|
|
61
|
+
'crispy_formset_modal',
|
|
62
|
+
...
|
|
63
|
+
]
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Usage
|
|
67
|
+
|
|
68
|
+
For detailed instructions on how to use Django Crispy Formset Modal, please refer to the [documentation](https://blasferna.github.io/django-crispy-formset-modal/) and check out the [demo](https://django-crispy-formset-modal.fly.dev/) for practical examples.
|
|
69
|
+
|
|
70
|
+
## Examples
|
|
71
|
+
|
|
72
|
+
The [demo](https://django-crispy-formset-modal.fly.dev/) provides various examples of how to use Django Crispy Formset Modal in different scenarios.
|
|
73
|
+
|
|
74
|
+
### Running the Demo App Locally
|
|
75
|
+
|
|
76
|
+
If you'd like to run the demo application on your local machine. Please follow the steps below:
|
|
77
|
+
|
|
78
|
+
#### Instructions
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
1. Clone this repository to your local machine:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
git clone https://github.com/blasferna/django-crispy-formset-modal.git
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
2. Navigate to the project's directory:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
cd django-crispy-formset-modal
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
3. Set up a virtual environment. This step helps to isolate the Python environment for this project:
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
python -m venv venv
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
4. Activate the virtual environment:
|
|
100
|
+
|
|
101
|
+
`On Windowds`
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
.\venv\Scripts\activate
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`On Unix or MacOS:`
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
source venv/bin/activate
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
5. Install the required dependencies:
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
pip install -r requirements.txt
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
6. Apply migrations:
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
python manage.py migrate
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
7. Start the local development server:
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
python manage.py runserver
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
8. Visit `http://localhost:8000` on your browser to explore the demo application.
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
## License
|
|
135
|
+
|
|
136
|
+
Django Crispy Formset Modal is released under the [MIT License](https://github.com/blasferna/django-crispy-formset-modal/blob/main/LICENSE).
|
|
137
|
+
|
|
138
|
+
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# django-crispy-formset-modal
|
|
2
|
+
|
|
3
|
+
Reusable Django app that provides an easy way to manage and manipulate formsets using modals with Django Crispy Forms. It enables you to dynamically add, edit, and delete formsets on the frontend.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
* Dynamic formset operations: Add, edit, and delete formsets dynamically in a modal on the frontend.
|
|
10
|
+
* Generates an HTML table according to the layout definition, allowing you to determine which fields to display as columns.
|
|
11
|
+
* Provides the option to define which numeric fields will be used for a totalizer at the footer of the corresponding field's column.
|
|
12
|
+
* Enables mass deletion of records from the HTML table, thanks to the generation of a selection column with checkboxes that can be selected individually or collectively to delete multiple records at once.
|
|
13
|
+
* Offers support for various templates packs, including [Bootstrap 4](https://github.com/django-crispy-forms/crispy-bootstrap4), [Bootstrap 5](https://github.com/django-crispy-forms/crispy-bootstrap5), [Tailwind](https://github.com/django-crispy-forms/crispy-tailwind), and [Bulma](https://github.com/ckrybus/crispy-bulma).
|
|
14
|
+
|
|
15
|
+
## Dependencies
|
|
16
|
+
|
|
17
|
+
* [Django Crispy Forms](https://github.com/django-crispy-forms/django-crispy-forms): Django Crispy Formset Modal relies on Django Crispy Forms for form rendering
|
|
18
|
+
* [Django Extra Views](https://github.com/AndrewIngram/django-extra-views): For handling views with formsets.
|
|
19
|
+
* jQuery: Used to enable dynamic functionality.
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
1. Install the package using pip:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
pip install django-crispy-formset-modal
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
2. Add `crispy_formset_modal` to your `INSTALLED_APPS` in `settings.py`:
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
INSTALLED_APPS = [
|
|
32
|
+
...
|
|
33
|
+
'crispy_formset_modal',
|
|
34
|
+
...
|
|
35
|
+
]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Usage
|
|
39
|
+
|
|
40
|
+
For detailed instructions on how to use Django Crispy Formset Modal, please refer to the [documentation](https://blasferna.github.io/django-crispy-formset-modal/) and check out the [demo](https://django-crispy-formset-modal.fly.dev/) for practical examples.
|
|
41
|
+
|
|
42
|
+
## Examples
|
|
43
|
+
|
|
44
|
+
The [demo](https://django-crispy-formset-modal.fly.dev/) provides various examples of how to use Django Crispy Formset Modal in different scenarios.
|
|
45
|
+
|
|
46
|
+
### Running the Demo App Locally
|
|
47
|
+
|
|
48
|
+
If you'd like to run the demo application on your local machine. Please follow the steps below:
|
|
49
|
+
|
|
50
|
+
#### Instructions
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
1. Clone this repository to your local machine:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
git clone https://github.com/blasferna/django-crispy-formset-modal.git
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
2. Navigate to the project's directory:
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
cd django-crispy-formset-modal
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
3. Set up a virtual environment. This step helps to isolate the Python environment for this project:
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
python -m venv venv
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
4. Activate the virtual environment:
|
|
72
|
+
|
|
73
|
+
`On Windowds`
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
.\venv\Scripts\activate
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`On Unix or MacOS:`
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
source venv/bin/activate
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
5. Install the required dependencies:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
pip install -r requirements.txt
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
6. Apply migrations:
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
python manage.py migrate
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
7. Start the local development server:
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
python manage.py runserver
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
8. Visit `http://localhost:8000` on your browser to explore the demo application.
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
## License
|
|
107
|
+
|
|
108
|
+
Django Crispy Formset Modal is released under the [MIT License](https://github.com/blasferna/django-crispy-formset-modal/blob/main/LICENSE).
|
|
109
|
+
|
|
110
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
class ModalSize:
|
|
2
|
+
SM = "sm"
|
|
3
|
+
MD = "md"
|
|
4
|
+
LG = "lg"
|
|
5
|
+
XL = "xl"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ModalPlacement:
|
|
9
|
+
TOP_LEFT = "top-left"
|
|
10
|
+
TOP_CENTER = "top-center"
|
|
11
|
+
TOP_RIGHT = "top-right"
|
|
12
|
+
CENTER_LEFT = "center-left"
|
|
13
|
+
CENTER = "center"
|
|
14
|
+
CENTER_RIGHT = "center-right"
|
|
15
|
+
BOTTOM_LEFT = "bottom-left"
|
|
16
|
+
BOTTOM_CENTER = "bottom-center"
|
|
17
|
+
BOTTOM_RIGHT = "bottom-right"
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
from crispy_forms.layout import Div, Field
|
|
2
|
+
from crispy_forms.layout import Layout as CrispyLayout
|
|
3
|
+
from crispy_forms.layout import LayoutObject
|
|
4
|
+
from django import forms
|
|
5
|
+
from django.conf import settings
|
|
6
|
+
from django.forms.formsets import DELETION_FIELD_NAME
|
|
7
|
+
from django.forms.utils import pretty_name
|
|
8
|
+
from django.template.loader import render_to_string
|
|
9
|
+
|
|
10
|
+
from crispy_formset_modal import ModalPlacement, ModalSize
|
|
11
|
+
|
|
12
|
+
HIDDEN_CLASSES = {
|
|
13
|
+
"tailwind": "hidden",
|
|
14
|
+
"bootstrap4": "d-none",
|
|
15
|
+
"bootstrap5": "d-none",
|
|
16
|
+
"bulma": "is-hidden",
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ModalEditLayout(CrispyLayout):
|
|
21
|
+
def __init__(self, *fields):
|
|
22
|
+
css_class = HIDDEN_CLASSES.get(settings.CRISPY_TEMPLATE_PACK, "")
|
|
23
|
+
|
|
24
|
+
self.fields = list(
|
|
25
|
+
fields
|
|
26
|
+
+ (Div(Field("DELETE", css_class="formset-delete"), css_class=css_class),)
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ModalEditFormsetLayout(LayoutObject):
|
|
31
|
+
template = "crispy_formset_modal/{template_pack}/table.html"
|
|
32
|
+
|
|
33
|
+
def __init__(
|
|
34
|
+
self,
|
|
35
|
+
formset_name,
|
|
36
|
+
list_display=[],
|
|
37
|
+
sum_columns=[],
|
|
38
|
+
modal_size=ModalSize.MD,
|
|
39
|
+
modal_placement=ModalPlacement.CENTER,
|
|
40
|
+
):
|
|
41
|
+
self.formset_name = formset_name
|
|
42
|
+
self.list_display = list_display
|
|
43
|
+
self.sum_columns = sum_columns
|
|
44
|
+
self.modal_size = modal_size
|
|
45
|
+
self.modal_placement = modal_placement
|
|
46
|
+
|
|
47
|
+
def get_html_name(self, empty_form, field):
|
|
48
|
+
return empty_form[field].html_name.split("__prefix__")[1][1:]
|
|
49
|
+
|
|
50
|
+
def has_summary(self, field):
|
|
51
|
+
return field in self.sum_columns
|
|
52
|
+
|
|
53
|
+
def get_headers(self, empty_form):
|
|
54
|
+
fields = empty_form.fields
|
|
55
|
+
# id, delete and hidden fields are excluded by the default list display fields
|
|
56
|
+
list_display = [
|
|
57
|
+
{
|
|
58
|
+
"field": self.get_html_name(empty_form, k),
|
|
59
|
+
"title": pretty_name(k) if v.label is None else v.label,
|
|
60
|
+
"type": self._get_field_type(v),
|
|
61
|
+
"has_summary": self.has_summary(k),
|
|
62
|
+
}
|
|
63
|
+
for k, v in fields.items()
|
|
64
|
+
if k not in ("id", DELETION_FIELD_NAME)
|
|
65
|
+
and getattr(v.widget, "input_type", None) != "hidden"
|
|
66
|
+
]
|
|
67
|
+
if not self.list_display:
|
|
68
|
+
return list_display
|
|
69
|
+
return [
|
|
70
|
+
{
|
|
71
|
+
"field": self.get_html_name(empty_form, field),
|
|
72
|
+
"title": pretty_name(field)
|
|
73
|
+
if fields.get(field).label is None
|
|
74
|
+
else fields.get(field).label,
|
|
75
|
+
"type": self._get_field_type(fields.get(field)),
|
|
76
|
+
"has_summary": self.has_summary(field),
|
|
77
|
+
}
|
|
78
|
+
for field in self.list_display
|
|
79
|
+
if field not in ("id", DELETION_FIELD_NAME)
|
|
80
|
+
and getattr(fields.get(field).widget, "input_type", None) != "hidden"
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
def _get_field_type(self, field):
|
|
84
|
+
_type = "text"
|
|
85
|
+
if isinstance(field, forms.DecimalField):
|
|
86
|
+
_type = "numeric"
|
|
87
|
+
if isinstance(field, forms.FloatField):
|
|
88
|
+
_type = "numeric"
|
|
89
|
+
if isinstance(field, forms.IntegerField):
|
|
90
|
+
_type = "numeric"
|
|
91
|
+
if isinstance(field, forms.BooleanField):
|
|
92
|
+
_type = "bool"
|
|
93
|
+
if isinstance(field, forms.DateField):
|
|
94
|
+
_type = "date"
|
|
95
|
+
return _type
|
|
96
|
+
|
|
97
|
+
def render(self, *args, **kwargs):
|
|
98
|
+
form = args[0] # noqa F841
|
|
99
|
+
if len(args) > 2:
|
|
100
|
+
context = args[2]
|
|
101
|
+
else:
|
|
102
|
+
context = args[1]
|
|
103
|
+
template_pack = kwargs.get("template_pack", settings.CRISPY_TEMPLATE_PACK)
|
|
104
|
+
formset = None
|
|
105
|
+
view = context.get("view")
|
|
106
|
+
inlines = context.get("inlines", [])
|
|
107
|
+
|
|
108
|
+
i = 0
|
|
109
|
+
for inline in view.inlines:
|
|
110
|
+
if inline.__name__ == self.formset_name:
|
|
111
|
+
formset = inlines[i]
|
|
112
|
+
i += 1
|
|
113
|
+
|
|
114
|
+
context.update(
|
|
115
|
+
{
|
|
116
|
+
"formset": formset,
|
|
117
|
+
"list_display": self.list_display,
|
|
118
|
+
"headers": self.get_headers(formset.empty_form),
|
|
119
|
+
"has_footer": len(self.sum_columns) > 0,
|
|
120
|
+
"form_template_name": (
|
|
121
|
+
f"crispy_formset_modal/{template_pack}/form.html"
|
|
122
|
+
),
|
|
123
|
+
"modal_template_name": (
|
|
124
|
+
f"crispy_formset_modal/{template_pack}/modal.html"
|
|
125
|
+
),
|
|
126
|
+
"template_pack": template_pack,
|
|
127
|
+
"modal_size": self.modal_size,
|
|
128
|
+
"modal_placement": self.modal_placement,
|
|
129
|
+
}
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
template = self.template.format(template_pack=template_pack)
|
|
133
|
+
return render_to_string(template, context.flatten())
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# django-crispy-formset-modal
|
|
2
|
+
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
|
3
|
+
# This file is distributed under the same license as the PACKAGE package.
|
|
4
|
+
# Blas Fernandez blasferna@gmail.com, YEAR.
|
|
5
|
+
#
|
|
6
|
+
#, fuzzy
|
|
7
|
+
msgid ""
|
|
8
|
+
msgstr ""
|
|
9
|
+
"Project-Id-Version: PACKAGE VERSION\n"
|
|
10
|
+
"Report-Msgid-Bugs-To: \n"
|
|
11
|
+
"POT-Creation-Date: 2023-05-16 15:55-0400\n"
|
|
12
|
+
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
13
|
+
"Last-Translator: Blas Fernandez blasferna@gmail.com\n"
|
|
14
|
+
"Language: Spanish\n"
|
|
15
|
+
"MIME-Version: 1.0\n"
|
|
16
|
+
"Content-Type: text/plain; charset=UTF-8\n"
|
|
17
|
+
"Content-Transfer-Encoding: 8bit\n"
|
|
18
|
+
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
19
|
+
|
|
20
|
+
#: crispy_formset_modal/templates/crispy_formset_modal/bootstrap4/modal.html:7
|
|
21
|
+
msgid "Edit"
|
|
22
|
+
msgstr "Editar"
|
|
23
|
+
|
|
24
|
+
#: crispy_formset_modal/templates/crispy_formset_modal/bootstrap4/modal.html:17
|
|
25
|
+
#: crispy_formset_modal/templates/crispy_formset_modal/bootstrap4/table.html:70
|
|
26
|
+
msgid "Delete"
|
|
27
|
+
msgstr "Eliminar"
|
|
28
|
+
|
|
29
|
+
#: crispy_formset_modal/templates/crispy_formset_modal/bootstrap4/modal.html:18
|
|
30
|
+
msgid "Close"
|
|
31
|
+
msgstr "Cerrar"
|
|
32
|
+
|
|
33
|
+
#: crispy_formset_modal/templates/crispy_formset_modal/bootstrap4/table.html:50
|
|
34
|
+
msgid "No data"
|
|
35
|
+
msgstr "No hay datos"
|
|
36
|
+
|
|
37
|
+
#: crispy_formset_modal/templates/crispy_formset_modal/bootstrap4/table.html:69
|
|
38
|
+
msgid "Add"
|
|
39
|
+
msgstr "Agregar"
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# django-crispy-formset-modal
|
|
2
|
+
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
|
3
|
+
# This file is distributed under the same license as the PACKAGE package.
|
|
4
|
+
# Blas Fernandez blasferna@gmail.com, YEAR.
|
|
5
|
+
#
|
|
6
|
+
#, fuzzy
|
|
7
|
+
msgid ""
|
|
8
|
+
msgstr ""
|
|
9
|
+
"Project-Id-Version: PACKAGE VERSION\n"
|
|
10
|
+
"Report-Msgid-Bugs-To: \n"
|
|
11
|
+
"POT-Creation-Date: 2023-05-16 15:55-0400\n"
|
|
12
|
+
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
13
|
+
"Last-Translator: Blas Fernandez blasferna@gmail.com\n"
|
|
14
|
+
"Language: Spanish\n"
|
|
15
|
+
"MIME-Version: 1.0\n"
|
|
16
|
+
"Content-Type: text/plain; charset=UTF-8\n"
|
|
17
|
+
"Content-Transfer-Encoding: 8bit\n"
|
|
18
|
+
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
19
|
+
|
|
20
|
+
#: crispy_formset_modal/static/crispy_formset_modal/js/crispy-formset-modal.min.js:33
|
|
21
|
+
#: js/src/modal-form.js:88
|
|
22
|
+
msgid "Editing row #"
|
|
23
|
+
msgstr "Editando registro #"
|
|
24
|
+
|
|
25
|
+
#: js/src/formset-modal.js:29
|
|
26
|
+
msgid "Edit"
|
|
27
|
+
msgstr "Editar"
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
!function(t){"use strict";const e='\n<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pencil" viewBox="0 0 16 16">\n <path d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z"/>\n</svg>\n';let s=window.gettext;const i=Object.prototype.hasOwnProperty;function a(){function t(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)}return`${t()+t()}-${t()}-${(4095&parseInt(t(),16)|16384).toString(16)}-${(16383&parseInt(t(),16)|32768).toString(16)}-${t()+t()+t()}`}function o(t){let e="";var s,a;return"select"===t.tagName.toLowerCase()?e=t.options[t.selectedIndex].innerText:(s=t,a="inputmask",i.call(s,a)?e=t.inputmask.undoValue:"date"==t.getAttribute("type")?t.value&&(e=new Date(...t.value.split("-")).toLocaleDateString()):e="checkbox"==t.getAttribute("type")?t.checked?"on":"off":t.value),e}function r(){window.hasOwnProperty("calculatedFields")&&calculatedFields.forEach((function(t){t.executeAll()}))}function n(){window.hasOwnProperty("calculatedFields")&&window.calculatedFields.forEach((function(t){let e=t.field,s=e.getAttribute("id");document.querySelector("td[data-source='"+s+"']")&&(e.hasAttribute("data-event")||(e.addEventListener("oncalculate",(function(){let t=o(e),i=document.querySelector("td[data-source='"+s+"']");i&&(i.innerText=t)})),e.setAttribute("data-event",!0)))}))}function l(t,e){return!!e.some((e=>e.id===t))&&e.find((e=>e.id===t))}window.django&&window.django.jsi18n_initialized||(s=t=>t);const d={hidden:"d-none",inlineFlex:"d-inline-flex",flex:"d-flex",relative:"position-relative",textRight:"text-right",textCenter:"text-center",alignMiddle:"align-middle",pointer:"cfm-cursor-pointer",editBtn:"btn-open-row btn btn-sm btn-primary",checkbox:"checkbox",td:"cfm-td",tr:"cfm-tr",selectionMark:"cfm-selection-border",p0:"p-0",opacity50:"cfm-opacity-50",opacity100:"cfm-opacity-100",backdrop:"cfm-modal-backdrop",justifyStart:"justify-content-start",justifyCenter:"justify-content-center",justifyEnd:"justify-content-end",itemsStart:"align-items-start",itemsCenter:"align-items-center",itemsEnd:"align-items-end"},c={sm:"modal-sm",md:"modal-md",lg:"modal-lg",xl:"modal-xl"},m={bootstrap4:{classes:d,sizes:c,pencilIcon:e},bootstrap5:{classes:{...d,textRight:"text-end"},sizes:c,pencilIcon:e},tailwind:{classes:{hidden:"hidden",inlineFlex:"inline-flex",flex:"flex",relative:"relative",textRight:"text-right",textCenter:"text-center",alignMiddle:"align-middle",pointer:"cursor-pointer",editBtn:"btn-open-row mx-auto p-1 border border-transparent rounded-full shadow-sm text-gray-500 bg-gray-100 hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-gray-500",checkbox:"w-4 rounded border-gray-300 focus:ring-indigo-500 text-indigo-600 h-4",td:"whitespace-nowrap px-3 py-3 text-sm text-gray-500",tr:"divide-x divide-gray-200 border-b",selectionMark:"absolute inset-y-0 left-0 w-0.5 bg-indigo-600 selection-border",p0:"p-0",opacity50:"opacity-50",opacity100:"opacity-100",backdrop:"transition-opacity ease-in-out duration-300 opacity-0 bg-gray-800 fixed inset-0 z-40",justifyStart:"justify-start",justifyCenter:"justify-center",justifyEnd:"justify-end",itemsStart:"items-start",itemsCenter:"items-center",itemsEnd:"items-end"},sizes:{sm:"max-w-lg",md:"max-w-4xl",lg:"max-w-5xl",xl:"max-w-6xl"},pencilIcon:'\n<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">\n <path d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z" />\n</svg>\n'},bulma:{classes:{hidden:"is-hidden",inlineFlex:"is-inline-flex",flex:"is-flex",relative:"is-relative",textRight:"has-text-right",textCenter:"has-text-center",alignMiddle:"is-vcentered",pointer:"cfm-cursor-pointer",editBtn:"btn-open-row button is-primary is-small",checkbox:"checkbox",td:"cfm-td",tr:"cfm-tr",selectionMark:"cfm-selection-border",p0:"p-0",opacity50:"cfm-opacity-50",opacity100:"cfm-opacity-100",backdrop:"cfm-modal-backdrop",justifyStart:"is-justify-content-start",justifyCenter:"is-justify-content-center",justifyEnd:"is-justify-content-end",itemsStart:"is-align-items-start",itemsCenter:"is-align-items-center",itemsEnd:"is-align-items-end"},sizes:{sm:"modal-sm",md:"modal-md",lg:"modal-lg",xl:"modal-xl"},pencilIcon:e}},h="formset";class u{constructor(e,s){var i=this;this.opts=t.extend({},u.defaults,s),this.$formset=t(e),this.$formset.attr("data-uuid",a()),this.$emptyForm=this.$formset.find(this.opts.emptyForm),this.$body=this.$formset.find(this.opts.body),this.$add=this.$formset.find(this.opts.add),this.formsetPrefix=t(e).data("formset-prefix"),this.addForm=t.proxy(this,"addForm"),this.$add.click(this.addForm),this.$formset.on("formAdded formDeleted",this.opts.form,t.proxy(this,"checkMaxForms")),this.$forms().each((function(e,s){t(s),i.bindForm(t(this),e)})),this.$formset.data(h,this);t.each(["animateForms"],(function(t,e){e in i.opts&&i.opts[e]&&i[e]()}))}static getOrCreate(e,s){var i=t(e).data(h);return i||(i=new u(e,s)),i}addForm(){if(this.hasMaxForms())throw new Error("MAX_NUM_FORMS reached");var e=this.totalFormCount();this.$managementForm("TOTAL_FORMS").val(e+1);var s=this.$emptyForm.html().replace(new RegExp("__prefix__","g"),e).replace(new RegExp("<\\\\/script>","g"),"<\/script>"),i=t(t.parseHTML(s,this.$body.document,!0));this.$body.append(i);var a=i.filter(this.opts.form);return this.bindForm(a,e),this.opts.newFormCallback&&this.opts.newFormCallback(a),a}bindForm(e,s){var i=this.formsetPrefix+"-"+s;e.data(h+"__formPrefix",i);var a=e.find("[name="+i+"-DELETE]");a.change((function(s){a.is(":checked")?(e.attr("data-formset-form-deleted",""),e.find(":required").data(h+"-required-field",!0).prop("required",!1),e.find("input[pattern]").each((function(){var e=t(this).attr("pattern");t(this).data(h+"-field-pattern",e).removeAttr("pattern")})),e.trigger("formDeleted")):(e.removeAttr("data-formset-form-deleted"),e.find("*").filter((function(){return!0===t(this).data(h+"-required-field")})).prop("required",!0),e.find("input").each((function(){var e=t(this).data(h+"-field-pattern");e&&t(this).attr("pattern",e)})),e.trigger("formAdded"))})).trigger("change"),e.find(this.opts.deleteButton).bind("click",(function(){a.attr("checked",!0).change()}))}$forms(){return this.$body.find(this.opts.form)}$managementForm(t){return this.$formset.find("[name="+this.formsetPrefix+"-"+t+"]")}totalFormCount(){return this.$forms().length}deletedFormCount(){return this.$forms().filter("[data-formset-form-deleted]").length}clear(){this.$forms().each((function(e,s){t(s).find(":input").not(":button, :submit, :reset, :hidden, :checkbox, :radio").val("")}))}deleteAll(){this.$forms().each((function(e,s){t(s).find("[deletecheckbox]").prop("checked",!0).change()}))}activeFormCount(){return this.totalFormCount()-this.deletedFormCount()}openRownum(){var t=this.$formset.find("tr.row-open").attr("data-rownum");return null!=typeof t?parseInt(t):0}hasMaxForms(){var t=parseInt(this.$managementForm("MAX_NUM_FORMS").val(),10)||1e3;return this.activeFormCount()>=t}checkMaxForms(){this.hasMaxForms()?(this.$formset.addClass(this.opts.hasMaxFormsClass),this.$add.attr("disabled","disabled")):(this.$formset.removeClass(this.opts.hasMaxFormsClass),this.$add.removeAttr("disabled"))}animateForms(){this.$formset.on("formAdded",this.opts.form,(function(){var e=t(this);e.slideUp(0),e.slideDown()})).on("formDeleted",this.opts.form,(function(){t(this).slideUp()})),this.$forms().filter("[data-formset-form-deleted]").slideUp(0)}}u.defaults={form:"[data-formset-form]",emptyForm:"script[type=form-template][data-formset-empty-form]",body:"[data-formset-body]",add:"[data-formset-add]",deleteButton:"[data-formset-delete-button]",hasMaxFormsClass:"has-max-forms",animateForms:!1,newFormCallback:!1};const f={placement:"center",size:"md",templatePack:null,onHide:()=>{},onShow:()=>{},onToggle:()=>{}};class p{constructor(t=null,e={}){this._targetEl=t,this._parentEl=t.parentElement,this._options={...f,...e},this._isHidden=!0,this._init(),this._addEventListeners()}_init(){this._getPlacementClasses().map((t=>{this._targetEl.classList.add(t)})),this._clearSize(),this._getSizeClasses().map((t=>{this._targetEl.firstElementChild.classList.add(t)}))}_createBackdrop(t){if(this._isHidden){const e=document.createElement("div");e.setAttribute("data-ref-id",t),e.setAttribute("modal-backdrop",""),e.classList.add(...this._getClasses("backdrop")),this._parentEl.append(e),e.offsetWidth,e.classList.add(...this._getClasses("opacity50"))}}_destroyBackdropEl(){if(!this._isHidden){let t=this._targetEl.getAttribute("data-ref-id");document.querySelector(`[modal-backdrop][data-ref-id="${t}"]`).remove()}}_getPlacementClasses(){let t=this;switch(this._options.placement){case"top-left":return[t._getClasses("justifyStart",!1),t._getClasses("itemsStart",!1)];case"top-center":return[t._getClasses("justifyCenter",!1),t._getClasses("itemsStart",!1)];case"top-right":return[t._getClasses("justifyEnd",!1),t._getClasses("itemsStart",!1)];case"center-left":return[t._getClasses("justifyStart",!1),t._getClasses("itemsCenter",!1)];case"center":default:return[t._getClasses("justifyCenter",!1),t._getClasses("itemsCenter",!1)];case"center-right":return[t._getClasses("justifyEnd",!1),t._getClasses("itemsCenter",!1)];case"bottom-left":return[t._getClasses("justifyStart",!1),t._getClasses("itemsEnd",!1)];case"bottom-center":return[t._getClasses("justifyCenter",!1),t._getClasses("itemsEnd",!1)];case"bottom-right":return[t._getClasses("justifyEnd",!1),t._getClasses("itemsEnd",!1)]}}_getSizeClasses(){return m[this._options.templatePack].sizes[this._options.size].split(" ")}_getClasses(t,e=!1){let s=m[this._options.templatePack].classes[t];return e?s:s.split(" ")}_clearSize(){const t=this._targetEl.firstElementChild,e=m[this._options.templatePack].sizes;for(const s in e)e.hasOwnProperty(s)&&t.classList.remove(e[s])}_addEventListeners(){let t=this;this._targetEl.addEventListener("keyup",(function(e){"Escape"===e.key&&t.hide()}))}toggle(){this._isHidden?this.show():this.hide(),this._options.onToggle(this)}show(){const t=a();this._targetEl.classList.add(...this._getClasses("flex")),this._targetEl.classList.remove(...this._getClasses("hidden")),this._targetEl.setAttribute("aria-modal","true"),this._targetEl.setAttribute("role","dialog"),this._targetEl.removeAttribute("aria-hidden"),this._targetEl.setAttribute("data-ref-id",t),this._createBackdrop(t),this._isHidden=!1,document.body.classList.add("modal-open"),this._options.onShow(this);let e=this._targetEl.querySelector('select, input:not([type="hidden"]');e&&(e.setAttribute("tabindex","0"),e.focus()),this._targetEl.offsetWidth,this._targetEl.classList.add(...this._getClasses("opacity100"))}hide(){this._targetEl.classList.add(...this._getClasses("hidden")),this._targetEl.classList.remove(...this._getClasses("flex")),this._targetEl.setAttribute("aria-hidden","true"),this._targetEl.removeAttribute("aria-modal"),this._targetEl.removeAttribute("role"),this._destroyBackdropEl(),this._isHidden=!0,document.body.classList.remove("modal-open"),this._options.onHide(this)}}const g={parent:null,modalId:null,onKeyUp:function(){},onClose:function(){},onOpen:function(){}};class _{constructor(t,e={}){this.targetEl=t,this._options={...g,...e},this.modalId=this._options.modalId,this._modalEl=null,this._modalTitleEl=null,this._modalDeleteBt=null,this.modalInstance=!1,this.rownum=null,this._init(),this._addEvents()}_init(){this._modalEl=document.getElementById(this.modalId),this._modalTitleEl=this._modalEl.querySelector(".modal-title"),this._modalDeleteBt=this._modalEl.querySelector(".formset-delete"),this._createModal()}_addEvents(){let t=this;this._modalEl.querySelectorAll('[data-formset-modal-toggle="'+this.modalId+'"]').forEach((function(e){e.addEventListener("click",(function(){t.close()}))}))}hasFieldError(t){let e=this.targetEl.querySelector(`#div_${t}`),s=!1,i="";return e.querySelectorAll(".field-error").forEach((function(t){s=!0,i=t.innerText})),{error:s,text:i}}hasNonFieldError(){return null!=this.targetEl.querySelector(".non-field-errors")}_hiddeDefaultDeleteBt(t){t.parentNode.classList.add("d-none")}_createModal(){let t=this;if(!this.modalInstance){let e=this.targetEl.querySelector(".formset-delete"),s=new p(this._modalEl,{placement:t._options.placement,size:t._options.size,templatePack:t._options.templatePack,onHide:function(e){t._onModalClose(e)},onShow:function(e){t._onModalShow(e)}});s._targetEl.addEventListener("keyup",(function(e){t._options.onKeyUp(e,t)})),this.modalInstance=s,this._hiddeDefaultDeleteBt(e)}}_onModalShow(t){this._options.onOpen(this);let e=this._options.parent.targetEl.querySelector(".btn-open-row[data-formset-modal-toggle='"+this.modalId+"']").closest("tr");this._modalTitleEl.innerText=s("Editing row #")+this.rownum,e.classList.add("row-open")}_onModalClose(t){this._options.onClose(this);let e=this._options.parent.targetEl.querySelector(".btn-open-row[data-formset-modal-toggle='"+this.modalId+"']");if(e){e.closest("tr").classList.remove("row-open")}}isDeleted(){return this.targetEl.hasAttribute("data-formset-form-deleted")}isSelected(){return this.targetEl.hasAttribute("data-formset-form-selected")}open(){this.modalInstance.show()}close(){this.modalInstance.hide()}}const y="tabular",b="modal",E={editText:s("Edit")};class C{constructor(t){this._id=t,this.targetEl=document.getElementById(this._id),this.variant=y,this.$formset=null,this._options={...E},this._modalForms=[],this._deleteBt=null,this._table=null,this._tbody=null,this._tfoot=null,this._init(),this._addEvents()}_init(){this.variant=this._getVariant(),this.templatePack=this._getTemplatePack(),this.modalSize=this._getModalSize(),this.modalPlacement=this._getModalPlacement(),this.$formset=t(`#${this._id}`),this.$formset.formset({animateForms:!0}),this.variant!==b&&this.variant!=y||(this._table=this.targetEl.querySelector("table"),this._tbody=this._table.querySelector("tbody"),this._tfoot=this._table.querySelector("tfoot"),this._emptyState=this._tbody.innerHTML),this.variant===b&&(this._deleteBt=this.targetEl.querySelector(".delete-selected"),this._checkInitials(),this._configureSelectAllToggler(),this._refresh())}_getVariant(){return this.targetEl.getAttribute("data-formset-variant")}_getTemplatePack(){return this.targetEl.getAttribute("data-template-pack")}_getClasses(t){return m[this.templatePack].classes[t].split(" ")}_getPencilIcon(){return m[this.templatePack].pencilIcon}_getModalSize(){return this.targetEl.getAttribute("data-modal-size")}_getModalPlacement(){return this.targetEl.getAttribute("data-modal-placement")}_getModalFormInstanceByRownum(t){let e=!1;return this._modalForms.forEach((function(s){s.rownum!==t||s.isDeleted()||(e=s)})),e}_addEvents(){let t=this;this.$formset.on("formAdded",(function(e){t._onFormsetAdded(e)})),this.$formset.on("formDeleted",(function(e){t._onFormsetDeleted(e)}))}_checkInitials(){let t=this,e=[];this.targetEl.querySelectorAll("[data-formset-modal-toggle]").forEach((function(s){let i=s.closest("[data-formset-form]"),a=s.getAttribute("data-formset-modal-toggle");e.includes(a)||t._newModalForm(i,a),e.push(a)}))}_newModalForm(t,e){let s=this,i={parent:s,modalId:e,size:s.modalSize,placement:s.modalPlacement,templatePack:s.templatePack,onKeyUp:function(t,e){s._onModalFormKeyUp(t,e)},onOpen:function(t){s._onModalFormOpen(t)},onClose:function(t){s._onModalFormClose(t)}},a=new _(t,i);return s._modalForms.push(a),a}_onFormsetAdded(e){if(this.variant===b){let s=a();t(this.targetEl).find("#__dialog_id__").attr("id",s),t(this.targetEl).find('[data-formset-modal-toggle="__dialog_id__"]').attr("data-formset-modal-toggle",s),this._newModalForm(e.target,s).open()}window.hasOwnProperty("calculatedFields")&&(window.resetCalculatedFields(),n())}_onFormsetDeleted(){this.variant==b&&this._refresh(),r()}_onModalFormKeyUp(t,e){if(t.ctrlKey&&(38===t.keyCode||40===t.keyCode)){t.preventDefault();let s=e.rownum,i=this.$formset.formset("getOrCreate"),a=i.activeFormCount();if(38==t.keyCode&&s>1){e.close(),this._getModalFormInstanceByRownum(s-1).open()}if(40===t.keyCode){if(s<a){e.close(),this._getModalFormInstanceByRownum(s+1).open()}s==a&&(e.close(),i.addForm())}}}_onModalFormOpen(t){this._refresh()}_onModalFormClose(t){this._refresh()}_configureSelectAllToggler(){let t=this,e=this._table,s=this.targetEl.querySelector(".select-all"),i=this.targetEl.querySelector(".delete-selected");s.addEventListener("change",(function(i){let a=s.checked;e.querySelectorAll(".select-row").forEach((function(e){let s=e.closest("tr"),i=e.closest("td"),o=s.querySelector("[data-formset-modal-toggle]").getAttribute("data-formset-modal-toggle"),r=document.getElementById(o).closest("[data-formset-form]");e.checked=a,t._checker(s,i,r,e)}))})),i.addEventListener("click",(function(e){t.targetEl.querySelectorAll("[data-formset-form-selected]").forEach((function(t){let e=t.querySelector(".formset-delete");e.checked=!0,e.dispatchEvent(new Event("change"))}))}))}_checkSelectAllState(){let t=this._table,e=this.targetEl.querySelector(".delete-selected"),s=!1,i=t.querySelector(".select-all"),a=t.querySelectorAll("tbody tr").length,o=t.querySelectorAll("tr.selected").length;o===a&&a>0?(i.checked=!0,i.indeterminate=!1,s=!0):(o!=a&&o>0&&(i.indeterminate=!0,i.checked=!1,s=!0),0===o&&(i.checked=!1,i.indeterminate=!1,s=!1)),s?(e.classList.remove(...this._getClasses("hidden")),e.classList.add(...this._getClasses("inlineFlex"))):(e.classList.remove(...this._getClasses("inlineFlex")),e.classList.add(...this._getClasses("hidden")))}_checker(t,e,s,i){let a=e.querySelector(".cfm-selection-border, .selection-border");if(a&&a.remove(),i.checked){let i=document.createElement("div");e.classList.add(...this._getClasses("relative")),i.classList.add(...this._getClasses("selectionMark")),e.prepend(i),s.setAttribute("data-formset-form-selected","selected"),t.classList.add("selected")}else i.classList.remove(...this._getClasses("relative")),t.classList.remove("selected"),s.removeAttribute("data-formset-form-selected");this._checkSelectAllState()}_refresh(){let t=this,e={},s=[],i=[];this._table.querySelectorAll("[data-field-name]").forEach((function(t){e[t.getAttribute("data-field-name")]={type:t.getAttribute("data-field-type"),hasSummary:t.hasAttribute("data-field-summary"),summary:0}})),s=Object.keys(e),this._modalForms.forEach((function(t){if(!t.isDeleted()){let e={};t.targetEl.querySelectorAll("input, select").forEach((function(i){let a=i.name.match(/(?<form>\w+)-(?<number>\w+)-(?<name>\w+)/);if(a){let r=a.groups.name;if(s.includes(r)){let s=o(i);e[r]={value:s,sourceId:i.getAttribute("id")},e.modalForm=t}}})),i.push(e)}})),function(t){for(;t.hasChildNodes();)t.removeChild(t.lastChild)}(this._tbody),0===i.length&&(this._tbody.innerHTML=this._emptyState);let a=1;i.forEach((function(i){i.modalForm.rownum=a;let o=document.createElement("tr");o.classList.add(...t._getClasses("tr")),o.setAttribute("data-rownum",a),i.modalForm.hasNonFieldError()&&(o.style="border: 1px solid #ff4545");let r=document.createElement("td"),n=document.createElement("input");n.setAttribute("type","checkbox"),n.classList.add(...t._getClasses("checkbox")),n.classList.add("select-row"),r.appendChild(n),r.classList.add(...t._getClasses("td")),n.addEventListener("change",(function(e){t._checker(o,r,i.modalForm.targetEl,e.target)})),o.appendChild(r);let l=document.createElement("td");l.classList.add(...t._getClasses("td")),l.classList.add(...t._getClasses("textRight")),l.classList.add(...t._getClasses("pointer")),l.innerText=a,l.addEventListener("click",(function(){i.modalForm.open()})),o.appendChild(l),s.forEach((function(s){let a=document.createElement("td"),r=i.modalForm.hasFieldError(i[s].sourceId);var n;a.classList.add(...t._getClasses("td")),r.error&&(a.style="border: 1px solid #ff4545",a.title=r.text),"bool"===e[s].type?(checked="on"===i[s].value?"checked":"",a.innerHTML=`<input type="checkbox" class="${t._getClasses("checkbox").join(" ")}" ${checked} disabled></input>`):a.innerText=i[s].value,"numeric"===e[s].type&&(a.classList.add(...t._getClasses("textRight")),e[s].hasSummary&&(e[s].summary=e[s].summary+(n=i[s].value,Number(n)))),"bool"!==e[s].type&&"date"!=e[s].type||a.classList.add(...t._getClasses("textCenter")),a.setAttribute("data-source",i[s].sourceId),o.appendChild(a)}));let d=document.createElement("td");d.classList.add(...t._getClasses("td")),d.classList.add(...t._getClasses("textCenter")),d.classList.add(...t._getClasses("p0")),d.classList.add(...t._getClasses("alignMiddle")),d.innerHTML=`\n <button type="button"\n title="${t._options.editText}" \n class="${t._getClasses("editBtn").join(" ")}"\n data-formset-modal-toggle="${i.modalForm.modalId}">\n ${t._getPencilIcon()}\n </button>`,d.querySelector(".btn-open-row").addEventListener("click",(function(t){i.modalForm.open()})),o.appendChild(d),t._tbody.appendChild(o),i.modalForm.isSelected()&&(n.checked=!0,t._checker(o,r,i.modalForm.targetEl,n)),a++})),this._tfoot&&this._tfoot.querySelectorAll("[data-summary-column]").forEach((function(t){let s=e[t.getAttribute("data-summary-column")].summary;t.innerText=s})),this._checkSelectAllState()}}var x;t.fn[h]=function(){var e,s,i;if(0===arguments.length||1===arguments.length&&"string"!=t.type(arguments[0]))return e=arguments[0],this.each((function(){return u.getOrCreate(this,e)}));if(s=arguments[0],i=t.makeArray(arguments).slice(1),s in u)return i.unshift(this),u[s].apply(u,i);throw new Error("Unknown function call "+s+" for $.fn.formset")},x=function(){!function(){const t=document.createElement("style");t.innerHTML="\n .cfm-selection-border {\n position: absolute;\n top: 0px;\n bottom: 0px;\n left: 0px;\n width: 0.150rem;\n background-color: rgb(220 53 69 / 1);\n }\n .cfm-modal-backdrop {\n position: fixed;\n inset: 0px;\n z-index: 100;\n background-color: rgb(31 41 55 / 1);\n opacity: 0;\n transition-property: opacity;\n transition-duration: 300ms;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n }\n .cfm-opacity-50 {\n opacity: 0.5;\n }\n .cfm-opacity-100 {\n opacity: 1;\n }\n .cfm-tr.selected{\n background-color: rgba(0, 0, 0, 0.08) !important;\n }\n .cfm .modal-body {\n max-height: calc(100vh - 150px);\n overflow-x: auto;\n }\n .cfm-cursor-pointer {\n cursor: pointer;\n }\n ",document.head.appendChild(t)}(),function(){let t=[];document.querySelectorAll("[data-modal-toggle]").forEach((e=>{const s=e.getAttribute("data-modal-toggle"),i=document.getElementById(s),a=i.getAttribute("data-modal-placement");i&&(i.hasAttribute("aria-hidden")||i.hasAttribute("aria-modal")||i.setAttribute("aria-hidden","true"));let o=null;l(s,t)?(o=l(s,t),o=o.object):(o=new p(i,{placement:a||Default.placement}),t.push({id:s,object:o})),i.hasAttribute("data-modal-show")&&"true"===i.getAttribute("data-modal-show")&&o.show(),e.addEventListener("click",(()=>{o.toggle()}))}))}(),n(),document.querySelectorAll(".formset").forEach((function(t){new C(t.getAttribute("id"))})),r()},"loading"!==document.readyState?x():document.addEventListener("DOMContentLoaded",x)}($);
|
|
2
|
+
//# sourceMappingURL=crispy-formset-modal.min.js.map
|