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.
Related
I am working on a Django environment.
I have created a form in my html page which contains a textbox for input for a label like "Enter your name" .
I have a submit button below the textbox.
I need to pass the inputted name to the button as a value and then this button value is to be passed to a python function in views.py.
Can anyone help me with this ?
To do this you need to use Ajax, its like calling a url in the background without affecting the user. but first to call a a url(view) we need a url and a view. so i will think you have something like this
url('^click/btn/(?P<data>[0-9]+)', views.click_btn, name="btn_click");
and the view
def click_btn(request, data):
# do whatever you want with the data....
return HttpResponse('Done')
now to call this from the fron-end we will use jQuery.ajax
first you have the button
<button id="btn_click">Click me!</button>
now create a script tag and type the following
the script tag must be after the button so he can see it
<!-- if you haven't included jQuery -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
// get your input value...
var data = $('#my_input').val();
$.ajax({
url: `/click/btn/${data}`,
success: function (res) {
// every code in this function will execute when Ajax call the url
alert(`Nice! you called the url and get this data: ${res}`)
}
});
</script>
I use in a form a simple radio button with "YES" or "No", I wish that when I click yes a pop-up window will be automatically shown with this specific message:
Are you sure you want to sell a new membership to [User’s Full Real Name from database] with the number [ number of product from database ] ?
That means at the same time an ajax query will be established to return the name of user and the number of product from database.
I'm not very good in JS/Ajax, can anyone help me with this?
Edit :
I know to do what you wrote in the message bellow,what I'm not sure is how to run the pop-up window automatically when I choose "yes" radio button?
To use ajax, you first need to create a server-side function that does what you need. For instance, a php script that takes a userID and returns the user's full name. Let's suppose you create that script and call it "username.php".
On your page, you'll use a javascript function, such as the jquery .ajax function to send an asynchronous request to username.php. The function call will look something like this:
function lookupUsername(){
$.ajax({
type: "POST",
url: "username.php",
data: { ID: $("#userID").val() }
}).done(function( msg ) {
alert( "Username: " + msg );
});
}
In the above example, I've assumed that the user ID is embedded somewhere on your page in an element with ID="userID". The term $("#userID").val() is a jQuery function that looks up the value of the HTML element called "userID".
Next, you need to call the lookup function when the yes radio button is clicked. So something like:
<input type="radio" name="foo" id="foo" value="yes" onclick="lookupUsername()" />
Note that to use the JQuery framework (The .ajax() function and the $() selector function, you need to include the JQuery framework on your page:
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
It's totally possible to do an ajax call without jQuery, but the code is a little messier.
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>
I am attempt to make a custom autocomplete box but I am having some trouble. Right now I have an input that calls this function on keydown
function pingAutoComplete(event)
{
console.log("pingAutoComlete Called");
window.clearTimeout(window.keyTimeout);
//Wait 2 seconds before we attempt to pingAutoComplete incase user has not finished typing
window.keyTimeout = setTimeout(function() {
jsf.ajax.request(event, "keydown", {execute:'searchTerm',render:'autoCompletePanel'})
autoCompleteLayoutPanel.show();
return false;
}, 2000);
return false;
}
The auto complete panel contains a bunch of selects that look like this
<h:selectOneListbox id="vehicleResult" title="Vehicles"
value="#{searchBean.searchTerm}"
converter="entityConverter"
required="false"
rendered="#{!searchBean.filterAutoComplete().isEmpty()}">
<f:selectItems value="#{searchBean.filterAutoComplete()}"
var="searchItem" itemValue="#{searchItem}"
itemLabel="#{searchItem.displayString}"
itemLabelEscaped="true" />
</h:selectOneListbox>
Now when the javascript is called it seems to be hitting searchBean.filterAutoComplete() on the back end, but it is not actually updating the select list in the gui. Anyone know why?
You have to specify the exact client ID. That is the value of the id attribute of the generated HTML element, not of the JSF component itself. If the JSF components are placed in a <h:form>, then the client ID will by default be prepended with its ID.
Thus the following panelgroup
<h:form id="form">
<h:panelGroup id="autoCompletePanel">
will have a client ID of form:autoCompletePanel. You need to specify exactly that ID in the render attribute. The same rules also applies to execute by the way.
Forgive me if this is already 'somewhere' on StackOverflow, but I don't 100% know exactly what it would come under...
I'm trying to retrieve information from a WebService, store this in an array, and then for each <select> within my ASP.Net Datalist, populate it with the array AND have binding attached to an OnChange event.
In other words, I have an array which contains "Yes, No, Maybe"
I've an ASP.Net Datalist with ten items, therefore I'd have 10 <Select>s each one having "Yes, No, Maybe" as a selectable item.
When the user changes one of those <Select>s, an event is fired for me to write back to the database.
I know I can use the [ID=^ but don't know how to:
a) Get the page to populate the <Select> as it's created with the array
b) Assign a Change function per <Select> so I can write back (the writing back I can do easy, it's just binding the event).
Any thoughts on this?
I have built a simple example that demonstrates, I think, what you are attempting to accomplish. I don't have an ASP.Net server for building examples, so I have instead used Yahoo's YQL to simulate the remote datasource you would be getting from your server.
Example page => http://mikegrace.s3.amazonaws.com/forums/stack-overflow/example-multiple-selects-from-datasource.html
Example steps:
query datasource to get array of select questions
build HTML of selects
append HTML to page
attach change event listener to selects
on select value change submit value
Example jQuery:
// get list of questions
$.ajax({
url: url,
dataType: "jsonp",
success: function(data) {
// build string of HTML of selects to append to page
var selectHtml = "";
$(data.query.results.p).each(function(index, element) {
selectHtml += '<select class="auto" name="question'+index+'"><option value="Yes">Yes</option><option value="No">No</option><option value="Maybe">Maybe</option></select> '+element+'<br/>';
});
// append HTML to page
$(document.body).append(selectHtml);
// bind change event to submit data
$("select.auto").change(function() {
var name = $(this).attr("name");
var val = $(this).val();
// replace the following with real submit code
$(document.body).append("<p>Submitting "+name+" with value of "+val+"</p>");
});
}
});
Example datasource => http://mikegrace.s3.amazonaws.com/forums/stack-overflow/example-multiple-selects-from-datasource-datasource.html
Example loaded:
Example select value changed: