Move closet-hangers-update form from partial to JS

We lose no-JS support, which I kinda miss, but caching is gonna be more
important down the line. Delete form moves next, then we cache.

CSRF token changes: it looks like, by setting a data attribute in AJAX, I
was overwriting the CSRF token. I don't remember it working that way, but
now we use beforeSend to add the X-CSRF-Token header instead, which is nicer,
anyway. The issue might've been something else, but this worked :/

The CSS was also not showing the loading ellipsis properly. I think that's a
dev-only issue in how live assets are being served versus static assets, but
may as well add UTF-8 charset directives everywhere, anyway.
This commit is contained in:
Emi Matchu 2013-06-22 15:27:00 -07:00
parent f1aca20185
commit 2876de2db0
6 changed files with 73 additions and 33 deletions

View file

@ -1,9 +1,10 @@
(function () { (function () {
var csrf_param = $('meta[name=csrf-param]').attr('content'), var CSRFProtection = function (xhr) {
csrf_token = $('meta[name=csrf-token]').attr('content'), var token = $('meta[name="csrf-token"]').attr('content');
data = {}; if(token) xhr.setRequestHeader('X-CSRF-Token', token);
};
data[csrf_param] = csrf_token; $.ajaxSetup({
beforeSend: CSRFProtection
$.ajaxSetup({data: data}); });
})(); })();

View file

