From f0c551933c5e725b980014b559d757bee99d0536 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Wed, 25 Nov 2015 04:08:39 -0500 Subject: fix auth bugs pt 1 --- StoneIsland/www/js/lib/account/AccountView.js | 2 + StoneIsland/www/js/lib/auth/LogoutView.js | 3 +- StoneIsland/www/js/lib/cart/CartSummary.js | 18 +-- StoneIsland/www/js/lib/cart/CartView.js | 14 +++ StoneIsland/www/js/lib/nav/HeaderView.js | 2 +- StoneIsland/www/js/lib/products/ProductView.js | 27 ++--- StoneIsland/www/js/lib/view/Router.js | 75 +++++++++++++ StoneIsland/www/js/lib/view/Scrollable.js | 20 ++++ StoneIsland/www/js/lib/view/Serializable.js | 129 ++++++++++++++++++++++ StoneIsland/www/js/lib/view/View.js | 147 +++++++++++++++++++++++++ StoneIsland/www/js/sdk/auth.js | 14 ++- StoneIsland/www/js/vendor/view/router.js | 75 ------------- StoneIsland/www/js/vendor/view/scrollable.js | 20 ---- StoneIsland/www/js/vendor/view/serializable.js | 129 ---------------------- StoneIsland/www/js/vendor/view/view.js | 147 ------------------------- 15 files changed, 417 insertions(+), 405 deletions(-) create mode 100644 StoneIsland/www/js/lib/view/Router.js create mode 100644 StoneIsland/www/js/lib/view/Scrollable.js create mode 100644 StoneIsland/www/js/lib/view/Serializable.js create mode 100644 StoneIsland/www/js/lib/view/View.js delete mode 100644 StoneIsland/www/js/vendor/view/router.js delete mode 100644 StoneIsland/www/js/vendor/view/scrollable.js delete mode 100644 StoneIsland/www/js/vendor/view/serializable.js delete mode 100644 StoneIsland/www/js/vendor/view/view.js (limited to 'StoneIsland/www/js') diff --git a/StoneIsland/www/js/lib/account/AccountView.js b/StoneIsland/www/js/lib/account/AccountView.js index cbd9a9c6..ddca9666 100644 --- a/StoneIsland/www/js/lib/account/AccountView.js +++ b/StoneIsland/www/js/lib/account/AccountView.js @@ -48,10 +48,12 @@ var AccountView = View.extend({ cb && cb() } if ( ! auth.has_cart() ) { + console.log("VV make cart") auth.create_cart(auth.add_deferred_product_to_cart) } else { if (auth.deferred_product) { + console.log("VV got def prod", auth.deferred_product) auth.add_deferred_product_to_cart() } else { diff --git a/StoneIsland/www/js/lib/auth/LogoutView.js b/StoneIsland/www/js/lib/auth/LogoutView.js index 735c0242..481dcb8d 100644 --- a/StoneIsland/www/js/lib/auth/LogoutView.js +++ b/StoneIsland/www/js/lib/auth/LogoutView.js @@ -7,9 +7,10 @@ var LogoutView = View.extend({ show: function(){ document.body.className = "logout" + app.header.set_cart_count(0) app.footer.hide() + auth.log_out() app.account.logged_out() - auth.clear_user() }, }) \ No newline at end of file diff --git a/StoneIsland/www/js/lib/cart/CartSummary.js b/StoneIsland/www/js/lib/cart/CartSummary.js index 209e3102..05842380 100644 --- a/StoneIsland/www/js/lib/cart/CartSummary.js +++ b/StoneIsland/www/js/lib/cart/CartSummary.js @@ -110,21 +110,21 @@ var CartSummary = ScrollableView.extend({ .replace(/{{price}}/, as_cash(details.Item.Price.DiscountedPrice)) $el.data("price", details.Item.Price.DiscountedPrice) $el.html(t) - this.deferScrollToTop() + this.refreshScroller() }.bind(this)) }.bind(this)) this.updateTotals() this.el.className = "full" - this.deferScrollToTop() + this.refreshScroller() }, updateCounts: function(){ - app.header.set_cart_count(this.data.Cart.Items.length) - this.parent.$itemcount.html(pluralize(this.data.Cart.Items.length, "ITEM", "S")) + app.header.set_cart_count( this.data.Cart.Items.length ) + this.parent.setHeaderCount( this.data.Cart.Items.length ) }, - + updateTotals: function(){ var subtotal = this.data.Cart.Totals.TotalWithoutPromotions var shipping_cost = this.data.Cart.DeliveryMethod.Selected.Amount.Total @@ -140,6 +140,7 @@ var CartSummary = ScrollableView.extend({ empty: function(){ app.footer.hide() app.header.set_cart_count(0) + this.parent.setHeaderCount( 0 ) this.parent.$itemcount.html("0 ITEMS") this.el.className = "empty" }, @@ -155,9 +156,9 @@ var CartSummary = ScrollableView.extend({ remove_item: function(e){ var $el = $( e.currentTarget ).closest(".cart_item_row") var data = $el.data() - data.Cart.Totals.TotalWithoutPromotions -= data.price - data.Cart.Totals.TotalToPay -= data.price - + + this.data.Cart.Totals.TotalWithoutPromotions -= data.price + this.data.Cart.Totals.TotalToPay -= data.price this.data.Cart.Items = this.data.Cart.Items.filter(function(item){ return ( item['Code10'] !== data.code || item['Size'] !== data.size) }) @@ -165,6 +166,7 @@ var CartSummary = ScrollableView.extend({ this.updateTotals() this.updateCounts() $el.remove() + this.refreshScroller() if (this.data.Cart.Items.length == 0) { this.empty() diff --git a/StoneIsland/www/js/lib/cart/CartView.js b/StoneIsland/www/js/lib/cart/CartView.js index 8bea43dc..b57caadd 100644 --- a/StoneIsland/www/js/lib/cart/CartView.js +++ b/StoneIsland/www/js/lib/cart/CartView.js @@ -15,6 +15,8 @@ var CartView = View.extend({ this.confirm = new CartConfirm ({ parent: this }) this.thanks = new CartThanks ({ parent: this }) + this.$full_msg = this.$(".full_msg") + this.$empty_msg = this.$(".empty_msg") this.$itemcount = this.$(".itemcount") }, @@ -47,4 +49,16 @@ var CartView = View.extend({ this.payment.show() }, + setHeaderCount: function(n){ + if (n) { + this.$itemcount.html(pluralize(n, "ITEM", "S")) + this.$full_msg.show() + this.$empty_msg.hide() + } + else { + this.$full_msg.hide() + this.$empty_msg.show() + } + }, + }) \ No newline at end of file diff --git a/StoneIsland/www/js/lib/nav/HeaderView.js b/StoneIsland/www/js/lib/nav/HeaderView.js index 7563be2d..f4b3f76e 100644 --- a/StoneIsland/www/js/lib/nav/HeaderView.js +++ b/StoneIsland/www/js/lib/nav/HeaderView.js @@ -43,7 +43,7 @@ var HeaderView = View.extend({ count: 0, set_cart_count: function(n){ this.count = n - this.$cart_count.html(n) + this.$cart_count.html(n || " ") }, increment_cart_count: function(){ this.$cart_count.html( ++this.count ) diff --git a/StoneIsland/www/js/lib/products/ProductView.js b/StoneIsland/www/js/lib/products/ProductView.js index c99ff0ab..bd28955f 100644 --- a/StoneIsland/www/js/lib/products/ProductView.js +++ b/StoneIsland/www/js/lib/products/ProductView.js @@ -205,27 +205,14 @@ var ProductView = ScrollableView.extend({ // ADD TO CART save: function(){ - auth.deferred_product = { Size: this.size, Code10: this.code } - if ( ! auth.logged_in() ) { - app.router.go("account/login") - app.last_view = app.cart - } - else if ( ! auth.has_cart() ) { - auth.create_cart(function(){ - auth.add_deferred_product_to_cart(function(){ - app.router.go("cart") - }) - }) - } - else { - auth.add_deferred_product_to_cart(function(){ - app.router.go("cart") - }) - } + this.add_to_cart({ route: false }) }, - // BUY NOW cancel: function(){ + this.add_to_cart({ route: true }) + }, + + add_to_cart: function(opt){ auth.deferred_product = { Size: this.size, Code10: this.code } if ( ! auth.logged_in() ) { app.router.go("account/login") @@ -240,7 +227,9 @@ var ProductView = ScrollableView.extend({ } else { auth.add_deferred_product_to_cart(function(){ - app.router.go("cart") + if (opt.route) { + app.router.go("cart") + } }) } }, diff --git a/StoneIsland/www/js/lib/view/Router.js b/StoneIsland/www/js/lib/view/Router.js new file mode 100644 index 00000000..a8ec331f --- /dev/null +++ b/StoneIsland/www/js/lib/view/Router.js @@ -0,0 +1,75 @@ +var Router = View.extend({ + + routeByHash: false, + + go: function(url){ + this.parseRoute(url) + }, + + route: function(){ + var path = this.routeByHash ? window.location.hash.substr(0) : window.location.pathname + path = path || "/" + this.originalPath = path + this.parseRoute(path) + }, + + parseRoute: function(pathname){ + + pathname = pathname.replace(/^#/, "") + + if (pathname[0] !== "/") { pathname = "/" + pathname } + + var routes = this.routes, + path = pathname.split("/"); + + for (var i = 0; i < path.length; i++) { + if (! path[i].length) { + path[i] = null + } + } + + if (pathname in routes) { + this[this.routes[pathname]]() + return + } + + if (path[path.length-1] == null) { + path.pop() + } + + for (var route in routes) { + var routePath = route.split("/") + if (routePath[1] == path[1]) { + if (routePath[2] && routePath[2].indexOf(":") !== -1 && path[2] && (path[3] === routePath[3]) ) { + this[this.routes[route]](path[2]) + return + } + else if (routePath[2] == path[2]) { + if (routePath[3] && path[3]) { + if (routePath[3].indexOf(":") !== -1) { + this[this.routes[route]](path[3]) + return + } + else if (routePath[3] == path[3]) { + this[this.routes[route]]() + return + } + } + else if (! routePath[3] && ! path[3]) { + this[this.routes[route]]() + return + } + } + else if (! routePath[2] && (! path[2].length || ! path[2])) { + this[this.routes[route]]() + return + } + } + } + + if (is_mobile) { + window.location.href = "/" + } + } + +}) diff --git a/StoneIsland/www/js/lib/view/Scrollable.js b/StoneIsland/www/js/lib/view/Scrollable.js new file mode 100644 index 00000000..7cd96f89 --- /dev/null +++ b/StoneIsland/www/js/lib/view/Scrollable.js @@ -0,0 +1,20 @@ +var ScrollableView = View.extend({ + + events: { + "load img": "deferScrollToTop", + }, + + deferScrollToTop: function(){ + setTimeout(this.scrollToTop.bind(this), 0) + }, + + refreshScroller: function(){ + this.scroller.refresh() + }, + + scrollToTop: function(){ + this.scroller.refresh() + app.collection.scroller.scrollTo(0, 0) + }, + +}) \ No newline at end of file diff --git a/StoneIsland/www/js/lib/view/Serializable.js b/StoneIsland/www/js/lib/view/Serializable.js new file mode 100644 index 00000000..e9459229 --- /dev/null +++ b/StoneIsland/www/js/lib/view/Serializable.js @@ -0,0 +1,129 @@ +var SerializableView = View.extend({ + + events: { + "change select": "update_select", + "focus input": "focus_input", + }, + + preload: function(data){ + if (! data && sdk.env == "production") { return } + data = data || this.test_data + if (! data) { return } + + Object.keys(data).forEach(function(key){ + var value = data[key] + var $el = this.$("[name=" + key + "]") + + if ($el.attr("type") == "checkbox") { + $el.prop("checked", value) + } + 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 + } + } + 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") + }, + + update_select: function(e){ + var $target = $(e.currentTarget), value = $target.val() + var label = $($("select")[0]).find("option").filter(function(){ return this.value === value }).html() + + $target.parent().addClass("picked") + $target.parent().find("span").html(label) + }, + + validate: function(errors){ + var data = this.serialize() + var errors = [] + var presence_msgs = this.validate_presence + 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(errors) + this.address && this.address.validate(errors) + return { errors: errors, data: data } + }, + + show_errors: function(errors){ + var msgs = [] + errors.forEach(function(e, i){ + if (i > 0) { return } + this.$("[name=" + e[0] + "]").addClass('error_hilite') + msgs.push(e[1]) + }.bind(this)) + this.$msg.html(msgs.join("
")) + this.$msg.addClass('alert-notice') + }, + + hide_errors: function(){ + this.$msg.removeClass('alert-notice') + this.$msg.html("") + }, + + save: function(e){ + e && e.preventDefault() + + var valid = this.validate() + if (valid.errors.length) { + this.show_errors(valid.errors) + return + } + else { + this.hide_errors() + } + + app.curtain.show("loading") + this.action({ + data: valid.data, + success: function(data){ + app.curtain.hide("loading") + this.success(data) + }.bind(this), + error: function(data){ + app.curtain.hide("loading") + this.error(data) + }.bind(this), + }) + }, + + success: function(data){ + console.log("SUCCESS", data) + }, + + error: function(data){ + console.log("FAIL", data) + }, + +}) + +var FormView = View.extend(SerializableView.prototype).extend(ScrollableView.prototype) diff --git a/StoneIsland/www/js/lib/view/View.js b/StoneIsland/www/js/lib/view/View.js new file mode 100644 index 00000000..41638ab7 --- /dev/null +++ b/StoneIsland/www/js/lib/view/View.js @@ -0,0 +1,147 @@ +var View = (function($, _){ + + var View = function(options) { + this._id = _.uniqueId('view') + this.type = "view" + options || (options = {}); + _.extend(this, _.pick(options, viewOptions)) + this._ensureElement() + this.initialize.apply(this, arguments) + this.delegateEvents() + } + + var delegateEventSplitter = /^(\S+)\s*(.*)$/; + + var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events']; + + _.extend(View.prototype, { + + // The default `tagName` of a View's element is `"div"`. + tagName: 'div', + + $: function(selector) { + return this.$el.find(selector); + }, + + initialize: function(){}, + + setElement: function(element, delegate) { + if (this.$el) this.undelegateEvents(); + this.$el = element instanceof $ ? element : $(element); + this.el = this.$el[0]; + if (delegate !== false) this.delegateEvents(); + return this; + }, + + // Set callbacks, where `this.events` is a hash of + // + // *{"event selector": "callback"}* + // + // { + // 'mousedown .title': 'edit', + // 'click .button': 'save', + // 'click .open': function(e) { ... } + // } + // + // pairs. Callbacks will be bound to the view, with `this` set properly. + // Uses event delegation for efficiency. + // Omitting the selector binds the event to `this.el`. + // This only works for delegate-able events: not `focus`, `blur`, and + // not `change`, `submit`, and `reset` in Internet Explorer. + delegateEvents: function(events) { + if (!(events || (events = _.result(this, 'events')))) return this; + this.undelegateEvents(); + for (var key in events) { + var method = events[key]; + if (!_.isFunction(method)) method = this[events[key]]; + if (!method) continue; + + var match = key.match(delegateEventSplitter); + var eventName = match[1], selector = match[2]; + method = _.bind(method, this); + eventName += '.delegateEvents' + this._id; + if (is_mobile) { + if (eventName === 'mouseenter' || eventName === 'mouseleave') { + continue + } +// if (eventName === 'click') { +// eventName = 'tap' +// } + } + if (selector === '') { + this.$el.on(eventName, method); + } else { + this.$el.on(eventName, selector, method); + } + } + return this; + }, + + // Clears all callbacks previously bound to the view with `delegateEvents`. + undelegateEvents: function() { + this.$el.off('.delegateEvents' + this._id); + return this; + }, + + // Ensure that the View has a DOM element to render into. + // If `this.el` is a string, pass it through `$()`, take the first + // matching element, and re-assign it to `el`. Otherwise, create + // an element from the `id`, `className` and `tagName` properties. + _ensureElement: function() { + this.setElement(_.result(this, 'el'), false); + }, + + preventDefault: function(e){ + e && e.preventDefault() + }, + + stopPropagation: function(e){ + e && e.stopPropagation() + }, + + }); + + + var extend = function(protoProps, staticProps) { + var staticProps = staticProps || {} + var parent = this; + var child; + var childEvents = {}; + + // The constructor function for the new subclass is either defined by you + // (the "constructor" property in your `extend` definition), or defaulted + // by us to simply call the parent's constructor. + if (protoProps && _.has(protoProps, 'constructor')) { + child = protoProps.constructor; + } else { + child = function(){ return parent.apply(this, arguments); }; + } + + // Extend events so we can subclass views + _.extend(childEvents, parent.prototype.events, protoProps.events) + + // Add static properties to the constructor function, if supplied. + _.extend(child, parent, staticProps); + + // Set the prototype chain to inherit from `parent`, without calling + // `parent`'s constructor function. + var Surrogate = function(){ this.constructor = child; }; + Surrogate.prototype = parent.prototype; + child.prototype = new Surrogate; + + // Add prototype properties (instance properties) to the subclass, + // if supplied. + if (protoProps) _.extend(child.prototype, protoProps); + + // Set a convenience property in case the parent's prototype is needed + // later. + child.prototype.__super__ = parent.prototype; + child.prototype.events = childEvents + + return child; + }; + + View.extend = extend; + + return View; +})(jQuery, _) diff --git a/StoneIsland/www/js/sdk/auth.js b/StoneIsland/www/js/sdk/auth.js index 8a72dd46..87ce60ea 100644 --- a/StoneIsland/www/js/sdk/auth.js +++ b/StoneIsland/www/js/sdk/auth.js @@ -95,15 +95,20 @@ var auth = sdk.auth = (function(){ auth.add_deferred_product_to_cart = function(cb){ // auth.deferred_product if (! auth.deferred_product) { + console.log("VV NO DEF PROD") cb && cb() return } sdk.cart.add_item({ data: auth.deferred_product, success: function(){ - console.log("ADDED") + console.log("ADDED ITEM") cb && cb() - } + }, + error: function(data){ + console.log("ERROR ADDING ITEM", data) + cb && cb() + }, }) auth.deferred_product = null app.header.increment_cart_count() @@ -112,13 +117,12 @@ var auth = sdk.auth = (function(){ auth.log_out = function(){ auth.clear_user() auth.clear_cart() - auth.view_logged_out() } auth.logged_in = function(){ - return (auth.user_id !== -1) && (auth.user_id !== "undefined") + return (auth.user_id && auth.user_id !== -1 && auth.user_id !== "undefined") } auth.has_cart = function(){ - return (sdk.cart.id !== -1) && (sdk.cart.id !== "undefined") + return (sdk.cart.id && sdk.cart.id !== -1 && sdk.cart.id !== "undefined") } return auth diff --git a/StoneIsland/www/js/vendor/view/router.js b/StoneIsland/www/js/vendor/view/router.js deleted file mode 100644 index a8ec331f..00000000 --- a/StoneIsland/www/js/vendor/view/router.js +++ /dev/null @@ -1,75 +0,0 @@ -var Router = View.extend({ - - routeByHash: false, - - go: function(url){ - this.parseRoute(url) - }, - - route: function(){ - var path = this.routeByHash ? window.location.hash.substr(0) : window.location.pathname - path = path || "/" - this.originalPath = path - this.parseRoute(path) - }, - - parseRoute: function(pathname){ - - pathname = pathname.replace(/^#/, "") - - if (pathname[0] !== "/") { pathname = "/" + pathname } - - var routes = this.routes, - path = pathname.split("/"); - - for (var i = 0; i < path.length; i++) { - if (! path[i].length) { - path[i] = null - } - } - - if (pathname in routes) { - this[this.routes[pathname]]() - return - } - - if (path[path.length-1] == null) { - path.pop() - } - - for (var route in routes) { - var routePath = route.split("/") - if (routePath[1] == path[1]) { - if (routePath[2] && routePath[2].indexOf(":") !== -1 && path[2] && (path[3] === routePath[3]) ) { - this[this.routes[route]](path[2]) - return - } - else if (routePath[2] == path[2]) { - if (routePath[3] && path[3]) { - if (routePath[3].indexOf(":") !== -1) { - this[this.routes[route]](path[3]) - return - } - else if (routePath[3] == path[3]) { - this[this.routes[route]]() - return - } - } - else if (! routePath[3] && ! path[3]) { - this[this.routes[route]]() - return - } - } - else if (! routePath[2] && (! path[2].length || ! path[2])) { - this[this.routes[route]]() - return - } - } - } - - if (is_mobile) { - window.location.href = "/" - } - } - -}) diff --git a/StoneIsland/www/js/vendor/view/scrollable.js b/StoneIsland/www/js/vendor/view/scrollable.js deleted file mode 100644 index 7cd96f89..00000000 --- a/StoneIsland/www/js/vendor/view/scrollable.js +++ /dev/null @@ -1,20 +0,0 @@ -var ScrollableView = View.extend({ - - events: { - "load img": "deferScrollToTop", - }, - - deferScrollToTop: function(){ - setTimeout(this.scrollToTop.bind(this), 0) - }, - - refreshScroller: function(){ - this.scroller.refresh() - }, - - scrollToTop: function(){ - this.scroller.refresh() - app.collection.scroller.scrollTo(0, 0) - }, - -}) \ No newline at end of file diff --git a/StoneIsland/www/js/vendor/view/serializable.js b/StoneIsland/www/js/vendor/view/serializable.js deleted file mode 100644 index e9459229..00000000 --- a/StoneIsland/www/js/vendor/view/serializable.js +++ /dev/null @@ -1,129 +0,0 @@ -var SerializableView = View.extend({ - - events: { - "change select": "update_select", - "focus input": "focus_input", - }, - - preload: function(data){ - if (! data && sdk.env == "production") { return } - data = data || this.test_data - if (! data) { return } - - Object.keys(data).forEach(function(key){ - var value = data[key] - var $el = this.$("[name=" + key + "]") - - if ($el.attr("type") == "checkbox") { - $el.prop("checked", value) - } - 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 - } - } - 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") - }, - - update_select: function(e){ - var $target = $(e.currentTarget), value = $target.val() - var label = $($("select")[0]).find("option").filter(function(){ return this.value === value }).html() - - $target.parent().addClass("picked") - $target.parent().find("span").html(label) - }, - - validate: function(errors){ - var data = this.serialize() - var errors = [] - var presence_msgs = this.validate_presence - 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(errors) - this.address && this.address.validate(errors) - return { errors: errors, data: data } - }, - - show_errors: function(errors){ - var msgs = [] - errors.forEach(function(e, i){ - if (i > 0) { return } - this.$("[name=" + e[0] + "]").addClass('error_hilite') - msgs.push(e[1]) - }.bind(this)) - this.$msg.html(msgs.join("
")) - this.$msg.addClass('alert-notice') - }, - - hide_errors: function(){ - this.$msg.removeClass('alert-notice') - this.$msg.html("") - }, - - save: function(e){ - e && e.preventDefault() - - var valid = this.validate() - if (valid.errors.length) { - this.show_errors(valid.errors) - return - } - else { - this.hide_errors() - } - - app.curtain.show("loading") - this.action({ - data: valid.data, - success: function(data){ - app.curtain.hide("loading") - this.success(data) - }.bind(this), - error: function(data){ - app.curtain.hide("loading") - this.error(data) - }.bind(this), - }) - }, - - success: function(data){ - console.log("SUCCESS", data) - }, - - error: function(data){ - console.log("FAIL", data) - }, - -}) - -var FormView = View.extend(SerializableView.prototype).extend(ScrollableView.prototype) diff --git a/StoneIsland/www/js/vendor/view/view.js b/StoneIsland/www/js/vendor/view/view.js deleted file mode 100644 index 41638ab7..00000000 --- a/StoneIsland/www/js/vendor/view/view.js +++ /dev/null @@ -1,147 +0,0 @@ -var View = (function($, _){ - - var View = function(options) { - this._id = _.uniqueId('view') - this.type = "view" - options || (options = {}); - _.extend(this, _.pick(options, viewOptions)) - this._ensureElement() - this.initialize.apply(this, arguments) - this.delegateEvents() - } - - var delegateEventSplitter = /^(\S+)\s*(.*)$/; - - var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events']; - - _.extend(View.prototype, { - - // The default `tagName` of a View's element is `"div"`. - tagName: 'div', - - $: function(selector) { - return this.$el.find(selector); - }, - - initialize: function(){}, - - setElement: function(element, delegate) { - if (this.$el) this.undelegateEvents(); - this.$el = element instanceof $ ? element : $(element); - this.el = this.$el[0]; - if (delegate !== false) this.delegateEvents(); - return this; - }, - - // Set callbacks, where `this.events` is a hash of - // - // *{"event selector": "callback"}* - // - // { - // 'mousedown .title': 'edit', - // 'click .button': 'save', - // 'click .open': function(e) { ... } - // } - // - // pairs. Callbacks will be bound to the view, with `this` set properly. - // Uses event delegation for efficiency. - // Omitting the selector binds the event to `this.el`. - // This only works for delegate-able events: not `focus`, `blur`, and - // not `change`, `submit`, and `reset` in Internet Explorer. - delegateEvents: function(events) { - if (!(events || (events = _.result(this, 'events')))) return this; - this.undelegateEvents(); - for (var key in events) { - var method = events[key]; - if (!_.isFunction(method)) method = this[events[key]]; - if (!method) continue; - - var match = key.match(delegateEventSplitter); - var eventName = match[1], selector = match[2]; - method = _.bind(method, this); - eventName += '.delegateEvents' + this._id; - if (is_mobile) { - if (eventName === 'mouseenter' || eventName === 'mouseleave') { - continue - } -// if (eventName === 'click') { -// eventName = 'tap' -// } - } - if (selector === '') { - this.$el.on(eventName, method); - } else { - this.$el.on(eventName, selector, method); - } - } - return this; - }, - - // Clears all callbacks previously bound to the view with `delegateEvents`. - undelegateEvents: function() { - this.$el.off('.delegateEvents' + this._id); - return this; - }, - - // Ensure that the View has a DOM element to render into. - // If `this.el` is a string, pass it through `$()`, take the first - // matching element, and re-assign it to `el`. Otherwise, create - // an element from the `id`, `className` and `tagName` properties. - _ensureElement: function() { - this.setElement(_.result(this, 'el'), false); - }, - - preventDefault: function(e){ - e && e.preventDefault() - }, - - stopPropagation: function(e){ - e && e.stopPropagation() - }, - - }); - - - var extend = function(protoProps, staticProps) { - var staticProps = staticProps || {} - var parent = this; - var child; - var childEvents = {}; - - // The constructor function for the new subclass is either defined by you - // (the "constructor" property in your `extend` definition), or defaulted - // by us to simply call the parent's constructor. - if (protoProps && _.has(protoProps, 'constructor')) { - child = protoProps.constructor; - } else { - child = function(){ return parent.apply(this, arguments); }; - } - - // Extend events so we can subclass views - _.extend(childEvents, parent.prototype.events, protoProps.events) - - // Add static properties to the constructor function, if supplied. - _.extend(child, parent, staticProps); - - // Set the prototype chain to inherit from `parent`, without calling - // `parent`'s constructor function. - var Surrogate = function(){ this.constructor = child; }; - Surrogate.prototype = parent.prototype; - child.prototype = new Surrogate; - - // Add prototype properties (instance properties) to the subclass, - // if supplied. - if (protoProps) _.extend(child.prototype, protoProps); - - // Set a convenience property in case the parent's prototype is needed - // later. - child.prototype.__super__ = parent.prototype; - child.prototype.events = childEvents - - return child; - }; - - View.extend = extend; - - return View; -})(jQuery, _) -- cgit v1.2.3-70-g09d2