Answer the question
In order to leave comments, you need to log in
Backbone - transition through sub-tabs in turn, if the fields are all filled?
Hello. I'm more of a backend developer. Faced backbone + marionette.
The question is:
There are tabs, step 1 step 2, etc. While the user on each tab in turn fills out the form, it is impossible to move on to the next tab. It works. But starting from the second step, the tab has more sub-tabs (under steps), when filled in, validation does not work and you can walk through them back and forth, but you need to go to the next sub-tab only after filling in all the fields.
When I set a breakpoint to fire, the tab transition event fires only for tabs and not for tabs.
Here is the code itself:
views/inputs/steps.js
Lib.ns('Views.Inputs', function(Inputs) {
'use strict';
var Empty = Mn.ItemView.extend({
tagName: 'li',
template: function() { return ''; }
});
var Tab = Mn.ItemView.extend({
template: '#Inputs-StepTabTemplate',
tagName: 'li',
triggers: {click: 'select'},
ui: {index: '[data-ui="index"]'},
bindings: {'[data-ui="title"]': 'title'},
onRender: function() {
this.stickit();
this.ui.index.html(this.getOption('index') + 1);
}
});
var Tabs = Mn.CollectionView.extend({
tagName: 'ul',
className: 'special',
childView: Tab,
childEvents: {select: 'selectHandler'},
filter: function(child) {
return child.get('name') !== 'active_step';
},
childViewOptions: function(item, index) {
return {index: index};
},
selectHandler: function(view) {
this.triggerMethod('select', this.collection.indexOf(view.model));
},
select: function(index) {
this.$('li').removeClass('uk-active');
this.children.findByModel(this.collection.at(index)).$el.addClass('uk-active');
}
});
var Parent = Inputs.Container;
var Steps = Parent.extend({
tagName: 'ul',
className: 'uk-switcher special',
defaultChild: Empty,
initialize: function() {
Parent.prototype.initialize.apply(this, arguments);
this.collection = this.model.get('fields');
},
childViewOptions: function(item) {
var opts = Parent.prototype.childViewOptions.apply(this, arguments);
opts.tagName = 'li';
opts.showTitle = item.has('showTitle') ? item.get('showTitle') : false;
opts.formSection = false;
return opts;
}
});
Inputs.Steps = Mn.LayoutView.extend({
className: 'steps',
template: '#Inputs-StepsTemplate',
behaviors: {
Messageable: {el: '[data-region="messages"]'},
},
regions: {
tabs: '[data-region="step-tabs"]',
panes: '[data-region="step-panes"]'
},
ui: {
prev: '[data-ui="prev"]',
next: '[data-ui="next"]',
save: '[data-ui="save"]'
},
events: {
'click @ui.prev': 'prevClickHandler',
'click @ui.next': 'nextClickHandler',
'click @ui.save': 'saveClickHandler'
},
childEvents: {
next: 'nextHandler'
},
initialize: function() {
var fields = this.model.get('fields');
this.activeStep = this.model.find('active_step');
if (!this.activeStep) {
fields.add({name: 'active_step', type: 'integer', visible: false});
this.activeStep = this.model.find('active_step');
this.activeStep.setValue(0);
}
var step = this.getOption('step');
if (step == null) { step = this.activeStep.getValue(); }
if (step == null) { step = 0; }
this.activeStep.setValue(step);
},
select: function(index) {
if (!this.switcher) { return; }
this.scrollTop();
this.tabs.select(index);
this.switcher.show(index);
this.activeStep.setValue(index);
},
onRender: function() {
var opts = {
rootView: this.getOption('rootView') || this,
collection: this.model.get('fields')
};
this.tabs = new Tabs(opts);
this.listenTo(this.tabs, 'select', this.selectHandler);
this.fakeTabs = new Tabs(opts);
this.steps = new Steps(_.extend(opts, {model: this.model}));
this.getRegion('tabs').show(this.tabs);
this.getRegion('panes').show(this.steps);
this.fakeTabs.render();
var step = this.activeStep.getValue();
this.index = step;
this.updateNavigation();
_.defer(function(view) {
view.switcher = UIkit.switcher(view.fakeTabs.$el, {
connect: view.steps.$el,
animation: 'slide-horizontal'
});
view.switcher.on('show.uk.switcher', _.bind(view.switchHandler, view));
view.select(step);
}, this);
},
updateNavigation: function(index) {
if (index == null) { index = this.index; }
if (index === 0) {
this.ui.prev.attr('disabled', 'disabled');
} else {
this.ui.prev.removeAttr('disabled');
}
// this.tabs.collection.length - active_step - 1
if (index === this.tabs.children.length - 1) {
this.ui.next.find('span').html('Подготовить');
} else {
this.ui.next.find('span').html('Следующий шаг');
}
},
setRegistered: function(registered) {
this.registered = registered;
if (registered) {
this.ui.save.show();
} else {
this.ui.save.hide();
}
},
switchHandler: function(event, item) {
this.index = $(item).index();
this.updateNavigation();
},
prevClickHandler: function() {
if (this.index === 0) { return; }
this.select(this.index - 1);
},
nextClickHandler: function() {
var view = this.getOption('rootView') || this;
if (this.index === this.tabs.children.length - 1) {
if (!this.validateCurrentStep()) {
this.scrollTop();
return;
}
view.triggerMethod('create');
} else {
if (this.index === 0 && !this.registered) {
view.triggerMethod('register', 1);
return;
}
if (!this.validateCurrentStep()) {
this.scrollTop();
return;
}
this.select(this.index + 1);
view.triggerMethod('save');
}
},
validateCurrentStep: function() {
return this.model.get('fields').at(this.index).validate();
},
saveClickHandler: function() {
var view = this.getOption('rootView') || this;
view.triggerMethod('save');
},
selectHandler: function(index) {
if (!this.registered) {
var view = this.getOption('rootView') || this;
view.triggerMethod('register', index);
return;
}
if (this.index < index && !this.validateCurrentStep()) {
this.scrollTop();
return;
}
this.select(index);
},
nextHandler: function(view) {
if (this.steps.children.last() === view) {
this.triggerMethod('next');
return;
}
var index = this.model.get('fields').indexOf(view.model);
if (index >= 0) { this.select(index + 1); }
},
scrollTop: function() {
// stop scroll animation on any user action
var stopEvents = 'scroll mousedown wheel DOMMouseScroll mousewheel keyup touchmove';
var stop = function() {
UIkit.$('html,body').stop();
$('html,body').off(stopEvents, stop);
};
$('html,body').on(stopEvents, stop);
UIkit.Utils.scrollToElement(this.tabs.$el, {
complete: function() { $('html,body').off(stopEvents, stop); }
});
}
});
});
selectHandler: function(view) {
this.triggerMethod('select', this.collection.indexOf(view.model));
},
var Steps = Parent.extend({
tagName: 'ul',
className: 'uk-switcher special',
defaultChild: Empty
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question