I am appending different inputs depending on the user's actions on my form. If the user clicks on the "list" radio button, I want to display nested inputs for possibilities
. I am trying to use the cocoon gem which enables to create dynamically input fields. My form looks like this :
<%= form_for([@issue, @question]) do |f| %>
<%= f.label :content %>
<%= f.text_area :content%>
<br>
<%= f.fields_for :answer do |a| %>
<%= a.label "Answer Type :" %>
<br>
<% Answer.answer_type.options.each do |option| %>
<%= a.label option.first %>
<%= a.radio_button :answer_type, option.first, class: "answer_type" %>
<br>
<% end -%>
<div class="question_list"></div>
<% end -%>
<%= f.submit %>
<ul>
<% @question.errors.full_messages.each do |message| %>
<li><%= message%></li>
<% end -%>
</ul>
<% end %>
And this is the JS displaying different partials depending on where the user clicks :
<%= content_for(:after_js) do %>
<script>
$(document).ready(function(){
$(".answer_type").click(function(){
var value = $(this).val();
console.log(value);
if (value == "Yes/no") {
$(".question_list").empty();
$(".question_list").append("<%= j render 'questions/type/yes_no' %>");
}
else if (value == "List") {
$(".question_list").empty();
$(".question_list").append("<%= j render 'questions/type/list', a:a %>");
}
});
})
</script>
<% end -%>
if the user clicks on the checkbox "list", I am displaying this partial which needs the a
variable to be built:
<%= a.fields_for :possibilities do |possibility| %>
<%= render 'possibilities/possibility_fields', a: possibility%>
<div class="links">
<%= link_to_add_association 'add possibility', a, :possibilities %>
</div>
<% end -%>
Problem is the js:
else if (value == "List") {
$(".question_list").empty();
$(".question_list").append("<%= j render 'questions/type/list', a:a %>");
triggers an error
undefined local variable or method `a' for #<#<Class:0x007fb5d4786568>:0x007fb5d59c2808>
because I believe a
is not built yet when the JS is read.
How can I bypass this and build dynamically my nested fields when the user clicks on "list" radio button ?
There seems to be a confusion between server-side rendering and client side rendering here:
This means that you can't render any ERB with Javascript.
More precisely, when your ruby app tries to render $(".question_list").append("<%= j render 'questions/type/list', a:a %>");
, it tries to render the partial right away, before sending the response to the client. Since the a
variable is only defined in your <%= f.fields_for :answer do |a| %>
block, it raises the error you see.
Bottom line is, to do some real rendering on the client side, you'll probably need a rendering library such as ReactJS.