I have a multi step form which is built using sessionwizardview
of django form wizard, I have added next and previous buttons, but the problem is, if I am in a step and when I click previous, it asks for the form to be filled up first and then could proceed and go to previous step on click of that previous button. I am clueless as I couldnt find anything related to my problem, am I missing something?
Here are couple of sample forms:
from django import forms
from django.utils.translation import gettext as _
from addresses.forms import AddressForm, InvoiceAddressForm
from core.api import NcpAPI
from django_countries import countries
api = NcpAPI()
CHOICES=[('0','Pay by card'), ('1','Invoice')]
class RegistrationForm(forms.Form):
title = 'registration'
first_name = forms.CharField(label=_("First Name"), widget=forms.TextInput(attrs={'class':'form-text required'}))
last_name = forms.CharField(label=_("Last Name"), widget=forms.TextInput(attrs={'class':'form-text required'}))
registration_company = forms.CharField(label=_("Company"), widget=forms.TextInput(attrs={'class':'form-text required'}))
phone = forms.CharField(label=_("Phone"), widget=forms.TextInput(attrs={'class':'form-text required'}))
email = forms.EmailField(label=_("Email"), widget=forms.TextInput(attrs={'class':'form-text required'}))
def clean_email(self):
email = self.cleaned_data.get('email')
if api.is_username_taken(email):
raise forms.ValidationError(_('Email is in use'))
return email
class AddressesForm(InvoiceAddressForm, AddressForm):
title = 'addresses'
class PaymentForm(forms.Form):
title = 'payment'
payment_method = forms.ChoiceField(label = _("Payment Options"), choices=CHOICES, widget=forms.RadioSelect(attrs={'class':'form-text required'}), required = True, initial = "1")
class ConfirmationForm(forms.Form):
title = 'confirm'
And here is my session wizard class:
class SubscriptionWizard(SessionWizardView):
def get_template_names(self):
return [TEMPLATES.get(self.steps.current)]
extra_data = {}
def get_context_data(self, form, **kwargs):
pp = pprint.PrettyPrinter(indent=4)
context = super(SubscriptionWizard, self).get_context_data(form=form, **kwargs)
context.update(self.extra_data)
data = self.get_all_cleaned_data()
context['all_data'] = {"product":self.kwargs['product']}
# if self.steps.current == 'addresses':
# print ' yes its addresses %s' % data.get('company')
# context['all_data'].update({"reg_company":data.get('company')})
if self.steps.current in ('payment', 'confirm'):
if data[u'invoice_name'] != '':
p = Prices.objects.filter(name = self.kwargs['product'], currency = str(self.getCurrencyCode(str(data[u'invoice_country']))) )
else:
p = Prices.objects.filter(name = self.kwargs['product'], currency = str(self.getCurrencyCode(data.get('country'))) )
context['all_data']['product_price'] = p[0].price
context['all_data']['product_currency'] = p[0].currency
if data.get('invoice_name'):
currency_country = data.get('invoice_country')
else:
currency_country = data.get('country')
if self.steps.current == 'confirm':
p = Prices.objects.filter(name = self.kwargs['product'], currency = str(self.getCurrencyCode(data.get('country'))) )
context['all_data']['product_price'] = p[0].price
context['all_data']['product_currency'] = p[0].currency
if data:
# pp.pprint(data)
context['all_data'].update(data)
# pp.pprint(context['all_data'])
return context
def get_form_initial(self, step):
initial = self.initial_dict.get(step, {})
if 'profiler' in self.request.session and step in ('registration', 'address', 'payment'):
profiler = self.request.session.get('profiler')
data = {}
if step == 'registration':
# pp = pprint.PrettyPrinter(indent=4)
# pp.pprint(profiler.user.account.account)
# print profiler.user.account
data = {'email': profiler.user.account.email ,
'first_name':profiler.user.account.firstName if profiler.user.account.account.firstName != '' else '',
'last_name':profiler.user.account.lastName,
'phone': profiler.user.account.phone1 if profiler.user.account.account.firstName != '' else ''}
initial.update(data)
return initial
def get_form(self, step=None, data=None, files=None):
form = super(SessionWizardView, self).get_form(step, data, files)
if hasattr(form, 'initialize_wizard'):
form.initialize_wizard(self)
return form
def getCurrencyCode(self, countryCode):
continent = transformations.cca_to_ctn(countryCode)
# print continent
if str(countryCode) == 'NO':
return 'NOK'
if str(countryCode) == 'GB':
return 'GBP'
if (continent == 'Europe') or (continent == 'Africa'):
return 'EUR'
return 'USD'
def done(self, form_list, **kwargs):
pp = pprint.PrettyPrinter(indent=4)
import hashlib
data = dict(('%s_%s' % (form.prefix,k),v) for form in form_list for k, v in form.cleaned_data.items())
# print 'print data ....'
# print ''
# print ''
# pp.pprint(data)
# print ''
# print ''
# print ''
# print '--------------'
# print data
full_name = "%s %s" % (data['registration_first_name'],data['registration_last_name'])
data['product'] = kwargs['product']
dumps = simplejson.dumps(data)
data['country_label']=unicode(fields.Country(data['addresses_country']).name)
print data
if data.get('invoice_name'):
currency_country = data.get('addresses_invoice_country')
else:
currency_country = data.get('addresses_country')
currencyCode = self.getCurrencyCode(currency_country)
prices = Prices.objects.filter(name = kwargs['product'], currency = str(currencyCode))
data['product_price'] = prices[0].price
data['product_currency'] = str(currencyCode)
# print currencyCode
include_archive = 'standard' in kwargs.values()
# Register.
# print 'print data before registering the product ....'
# print ''
# print ''
# pp.pprint(data)
# print ''
# print ''
# print ''
# print '--------------'
result = api.subscribe_to_product(subscribe_to_archive=include_archive, **data)
if 'errorCode' in result:
messages.add_message(self.request, messages.ERROR, _('The registration was not successfull.'))
return render(self.request, 'subscription_product/failed.html', {'clean_data': data})
print '--------'
cs_message = render_to_string(
'subscription_product/email/registered_cs.html', {'data':data})
print api.email(settings.EMAIL_CS_NAME, settings.EMAIL_CS_EMAIL, "Registration for %s" % data['product'], cs_message)
# Save subscription.
s = SubscriptionInfo(subscriptionId = str(result[u'subscriptionId']), customerNumber = result[u'customerNumber'],subscriptionType = str(data['product']), currency = str(currencyCode))
s.save()
if int(data['payment_payment_method']) == 1:
# Sends activation email.
token = api.create_token(7200, 99,'productSub', data['registration_email']).get('tokenValue', '')
activation_url = Site.objects.get_current().domain + reverse("activation_home", kwargs={'token':token})
# activation_url = 'http://localhost:8080' + reverse("activation_home", kwargs={'token':token})
# full_name = '%s %s' % (data.get('registration_first_name'), data.get('registration_last_name'))
customer_message = render_to_string(
'subscription_product/email/registered_customer.html', {'activation_url':activation_url})
print api.email("%s %s" % (data['registration_first_name'], data['registration_last_name']), data['registration_email'], "Your Tradewindsnews.com order registration", customer_message)
#SEND EMAIL TO SALES ON SUCCESS
sales_message = render_to_string(
'subscription_product/email/invoice_sales_success.html',
{'customer_name': full_name,
'account': data,
'alternative_invoice_company':data['addresses_invoice_company'],
'alternative_invoice_street':data['addresses_invoice_street'],
'alternative_invoice_city':data['addresses_invoice_city'],
'alternative_invoice_postal_code':data['addresses_invoice_postal_code'],
'alternative_invoice_country':data['addresses_invoice_country'],
'payment_date': datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
'amount': float(prices[0].price),
'currency' : currencyCode,
'transactionid' :'',
'authorizationid' : '',
'confirmation_number': ''})
api.email("%s %s" % (data['registration_first_name'], data['registration_last_name']), settings.EMAIL_SALES, "New Subscription Order", sales_message)
return render(self.request, 'subscription_product/receipt.html', {'clean_data': data})
else:
site_url = "http://%s" % Site.objects.get(name='secondary')
# site_url = "http://localhost:8000"
# dumps = simplejson.dumps(data)
p = PaymentBeforeDump(dump = dumps, subscriptionInfo = s)
p.save()
# prices = Prices.objects.get(name = kwargs['product'])
return HttpResponseRedirect(
Register(
p_request_Order_Amount = int(float(prices[0].price)*100),
p_request_Order_CurrencyCode = currencyCode,
p_request_Order_OrderNumber = hashlib.md5("foobar" + str(time.time())).hexdigest(),
p_request_Terminal_RedirectUrl = site_url + reverse("subscription_product_payment_return",kwargs={'amount':int(float(prices[0].price)*100), 'currency': str(currencyCode), 'subscription': kwargs['product'], 'id':p.id}),
p_request_TransactionReconRef = 'tw-random',
)
)
And here is one template:
{% extends "base.html" %}
{% load url from future %}
{% load i18n %}
{% load subscription_product_tags %}
{% block content %}
<section class="topsection group">
<div class="col span_3_of_3 first-child last-child">
<div class="order">
<ol class="steps">
<li class="done">Subscription</li>
<li class="done">Details</li>
<li class="done">Delivery</li>
<li class="active">Payment</li>
<li class="queue">Confirm</li>
<li class="queue">Receipt</li>
</ol>
<div class="box">
<section class="section group first-child">
<h1>Payment Summary</h1>
Please review the following details for this transaction.
</section>
<section class="topsection group">
<table border="1">
<tr>
<th>
Description
</th>
<th>
Item Price
</th>
</tr>
<tr>
{% comment %}get the pricing and other product related info{% endcomment %}
{{ all_data|product_price_info|safe }}
</tr>
</table>
</section>
<form action="" method="post">{% csrf_token %}
{{ wizard.management_form }}
{% if wizard.form.forms %}
{{ wizard.form.management_form }}
{% for form in wizard.form.forms %}
{{ form }}
{% endfor %}
{% else %}
<section class="topsection group">
{{ wizard.form.payment_method.label_tag }}
{{wizard.form.payment_method}}
{{ wizard.form.payment_method.errors}}
</section>
{%endif %}
<section class="section group last-child">
<div class="col span_3_of_3 first-child last-child">
<fieldset class="form-actions">
<!-- <a class="backbutton" onClick="goPrevious()">Previous</a> -->
{# <button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">{% trans "Previous" %}</button> #}
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">{% trans "Previous" %}</button>
<input type="submit" value="Next">
</fieldset>
</div>
</section>
</form>
</div>
</div>
</div>
</section>
{% endblock %}
{% block customerservice %}{% endblock %}
{% block footer %}{% endblock %}
This problem is due to validation done in javascript. Not related to django form wizard or django as such.
You may want to disable it or skip in particular case.