Procházet zdrojové kódy

Add form field prefixes for input forms in chooser modals

Update chooser modal JS to use field IDs with prefixes

Note that the tag field JS no longer needs to be initialised here, as that's done in AdminTagWidget's inline JS
Matt Westcott před 5 roky
rodič
revize
c109dd3495

+ 1 - 0
CHANGELOG.txt

@@ -14,6 +14,7 @@ Changelog
  * Multiple clarifications, grammar and typo fixes throughout documentation (Dan Swain)
  * Use correct URL in API example in documentation (Michael Bunsen)
  * Move datetime widget initialiser JS into the widget's form media instead of page editor media (Matt Westcott)
+ * Add form field prefixes for input forms in chooser modals (Matt Westcott)
  * Fix: ModelAdmin no longer fails when filtering over a foreign key relation (Jason Dilworth, Matt Westcott)
  * Fix: The Wagtail version number is now visible within the Settings menu (Kevin Howbrook)
  * Fix: Scaling images now rounds values to an integer so that images render without errors (Adrian Brunyate)

+ 1 - 0
docs/releases/2.6.rst

@@ -23,6 +23,7 @@ Other features
  * Multiple clarifications, grammar and typo fixes throughout documentation (Dan Swain)
  * Use correct URL in API example in documentation (Michael Bunsen)
  * Move datetime widget initialiser JS into the widget's form media instead of page editor media (Matt Westcott)
+ * Add form field prefixes for input forms in chooser modals (Matt Westcott)
 
 Bug fixes
 ~~~~~~~~~

+ 10 - 10
wagtail/admin/tests/test_page_chooser.py

@@ -512,7 +512,7 @@ class TestChooserExternalLink(TestCase, WagtailTestUtils):
         self.assertContains(response, 'https://torchbox.com/')
 
     def test_create_link(self):
-        response = self.post({'url': 'http://www.example.com/', 'link_text': 'example'})
+        response = self.post({'external-link-chooser-url': 'http://www.example.com/', 'external-link-chooser-link_text': 'example'})
         self.assertEqual(response.status_code, 200)
         response_json = json.loads(response.content.decode())
         self.assertEqual(response_json['step'], 'external_link_chosen')
@@ -521,7 +521,7 @@ class TestChooserExternalLink(TestCase, WagtailTestUtils):
         self.assertEqual(response_json['result']['prefer_this_title_as_link_text'], True)
 
     def test_create_link_without_text(self):
-        response = self.post({'url': 'http://www.example.com/'})
+        response = self.post({'external-link-chooser-url': 'http://www.example.com/'})
         self.assertEqual(response.status_code, 200)
         response_json = json.loads(response.content.decode())
         self.assertEqual(response_json['step'], 'external_link_chosen')
@@ -531,7 +531,7 @@ class TestChooserExternalLink(TestCase, WagtailTestUtils):
 
     def test_notice_changes_to_link_text(self):
         response = self.post(
-            {'url': 'http://www.example.com/', 'link_text': 'example'},  # POST data
+            {'external-link-chooser-url': 'http://www.example.com/', 'external-link-chooser-link_text': 'example'},  # POST data
             {'link_url': 'http://old.example.com/', 'link_text': 'example'}  # GET params - initial data
         )
         result = json.loads(response.content.decode())['result']
@@ -541,7 +541,7 @@ class TestChooserExternalLink(TestCase, WagtailTestUtils):
         self.assertEqual(result['prefer_this_title_as_link_text'], False)
 
         response = self.post(
-            {'url': 'http://www.example.com/', 'link_text': 'new example'},  # POST data
+            {'external-link-chooser-url': 'http://www.example.com/', 'external-link-chooser-link_text': 'new example'},  # POST data
             {'link_url': 'http://old.example.com/', 'link_text': 'example'}  # GET params - initial data
         )
         result = json.loads(response.content.decode())['result']
@@ -551,14 +551,14 @@ class TestChooserExternalLink(TestCase, WagtailTestUtils):
         self.assertEqual(result['prefer_this_title_as_link_text'], True)
 
     def test_invalid_url(self):
-        response = self.post({'url': 'ntp://www.example.com', 'link_text': 'example'})
+        response = self.post({'external-link-chooser-url': 'ntp://www.example.com', 'external-link-chooser-link_text': 'example'})
         self.assertEqual(response.status_code, 200)
         response_json = json.loads(response.content.decode())
         self.assertEqual(response_json['step'], 'external_link')  # indicates failure / show error message
         self.assertContains(response, "Enter a valid URL.")
 
     def test_allow_local_url(self):
