Rails 2.2 プロジェクトでは、ユーザーにプロジェクトのリストをポートフォリオ オブジェクト (つまり: ) にまとめてもらいますPortfolioHasManyProjects
。このページには、通常のテキスト、タイトルなどの Rails フォームと、2 つの並べ替え可能なリストがあります。リストは、プロジェクトをグローバル プロジェクト リストからポートフォリオ プロジェクト リストにドラッグするために使用されます。
ここで行われていることと似ています: http://ui.jquery.com/latest/demos/functional/#ui.sortable。
変更時にポートフォリオ リスト (#drag_list) を更新し、AJAX 呼び出しを介してシリアル化されたデータを送信します。 これは application.js ファイルで行われます。
jQuery.ajaxSetup({
'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
})
jQuery.fn.submitDragWithAjax = function() {
this.submit(function() {
$.post(this.action, $("#drag_list").sortable('serialize'), null, "script");
return false;
})
return this;
};
$(document).ajaxSend(function(event, request, settings) {
if (typeof(AUTH_TOKEN) == "undefined") return;
// settings.data is a serialized string like "foo=bar&baz=boink" (or null)
settings.data = settings.data || "";
settings.data += (settings.data ? "&" : "") + "authenticity_token=" + encodeURIComponent(AUTH_TOKEN);
});
/-------------------------------------------/
$(document).ready(function(){
$(".ajax_drag").submitDragWithAjax();
$("#drag_list").sortable({
placeholder: "ui-selected",
revert: true,
connectWith:["#add_list"],
update : function () {
$("#drag_list").submit();
}
});
$("#add_list").sortable({
placeholder: "ui-selected",
revert: true,
connectWith:["#drag_list"]
});
ここで問題が発生しました。シリアル化されたデータをどのように処理し、フォームと共にnew.html.erb
ファイル内のコントローラーに送信するかがわかりませんでした。だから私がしたことは、コントローラーで抽出するデータnew.js.erb
に非表示のフォームフィールドを挿入することでした。new.html.erb
ここに new.js.erb があります:
$("#projects").html("");
<% r = params[:proj] %>
<% order=1 %>
<% for i in r %>
$("#projects").append("<input type=hidden name=proj[<%=order%>] value=<%=i%> />");
<% order=order+1 %>
<% end %>
new.html.erb を編集します。
<h1>New portfolio</h1>
<h2>The List</h2>
<div class="list_box">
<h3>All Available Projects</h3>
<%= render :partial => "projects/add_list" %>
</div>
<div class="list_box">
<h3>Projects currently in your new portfolio</h3>
<%= render :partial => "projects/drag_list" %>
</div>
<div style="clear:both"></div>
<br/>
<br/>
<h2>Portfolio details</h2>
<% form_for(@portfolio) do |f| %>
<%= f.error_messages %>
<h3>Portfolio Name</h3>
<p>
<%= f.text_field :name %>
</p>
<h3>URL</h3>
<p>
<%= f.text_field :url %>
</p>
<h3>Details</h3>
<p>
<%= f.text_area :details %>
</p>
<p>
<div id="projects">
<input type="hidden" name="proj" value="" />
</div>
<%= f.submit "Create" %>
</p>
<% end %>
次に、フォームはポートフォリオ コントローラーの create メソッドに送信されます。
def new
@projects = Project.find(:all)
@portfolio = Portfolio.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @portfolio }
format.js
end
end
def create
@portfolio = Portfolio.new(params[:portfolio])
proj_ids = params[:proj]
@portfolio.projects = []
@portfolio.save
proj_ids.each {|key, value| puts "Key:#{key} , Value:#{value} " }
proj_ids.each_value {|value| @portfolio.projects << Project.find_by_id(value) }
respond_to do |format|
if @portfolio.save
flash[:notice] = 'Portfolio was successfully created.'
format.html { render :action => "index" }
format.xml { render :xml => @portfolio, :status => :created, :location => @portfolio }
else
format.html { render :action => "new" }
format.xml { render :xml => @portfolio.errors, :status => :unprocessable_entity }
end
end
end
最後に私の質問:
これはこれを行う適切な方法ですか?なんらかの理由でそうではないと感じています.Railsで他のすべてを行うのはとても簡単で直感的だと思われたからです. これは機能しますが、それを実現するのは地獄でした。AJAX 呼び出しを介してシリアル化されたデータをコントローラーに送信する、より洗練された方法が必要です。
同じページで異なる AJAX アクションを呼び出すにはどうすればよいですか? ソート可能でオートコンプリートの AJAX 呼び出しがあったとしましょう。任意のファイルから and を呼び出すことができますか
sortable.js.erb
?autocomplete.js.erb
これに応答するようにコントローラーをセットアップする方法がわかりません。