diff options
Diffstat (limited to 'public/assets/javascripts/ui/lib')
| -rw-r--r-- | public/assets/javascripts/ui/lib/AlertModal.js | 25 | ||||
| -rw-r--r-- | public/assets/javascripts/ui/lib/ConfirmModal.js | 25 | ||||
| -rw-r--r-- | public/assets/javascripts/ui/lib/ModalFormView.js | 96 | ||||
| -rw-r--r-- | public/assets/javascripts/ui/lib/ModalView.js | 28 | ||||
| -rw-r--r-- | public/assets/javascripts/ui/lib/Router.js | 28 | ||||
| -rw-r--r-- | public/assets/javascripts/ui/lib/view.js | 130 |
6 files changed, 332 insertions, 0 deletions
diff --git a/public/assets/javascripts/ui/lib/AlertModal.js b/public/assets/javascripts/ui/lib/AlertModal.js new file mode 100644 index 0000000..c5693ad --- /dev/null +++ b/public/assets/javascripts/ui/lib/AlertModal.js @@ -0,0 +1,25 @@ + + +var AlertModal = ModalFormView.extend({ + el: ".mediaDrawer.alert", + + events: { + "click .ok": "advance", + "click .close": "advance", + }, + + alert: function(message, callback){ + this.$(".message").html(message) + this.callback = callback + this.show() + }, + + advance: function(e){ + e && e.preventDefault() + this.hide() + this.callback && this.callback() + this.callback = null + } + +}) + diff --git a/public/assets/javascripts/ui/lib/ConfirmModal.js b/public/assets/javascripts/ui/lib/ConfirmModal.js new file mode 100644 index 0000000..868ce8e --- /dev/null +++ b/public/assets/javascripts/ui/lib/ConfirmModal.js @@ -0,0 +1,25 @@ + + +var ConfirmModal = ModalFormView.extend({ + el: ".mediaDrawer.confirm", + + events: { + "click .yes": "advance", + "click .no": "hide", + }, + + confirm: function(question, callback){ + this.$(".question").html(question) + this.callback = callback + this.show() + }, + + advance: function(e){ + e && e.preventDefault() + this.hide() + this.callback && this.callback() + this.callback = null + } + +}) + diff --git a/public/assets/javascripts/ui/lib/ModalFormView.js b/public/assets/javascripts/ui/lib/ModalFormView.js new file mode 100644 index 0000000..d084031 --- /dev/null +++ b/public/assets/javascripts/ui/lib/ModalFormView.js @@ -0,0 +1,96 @@ + +var ModalFormView = ModalView.extend({ + + method: "post", + + events: { + "submit form": "submit" + }, + + initialize: function(){ + this.$form = this.$("form") + this.$errors = this.$(".errors") + this.$errorList = this.$(".errorList") + }, + + reset: function(){ + this.$("input,textarea").not("[type='submit']").not("[type='hidden']").val("") + }, + + load: function(){ + this.reset() + this.show() + }, + + showErrors: function(errors){ + if (errors && errors.length) { + this.$errorList.empty(); + for (var i in errors) { + this.$errorList.append('<div>' + errors[i] + '</div>'); + } + this.$errors.css("opacity", 1.0); + setTimeout($.proxy(function(){ + this.$errors.show().css("opacity", 1.0); + }, this), 200) + } + }, + + serialize: function(){ + var fd = new FormData() + + this.$("input[name], select[name], textarea[name]").each( function(){ + if (this.type == "file") { + if (this.files.length > 0) { + fd.append(this.name, this.files[0]); + } + } + else if (this.type == "password") { + if (this.value.length > 0) { + fd.append(this.name, SHA1.hex('lol$' + this.value + '$vvalls')) + } + } + else { + fd.append(this.name, this.value); + } + }); + + return fd + }, + + submit: function(e){ + e.preventDefault() + + this.$errors.hide().css("opacity", 0.0); + + if (this.validate) { + var errors = this.validate() + if (errors && errors.length) { + this.showErrors(errors) + return + } + } + + var request = $.ajax({ + url: this.action, + type: this.method, + data: this.serialize(), + dataType: "json", + processData: false, + contentType: false, + }); + request.done($.proxy(function (response) { + if (response.error) { + var errors = [] + for (var key in response.error.errors) { + errors.push(response.error.errors[key].message); + } + this.showErrors(errors) + return + } + else { + this.success && this.success(response) + } + }, this)); + } + +}) diff --git a/public/assets/javascripts/ui/lib/ModalView.js b/public/assets/javascripts/ui/lib/ModalView.js new file mode 100644 index 0000000..b90b3c4 --- /dev/null +++ b/public/assets/javascripts/ui/lib/ModalView.js @@ -0,0 +1,28 @@ + +var ModalView = View.extend({ + events: { + "click .close": 'close', + }, + + show: function(){ + $(".mediaDrawer").removeClass("active"); + this.$el.addClass("active"); + $("body").addClass("noOverflow"); + }, + + hide: function(){ + // $(".mediaDrawer, .room1").removeClass("active editing"); + this.$el.removeClass("active"); + $("body").removeClass("noOverflow"); + }, + + close: function(){ + if (window.isModalView) { + window.location.pathname = "/" + } + else { + history.pushState(null, document.title, app.router.originalPath) + this.hide() + } + } +}) diff --git a/public/assets/javascripts/ui/lib/Router.js b/public/assets/javascripts/ui/lib/Router.js new file mode 100644 index 0000000..d06c07a --- /dev/null +++ b/public/assets/javascripts/ui/lib/Router.js @@ -0,0 +1,28 @@ +var Router = View.extend({ + + route: function(){ + + this.originalPath = window.location.pathname + + var path = window.location.pathname.split("/") + // console.log(path) + for (var route in this.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]](null, path[2]) + break; + } + else if (routePath[2] == path[2]) { + this[this.routes[route]](null) + break; + } + else if (! routePath[2] && (! path[2].length || ! path[2])) { + this[this.routes[route]](null) + break; + } + } + } + } + +}) diff --git a/public/assets/javascripts/ui/lib/view.js b/public/assets/javascripts/ui/lib/view.js new file mode 100644 index 0000000..823a75b --- /dev/null +++ b/public/assets/javascripts/ui/lib/view.js @@ -0,0 +1,130 @@ +var View = (function($, _){ + + var View = function(options) { + this.cid = _.uniqueId('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.cid; + 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.cid); + 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); + } + + }); + + + 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, _) |
