diff options
| -rw-r--r-- | StoneIsland/www/index.html | 67 | ||||
| -rw-r--r-- | StoneIsland/www/js/lib/account/AccountView.js | 30 | ||||
| -rw-r--r-- | StoneIsland/www/js/lib/account/ProfileView.js | 4 | ||||
| -rw-r--r-- | StoneIsland/www/js/lib/account/ShippingView.js | 49 | ||||
| -rw-r--r-- | StoneIsland/www/js/lib/nav/AddressView.js | 7 | ||||
| -rw-r--r-- | StoneIsland/www/js/lib/nav/CreditCardView.js | 11 | ||||
| -rw-r--r-- | StoneIsland/www/js/lib/view/Serializable.js | 25 | ||||
| -rw-r--r-- | StoneIsland/www/js/vendor/jquery.creditCardValidator.js | 208 |
8 files changed, 335 insertions, 66 deletions
diff --git a/StoneIsland/www/index.html b/StoneIsland/www/index.html index 8d25ed9b..fad265e2 100644 --- a/StoneIsland/www/index.html +++ b/StoneIsland/www/index.html @@ -676,6 +676,18 @@ <div class="container-row"> <div class="cc"></div> <div class="address"></div> + <div class="checkbox-container"> + <div class="checkbox-row"> + <div class="checkbox-toggle"> + <input id="save_as_default_cart_shipping" type="checkbox" name="IsDefault" value="true" required> + <label for="save_as_default_cart_shipping"></label> + </div> + <label class="checkbox-caption" for="save_as_default_cart_shipping"> + SAVE AS DEFAULT + </label> + </div> + </div> + </div> <div class="container-fill"> <div class="container-message"> @@ -722,13 +734,44 @@ <script type="text/html" id="creditcard_template"> <input type="text" name="Number" placeholder="CREDIT CARD NUMBER" required> <div class="half-input"> - <!-- NOTE text shifted to the left because of dropdown arrow --> - <input type="text" onfocus="(this.type='number')" name="ExpirationMonth" placeholder="EXPIRATION MONTH" required> - <input type="text" onfocus="(this.type='number')" name="ExpirationYear" placeholder="EXPIRATION YEAR" required> + + <div class="select-wrapper"> + <span>EXPIRATION MONTH</span> + <select name="ExpirationMonth"> + <option value="NONE">EXPIRATION MONTH</option> + <option value="01">01</option> + <option value="02">02</option> + <option value="03">03</option> + <option value="04">04</option> + <option value="05">05</option> + <option value="06">06</option> + <option value="07">07</option> + <option value="08">08</option> + <option value="09">09</option> + <option value="10">10</option> + <option value="11">11</option> + <option value="12">12</option> + </select> + </div> + <div class="select-wrapper"> + <span>EXPIRATION YEAR</span> + <select name="ExpirationYear"> + <option value="NONE">EXPIRATION YEAR</option> + <option value="2016">2016</option> + <option value="2017">2017</option> + <option value="2018">2018</option> + <option value="2019">2019</option> + <option value="2020">2020</option> + <option value="2021">2021</option> + <option value="2022">2022</option> + <option value="2023">2023</option> + <option value="2024">2024</option> + <option value="2025">2025</option> + </select> + </div> </div> <!-- NOTE text shifted to the left because of dropdown arrow --> - <input type="text" onfocus="(this.type='number')" name="CVV" placeholder="SECURITY CODE" required> - <span class="address"></span> + <input type="number" name="CVV" placeholder="SECURITY CODE" required> </script> <script type="text/html" id="address_template"> @@ -808,19 +851,6 @@ </div> </div> <input type="number" name="Phone" placeholder="Phone Number"> - - <div class="checkbox-container"> - <div class="checkbox-row"> - <div class="checkbox-toggle"> - <input id="save_as_default_cart_shipping" type="checkbox" name="IsDefault" value="true" required> - <label for="save_as_default_cart_shipping"></label> - </div> - <label class="checkbox-caption" for="save_as_default_cart_shipping"> - SAVE AS DEFAULT - </label> - </div> - </div> - </script> </body> @@ -836,6 +866,7 @@ <script src="js/vendor/promise.js"></script> <script src="js/vendor/flickity.pkgd.js"></script> <script src="js/vendor/util.js"></script> +<script src="js/vendor/jquery.creditCardValidator.js"></script> <script src="js/sdk/_sdk.js"></script> <script src="js/sdk/account.js"></script> diff --git a/StoneIsland/www/js/lib/account/AccountView.js b/StoneIsland/www/js/lib/account/AccountView.js index e1d7ca71..ce976094 100644 --- a/StoneIsland/www/js/lib/account/AccountView.js +++ b/StoneIsland/www/js/lib/account/AccountView.js @@ -16,29 +16,35 @@ var AccountView = View.extend({ } }, - populateAddresses: function(data){ - console.log("populate addresses:", data) + listAddresses: function(cb){ + sdk.address.list({ + success: function(data){ + this.populateAddresses(data, cb) + }.bind(this) + }) + }, + + populateAddresses: function(data, cb){ + console.log("populate addresses:", data.AddressBook.addressBookItem) if (! data.AddressBook) { console.log("no addresses") return } - // console.log(data.AddressBook) data.AddressBook.addressBookItem.forEach(function(item){ - if (item.isDefault) { - // populate app.shipping.address - app.shipping.address.populate(item) + if (item.IsDefault) { + console.log("SHIPPING ADDRESS", item) + app.shipping.populate(item) } - else if (item.isBillingDefault) { - // populate app.billing.address - app.payment.address.populate(item) + if (item.IsBillingDefault) { + console.log("BILLING ADDRESS") + app.payment.populate(item) } }) + cb && cb() }, logged_in: function(cb){ - sdk.address.list({ - success: this.populateAddresses.bind(this) - }) + this.listAddresses() $("#nav .login").hide() $("#nav .account, #nav .logout").show() if (! auth.deferred_product && app.last_view) { diff --git a/StoneIsland/www/js/lib/account/ProfileView.js b/StoneIsland/www/js/lib/account/ProfileView.js index d05ef5cd..999e8d65 100644 --- a/StoneIsland/www/js/lib/account/ProfileView.js +++ b/StoneIsland/www/js/lib/account/ProfileView.js @@ -71,5 +71,9 @@ var ProfileView = FormView.extend({ error: function(data){ }, + + cancel: function(){ + app.router.go("intro") + }, })
\ No newline at end of file diff --git a/StoneIsland/www/js/lib/account/ShippingView.js b/StoneIsland/www/js/lib/account/ShippingView.js index e2426d2e..b8b260ab 100644 --- a/StoneIsland/www/js/lib/account/ShippingView.js +++ b/StoneIsland/www/js/lib/account/ShippingView.js @@ -2,8 +2,7 @@ var ShippingView = FormView.extend({ el: "#shipping", - createAction: sdk.address.add, - updateAction: sdk.address.update, + action: sdk.address.add, events: { }, @@ -11,14 +10,14 @@ var ShippingView = FormView.extend({ test_data: { "Name":"name", "Surname":"surname", - "Address":"address", + "Address":"address1\naddress2", "IsDefault":false, "IsBillingDefault":false, "IsOwner":false, "ZipCode":"88040", "City":"City", - "Province":"Province", - "Phone":"Phone", + "Province":"NY", + "Phone":"1234567890", "Mobile":"Mobile", "Mail":"Mail", "UserId": sdk.auth.user_id, @@ -27,37 +26,51 @@ var ShippingView = FormView.extend({ initialize: function(){ this.$form = this.$("form") this.$msg = this.$(".msg") - this.$isDefault = this.$("[name=IsDefault]") this.address = new AddressView ({ parent: this }) this.scroller = new IScroll('#shipping', app.iscroll_options) - this.preload() }, show: function(){ if (! auth.logged_in()) { return app.router.go("intro") } +// this.preload( this.data || this.test_data ) app.footer.show("SAVE", "CANCEL") document.body.className = "shipping" }, + populate: function(data){ + this.data = data || this.data + this.address.populate(data) + }, + finalize: function(data){ if (this.address.data && this.address.data.Id) { sdk.address.destroy({ id: this.address.data.Id, - success: function(){ console.log("destroyed") }, - error: function(){ console.log("destroyed") }, + success: function(){}, + error: function(){}, }) - this.action = this.updateAction - } - else { - this.action = this.createAction } - data.IsDefault = data.IsDefault ? "true" : "false" - data.Address = data.Address1 + "\n" + data.Address2 - delete data.Address1 - delete data.Address2 + + data.IsDefault = "true" // this.$isDefault.prop("checked") ? "true" : "false" + data.UserId = sdk.auth.user_id + console.log(data) - return return data }, + + success: function(data){ + app.curtain.show("loading") + app.account.listAddresses(function(){ + app.curtain.hide("loading") + }) + }, + + error: function(data){ + console.log(data) + }, + + cancel: function(){ + app.router.go("intro") + }, })
\ No newline at end of file diff --git a/StoneIsland/www/js/lib/nav/AddressView.js b/StoneIsland/www/js/lib/nav/AddressView.js index fb30062e..9d4a97b9 100644 --- a/StoneIsland/www/js/lib/nav/AddressView.js +++ b/StoneIsland/www/js/lib/nav/AddressView.js @@ -18,9 +18,7 @@ var AddressView = SerializableView.extend({ data.Address1 = address[0] data.Address2 = address[1] this.$(".address input").val("") - Object.keys(data).forEach(function(key){ - this.$(".address [name=" + key + "]").val(data[key]) - }.bind(this)) + this.load_data(data) }, validate_presence: { @@ -33,12 +31,11 @@ var AddressView = SerializableView.extend({ validate_fields: function(data, errors){ if (data.Phone.replace(/[^0-9]/g, "").length < 10) { errors.push([ "Phone", "Phone numbers must be at least 10 digits." ]) } - if (data.Province == "NONE") { errors.push([ "Province", "Please choose your state." ]) } + if (! data.Province || data.Province == "NONE") { errors.push([ "Province", "Please choose your state." ]) } data.Address = data.Address1 + "\n" + data.Address2 data.UserId = auth.user_id delete data.Address1 delete data.Address2 - console.log(errors) }, }) diff --git a/StoneIsland/www/js/lib/nav/CreditCardView.js b/StoneIsland/www/js/lib/nav/CreditCardView.js index 33ecab79..eaab7086 100644 --- a/StoneIsland/www/js/lib/nav/CreditCardView.js +++ b/StoneIsland/www/js/lib/nav/CreditCardView.js @@ -8,20 +8,25 @@ var CreditCardView = View.extend({ initialize: function(opt){ this.parent = opt.parent + this.setElement( this.parent.$(".cc") ) this.parent.$(".cc").html(this.template) }, populate: function(data){ this.parent.$(".cc input").val("") - Object.keys(data).forEach(function(key){ - this.parent$(".cc [name=" + key + "]").val(data[key]) - }.bind(this)) + this.$(".cc input").val("") + this.load_data(data) }, validate_presence: { + 'Number': 'Please enter your credit card number.', + 'CVV': 'Please enter your security code.', }, validate_fields: function(data, errors){ + if (! data.ExpirationMonth || data.ExpirationMonth == "NONE") { errors.push([ "ExpirationMonth", "Please enter the expiration month." ]) } + if (! data.ExpirationYear || data.ExpirationYear == "NONE") { errors.push([ "ExpirationYear", "Please select the expiration month." ]) } + data.UserId = auth.user_id }, }) diff --git a/StoneIsland/www/js/lib/view/Serializable.js b/StoneIsland/www/js/lib/view/Serializable.js index 72978985..b1e095d3 100644 --- a/StoneIsland/www/js/lib/view/Serializable.js +++ b/StoneIsland/www/js/lib/view/Serializable.js @@ -10,7 +10,10 @@ var SerializableView = View.extend({ 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 + "]") @@ -56,22 +59,21 @@ var SerializableView = View.extend({ update_select: function(e){ var $target = $(e.currentTarget), value = $target.val() - var label = $($("select")[0]).find("option").filter(function(){ return this.value === value }).html() - + var label = $target.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 = [] + validate: function(data, errors){ + var data = data || this.serialize() + var errors = 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) + this.cc && this.cc.validate(data, errors) + this.address && this.address.validate(data, errors) return { errors: errors, data: data } }, @@ -108,13 +110,16 @@ var SerializableView = View.extend({ } var finalized_data = this.finalize(valid.data) - if (! finalized_data) { + this.submit( finalized_data ) + }, + + submit: function(data){ + if (! data) { return } - app.curtain.show("loading") this.action({ - data: finalized_data, + data: data, success: function(data){ app.curtain.hide("loading") this.success(data) diff --git a/StoneIsland/www/js/vendor/jquery.creditCardValidator.js b/StoneIsland/www/js/vendor/jquery.creditCardValidator.js new file mode 100644 index 00000000..a9117abe --- /dev/null +++ b/StoneIsland/www/js/vendor/jquery.creditCardValidator.js @@ -0,0 +1,208 @@ +// Generated by CoffeeScript 1.8.0 + +/* +jQuery Credit Card Validator 1.0 + +Copyright 2012-2015 Pawel Decowski + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. + */ + +(function() { + var $, + __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + + $ = jQuery; + + $.fn.validateCreditCard = function(callback, options) { + var bind, card, card_type, card_types, get_card_type, is_valid_length, is_valid_luhn, normalize, validate, validate_number, _i, _len, _ref; + card_types = [ + { + name: 'amex', + pattern: /^3[47]/, + valid_length: [15] + }, { + name: 'diners_club_carte_blanche', + pattern: /^30[0-5]/, + valid_length: [14] + }, { + name: 'diners_club_international', + pattern: /^36/, + valid_length: [14] + }, { + name: 'jcb', + pattern: /^35(2[89]|[3-8][0-9])/, + valid_length: [16] + }, { + name: 'laser', + pattern: /^(6304|670[69]|6771)/, + valid_length: [16, 17, 18, 19] + }, { + name: 'visa_electron', + pattern: /^(4026|417500|4508|4844|491(3|7))/, + valid_length: [16] + }, { + name: 'visa', + pattern: /^4/, + valid_length: [16] + }, { + name: 'mastercard', + pattern: /^5[1-5]/, + valid_length: [16] + }, { + name: 'maestro', + pattern: /^(5018|5020|5038|6304|6759|676[1-3])/, + valid_length: [12, 13, 14, 15, 16, 17, 18, 19] + }, { + name: 'discover', + pattern: /^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)/, + valid_length: [16] + } + ]; + bind = false; + if (callback) { + if (typeof callback === 'object') { + options = callback; + bind = false; + callback = null; + } else if (typeof callback === 'function') { + bind = true; + } + } + if (options == null) { + options = {}; + } + if (options.accept == null) { + options.accept = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = card_types.length; _i < _len; _i++) { + card = card_types[_i]; + _results.push(card.name); + } + return _results; + })(); + } + _ref = options.accept; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + card_type = _ref[_i]; + if (__indexOf.call((function() { + var _j, _len1, _results; + _results = []; + for (_j = 0, _len1 = card_types.length; _j < _len1; _j++) { + card = card_types[_j]; + _results.push(card.name); + } + return _results; + })(), card_type) < 0) { + throw "Credit card type '" + card_type + "' is not supported"; + } + } + get_card_type = function(number) { + var _j, _len1, _ref1; + _ref1 = (function() { + var _k, _len1, _ref1, _results; + _results = []; + for (_k = 0, _len1 = card_types.length; _k < _len1; _k++) { + card = card_types[_k]; + if (_ref1 = card.name, __indexOf.call(options.accept, _ref1) >= 0) { + _results.push(card); + } + } + return _results; + })(); + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + card_type = _ref1[_j]; + if (number.match(card_type.pattern)) { + return card_type; + } + } + return null; + }; + is_valid_luhn = function(number) { + var digit, n, sum, _j, _len1, _ref1; + sum = 0; + _ref1 = number.split('').reverse(); + for (n = _j = 0, _len1 = _ref1.length; _j < _len1; n = ++_j) { + digit = _ref1[n]; + digit = +digit; + if (n % 2) { + digit *= 2; + if (digit < 10) { + sum += digit; + } else { + sum += digit - 9; + } + } else { + sum += digit; + } + } + return sum % 10 === 0; + }; + is_valid_length = function(number, card_type) { + var _ref1; + return _ref1 = number.length, __indexOf.call(card_type.valid_length, _ref1) >= 0; + }; + validate_number = (function(_this) { + return function(number) { + var length_valid, luhn_valid; + card_type = get_card_type(number); + luhn_valid = false; + length_valid = false; + if (card_type != null) { + luhn_valid = is_valid_luhn(number); + length_valid = is_valid_length(number, card_type); + } + return { + card_type: card_type, + valid: luhn_valid && length_valid, + luhn_valid: luhn_valid, + length_valid: length_valid + }; + }; + })(this); + validate = (function(_this) { + return function() { + var number; + number = normalize($(_this).val()); + return validate_number(number); + }; + })(this); + normalize = function(number) { + return number.replace(/[ -]/g, ''); + }; + if (!bind) { + return validate(); + } + this.on('input.jccv', (function(_this) { + return function() { + $(_this).off('keyup.jccv'); + return callback.call(_this, validate()); + }; + })(this)); + this.on('keyup.jccv', (function(_this) { + return function() { + return callback.call(_this, validate()); + }; + })(this)); + callback.call(this, validate()); + return this; + }; + +}).call(this); |
