Repository: saleor/saleor

Issue:
Dashboard voucher form fails validation
In **Chrome** 
- Attempt to add a voucher that is not a Category or Product voucher.
- Browser-side validation fails on hidden category and product fields.
- To user, failure is invisible and silent - just appears to do nothing.

ProductVoucherForm and CategoryVoucherForm's init methods explicitly set those fields as required. Setting required to false removes this issue, but has the side effect of allowing product or category vouchers to be created without specifying a product or category.



Discussion:
@royal-mcb Could you check if the issue still occurs with latest code from master branch?
I can't recreate it - when I try to create a voucher for all products, everything works fine:

![image](https://cloud.githubusercontent.com/assets/1754812/19300250/96ba85d4-9059-11e6-9548-fe2b001fa431.png)

Cloned a new copy of the master branch, set up a new virtualenv and pip installed requirements.txt. For server I'm running on Ubuntu 14.04 with python2.7 and Django 1.10.1

I've tested the error using both windows and ubuntu builds of Firefox/Chrome, and see the following:

In Chrome 53.0.2785.143, clicking the create button has no effect, and I get this error in dev console:
![chrome](https://cloud.githubusercontent.com/assets/22780200/19321090/e55350d6-9068-11e6-8dee-03c5398972c8.png)

In Firefox 49.0.1 I get no errors in the console, but instead get the validation failure notice posted at the top left.
![firefox](https://cloud.githubusercontent.com/assets/22780200/19321232/0aececda-9069-11e6-8de2-6787ddf85a2a.png)

If I manually toggle all the voucher types one by one, and select a product and a category, the form then allows me to create whatever voucher type I want- because now the client sees that the 'required' fields have data in them, even if the backend ignores that data.

This looks like a bug in how controls are rendered in HTML. We should not depend on client side validation (or the `required` attribute).

I agree that client side validation shouldn't be depended upon, but it makes a nice preliminary check that prevents a hit against the server, and, when it works, feels very responsive as a user.

The issue is that hiding the unused form elements doesn't add or remove the 'required' attribute programmatically, so browsers freak out about hidden required forms (or worse, fail silently). 

To fix this you'd want to, say, remove the required attribute from all fields as they're being hidden and mark them with a dummy css tag or something. Then when you unhide them simply replace the dummy tag with the required attribute again. 

You are right but there is currently no such code in place so triggering client side form validation is a bug.

@royal-mcb Now I managed to reproduce it, probably I was checking older version of the branch. This issue will be fixed soon.


Resolving patch:
diff --git a/saleor/settings.py b/saleor/settings.py
--- a/saleor/settings.py
+++ b/saleor/settings.py
@@ -241,24 +241,25 @@
 PAYMENT_MODEL = 'order.Payment'
 
 PAYMENT_VARIANTS = {
-    'default': ('payments.dummy.DummyProvider', {})
-}
+    'default': ('payments.dummy.DummyProvider', {})}
 
 SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer'
 SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
 
 CHECKOUT_PAYMENT_CHOICES = [
-    ('default', 'Dummy provider')
-]
+    ('default', 'Dummy provider')]
 
 MESSAGE_TAGS = {
-    messages.ERROR: 'danger',
-}
+    messages.ERROR: 'danger'}
 
 LOW_STOCK_THRESHOLD = 10
 
 PAGINATE_BY = 16
 
+BOOTSTRAP3 = {
+    'set_required': False,
+    'success_css_class': ''}
+
 TEST_RUNNER = ''
 
 ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', 'localhost').split()


Test patch: