forked from OpenNeo/impress
can now have the same item in more than one list
This commit is contained in:
parent
6bf926eb3b
commit
44156c5b21
13 changed files with 344 additions and 155 deletions
|
@ -1,7 +1,7 @@
|
|||
class ClosetHangersController < ApplicationController
|
||||
before_filter :authorize_user!, :only => [:destroy, :create, :update, :petpage]
|
||||
before_filter :find_item, :only => [:destroy, :create, :update]
|
||||
before_filter :find_user, :only => [:index, :petpage]
|
||||
before_filter :authorize_user!, :only => [:destroy, :create, :update, :update_quantities, :petpage]
|
||||
before_filter :find_item, :only => [:destroy, :create, :update_quantities]
|
||||
before_filter :find_user, :only => [:index, :petpage, :update_quantities]
|
||||
|
||||
def destroy
|
||||
raise ActiveRecord::RecordNotFound unless params[:closet_hanger]
|
||||
|
@ -39,19 +39,38 @@ class ClosetHangersController < ApplicationController
|
|||
find_closet_hangers!
|
||||
end
|
||||
|
||||
# Since the user does not care about the idea of a hanger, but rather the
|
||||
# quantity of an item they own, the user would expect a create form to work
|
||||
# even after the record already exists, and an update form to work even after
|
||||
# the record is deleted. So, create and update are aliased, and both find
|
||||
# the record if it exists or create a new one if it does not. They will even
|
||||
# delete the record if quantity is zero.
|
||||
#
|
||||
# This is kinda a violation of REST. It's not worth breaking user
|
||||
# expectations, though, and I can't really think of a genuinely RESTful way
|
||||
# to pull this off.
|
||||
def create
|
||||
@closet_hanger = current_user.closet_hangers.build(params[:closet_hanger])
|
||||
@closet_hanger.item = @item
|
||||
|
||||
if @closet_hanger.save
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
message = "Success! You #{@closet_hanger.verb(:you)} #{@closet_hanger.quantity} "
|
||||
message << ((@closet_hanger.quantity > 1) ? @item.name.pluralize : @item.name)
|
||||
message << " in the \"#{@closet_hanger.list.name}\" list" if @closet_hanger.list
|
||||
flash[:success] = "#{message}."
|
||||
redirect_back!(@item)
|
||||
}
|
||||
|
||||
format.json { render :json => true }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
flash[:alert] = "We couldn't save how many of this item you #{@closet_hanger.verb(:you)}: #{@closet_hanger.errors.full_messages.to_sentence}"
|
||||
redirect_back!(@item)
|
||||
}
|
||||
|
||||
format.json { render :json => {:errors => @closet_hanger.errors.full_messages}, :status => :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@closet_hanger = current_user.closet_hangers.find_or_initialize_by_item_id_and_owned(@item.id, owned)
|
||||
@closet_hanger = current_user.closet_hangers.find(params[:id])
|
||||
@closet_hanger.attributes = params[:closet_hanger]
|
||||
@item = @closet_hanger.item
|
||||
|
||||
unless @closet_hanger.quantity == 0 # save the hanger, new record or not
|
||||
if @closet_hanger.save
|
||||
|
@ -85,8 +104,21 @@ class ClosetHangersController < ApplicationController
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
alias_method :create, :update
|
||||
|
||||
def update_quantities
|
||||
begin
|
||||
ClosetHanger.transaction do
|
||||
params[:quantity].each do |key, quantity|
|
||||
ClosetHanger.set_quantity!(quantity, :user_id => @user.id,
|
||||
:item_id => @item.id, :key => key)
|
||||
end
|
||||
flash[:success] = "Successfully saved how many #{@item.name} you own and want."
|
||||
end
|
||||
rescue ActiveRecord::RecordInvalid => e
|
||||
flash[:alert] = "We couldn't save those quantities. #{e.message}"
|
||||
end
|
||||
redirect_to @item
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
|
|
|
@ -54,10 +54,20 @@ class ItemsController < ApplicationController
|
|||
}
|
||||
|
||||
if user_signed_in?
|
||||
@current_user_hangers = [true, false].map do |owned|
|
||||
hanger = current_user.closet_hangers.find_or_initialize_by_item_id_and_owned(@item.id, owned)
|
||||
hanger.quantity ||= 1
|
||||
hanger
|
||||
# Empty arrays are important so that we can loop over this and still
|
||||
# show the generic no-list case
|
||||
@current_user_lists = {true => [], false => []}
|
||||
current_user.closet_lists.alphabetical.each do |list|
|
||||
@current_user_lists[list.hangers_owned] << list
|
||||
end
|
||||
|
||||
@current_user_quantities = Hash.new(0) # default is zero
|
||||
hangers = current_user.closet_hangers.where(:item_id => @item.id).
|
||||
select([:owned, :list_id, :quantity])
|
||||
|
||||
hangers.each do |hanger|
|
||||
key = hanger.list_id || hanger.owned
|
||||
@current_user_quantities[key] = hanger.quantity
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -47,6 +47,10 @@ module ItemsHelper
|
|||
)
|
||||
end
|
||||
end
|
||||
|
||||
def closet_list_verb(owned)
|
||||
ClosetHanger.verb(:you, owned)
|
||||
end
|
||||
|
||||
def closeted_icons_for(item)
|
||||
content = ''.html_safe
|
||||
|
|
|
@ -5,7 +5,7 @@ class ClosetHanger < ActiveRecord::Base
|
|||
|
||||
attr_accessible :list_id, :owned, :quantity
|
||||
|
||||
validates :item_id, :uniqueness => {:scope => [:user_id, :owned]}
|
||||
validates :item_id, :uniqueness => {:scope => [:user_id, :owned, :list_id]}
|
||||
validates :quantity, :numericality => {:greater_than => 0}
|
||||
validates_presence_of :item, :user
|
||||
|
||||
|
@ -28,7 +28,7 @@ class ClosetHanger < ActiveRecord::Base
|
|||
))
|
||||
end
|
||||
|
||||
before_validation :set_owned_by_list
|
||||
before_validation :merge_quantities, :set_owned_by_list
|
||||
|
||||
def verb(subject=:someone)
|
||||
self.class.verb(subject, owned?)
|
||||
|
@ -39,6 +39,41 @@ class ClosetHanger < ActiveRecord::Base
|
|||
base << 's' if positive && subject != :you && subject != :i
|
||||
base
|
||||
end
|
||||
|
||||
def self.set_quantity!(quantity, options)
|
||||
quantity = quantity.to_i
|
||||
conditions = {:user_id => options[:user_id].to_i,
|
||||
:item_id => options[:item_id].to_i}
|
||||
|
||||
if options[:key] == "true"
|
||||
conditions[:owned] = true
|
||||
conditions[:list_id] = nil
|
||||
elsif options[:key] == "false"
|
||||
conditions[:owned] = false
|
||||
conditions[:list_id] = nil
|
||||
else
|
||||
conditions[:list_id] = options[:key].to_i
|
||||
end
|
||||
|
||||
hanger = self.where(conditions).first
|
||||
unless hanger
|
||||
hanger = self.new
|
||||
hanger.user_id = conditions[:user_id]
|
||||
hanger.item_id = conditions[:item_id]
|
||||
# One of the following will be nil, and that's okay. If owned is nil,
|
||||
# we'll cover for it before validation, as always.
|
||||
hanger.owned = conditions[:owned]
|
||||
hanger.list_id = conditions[:list_id]
|
||||
end
|
||||
|
||||
unless quantity == 0
|
||||
Rails.logger.debug("Logging to #{hanger.id} quantity #{quantity}")
|
||||
hanger.quantity = quantity
|
||||
hanger.save!
|
||||
else
|
||||
hanger.destroy if hanger
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
|
@ -51,6 +86,23 @@ class ClosetHanger < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
def merge_quantities
|
||||
# Find a hanger that conflicts: for the same item, in the same user's
|
||||
# closet, same owned status, same list. It also must not be the current
|
||||
# hanger.
|
||||
conflicting_hanger = self.class.select([:id, :quantity]).
|
||||
where(:user_id => user_id, :item_id => item_id, :owned => owned,
|
||||
:list_id => list_id).where(['id != ?', self.id]).first
|
||||
|
||||
# If there is such a hanger, remove it and merge its quantity into this one.
|
||||
if conflicting_hanger
|
||||
self.quantity += conflicting_hanger.quantity
|
||||
conflicting_hanger.destroy
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def set_owned_by_list
|
||||
self.owned = list.hangers_owned if list
|
||||
|
|
|
@ -295,6 +295,7 @@ body.closet_hangers-index
|
|||
|
||||
.closet-hangers-group-autocomplete-item, .closet-list-autocomplete-item
|
||||
span
|
||||
+opacity(.5)
|
||||
font-style: italic
|
||||
padding: .2em .4em
|
||||
|
||||
|
|
|
@ -112,14 +112,33 @@ body.items-show
|
|||
font-size: 85%
|
||||
margin-left: 1em
|
||||
padding: 1em
|
||||
width: 21em
|
||||
width: 30em
|
||||
|
||||
// compete with #trade-hangers
|
||||
position: relative
|
||||
z-index: 2
|
||||
|
||||
label, header
|
||||
display: block
|
||||
h3
|
||||
font-size: 150%
|
||||
font-weight: bold
|
||||
|
||||
header
|
||||
font-size: 125%
|
||||
margin-bottom: .25em
|
||||
|
||||
#closet-hangers-ownership-groups
|
||||
+clearfix
|
||||
margin-bottom: .5em
|
||||
|
||||
div
|
||||
float: left
|
||||
margin: 0 5%
|
||||
text-align: left
|
||||
width: 40%
|
||||
|
||||
li
|
||||
list-style: none
|
||||
word-wrap: break-word
|
||||
|
||||
&.unlisted
|
||||
font-style: italic
|
||||
|
||||
form
|
||||
padding: .5em 0
|
||||
|
@ -128,7 +147,8 @@ body.items-show
|
|||
width: 9em
|
||||
|
||||
input[type=number]
|
||||
width: 4em
|
||||
margin-right: .5em
|
||||
width: 3em
|
||||
|
||||
&.js
|
||||
#trade-hangers
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
.quantity{:class => "quantity-#{closet_hanger.quantity}"}
|
||||
%span= closet_hanger.quantity
|
||||
- if show_controls
|
||||
= form_for closet_hanger, :url => user_item_closet_hanger_path(current_user, closet_hanger.item), :html => {:class => 'closet-hanger-update'} do |f|
|
||||
= form_for [current_user, closet_hanger], :html => {:class => 'closet-hanger-update'} do |f|
|
||||
= return_to_field_tag
|
||||
= f.hidden_field :list_id
|
||||
= f.hidden_field :owned
|
||||
|
|
|
@ -95,21 +95,22 @@
|
|||
= link_to_add_closet_list 'Add new list', :owned => owned, :class => 'add-closet-list'
|
||||
.closet-hangers-group-content
|
||||
= render_closet_lists(@closet_lists_by_owned[owned])
|
||||
.closet-list.unlisted{'data-hangers-count' => unlisted_hangers_count(owned)}
|
||||
%header
|
||||
- unless public_perspective?
|
||||
= form_for @user, :html => {:class => 'visibility-form'} do |f|
|
||||
= f.select hangers_group_visibility_field_name(owned),
|
||||
closet_visibility_choices(:human_name)
|
||||
= f.submit "Save"
|
||||
= closet_visibility_descriptions
|
||||
- if has_lists?(owned)
|
||||
%h4 (Not in a list)
|
||||
.closet-list-content
|
||||
.closet-list-hangers
|
||||
= render_unlisted_closet_hangers(owned)
|
||||
%span.empty-list
|
||||
There aren't any items here.
|
||||
- if !public_perspective? || unlisted_hangers_count(owned) > 0
|
||||
.closet-list.unlisted{'data-hangers-count' => unlisted_hangers_count(owned)}
|
||||
%header
|
||||
- unless public_perspective?
|
||||
= form_for @user, :html => {:class => 'visibility-form'} do |f|
|
||||
= f.select hangers_group_visibility_field_name(owned),
|
||||
closet_visibility_choices(:human_name)
|
||||
= f.submit "Save"
|
||||
= closet_visibility_descriptions
|
||||
- if has_lists?(owned)
|
||||
%h4 (Not in a list)
|
||||
.closet-list-content
|
||||
.closet-list-hangers
|
||||
= render_unlisted_closet_hangers(owned)
|
||||
%span.empty-list
|
||||
There aren't any items here.
|
||||
|
||||
- content_for :stylesheets do
|
||||
= stylesheet_link_tag 'south-street/jquery-ui'
|
||||
|
|
|
@ -10,25 +10,34 @@
|
|||
== Rarity: #{@item.rarity_index} (#{@item.rarity})
|
||||
= link_to 'NeoItems', neoitems_url_for(@item), :class => 'button'
|
||||
|
||||
- if @current_user_hangers
|
||||
- if user_signed_in?
|
||||
#closet-hangers
|
||||
%header
|
||||
%h3
|
||||
Track this in
|
||||
= link_to 'Your Items', user_closet_hangers_path(current_user)
|
||||
- @current_user_hangers.each do |hanger|
|
||||
= form_for(hanger, :url => user_item_closet_hanger_path(current_user, @item)) do |f|
|
||||
- if hanger.new_record?
|
||||
= f.hidden_field :quantity
|
||||
= f.hidden_field :owned
|
||||
= f.submit "I #{hanger.verb(:you)} this item!"
|
||||
- else
|
||||
= f.hidden_field :owned
|
||||
= f.label :quantity, "How many of these do you #{hanger.verb(:you)}?"
|
||||
= f.number_field :quantity, :min => 0, :required => true
|
||||
- lists = current_user.closet_lists.where(:hangers_owned => hanger.owned).all
|
||||
- unless lists.empty?
|
||||
= f.collection_select :list_id, lists, :id, :name, :include_blank => 'Not in a list'
|
||||
= f.submit "Save"
|
||||
= form_tag update_quantities_user_item_closet_hangers_path(:user_id => current_user, :item_id => @item), :method => :put do
|
||||
#closet-hangers-ownership-groups
|
||||
- @current_user_lists.each do |owned, lists|
|
||||
%div
|
||||
%h4 Items you #{closet_list_verb(owned)}
|
||||
%ul
|
||||
- lists.each do |list|
|
||||
%li
|
||||
= number_field_tag "quantity[#{list.id}]",
|
||||
@current_user_quantities[list.id], :min => 0
|
||||
= label_tag "quantity[#{list.id}]", list.name
|
||||
|
||||
%li
|
||||
= number_field_tag "quantity[#{owned}]",
|
||||
@current_user_quantities[owned], :min => 0
|
||||
|
||||
- unless lists.empty?
|
||||
= label_tag "quantity[#{owned}]" do
|
||||
Not in a list
|
||||
- else
|
||||
= label_tag "quantity[#{owned}]" do
|
||||
How many?
|
||||
= submit_tag 'Save to Your Items'
|
||||
%p= @item.description
|
||||
|
||||
#item-zones
|
||||
|
|
|
@ -52,7 +52,7 @@ OpenneoImpressItems::Application.routes.draw do |map|
|
|||
|
||||
resources :users, :path => 'user', :only => [:index, :update] do
|
||||
resources :contributions, :only => [:index]
|
||||
resources :closet_hangers, :only => [:index], :path => 'closet' do
|
||||
resources :closet_hangers, :only => [:index, :update], :path => 'closet' do
|
||||
collection do
|
||||
get :petpage
|
||||
end
|
||||
|
@ -60,7 +60,13 @@ OpenneoImpressItems::Application.routes.draw do |map|
|
|||
resources :closet_lists, :only => [:new, :create, :edit, :update, :destroy], :path => 'closet/lists'
|
||||
|
||||
resources :items, :only => [] do
|
||||
resource :closet_hanger, :only => [:create, :update, :destroy]
|
||||
resources :closet_hangers, :only => [:create] do
|
||||
collection do
|
||||
put :update_quantities
|
||||
end
|
||||
end
|
||||
|
||||
resource :closet_hanger, :only => [:update, :destroy]
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -136,11 +136,11 @@
|
|||
return a.find('span.name').text().localeCompare(b.find('span.name').text());
|
||||
}
|
||||
|
||||
function findList(id, item) {
|
||||
function findList(owned, id, item) {
|
||||
if(id) {
|
||||
return $('#closet-list-' + id);
|
||||
} else {
|
||||
return item.closest('.closet-hangers-group').find('div.closet-list.unlisted');
|
||||
return $("div.closet-hangers-group[data-owned=" + owned + "] div.closet-list.unlisted");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,8 +148,8 @@
|
|||
el.attr('data-hangers-count', el.find('div.object').length);
|
||||
}
|
||||
|
||||
function moveItemToList(item, listId) {
|
||||
var newList = findList(listId, item);
|
||||
function moveItemToList(item, owned, listId) {
|
||||
var newList = findList(owned, listId, item);
|
||||
var oldList = item.closest('div.closet-list');
|
||||
var hangersWrapper = newList.find('div.closet-list-hangers');
|
||||
item.insertIntoSortedList(hangersWrapper, compareItemsByName);
|
||||
|
@ -160,8 +160,9 @@
|
|||
function submitUpdateForm(form) {
|
||||
if(form.data('loading')) return false;
|
||||
var quantityEl = form.children("input[name=closet_hanger\[quantity\]]");
|
||||
var ownedEl = form.children("input[name=closet_hanger\[owned\]]");
|
||||
var listEl = form.children("input[name=closet_hanger\[list_id\]]");
|
||||
var listChanged = listEl.hasChanged();
|
||||
var listChanged = ownedEl.hasChanged() || listEl.hasChanged();
|
||||
if(listChanged || quantityEl.hasChanged()) {
|
||||
var objectWrapper = form.closest(".object").addClass("loading");
|
||||
var newQuantity = quantityEl.val();
|
||||
|
@ -170,7 +171,7 @@
|
|||
var data = form.serialize(); // get data before disabling inputs
|
||||
objectWrapper.disableForms();
|
||||
form.data('loading', true);
|
||||
if(listChanged) moveItemToList(objectWrapper, listEl.val());
|
||||
if(listChanged) moveItemToList(objectWrapper, ownedEl.val(), listEl.val());
|
||||
$.ajax({
|
||||
url: form.attr("action") + ".json",
|
||||
type: "post",
|
||||
|
@ -185,13 +186,37 @@
|
|||
form.data('loading', false);
|
||||
},
|
||||
success: function () {
|
||||
// Now that the move was successful, let's merge it with any
|
||||
// conflicting hangers
|
||||
var id = objectWrapper.attr("data-item-id");
|
||||
var conflictingHanger = findList(ownedEl.val(), listEl.val(), objectWrapper).
|
||||
find("div[data-item-id=" + id + "]").not(objectWrapper);
|
||||
if(conflictingHanger.length) {
|
||||
var conflictingQuantity = parseInt(
|
||||
conflictingHanger.attr('data-quantity'),
|
||||
10
|
||||
);
|
||||
|
||||
var currentQuantity = parseInt(newQuantity, 10);
|
||||
|
||||
var mergedQuantity = conflictingQuantity + currentQuantity;
|
||||
|
||||
quantitySpan.text(mergedQuantity);
|
||||
quantityEl.val(mergedQuantity);
|
||||
objectWrapper.attr('data-quantity', mergedQuantity);
|
||||
|
||||
conflictingHanger.remove();
|
||||
}
|
||||
|
||||
quantityEl.storeValue();
|
||||
ownedEl.storeValue();
|
||||
listEl.storeValue();
|
||||
},
|
||||
error: function (xhr) {
|
||||
quantityEl.revertValue();
|
||||
ownedEl.revertValue();
|
||||
listEl.revertValue();
|
||||
if(listChanged) moveItemToList(objectWrapper, listEl.val());
|
||||
if(listChanged) moveItemToList(objectWrapper, ownedEl.val(), listEl.val());
|
||||
quantitySpan.text(quantityEl.val());
|
||||
|
||||
handleSaveError(xhr, "updating the quantity");
|
||||
|
@ -205,7 +230,13 @@
|
|||
submitUpdateForm($(this));
|
||||
});
|
||||
|
||||
function editableInputs() { return $(hangersElQuery).find('input[name=closet_hanger\[quantity\]], input[name=closet_hanger\[list_id\]]') }
|
||||
function editableInputs() {
|
||||
return $(hangersElQuery).find(
|
||||
'input[name=closet_hanger\[quantity\]], ' +
|
||||
'input[name=closet_hanger\[owned\]], ' +
|
||||
'input[name=closet_hanger\[list_id\]]'
|
||||
)
|
||||
}
|
||||
|
||||
$(hangersElQuery + 'input[name=closet_hanger\[quantity\]]').live('change', function () {
|
||||
submitUpdateForm($(this).parent());
|
||||
|
@ -264,7 +295,9 @@
|
|||
select: function (e, ui) {
|
||||
if(ui.item.is_item) {
|
||||
// Let the autocompleter finish up this search before starting a new one
|
||||
setTimeout(function () { itemsSearchField.autocomplete("search", ui.item) }, 0);
|
||||
setTimeout(function () {
|
||||
itemsSearchField.autocomplete("search", ui.item);
|
||||
}, 0);
|
||||
} else {
|
||||
var item = ui.item.item;
|
||||
var group = ui.item.group;
|
||||
|
@ -276,10 +309,10 @@
|
|||
list_id: ui.item.list ? ui.item.list.id : ''
|
||||
};
|
||||
|
||||
if(!item.hangerInGroup) closetHanger.quantity = 1;
|
||||
if(!item.hasHanger) closetHanger.quantity = 1;
|
||||
|
||||
$.ajax({
|
||||
url: "/user/" + itemsSearchForm.data("current-user-id") + "/items/" + item.id + "/closet_hanger",
|
||||
url: "/user/" + itemsSearchForm.data("current-user-id") + "/items/" + item.id + "/closet_hangers",
|
||||
type: "post",
|
||||
data: {closet_hanger: closetHanger, return_to: window.location.pathname + window.location.search},
|
||||
complete: function () {
|
||||
|
@ -312,29 +345,29 @@
|
|||
});
|
||||
} else { // item was chosen, now choose a group to insert
|
||||
var groupInserts = [], group;
|
||||
var item = input.term, itemEl, hangerInGroup, currentListId;
|
||||
var item = input.term, itemEl, occupiedGroups, hasHanger;
|
||||
for(var i in hangerGroups) {
|
||||
group = hangerGroups[i];
|
||||
itemEl = $('div.closet-hangers-group[data-owned=' + group.owned + '] div.object[data-item-id=' + item.id + ']');
|
||||
hangerInGroup = itemEl.length > 0;
|
||||
currentListId = itemEl.closest('.closet-list').attr('data-id');
|
||||
occupiedGroups = itemEl.closest('.closet-list');
|
||||
hasHanger = occupiedGroups.filter('.unlisted').length > 0;
|
||||
|
||||
groupInserts[groupInserts.length] = {
|
||||
group: group,
|
||||
item: item,
|
||||
label: item.label,
|
||||
hangerInGroup: hangerInGroup,
|
||||
hangerInList: !!currentListId
|
||||
hasHanger: hasHanger
|
||||
}
|
||||
|
||||
for(var i = 0; i < group.lists.length; i++) {
|
||||
hasHanger = occupiedGroups.
|
||||
filter("[data-id=" + group.lists[i].id + "]").length > 0;
|
||||
groupInserts[groupInserts.length] = {
|
||||
group: group,
|
||||
item: item,
|
||||
label: item.label,
|
||||
list: group.lists[i],
|
||||
hangerInGroup: hangerInGroup,
|
||||
currentListId: currentListId
|
||||
hasHanger: hasHanger
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -350,27 +383,19 @@
|
|||
if(item.is_item) { // these are items from the server
|
||||
li.append("<a>Add <strong>" + item.label + "</strong>");
|
||||
} else if(item.list) { // these are list inserts
|
||||
if(item.hangerInGroup) {
|
||||
if(item.currentListId == item.list.id) {
|
||||
li.append("<span>It's in <strong>" + item.list.label + "</strong> now");
|
||||
} else {
|
||||
li.append("<a>Move to <strong>" + item.list.label + "</strong>");
|
||||
}
|
||||
if(item.hasHanger) {
|
||||
li.append("<span>It's already in <strong>" + item.list.label + "</strong>");
|
||||
} else {
|
||||
li.append("<a>Add to <strong>" + item.list.label + "</strong>");
|
||||
}
|
||||
li.addClass("closet-list-autocomplete-item");
|
||||
} else { // these are group inserts
|
||||
if(item.hangerInGroup) {
|
||||
var groupName = item.group.label;
|
||||
if(item.hangerInList) {
|
||||
li.append("<a>Move to <strong>" + groupName.replace(/\s+$/, '') + "</strong>, no list");
|
||||
} else {
|
||||
li.append("<span>It's in <strong>" + groupName + "</strong> now");
|
||||
}
|
||||
var groupName = item.group.label;
|
||||
if(!item.hasHanger) {
|
||||
li.append("<a>Add to <strong>" + groupName.replace(/\s+$/, '') + "</strong>, no list");
|
||||
} else {
|
||||
li.append("<a>Add to <strong>" + item.group.label + "</strong>");
|
||||
}
|
||||
li.append("<span>It's already in <strong>" + groupName + "</strong>");
|
||||
}
|
||||
li.addClass('closet-hangers-group-autocomplete-item');
|
||||
}
|
||||
return li.appendTo(ul);
|
||||
|
@ -445,23 +470,23 @@
|
|||
*/
|
||||
|
||||
onHangersInit(function () {
|
||||
$('.closet-hangers-group').each(function () {
|
||||
var group = $(this);
|
||||
group.find('div.closet-list').droppable({
|
||||
accept: '#' + group.attr('id') + ' div.object',
|
||||
activate: function () {
|
||||
$(this).find('.closet-list-content').animate({opacity: 0, height: 100}, 250);
|
||||
},
|
||||
activeClass: 'droppable-active',
|
||||
deactivate: function () {
|
||||
$(this).find('.closet-list-content').css('height', 'auto').animate({opacity: 1}, 250);
|
||||
},
|
||||
drop: function (e, ui) {
|
||||
var form = ui.draggable.find('form.closet-hanger-update');
|
||||
form.find('input[name=closet_hanger\[list_id\]]').val(this.getAttribute('data-id'));
|
||||
submitUpdateForm(form);
|
||||
}
|
||||
});
|
||||
$('div.closet-list').droppable({
|
||||
accept: 'div.object',
|
||||
activate: function () {
|
||||
$(this).find('.closet-list-content').animate({opacity: 0, height: 100}, 250);
|
||||
},
|
||||
activeClass: 'droppable-active',
|
||||
deactivate: function () {
|
||||
$(this).find('.closet-list-content').css('height', 'auto').animate({opacity: 1}, 250);
|
||||
},
|
||||
drop: function (e, ui) {
|
||||
var form = ui.draggable.find('form.closet-hanger-update');
|
||||
form.find('input[name=closet_hanger\[list_id\]]').
|
||||
val(this.getAttribute('data-id'));
|
||||
form.find('input[name=closet_hanger\[owned\]]').
|
||||
val($(this).closest('.closet-hangers-group').attr('data-owned'));
|
||||
submitUpdateForm(form);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -229,7 +229,6 @@ function Wardrobe() {
|
|||
}
|
||||
},
|
||||
error: function (xhr) {
|
||||
console.log($.parseJSON(xhr.responseText));
|
||||
try {
|
||||
var json = $.parseJSON(xhr.responseText);
|
||||
} catch(e) {
|
||||
|
|
|
@ -1163,30 +1163,34 @@ body.closet_hangers-index .closet-list.droppable-active .visibility-form {
|
|||
}
|
||||
/* line 297, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index .closet-hangers-group-autocomplete-item span, body.closet_hangers-index .closet-list-autocomplete-item span {
|
||||
-moz-opacity: 0.5;
|
||||
-webkit-opacity: 0.5;
|
||||
-o-opacity: 0.5;
|
||||
-khtml-opacity: 0.5;
|
||||
font-style: italic;
|
||||
padding: 0.2em 0.4em;
|
||||
}
|
||||
/* line 302, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 303, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index .closet-list-autocomplete-item a, body.closet_hangers-index .closet-list-autocomplete-item span {
|
||||
font-size: 85%;
|
||||
padding-left: 2em;
|
||||
}
|
||||
/* line 307, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 308, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index .closet-hangers-group[data-owned=true] .user-wants, body.closet_hangers-index .closet-hangers-group[data-owned=false] .user-owns {
|
||||
background: #eeffee;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* line 314, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 315, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.current-user #closet-hangers .object:hover form {
|
||||
display: inline;
|
||||
}
|
||||
/* line 317, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 318, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.current-user #closet-hangers .object:hover .closet-hanger-destroy {
|
||||
position: absolute;
|
||||
right: 18px;
|
||||
top: 52px;
|
||||
}
|
||||
/* line 322, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 323, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.current-user #closet-hangers .object:hover .closet-hanger-destroy input {
|
||||
/* http://www.zurb.com/blog_uploads/0000/0617/buttons-03.html */
|
||||
-moz-border-radius: 5px;
|
||||
|
@ -1227,7 +1231,7 @@ body.closet_hangers-index.current-user #closet-hangers .object:hover .closet-han
|
|||
body.closet_hangers-index.current-user #closet-hangers .object:hover .closet-hanger-destroy input:hover {
|
||||
background-color: #999999;
|
||||
}
|
||||
/* line 325, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 326, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.current-user #closet-hangers .object:hover .quantity {
|
||||
-moz-opacity: 1;
|
||||
-webkit-opacity: 1;
|
||||
|
@ -1237,89 +1241,89 @@ body.closet_hangers-index.current-user #closet-hangers .object:hover .quantity {
|
|||
top: 0;
|
||||
padding: 0;
|
||||
}
|
||||
/* line 331, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 332, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.current-user #closet-hangers .object:hover .quantity span {
|
||||
display: none;
|
||||
}
|
||||
/* line 334, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 335, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.current-user #closet-hangers .object:hover .quantity input[type=number] {
|
||||
padding: 2px;
|
||||
width: 2em;
|
||||
}
|
||||
/* line 338, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 339, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.current-user #closet-hangers .object:hover .quantity input[type=submit] {
|
||||
font-size: 85%;
|
||||
}
|
||||
/* line 343, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 344, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.current-user.js #closet-hangers .object:hover .quantity {
|
||||
display: block;
|
||||
}
|
||||
/* line 346, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 347, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.current-user.js #closet-hangers .object:hover .quantity input[type=number] {
|
||||
width: 2.5em;
|
||||
}
|
||||
/* line 349, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 350, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.current-user.js #closet-hangers .object:hover .quantity input[type=submit] {
|
||||
display: none;
|
||||
}
|
||||
/* line 352, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 353, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.current-user.js #closet-hangers .object.loading {
|
||||
background: #eeffee;
|
||||
outline: 1px solid #006600;
|
||||
}
|
||||
/* line 356, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 357, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.current-user.js #closet-hangers .object.loading .quantity {
|
||||
display: block;
|
||||
}
|
||||
/* line 359, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 360, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.current-user.js #closet-hangers .object.loading .quantity span:after {
|
||||
content: "…";
|
||||
}
|
||||
/* line 363, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 364, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.current-user.js #closet-hangers-contact form {
|
||||
display: none;
|
||||
}
|
||||
/* line 366, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 367, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.current-user.js #closet-hangers-contact .edit-contact-link, body.closet_hangers-index.current-user.js #closet-hangers-contact #cancel-contact-link {
|
||||
display: inline;
|
||||
}
|
||||
/* line 370, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 371, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.current-user.js #closet-hangers-contact.editing form {
|
||||
display: block;
|
||||
}
|
||||
/* line 373, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 374, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.current-user.js #closet-hangers-contact.editing .edit-contact-link {
|
||||
display: none;
|
||||
}
|
||||
/* line 378, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 379, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.current-user.js .closet-hangers-group header .show, body.closet_hangers-index.current-user.js .closet-hangers-group header .hide {
|
||||
cursor: pointer;
|
||||
}
|
||||
/* line 381, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 382, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.current-user.js .closet-hangers-group header .hide {
|
||||
display: block;
|
||||
}
|
||||
/* line 385, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 386, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.current-user.js .closet-hangers-group.hidden header .hide, body.closet_hangers-index.current-user.js .closet-hangers-group.hidden .closet-hangers-group-content {
|
||||
display: none;
|
||||
}
|
||||
/* line 388, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 389, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.current-user.js .closet-hangers-group.hidden header .show {
|
||||
display: block;
|
||||
}
|
||||
/* line 391, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 392, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.current-user.js #toggle-help {
|
||||
display: inline;
|
||||
}
|
||||
/* line 395, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 396, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.js #toggle-compare {
|
||||
display: inline;
|
||||
}
|
||||
/* line 399, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 400, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.js #closet-hangers.comparing .object {
|
||||
display: none;
|
||||
}
|
||||
/* line 403, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
/* line 404, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||
body.closet_hangers-index.js #closet-hangers.comparing .closet-hangers-group[data-owned=true] .user-wants, body.closet_hangers-index.js #closet-hangers.comparing .closet-hangers-group[data-owned=false] .user-owns {
|
||||
display: inline-block;
|
||||
}
|
||||
|
@ -1878,35 +1882,61 @@ body.items-show #closet-hangers {
|
|||
font-size: 85%;
|
||||
margin-left: 1em;
|
||||
padding: 1em;
|
||||
width: 21em;
|
||||
}
|
||||
/* line 117, ../../../app/stylesheets/items/_show.sass */
|
||||
body.items-show #closet-hangers label, body.items-show #closet-hangers header {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
width: 30em;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
/* line 121, ../../../app/stylesheets/items/_show.sass */
|
||||
body.items-show #closet-hangers header {
|
||||
font-size: 125%;
|
||||
body.items-show #closet-hangers h3 {
|
||||
font-size: 150%;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.25em;
|
||||
}
|
||||
/* line 124, ../../../app/stylesheets/items/_show.sass */
|
||||
/* line 126, ../../../app/stylesheets/items/_show.sass */
|
||||
body.items-show #closet-hangers #closet-hangers-ownership-groups {
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
/* line 8, ../../../app/stylesheets/partials/clean/_mixins.sass */
|
||||
body.items-show #closet-hangers #closet-hangers-ownership-groups {
|
||||
display: block;
|
||||
}
|
||||
/* line 130, ../../../app/stylesheets/items/_show.sass */
|
||||
body.items-show #closet-hangers #closet-hangers-ownership-groups div {
|
||||
float: left;
|
||||
margin: 0 5%;
|
||||
text-align: left;
|
||||
width: 40%;
|
||||
}
|
||||
/* line 136, ../../../app/stylesheets/items/_show.sass */
|
||||
body.items-show #closet-hangers #closet-hangers-ownership-groups div li {
|
||||
list-style: none;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
/* line 140, ../../../app/stylesheets/items/_show.sass */
|
||||
body.items-show #closet-hangers #closet-hangers-ownership-groups div li.unlisted {
|
||||
font-style: italic;
|
||||
}
|
||||
/* line 143, ../../../app/stylesheets/items/_show.sass */
|
||||
body.items-show #closet-hangers form {
|
||||
padding: 0.5em 0;
|
||||
}
|
||||
/* line 127, ../../../app/stylesheets/items/_show.sass */
|
||||
/* line 146, ../../../app/stylesheets/items/_show.sass */
|
||||
body.items-show #closet-hangers select {
|
||||
width: 9em;
|
||||
}
|
||||
/* line 130, ../../../app/stylesheets/items/_show.sass */
|
||||
/* line 149, ../../../app/stylesheets/items/_show.sass */
|
||||
body.items-show #closet-hangers input[type=number] {
|
||||
width: 4em;
|
||||
margin-right: 0.5em;
|
||||
width: 3em;
|
||||
}
|
||||
/* line 135, ../../../app/stylesheets/items/_show.sass */
|
||||
/* line 155, ../../../app/stylesheets/items/_show.sass */
|
||||
body.items-show.js #trade-hangers p {
|
||||
max-height: 3em;
|
||||
overflow: hidden;
|
||||
}
|
||||
/* line 139, ../../../app/stylesheets/items/_show.sass */
|
||||
/* line 159, ../../../app/stylesheets/items/_show.sass */
|
||||
body.items-show.js #trade-hangers p.showing-more {
|
||||
max-height: none;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue