Skip to content

Commit 22a5865

Browse files
authored
Merge pull request #46 from greyli/multiple-dropzone
Support to customize the element id
2 parents a7a0477 + 02ce651 commit 22a5865

File tree

9 files changed

+116
-12
lines changed

9 files changed

+116
-12
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ examples/click-upload/uploads/*
8383
examples/in-form/uploads/*
8484
examples/large-file/uploads/*
8585
examples/custom-options/uploads/*
86+
examples/multiple-dropzone/uploads/*
8687

8788
!examples/basic/uploads/.gitkeep
8889
!examples/csrf/uploads/.gitkeep
@@ -92,4 +93,4 @@ examples/custom-options/uploads/*
9293
!examples/in-form/uploads/.gitkeep
9394
!examples/large-file/uploads/.gitkeep
9495
!examples/custom-options/uploads/.gitkeep
95-
96+
!examples/multiple-dropzone/uploads/.gitkeep

CHANGES.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ WARNING: **New major upstream release (backwards incompatible!).**
99

1010
* Remove ``dropzone.load()`` method.
1111
* Added more options to customize messages.
12+
* Drop Python 2 support.
13+
14+
1.6.0
15+
-----
16+
released date: --
17+
18+
* Add a ``id`` parameter for ``dropzone.create()`` and ``dropzone.config()`` to support
19+
customize element id and putting multiple dropzones in one page.
1220

1321
1.5.4
1422
-----

docs/basic.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,21 @@ Remember to edit the ``action`` to the URL or endpoint which handles the
7979
uploads, for example ``dropzone.create(action='upload_view')`` or
8080
``dropzone.create(action=url_for('upload_view')')``.
8181

82+
The default ID of the dropzone form element is `myDropzone`, usually you don't
83+
need to change it. If you have specific need, for example, you want to have multiple
84+
dropzones on one page, you can use the ``id`` parameter to assign the id:
85+
86+
.. code-block:: jinja
87+
88+
{{ dropzone.create(id='foo') }}
89+
{{ dropzone.create(id='bar') }}
90+
...
91+
{{ dropzone.config(id='foo') }}
92+
{{ dropzone.config(id='bar') }}
93+
</body>
94+
95+
Notice that the same id must passed both in ``dropzone.create()`` and ``dropzone.config()``.
96+
8297
Beautify Dropzone
8398
-----------------
8499

examples/README.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ Aside from the basic example, there are a couple of additional examples:
1919
- examples/in-form
2020
- examples/large-file
2121
- examples/parallel-upload
22+
- examples/multiple-dropzone

examples/multiple-dropzone/app.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
:author: Grey Li <[email protected]>
4+
:copyright: (c) 2017 by Grey Li.
5+
:license: MIT, see LICENSE for more details.
6+
"""
7+
import os
8+
9+
from flask import Flask, render_template, request, jsonify
10+
from flask_dropzone import Dropzone
11+
12+
basedir = os.path.abspath(os.path.dirname(__file__))
13+
14+
app = Flask(__name__)
15+
16+
app.config.update(
17+
UPLOADED_PATH=os.path.join(basedir, 'uploads'),
18+
# Flask-Dropzone config:
19+
DROPZONE_ALLOWED_FILE_TYPE='image',
20+
DROPZONE_MAX_FILE_SIZE=3,
21+
DROPZONE_MAX_FILES=30,
22+
)
23+
24+
dropzone = Dropzone(app)
25+
26+
27+
@app.route('/', methods=['POST', 'GET'])
28+
def upload():
29+
if request.method == 'POST':
30+
f = request.files.get('file')
31+
file_path = os.path.join(app.config['UPLOADED_PATH'], f.filename)
32+
f.save(file_path)
33+
# You can return a JSON response then get it on client side:
34+
# (see template index.html for client implementation)
35+
# return jsonify(uploaded_path=file_path)
36+
return render_template('index.html')
37+
38+
39+
if __name__ == '__main__':
40+
app.run(debug=True)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Flask-Dropzone Demo: Multiple Dropzone</title>
6+
{{ dropzone.load_css() }}
7+
{{ dropzone.style('border: 2px dashed #0087F7; margin: 10%; min-height: 400px;') }}
8+
</head>
9+
<body>
10+
{{ dropzone.create(action='upload', id='foo') }}
11+
{{ dropzone.create(action='upload', id='bar') }}
12+
{{ dropzone.load_js() }}
13+
{{ dropzone.config(id='foo', default_message='Dropzone Foo') }}
14+
{{ dropzone.config(id='bar', default_message='Dropzone Bar') }}
15+
</body>
16+
</html>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

flask_dropzone/__init__.py

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -178,15 +178,20 @@ def load_js(js_url=None, version='5.2.0'):
178178
return Markup(js)
179179

180180
@staticmethod
181-
def config(redirect_url=None, custom_init='', custom_options='', nonce=None, **kwargs):
181+
def config(redirect_url=None, custom_init='', custom_options='', nonce=None, id=None, **kwargs):
182182
"""Initialize dropzone configuration.
183183
184+
.. versionchanged:: 1.5.4
185+
Added ``id`` parameter.
186+
184187
.. versionadded:: 1.4.4
185188
186189
:param redirect_url: The URL to redirect when upload complete.
187190
:param custom_init: Custom javascript code in ``init: function() {}``.
188191
:param custom_options: Custom javascript code in ``Dropzone.options.myDropzone = {}``.
189192
:param nonce: Pass a nonce value that is newhen embedding the JavaScript code into a Content Security Policy protected web page.
193+
:param id: The id of the dropzone element, it must matches the ``id`` argument passed to
194+
``dropzone.create()`` if provided.
190195
:param **kwargs: Mirror configuration variable, lowercase and without prefix.
191196
For example, ``DROPZONE_UPLOAD_MULTIPLE`` becomes ``upload_multiple`` here.
192197
"""
@@ -294,13 +299,12 @@ def config(redirect_url=None, custom_init='', custom_options='', nonce=None, **k
294299
csrf_token = render_template_string('{{ csrf_token() }}')
295300
custom_options += 'headers: {"X-CSRF-Token": "%s"},' % csrf_token
296301

297-
if nonce:
298-
nonce_html = " nonce=\"%s\"" % nonce
299-
else:
300-
nonce_html = ""
301-
302+
nonce_html = ' nonce="%s"' % nonce if nonce else ''
303+
if id is None:
304+
id = 'myDropzone'
305+
302306
return Markup('''<script%s>
303-
Dropzone.options.myDropzone = {
307+
Dropzone.options.%s = {
304308
init: function() {
305309
%s // redirect after queue complete
306310
%s // upload queue when button click
@@ -326,14 +330,14 @@ def config(redirect_url=None, custom_init='', custom_options='', nonce=None, **k
326330
%s // custom options code
327331
};
328332
</script>
329-
''' % (nonce_html, redirect_js, click_listener, custom_init, click_option,
333+
''' % (nonce_html, id, redirect_js, click_listener, custom_init, click_option,
330334
upload_multiple, parallel_uploads, param, size, allowed_type, max_files,
331335
default_message, browser_unsupported, invalid_file_type, file_too_big,
332336
server_error, max_files_exceeded, cancelUpload, removeFile, cancelConfirmation,
333337
uploadCanceled, custom_options))
334338

335339
@staticmethod
336-
def create(action='', csrf=False, action_view='', **kwargs):
340+
def create(action='', csrf=False, action_view='', id=None, **kwargs):
337341
"""Create a Dropzone form with given action.
338342
339343
.. versionchanged:: 1.4.2
@@ -348,9 +352,14 @@ def create(action='', csrf=False, action_view='', **kwargs):
348352
.. versionchanged:: 1.5.4
349353
``csrf`` was deprecated now.
350354
355+
.. versionchanged:: 1.5.4
356+
Added ``id`` parameter.
357+
351358
:param action: The action attribute in ``<form>``, pass the url which handle uploads.
352359
:param csrf: Enable CSRF protect or not, same with ``DROPZONE_ENABLE_CSRF``, deprecated since 1.5.4.
353360
:param action_view: The view which handle the post data, deprecated since 1.4.2.
361+
:param id: The id of the dropzone element, it must matches the ``id`` argument passed to
362+
``dropzone.config()`` if provided.
354363
"""
355364
if current_app.config['DROPZONE_IN_FORM']:
356365
return Markup('<div class="dropzone" id="myDropzone"></div>')
@@ -364,8 +373,10 @@ def create(action='', csrf=False, action_view='', **kwargs):
364373
if csrf:
365374
warnings.warn('The argument was deprecated and will be removed in 2.0, use DROPZONE_ENABLE_CSRF instead.')
366375

367-
return Markup('''<form action="%s" method="post" class="dropzone" id="myDropzone"
368-
enctype="multipart/form-data"></form>''' % action_url)
376+
if id is None:
377+
id = 'myDropzone'
378+
return Markup('''<form action="%s" method="post" class="dropzone" id="%s"
379+
enctype="multipart/form-data"></form>''' % (action_url, id))
369380

370381
@staticmethod
371382
def style(css):

test_flask_dropzone.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,14 @@ def test_custom_js(self):
205205

206206
rv = self.dropzone.config(custom_options='foo = true')
207207
self.assertIn('foo = true,', rv)
208+
209+
def test_custom_id(self):
210+
rv = self.dropzone.create(action=url_for('upload'))
211+
self.assertIn('id="myDropzone"', rv)
212+
rv = self.dropzone.config()
213+
self.assertIn('Dropzone.options.myDropzone', rv)
214+
215+
rv = self.dropzone.create(action=url_for('upload'), id='hello')
216+
self.assertIn('id="hello"', rv)
217+
rv = self.dropzone.config(id='hello')
218+
self.assertIn('Dropzone.options.hello', rv)

0 commit comments

Comments
 (0)