jQuery更新rails表格部分基于下拉列表中的选定项目 [英] jQuery updating rails form partial based on selected item in drop down

查看:59
本文介绍了jQuery更新rails表格部分基于下拉列表中的选定项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的rails应用程序中,我有一个下拉菜单,用户可以选择一个帐户进行付款:

  / /_payment.html.erb 

< div class =fieldid =payment-to-account>
<%= f.label'付款到:'%>< br>
<%= f.collection_select:to_account_id,@ liability_account_payment_list,:id,:account_details,{include_blank:'Please Select'}%>
< / div>

当用户选择一个帐户时,我会根据他们的选择在该表单内部呈现部分:

  //_payment.html.erb 
<%= form_for(@ tranaction,
as :: transaction ,
url:
@ transaction.id?account_transaction_path(@account,@ transaction):account_transactions_path)do | f | %GT;

...

<%@ f = f%>
< div id =to-account-formstyle =display:none;>< / div>

...
< script>

jQuery(function(){

$(#payment-to-account)。change(function(){
var selected_item = $( #payment-to-account选项:selected)。text();
var selected_item_index = $(#payment-to-account option:selected)。index();
//查找括号中的帐户类型后跟空格币$
var regExp = / \(([^]] +)\)\\\\ $ /;
var matches = regExp.exec (selected_item);

//按列表顺序排列的帐户ID数组
var payment_account_ids =<%= raw @payment_list_ids%> ;;

switch(匹配[1]){
案例'按揭':
$('#to-account-form')。html(<%= j render'fayment_to_mortgage',f:@f%> ;);
$('#to-account-form')。slideDown(350);
break;
case'PersonalLoan':
case'CreditCard':
案例'StudentLoan':
案例'OtherLiability':
$('#to-account-form')。html(<%= j render'dayment_to_all_other_liability',f:@f%>);
$('#to-account-form')。slideDown(350);
休息;
默认值:
$('#to-account-form')。html(< br>+联系支持,发生错误);
$('#to-account-form')。slideDown(350);
}
});

});

< / script>

现在它根据选择呈现正确的部分,但是当部分加载时我需要更多信息来自帐户模型。我创建了一个名为find_pay_to_account的方法,该方法在Accounts模型中获取输入所选帐户ID,该模型根据id查找帐户。



当用户从下拉菜单中选择并进行帐户时,我希望在加载的部分上调用该方法,以便向用户显示有关该帐户的其他信息他们在提交表格之前付款。但我不知道怎么做。我想在我的jQuery switch语句中添加类似这样的东西。

  selected_account_id = payment_account_ids [selected_item_index-1] 
@ payment_to_account = Account.find_pay_to_account(selected_account_id)

由于rails在后台预加载部分内容,因此进行以下更改对于我在案例陈述中的部分渲染仍然无法工作:



从此

  $('#to-account-form')。html(<%= j render'payment_to_mortgage',f:@f%>); 

到此

  $('#to-account-form')。html(<%= j render'payment_to_mortgage',f:@ f,@ pay_to_account:@payment_to_account%>); 

我做了一些搜索,发现使用AJAX可能会有所帮助:







解决方案

访问渲染部分中的信息而不再创建另一部分控制器动作,我收集了原始动作中可能需要的所有数据。这样我就可以得到我正在寻找的确切结果,而无需更改我的路线和执行ajax请求。



为此,我向控制器新操作添加了方法。您可以从我原来的问题中看到,我可能需要的所有帐户信息都在下拉菜单中的变量中:

  @liability_account_payment_list 

这是下拉菜单从


$获取信息的地方b $ b



该变量位于事务控制器新操作中。所以我在上面的变量之后创建了另一个在行上存储数组的变量:

  @liability_accounts_payment_list_minimum_payments = @ liability_account_payment_list.map {| account | account.minimum_payment.to_f + account.minimum_escrow_payment.to_f} 

这个新变量是一个包含所有数组的数组根据用户将从中选择的下拉菜单中列出的顺序记帐最低付款。



然后我将页面上的jQuery更改为以下

  // _ payments.html.erb 
< script>

