From 7a5841a1e19473857e232d4e4b236421490b99f8 Mon Sep 17 00:00:00 2001 From: Dennis Collinson Date: Fri, 9 Mar 2012 17:38:04 -0800 Subject: [PATCH] Select multiple aspects --- .../javascripts/app/models/status_message.js | 6 +- .../app/templates/aspects-dropdown.handlebars | 6 +- .../app/views/aspects_dropdown_view.js | 44 ++++++++++--- public/stylesheets/sass/new-templates.scss | 14 +++++ .../app/views/aspects_dropdown_view_spec.js | 61 ++++++++++++++++--- 5 files changed, 106 insertions(+), 25 deletions(-) diff --git a/public/javascripts/app/models/status_message.js b/public/javascripts/app/models/status_message.js index 6359af399..8152db67f 100644 --- a/public/javascripts/app/models/status_message.js +++ b/public/javascripts/app/models/status_message.js @@ -6,16 +6,12 @@ app.models.StatusMessage = app.models.Post.extend({ mungeAndSave : function(){ var mungedAttrs = { status_message : _.clone(this.attributes), - aspect_ids : mungeAspects(this.get("aspect_ids")), + 'aspect_ids[]' : this.get("aspect_ids"), services : mungeServices(this.get("services")) } this.save(mungedAttrs) - function mungeAspects (value){ - return [value] - } - function mungeServices (values) { if(!values) { return; } return values.length > 1 ? values : [values] diff --git a/public/javascripts/app/templates/aspects-dropdown.handlebars b/public/javascripts/app/templates/aspects-dropdown.handlebars index de4452e15..aca5b30d7 100644 --- a/public/javascripts/app/templates/aspects-dropdown.handlebars +++ b/public/javascripts/app/templates/aspects-dropdown.handlebars @@ -3,12 +3,12 @@ diff --git a/public/javascripts/app/views/aspects_dropdown_view.js b/public/javascripts/app/views/aspects_dropdown_view.js index b5da17fd2..a6085263f 100644 --- a/public/javascripts/app/views/aspects_dropdown_view.js +++ b/public/javascripts/app/views/aspects_dropdown_view.js @@ -9,28 +9,47 @@ app.views.AspectsDropdown = app.views.Base.extend({ }, setVisibility : function(evt){ - var link = $(evt.target) + var self = this + , link = $(evt.target).closest("a") , visibilityCallbacks = { 'public' : setPublic, 'all-aspects' : setPrivate, 'custom' : setCustom } - visibilityCallbacks[link.data("visibility")].call(this) + visibilityCallbacks[link.data("visibility")]() + + this.setAspectIds() function setPublic (){ - this.setAspectIds("public") - this.setDropdownText(link.text()) + deselectAll() + selectAspect() + self.setDropdownText(link.text()) } function setPrivate (){ - this.setAspectIds("all_aspects") - this.setDropdownText(link.text()) + deselectAll() + selectAspect() + self.setDropdownText(link.text()) } function setCustom (){ - this.setAspectIds(link.data("aspect-id")) - this.setDropdownText(link.text()) + deselectOverrides() + link.parents("li").toggleClass("selected") + self.setDropdownText(link.text()) + evt.stopImmediatePropagation(); + } + + function selectAspect() { + link.parents("li").addClass("selected") + } + + function deselectOverrides() { + self.$("a.public, a.all-aspects").parent().removeClass("selected") + } + + function deselectAll() { + self.$("li.selected").removeClass("selected") } }, @@ -38,7 +57,12 @@ app.views.AspectsDropdown = app.views.Base.extend({ $.trim(this.$(".dropdown-toggle .text").text(text)) }, - setAspectIds : function(val){ - this.$("input.aspect_ids").val(val) + setAspectIds : function(){ + var selectedAspects = this.$("li.selected a") + var aspectIds = _.map(selectedAspects, function(aspect){ + return $(aspect).data("aspect-id")} + ) + + this.$("input.aspect_ids").val(aspectIds) } }) diff --git a/public/stylesheets/sass/new-templates.scss b/public/stylesheets/sass/new-templates.scss index 094627e99..6edb196b2 100644 --- a/public/stylesheets/sass/new-templates.scss +++ b/public/stylesheets/sass/new-templates.scss @@ -764,3 +764,17 @@ text-rendering: optimizelegibility; right: 8px; top: 8px; } + +.aspects_dropdown { + i { + display: none; + } + + .selected i { + display: inline-block; + } + + a { + display : inline-block; + } +} diff --git a/spec/javascripts/app/views/aspects_dropdown_view_spec.js b/spec/javascripts/app/views/aspects_dropdown_view_spec.js index eb34414f7..b5a47604d 100644 --- a/spec/javascripts/app/views/aspects_dropdown_view_spec.js +++ b/spec/javascripts/app/views/aspects_dropdown_view_spec.js @@ -23,7 +23,8 @@ describe("app.views.AspectsDropdown", function(){ describe("selecting Public", function(){ beforeEach(function(){ - this.view.$("a[data-visibility='public']").click() + this.link = this.view.$("a[data-visibility='public']") + this.link.click() }) it("calls set aspect_ids to 'public'", function(){ @@ -33,11 +34,16 @@ describe("app.views.AspectsDropdown", function(){ it("sets the dropdown title to 'public'", function(){ expect(this.view.$(".dropdown-toggle .text").text()).toBe("Public") }) + + it("adds the selected class to the link", function(){ + expect(this.link.parent().hasClass("selected")).toBeTruthy(); + }) }) describe("selecting All Aspects", function(){ beforeEach(function(){ - this.view.$("a[data-visibility='all-aspects']").click() + this.link = this.view.$("a[data-visibility='all-aspects']") + this.link.click() }) it("calls set aspect_ids to 'all'", function(){ @@ -47,21 +53,62 @@ describe("app.views.AspectsDropdown", function(){ it("sets the dropdown title to 'public'", function(){ expect($.trim(this.view.$(".dropdown-toggle .text").text())).toBe("All Aspects") }) + + it("adds the selected class to the link", function(){ + expect(this.link.parent().hasClass("selected")).toBeTruthy(); + }) }) describe("selecting An Aspect", function(){ beforeEach(function(){ - this.view.$("a:contains('lovers')").click() - }) - - it("calls set aspect_ids to to the aspect id", function(){ - expect(this.view.$("input.aspect_ids").val()).toBe("7") + this.link = this.view.$("a:contains('lovers')") + this.link.click() }) it("sets the dropdown title to the aspect title", function(){ expect($.trim(this.view.$(".dropdown-toggle .text").text())).toBe("lovers") }) + + it("adds the selected class to the link", function(){ + expect(this.link.parent().hasClass("selected")).toBeTruthy(); + }) + + it("sets aspect_ids to to the aspect id", function(){ + expect(this.view.$("input.aspect_ids").val()).toBe("7") + }) + + describe("selecting another aspect", function(){ + beforeEach(function(){ + this.view.$("a:contains('sauce')").click() + }) + + it("sets aspect_ids to the selected aspects", function(){ + expect(this.view.$("input.aspect_ids").val()).toBe("3,7") + }) + + describe("deselecting another aspect", function(){ + it("removes the clicked aspect", function(){ + expect(this.view.$("input.aspect_ids").val()).toBe("3,7") + this.view.$("a:contains('lovers')").click() + expect(this.view.$("input.aspect_ids").val()).toBe("3") + }) + }) + + describe("selecting all_aspects", function(){ + it("sets aspect_ids to all_aspects", function(){ + this.view.$("a[data-visibility='all-aspects']").click() + expect(this.view.$("input.aspect_ids").val()).toBe("all_aspects") + }) + }) + + describe("selecting public", function(){ + it("sets aspect_ids to public", function(){ + this.view.$("a[data-visibility='public']").click() + expect(this.view.$("input.aspect_ids").val()).toBe("public") + }) + }) + }) }) }) }) \ No newline at end of file