var SerializableView = View.extend({ events: { "change select": "update_select", "change [type=date]": "update_date", "focus input": "focus_input", "click .date-wrapper": "focus_date", "submit form": "save", }, preload: function(data){ if (! data && sdk.env == "production") { return } data = data || this.test_data if (! data) { return } this.load_data(data) }, load_data: function(data){ Object.keys(data).forEach(function(key){ var value = data[key] var $el = this.$("[name=" + key + "]") if ($el.attr("type") == "checkbox") { $el.prop("checked", value) } if ($el.attr("type") == "date") { $el.val( value ) this.update_date({ currentTarget: $el }) } else if ($el.prop("tagName") == "SELECT") { $el.val( value ) this.update_select({ currentTarget: $el }) } else { $el.val( value ) } }.bind(this)) }, serialize: function(){ var fields = {} this.$("input[name], select[name], textarea[name]").each( function(){ if (this.type == "checkbox") { if ($(this).prop("checked")) { fields[this.name] = this.value || "true" } } else { fields[this.name] = this.value } }) return fields }, deserialize: function(data){ this.$("input[name], textarea[name]").val("") Object.keys(data).forEach(function(k){ this.$("[" + k + "]").val(data[k]) }) }, focus_input: function(e){ $(e.currentTarget).removeClass("error_hilite") $(e.currentTarget).closest(".checkbox-row").removeClass("error_hilite") }, focus_date: function(e){ $(e.currentTarget).find("input").focus() }, update_select: function(e){ var $target = $(e.currentTarget), value = $target.val() var label = $target.find("option").filter(function(){ return this.value === value }).html() var $parent = $target.parent() $parent.addClass("picked").removeClass("error_hilite") $parent.find("span").html(label) }, update_date: function(e){ var $target = $(e.currentTarget), value = $target.val() var label = moment(value).format("MM/DD/YYYY") if (label === 'Invalid date') { label = '' // 'BIRTHDAY (OPTIONAL)' } $target.parent().addClass("picked") $target.parent().find("span").html(label) }, validate: function(data, errors){ var data = data || this.serialize() var errors = errors || [] var presence_msgs = this.validate_presence || {} if (! this.disabled) { Object.keys(presence_msgs).forEach(function(k){ if (! data[k]) errors.push( [ k, presence_msgs[k] ] ) }) } this.validate_fields && this.validate_fields(data, errors) this.cc && this.cc.validate(data, errors) this.address && this.address.validate(data, errors) return { errors: errors, data: data } }, show_errors: function(errors){ console.log("showing errors") console.log(errors) var msgs = [] this.$('.err_heading').addClass('error_visible') this.$('.error_hilite').removeClass('error_hilite') this.$('.err').html('') errors.forEach(function(e, i){ // if (i > 0) { return } if (e[0]) { var $el = this.$("[name=" + e[0] + "]") var el = $el[0] if (el && el.nodeName === 'SELECT') { $el.parent().addClass('error_hilite') $el.parent().next('.err').html(e[1]) } else if (el && el.type === 'date') { $el.parent().addClass('error_hilite') $el.parent().next('.err').html(e[1]) } else { $el.addClass('error_hilite') $el.next('.err').html(e[1]) } } // msgs.push(e[1]) }.bind(this)) // this.$msg.html(msgs.join("
")) this.$msg.addClass('alert-notice') if (app.view.scroller) { app.view.scroller.refresh() app.view.scroller.scrollTo(0, 0) } }, hide_errors: function(){ this.$msg.removeClass('alert-notice') this.$msg.html("") }, finalize: function(data){ return data }, save: function(e){ e && e.preventDefault() this.$('.err_heading').removeClass('error_visible') var valid = this.validate() if (valid.errors.length) { this.show_errors(valid.errors) return } else { this.hide_errors() window.cordova && cordova.plugins.Keyboard.close() } var finalized_data = this.finalize(valid.data) this.submit( finalized_data ) }, submit: function(data){ if (! data) { return } app.curtain.show("loading") this.action({ data: data, success: function(data){ app.curtain.hide("loading") this.success(data) }.bind(this), error: function(data){ app.curtain.hide("loading") console.log("api error") this.error(data) }.bind(this), }) }, success: function(data){ console.log("SUCCESS") console.log(data) }, error: function(data){ console.log("FAIL") console.log(data) }, }) var FormView = View.extend(SerializableView.prototype).extend(ScrollableView.prototype)