diff options
| author | Jules Laplace <jules@okfoc.us> | 2015-11-25 04:08:39 -0500 |
|---|---|---|
| committer | Jules Laplace <jules@okfoc.us> | 2015-11-25 04:08:39 -0500 |
| commit | f0c551933c5e725b980014b559d757bee99d0536 (patch) | |
| tree | ba8f090c42934f3ef601eb8d0e42b4398242fc68 /StoneIsland/www/js/lib | |
| parent | e024c35a2584f5d975b3b4f8fe942bb8e35b6e47 (diff) | |
fix auth bugs pt 1
Diffstat (limited to 'StoneIsland/www/js/lib')
| -rw-r--r-- | StoneIsland/www/js/lib/account/AccountView.js | 2 | ||||
| -rw-r--r-- | StoneIsland/www/js/lib/auth/LogoutView.js | 3 | ||||
| -rw-r--r-- | StoneIsland/www/js/lib/cart/CartSummary.js | 18 | ||||
| -rw-r--r-- | StoneIsland/www/js/lib/cart/CartView.js | 14 | ||||
| -rw-r--r-- | StoneIsland/www/js/lib/nav/HeaderView.js | 2 | ||||
| -rw-r--r-- | StoneIsland/www/js/lib/products/ProductView.js | 27 | ||||
| -rw-r--r-- | StoneIsland/www/js/lib/view/Router.js | 75 | ||||
| -rw-r--r-- | StoneIsland/www/js/lib/view/Scrollable.js | 20 | ||||
| -rw-r--r-- | StoneIsland/www/js/lib/view/Serializable.js | 129 | ||||
| -rw-r--r-- | StoneIsland/www/js/lib/view/View.js | 147 |
10 files changed, 408 insertions, 29 deletions
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("<br>")) + 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, _) |
