2012-02-28 25 views
1

我想知道是否可以在的edit.erb頁面中有form_for標籤而不是標籤。因爲我有一個帶有兩個attrib的Counter模型,我想單獨更新它們,基於按下的按鈕,它位於值的旁邊。我能夠使用<%= form.submit 'up_a' %> &檢查哪個按鈕被按下更新方法,像做在軌:需要類似羅德的form_for標籤的導軌

def update  
    @counter = Counter.find(params[:id]) 
    if params[:commit] == 'up_a'  
    update_attri1 # simple increment method for attrib 1 
    elsif params[:commit] == 'up_b'  
    update_attri2 # simple increment method for attrib 2 
    end 
end 

,並調用該方法來更新該值。

所以我想要更多的控制什麼屬性我想更新基於 在窗體中的點擊。無論如何,我可以在羅德島實現這一目標嗎?

回答

1

編輯:

普遍的問題似乎是要兩個提交按鈕在一個單一的形式,其中的每一個應該做的兩個稍微不同的事情。

如果你只有兩個不同的值和一個提交按鈕,最簡單的解決方案就是製作兩個表單,這兩個表單都調用def(通過它們的action-attribute),但每個都有其特定的查詢參數的值(在本例中爲「提交」)。這些調用將有以下形式:

<form method="POST" class="myForm" action="<%=url_for :controller => :Counter, :action => :update, :query => {:commit => 'up_a'}%>"> 

但是,如果你只想要一個單一的形式(可能還與許多其他的輸入值),有幾種不同的方式來做到這一點。在下面,您將看到一種實現方法的詳細實現。

在這個解決方案中,您的按鈕不應該是提交按鈕,而是常規按鈕(它們是如何用jQuery Mobile製作的)。

爲了使這個解決方案的工作,你將需要使用一些JavaScript。因此,您應該將以下javascript函數添加到application.js,並將其包含在您的layout.erb中。

function submitForm(formClass){ 
    var activeForm = 'div.ui-page-active '+formClass; 
    $(activeForm).submit(); 
} 
function callCounterSetUpdateAction(c){ 
    $.get('/app/Counter/setUpdateAction', { commit: c}); 
} 

現在我們已經所需的JavaScript函數的地方,讓我們一起來看看edit.erb

在這個例子中,Counter有三個不同的屬性:a,b和c。但是,我們只會關注a和b。

您的edit.erb文件中的表單應與下面的實施類似。注意,表單實際上沒有提交按鈕(我們稍後會看到,提交實際上是通過我們的javascript函數submitForm(formClass))完成的。

<form method="POST" class="myForm" action="<%= url_for :action => :update %>"> 
    <input type="hidden" name="id" value="<%= @counter.object %>"/> 

     <div data-role="fieldcontain"> 
     <label for="counter[a]" class="fieldLabel">A</label> 
     <input type="text" id="counter[a]" name="counter[a]" value="<%= @counter.a %>" <%= placeholder("A") %> /> 
     </div> 

     <div data-role="fieldcontain"> 
     <label for="counter[b]" class="fieldLabel">B</label> 
     <input type="text" id="counter[b]" name="counter[b]" value="<%= @counter.b %>" <%= placeholder("B") %> /> 
     </div> 

     <div data-role="fieldcontain"> 
     <label for="counter[c]" class="fieldLabel">C</label> 
     <input type="text" id="counter[c]" name="counter[c]" value="<%= @counter.c %>" <%= placeholder("C") %> /> 
     </div> 
     <a data-role="button" data-transition="none" href="javascript:callCounterSetUpdateAction('up_a');">Update A</a> 
     <a data-role="button" data-transition="none" href="javascript:callCounterSetUpdateAction('up_b');">Update B</a> 
</form> 

現在,我們已經定義了我們的觀點(edit.erb)讓我們來看看定義,我們需要我們的控制器。

Firsly,因爲它可以從href屬性上的按鈕,一旦我們按下一個按鈕,它調用javascript函數進而調用控制器以下def實際發生的事情中可以看出:

def setUpdateAction 
    $pressedButton = @params['commit'] 
    WebView.execute_js("submitForm('.myForm');") 
end 

這個def的目的是存儲我們從我們的按鈕發送的參數,然後在活動頁面上提交表單。請注意,我們在上面顯示的表單中添加了一個名爲myFormclass。你還應該注意到我們確保只有活動頁面上的表單通過在我們的formClass的jQuery選擇中加入'div.ui-page-active '來選擇。

最後,讓我們來看看你update定義應該如何看起來像:

def update 
@counter = Counter.find(@params['id']) 
c = @params['counter'] 
if @counter 
    if $pressedButton == 'up_a' 
    # Update value A. 
    @counter.update_attributes(
     {"a" => c['a']} 
    ) 
    elsif $pressedButton == 'up_b' 
    # Update value B. 
    @counter.update_attributes(
       {"b" => c['b']} 
      ) 
    end 
end 
redirect :action => :index 
end 

這裏應該注意到,我們選擇哪個屬性來更新基於我們通過setUpdateAction分配$pressedButton變量。作爲最終評論,我們也可以更新多個屬性,如下所示(我們也在這裏更新'c'屬性)。

@counter.update_attributes(
       {"b" => c['b'],"c" => c['c']} 
      ) 
+0

它不工作...你可以試試看嗎? – uday 2012-02-29 20:48:09

+0

你在'def'中接收參數嗎?如果是這樣,您可能只需刷新頁面。無論哪種情況,您的[這裏](https://github.com/rhomobile/rhomobile-docs/blob/master/docs/rhodes/application.txt)都是對使用url_for和:link_to語句的一些高級方法的參考。 – corthmann 2012-02-29 21:29:34

+0

如果你需要刷新你的頁面並想避免它,你可以編寫一個簡單的javascript函數,你可以直接從你的控制器執行參數,如下所示:'WebView.execute_js(「incrementField('a');」) '。 – corthmann 2012-02-29 21:35:00