繁体   English   中英

Rails-从表单选择下拉列表中向控制器传递参数

[英]Rails - pass a parameter to controller from form select dropdown

我有2个模型: TeamQuest 创建新团队时,我会下拉所有任务。 选择任务后,我要显示有关任务的信息。

我的理解是,表单中的所有内容都在客户端,并且需要AJAX才能将选定的任务传递到服务器端。 我的代码基于 Stack Overflow答案。

这是我构造表单的方式:

app / views / teams_form.html.erb

<%= form_for(@team) do |f| %>
  <fieldset>
    <ol>
      <li>
        <%= f.label :name %>
        <%= f.text_field :name %>
      </li>
      <li>
        <%= f.label :quest_id %>
        <%= f.select :quest_id, 
                     options_from_collection_for_select(@quests, :id, :name), 
                     {}, {remote: true, url: '/teams/new', method: 'get'} %>
      </li>
      <% if @x != nil && @x.id != nil %>
        <li><%= @x.id %></li>
      <% end %>
    </ol>
    <p>
      <%= f.submit %>
    </p>
  </fieldset>
<% end %>

app / controllers / team_controller.rb

def new
  @team = Team.new
  @quests = Quest.all
  respond_to do |format|
    if params[:quest_id] != nil
      @x = Quest.find(params[:quest_id])
    end
    format.html #new.html.erb
    format.json
    format.js
  end
end

我的目标是通过:quest_id从表单参数的@x变量和使用形式。

这什么也没产生。 我没有在控制器中获取参数,也不确定要丢失什么。

按照共享的描述,您似乎无法从下拉列表中获取所选项目的值。

下面提到的代码用于从下拉列表中选择值,您也可以使用浏览器的开发人员工具进行检查。

quest = $("#quest_id").val();

注意:假设选择器ID为quest_id,请根据您的表单进行更改。

现在,您可以使用下面提到的代码来调用ajax。

$.ajax({
  type: "GET",
  url: "/teams/new",
  data:{ quest_id: quest },
  dataType: "json",
  success:function(data){
    # logic for using ajax result
  }

希望能帮助到你!!

终于解决了这个问题,如果有人看到并遇到相同的问题,我想发表一下:

我提出了一个单独的AJAX请求,因为有人建议

app / views / teams_form.html.erb

<script>
   $(document).ready(function() {
    $('#team_quest_id').change(function() {
       $.ajax({
         url: "/teams/new",
         data: {quest_id: $("#team_quest_id option:selected").val()},
         dataType: "script",
         method: "get",
         success: function(r){}
       });
     });
   });
</script>

我移动了参数分配的位置

app / controllers / team_controller.rb

def new
  @team = Team.new
  @quests = Quest.all
  if params[:quest_id] != nil
    @x = Quest.find(params[:quest_id])
  end
  respond_to do |format|
    format.html #new.html.erb
    format.json
    format.js
  end
end

最重要的是-我创建了一个js文件来呈现表单

app / views / new.js.erb

$('#new_team').html("<%= j (render 'form') %>");

这部影片非常有帮助

您问题中的代码几乎是正确的,您忘记了将属性嵌套在data中

<% # app/views/teams_form.html.erb %>

<%= f.select :quest_id, 
                     options_from_collection_for_select(@quests, :id, :name), 
                     {}, {remote: true, url: '/teams/new', method: 'get'} %>
<% # should be: %>
<%= f.select :quest_id, 
                     options_from_collection_for_select(@quests, :id, :name), 
                     {}, {data: {remote: true, url: '/teams/new', method: 'get'}} %>
<% # or even better, use the path helper instead of the hard coded path %>
<%= f.select :quest_id, 
                     options_from_collection_for_select(@quests, :id, :name), 
                     {}, {data: {remote: true, url: new_team_path, method: :get}} %>

正确设置属性后,我们仍然需要进一步修复表单。 在页面请求中,浏览器将请求该表单,但是将永远不会设置@x 由于不会将ERB发送给客户端,因此我们需要添加一个句柄以找到我们的任务容器元素。

<% # app/views/teams_form.html.erb %>

<% if @x != nil && @x.id != nil %>
  <li><%= @x.id %></li>
<% end %>
<% # should be something like %>
<li id="quest-info-container"></li>

现在,在控制器中,将HTML请求与JS请求分开。

# app/controllers/teams_controller.rb

def new
  respond_to do |format|
    format.html do
      @team = Team.new
      @quests = Quest.all
    end
    format.js do
      @quest = Quest.find(params.dig(:team, :quest_id))
    end
  end
end

通过将选择数据路径发送到另一个用于处理任务预览的URL,可以简化上述操作。

现在我们需要在容器中渲染预览,为此我们需要2个文件,首先是结果结构的外观。 请记住,这将在容器内部呈现。

<% # app/views/teams/_quest_preview.html.erb %>

<% # Here comes what you want to display about the quest. You can give this %>
<% # file another name if you like. You have @quest to your disposal here. %>
<%= @quest.id %> <strong><%= @quest.name %></strong>

现在,我们只需要一个JavaScript文件即可将上述结构加载到我们创建的句柄中。

<% # app/views/teams/new.js.erb %>

handle = document.getElementById('quest-info-container');
handle.innerHTML = '<%= j render('quest_preview') %>';

jescape_javascript的别名。 如果局部文件不在同一目录中,请使用<%= j render('other_dir/some_partial') %>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM