I'm using the ajax-datatables-rails gem to use the datatables jquery plugin with server-side processing.
I have the table and a form below to filter the table with data that is not displayed in it.
Here is my table in my index.html.erb file :
<table id='dttb' role='datatable' class="table table-striped table-bordered" data-source="<%= datatable_users_path(format: :json) %>">
</table>
Here is my form in the index aswell :
<%= form_tag(datatable_users_path, method: :get) do %>
<%= submit_tag 'Apply filters' %>
My controller is rendering json like this :
respond_to do |format|
format.html { render :layout => 'application' } # index.html.erb
format.xml { render :xml => #users }
format.json { render json: UserDatatable.new(params) }
end
and my user_datatable.rb gets its raw_record with this :
def get_raw_records
#users = User.all
if(#id.present?)
#users = #users.id(#id)
end
return #users
end
The problem is this #id in the last file. This should be the params[:id] that my form is giving to the controller, and i want to use it in a scope to filter the User.all with it, so that the table displays only the entries that passed the scope.
I don't understand how to pass the data that my form gets to the user_datatable.rb
On the gem github there is a way to do it but it doesn't seem to work with the form data that i'm getting in the controller.
Do you guys have any idea on how to do this ?
Related
I'm looking if theres a way to render a partial once the page is fully loaded.
I have a main view new.vue.erb
<div>
<%= render partial: "builder.vue" %>
</div>
And a partial builder.vue with a huge vue code with many data processing.
I want to be able to render the new view, so I can show a spinner while builder.vue loads.
My approach is making an AJAX request when page is loaded, but It wont work:
New.html.erb
<div>
<div id="builderloaded"></div>
</div>
new.js.erb
$( document ).ready(function() {
$('#builderloaded').html('<%=j render partial: 'campaigns/builder.vue', locals: { f: f } %>')
});
Controller
def new
#campaign = Campaign.new
#categories = Category.all.where(active: true).order(name: :asc)
#products = Product.where(tipo: "gift", active:
respond_to do |format|
format.html { render 'new.vue.erb' }
format.json
format.js
end
end
¿Any ideas on how to achieve this?
Thanks a lot!
I would like to understand the response format actions in Rails. Suppose I have a link_to in my partial which is rendered in show page like below:
show.html.erb
<%= render partial: 'my_partial', locals: { stage: #stage } %>
my_partial.html.erb
<% case 'stage' %>
<% when 'beginning' %>
<%= link_to 'Submit', { controller: 'my_controller', action: 'update_model' } %>
<% when 'ongoing' %>
<%= render partial: 'another_partial' %>
<% end %>
my_controller.rb
def update_model
#do something
respond_to do |format|
format.json { render json: { some_key: some_value } }
format.js { render partial: 'path_to_partial/partial.js' }
format.html { redirect_to action: 'show' }
end
end
Here whenever show page is loaded for the first time #stage will be beginning and then on clicking link_to 'Submit' then before the response from controller the #stage will be changed to ongoing.
Now Whenever I click on link_to, the page reloads and the response is in html so format.html is sent. If I add remote: true then the response is in js and the page does not reload because it is remote.
So the exact functionality that I want is to re render the show page and then inside the my_partial it should go to when ongoing and then render the another_partial page without reloading. This happens in the same url.
What I am trying to understand is why does the page reload when it is the same url? Is that how format.html works? What should I do to render the show page again but without reloading the page?
What the respond_to do |format| does it looks which response the incoming http request is expecting.
Normally, if you click on a link or submit a form, it expects html. But, as you state correctly, if you add remote: true the http request issued by the link is expecting javascript.
Now you want to rerender only the partial, not the whole page. You can do it like so
in the controller
def update_model
...
respond_to do |format|
...
format.js
...
end
end
Don't give a block to format.js this will automatically render a file in the views which - like always - should be named like the controller action.
So update_model.js.erb
And here you can decide what to do.
So for example find the div that holds your partial and then rerender it. Thanks to .erb you can write embedded ruby code in this js file too. And this is where you decide which part to rerender or whatever to do (toggle classes,...)
const container = document.querySelector("#container-for-partial")
const partial = "<%= j render 'some_partial' %>"
// Inject HTML to partial
container.innerHTML = partial
I have a Rails 5 app that has a view that shows different forms based on params. The correct form is shown when the view first shows
However, when there's an error, it always shows the same partial.
diary_controller
def edit
#view = params[:view]
end
def update
respond_to do |format|
if #diary.update(diary_params)
format.html { redirect_to #diary, notice: 'Diary was successfully updated.' }
format.json { render :show, status: :ok, location: #diary }
else
format.html { render :edit }
format.json { render json: #diary.errors, status: :unprocessable_entity }
end
end
end
edit.html.erb
<% if #view == 'close' %>
<%= render 'close_fields'%>
<% elsif #view == 'new'%>
<%= render 'new_fields' %>
<% else %>
<%= render 'all_fields' %>
<% end %>
Currently, it always shows the 'all_fields' partial when there's an error.
Is it possible to show the partial originally shown while retaining the data the user entered in the fields, along with the error messages (currently shown under the text field because I use simple_form)?
------------UPDATE------------
When I add puts params[:view] in :edit, it returns close in the console.
When I add puts params[:view] in :update, it returns nothing in the console. I also tried putting #view = "close" in update. When I did this, the correct view was shown after an error.
Parameters: {"utf8"=>"✓", "authenticity_token"=>"f7JoOucLkUlOyt31NW9HaJIWyXKVSu7q91kspfZYjgdF3hJneRKapnCPtgJn+R5NOC5nDhNvkB8PzzHNs9aLkg==", "diary"=>{"last_date"=>"", "notes"=>"hi, hi!", "update_type"=>"close", "view"=>"close"}, "reason_list_select2"=>"going on vacation", "season_reason_list_select2"=>"", "temp_reason_list_select2"=>"", "area"=>[{"id"=>"4", "action"=>"Not Applicable"}], "commit"=>"Close Diary", "id"=>"27"}
In your update action, you never set #view and so it is always nil in which case your if... elsif... else statement always resolves to <%= render 'all_fields' %>.
If you want your if statement in edit.html.erb to resolve to something other than else, then set your #view variable in your update action.
Based on the update to your question, the problem is now that :view is nested inside :diary:
"diary"=>{"last_date"=>"", "notes"=>"hi, hi!", "update_type"=>"close", "view"=>"close"}
So, you need to do #view = params[:diary][:view] instead of #view = params[:view].
In your diary_controller
before_action :load_view, only: [:edit, :update]
# Your action methods here
private
def load_view
#view = params[:view]
end
And make sure in all your forms (close_fields, new_fields, all_fields), you have a hidden filed named view which value is set to #view.
Once try like this in your
edit.html.erb
<% if #view.to_s == 'close' %>
<%= render :partial => 'close_fields'%>
<% elsif #view.to_s == 'new'%>
<%= render :partial => 'new_fields' %>
<% else %>
<%= render :partial =>'all_fields' %>
<% end %>
Note :your partial file name should have an underscore like this: _all_fields.html.erb
I am trying to have my partial display search results in a rails view. When I check my console > network > preview, I see my partial rendered with the data I need but it doesn't display in my view.
Here's my app/controllers/searchs_controller.rb
def nearby_guides
#address = params[:address]
initial_array = #address.split(',')
city = initial_array[0]
state = initial_array[1].split(' ')
final_state = state[0]
country = initial_array[2]
#result = User.where("city = ?", city)
respond_to do |format|
format.html {render :partial => '/searchs/result', object: #result}
end
end
Here's my views/searchs/_result.html.erb
<h1>HELLO WORLD</h1>
<% if #result %>
<% #result.each do |r| %>
<p><%= r.firstname %></p>
<% end %>
<% end %>
Then in my views/searchs/new.html.erb
<%= render 'result' %>
This is the response I see in my console > network > preview
HELLO WORLD
Kevin
Which is exactly the response I expected but again, it doesn't display in the view. I've looked over stack overflow with no luck. Thanks so much for any and all help!
I think that this is your issue: format.html {render :partial =>
When you are rendering the result of an action as html - it needs to be a whole view, not just a partial.
Rendering partials is generally reserved for AJAX queries - where you need only part of the page and your javascript will insert it into the page in the right place. so either you need javascript, or you need to do something like: render :new
I'm trying to render different partials into my index view from the controller, depending on the params I receive.
I have a simple unless-else condition inside my controller that checks the params
def index
unless params[:check].nil?
render :partial => /layout/check
else
render :partial => /layout/not_check
end
end
And I have the files _check.html.erb and not_check.html.erb into the folder layout/
Now, how can I show that partials inside my index view?
At the moment I can just visualize the partial alone as a single view, but not inside the requested view.
The better way would be to call the partials from index.html.erb
<% unless params[:check].nil? %>
<%= render :partial => '/layout/check' %>
<% else %>
<%= render :partial => '/layout/not_check' %>
<% end %>
so your def index would look like this
def index
respond_to do |format|
format.html
end
end
I did not understand what you are trying to do but partial which are related to controller/actions should not be in layout unless they are serving some layout.
If you're trying to render a layout (and not actual view information) try using render layout
def index
if params[:check].nil?
render layout: "not_check"
else
render layout: "check"
end
end