I would like to add in a with JS from a JSP variable that contains the result of a SQL query.
This is my two inputs :
<tr>
<td><label>Code postal* :</label></td>
<td><input type="number" name="cp" placeholder="CP du lieu de résidence" required /></td>
<td><label>Ville* :</label></td>
<td><select name="ville" required disabled/></select></td>
</tr>
And ths is my JS and JSTL query:
<sql:query dataSource="jdbc/Referentiel" var="communeCp" >
SELECT code_postal, nom_commune_min, insee_commune FROM commune
</sql:query>
<script>
$('input[name=cp]').keyup(function(){
if ($(this).val().length == 5)
{
$('select[name=ville]').prop('disabled', false);
var communeListe = "${communeCp}";
for (var i in communeListe)
{
var currentCp = communeListe[i][code_postal];
var currentVille = communeListe[i][nom_commune_min];
if($('input[name=cp]').val() == currentCp)
{
$('select[name=ville]').append('<option value="'+ currentVille +'">'+ currentVille +'</option>');
}
}
}
else
{
$('select[name=ville]').prop('disabled', true);
}
});
</script>
My navigator say "code_postal is not defined".
I am forced to use ajax to do this ? I really don't know ajax. :/
"code_postal is not defined" happens because of this line of javascript:
var currentCp = communeListe[i][code_postal];
Javascript thinks code_postal is the name of a variable, but there's no "var codePostal = ..." anywhere in your javascript.
Here's what's going on with your JSP page:
First, your JSP is rendered. JSP invokes the SQL query and stores the result in the communeCp variable (an object of type javax.servlet.jsp.jstl.sql.Result).
JSP then replaces this line:
var communeListe = "${communeCp}";
with the result of evaluating "communeCp.toString()". I don't know what that is, but it might be something as simple as the default Object.toString implementation, so this is the actual javascript that would be rendered to the page:
var communeListe = "javax.servlet.jsp.jstl.sql.Result#123456".
Now that the JSP has been rendered, the browser executes the javascript. It fails to even evaluate because you have the undefined code_postal reference, but if for some reason that wasn't a problem, it would fail because you are trying to do a for each loop over the communeListe, but javascript sees that communeListe is just a simple string, so it doesn't make sense to do a for loop over that.
Now, with that understood, I'll try to explain how you could achieve the behavior you want without AJAX.
From your code, it looks like you want the following behavior: A user needs to enter a postal code and select a ville in that postal code. After they've entered 5 characters of their postal code, enable the "ville" dropdown and populate it with the possible villa choices for that postal code.
You have the basic idea for one way to achieve this: Do a query in JSP that gets all postal codes and all villes, then, when the postal code is entered, look through this data somehow in javascript and populate the ville dropdown with the villes that are in that postal code.
The problem is in making the data from the SQL query available to the javascript. Here's how you might do that without AJAX. The basic idea is to initialize a javascript array of objects using a literal which is generated by rendering your JSP:
<sql:query dataSource="jdbc/Referentiel" var="communeCp" >
SELECT code_postal, nom_commune_min, insee_commune FROM commune
</sql:query>
<script>
var communeListe= [];
<c:forEach var="row" items="${communeCp.rows}">
communeListe.push({
code_postal: '${row.code_postal}',
nom_commune_min: '${row.nom_commune_min}',
insee_commune: '${row.insee_commune}'
});
</c:forEach>
$('input[name=cp]').keyup(function(){
if ($(this).val().length == 5)
{
$('select[name=ville]').prop('disabled', false);
$.each(communeListe, function(index, currentRow) {
var currentCp = currentRow.code_postal;
var currentVille = currentRow.nom_commune_min;
if($('input[name=cp]').val() == currentCp)
{
$('select[name=ville]').append('<option value="'+ currentVille +'">'+ currentVille +'</option>');
}
});
}
else
{
$('select[name=ville]').prop('disabled', true);
}
});
</script>
Be warned! This has the potential to make the page very slow to load if you have a lot of rows in the commune table, because you are sending the text of every single row to the user's browser.
For you use case, it would almost certainly be a better overall design to use AJAX. The way this would improve load speeds is that it would only query for the villes that it needs and it would only need to send back a small subset of all possible villes to the user's browser. I can provide a bit of guidance on that:
Basically, you will first need to develop a server-side webservice. You can probably just make this using a Java servlet since you are already using JSP. This servlet will need to accept a postal code as a request parameter and will do a query to the commune database on that postal code (so it should only get rows where postal_code == the postal code request parameter value). It will then return JSON containing an array of objects representing those rows from the commune database, so something like this:
//assume this is the request coming to your webservice
/get_villes?postalCode=12345
//This would be the JSON response returned by your webservice
[
{
'nom_commune_min': 'ville name 1',
'insee_commune': 'insee_commune 1'
},
{
'nom_commune_min': 'ville name 2',
'insee_commune': 'insee_commune 3'
},
... and so on depending on how many villes have that postal code
]
To implement this webservice you could make a simple java object called something like Commune and give it nom_commune_min and insee_commune as fields. Then you could use a simple JSON serialization library like Jackson to serialize that object to a string and return that from your servlet as the body of your HTTP response.
On the frontend side, you'll need to change your javascript so that, when the postal code is entered, it uses $.ajax({ ... }) and invokes that webservice, you made passing it the value of the postal code to lookup.
The call to $.ajax might look something like this (I would probably use $.get just because it's a simpler version of $.ajax):
$.get({
url: "/get_villes?postalCode=" + postalCode,
success: function(communeCp){
$.forEach(communeCp,function(index,currentRow){
//put code here to populate the dropdown list using
//currentRow.postal_code, just like the previous code I provided
});
},
});
Another thing to consider is that, since this is asynchronous, when the browser performs this query, the dropdown is going to be blank for a small time while that query runs (but the user will still be free to interact with the page and might be confused by the blank enabled ville dropdown). So, you need to communicate to the user that you are waiting for results from the webservice when that javascript ajax query runs. So, you could do something like show a "Loading..." text somewhere when they enter the 5 digits of their postal code, and then hide that text in the success function of that $.get (after the dropdown is populated).
Other than that, I would suggest you take some time to wrap your mind around how AJAX and webservices work and look at some tutorials and examples. Webservices, ajax, and everything related to building dynamic websites are a vital part of modern web development.
Related
I am currently trying to implement the pre-built inline editor located here: https://github.com/wbotelhos/inplace
Unfortunately, the support documentation leaves a lot to desire and I have very little experience with Javascript, jQuery, or Ajax.
I have been able to successfully implement the HTML edits:
<td><div class="inplace" data-field-name="name" data-field-value="{{people['name']}}" data-url="/update/{{id}}">{{ people['name'] }}</a></td>
The Js:
<script type="text/javascript">
$('.inplace').inplace();
</script>
and have successfully grabbed, and printed the info sent from the Javascript.
#app.route('/update/<id>', methods=["POST", "PATCH"])
#login_required
def update(id):
new_data = request.get_data(as_text=True)
print(new_data)
return "200"
The issue I am facing, is that the Js returns an Undefined value which is what the HTML updates to.
Ignore the return "200" - I have tired several different methods. Success = True, json values, etc and nothing seems to work.
I am sure I am missing something simple.
It looks like you need to print json with the field name that matches your field_name attribute which is name.
So you will need to print something like this. I don't use python, so you will need to follow actual python syntax. Where the word name is correct, but you will need to add the value that you want shown
print('{"name":"NEW FIELD VALUE"}')
As a follow-up to my last question, I have run into another problem. I am making a project on google homepage replica. The aim is to show search results the same as google and store the search history on a database. To show results, I have used this javascript:-
const q = document.getElementById('form_search');
const google = 'https://www.google.com/search?q=';
const site = '';
function google_search(event) {
event.preventDefault();
const url = google + site + '+' + q.value;
const win = window.open(url, '_self');
win.focus();
}
document.getElementById("s-btn").addEventListener("click", google_search)
To create my form, I have used the following HTML code:-
<form method="POST" name="form_search" action="form.php">
<input type="text" id="form_search" name="form_search" placeholder="Search Google or type URL">
The terms from the search bar are to be sent to a PHP file with the post method. I have 2 buttons. Let's name them button1 and button2. The javascript uses the id of button1 while button2 has no javascript and is simply a submit button.
The problem is that when I search using button1, the search results show up but no data is added to my database. But when I search using button2, no results show up( obviously because there is no js for it) but the search term is added to my database. If I reverse the id in javascript, the outcome is also reversed. I need help with making sure that when I search with button1, it shows results and also saves the data in the database. If you need additional code, I will provide it. Please keep your answers limited to javascript, PHP, or HTML solutions. I have no experience with Ajax and JQuery. Any help is appreciated.
Tony since there is limited code available so go with what you had stated in your question.
It is a design pattern issue not so much as so the event issue.
Copy pasting from Wikipedia "software design pattern is a general, reusable solution to a commonly occurring problem within a given context in software design. It is not a finished design that can be transformed directly into source or machine code. Rather, it is a description or template for how to solve a problem that can be used in many different situations. Design patterns are formalized best practices that the programmer can use to solve common problems when designing an application or system."
So here is how things play out at present;
forms gets submitted to specific URL i.e. based on action attribute
Requested page gets Query sting in php and lets you play around with it
then from there on .....
3. either you get results from database and return response
4. or you put search request into database and return success response
Problem statement
if its 3 then search request is not added to database if its 4 then results in response to search request are not returned.
Solution
you need to combine both 3 and 4 in to one processing block and will always run regardless of the search query is.
So our design pattern could use mysql transaction so whole bunch of queries would run a single operation example
$db->beginTransaction(); // we tell tell mysql we will multiple queries as single operation
$db->query('insert query');
$results= $db->query('search query');
$db->commit(); // if we have reached to this end it means all went fine no error etc so we commit which will make database record insert query into database. If there were errors then mysql wont record data.
if($results) {echo $results;} else {echo 'opps no result found';}
slightly more safe version
try {
$db->beginTransaction(); // we tell tell mysql we will multiple queries as single operation
$db->query('insert query');
$results= $db->query('search query');
$db->commit(); // if we have reached to this end it means all went fine no error etc so we commit which will make database record insert query into database. If there were errors then mysql wont record data.
if($results) {echo $results;} else {echo 'opps no result found';}
} catch (\Throwable $e) {
// An exception has been thrown must rollback the transaction
$db->rollback();
echo 'oho server could not process request';
}
We have effectively combined two query operation into one always recording into database and always searching in database.
I have 5 textboxes(cfinput) on my form to enter organisation code. What I want to do is, As the user types the Org code, there should be an onkeyup function that will validate the value with all the values in database and if its invalid it should show "Invalid Code."
I have got all the Org codes in an array called OrgIndexArray. I am not getting, how would I do this for all the 5 textboxes (some sort of cfloop?)
<cfquery name="getOrgCodes" datasource="#sqlDS#">
select distinct OrgCode From #SAUserIndex#
</cfquery>
<cfset IndexCodesList = ValueList(getOrgCodes.OrgCode)>
<cfset IndexCodesArray = #ListToArray(IndexCodesList)#>
<script>
var IndexArray=<cfoutput>#SerializeJSON(getOrgCodes,true)# </cfoutput>
$(document).ready(fucntion() {
$('.IndexCodes').on('keyup',function(){
if(!!~jQuery.inArray($this.val(),IndexArray)) {
document.getElementById("message").innerHTML="Invalid Index";
}
});
});
</script>
The issue at the moment is that all your "validation" data is only available serverside. Ideally you want to use javascript for the validation on the form fields as the user types. This way you can do the validation client side without having to make additional calls to the server.
There are few ways to achieve what you want to do:
One (possibly a bit hacky) way to do this is to use Coldfusion to populate a javascript array in your page:
<script>
var myArray = <cfoutput>#serializeJson(OrgIndexArray)#</cfoutput>;
//use javascript to validate the input by checking the cfinput value with the array.
//assuming you have jquery:
$(document).ready(function(){
$('.classOfYourInputHere').on('keyup',function(){
if ($.inArray( $this.val(), arr ))
{
//do something
}
});
});
</script>
Alternatively you can create an API of sorts, that will allow you to do an ajax request to a coldfusion .cfc to retrieve the array data in javascript and then you would proceed similar to the above.
Please note that this is not tested in anyway, but it hopefully should help you in the right direction.
Hello people
I'm trying to figured this out, but I still can't do it.
I have a rails 3 app, I'm working with invoices and payments. In the form for payments I have a collection_select where I display all the invoices number (extracted from a postgres database), and what I'm trying to do is when i select an invoice autopopulate others text_fields (provider, address, etc.) without reloading the page, in the same form.
I know I should use ajax, js, jquery, but I'm a beginner in these languages, so i don't know how or where to start
hope you can help me... thanks
What you are going to want to do is route an ajax call to a controller, which will respond with json containing the information. you will then use jquery to populate the different fields.
In your routes:
get "invoice/:id/get_json", :controller=>"invoice", :action=>"get_json"
In your invoice_controller:
def get_json
invoice = Invoice.find(params[:invoice_id])
render :text => invoice.to_json
end
In your invoice model (if the default to_json method is not sufficent):
def to_json
json = "{"
json += "id:'#{self.id}'"
json += ",date_created:'#{self.date}'"
... //add other data you want to have here later
json += "}"
end
In your javascript file,
$("#invoice_selecter").change(function(){ //calls this function when the selected value changes
$.get("/invoice/"+$(this).val()+"/get_json",function(data, status, xhr){ //does ajax call to the invoice route we set up above
data = eval(data); //turn the response text into a javascript object
$("#field_1").val(data.date_created); //sets the value of the fields to the data returned
...
});
});
You are probably going to run into a few issues, i would highly recommend downloading and installing fire bug if you are not on google chrome.. and if you are, make sure you are using the development tools. I believe you can open them up by right clicking and hitting inspect element. Through this, you should be able to monitor the ajax request, and whether or not it succeeded and things.
I am a real noob when it comes to javascript/ajax, so any help will be very appreciated.
In reference to this question:
Updating a MySql database using PHP via an onClick javascript function
But mainly concerned with the answer left by Phill Sacre. I am wondering if someone could elaborate on how we are(if we can?) passing values/data through his example, using jquery.
The code example left by him is as follows:
function updateScore(answer, correct) {
if (answer == correct) {
$.post('updatescore.php');
}
}
...
<a onclick="updateScore(this, correct)" ...> </a>
Say for example, we are wanting to pass any number of values to the database with php, could someone give me a snippet example of what is required in the javascript function? Or elaborate on what is posted above please?
Thanks again all.
The simplest example I can think of is this. Make your AJAX call in your if block like this:
$.get('updatescore.php', {'score': '222'}, function(d) {
alert('Hello from PHP: ' + d);
});
On your "updatescore.php" script, just do that: update the score. And return a plain text stating wether the update operation was successful or not.
Good luck.
P.S.: You could also use POST instead of GET.
What you would do is on the php server side have a page lets say its update.php. This page will be visited by your javascript in an Ajax request, take the request and put it in a database.
The php might look something like this:
<?php
mysql_connect(...)
mysql_query("INSERT INTO table
(score) VALUES('$_GET["score"]') ")
Your javascript would simply preform an ajax request on update.php and send it the variables as get value "score".
Phil is not passing any values to the script. He's simply sending a request to the script which most likely contains logic to 'update' the score. A savvy person taking his test though could simply look at the HTML source and see the answer by checking to see what the anchor is doing.
To further nitpick about his solution, a set of radio buttons should be used, and within the form, a button or some sort of clickable element should be used to send the values to the server via an ajax request, and the values sent to the server can be analyzed and the status of the answer sent back to the page.
Since you're using jQuery, the code can be made unobtrusive as seen in the following example:
$('#submit_answer').click(function() {
var answer = 'blah' // With blah being the value of the radio button
$.get('updatescore.php',
{'value': answer},
function(d) {
alert('Your answer is: ' + d') // Where d is the string 'incorrect' or 'correct'
}
});
Enjoy.