I am trying to change the colour of a row according to a rails database value. Also within the row is a form which is a drop down menu. On changing the selected value in the drop down form I update the changed value to the DB by a form submit and then call a javascript function to change the row colour using the new value through AJAX.
html.erb:
<%= f.select(:status, ["to call","didn't connect","confirmed","rejected"], {:selected => lead.status}, :onchange => %Q[$('#lead_form_#{lead.id}').submit();document.getElementById('lead_row_#{lead.id}').bgcolor=Application.getRowColour("#{lead.status}");]) %>
In the above code what is happening is that the #{lead.status} which is being passed to getRowColour is always the same i.e. the initial value of status when I first load the page. So how many ever times I change the status via the dropdown, the getRowColour("") does not change.
source of the page:
$('#lead_form_133').submit();document.getElementById('lead_row_133').bgcolor=Application.getRowColour("confirmed");
As can be seen the getRowColour() is taking a constant value and not re-evaluating it on every call. How can I send my lastest status param to this function?
Assuming the id of the status select-box is status consider using the following construction:
<%= f.select(:status, ["to call","didn't connect","confirmed","rejected"],
{:selected => lead.status} %>
Then add the onchange handler logic:
<script type="text/javascript">
$("#status").change(function() {
$('#lead_form_#{lead.id}').submit();
$('#lead_row_#{lead.id}')
.css('background-color', Application.getRowColour($("#status").val())
});
</script>
Related
I have a problem where, when adding a new html element such as:
<%= f.date_select :date, { id: "date-select"} %>
it affects my already existing collection select:
<%= f.collection_select :id,
Customer.where(business_id: current_customer.business_id),
:id,
:full_name,
{ prompt: 'Select' },
{ id: "colleague-select", onChange: "renderColCal(this)" } %>
Usually, the customer can select another customer from the list, triggering an ajax call to render the selected customer's calendar using the selected customer's id. This works fine by itself.
However, when I put in this new date_select option further up in the form, and then try to use the collection_select, the ajax call can't be finished because it is trying to find a customer with an id equal to the year of the date that's been selected in the other select box!!
Here is an example. I have selected a date with the year "2012" in my date_select. Then I select a customer in the collection_select and receive this in the console:
Started GET "/calendars/calendar_change?colleagueID=2012" for 127.0.0.1 at 2016-02-01 11:38:01 +0000
Processing by CalendarsController#calendar_change as */*
Parameters: {"colleagueID"=>"2012"}
Customer Load (0.0ms) SELECT "customers".* FROM "customers" WHERE "customers"."id" = ? ORDER BY last_name ASC LIMIT 1 [["id", 2012]]
Completed 404 Not Found in 5ms
ActiveRecord::RecordNotFound (Couldn't find Customer with 'id'=2012):
app/controllers/calendars_controller.rb:19:in `calendar_change'
this is my javascript being called:
function renderColCal(select){
var colleagueID = select.value ;
$.ajax({
url: '/calendars/calendar_change',
data:{
colleagueID: $('select').val()
}
}
)
}
Why is this happening? How do I fix this? Thanks!
The problem is your javascript. The data you are submitting is
data:{
colleagueID: $('select').val()
}
which submit the value of the first select on the page. If you want to go that route, you'd have to make the selector you've passed to $() more selective (for example, using the id of the select box).
You are actually retrieving the value from the select box earlier in your event handler, but you're not using it for some reason. This is probably less error prone than using jquery to find the select element when it is already being passed to you.
In my Grails project I have a field that allows me to select between a list.
After user has selected a value, I store the id of the related object.
I would like that, after storing the id, I get a value related to the object with that id and show it into another input field.
Here is the javascript that I use to store the id:
$("#patient_textField").autocomplete({
source: data,
select: function (event, ui){
$('#patient_id').val(ui.item.id);
}
});
I've created a function in controller that allows me to get the value that I need to show into the second input field
def getPhoneNumberFromPatientId(int patientID)
{
int phone = Patient.findById(patientID).phone_1
if(phone == null)
phone = Patient.findById(patientID).phone_2
return phone
}
How can I solve it?
You need to use AJAX to accomplish what you want. In Grails you have some taglibs that are very useful to execute an AJAX call.
An example is g:remoteFunction. This taglib allows you to execute an AJAX call and update the content of an HTML element. It's a very useful taglib!
For this question I've wrote an example that allows the user to select an option in a list (HTML Select) and update the content of a textArea based on the user selection. The update is performed by an AJAX call.
Main GSP (test.gsp)
<%# page contentType="text/html;charset=UTF-8" %>
<html>
<head>
<asset:javascript src="application.js"/>
<asset:stylesheet src="application.css"/>
<title></title>
</head>
<body>
<label>Select an option: </label>
<g:select name="cbOption" noSelection="['':'']" from="${options}" onchange="${remoteFunction(action: 'getPhoneNumberFromPatientId', onSuccess: '\$("#value").val(data)', params:'\'patientId=\' + escape(this.value)')}; \$('#value').focus()"></g:select>
<g:textArea name="value"></g:textArea>
</body>
</html>
The AJAX call happens in the onchange event of g:select. For simplicity I omit some attributes of g:select as optionValue and optionKey.
This GSP is rendered by the following action:
def test() {
def options = ["A","B","C"]
return [options:options]
}
As you can see, this action returns an model to the above GSP that must be called test.gsp since this is name of the action. The variable options is the list of elements that could be selected by the user.
Remote Function
The remote function calls an action called getPhoneNumberFromPatientId and on the onSuccess event updates the textArea called value. The update is performed using JQuery.
${remoteFunction(action: 'getPhoneNumberFromPatientId', onSuccess: '\$("#value").val(data)', params:'\'patientId=\' + escape(this.value)')}
See below the action getPhoneNumberFromPatientId:
def getPhoneNumberFromPatientId(String patientId) {
def phone
if (patientId == "A")
phone = "3332-2222"
else if (patientId == "B")
phone = "4444-2222"
else if (patientId == "C")
phone = "5555-2222"
render phone
}
The actions above doesn't return, the actions render the content. It's a very importante difference. See this answer to understand the difference: Grails updating values in form using Ajax
Basically when you're working with AJAX call you'll render the content. The content could be a variable (as above), an HTML snippet or a GSP template.
Please, check the source code of your page (in your browser) to understand that your g:remoteFunction was rendered as a JQuery AJAX call.
Bonus
After the AJAX call I set the focus on the textArea. This is done using JQuery too. See the end of the onchange event to understand this part.
How to get the values from jQuery and assign it for hidden field and save it into the DB?
Actually I am developing a project, where there is some jQuery code for a button:
$(document).ready(function () {
$("#btnYes").click(function () {
$("#btnYes").html("Counted");
$("#<%= hdnYesNoAnswer.ClientID %>").val("Yes");
$('#txtComment').focus();
});
});
When I clicked the #btnYes, it changes to "Clicked". In that page I added one hidden field called #hdnYesNoAnswer. So now what I want is to get the value ("Yes") from that jQuery function and assign it to hidden field #hdnYesNoAnswer and save that hidden field value to the SQL Server database.
#Maris is right. Ajax is a defacto technic for these actions. Here are some links. I hope they help
http://api.jquery.com/jquery.ajax/
http://en.wikipedia.org/wiki/Ajax_(programming)
https://developer.mozilla.org/en/docs/AJAX
I am new to Rails and working on a quiz application, and am having trouble implementing the timer properly. When a user creates a new quiz, the controller calculates the time they are given based on the number of questions, 1 minute per question, and this is value is stored in the database. The user is then redirected to the first quiz question and the timer starts. They can choose a multiple choice answer, then click "Next" to go to the next question. The problem is that the page for the next question loads and the timer starts over instead of continuing where it left off on the previous page.
The timer is in javascript. It is implemented in my view as a div:
<%= content_tag "div", class: "timer", data: {time: #time} do %><% end %>
I can access the current time in my .js.coffee file (such as when "Next" is clicked) with
$(".timer").countdown("getTimes")
How can I send this time value to the Rails controller / database since it is a javascript/jQuery object?
Or should I try a different approach altogether?
Thanks!
You can store the value returned by the JS timer code in an hidden html input field and retrieve that value as form variable when the form is submitted.
For more info on hidden inputs: http://webdesign.about.com/od/htmltags/p/input-hidden-tag.htm
As per DevDude's guidance, a hidden input field worked to solve this.
My view has the timer in the "content_tag"
The hidden input is placed in the form.
The submit buttons are given a class of "nav-time" to call in coffeescript.
show.html.erb
<%= content_tag "div", class: "timer", data: {time: #time} do %><% end %>
<%= form_tag . . . %>
.
.
<input type="hidden" name="time-submitted" value="">
.
.
<%= submit_tag "Next", class: "nav-time"%>
<%end%>
The coffeescript updates the value of the hidden field.
timed_test.js.coffee
jQuery ->
$('.nav-time').on 'click', (event) ->
times = $(".timer").countdown("getTimes")
$('input[name="time-submitted"]').val(times)
The time is passed to the controller through the params[time-submitted], and the database is updated. When the next page, is rendered, the time is where it left off on the previous page.
I have following situation:
I have a risk model and on my view it shows me a table with all risks. The table also includes a check_box_tag, as each risk should be able to be checked. In the tablehead there is a button and if this button is clicked, a method of the risk controller should be called, and it should have all checked risk IDs as parameter.
Actually, I don't know which would be the best way to solve this.
I have following code so far:
View:
<table>
<thead>
<tr>
<th>Risk Name</th>
<th>
<button id="mergerisks">Merge Risks</button>
</th>
</tr>
</thead>
<tbody>
<% Risks.all.each do |risk| %>
<tr>
<td><%= risk.name %></td>
<td><%= check_box_tag 'mergerisks', risk.id %>
</td>
</tr>
<% end %>
</tbody>
</table>
Javascript:
$( "#mergerisks" ).on( "click", function() {
var selectedriskmerge = new Array();
$("input:checked").each(
function() {
selectedriskmerge.push($(this).val());
});
});
Edit
Added the following ajax call to javascript
$.ajax({
url: '/riskmerge',
data:selectedriskmerge,
success:function() {
window.alert("Success!");
}
});
For now the Button only triggers the Javascript, and there are the ID's of all checked Risks are stored in an array.
But now I don't know what would be the best way to call a controller method in the risk controller and pass the IDs of all checked Risks to the method.
Thanks for any help.
NOTE: This is slightly different from what you wanted, but might provide a better user experience since they won't have to click an additional button at the end to update the records so heed with caution. No matter what though you will get a decent example of how to use ajax for your own needs.
First you need to create an action in the controller that updates the record you want which you already have. The twist is that instead of rendering html you will want to render json at the end. Something like this will do.
if risk.update_attribute(check: true)
render :json => { status: "Everything worked!"}
else
render :json => { status: "Something went wrong!"}
end
Next you will want to set up the javascript so that when a check box is clicked, an ajax post is sent to the action that updates the record. You have this partially done with your javascript. Inside your click event, you can have something like
$.post("/risk_update",
// This line below is the parameters sent to the action.
//So your action will recognize params[:risk_id]
{ risk_id: $(".clicked_check_box").attr("value") },
"json")
.done(function (responseText) {
if (responseText.status === "Everything worked!") {
// Do something on success of info being saved
} else if (responseText.status === "Something went wrong!") {
// Do something on failure of info being saved
}
});
Finally, there is a problem with the check box. Do you want the user to uncheck the box and call a record again. This of course goes beyond the discussion of the question but they are some things you have to keep in mind.
Of course in your case you will want to click a button that grabs all the ids and sends them to the action to update the records. One way would be to have javascript inject the id into an array when a check box is marked, then when the user clicks on the submit button the array is sent as params to the action that then loops through the arrays and updates the risks.
I'm sure there are better ways though, that's just the first thing that came to mind.
Your best bet would be to place all of the check boxes inside of a form.
<%= form_tag controller_method_name_your_controller_path, :method => 'get', do %>
...
<%= submit_tag 'submit' %>
<% end %>
Declare the path in the routes.rb file under your_controller
get :controller_method_name
You can group you check boxes together by using check_box:
<%= check_box 'mergerisks', risk.id %>
Then using params[:mergerisks] in the controller will return a hash with risk.id as the keys and a 1 or 0 depending on if the check box is checked.
Some documentation on routes and forms:
http://guides.rubyonrails.org/routing.html
http://guides.rubyonrails.org/form_helpers.html