jQuery(function(){

$(#payment-to-account)。change(function(){
var selected_item = $( #payment-to-account选项:selected)。text();
var selected_item_index = $(#payment-to-account option:selected)。index();
//查找括号中的内容后面跟着空格币$
var regExp = / \(([^]] +)\)\\\\ $ /;
var matches = regExp.exec( selected_item);

//从红宝石转换为js
var min_payments =<%= raw @liability_accounts_payment_list_minimum_payments%> ;;
//列表中的帐户的最低付款数组将js变量设置为适当的最小付款
var selected_account_min_payment = min_payments [selected_item_index-1];

switch(匹配[1]){
case'抵押贷款':
$('#to-account-form')。html(<%= j render'fayment_to_mortgage',f:@f%>);

$(#min - 付款 - 现场hidd EN)VAL(selected_account_min_payment)。
$(#min-payment-field)。html(selected_account_min_payment);

$('#to-account-form')。slideDown(350);
休息;
案例'PersonalLoan':
案例'CreditCard':
案例'StudentLoan':
案例'OtherLiability':
$('#to-account-form' ).html(<%= j render'dayment_to_all_other_liability',f:@f%>);

$(#min-payment-field-hidden)。val(selected_account_min_payment);
$(#min-payment-field)。html(selected_account_min_payment);

$('#to-account-form')。slideDown(350);
休息;
默认值:
$('#to-account-form')。html(< br>+联系支持,发生错误);
$('#to-account-form')。slideDown(350);
}
});

});

< / script>

具有min-payment-field-hidden的行是因为设置两个具有相同id的不同div不起作用。一个div用于设置hidden_​​field,另一个显示用户的值是什么。

  // _ payment.html。 erb 
< - 确保向控制器提交适当的最低付款额 - >
<%= f.hidden_​​field:amount,:id => min-payment-field-hidden%>

< div>
<%= f.label最低付款额%>
< div id =min-payment-field>< / div>
< / div>

如果查看我的switch语句,可以看到我用以下行设置了上述值: / p>

  $(#min-payment-field-hidden)。val(selected_account_min_payment); 
$(#min-payment-field)。html(selected_account_min_payment);

现在,用户可以从下拉列表中看到他们选择的特定帐户的最低付款。




In my rails app I have a dropdown menu that a user can select an account to make a payment to:

    //_payment.html.erb

     <div class="field" id="payment-to-account">
      <%= f.label 'Payment To:' %><br>
      <%= f.collection_select :to_account_id, @liability_account_payment_list, :id, :account_details, {include_blank: 'Please Select'} %>
    </div>

When the user selects a account I render a partial inside of this form based on their selection:

    //_payment.html.erb
    <%= form_for(@transaction, 
             as: :transaction,
             url: 
             @transaction.id ? account_transaction_path(@account, @transaction) : account_transactions_path) do |f| %>

    ...

    <% @f = f %>
    <div id="to-account-form" style="display:none;"></div>

    ...
    <script>

    jQuery(function(){

      $("#payment-to-account").change(function() {
        var selected_item = $( "#payment-to-account option:selected" ).text();
        var selected_item_index = $( "#payment-to-account option:selected" ).index(); 
        //looks for account type in parentheses followed by space moneysign " $"
        var regExp = /\(([^)]+)\)\s\$/;
        var matches = regExp.exec(selected_item);

    // array of account ids in order of list
    var payment_account_ids = <%= raw @payment_list_ids %>;

    switch (matches[1]) {
      case 'Mortgage':
        $('#to-account-form').html("<%= j render 'payment_to_mortgage', f: @f %>");
        $('#to-account-form').slideDown(350);
        break;
      case 'PersonalLoan':
      case 'CreditCard':
      case 'StudentLoan':
      case 'OtherLiability':
        $('#to-account-form').html("<%= j render 'payment_to_all_other_liabilities', f: @f %>");
        $('#to-account-form').slideDown(350);
        break;
      default:
        $('#to-account-form').html("<br>" + "Contact support, an error has occurred");
        $('#to-account-form').slideDown(350);
        }
      });

    });

    </script>

Right now it renders the correct partial based on the selection, but when that partial loads I need more information from the account model. I created a method called find_pay_to_account that take the input selected account id in the Accounts model that looks for the account based on the id.

When the user selects and account from the drop down, I'd like that method called on the partial that is loaded so I can show the user additional information about the account they are making a payment to before they submit the form. But I don't know how. I wanted to add something like this to my jQuery switch statement.

    selected_account_id = payment_account_ids[selected_item_index-1]
    @payment_to_account = Account.find_pay_to_account(selected_account_id)

Since rails preloads the partials in the background, making the following change to my partial render in the case statements still wont work:

From this

  $('#to-account-form').html("<%= j render 'payment_to_mortgage', f: @f %>");

To this

  $('#to-account-form').html("<%= j render 'payment_to_mortgage', f: @f, @payment_to_account: @payment_to_account %>");

I did some searching and found that with AJAX might be able to help:
Pragmatic Studio
Rails Cast

But i'm trying to access the model, not the controller and I'm trying to update a form partial. What is the correct way to do this?

Here are pics that show the user flow. An example of what I'm trying to update can be seen in the last pic. When the mortgage account is selected, it needs to show the minimum payment for the mortgage account. Right now it says zero because the partials rendering with all the information from BOA seed 0214.

解决方案

To access the information in the rendered partial without making another controller action, I collected all data I might need in the original action. That way I could get the exact result I was looking for without changing my routes and doing ajax request.

To do this I added methods to the controller new action. You can see from my original question, all accounts I may need information for are in the variable that is in the dropdown menu:

@liability_account_payment_list

This is where the dropdown menu gets its information from

That variable is in the Transaction controller new action. So I created another variable storing an array on the line after the above variable:

@liability_accounts_payment_list_minimum_payments = @liability_account_payment_list.map {|account| account.minimum_payment.to_f + account.minimum_escrow_payment.to_f}

This new variable is an array of all the accounts minimum payments in the order they are listed in the dropdown menu the user will select from.

Then I changed the jQuery on the page to the following

//_payments.html.erb
<script>

jQuery(function(){

  $("#payment-to-account").change(function() {
    var selected_item = $( "#payment-to-account option:selected" ).text();
    var selected_item_index = $( "#payment-to-account option:selected" ).index(); 
    //looks for something in parentheses followed by space moneysign " $"
    var regExp = /\(([^)]+)\)\s\$/;
    var matches = regExp.exec(selected_item);

    // array of minimum payments from accounts in list converted from ruby to js
    var min_payments = <%= raw @liability_accounts_payment_list_minimum_payments %>;
    // set the js variable to the appropriate minimum payment
    var selected_account_min_payment = min_payments[selected_item_index-1];

    switch (matches[1]) {
      case 'Mortgage':
        $('#to-account-form').html("<%= j render 'payment_to_mortgage', f: @f %>");

        $("#min-payment-field-hidden").val(selected_account_min_payment);
        $("#min-payment-field").html(selected_account_min_payment);

        $('#to-account-form').slideDown(350);
        break;
      case 'PersonalLoan':
      case 'CreditCard':
      case 'StudentLoan':
      case 'OtherLiability':
        $('#to-account-form').html("<%= j render 'payment_to_all_other_liabilities', f: @f %>");

        $("#min-payment-field-hidden").val(selected_account_min_payment);
        $("#min-payment-field").html(selected_account_min_payment);

        $('#to-account-form').slideDown(350);
        break;
      default:
        $('#to-account-form').html("<br>" + "Contact support, an error has occurred");
        $('#to-account-form').slideDown(350);
    }
  });

});

</script>

The lines that have min-payment-field-hidden are because setting two different divs with the same id does not work. One div is being used to set hidden_field, the other is showing the user what the value is.

//_payment.html.erb
<-- To make sure the appropriate minimum payment is submitted to controller -->
<%= f.hidden_field :amount, :id => "min-payment-field-hidden" %>

<div>
  <%= f.label "Minimum Payment" %>
  <div id="min-payment-field"></div>
</div>

If you look at my switch statement, you can see I set the above value with these lines:

$("#min-payment-field-hidden").val(selected_account_min_payment);
$("#min-payment-field").html(selected_account_min_payment);

Now the user can see the minimum payment for the specific account they choose from the dropdown.

这篇关于jQuery更新rails表格部分基于下拉列表中的选定项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