closet hangers page gets serious ajax action
This commit is contained in:
parent
3ac30bb6b1
commit
eeb3fc3af9
7 changed files with 169 additions and 33 deletions
|
@ -22,16 +22,35 @@ class ClosetHangersController < ApplicationController
|
||||||
|
|
||||||
unless @closet_hanger.quantity == 0 # save the hanger, new record or not
|
unless @closet_hanger.quantity == 0 # save the hanger, new record or not
|
||||||
if @closet_hanger.save
|
if @closet_hanger.save
|
||||||
flash[:success] = "Success! You own #{@closet_hanger.quantity} #{@item.name.pluralize}."
|
respond_to do |format|
|
||||||
|
format.html {
|
||||||
|
flash[:success] = "Success! You own #{@closet_hanger.quantity} #{@item.name.pluralize}."
|
||||||
|
redirect_back!
|
||||||
|
}
|
||||||
|
|
||||||
|
format.json { render :json => true }
|
||||||
|
end
|
||||||
else
|
else
|
||||||
flash[:alert] = "We couldn't save how many of this item you own: #{@closet_hanger.errors.full_messages.to_sentence}"
|
respond_to do |format|
|
||||||
|
format.html {
|
||||||
|
flash[:alert] = "We couldn't save how many of this item you own: #{@closet_hanger.errors.full_messages.to_sentence}"
|
||||||
|
redirect_back!
|
||||||
|
}
|
||||||
|
|
||||||
|
format.json { render :json => {:errors => @closet_hanger.errors.full_messages}, :status => :unprocessable_entity }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
else # delete the hanger since the user doesn't want it
|
else # delete the hanger since the user doesn't want it
|
||||||
@closet_hanger.destroy
|
@closet_hanger.destroy
|
||||||
flash[:success] = "Success! You do not own #{@item.name}."
|
respond_to do |format|
|
||||||
end
|
format.html {
|
||||||
|
flash[:success] = "Success! You do not own #{@item.name}."
|
||||||
|
redirect_back!
|
||||||
|
}
|
||||||
|
|
||||||
redirect_to params[:return_to] || @item
|
format.json { render :json => true }
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
alias_method :create, :update
|
alias_method :create, :update
|
||||||
|
@ -41,5 +60,9 @@ class ClosetHangersController < ApplicationController
|
||||||
def authorize_user!
|
def authorize_user!
|
||||||
raise AccessDenied unless user_signed_in? && current_user.id == params[:user_id].to_i
|
raise AccessDenied unless user_signed_in? && current_user.id == params[:user_id].to_i
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def redirect_back!
|
||||||
|
redirect_to params[:return_to] || @item
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -157,8 +157,8 @@ ul.buttons
|
||||||
|
|
||||||
.object
|
.object
|
||||||
+inline-block
|
+inline-block
|
||||||
margin: .5em 0
|
margin: $object-padding 0
|
||||||
padding: 0 .5em
|
padding: 0 $object-padding
|
||||||
position: relative
|
position: relative
|
||||||
text-align: center
|
text-align: center
|
||||||
vertical-align: top
|
vertical-align: top
|
||||||
|
|
|
@ -24,8 +24,9 @@ body.closet_hangers-index
|
||||||
padding: 2px 4px
|
padding: 2px 4px
|
||||||
position: absolute
|
position: absolute
|
||||||
left: ($object-width - $object-img-size) / 2 + $object-padding
|
left: ($object-width - $object-img-size) / 2 + $object-padding
|
||||||
|
line-height: 1
|
||||||
text-align: left
|
text-align: left
|
||||||
top: $object-img-size - 24px
|
top: $object-img-size - 20px
|
||||||
|
|
||||||
form
|
form
|
||||||
display: none
|
display: none
|
||||||
|
@ -35,23 +36,37 @@ body.closet_hangers-index
|
||||||
font-weight: bold
|
font-weight: bold
|
||||||
|
|
||||||
&.current-user
|
&.current-user
|
||||||
.object:hover
|
.object:hover .quantity
|
||||||
.quantity
|
+opacity(1)
|
||||||
+opacity(1)
|
background: transparent
|
||||||
background: transparent
|
top: $object-img-size - 24px
|
||||||
top: $object-img-size - 25px
|
padding: 0
|
||||||
padding: 0
|
|
||||||
|
|
||||||
span
|
span
|
||||||
display: none
|
display: none
|
||||||
|
|
||||||
form
|
form
|
||||||
display: inline
|
display: inline
|
||||||
|
|
||||||
input[type=number]
|
input[type=number]
|
||||||
padding: 2px
|
padding: 2px
|
||||||
width: 2em
|
width: 2em
|
||||||
|
|
||||||
|
input[type=submit]
|
||||||
|
font-size: 85%
|
||||||
|
|
||||||
|
&.js
|
||||||
|
.object:hover .quantity
|
||||||
|
input[type=number]
|
||||||
|
width: 2.5em
|
||||||
|
|
||||||
input[type=submit]
|
input[type=submit]
|
||||||
font-size: 85%
|
display: none
|
||||||
|
|
||||||
|
.object.loading
|
||||||
|
background: $module-bg-color
|
||||||
|
outline: 1px solid $module-border-color
|
||||||
|
|
||||||
|
.quantity span:after
|
||||||
|
content: "…"
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,8 @@ $text-font: "Droid Serif", Georgia, "Times New Roman", Times, serif
|
||||||
|
|
||||||
$object-img-size: 80px
|
$object-img-size: 80px
|
||||||
$object-width: 100px
|
$object-width: 100px
|
||||||
$object-padding: 6px
|
$object-padding: 8px
|
||||||
$nc-icon-size: 16px
|
$nc-icon-size: 16px
|
||||||
|
|
||||||
$container-top-padding: 3em
|
$container-top-padding: 3em
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,13 @@
|
||||||
= link_to "Import closet from Neopets", new_closet_page_path, :id => 'import-link'
|
= link_to "Import closet from Neopets", new_closet_page_path, :id => 'import-link'
|
||||||
- else
|
- else
|
||||||
- title "#{@user.name}'s Items"
|
- title "#{@user.name}'s Items"
|
||||||
|
|
||||||
#closet-hangers{:class => user_is?(@user) ? 'current-user' : nil}
|
#closet-hangers{:class => user_is?(@user) ? 'current-user' : nil}
|
||||||
- if !@closet_hangers.empty?
|
- if !@closet_hangers.empty?
|
||||||
|
- if user_is?(@user)
|
||||||
|
%p
|
||||||
|
These are the items you own. Hover over an item to remove it from the
|
||||||
|
list or to change the quantity.
|
||||||
= render @closet_hangers
|
= render @closet_hangers
|
||||||
- else
|
- else
|
||||||
- if user_is?(@user)
|
- if user_is?(@user)
|
||||||
|
@ -22,3 +27,7 @@
|
||||||
- else
|
- else
|
||||||
%p #{@user.name} hasn't tracked any items on Dress to Impress.
|
%p #{@user.name} hasn't tracked any items on Dress to Impress.
|
||||||
|
|
||||||
|
- content_for :javascripts do
|
||||||
|
= include_javascript_libraries :jquery
|
||||||
|
= javascript_include_tag 'jquery.jgrowl.js', 'closet_hangers/index'
|
||||||
|
|
||||||
|
|
70
public/javascripts/closet_hangers/index.js
Normal file
70
public/javascripts/closet_hangers/index.js
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
(function () {
|
||||||
|
var hangersEl = $('#closet-hangers.current-user');
|
||||||
|
hangersEl.addClass('js');
|
||||||
|
|
||||||
|
$.fn.hasChanged = function () {
|
||||||
|
return this.data('previousValue') != this.val();
|
||||||
|
}
|
||||||
|
|
||||||
|
$.fn.revertValue = function () {
|
||||||
|
this.each(function () {
|
||||||
|
var el = $(this);
|
||||||
|
el.val(el.data('previousValue'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$.fn.storeValue = function () {
|
||||||
|
this.each(function () {
|
||||||
|
var el = $(this);
|
||||||
|
el.data('previousValue', el.val());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitForm(form) {
|
||||||
|
if(form.data('loading')) return false;
|
||||||
|
var input = form.children("input[type=number]");
|
||||||
|
if(input.hasChanged()) {
|
||||||
|
var objectWrapper = form.closest(".object").addClass("loading");
|
||||||
|
var span = objectWrapper.find("span").text(input.val());
|
||||||
|
form.data('loading', true);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: form.attr("action") + ".json",
|
||||||
|
type: "post",
|
||||||
|
data: form.serialize(),
|
||||||
|
dataType: "json",
|
||||||
|
complete: function (data) {
|
||||||
|
objectWrapper.removeClass("loading");
|
||||||
|
form.data('loading', false);
|
||||||
|
},
|
||||||
|
success: function () {
|
||||||
|
input.storeValue();
|
||||||
|
},
|
||||||
|
error: function (xhr) {
|
||||||
|
var data = $.parseJSON(xhr.responseText);
|
||||||
|
input.revertValue();
|
||||||
|
span.text(input.val());
|
||||||
|
if(typeof data.errors != 'undefined') {
|
||||||
|
$.jGrowl("Error updating quantity: " + data.errors.join(", "));
|
||||||
|
} else {
|
||||||
|
$.jGrowl("We had trouble updating the quantity just now. Try again?");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hangersEl.find('form').submit(function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
submitForm($(this));
|
||||||
|
});
|
||||||
|
|
||||||
|
hangersEl.find('input[type=number]').change(function () {
|
||||||
|
submitForm($(this).parent());
|
||||||
|
}).storeValue();
|
||||||
|
|
||||||
|
hangersEl.find('div.object').mouseleave(function () {
|
||||||
|
submitForm($(this).find('form'));
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
|
@ -271,8 +271,8 @@ ul.buttons li, ul.buttons li form {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
*display: inline;
|
*display: inline;
|
||||||
*vertical-align: auto;
|
*vertical-align: auto;
|
||||||
margin: 0.5em 0;
|
margin: 8px 0;
|
||||||
padding: 0 0.5em;
|
padding: 0 8px;
|
||||||
position: relative;
|
position: relative;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
|
@ -323,11 +323,11 @@ ul.buttons li, ul.buttons li form {
|
||||||
}
|
}
|
||||||
/* line 190, ../../../app/stylesheets/_layout.sass */
|
/* line 190, ../../../app/stylesheets/_layout.sass */
|
||||||
.object .nc-icon {
|
.object .nc-icon {
|
||||||
right: 16px;
|
right: 18px;
|
||||||
}
|
}
|
||||||
/* line 193, ../../../app/stylesheets/_layout.sass */
|
/* line 193, ../../../app/stylesheets/_layout.sass */
|
||||||
.object .closeted-icon {
|
.object .closeted-icon {
|
||||||
left: 16px;
|
left: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 196, ../../../app/stylesheets/_layout.sass */
|
/* line 196, ../../../app/stylesheets/_layout.sass */
|
||||||
|
@ -610,15 +610,16 @@ body.closet_hangers-index #closet-hangers .object .quantity {
|
||||||
background: white;
|
background: white;
|
||||||
padding: 2px 4px;
|
padding: 2px 4px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 16px;
|
left: 18px;
|
||||||
|
line-height: 1;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
top: 56px;
|
top: 60px;
|
||||||
}
|
}
|
||||||
/* line 30, ../../../app/stylesheets/closet_hangers/_index.sass */
|
/* line 31, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||||
body.closet_hangers-index #closet-hangers .object .quantity form {
|
body.closet_hangers-index #closet-hangers .object .quantity form {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
/* line 33, ../../../app/stylesheets/closet_hangers/_index.sass */
|
/* line 34, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||||
body.closet_hangers-index #closet-hangers .object .quantity span, body.closet_hangers-index #closet-hangers .object .quantity input[type=number] {
|
body.closet_hangers-index #closet-hangers .object .quantity span, body.closet_hangers-index #closet-hangers .object .quantity input[type=number] {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
@ -630,7 +631,7 @@ body.closet_hangers-index #closet-hangers.current-user .object:hover .quantity {
|
||||||
-o-opacity: 1;
|
-o-opacity: 1;
|
||||||
-khtml-opacity: 1;
|
-khtml-opacity: 1;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
top: 55px;
|
top: 56px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
/* line 45, ../../../app/stylesheets/closet_hangers/_index.sass */
|
/* line 45, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||||
|
@ -642,7 +643,7 @@ body.closet_hangers-index #closet-hangers.current-user .object:hover .quantity f
|
||||||
display: inline;
|
display: inline;
|
||||||
}
|
}
|
||||||
/* line 51, ../../../app/stylesheets/closet_hangers/_index.sass */
|
/* line 51, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||||
body.closet_hangers-index #closet-hangers.current-user .object:hover .quantity form input[type=number] {
|
body.closet_hangers-index #closet-hangers.current-user .object:hover .quantity input[type=number] {
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
width: 2em;
|
width: 2em;
|
||||||
}
|
}
|
||||||
|
@ -650,6 +651,23 @@ body.closet_hangers-index #closet-hangers.current-user .object:hover .quantity f
|
||||||
body.closet_hangers-index #closet-hangers.current-user .object:hover .quantity input[type=submit] {
|
body.closet_hangers-index #closet-hangers.current-user .object:hover .quantity input[type=submit] {
|
||||||
font-size: 85%;
|
font-size: 85%;
|
||||||
}
|
}
|
||||||
|
/* line 60, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||||
|
body.closet_hangers-index #closet-hangers.current-user.js .object:hover .quantity input[type=number] {
|
||||||
|
width: 2.5em;
|
||||||
|
}
|
||||||
|
/* line 63, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||||
|
body.closet_hangers-index #closet-hangers.current-user.js .object:hover .quantity input[type=submit] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
/* line 66, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||||
|
body.closet_hangers-index #closet-hangers.current-user.js .object.loading {
|
||||||
|
background: #eeffee;
|
||||||
|
outline: 1px solid #006600;
|
||||||
|
}
|
||||||
|
/* line 70, ../../../app/stylesheets/closet_hangers/_index.sass */
|
||||||
|
body.closet_hangers-index #closet-hangers.current-user.js .object.loading .quantity span:after {
|
||||||
|
content: "…";
|
||||||
|
}
|
||||||
|
|
||||||
/* line 3, ../../../app/stylesheets/closet_pages/_new.sass */
|
/* line 3, ../../../app/stylesheets/closet_pages/_new.sass */
|
||||||
body.closet_pages-new #closet-page-form, body.closet_pages-create #closet-page-form {
|
body.closet_pages-new #closet-page-form, body.closet_pages-create #closet-page-form {
|
||||||
|
|
Loading…
Reference in a new issue