From 2d550724f0b93ef909a5d1f33789e798d4f198bc Mon Sep 17 00:00:00 2001 From: Matchu Date: Fri, 5 Nov 2010 20:09:03 -0400 Subject: [PATCH] bulk add pets --- app/controllers/pets_controller.rb | 35 +++++++--- app/helpers/application_helper.rb | 4 ++ app/helpers/outfits_helper.rb | 4 -- app/stylesheets/pets/_bulk.sass | 48 +++++++++++++ app/stylesheets/screen.sass | 1 + app/views/pets/bulk.html.haml | 33 +++++++++ config/assets.yml | 4 ++ public/javascripts/pets/bulk.js | 74 ++++++++++++++++++++ public/stylesheets/compiled/screen.css | 94 ++++++++++++++++++++++++-- 9 files changed, 279 insertions(+), 18 deletions(-) create mode 100644 app/stylesheets/pets/_bulk.sass create mode 100644 app/views/pets/bulk.html.haml create mode 100644 public/javascripts/pets/bulk.js diff --git a/app/controllers/pets_controller.rb b/app/controllers/pets_controller.rb index b610081a..165408a6 100644 --- a/app/controllers/pets_controller.rb +++ b/app/controllers/pets_controller.rb @@ -8,21 +8,40 @@ class PetsController < ApplicationController } def load + + # TODO: include point value with JSON once contributions implemented + raise Pet::PetNotFound unless params[:name] @pet = Pet.load(params[:name]) @pet.save - destination = params[:destination] - destination = 'root' unless DESTINATIONS[destination] - query_joiner = DESTINATIONS[destination] - path = send("#{destination}_path") + query_joiner + @pet.wardrobe_query - redirect_to path + respond_to do |format| + format.html do + destination = params[:destination] + destination = 'root' unless DESTINATIONS[destination] + query_joiner = DESTINATIONS[destination] + path = send("#{destination}_path") + query_joiner + @pet.wardrobe_query + redirect_to path + end + + format.json do + render :json => true + end + end end protected def pet_not_found - path = params[:origin] || root_path - path += "?name=#{params[:name]}" - redirect_to path, :alert => 'Could not find any pet by that name. Did you spell it correctly?' + respond_to do |format| + format.html do + path = params[:origin] || root_path + path += "?name=#{params[:name]}" + redirect_to path, :alert => 'Could not find any pet by that name. Did you spell it correctly?' + end + + format.json do + render :text => 'Pet not found', :status => :not_found + end + end end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 8257b317..34fc42ae 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -35,4 +35,8 @@ module ApplicationHelper def login_path_with_return_to login_path :return_to => request.request_uri end + + def origin_tag(value) + hidden_field_tag 'origin', value, :id => nil + end end diff --git a/app/helpers/outfits_helper.rb b/app/helpers/outfits_helper.rb index d13a630c..f3f530ee 100644 --- a/app/helpers/outfits_helper.rb +++ b/app/helpers/outfits_helper.rb @@ -3,10 +3,6 @@ module OutfitsHelper hidden_field_tag 'destination', value, :id => nil end - def origin_tag(value) - hidden_field_tag 'origin', value, :id => nil - end - def pet_attribute_select(name, collection, value=nil) select_tag name, options_from_collection_for_select(collection, :id, :human_name, value) diff --git a/app/stylesheets/pets/_bulk.sass b/app/stylesheets/pets/_bulk.sass new file mode 100644 index 00000000..608d8061 --- /dev/null +++ b/app/stylesheets/pets/_bulk.sass @@ -0,0 +1,48 @@ +body.pets-bulk + text-align: center + + #bulk-pets-form + textarea, div + +inline-block + textarea + +inline-block + @extend input[type=text] + display: inline + font: inherit + height: 1.5em + overflow: hidden + resize: none + ul + list-style: none + margin-bottom: 1em + li + +inline-block + background: #eee + margin: 0 auto + min-width: 25% + text-align: left + &.loaded + background: $notice-bg-color + &.failed + background: $error-bg-color + img + @extend .inline-image + float: left + height: 50px + width: 50px + span + display: block + .response + font: + size: 75% + style: italic + margin-left: 75px + + &.js + .noscript + display: none + .script-only + display: block + + .script-only + display: none diff --git a/app/stylesheets/screen.sass b/app/stylesheets/screen.sass index e0522e22..bc169f8e 100644 --- a/app/stylesheets/screen.sass +++ b/app/stylesheets/screen.sass @@ -8,4 +8,5 @@ @import items/index @import items/show @import outfits/new +@import pets/bulk @import static/terms diff --git a/app/views/pets/bulk.html.haml b/app/views/pets/bulk.html.haml new file mode 100644 index 00000000..88b69820 --- /dev/null +++ b/app/views/pets/bulk.html.haml @@ -0,0 +1,33 @@ +- unless user_signed_in? + %p.warning + = link_to 'You are not logged in!', login_path(:return_to => bulk_pets_path) + We award points for each new contribution to our database, and we don't want + you to miss out, since our users have made the Dress to Impress database + what it is today. Thanks for all your hard work! +%p.noscript + Note that submitting pets in bulk requires Javascript. +%p.script-only + We like to make it as easy as possible for you to contribute, so we thought + this might help! + %strong + Type a pet's name in the box below, and we'll + start loading it the moment you press enter! + If you're a power-user, + you can even submit a whole list at once — just put one pet per line, and + copy-paste it into the box. We do the rest! +%p + %strong + Thanks for all your hard work! += form_tag load_pet_path, :id => 'bulk-pets-form' do + = origin_tag bulk_pets_path + %span.noscript + %input{:name => "name", :type => "text"}/ + %input{:type => "submit", :value => "Load pet"}/ + %span.script-only + %ul + %textarea + %button#bulk-pets-form-add{:type => "button"} Add + %button#bulk-pets-form-clear{:type => "button"} Clear +- content_for :javascripts do + = include_javascript_libraries :jquery + = include_javascripts :bulk_pets_package diff --git a/config/assets.yml b/config/assets.yml index 1b812a46..34ac1e17 100644 --- a/config/assets.yml +++ b/config/assets.yml @@ -1,6 +1,10 @@ embed_assets: on javascripts: + bulk_pets_package: + - public/javascripts/pet_query.js + - public/javascripts/pets/bulk.js + edit_outfit_package: - public/javascripts/wardrobe.js - public/javascripts/outfits/edit.js diff --git a/public/javascripts/pets/bulk.js b/public/javascripts/pets/bulk.js new file mode 100644 index 00000000..13884f8b --- /dev/null +++ b/public/javascripts/pets/bulk.js @@ -0,0 +1,74 @@ +var form = $('#bulk-pets-form'), + queue_el = form.find('ul'), + names_el = form.find('textarea'), + add_el = $('#bulk-pets-form-add'), + clear_el = $('#bulk-pets-form-clear'), + bulk_load_queue; + +$(document.body).addClass('js'); + +bulk_load_queue = new (function BulkLoadQueue() { + var pets = [], + standard_pet_el = $('
  • '), + url = form.attr('action') + '.json'; + standard_pet_el.append('').append($('', {'class': 'name'})) + .append($('', {'class': 'response', text: 'Waiting...'})); + + function Pet(name) { + var el = standard_pet_el.clone() + .children('img').attr('src', petImage('cpn/' + name, 1)).end() + .children('span.name').text(name).end(); + el.appendTo(queue_el); + + this.load = function () { + var response_el = el.children('span.response').text('Loading...'); + $.ajax({ + complete: function (data) { + pets.shift(); + if(pets.length) { + pets[0].load(); + } + }, + data: {name: name}, + dataType: 'json', + error: function (xhr) { + el.addClass('failed'); + response_el.text(xhr.responseText); + }, + success: function (data) { + var response = data === true ? 'Thanks!' : data + ' points'; + el.addClass('loaded'); + response_el.text(response); + }, + type: 'post', + url: url + }); + } + } + + this.add = function (name) { + name = name.replace(/^\s+|\s+$/g, ''); + if(name.length) { + var pet = new Pet(name); + pets.push(pet); + if(pets.length == 1) pet.load(); + } + } +})(); + +names_el.keyup(function () { + var names = this.value.split('\n'), x = names.length - 1, i, name; + for(i = 0; i < x; i++) { + bulk_load_queue.add(names[i]); + } + this.value = (x >= 0) ? names[x] : ''; +}); + +add_el.click(function () { + bulk_load_queue.add(names_el.val()); + names_el.val(''); +}); + +clear_el.click(function () { + queue_el.children('li.loaded, li.failed').remove(); +}); diff --git a/public/stylesheets/compiled/screen.css b/public/stylesheets/compiled/screen.css index b57b199d..256b2c07 100644 --- a/public/stylesheets/compiled/screen.css +++ b/public/stylesheets/compiled/screen.css @@ -75,7 +75,7 @@ h3 { } /* line 59, ../../../app/stylesheets/_layout.sass */ -.inline-image { +.inline-image, body.pets-bulk #bulk-pets-form ul img { margin-right: 1em; vertical-align: middle; } @@ -95,7 +95,7 @@ input, button, select, label { } /* line 76, ../../../app/stylesheets/_layout.sass */ -input[type=text], input[type=password], input[type=search], select { +input[type=text], body.pets-bulk #bulk-pets-form textarea, input[type=password], input[type=search], select { -moz-border-radius: 3px; -webkit-border-radius: 3px; background: white; @@ -104,7 +104,7 @@ input[type=text], input[type=password], input[type=search], select { padding: 0.25em; } /* line 82, ../../../app/stylesheets/_layout.sass */ -input[type=text]:focus, input[type=text]:active, input[type=password]:focus, input[type=password]:active, input[type=search]:focus, input[type=search]:active, select:focus, select:active { +input[type=text]:focus, body.pets-bulk #bulk-pets-form textarea:focus, input[type=text]:active, body.pets-bulk #bulk-pets-form textarea:active, input[type=password]:focus, input[type=password]:active, input[type=search]:focus, input[type=search]:active, select:focus, select:active { color: inherit; } @@ -372,7 +372,7 @@ body.items { text-align: center; } /* line 4, ../../../app/stylesheets/_items.sass */ -body.items input[type=text] { +body.items input[type=text], body.items body.pets-bulk #bulk-pets-form textarea, body.pets-bulk #bulk-pets-form body.items textarea { font-size: 125%; width: 15em; } @@ -715,7 +715,7 @@ body.outfits-new #how-can-i-help input, body.outfits-new #how-can-i-help button, font-size: 115%; } /* line 82, ../../../app/stylesheets/outfits/_new.sass */ -body.outfits-new #how-can-i-help input[type=text], body.outfits-new #i-found-something input[type=text] { +body.outfits-new #how-can-i-help input[type=text], body.outfits-new #how-can-i-help body.pets-bulk #bulk-pets-form textarea, body.pets-bulk #bulk-pets-form body.outfits-new #how-can-i-help textarea, body.outfits-new #i-found-something input[type=text], body.outfits-new #i-found-something body.pets-bulk #bulk-pets-form textarea, body.pets-bulk #bulk-pets-form body.outfits-new #i-found-something textarea { border-color: #006600; width: 12em; } @@ -775,7 +775,7 @@ body.outfits-new #sections h4, body.outfits-new #sections input { font-size: 116%; } /* line 123, ../../../app/stylesheets/outfits/_new.sass */ -body.outfits-new #sections h4, body.outfits-new #sections input[type=text] { +body.outfits-new #sections h4, body.outfits-new #sections input[type=text], body.outfits-new #sections body.pets-bulk #bulk-pets-form textarea, body.pets-bulk #bulk-pets-form body.outfits-new #sections textarea { color: inherit; } /* line 125, ../../../app/stylesheets/outfits/_new.sass */ @@ -817,6 +817,88 @@ body.outfits-new #tell-the-world img { width: 16px; } +/* line 1, ../../../app/stylesheets/pets/_bulk.sass */ +body.pets-bulk { + text-align: center; +} +/* line 5, ../../../app/stylesheets/pets/_bulk.sass */ +body.pets-bulk #bulk-pets-form textarea, body.pets-bulk #bulk-pets-form div { + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: middle; + *display: inline; + *vertical-align: auto; +} +/* line 7, ../../../app/stylesheets/pets/_bulk.sass */ +body.pets-bulk #bulk-pets-form textarea { + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: middle; + *display: inline; + *vertical-align: auto; + display: inline; + font: inherit; + height: 1.5em; + overflow: hidden; + resize: none; +} +/* line 15, ../../../app/stylesheets/pets/_bulk.sass */ +body.pets-bulk #bulk-pets-form ul { + list-style: none; + margin-bottom: 1em; +} +/* line 18, ../../../app/stylesheets/pets/_bulk.sass */ +body.pets-bulk #bulk-pets-form ul li { + display: -moz-inline-box; + -moz-box-orient: vertical; + display: inline-block; + vertical-align: middle; + *display: inline; + *vertical-align: auto; + background: #eeeeee; + margin: 0 auto; + min-width: 25%; + text-align: left; +} +/* line 24, ../../../app/stylesheets/pets/_bulk.sass */ +body.pets-bulk #bulk-pets-form ul li.loaded { + background: #e6efc2; +} +/* line 26, ../../../app/stylesheets/pets/_bulk.sass */ +body.pets-bulk #bulk-pets-form ul li.failed { + background: #fbe3e4; +} +/* line 28, ../../../app/stylesheets/pets/_bulk.sass */ +body.pets-bulk #bulk-pets-form ul img { + float: left; + height: 50px; + width: 50px; +} +/* line 33, ../../../app/stylesheets/pets/_bulk.sass */ +body.pets-bulk #bulk-pets-form ul span { + display: block; +} +/* line 35, ../../../app/stylesheets/pets/_bulk.sass */ +body.pets-bulk #bulk-pets-form ul .response { + font-size: 75%; + font-style: italic; + margin-left: 75px; +} +/* line 42, ../../../app/stylesheets/pets/_bulk.sass */ +body.pets-bulk.js .noscript { + display: none; +} +/* line 44, ../../../app/stylesheets/pets/_bulk.sass */ +body.pets-bulk.js .script-only { + display: block; +} +/* line 47, ../../../app/stylesheets/pets/_bulk.sass */ +body.pets-bulk .script-only { + display: none; +} + /* line 1, ../../../app/stylesheets/static/_terms.sass */ body.static-terms { text-align: center;