-        response = self.post({'url': '/admin/', 'link_text': 'admin'})
+        response = self.post({'external-link-chooser-url': '/admin/', 'external-link-chooser-link_text': 'admin'})
         self.assertEqual(response.status_code, 200)
         response_json = json.loads(response.content.decode())
         self.assertEqual(response_json['step'], 'external_link_chosen')  # indicates success / post back to calling page
@@ -591,14 +591,14 @@ class TestChooserEmailLink(TestCase, WagtailTestUtils):
         self.assertContains(response, 'example@example.com')
 
     def test_create_link(self):
-        response = self.post({'email_address': 'example@example.com', 'link_text': 'contact'})
+        response = self.post({'email-link-chooser-email_address': 'example@example.com', 'email-link-chooser-link_text': 'contact'})
         result = json.loads(response.content.decode())['result']
         self.assertEqual(result['url'], "mailto:example@example.com")
         self.assertEqual(result['title'], "contact")  # When link text is given, it is used
         self.assertEqual(result['prefer_this_title_as_link_text'], True)
 
     def test_create_link_without_text(self):
-        response = self.post({'email_address': 'example@example.com'})
+        response = self.post({'email-link-chooser-email_address': 'example@example.com'})
         result = json.loads(response.content.decode())['result']
         self.assertEqual(result['url'], "mailto:example@example.com")
         self.assertEqual(result['title'], "example@example.com")  # When no link text is given, it uses the email
@@ -606,7 +606,7 @@ class TestChooserEmailLink(TestCase, WagtailTestUtils):
 
     def test_notice_changes_to_link_text(self):
         response = self.post(
-            {'email_address': 'example2@example.com', 'link_text': 'example'},  # POST data
+            {'email-link-chooser-email_address': 'example2@example.com', 'email-link-chooser-link_text': 'example'},  # POST data
             {'link_url': 'example@example.com', 'link_text': 'example'}  # GET params - initial data
         )
         result = json.loads(response.content.decode())['result']
@@ -616,7 +616,7 @@ class TestChooserEmailLink(TestCase, WagtailTestUtils):
         self.assertEqual(result['prefer_this_title_as_link_text'], False)
 
         response = self.post(
-            {'email_address': 'example2@example.com', 'link_text': 'new example'},  # POST data
+            {'email-link-chooser-email_address': 'example2@example.com', 'email-link-chooser-link_text': 'new example'},  # POST data
             {'link_url': 'example@example.com', 'link_text': 'example'}  # GET params - initial data
         )
         result = json.loads(response.content.decode())['result']

+ 4 - 4
wagtail/admin/views/chooser.py

@@ -192,7 +192,7 @@ def external_link(request):
     }
 
     if request.method == 'POST':
-        form = ExternalLinkChooserForm(request.POST, initial=initial_data)
+        form = ExternalLinkChooserForm(request.POST, initial=initial_data, prefix='external-link-chooser')
 
         if form.is_valid():
             result = {
@@ -211,7 +211,7 @@ def external_link(request):
                 None, json_data={'step': 'external_link_chosen', 'result': result}
             )
     else:
-        form = ExternalLinkChooserForm(initial=initial_data)
+        form = ExternalLinkChooserForm(initial=initial_data, prefix='external-link-chooser')
 
     return render_modal_workflow(
         request,
@@ -229,7 +229,7 @@ def email_link(request):
     }
 
     if request.method == 'POST':
-        form = EmailLinkChooserForm(request.POST, initial=initial_data)
+        form = EmailLinkChooserForm(request.POST, initial=initial_data, prefix='email-link-chooser')
 
         if form.is_valid():
             result = {
@@ -245,7 +245,7 @@ def email_link(request):
                 None, json_data={'step': 'external_link_chosen', 'result': result}
             )
     else:
