Making a dropdown and getting the value in Rails - ruby-on-rails

I have a many-to-many relation between my User model and my Project model for the purpose of assigning projects to users. I'm now trying to impement the feature for actual assignment using a dropdown containing the projects on the edit user page. My code looks like this, but I can't seem to figure out how send the selected value back to the controller once the button is clicked:
<div class="input-group my-2">
<%= collection_select('user', 'project', Project.all, :id, :name, include_blank: true) %>
<div class="input-group-append">
<%= link_to '<div class="btn btn-outline-primary">Toggle access to selected project</div>'.html_safe, toggle_project_access_user_url %>
</div>
</div>
I've tried using the suggestions for JS I've found, but I think I'm missing some knowlegde on how to implement the functionality completely with those.

Working with Javascript in Rails covers this.
Use form_with to set up a form with data-remote=true. Then proceed as normal.
form_with url: toggle_project_access_user_url, method: :patch do |f|
f.collection_select(:project_id, Project.all, :id, :name, include_blank: true)
f.submit("Toggle access to selected project")
end
This will send a POST to toggle_project_access_user_url with a hidden _method input indicating it's a PATCH. Use a hook on ajax:success to update the page.

Related

How to have multiple, separate, instances of Trix / ActionText rich text areas on the same page?

I have a list of commentable models in my Rails view, represented by cards that each have their own comment form. The forms are identical (from the same partial), and have a rich_text_area for the commentable's body (defined as has_rich_text :body on the model, per the docs). It is close to the following (simplified) example:
<% #assignables.each do |assignables| %>
<!-- omitted code displaying the assignable object -->
<!-- ADD COMMENT FORM -->
<%= form_with model: Comment.new do |form| %>
<div class="">
<%= form.hidden_field :commentable_id, value: assignable.id %>
<%= form.hidden_field :commentable_type, value: assignable.class.name %>
<%= form.rich_text_area :body, data: { controller: "mentions" } %>
<%= form.submit "Submit", class: "button button-primary" %>
</div>
<% end %>
<% end %>
Only the first form on the page (in DOM order) actually submits a body parameter. Network requests from any other form shows a blank comment[body] parameter. Additionally, if I add text to the 2nd form's input, then go back and submit the first form without touching it, the submission includes the input I entered into the 2nd form.
From this, I understand I need to override some attribute which is supposed to be unique. I've scoured the Rails docs and the Trix docs, but I haven't found anything which indicates how to make Rails do this override such that Trix accepts it.
What attribute do I override, and how?
Turns out, the answer is simple: override the id attribute of the rich text area to include a unique value like a primary key, and Rails handles the rest.
E.g.:
<%= form.rich_text_area :body, data: { controller: "mentions" },
id: "commentable_#{commentable.id}_comment" %>
Translates to:
<form …>
<input id="commentable_1_comment" value="Editor content goes here" type="hidden" name="content">
<trix-editor input="commentable_1_comment"></trix-editor>
</form>
Now every instance of the text area has a unique ID (rather than the generic new_comment) and the hidden inputs all submit their values correctly.
For reference: The Trix documentation show what the HTML is supposed to look like at the after ERB is done with it, but the Rails rich_text_area docs don't indicate anything about attributes you might want to override.

How to determine button id in another view depending on a different view Rails