@ -64,6 +64,42 @@
*/ */
var body = $(document.body).addClass("js");
if(!body.hasClass("current-user")) return false;
// When we get hangers HTML, add the controls. We do this in JS rather than
// in the HTML for caching, since otherwise the requests can take forever.
// If there were another way to add hangers, then we'd have to worry about
// that, but, right now, the only way to create a new hanger from this page
// is through the autocompleter, which reinitializes anyway. Geez, this thing
// is begging for a rewrite, but today we're here for performance.
$("#closet-hanger-update-tmpl").template("updateFormTmpl");
onHangersInit(function () {
// Super-lame hack to get the user ID from where it already is :/
var currentUserId = itemsSearchForm.data("current-user-id");
$("#closet-hangers div.closet-hangers-group").each(function () {
var groupEl = $(this);
var owned = groupEl.data("owned");
groupEl.find("div.closet-list").each(function () {
var listEl = $(this);
var listId = listEl.data("id");
listEl.find("div.object").each(function () {
var hangerEl = $(this);
var hangerId = hangerEl.data("id");
var quantityEl = hangerEl.find("div.quantity");
var quantity = hangerEl.data("quantity");
$.tmpl("updateFormTmpl", {
quantity: quantity,
list_id: listId,
owned: owned,
user_id: currentUserId,
closet_hanger_id: hangerId
}).appendTo(quantityEl);
});
});
});
});
$.fn.liveDraggable = function (opts) { $.fn.liveDraggable = function (opts) {
this.live("mouseover", function() { this.live("mouseover", function() {
if (!$(this).data("init")) { if (!$(this).data("init")) {
@ -72,9 +108,6 @@
}); });
}; };
var body = $(document.body).addClass("js");
if(!body.hasClass("current-user")) return false;
$.fn.disableForms = function () { $.fn.disableForms = function () {
return this.data("formsDisabled", true).find("input").attr("disabled", "disabled").end(); return this.data("formsDisabled", true).find("input").attr("disabled", "disabled").end();
} }

View file

@ -1,3 +1,5 @@
@charset "UTF-8"
@import compass @import compass
@import partials/clean/constants @import partials/clean/constants

View file

@ -1,18 +1,10 @@
- show_controls ||= false # we could do user check here, but may as well do it once - show_controls ||= false # we could do user check here, but may as well do it once
%div{'class' => closet_hanger_partial_class(closet_hanger), 'data-item-id' => closet_hanger.item_id, 'data-quantity' => closet_hanger.quantity} %div{'class' => closet_hanger_partial_class(closet_hanger), 'data-item-id' => closet_hanger.item_id, 'data-quantity' => closet_hanger.quantity, 'data-id' => closet_hanger.id}
= render :partial => 'items/item_link', :locals => {:item => closet_hanger.item} = render :partial => 'items/item_link', :locals => {:item => closet_hanger.item}
.quantity{:class => "quantity-#{closet_hanger.quantity}"} .quantity{:class => "quantity-#{closet_hanger.quantity}"}
%span= closet_hanger.quantity %span= closet_hanger.quantity
- if show_controls
= 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
= f.number_field :quantity, :min => 0, :required => true
= f.submit t('.submit')
- if show_controls - if show_controls
= form_tag [current_user, closet_hanger], :method => :delete, :class => 'closet-hanger-destroy' do = form_tag [current_user, closet_hanger], :method => :delete, :class => 'closet-hanger-destroy' do
= return_to_field_tag = return_to_field_tag
= hidden_field_tag 'closet_hanger[owned]', closet_hanger.owned = hidden_field_tag 'closet_hanger[owned]', closet_hanger.owned
= submit_tag t('.delete') = submit_tag t('.delete')

View file

@ -73,23 +73,34 @@
= render_unlisted_closet_hangers(owned) = render_unlisted_closet_hangers(owned)
%span.empty-list= t '.unlisted.empty' %span.empty-list= t '.unlisted.empty'
- localized_cache :action_suffix => 'autocomplete_tmpls' do - if user_signed_in?
%script#autocomplete-item-tmpl{:type => 'text/x-jquery-tmpl'} - localized_cache action_suffix: 'tmpls' do
%script#autocomplete-item-tmpl{type: 'text/x-jquery-tmpl'}
%a %a
= t '.autocomplete.add_item_html', :item_name => '${item_name}' = t '.autocomplete.add_item_html', item_name: '${item_name}'
%script#autocomplete-add-to-list-tmpl{:type => 'text/x-jquery-tmpl'} %script#autocomplete-add-to-list-tmpl{type: 'text/x-jquery-tmpl'}
%a %a
= t '.autocomplete.add_to_list_html', :list_name => '${list_name}' = t '.autocomplete.add_to_list_html', list_name: '${list_name}'
%script#autocomplete-add-to-group-tmpl{:type => 'text/x-jquery-tmpl'} %script#autocomplete-add-to-group-tmpl{type: 'text/x-jquery-tmpl'}
%a %a
= t '.autocomplete.add_to_group_html', :group_name => '${group_name}' = t '.autocomplete.add_to_group_html', group_name: '${group_name}'
%script#autocomplete-already-in-collection-tmpl{:type => 'text/x-jquery-tmpl'} %script#autocomplete-already-in-collection-tmpl{type: 'text/x-jquery-tmpl'}
%span %span
= t '.autocomplete.already_in_collection_html', = t '.autocomplete.already_in_collection_html',
:collection_name => '${collection_name}' collection_name: '${collection_name}'
%script#closet-hanger-update-tmpl{type: 'text/x-jquery-tmpl'}
-# Gotta do this weird subbing in the path, since the braces will be
-# escaped if they themselves are inserted. Probably deserves a more
-# legit method, especially if we ever need it again.
= form_tag user_closet_hanger_path(user_id: '$0', id: '$1').sub('$0', '${user_id}').sub('$1', '${closet_hanger_id}'), method: :put, authenticity_token: false, class: 'closet-hanger-update' do
= hidden_field_tag 'closet_hanger[list_id]', '${list_id}'
= hidden_field_tag 'closet_hanger[owned]', '${owned}'
= number_field_tag 'closet_hanger[quantity]', '${quantity}',
min: 0, required: true
- content_for :stylesheets do - content_for :stylesheets do
= stylesheet_link_tag 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.0/themes/south-street/jquery-ui.css' = stylesheet_link_tag 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.0/themes/south-street/jquery-ui.css'

View file

@ -1,6 +1,7 @@
!!! 5 !!! 5
%html %html
%head %head
%meta{charset: 'utf-8'}
%title %title
- if content_for? :title - if content_for? :title
= yield :title = yield :title