mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-18 05:51:26 +02:00
Merge pull request #735 from tonioo/conditional_wizard_step
Conditional wizard step
This commit is contained in:
+53
-31
@@ -24,26 +24,17 @@ class WizardStep(object):
|
||||
|
||||
"""A wizard step."""
|
||||
|
||||
def __init__(self, cls, title, formtpl=None, new_args=None):
|
||||
"""Constructor.
|
||||
|
||||
"""
|
||||
self._cls = cls
|
||||
self._title = title
|
||||
def __init__(self, uid, formclass, title, formtpl=None, new_args=None):
|
||||
"""Constructor."""
|
||||
self.uid = uid
|
||||
self._cls = formclass
|
||||
self.title = title
|
||||
self.formtpl = formtpl
|
||||
self._new_args = new_args
|
||||
self._prev = None
|
||||
self._next = None
|
||||
self.index = None
|
||||
self.form = None
|
||||
|
||||
@property
|
||||
def title(self):
|
||||
"""Return step title"""
|
||||
if self.index is None:
|
||||
return self._title
|
||||
return "%d. %s" % (self.index + 1, self._title)
|
||||
|
||||
@property
|
||||
def prev(self):
|
||||
return self._prev
|
||||
@@ -60,7 +51,12 @@ class WizardStep(object):
|
||||
def next(self, step):
|
||||
self._next = step
|
||||
|
||||
def check_access(self, wizard):
|
||||
"""Check if this step should be displayed or not."""
|
||||
return True
|
||||
|
||||
def create_form(self, data=None):
|
||||
"""Instantiate a new form."""
|
||||
args = []
|
||||
if self._new_args is not None:
|
||||
args += self._new_args
|
||||
@@ -100,44 +96,69 @@ class WizardForm(object):
|
||||
|
||||
@property
|
||||
def first_step(self):
|
||||
"""Return the first step.
|
||||
"""
|
||||
"""Return the first step."""
|
||||
return self.steps[0] if self.steps else None
|
||||
|
||||
def add_step(self, cls, title, formtpl=None, new_args=None):
|
||||
"""Add a new step to the wizard.
|
||||
"""
|
||||
step = WizardStep(cls, title, formtpl, new_args)
|
||||
def add_step(self, step):
|
||||
"""Add a new step to the wizard."""
|
||||
if self.steps:
|
||||
step.prev = self.steps[-1]
|
||||
self.steps[-1].next = step
|
||||
self.steps += [step]
|
||||
step.index = len(self.steps) - 1
|
||||
|
||||
def create_forms(self, data=None):
|
||||
for step in self.steps:
|
||||
step.create_form(data)
|
||||
|
||||
def validate_step(self):
|
||||
def _get_step_id(self):
|
||||
"""Retrieve the step identifier from the request."""
|
||||
stepid = self.request.POST.get("stepid", None)
|
||||
if stepid is None:
|
||||
raise BadRequest(_("Invalid request"))
|
||||
stepid = int(stepid.replace("step", ""))
|
||||
if stepid < 0 or stepid > len(self.steps):
|
||||
if stepid < 0:
|
||||
raise BadRequest(_("Invalid request"))
|
||||
return min(stepid, len(self.steps))
|
||||
|
||||
def previous_step(self):
|
||||
"""Go back to the previous step."""
|
||||
stepid = self._get_step_id()
|
||||
stepid -= 2
|
||||
self.create_forms(self.request.POST)
|
||||
for step in self.steps:
|
||||
step.form.is_valid()
|
||||
while stepid >= 0:
|
||||
if self.steps[stepid].check_access(self):
|
||||
break
|
||||
stepid -= 1
|
||||
return render_to_json_response({
|
||||
"title": self.steps[stepid].title, "id": self.steps[stepid].uid,
|
||||
"stepid": stepid
|
||||
})
|
||||
|
||||
def next_step(self):
|
||||
"""Go to the next step if previous forms are valid."""
|
||||
stepid = self._get_step_id()
|
||||
self.create_forms(self.request.POST)
|
||||
statuses = []
|
||||
for cpt in xrange(0, stepid):
|
||||
statuses.append(self.steps[cpt].form.is_valid())
|
||||
if self.steps[cpt].check_access(self):
|
||||
statuses.append(self.steps[cpt].form.is_valid())
|
||||
if False in statuses:
|
||||
return render_to_json_response({
|
||||
'stepid': stepid, 'form_errors': self.errors
|
||||
"stepid": stepid, "id": self.steps[stepid - 1].uid,
|
||||
"form_errors": self.errors
|
||||
}, status=400)
|
||||
while stepid < len(self.steps):
|
||||
if self.steps[stepid].check_access(self):
|
||||
break
|
||||
stepid += 1
|
||||
if stepid == len(self.steps):
|
||||
return self.done()
|
||||
return render_to_json_response(
|
||||
{'title': self.steps[stepid].title, 'stepid': stepid}
|
||||
)
|
||||
return render_to_json_response({
|
||||
"title": self.steps[stepid].title, "id": self.steps[stepid].uid,
|
||||
"stepid": stepid
|
||||
})
|
||||
|
||||
def extra_context(self, context):
|
||||
"""Provide additional information to template's context.
|
||||
@@ -145,10 +166,11 @@ class WizardForm(object):
|
||||
pass
|
||||
|
||||
def process(self):
|
||||
"""Process the request.
|
||||
"""
|
||||
"""Process the request."""
|
||||
if self.request.method == "POST":
|
||||
return self.validate_step()
|
||||
if self.request.POST.get("target", "next") == "next":
|
||||
return self.next_step()
|
||||
return self.previous_step()
|
||||
self.create_forms()
|
||||
context = {"wizard": self}
|
||||
self.extra_context(context)
|
||||
|
||||
@@ -34,9 +34,9 @@
|
||||
$(".modal-header").find("small").html(title);
|
||||
},
|
||||
|
||||
post: function(last) {
|
||||
post: function(last, target) {
|
||||
var $form = (this.options.formid) ? $('#' + this.options.formid) : $('form');
|
||||
var data = $form.serialize() + "&stepid=" + this.get_current_step_id();
|
||||
var data = $form.serialize() + "&stepid=" + this.get_current_step_id() + "&target=" + target;
|
||||
|
||||
$.ajax({
|
||||
type: 'POST', url: $form.attr("action"), data: data, global: false
|
||||
@@ -44,11 +44,11 @@
|
||||
if (!last) {
|
||||
$('input:text:visible:first').focus();
|
||||
this.set_current_title(resp.title);
|
||||
if (this.options.transition_callbacks[resp.stepid] !== undefined) {
|
||||
this.options.transition_callbacks[resp.stepid]();
|
||||
if (this.options.transition_callbacks[resp.id] !== undefined) {
|
||||
this.options.transition_callbacks[resp.id]();
|
||||
}
|
||||
$(".carousel-inner").css("overflow", "hidden");
|
||||
this.$element.carousel('next');
|
||||
this.$element.carousel(resp.stepid);
|
||||
} else {
|
||||
$("#modalbox").modal('hide');
|
||||
if (this.options.success_callback !== undefined) {
|
||||
@@ -86,20 +86,23 @@
|
||||
var step_id = this.get_current_step_id();
|
||||
this.titles[step_id] = this.get_current_title();
|
||||
this.$element.on('slid.bs.carousel', this.update_buttons);
|
||||
this.post(false);
|
||||
this.post(false, "next");
|
||||
},
|
||||
|
||||
/**
|
||||
* Go back to the previous step.
|
||||
*/
|
||||
prev: function(evt) {
|
||||
var stepid = this.get_current_step_id();
|
||||
|
||||
evt.preventDefault();
|
||||
this.$element.on('slid.bs.carousel', this.update_buttons);
|
||||
$(".carousel-inner").css("overflow", "hidden");
|
||||
this.$element.carousel('prev');
|
||||
this.set_current_title(this.titles[this.get_current_step_id()]);
|
||||
this.post(false, "prev", stepid);
|
||||
},
|
||||
|
||||
submit: function(evt) {
|
||||
evt.preventDefault();
|
||||
this.post(true);
|
||||
this.post(true, "next");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user