-        form = EmailLinkChooserForm(initial=initial_data)
+        form = EmailLinkChooserForm(initial=initial_data, prefix='email-link-chooser')
 
     return render_modal_workflow(
         request,

+ 1 - 5
wagtail/documents/static_src/wagtaildocs/js/document-chooser-modal.js

@@ -16,7 +16,7 @@ DOCUMENT_CHOOSER_MODAL_ONLOAD_HANDLERS = {
                 // Set current collection ID at upload form tab
                 let collectionId = $('#collection_chooser_collection_id').val();
                 if (collectionId) {
-                  $('#id_collection').val(collectionId);
+                  $('#id_document-chooser-upload-collection').val(collectionId);
                 }
 
                 // Select upload form tab
@@ -92,10 +92,6 @@ DOCUMENT_CHOOSER_MODAL_ONLOAD_HANDLERS = {
         });
 
         $('#collection_chooser_collection_id').on('change', search);
-
-        $('#id_tags', modal.body).tagit({
-            autocomplete: {source: jsonData['tag_autocomplete_url']}
-        });
     },
     'document_chosen': function(modal, jsonData) {
         modal.respond('documentChosen', jsonData['result']);

+ 4 - 4
wagtail/documents/tests/test_admin_views.py

@@ -824,8 +824,8 @@ class TestDocumentChooserUploadView(TestCase, WagtailTestUtils):
 
         # Submit
         post_data = {
-            'title': "Test document",
-            'file': fake_file,
+            'document-chooser-upload-title': "Test document",
+            'document-chooser-upload-file': fake_file,
         }
         response = self.client.post(reverse('wagtaildocs:chooser_upload'), post_data)
 
@@ -894,8 +894,8 @@ class TestDocumentChooserUploadViewWithLimitedPermissions(TestCase, WagtailTestU
 
         # Submit
         post_data = {
-            'title': "Test document",
-            'file': fake_file,
+            'document-chooser-upload-title': "Test document",
+            'document-chooser-upload-file': fake_file,
         }
         response = self.client.post(reverse('wagtaildocs:chooser_upload'), post_data)
 

+ 5 - 3
wagtail/documents/views/chooser.py

@@ -46,7 +46,7 @@ def chooser(request):
 
     if permission_policy.user_has_permission(request.user, 'add'):
         DocumentForm = get_document_form(Document)
-        uploadform = DocumentForm(user=request.user)
+        uploadform = DocumentForm(user=request.user, prefix='document-chooser-upload')
     else:
         uploadform = None
 
@@ -126,7 +126,9 @@ def chooser_upload(request):
 
     if request.method == 'POST':
         document = Document(uploaded_by_user=request.user)
-        form = DocumentForm(request.POST, request.FILES, instance=document, user=request.user)
+        form = DocumentForm(
+            request.POST, request.FILES, instance=document, user=request.user, prefix='document-chooser-upload'
+        )
 
         if form.is_valid():
             document.file_size = document.file.size
@@ -146,7 +148,7 @@ def chooser_upload(request):
                 None, json_data={'step': 'document_chosen', 'result': get_document_result_data(document)}
             )
     else:
-        form = DocumentForm(user=request.user)
+        form = DocumentForm(user=request.user, prefix='document-chooser-upload')
 
     documents = Document.objects.order_by('title')
 

+ 2 - 2
wagtail/embeds/tests/test_embeds.py

@@ -179,7 +179,7 @@ class TestChooser(TestCase, WagtailTestUtils):
         get_embed.return_value = Embed(html='<img src="http://www.example.com" />', title="An example embed")
 
         response = self.client.post(reverse('wagtailembeds:chooser_upload'), {
-            'url': 'http://www.example.com/'
+            'embed-chooser-url': 'http://www.example.com/'
         })
         self.assertEqual(response.status_code, 200)
         response_json = json.loads(response.content.decode())
@@ -191,7 +191,7 @@ class TestChooser(TestCase, WagtailTestUtils):
         get_embed.side_effect = EmbedNotFoundException
 
         response = self.client.post(reverse('wagtailembeds:chooser_upload'), {
-            'url': 'http://www.example.com/'
+            'embed-chooser-url': 'http://www.example.com/'
         })
         self.assertEqual(response.status_code, 200)
 

+ 3 - 3
wagtail/embeds/views/chooser.py

@@ -10,7 +10,7 @@ from wagtail.embeds.forms import EmbedForm
 
 
 def chooser(request):
-    form = EmbedForm(initial=request.GET.dict())
+    form = EmbedForm(initial=request.GET.dict(), prefix='embed-chooser')
 
     return render_modal_workflow(
         request, 'wagtailembeds/chooser/chooser.html', None,
@@ -21,7 +21,7 @@ def chooser(request):
 
 def chooser_upload(request):
     if request.method == 'POST':
-        form = EmbedForm(request.POST, request.FILES)
+        form = EmbedForm(request.POST, request.FILES, prefix='embed-chooser')
 
         if form.is_valid():
             error = None
@@ -59,7 +59,7 @@ def chooser_upload(request):
                     json_data={'step': 'chooser'}
                 )
     else:
-        form = EmbedForm()
+        form = EmbedForm(prefix='embed-chooser')
 
     return render_modal_workflow(
         request, 'wagtailembeds/chooser/chooser.html', None,

+ 5 - 12
wagtail/images/static_src/wagtailimages/js/image-chooser-modal.js

@@ -59,11 +59,11 @@ IMAGE_CHOOSER_MODAL_ONLOAD_HANDLERS = {
         $('form.image-upload', modal.body).on('submit', function() {
             var formdata = new FormData(this);
 
-            if ($('#id_title', modal.body).val() == '') {
-                var li = $('#id_title', modal.body).closest('li');
+            if ($('#id_image-chooser-upload-title', modal.body).val() == '') {
+                var li = $('#id_image-chooser-upload-title', modal.body).closest('li');
                 if (!li.hasClass('error')) {
                     li.addClass('error');
-                    $('#id_title', modal.body).closest('.field-content').append('<p class="error-message"><span>This field is required.</span></p>')
+                    $('#id_image-chooser-upload-title', modal.body).closest('.field-content').append('<p class="error-message"><span>This field is required.</span></p>')
                 }
                 setTimeout(cancelSpinner, 500);
             } else {
@@ -106,11 +106,9 @@ IMAGE_CHOOSER_MODAL_ONLOAD_HANDLERS = {
         });
 
         function populateTitle(context) {
-            // Note: There are two inputs with `#id_title` on the page.
-            // The page title and image title. Select the input inside the modal body.
-            var fileWidget = $('#id_file', context);
+            var fileWidget = $('#id_image-chooser-upload-file', context);
             fileWidget.on('change', function () {
-                var titleWidget = $('#id_title', context);
+                var titleWidget = $('#id_image-chooser-upload-title', context);
                 var title = titleWidget.val();
                 if (title === '') {
                     // The file widget value example: `C:\fakepath\image.jpg`
@@ -122,11 +120,6 @@ IMAGE_CHOOSER_MODAL_ONLOAD_HANDLERS = {
         }
 
         populateTitle(modal.body);
-
-        /* Add tag entry interface (with autocompletion) to the tag field of the image upload form */
-        $('#id_tags', modal.body).tagit({
-            autocomplete: {source: jsonData['tag_autocomplete_url']}
-        });
     },
     'image_chosen': function(modal, jsonData) {
         modal.respond('imageChosen', jsonData['result']);

+ 11 - 11
wagtail/images/tests/test_admin_views.py

@@ -693,7 +693,7 @@ class TestImageChooserSelectFormatView(TestCase, WagtailTestUtils):
         self.assertContains(response, 'value=\\"some previous alt text\\"')
 
     def test_post_response(self):
-        response = self.post({'format': 'left', 'alt_text': 'Arthur "two sheds" Jackson'})
+        response = self.post({'image-chooser-insertion-format': 'left', 'image-chooser-insertion-alt_text': 'Arthur "two sheds" Jackson'})
 
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response['Content-Type'], 'application/json')
@@ -725,8 +725,8 @@ class TestImageChooserUploadView(TestCase, WagtailTestUtils):
 
     def test_upload(self):
         response = self.client.post(reverse('wagtailimages:chooser_upload'), {
-            'title': "Test image",
-            'file': SimpleUploadedFile('test.png', get_test_image_file().file.getvalue()),
+            'image-chooser-upload-title': "Test image",
+            'image-chooser-upload-file': SimpleUploadedFile('test.png', get_test_image_file().file.getvalue()),
         })
 
         # Check response
@@ -747,7 +747,7 @@ class TestImageChooserUploadView(TestCase, WagtailTestUtils):
 
     def test_upload_no_file_selected(self):
         response = self.client.post(reverse('wagtailimages:chooser_upload'), {
-            'title': "Test image",
+            'image-chooser-upload-title': "Test image",
         })
 
         # Shouldn't redirect anywhere
@@ -765,7 +765,7 @@ class TestImageChooserUploadView(TestCase, WagtailTestUtils):
             )
 
         response = self.client.post(reverse('wagtailimages:chooser_upload'), {
-            'title': "Test image",
+            'image-chooser-upload-title': "Test image",
         })
 
         self.assertEqual(response.status_code, 200)
@@ -778,8 +778,8 @@ class TestImageChooserUploadView(TestCase, WagtailTestUtils):
     def test_select_format_flag_after_upload_form_error(self):
         submit_url = reverse('wagtailimages:chooser_upload') + '?select_format=true'
         response = self.client.post(submit_url, {
-            'title': "Test image",
-            'file': SimpleUploadedFile('not_an_image.txt', b'this is not an image'),
+            'image-chooser-upload-title': "Test image",
+            'image-chooser-upload-file': SimpleUploadedFile('not_an_image.txt', b'this is not an image'),
         })
 
         self.assertEqual(response.status_code, 200)
@@ -794,8 +794,8 @@ class TestImageChooserUploadView(TestCase, WagtailTestUtils):
     @override_settings(DEFAULT_FILE_STORAGE='wagtail.tests.dummy_external_storage.DummyExternalStorage')
     def test_upload_with_external_storage(self):
         response = self.client.post(reverse('wagtailimages:chooser_upload'), {
-            'title': "Test image",
-            'file': SimpleUploadedFile('test.png', get_test_image_file().file.getvalue()),
+            'image-chooser-upload-title': "Test image",
+            'image-chooser-upload-file': SimpleUploadedFile('test.png', get_test_image_file().file.getvalue()),
         })
 
         # Check response
@@ -854,8 +854,8 @@ class TestImageChooserUploadViewWithLimitedPermissions(TestCase, WagtailTestUtil
 
     def test_add(self):
         response = self.client.post(reverse('wagtailimages:chooser_upload'), {
-            'title': "Test image",
-            'file': SimpleUploadedFile('test.png', get_test_image_file().file.getvalue()),
+            'image-chooser-upload-title': "Test image",
+            'image-chooser-upload-file': SimpleUploadedFile('test.png', get_test_image_file().file.getvalue()),
         })
 
         self.assertEqual(response.status_code, 200)

+ 12 - 6
wagtail/images/views/chooser.py

@@ -70,7 +70,7 @@ def chooser(request):
 
     if permission_policy.user_has_permission(request.user, 'add'):
         ImageForm = get_image_form(Image)
-        uploadform = ImageForm(user=request.user)
+        uploadform = ImageForm(user=request.user, prefix='image-chooser-upload')
     else:
         uploadform = None
 
@@ -145,7 +145,9 @@ def chooser_upload(request):
 
     if request.method == 'POST':
         image = Image(uploaded_by_user=request.user)
-        form = ImageForm(request.POST, request.FILES, instance=image, user=request.user)
+        form = ImageForm(
+            request.POST, request.FILES, instance=image, user=request.user, prefix='image-chooser-upload'
+        )
 
         if form.is_valid():
             # Set image file size
@@ -162,7 +164,9 @@ def chooser_upload(request):
             search_index.insert_or_update_object(image)
 
             if request.GET.get('select_format'):
-                form = ImageInsertionForm(initial={'alt_text': image.default_alt_text})
+                form = ImageInsertionForm(
+                    initial={'alt_text': image.default_alt_text}, prefix='image-chooser-insertion'
+                )
                 return render_modal_workflow(
                     request, 'wagtailimages/chooser/select_format.html', None,
                     {'image': image, 'form': form}, json_data={'step': 'select_format'}
@@ -174,7 +178,7 @@ def chooser_upload(request):
                     None, json_data={'step': 'image_chosen', 'result': get_image_result_data(image)}
                 )
     else:
-        form = ImageForm(user=request.user)
+        form = ImageForm(user=request.user, prefix='image-chooser-upload')
 
     images = Image.objects.order_by('-created_at')
 
@@ -200,7 +204,9 @@ def chooser_select_format(request, image_id):
     image = get_object_or_404(get_image_model(), id=image_id)
 
     if request.method == 'POST':
-        form = ImageInsertionForm(request.POST, initial={'alt_text': image.default_alt_text})
+        form = ImageInsertionForm(
+            request.POST, initial={'alt_text': image.default_alt_text}, prefix='image-chooser-insertion'
+        )
         if form.is_valid():
 
             format = get_image_format(form.cleaned_data['format'])
@@ -228,7 +234,7 @@ def chooser_select_format(request, image_id):
     else:
         initial = {'alt_text': image.default_alt_text}
         initial.update(request.GET.dict())
-        form = ImageInsertionForm(initial=initial)
+        form = ImageInsertionForm(initial=initial, prefix='image-chooser-insertion')
 
     return render_modal_workflow(
         request, 'wagtailimages/chooser/select_format.html', None,