I am using below button_to tag inside view file (index.html.erb)
<textarea rows="2" cols="20"><%=#write_date%></textarea>
<%= button_to t(:get_date_write_new),channel_get_dates_path(#channel, :write => 1) %>
when i click the button it will get date from device and prints it on screen.
my question is that how do i make call to function "channel_get_dates_path(#channel, :write => 1)" continuously, and display the date in textarea without refreshing the page. by pressing the button only once?
my controller file:
class GetDatesController < ApplicationController
include DateUtilities
before_filter :require_user, :set_channels_menu
def index
#channel = current_user.channels.find(params[:channel_id])
#write_date = #channel.get_dates.write_dates.first
end
def create
#channel = current_user.channels.find(params[:channel_id])
#get_date = #channel.get_dates.write_dates.first
if (#get_date.nil?)
#get_date = GetDate.new
#get_date.channel_id = #channel.id
#get_date.user_id = current_user.id
#get_date.write_flag = params[:write]
end
#get_date.get_date = generate_get_date
#get_date.save
redirect_to channel_get_dates_path(#channel)
end
end
and i have date generation file(myapp/lib) as:
module DateUtilities
def generate_get_date
require 'rubygems'
require 'socket'
hostname = '127.0.0.1'
port = 2000
streamSock = TCPSocket.new( hostname, port )
streamSock.write "ON"
while line = streamSock.gets
k = line
end
k
end
end
In order to change the page without refreshing it, you need AJAX.
This can be done quite easily in rails by passing a :remote => true attribute in a form :
<%= form_tag(myupdate_path, :remote => true) do %>
<%= form_tag(channel_get_dates_path(#channel, :write => 1), :remote => true) do %>
<input type="submit" value="Get Today's Date">
<input id="thedate" type="text" value="<%=#write_date%>">
<% end %>
<% end %>
The remote option will call the myupdate method in your controller, and tell it to render a javascript view instead of a html view. Let's say you have in your controller :
def myupdate
#thedate = params['wathever'] # get the params from the form
end
Then you can add your javascript method in myController/myupdate.js.erb ( instead of myupdate.html.erb). Assuming you're using jquery, this would be
$("#thedate").val("<%= #thedate %>") # dynamically update
By doing this you're able to get the params from the form, process it as you want with a controller, and tell javascript to update your page according to whathever you just put in your instance variable.
Edit : I used your form as the example. Hopefully the javascript is now more clear : the idea of the javascript view is to get the "thedate" html element in your page, and set its value according to the updated instance variable #thedate. This is where you tell javascript to dynamically update your page.
Hope this helps
#Aurel,thanks for your suggestions. i followed your steps.
in my view file changed the code as:
<%= form_tag(channel_get_dates_path(#channel, :write => 1), :remote => true) do %>
<input type="submit" value="Get Today's Date">
<input type="text" value="<%=#write_date%>">
<% end %>
after this when i press the submit button the update method is called(and i can see that device is sending the date), but the date is not displaying in text field. when i refresh the page the last obtained date from device is displayed in text field.
Is it possible to display the date every time when press submit button?
Related
I have a notification system in my rails app. On my notifications model I have:
message
user_Id
read
link_path
The following code works great for showing me the notifications for the current user, and then showing me the notifications that are read. I'm looping through each of these records where this criteria is true, and then doing a link_to #link do, and then outputting the whole code.
Basically the whole block I can then click on and it will take me to the proper record. That works like a charm.
The default for all new notifications is :read => false.
However, when user clicks on the link, I'm trying to pass :read => true into that record, so that when I come back that particular notification will no longer show, since it's only showing me :read => false notifications.
What is the easiest way to go about this? I've tried wrapping everything in a form_for and trying to pass this value of :read => true into the record, but I can't get that to work. Thoughts?
Controller
#x = Notification.where(:user_id => current_user, :read => false)
View
<% #x.where(:user_id => current_user).each do |notify| %>
<% #link = notify.link_path %>
<%= link_to #link do %>
<div class="row notifyrow">
<div class="col-sm-7">
<p> <%= notify.message %></p>
</div>
<div class="col-sm-3">
<p> <%= time_ago_in_words(notify.created_at )%> ago</p>
</div>
</div>
<% end %>
<% end %>
What you seem to want to do is to update the read attribute on a particular Notification when the user clicks the link. That's absolutely what a Controller method is for. For example, assuming the route for your notify_link is something akin to get '/notifications/:id', to: 'notifications#show', you'd do the following:
class NotificationsController < ApplicationController
...
def show
#notice = Notification.find(params[:id])
#notice.update!(read: true)
end
end
That updates the read attribute on the record, so when you go back to the main view it will no longer appear in your unread list.
By the way, in your controller you run a query to get all the unread notifications for the current user, and then run where() again in your view. It should be sufficient to just do #x.each in your view.
EDIT
To summarise the comments discussion below, since the linked path doesn't include the Notification object ID, you just need to include it in the query parameters. The Rails-generated URL helpers take a hash (following any parameters required to complete the path) and includes them in the query string. So, something like:
national_race_path(#national_race.id, notify_id: notify.id)
will append the ID as <whatever_path>?notify_id=1234 and it will be accessible in the controller via params[:notify_id]. You'll need to handle what happens if no or invalid ID is passed, etc., but that should give you what you need.
I am new using Ruby On Rails so this question may seem stupid. I've been searching a lot tutorial and sort of understand what I could do, but what the code looks like exactly? how i should implement this and where to put them still confuse me.
I have a database called note which has two attributes, :note whose type is text and a foreign key called user_name whose type is string. In the main.html.erb, I have my main page and also a note pad whose is a text area. here's part of main
<div class="four columns" id="note">
<textarea id="area" style="width:250px; height:300px;" placeholder="Your notes starts here"><%= #note %></textarea>
<div id="clear" class="primary btn pretty">Clear</div>
<div class="secondary btn pretty"><%= link_to 'Save', controller: 'main', action: 'update_note', :remote => true, :method => :put %></div>
</div>
By the way, I'm using Gumby. so My button is called "Save". I want the user to input their note in the txtfiled and when they click the "save" button, it will update the note database in the row according to the user_name.
So my question is, should I write a action on main_controller or notes_controller. How should I do it. Sample could would be much helpful since I tried different way and it is really frustrating.
I tried putting the code in the main_controller like this:
def update_note
#note = Note.find_by(user_name: session[:user_name])
respond_to do |format|
if#note.update_attributes(params[:note])
format.html { redirect_to #note, :notice => 'Note was successfully updated.' }
format.js
else
format.html { render :action => "edit" }
format.js
end
end
end
as well as tried to put code in notes_controller. but I get "No route match"
I totally mess up. And it'd due tomorrow! thanks for any help. It's so nice to refers me some link of tutorial but the anything related to my code would be more helpful!
Thanks!
You would have to use a form for this or you can also do it by using Jquery Ajax.
First add a gem 'jquery-rails' to Gemfile and then do bundle install.
in Gemfile:
gem 'jquery-rails'
Next require both jquery and jquery_ujs into your /app/assets/javascripts/application.js manifest like this:
//= require jquery
//= require jquery-ujs
in /views/layouts/application.html.erb:
<%=javascript_include_tag "application.js"%>
#I guess it will be already there
in /views/main/home.html.erb
<%= form_tag({:controller=>'main',:action=>'update_note'},:method=>:post,:id=>"update_note",:name=>'note_form',:remote=>true) do %>
<div class="four columns" id="note">
<textarea id="area" name="note" style="width:250px; height:300px;" placeholder="Your notes starts here"><%= #note %></textarea>
<div id="clear" class="primary btn pretty">Clear</div>
<div class="secondary btn pretty"><%= submit_tag 'Save' %></div>
</div>
<%end%>
<div id="updated">
</div>
in main_controller.rb
def update_note
#note = Note.find_by(user_name: session[:user_name])
if #note.update_attributes(params[:note])
#updated = "true"
format.js
else
#updated = "false"
format.js #this will load update_note.js.erb
end
end
Create a file update_note.js.erb under ../views/main/
Now in app/views/main/update_note.js.erb:
<%if #updated == "true"%>
$('#updated').html("Your post has been successfully updated").show();
<%elsif #updated == "false"%>
$('#updated').html("Your post could not be updated").show();
<%end%>
And at last add this in /config/routes.rb:
#in Rails 3
#match "main/update_note" => "main#update_note"
#in Rails 4
match 'main/update_note' => 'main#update_note', :via => [:post]
Open this home page where you have the update_note textbox, open up console in Chrome/ Firefox. Now check under Net tab in the console (in Firefox) or Network tab (in Chrome) and check for the request being made when you click on Save button. Let me know if you find any difficulty.
Hi I'm making a rails app that uses Zendesk API calls. I have a controller that uses two classes I defined
class TicketsController < ApplicationController
require 'ticket_fields'
require 'ticket_search'
def getTickets
#search_fields = SearchFields.new(client)
#tickets = TicketSearch.new(client)
end
def search_tickets
#ddcustomvalues = [params[:customer_company_id], params[:study_id], params[:type_id], params[:system_id]]
#tickets.search_tickets(ddcustomvalues)
end
end
One class SearchFields uses the api to load values I want to filter tickets by into arrays. My view then uses these values to populate drop down lists.
The other class TicketSearch looks like this.
class TicketSearch
attr_reader :tickets, :text
def initialize(client)
#text = "query"
#tickets = Array.new
client.tickets.all do |resource|
#tickets << resource
end
end
def search_tickets(custom_search_fields)
querystring = "type:ticket+tags:"
custom_search_fields.each_with_index do |field, index|
unless field == ""
if index ==0
querystring += "#{field}"
else
querystring += " #{field}"
end
end
end
#text = querystring
end
end
What I want to happen in my view is when a button is pressed it changes the value of #text to the querystring generated by the drop down list options that were selected. I'm currently doing this for testing to see if my querystring is correct and the button works. What I eventually want it to do is send the querystring to the ZenDesk Server and returns the tickets I filtered for. the #tickets array would then be replaced with the filtered tickets the server returned. Currently my button code looks like this.
<%= button_to 'Search', :action => 'search_tickets' %>
with all the route code I've tried I either get an error upon starting the page. Or when I press the button nothing happens and the #text being displayed in my view remains "query". Can someone help explain what I need to do I don't quite understand how routes work.
==================================================================================
Hey so I made the changes you suggested and did some reading up on AJAX and js and I think I'm almost at the answer my view now looks like this
<div id="test" >
<%= render partial: 'text', locals: { text: #tickets.text} %>
<div id="test" >
and I created a partial _text file that looks like this
<p> Query: <%=text%> </p>
and a js file search_tickets.js.erb
$("#test").html("<%= escape_javascript(render partial: 'text', locals: { text: #tickets.text } ) %>");
any idea what may be going wrong everything loads up okay but the text remains the same in the partial i set up when i hit the button still
the console outputs this after the button is hit
ActionController::RoutingError (No route matches [POST] "/tickets/search_tickets"):
so I guess it may actually be a routing error my route looks like this
resources :tickets do
collection do
put :search_tickets
end
end
and the form tag calling the path looks like this
<%= form_tag search_tickets_tickets_path, remote: :true do %>
<table>
<tr>
<td align = "left" valign="middle"> <font size = 4> Customer Company </font> </td>
<td align = "left" valign="middle">
<%= select_tag "customer_company_id", options_for_select(#search_fields.customer_companies), :prompt => "Select One" %>
</td>
</tr>
......
<tr>
<td> </td>
<td align = "left" valign="middle">
<%= submit_tag "Search" %>
</td>
</tr>
</table>
<% end %>
==================================================================================
(Update)
I think I fixed my last problem by changing my form tag to this
<%= form_tag search_tickets_tickets_path(#tickets), method: :put, remote: :true do%>
however now I get this error from the terminal after I hit the button
NoMethodError (undefined method search_ticket' for nil:NilClass):
app/controllers/tickets_controller.rb:15:insearch_tickets'
how would I pass #tickets as a parameter through my route because clearly its not accessible by search_tickets right now as its giving a nil class error.
Variables
when a button is pressed it changes the value of #text to the querystring generated
It looks to me like you're confused with the stateless nature of Rails - in that, just because a view has been rendered doesn't mean the values / variables are still available for use.
It was mentioned in the comments that it seems you're basing a lot on experience with other frameworks / programming patterns. The best way to describe your solution is that Rails has to "refresh" all your variables / values each time it processes a request; consequently meaning that if you send a button request - you'll have to perform the request as if it were the first one
Ajax
The bottom line is that you need to use an ajax request to pull this off.
To do this, you'll be be best creating a form (not just a button_to), as this will give you the ability to send as many params as you want. You should use form_tag:
#config/routes.rb
resources :tickets do
collection do
get :search_tickets
end
end
#view
<%= form_tag tickets_search_tickets_path, remote: :true do %>
... #-> fields for your params
<%= submit_tag "Search" %>
<% end %>
This will give you the ability to define the following in your controller:
#app/controllers/tickets_controller.rb
Class TicketsController < ApplicationController
def search_tickets
#ddcustomvalues = [params[:customer_company_id], params[:study_id], params[:type_id], params[:system_id]]
#tickets.search_tickets(ddcustomvalues)
respond_to do |format|
format.js #-> loads /views/tickets/search_tickets.js.erb
format.html
end
end
end
#app/views/tickets/tickets_search.js.erb
//JS here to manipulate your original page
Requests
The bottom line here is that if you want to "manipulate" your view without refreshing, unlike "native" application frameworks, where you can rely on a persistent state, with Rails, you basically have to construct the request from scratch (IE passing all the params required for the method to run)
I got error when using controller to read text file:
#my_page.html.erb
<input id="test_input" >
#controller.rb
def my_page
File.open($directory+'\test.TXT', 'r') do |f1|
$line = f1.readlines
f1.close
end
respond_to do |format|
format.js
end
end
#my_page.js.erb
el = document.getElementById(test_input);
el.innerHTML='<%=$line$>';
It load blank page without input and I don't know why, Please correct me if I'm wrong.
I think I understand what you are doing. Here is what you can do.
#controller.rb
def my_page
#text= File.open('your_file.txt').read
end
#my_page.html.erb
<input id="test_input" value="<%= #text %>" />
When you refresh your page, the text should show up on your page. No need to use Javascript now. You should use it when you are requesting the resource using AJAX.
If you would like to update the value of the text box, you need to add a new action in your controller and update your routes.rb accordingly. Also, it's always a good idea to use form helpers that Rails provide to utilize security feature (CSFR token), as shown below. If you have a model for the text field, you can use a form_for helper. You can read about them in
http://guides.rubyonrails.org/form_helpers.html
Here is the code, nonetheless.
#my_page.html.erb
<%= form_tag save_text_path do %>
<%= text_field_tag :test_input, #text %>
<%= submit_tag "Update" %>
<% end %>
# in your controller
def save_text
updated_text = params[:test_input]
# do something with the text
end
# in your routes.rb
post "save_text" => "your_controller_name#save_text", as: "save_text"
URL : /evaluations
I have made a form to select a specific item (a period)
class EvaluationsController < ApplicationController
def index
#periods = Period.all
end
My form :
<% form_for XXXXX do %>
<%= collection_select(:period, :period_id, #periods, :id, :fullname) %>
<%= submit_tag("Valider") %>
<% end %>
I would like the form to go to /evaluations/3 when submited (if the selected period is 3).
When I go manually to /evaluations/3 it works like a charm but I really don't know how to write the form_for to go the right url by submitting the form.
Simple way
Submit period ID to process data, and then redirect to action, which handles
evaluations/:id with :id as parameters.
redirect_to <youraction>(:period => #id)
This should do the trick.
Not so simple way
If you want to change something dynamically on your page after data was submitted - call method and respond with javascript
respond_to do |format|
format.js
end
In javascript response you can put whatever you want - simple redirects or script, which will change page dynamically. It's up to you.
Hope it helps.
you need to use some javascript to update the action of the form
$('#period_period_id').change(function() {
$('form').attr('action', '/evaluations/' + this.value);
})