How to edit data onclick button using rails gem 'best_in_place'? - ruby-on-rails

I am using rails gem 'best_in_place' and data edit one by one, as clicked perticular field.
how can i active all fields for editable onclick update/edit button?
def update
if m_user[:name].present?
MUser.where(:id => id).update(:name => m_user[:name])
elsif m_user[:gender].present?
MUser.where(:id => id).update(:gender => m_user[:gender])
else
flash[:danger] = 'not updated'
end
end
View code:
<% #user.each do |record| %>
<tr>
<td>
<%= best_in_place record, :name, :as => :input %>
</td>
<td>
<%= best_in_place record, :gender, :as => :select, collection: (MUser.pluck(:id,:gender)) %>
</td>
<%= best_in_place record, :dob, :as => :date, class: 'datepicker1 %>
</td>
</tr>
<% end %>
<%= submit_tag('update',:name => 'update_data', class: 'btn btn-primary btn-sm', :id => 'update_btn') %>
Now data edit like if i edit name it will automatically editable
,but how can I edit when i clicked update/edit button then make all fields active for edit.

As we discussed, you need to do a couple of changes
Add a _user.html.erb partial to render the records with below code.
<td>
<%= user.name %>
</td>
<td>
<%= user.gender %>
</td>
<td>
<%= user.dob %>
</td>
<td>
<%= link_to "Edit", edit_user_path(user), remote: true %>
<td>
Now change your index.html.erb code like below.
<% #users.each do |user| %>
<tr id="record-row-<%= user.id %>">
<%= render prtial: 'user', locals: { user: user } %>
</tr>
<% end %>
Now refresh your page and you will see the User records in table rows.
Add a new partial _user_form.html.erb to render the form and add below code in it.
<td colspan="4">
<%= form_for(#user, remote: true) do |f|
<table>
<tbody>
<tr>
<td><%= f.text_field :name, class: 'form-control' %></td>
<td><%= f.select :gender, MUser.pluck(:gender, :id).uniq, { selected: #user.gender }, class: 'form-control' %></td>
<td><%= f.text_field :name, class: 'form-control datepicker1' %></td>
<td><%= f.submit "Update" %></td>
</tr>
</tbody>
</table>
<% end %>
</td>
Now need to update edit and update actions.
edit action
def edit
#user = User.find(params[:id])
respond_to do |format|
format.js { }
format.html { render 'edit' }
end
end
update action
def update
#user = User.find(params[:id])
respond_to do |format|
if #user.update_attributes(user_params)
format.js { }
format.html { redirect_to #user, notice: 'User was updated successfully.' }
else
format.js { }
format.html { render 'edit' }
end
end
end
private
def user_params
params.require(:user).permit(:name, :gender, :dob)
end
Now you need to create an edit.js.erb file to render the form on selected row.
$("#record-row-<%= #user.id %>").html("<%= escape_javascript(render 'user_form') %>")
And you also need an update.js.erb file to update the table row after updating the user record.
$("#record-row-<%= #user.id %>").html("<%= escape_javascript(render partial: 'user', locals: { user: #user } ) %>")
Now all set. Refresh your page and click on Edit button of a row. A form will appear. Change the value and click on Update button. You will see the updated record.
Let me know if you have nay issues. Happy to help.

Related

How to update a record from index in rails

I was trying to update a User record (only the "closed" named column) from the user index's view. This is what I tried. But, it is not working. I used Devise gem to generate views and controllers. But, whatever, How can I update a records one particular value, directly from index(without going to edit's view). It would be very helpful, if someone would help me.
<% #users.each do |user| %>
<tr>
<td> <%= user.last_name %></td>
<td> <%= user.telephone %></td>
<td> <%= form_for user do |f| %>
<% if user.closed %>
<%= f.hidden_field :closed, value: false %>
<%= f.submit "Activate" %>
<% else %>
<%= f.hidden_field :closed, value: true %>
<%= f.submit "Deactivate" %>
<% end %>
<% end %> </td>
<%= link_to 'Remove', user_destroy_path(user), method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
Controller:
def user_index
if current_user.admin?
if params[:user_search].present?
#users = User.search_user(params[:user_search]).super_admin
else
#users = User.super_admin
end
else
if params[:user_search].present?
#users = User.search_user(params[:user_search]).admin
else
#users = User.admin
end
end
respond_to do |format|
format.html
format.csv { send_data User.to_csv, type: 'text/csv', filename: "users.csv" }
end
end
here is my controller. Actually there is also something done to search the users
In your controller, create two methods activate and deactivate.
In controller,
def activate
#user = User.find_by(:id=>params[:id])
#user.update(:closed=>false)
redirect_to #your path
end
def deactivate
#user = User.find_by(:id=>params[:id])
#user.update(:closed=>true)
redirect_to #your path
end
Set your routes as,
patch '#yourcontroller/:id/activate',to:'#yourcontroller#activate' , as: :activate
patch '#yourcontroller/:id/deactivate',to:'#yourcontroller#deactivate' ,as: :deactivate
and finally do changes in your view as,
<% #users.each do |user| %>
<tr>
<td> <%= user.last_name %></td>
<td> <%= user.telephone %></td>
<td> <%if user.closed?%>
<%= link_to 'activate',activate_path(id:user.id), method: :patch%>
<%else%>
<%= link_to 'deactivate',deactivate_path(id:user.id), method: :patch%>
<% end -%> </td>
<%= link_to 'Remove', user_destroy_path(user), method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
Its helpful pls up-vote!

Update form from another scaffold

I am trying to update a record from the view of another scaffold, the problem is that it sends me the following error:
No route matches {:action=>"update", :controller=>"pedidosliberados"}
I'm showing one form per record
this is my form:
<% #pedidosliberados.each do |pedidoliberado| %>
<tr id="pedido_liberado_<%= pedidoliberado.id %>">
<td class="component_name_body_col"><%=pedidoliberado.try(:Client)%></td>
<td class="component_name_body_col">
<%= form_for(pedidoliberado, :method => :put, remote: true, :url => {:controller =>'pedidosliberados', :action => 'update'}, html: {class: "form-horizontal "}) do |f| %><!--ajax-->
<%= f.text_field :Status, value: "1" %>
<%= submit_tag "Actualizar", class: "btn btn-primary"%>
<% end %>
</td>
</tr>
<% end %>
my route:
resources :pedidosliberados
my action update from controller pedidosliberados:
def update
respond_to do |format|
if #pedidoliberado.update(pedidoliberado_params)
format.html { redirect_to #pedidoliberado, notice: 'Pedidoliberado was successfully updated.' }
format.json { render :show, status: :ok, location: #pedidoliberado
format.js {}
else
format.html { render :edit }
format.json { render json: #pedidoliberado.errors, status: :unprocessable_entity }
format.js {}
end
end
end
The problem is that you are using an incomplete route, that is /update; you need to add the id of the object to be updated, something like /update/12 where 12 is the id of the object. So in your code you could remove the :url attribute and you will be fine.
So your view, now should look like this:
<% #pedidosliberados.each do |pedidoliberado| %>
<tr id="pedido_liberado_<%= pedidoliberado.id %>">
<td class="component_name_body_col"><%=pedidoliberado.try(:Client)%></td>
<td class="component_name_body_col">
<%= form_for(pedidoliberado, :method => :put, remote: true, html: {class: "form-horizontal "}) do |f| %><!--ajax-->
<%= f.text_field :Status, value: "1" %>
<%= submit_tag "Actualizar", class: "btn btn-primary"%>
<% end %>
</td>
</tr>
<% end %>
This works because rails automatically assigns the correct controller and action for your object (when using REST routes).
UPDATE
If you want to explicity assign the url, then use :url like you are doing, but adding :id (remember, you need to specify the id of the object to be updated). So, your form should look something like this:
<%= form_for(pedidoliberado, method: :put, remote: true, url: { controller: 'pedidosliberados', action: 'update', id: pedidoliberado.id }, html: { class: "form-horizontal " }) do |f| %>

ActiveSupport::HashWithIndifferentAccess

My contorller is like this
class FriendController < ApplicationController
def friend_list
#user = User.new
end
def be_mine_friend
#user = params[:user]
if #user.save?
redirect_to friend_mine_friend_url
flash[:notice] = "#{#user[:name]} have been added to my friend list"
else
redirect_to friend_friend_list_path
end
end
def mine_friend
#title = "Details list of Mine Friend"
#friend = #user.paginate(page: params[:page], per_page: 10)
respond_to do |format|
format.html
format.json { render json: #friend }
end
end
end
View page for friend_list
<div class="container">
<%= notice %>
<%#= errors %>
<%= form_for(#user, url: friend_be_mine_frien_path) do |user| %>
<%= user.text_field 'name', placeholder: "Your name Please" %></br>
<%= user.text_field 'email', placeholder: "Your Email Please" %></br>
<%= user.text_field 'address', placeholder: "Your Address Please" %></br>
<%= user.submit "Be Mine Friend", class: "btn btn-primary" %>
<% end %>
</div>
view page for mine_friend
<div class="container">
<p><strong><%= #title %></strong><p>
<%= notice %>
<%= will_paginate #friend, previous_label: "<<", next_label: ">>", class: "pagination pagination-large" %>
<table class="table table table-striped">
<tr>
<th>Name</th>
<th>Address</th>
<th>Email</th>
</tr>
<% #friend.each do |friend| %>
<tr>
<td><%= friend.name %></td>
<td><%= friend.address %></td>
<td><%= friend.email %></td>
</tr>
<% end %>
</table>
</div>
and model is
class User < ActiveRecord::Base
attr_accessible :address, :email, :message, :name
validates :address, :email, :message, :name, presence: :true
end
I while I try to save user from friend_list I get such
Processing by FriendController#be_mine_friend as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"5A1dXtuYJpfqpOphkdl+WA657T3ok2zu/8U1v1B8tEg=", "user"=>{"name"=>"Amritdeep", "email"=>"amritdeepdhungana#hotmail.com", "address"=>"Bou"}, "commit"=>"Be Mine Friend"}
Completed 500 Internal Server Error in 1ms6090>:
the error is
NoMethodError - undefined method `save?' for #<ActiveSupport::HashWithIndifferentAccess:0x00000003c06090>:
What should I do now? Do you guys have any solution for it? I don't know why this ActiveSupport::HashWithIndifferentAccess error is following. Do you guys have any idea about it?
#user = params[:user]
if #user.save?
The params[:user] is a hash. it is not a user object. This is the norm:
#user = User.create(params[:user])

Why this won't pass previous input data when it returns error and redirect?

First of all, I input 'hello' into comment input box and submit it.
It succeeds without any problem.
Then if I try re-do again within 10 seconds, I designed it to returns 'spamming warning'
It does the action as I wished. But the problem is, all the input data I typed in at previous page is gone... so I have to type them all again.
How can I leave the previous input data?
def show
...
#comment_input = #user.comment_threads.build
...
end
def add_comment
#user = User.find_by_username(params[:id])
#post = #user.comment_threads.last
if #post
last_time = #post.created_at
if Time.now - last_time <= 10.second
redirect_to :controller => 'users', :action => 'show', :id => #user.username
flash[:notice] = "You cannot spam!"
return
end
end
#user_who_commented = current_user
#comment = Comment.build_from( #user, #user_who_commented.id, params[:comment][:body] )
#comment.comment_icon = params[:comment][:comment_icon]
#comment.save
redirect_to :controller => 'users', :action => 'show', :id => #user.username
flash[:notice] = "comment added!"
end
_form.html.erb
<%=form_for #comment_input, url: url_for( :controller => :users, :action => :add_comment ) do |f| %>
<div class="field">
<%= f.label :body %><br />
<%= f.text_field :body %>
</div>
<div class="field">
<%= f.file_field :comment_icon %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
UPDATE:
users_controller.rb #show
def show
#user = User.find_by_username(params[:id])
#comments = #user.comment_threads.order("updated_at DESC").page(params[:page]).per(5)
#comment_input = #user.comment_threads.build
respond_to do |format|
format.html # index.html.erb
format.json { render json: #user }
end
end
end
views/users/show.html.erb
.....
<table>
<tr>
<th>ID</th>
<th>PIC</th>
<th>Body</th>
<th>Subject</th>
<th>Posted by</th>
<th>Delete</th>
</tr>
<% #comments.each do |comment| %>
<tr>
<td><%= comment.id %></td>
<td>
<% if comment.comment_icon? %>
<ul class="thumbnails">
<%= image_tag(comment.comment_icon.url(:thumb),:height => 100, :width => 100, :style => 'border:3px double #545565;' ) %>
</ul>
<% end %>
</td>
<td><%= comment.body %></td>
<td><%= comment.subject %></td>
<td><%= comment.user.user_profile.nickname if comment.user.user_profile %></td>
<td>
<%= button_to 'destroy', delete_comment_user_path(#user,comment.id), confirm: 'Are you sure?', :disable_with => 'deleting...' if current_user && current_user.id == comment.user_id %>
</td>
</tr>
<% end %>
</table>
<%=form_for #comment_input, url: url_for( :controller => :users, :action => :add_comment ) do |f| %>
<div class="field">
<%= f.label :body %><br />
<%= f.text_field :body %>
</div>
<div class="field">
<%= f.file_field :comment_icon %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
......
def add_comment
#user = User.find_by_username(params[:id])
#post = #user.comment_threads.last
#user_who_commented = current_user
#comments = #user.comment_threads.order("updated_at DESC").page(params[:page]).per(5)
#comment = Comment.build_from( #user, #user_who_commented.id, params[:comment][:body] )
#comment.comment_icon = params[:comment][:comment_icon]
if #post && (Time.now - #post.created_at) <= 10.second
flash[:notice] = "You cannot spam!"
render :action => "show"
elsif #comment.save
flash[:notice] = "comment added!"
redirect_to :controller => 'users', :action => 'show', :id => #user.username
else # if model's errors
render :action => "show"
end
end

How can I make the input field empty after ajax submit?

I implemented a chat system to my app.
It refreshes the list of comments partially when after new comment was submit.
So new added comment pops up without reloading whole page.
It's working fine but the problem is, it won't make input field empty(initialize) after submit :(
How can I make it empty if it succeeded at submitting?
5 seconds Auto-refreshing will be another issue that's preventing.
So I have to care about it, too.
and If possible I want to pop up flash alert 'you cant spam' when the user tried to submit comment within 10 seconds.
Let's assume as if I'm trying to submit comment from Users#show page
views/users/show.html.erb
<%= javascript_tag do %>
jQuery(document).ready(function () {
refreshPartial();
setInterval(refreshPartial, 5000)
});
function refreshPartial() {
$.ajax({
url: "<%= show_user_path(#user) %>/refresh_part",
type: "GET",
dataType: "script",
});
}
<% end %>
......
<span id="chat">
<%= render 'users/comment' %>
</span>
<%= render 'users/comment_input' %>
views/users/_comment.html.erb
<table>
<tr>
<th>ID</th>
<th>PIC</th>
<th>Body</th>
<th>Subject</th>
<th>Posted by</th>
<th>Delete</th>
</tr>
<% #comments.each do |comment| %>
<tr id="<%= dom_id(comment) %>">
<td><%= comment.id %></td>
<td>
<% if comment.comment_icon? %>
<ul class="thumbnails">
<%= image_tag(comment.comment_icon.url(:thumb),:height => 100, :width => 100, :style => 'border:3px double #545565;' ) %>
</ul>
<% end %>
</td>
<td><%= comment.body %></td>
<td><%= comment.subject %></td>
<td><%= comment.user.user_profile.nickname if comment.user.user_profile %></td>
<td>
<%= button_to 'destroy', polymorphic_path([#user, comment]), :data => {:confirm => 'Are you sure?'}, :method => :delete, :disable_with => 'deleting...', :remote => true, :class => 'btn btn-danger' if current_user && current_user.id == comment.user_id %>
</td>
</tr>
<% end %>
</table>
<%= paginate #comments, :window => 4, :outer_window => 5, :left => 2, :right => 2 %>
views/users/_comment_input.html.erb <= This is input form!!!!!
<%=form_for(([#user, #comment]), :remote => true) do |f| %>
<div class="field">
<%= f.label :body %><br />
<%= f.text_field :body %>
</div>
<div class="field">
<%= f.file_field :comment_icon %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
comments_controller.rb
def create
commentable = #community_topic||#community||#user
#comments = commentable.comment_threads.order("updated_at DESC").page(params[:page]).per(5)
#comment = Comment.build_from(commentable, current_user.try(:id), params[:comment][:body])
#comment.comment_icon = params[:comment][:comment_icon]
if #user
#following_users = #user.all_following(order: 'updated_at DESC')
#followed_users = #user.followers
#communities_user = #user.get_up_voted(Community).order("updated_at ASC").page(params[:page]).per(5)
elsif #community
end
last_comment = Comment.where(:user_id => current_user.id).order("updated_at").last
if last_comment && (Time.now - last_comment.updated_at) <= 10.second
flash[:notice] = "You cannot spam!"
render :template => template_for(commentable)
elsif #comment.save
#if #community_topic.empty?
#comments = commentable.comment_threads.order("updated_at DESC").page(params[:page]).per(5)
#comment = commentable.comment_threads.build
respond_to do |format|
format.html { redirect_to [#community, commentable].uniq, :notice => "comment added!" }
format.js do
if #community.present?
render 'communities/refresh_part'
elsif #community_topic.present?
render 'community_topics/refresh_part'
elsif #user.present?
render 'users/refresh_part'
end
end
end
else
render :template => template_for(commentable)
end
end
views/users/refresh_part.js.erb
$('#chat').html("<%= j(render(:partial => 'users/comment')) %>")
Well I assume this is the "body" input you want to empty so basically, just add an id to it like this :
<%= f.text_field :body, :id => "body_input" %>
And in your views/users/refresh_part.js.erb, you can add something like :
$('#body_input').val('');
This should work only if it succeded at submitting because from what I saw, your template is rendered only if the comment is saved.

Resources