0

I am trying to get a script to assign the value of product_id when the form is submitted. My script now always assigns the value as 1. I need it to assign the product_id of the product. I have noticed that when I submit it will actually change the selection to the one that is equal to id 1, so did I mess up the script where it rewrites to 1?

Here is a JSFiddle where it seems to work fine there in html but not in my ruby code.

Script:

$(function(){
$("#commit").on("click", function(){
    var valueAssigned = false;
    $('select').each(function(){
        if($(this).val())
        {
            $("[name='question[product_id]']").val($(this).val());
            valueAssigned = true;
            return;
        }
    });
});
});

Form: Note that only one of the collection_select is shown based on the category selected. A script shows and hides them based on the selection.

<%= form_for @question, url: new_tf_question_path(@question) do |f| %>

<%= render 'shared/error_questions' %>

<%= f.label :category %><br>
<%= f.select :category, [ ["IP Voice Telephony", "ip_voice"], ["IP Video Surveillance", "ip_video_surveillance"], ["IP Video Telephony", "ip_video_telephony"], ["Enterprise Gateways", "enterprise_gateways"], ["Consumer ATAs", "consumer_atas"], ["IP PBX", "ip_pbx"] ], {prompt: "Select Category"}, class: "input-lg", :id => "category" %>

<div id="ip_voice">
<%= f.label :product_id %><br>
<%= f.collection_select :product_id, Product.where({ category: "ip_voice" }), :id, :name, {prompt: "Select a product"}, {class: "form-control input-lg", id: "question_product_id1", name: "voice"} %>
</div>

<div id="ip_video_surveillance">
<%= f.label :product_id %><br>
<%= f.collection_select :product_id, Product.where({ category: "ip_video_surveillance" }), :id, :name, {prompt: "Select a product"}, {class: "form-control input-lg", id: "question_product_id2", name: "surv"} %>
</div>

<div id="ip_video_telephony">
<%= f.label :product_id %><br>
<%= f.collection_select :product_id, Product.where({ category: "ip_video_telephony" }), :id, :name, {prompt: "Select a product"}, {class: "form-control input-lg", id: "question_product_id2", name: "video"} %>
</div>

<div id="consumer_atas">
<%= f.label :product_id %><br>
<%= f.collection_select :product_id, Product.where({ category: "consumer_atas" }), :id, :name, {prompt: "Select a product"}, {class: "form-control input-lg", id: "question_product_id3", name: "atas"} %>
</div>

<div id="enterprise_gateways">
<%= f.label :product_id %><br>
<%= f.collection_select :product_id, Product.where({ category: "enterprise_gateways" }), :id, :name, {prompt: "Select a product"}, {class: "form-control input-lg", id: "question_product_id4", name: "gate"} %>
</div>

<div id="ip_pbx">
<%= f.label :product_id %><br>
<%= f.collection_select :product_id, Product.where({ category: "ip_pbx" }), :id, :name, {prompt: "Select a product"}, {class: "form-control input-lg", id: "question_product_id5", name: "pbx"} %>
</div>

<input id="targetField" type="hidden" name="question[product_id]" value="0"/>

<%= f.label :section %><br>
<%= f.collection_select :section, @sections, :id, :name, {prompt: "Select a section"}, {class: "form-control input-lg" } %>

<%= f.label :active %><br>
<%= f.check_box :active %>


<%= f.fields_for :answers do |builder| %>

<%= render 'tf_answers', :f => builder %>

<% end %>

<%= f.submit "Create Question", class: "btn btn-lg btn-primary", id: "commit", style: "margin-top: 45px;" %>

<% end %>

I am not skilled in javascript so any help is appreciated.

EDIT

QuestionController

def new
@question = Question.new    
@products = Product.all
end
def new_mc
@sections = Section.all
@question = Question.new
4.times { @question.answers.build }
end
def new_tf
@sections = Section.all
@question = Question.new
@question.answers.build
end

# GET /questions/1/edit
def edit
@sections = Section.all
end

# POST /questions
# POST /questions.json
def create

if params[:ip_video_telephony_product_id] != nil
  params[:product_id] = params[:ip_video_telephony_product_id]
end
 #:enterprise_gateways_product_id, :ip_video_surveillance_product_id, :ip_voice_product_id, :consumer_atas_product_id
@question = Question.new(question_params + params[:product_id]) 
respond_to do |format|
  if @question.save
    @answer = Answer.find_by_question_id(@question.id)
    if @answer.option == "True"
      Answer.create(option: "False", question_id: @answer.question_id, correct: false)
    end
    if @answer.option == "False"
      Answer.create(option: "True", question_id: @answer.question_id, correct: false)
    end
    format.html { redirect_to @question, notice: 'Question was successfully created.' }
    format.json { render action: 'show', status: :created, location: @question }
  else
    format.html { render action: 'new' }
    format.json { render json: @question.errors, status: :unprocessable_entity }
  end
end
end
....
def question_params
  params.require(:question).permit(:ip_video_telephony_product_id, :enterprise_gateways_product_id, :ip_video_surveillance_product_id, :ip_voice_product_id, :consumer_atas_product_id, :section, :content, :question_type, :category, :product_id, :active, :user_id, answers_attributes: [ :option, :correct, :question_id ] ).
  merge user_id: current_user.id
end  

Log:

Started POST "/tf_question" for 127.0.0.1 at 2014-09-19 17:09:59 -0700
Processing by QuestionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"x", "question"=>{"question_type"=>"TF", "content"=>"damn", "category"=>"ip_video_telephony", "section"=>"1", "active"=>"1", "answers_attributes"=>{"0"=>{"correct"=>"1", "option"=>"True"}}}, "voice"=>"", "surv"=>"", "video"=>"20", "atas"=>"", "gate"=>"", "pbx"=>"", "commit"=>"Create Question"}
User Load (2.6ms)  SELECT  "users".* FROM "users"  WHERE "users"."remember_token" = 'x' LIMIT 1
(0.1ms)  begin transaction
(0.0ms)  rollback transaction
Completed 500 Internal Server Error in 23ms

New form: I only changed all of theses and removed the script.

<div id="ip_voice">
<%= f.label :product_id %><br>
<%= f.collection_select :ip_voice_product_id, Product.where({ category: "ip_voice" }), :id, :name, {prompt: "Select a product"}, {class: "form-control input-lg", id: "question_product_id1", name: "voice"} %>
</div>

1 Answer 1

1

Although I'm not in favor of your current form arrangement, but since you say that only one select would be visible, you can use the :visible selector of jQuery. You can change your JS click handler to something like this, assuming you added a question_product_id class to all of these select elements

var value = $('select.question_product_id:visible').val();
$("[name='question[product_id]']").val(value);

However, if it was me writing such form, I wouldn't bother setting the select value using a JS code, but I would add bunch of instance attribute to the question model (e.g. ip_video_telephony_product_id) and use them for the f.collection_select :ip_video_telephony_product_id call, then in the controller or the model I figure which value I should use based on category value, something like that.

Example

The model would be something like this

class Question < ActiveRecord::Base
   attr_accessor :ip_video_telephony_product_id, :enterprise_gateways_product_id # etc ...
end

The selects in the form should look like this

<div id="enterprise_gateways">
 <%= f.label :ip_video_telephony_product_id %><br>
 <%= f.collection_select :ip_video_telephony_product_id, Product.where({ category: "enterprise_gateways" }), :id, :name, {prompt: "Select a product"}, {class: "form-control input-lg"} %>
</div>

Since attribute names are consistent, we can do something like this in the controller (I prefer the model, but we're keeping it simple for now)

def create
  @question = Question.new(question_params)
  @question.product_id = question_params["#{question_params[:category]}_product_id"]
  # ...
end
Sign up to request clarification or add additional context in comments.

1 Comment

Works great, I had to remove the html settings name in the form as you mentioned.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.