forked from OpenNeo/impress
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
|
||||
if @closet_hanger.save
|
||||
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
|
||||
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
|
||||
else # delete the hanger since the user doesn't want it
|
||||
@closet_hanger.destroy
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
flash[:success] = "Success! You do not own #{@item.name}."
|
||||
end
|
||||
redirect_back!
|
||||
}
|
||||
|
||||
redirect_to params[:return_to] || @item
|
||||
format.json { render :json => true }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
alias_method :create, :update
|
||||
|
@ -41,5 +60,9 @@ class ClosetHangersController < ApplicationController
|
|||
def authorize_user!
|
||||
raise AccessDenied unless user_signed_in? && current_user.id == params[:user_id].to_i
|
||||
end
|
||||
|
||||
def redirect_back!
|
||||
redirect_to params[:return_to] || @item
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -157,8 +157,8 @@ ul.buttons
|
|||
|
||||
.object
|
||||
+inline-block
|
||||
margin: .5em 0
|
||||
padding: 0 .5em
|
||||
margin: $object-padding 0
|
||||
padding: 0 $object-padding
|
||||
position: relative
|
||||
text-align: center
|
||||
vertical-align: top
|
||||
|
|
|
@ -24,8 +24,9 @@ body.closet_hangers-index
|
|||
padding: 2px 4px
|
||||
position: absolute
|
||||
left: ($object-width - $object-img-size) / 2 + $object-padding
|
||||
line-height: 1
|
||||
text-align: left
|
||||
top: $object-img-size - 24px
|
||||
top: $object-img-size - 20px
|
||||
|
||||
form
|
||||
display: none
|
||||
|
@ -35,11 +36,10 @@ body.closet_hangers-index
|
|||
font-weight: bold
|
||||
|
||||
&.current-user
|
||||
.object:hover
|
||||
.quantity
|
||||
.object:hover .quantity
|
||||
+opacity(1)
|
||||
background: transparent
|
||||
top: $object-img-size - 25px
|
||||
top: $object-img-size - 24px
|
||||
padding: 0
|
||||
|
||||
span
|
||||
|
@ -55,3 +55,18 @@ body.closet_hangers-index
|
|||
input[type=submit]
|
||||
font-size: 85%
|
||||
|
||||
&.js
|
||||
.object:hover .quantity
|
||||
input[type=number]
|
||||
width: 2.5em
|
||||
|
||||
input[type=submit]
|
||||
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-width: 100px
|
||||
$object-padding: 6px
|
||||
$object-padding: 8px
|
||||
$nc-icon-size: 16px
|
||||
|
||||
$container-top-padding: 3em
|
||||
|
||||
|
|
|
@ -4,8 +4,13 @@
|
|||
= link_to "Import closet from Neopets", new_closet_page_path, :id => 'import-link'
|
||||
- else
|
||||
- title "#{@user.name}'s Items"
|
||||
|
||||
#closet-hangers{:class => user_is?(@user) ? 'current-user' : nil}
|
||||
- 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
|
||||
- else
|
||||
- if user_is?(@user)
|
||||
|
@ -22,3 +27,7 @@
|
|||
- else
|
||||
%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;
|
||||
*display: inline;
|
||||
*vertical-align: auto;
|
||||
margin: 0.5em 0;
|
||||
padding: 0 0.5em;
|
||||
margin: 8px 0;
|
||||
padding: 0 8px;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
vertical-align: top;
|
||||
|
@ -323,11 +323,11 @@ ul.buttons li, ul.buttons li form {
|
|||
}
|
||||
/* line 190, ../../../app/stylesheets/_layout.sass */
|
||||
.object .nc-icon {
|
||||
right: 16px;
|
||||
right: 18px;
|
||||
}
|
||||
/* line 193, ../../../app/stylesheets/_layout.sass */
|
||||
.object .closeted-icon {
|
||||
left: 16px;
|
||||
left: 18px;
|
||||
}
|
||||
|
||||
/* line 196, ../../../app/stylesheets/_layout.sass */
|
||||
|
@ -610,15 +610,16 @@ body.closet_hangers-index #closet-hangers .object .quantity {
|
|||
background: white;
|
||||
padding: 2px 4px;
|
||||
position: absolute;
|
||||
left: 16px;
|
||||
left: 18px;
|
||||
line-height: 1;
|
||||
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 {
|
||||
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] {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
|
@ -630,7 +631,7 @@ body.closet_hangers-index #closet-hangers.current-user .object:hover .quantity {
|
|||
-o-opacity: 1;
|
||||
-khtml-opacity: 1;
|
||||
background: transparent;
|
||||
top: 55px;
|
||||
top: 56px;
|
||||
padding: 0;
|
||||
}
|
||||
/* 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;
|
||||
}
|
||||
/* 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;
|
||||
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] {
|
||||
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 */
|
||||
body.closet_pages-new #closet-page-form, body.closet_pages-create #closet-page-form {
|
||||
|
|
Loading…
Reference in a new issue