UNPKG

dentalruralhealth-pack

Version:

Interactive to simulate a rural health office creation

446 lines (385 loc) 13.5 kB
/* global module: true */ // eslint-disable-next-line no-redeclare var jQuery = require('jquery'); var Backbone = require('backbone'); var _ = require('underscore'); var NumberedStepsView = require('./steps.js'); var models = require('./models.js'); window.jQuery = window.$ = jQuery; require('bootstrap'); var BaseView = Backbone.View.extend({ initializeResponses: function(responses) { this.responses = responses; }, initializeMap: function(layers) { this.layers = layers; var self = this; for (var i = 0; i < this.layers.length; i++) { this.layers.at(i).bind('change:visible', self.renderMap); } }, onSelectLayer: function(evt) { var layerId = jQuery(evt.target).data('id'); var layer = this.layers.get(layerId); layer.set('visible', jQuery(evt.target).is(':checked')); }, renderMap: function() { for (var i = 0; i < this.layers.length; i++) { var layer = this.layers.at(i); var $elt = this.$el.find('.map_layer_' + layer.id); if ($elt.length < 1) { continue; } var $legend = this.$el.find('.map_legend_' + layer.id); if (layer.get('visible')) { $elt[0].style.display = ''; $legend[0].style.display = ''; } else { $elt[0].style.display = 'none'; $legend[0].style.display = 'none'; } } }, onShowStrategy: function(evt) { var dataId = jQuery(evt.target).data('id'); this.visibleStrategy = this.strategies.get(dataId); var ctx = this.visibleStrategy.toTemplate(); ctx.showProsAndCons = this.showProsAndCons; var markup = this.strategyTemplate(ctx); var $modal = this.$el.find('#strategy-modal'); $modal.find('.modal-body').html(markup); $modal.modal({show_pros_cons: false}); }, onHideStrategy: function(evt) { this.visibleStrategy.set('viewed', true); }, isFormComplete: function(form) { var self = this; var valid = true; var children = jQuery(form).find('input,textarea,select'); jQuery.each(children, function() { if (valid && jQuery(this).is(':visible')) { var value; if (this.tagName === 'INPUT' && this.type === 'text' || this.tagName === 'TEXTAREA') { value = jQuery(this).val().trim(); valid = value.length > 0; } if (this.tagName === 'SELECT') { value = jQuery(this).val(); valid = value !== undefined && value.length > 0 && jQuery(this).val().trim() !== '-----'; } if (this.type === 'checkbox' || this.type === 'radio') { // one in the group needs to be checked var selector = 'input[name=' + jQuery(this).attr('name') + ']:checked'; value = jQuery(selector).val(); valid = value !== undefined; } if (valid) { self.responses[jQuery(this).attr('name')] = value; } } }); if (!valid) { alert('Please complete all form fields before continuing.'); } return valid; } }); var IntroView = BaseView.extend({ initialize: function(options) { _.bindAll(this, 'render'); this.template = require('../static/templates/page_one.html'); }, render: function() { var markup = this.template({ 'image': './northoralington.jpg' }); this.$el.html(markup); this.$el.show(); this.trigger('complete', this); } }); var StrategyView = BaseView.extend({ events: { 'click .select-layer': 'onSelectLayer', 'click .strategy-state': 'onShowStrategy', 'hidden.bs.modal #strategy-modal': 'onHideStrategy', }, initialize: function(options) { _.bindAll( this, 'render', 'renderMap', 'onSelectLayer', 'onShowStrategy', 'onHideStrategy', 'maybeComplete'); this.complete = false; this.strategies = options.strategies; this.initializeMap(options.layers); this.template = require('../static/templates/page_two.html'); this.strategyTemplate = require('../static/templates/strategy.html'); var self = this; for (var i = 0; i < this.strategies.length; i++) { this.strategies.at(i).bind('change:viewed', self.render); } }, render: function() { var markup = this.template({ strategies: this.strategies.toTemplate(), layers: this.layers.toTemplate(), complete: this.complete }); this.$el.html(markup); this.$el.show(); this.renderMap(); this.maybeComplete(); }, maybeComplete: function() { if (!this.complete) { var complete = 0; for (var i = 0; i < this.strategies.length; i++) { var strategy = this.strategies.at(i); if (strategy.get('viewed')) { complete++; } } if (complete === this.strategies.length) { this.complete = true; this.trigger('complete', this); } } } }); var SelectStrategyView = BaseView.extend({ events: { 'click button#select-strategy': 'onSelectStrategy', 'click .strategy-state': 'onShowStrategy' }, initialize: function(options) { _.bindAll( this, 'render', 'renderMap', 'onSelectStrategy', 'onShowStrategy', 'maybeComplete'); this.selectedStrategy = null; this.strategies = options.strategies; this.initializeResponses(options.responses); this.initializeMap(options.layers); this.template = require('../static/templates/page_three.html'); this.strategyTemplate = require('../static/templates/strategy.html'); var self = this; for (var i = 0; i < this.strategies.length; i++) { this.strategies.at(i).bind('change:selected', self.render); } }, strategyCtx: function() { var ctx = { strategies: this.strategies.toTemplate(), layers: this.layers.toTemplate(), selectedStrategy: null }; if (this.selectedStrategy) { ctx.selectedStrategy = this.selectedStrategy.toTemplate(); } return ctx; }, render: function() { this.selectedStrategy = this.strategies.selected(); var markup = this.template(this.strategyCtx()); this.$el.html(markup); this.$el.show(); this.renderMap(); this.maybeComplete(); }, maybeComplete: function() { if (this.selectedStrategy) { this.trigger('complete', this); } }, onSelectStrategy: function(evt) { evt.preventDefault(); var selected = jQuery(this.el).find('input[name="strategy"]:checked'); if (selected.length < 1) { alert('Please select a strategy to defend'); return false; } else { var dataId = parseInt(jQuery(selected[0]).val(), 10); for (var i = 0; i < this.strategies.length; i++) { var strategy = this.strategies.at(i); strategy.set('selected', strategy.id === dataId); } } } }); var DefendStrategyView = BaseView.extend({ events: { 'click button#defend-strategy': 'onSubmit', 'click .strategy-state': 'onShowStrategy' }, initialize: function(options) { _.bindAll(this, 'render', 'renderMap', 'onShowStrategy', 'onSubmit'); this.complete = false; this.strategies = options.strategies; this.initializeResponses(options.responses); this.initializeMap(options.layers); this.template = require('../static/templates/page_four.html'); this.strategyTemplate = require('../static/templates/strategy.html'); }, render: function() { var ctx = { complete: this.complete, strategies: this.strategies.toTemplate(), responses: this.responses, layers: this.layers.toTemplate(), selectedStrategy: this.strategies.selected().toTemplate() }; var markup = this.template(ctx); this.$el.html(markup); this.$el.show(); this.renderMap(); }, onSubmit: function(evt) { evt.preventDefault(); var form = jQuery(this.el).find('form'); if (!this.isFormComplete(form)) { return; } this.complete = true; this.render(); this.trigger('complete', this); } }); var ProsAndConsView = BaseView.extend({ events: { 'click .strategy-state': 'onShowStrategy' }, initialize: function(options) { _.bindAll(this, 'render', 'renderMap', 'onShowStrategy'); this.showProsAndCons = true; this.complete = true; this.strategies = options.strategies; this.initializeMap(options.layers); this.template = require('../static/templates/page_five.html'); this.strategyTemplate = require('../static/templates/strategy.html'); }, render: function() { var ctx = { strategies: this.strategies.toTemplate(), layers: this.layers.toTemplate(), selectedStrategy: this.strategies.selected().toTemplate() }; var markup = this.template(ctx); this.$el.html(markup); this.$el.show(); this.renderMap(); this.complete = true; this.trigger('complete', this); } }); var RethinkView = BaseView.extend({ events: { 'click button#rethink-strategy': 'onSubmit', 'click .strategy-state': 'onShowStrategy' }, initialize: function(options) { _.bindAll(this, 'render', 'renderMap', 'onSubmit'); this.complete = false; this.strategies = options.strategies; this.initializeResponses(options.responses); this.initializeMap(options.layers); this.template = require('../static/templates/page_six.html'); this.strategyTemplate = require('../static/templates/strategy.html'); }, render: function() { var ctx = { complete: this.complete, strategies: this.strategies.toTemplate(), responses: this.responses, layers: this.layers.toTemplate(), selectedStrategy: this.strategies.selected().toTemplate() }; var markup = this.template(ctx); this.$el.html(markup); this.$el.show(); this.renderMap(); }, onSubmit: function(evt) { evt.preventDefault(); var form = jQuery(this.el).find('form'); if (!this.isFormComplete(form)) { return; } this.complete = true; this.render(); this.trigger('complete', this); } }); var RuralHealthOfficeApp = { initialize: function(options) { var $parent = jQuery('.rural-health-office'); var data = require('../static/json/layers.json'); var layers = new models.MapLayerList(data); data = require('../static/json/strategies.json'); var strategies = new models.StrategyList(data); var views = []; var responses = {}; // Step 1 var page = jQuery('<div></div>'); $parent.append(page); var view = new IntroView({ el: page }); views.push(view); // Step 2 page = jQuery('<div></div>'); $parent.append(page); view = new StrategyView({ el: page, layers: layers, strategies: strategies }); views.push(view); // Step 3 page = jQuery('<div></div>'); $parent.append(page); view = new SelectStrategyView({ el: page, layers: layers, strategies: strategies, responses: responses }); views.push(view); // Step 4 page = jQuery('<div></div>'); $parent.append(page); view = new DefendStrategyView({ el: page, layers: layers, strategies: strategies, responses: responses }); views.push(view); // Step 5 page = jQuery('<div></div>'); $parent.append(page); view = new ProsAndConsView({ el: page, layers: layers, strategies: strategies }); views.push(view); // Step 6 page = jQuery('<div></div>'); $parent.append(page); view = new RethinkView({ el: page, layers: layers, strategies: strategies, responses: responses }); views.push(view); this.steps = new NumberedStepsView({ el: jQuery('.steps'), views: views }); jQuery('.interactive-container').show(); } }; module.exports.RuralHealthOfficeApp = RuralHealthOfficeApp;