I'm making an app where some activities are listed in a table called Fakultety (polish language, sorry), and participants on in another table called Uczestnicy.
I have a submit form where you can submit yourself to an activity, but I'm stuck on passing values to a DB. Firstly, I don't know how to tell to the database on which activity you want to be assigned to (I tried to change the submit button id to an activity id and then passing it into a database but don't know how to do this id: "#{#fakultet.id}" not working) and later I want to count how many people are assigned to field participants in a database Fakultety, but I don't want to pass all the data, just ID of the users from table called Uczestnicy. How to do it? I mean just to pass the ids to another table, and how to tell the database on which activity I want to be assigned to?
This is my form view:
<h1>Zapisujesz sie na fakultet</h1>
<div class="form-group">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#participant, url: zapisy_path) do |f| %>
<p>Imię:</p>
<%= f.text_field :firstName, class: 'form-control' %>
<p>Nazwisko:</p>
<%= f.text_field :lastName, class: 'form-control' %>
<p>Grupa:</p>
<%= f.text_field :group, class: 'form-control' %>
<%= f.submit "Zapisz się", class: "btn btn-primary" id: "#{#fakultet.id}"%>
<% end %>
</div>
</div>
</div>
Does anybody understand me and can help me?
Rails provides form collection helpers that make it really easy to assign associations:
# I'm going to just do this in english
<%= form_for(#activity) do |f| %>
<%= f.collection_select(:participant_ids, Partipicant.all, :id, :name, prompt: true, multiple: :new) %>
# ...
<% end %>
Then whitelist the attribute as an array:
params.require(:activity).permit(:foo, :bar, participants_ids: [])
Thats all you actually need to assign childen to to a parent resource. This is done as a part of the normal create/update actions of the parent resource.
You don't actually need the form for the child records unless you actually want to be creating the record. In that case you can setup a nested resource or if you want to create/edit multiple nested records at the same time as the parent record you can use nested attributes.
First you should rename your models and tables, to English, it's a really bad pattern to use your language, in English it is easier to understand by other devs.
According to the problem, probably what you are looking for is hidden_field
<%= f.hidden_field :fakultet_id, :value => #fakultet.id %>
and if you want to query Fakultety that have user assigned, you can select Fakultety where participant_id is not nil
Fakultety.where.not(participant_id: nil)

What is the purpose of the 'hidden_field'?

For example here's a snippit:
<%= form_for [#event, #event.comments.new], html: {class: 'form-horizontal', role: 'form'}, remote: true do |f| %>
<div><%= f.hidden_field :user_id, value: current_user.id %></div>
<div class="form-group">
What is the purpose of the f.hidden_field :user_id, ? Would the code work without it, or is it a necessity to include this line.
Cheers!
Without seeing the controller code which would process the form, the hidden field seems to be holding the id of the user currently logged in. I assume this would be used in further actions, for example, to attribute the event/comment being created against that user.
The view doesn't need the hidden field, but I would imagine the following controller action would fail if it were removed.
The hidden_field method simply creates <input ... type="hidden" /> in the html which means the value is included in the form parameters when the form submits, but the value is not visible to the user.
In Your Case,you are creating an Event with Comments for a particular User.So the user_id is passed as a hidden_field.Without it the value for user_id will be saved as nil,which would resulting an Error.

Rails form updating itself as it's filled out?

I'm trying to make a dynamic form, where the names of some forms at the bottom are based off the values of some forms at the top. For example...
At the top of the page there would be two dropdown menus. At the bottom of the page, there would be two radiobuttons. The name of the first radiobutton would have the name of the first dropdown menu choice, and the second radiobutton would have the name of the second dropdown menu choice.
This is what I have so far:
<%= simple_form_for(#game) do |f| %>
<%= f.error_notification %>
<center>
<div class="form-inputs">
<%= choices = options_for_select( Team.all.map { |team| team[:name] } ) %>
<p>Team 1:</p>
<%= f.select :first_team_name, choices %>
<p>Team 2:</p>
<%= f.select :second_team_name, choices %>
<p>Who you think will win</p>
<%= f.text_field :user_guess %>
</br>
<%= f.submit "Simulate!", class: "btn btn-large btn-primary"%>
</div>
</center>
<% end %>
The text field would be replaced by those radiobuttons instead of a text field.
How do I access the value of the dropdown menus before submitting the form?
For a more comprehensive answer, I'd recommend watching the railscasts episode on this topic, but you'd need a pro (read: paid) subscription.
Since you're not doing anything super complex, you could do it quick & dirty with some javascript:
$(function(){
$('select').change(function(){
html = ''
$('select').each(function(){
html += $(this).val() + '<input type="checkbox" name="game[user_guess]" val="' + $(this).val() +'"/>'
})
$('div.user_guess').html(html)
})
})
If you're pasting the code directly in, you'll need to add a div in your view as well:
<p>Who you think will win</p>
<div class="user_guess"></div>
Don't feel good building HTML with javascript? You can make the change() handler make an ajax call that will load server-generated HTML, which can be made with proper form helpers and such. But for such a simple task it seems like overkill.
(Also, be aware that if the team names can be user defined, this javascript may open you to script injection attacks, so sanitize as needed.)
note that if you want the form to change upon user interaction without the user actually having to submit the form before it changes (rebuilding the page and reloading the view), you have to use javascript. I think. There might be funky things you can do with CSS but that would be really obnoxious to implement.

Best way to reload parts of a form

I want to reload a part of a form generated with the form_for-helper via AJAX.
After reloading the part I still want to have access to the form object.
How can I do this?
Best regards
I am not sure if your are using different terminology than I've heard, but what do you mean "still want to have access to the form object"?
Do you mean access to it in JavaScript? That should still work as long as you don't overwrite the form tags.
Do you mean in the html.erb code generating the partial? That doesn't really make sense, because that form_for object has already generated its html tags and gone out of scope. You need to use to the regular form of the helpers that takes the name of the object as the first parameter. There is no problem with this working with the tags generated by the form_for version of the helpers.
So, in your main page:
<%= form_for :person, #person, :url => { :action => "create" } do |f| %>
<%= f.text_field :name %>
<div id="reloadable">
</div>
<% end %>
And in your partial that fills that div:
<%= text_field :person, :name %>
No step 3.

Resources