Receiving NULL in parameter when passing from js to Servlet. - javascript

I am getting null when trying to receive parameter from JavaScript. I have gone through few post, but could not figure out where i am making the mistake in my code.
Below is code from where i am sending request:
function funcOnChange() {
var index = document.detail.Class.selectedIndex;
var valueSelected = document.detail.Class.options[index].value;
handleRequestStateChange = function()
{
// Check to see if this state change was "request complete", and
// there was no server error (404 Not Found, 500 Server Error, etc)
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
var substring=xmlHttp.responseText;
alert("Alert Dialog! Gaurav");
}
}
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:8080/ReportFetcher/FormHandler', true);
xhr.send(valueSelected);
}
I am getting the valueselected from the following piece of code and valueselected's is correct:
<select name="Class" onchange="funcOnChange()">
<option value="None">None</option>
<option value="FIRST">FIRST</option>
<option value="SECOND">SECOND</option>
<option value="THIRD">THIRD</option>
<option value="FOURTH">FOURTH</option>
<option value="FIFTH">FIFTH</option>
<option value="SIXTH">SIXTH</option>
<option value="SEVENTH">SEVENTH</option>
<option value="EIGHTH">EIGHTH</option>
<option value="NINTH">NINTH</option>
<option value="TENTH">TENTH</option>
</select><br>
I am receiving a callback on onPost() of FormHandler.java
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
log.info("IN form doPost");
String selectedClass = request.getParameter("Class");
log.info(selectedClass);
}
Problem: selectedClass is null here.
Suggest where i am making mistake.

try this
function funcOnChange() {
var index = document.detail.Class.selectedIndex;
var valueSelected = "Class="+document.detail.Class.options[index].text;
.....
.....
xhr.send(valueSelected);
}

If you see through any proxy/ HTTP monitor tool ( I use Charles) your requests and responses you will see that you are not sending the request as key value pairs ( in simple terms you are not sending Class=value) but you are sending only the value of Class attribute as string. (i.e. Third if you select the option Third in the select box). You need to send the FormData if you want to read data on server as key value pairs.
function funcOnChange() {
var index = document.detail.Class.selectedIndex;
var valueSelected = document.detail.Class.options[index].value;
handleRequestStateChange = function()
{
// Check to see if this state change was "request complete", and
// there was no server error (404 Not Found, 500 Server Error, etc)
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
var substring=xmlHttp.responseText;
alert("Alert Dialog! Gaurav");
}
}
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://fiddle.jshell.net/', true);
var form = new FormData();
form.append("Class",valueSelected)
xhr.send(form);
}

Related

How to execute a XMLHttpRequest using onchange event of the select

I'm developing a web page and this web page I can't use php or another dynamic programming language and in this web page I want to get the result of a response from a REST API. I manage do this when the page is opened through this code:
var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", "https://..../select", true); // false for synchronous request
xmlHttp.send();
xmlHttp.onreadystatechange = processInitialRequest;
function processInitialRequest(e) {
if ((xmlHttp.readyState == 4) && (xmlHttp.status == 200)){
var jsonObj = JSON.parse(xmlHttp.responseText);
var i = 0;
var select = document.getElementById("select_manufacturers");
var content = select.innerHTML;
for (i = 0; i< jsonObj.manufacturers.length; i++){
//var opt = document.createElement("option");
var arObj = jsonObj.manufacturers[i];
var enable = arObj['enabled'];
if(enable)
select.options[select.options.length] = new Option(arObj['manufacturer'],arObj['id']);
}
}
}
I have some select components in my webpage:
<select id="select_manufacturers" onchange="processManufacturersChange()">
</select>
<select id="select_devicetypes">
</select>
And when I change the select_manufacturers I want to load the select_devicetypes but when I do this:
function processManufacturersChange(){
var select = document.getElementById("select_manufacturers");
var valueManufacturer = select.options[select.selectedIndex].value;
var textManufacturer = select.options[select.selectedIndex].text;
xmlHttpDeviceTypes.open("https://...../select?manufacturerId=" + valueManufacturer,true);
//process stop here
xmlHttpDeviceTypes.send();
xmlHttpDeviceTypes.onreadystatechange = processDeviceTypesRequest;
}
the process has stopped at the open line. I already enabled CORS at my API but it does not work.
Console said:
(index):149 Uncaught DOMException: Failed to execute 'open' on
'XMLHttpRequest':
'https://.....amazonaws.com/v1/.../select?manufacturerId=10' is not a
valid HTTP method.
at processManufacturersChange (http://localhost/jquery/jquery-ui-1.12.1/:149:21)
at HTMLSelectElement.onchange (http://localhost/jquery/jquery-ui-1.12.1/:58:75)
Anyone can help me?
Thanks for understanding.
is not a valid HTTP method.
The first argument to open has to be the HTTP method, like GET, PUT or POST.
You are passing a URL as the first argument. The URL should be the second argument.

Asynchronous AJAX call completes after function call. Solve WITHOUT JQUERY

I need an AJAX API call to complete before it's containing function does. All the solutions I have looked up use jQuery, which I do not want to add as a dependency just to make a single REST call...
I have been reading the following question How do I return the response from an asynchronous call? and am still attempting to make it work. Again, I do not want to add jQuery as a dependency.
Right now if a failing zip code value is entered, when the user clicks Submit an alert will show the other failing business rules without the "Mismatch in State and Zip." error. When logging to console I see that the REST call is made and a successful response received, but it appears alert(error) is called before the async REST call has completed and appended the value of error.
JS
function checkForm(form){
var state = form.state;
var zip = form.zip;
var error = '';
var flag = 0;
var ckZip = checkZip(state, zip);
if (ckZip.flag == 1){
flag = 1;
}
error += ckZip.error;
// show error and disable form submit if flag == 1
if (flag == 1){
alert(error);
return false;
}
}
function checkZip(state, zip){
var state = form.state;
var zip = form.zip;
var error = '';
var flag = 0;
// check if value entered
if (zip == ''){
error += "Please provide a zip/postal code.\r\n";
flag = 1;
}
// business rule: cannot enter - in a ZIP
if (zip.search(/\x2d/) != -1){
error += "Please remove dash from zip or postal code.\r\n";
flag = 1;
}
// check if state and zip match
// IMPORTANT: Fill in your client key
var clientKey = "this-is-a-valid-key";
var zipcode = zip.substring(0, 5);
var url = "https://www.zipcodeapi.com/rest/"+clientKey+"/info.json/" + zipcode + "/radians";
// Make AJAX request
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.onreadystatechange = function() {
if (this.readyState === 4) {
if (this.status >= 200 && this.status < 400) {alert("Got it");
// Success!
var data = JSON.parse(this.responseText);alert(data.state);
if (data.state != state){
error += "Mismatch in State and Zip.\r\n";
flag = 1;
}
} else {
// Error :(
var response = JSON.parse(this.responseText);
error += "error: " + response.error_msg;
}
}
};
request.send();
request = null;
return {flag: flag, error: error};
}
HTML
<form>
<select id="state" name="state">
<option value="" selected=""></option>
<option value="AA">APO AA</option>
<option value="AE">APO AE</option>
<option value="AP">APO AP</option>
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option>
<option value="AR">Arkansas</option>
<option value="CA">California</option>
<option value="CO">Colorado</option>
<option value="CT">Connecticut</option>
<!-- ... -->
</select>
<input type="text" id="zip" name="zip" value="">
<input type="Submit" id="Submit" name="Submit" value="Continue" onclick="return checkForm(this.form)">
</form>
The only way to make your function actually return the information from the ajax call is to make the ajax call synchronous. I strongly recommend that you don't do that. It locks up the UI of the browser tab (at least) during the call, making for a poor user experience, and moreover there's no need.
Instead, embrace the asynchronous call and learn how to deal with the fact that the function cannot return the information as a return value; see this question and its answers for how to do that. It's really not as difficult as people sometimes think. :-)
Here's how you can make your checkZip work asynchronously:
First, move the call from the submit button to the form itself:
<form onsubmit="return checkZip(this)">
Now, make checkZip always prevent form submission by returning false and have it submit the form when the ajax is done:
function checkZip(form) {
// ...
request.onreadystatechange = function() {
// ...
if (/* it's okay to submit the form*/) {
form.submit(); // Does NOT call the handler again
} else {
// show error to user
}
};
// Stop the initial form submission
return false;
}
Note: The form will not contain the Submit field with the value Continue, since when it was really submitted, that button wasn't pressed. If you need it to, remove the name from the submit button and instead include a hidden field:
<input type="hidden" name="Submit" value="Continue">
But just for completeness, it is possible to make the ajax call synchronous: The third argument to open is a flag where true = asynchronous and false = synchronous, so:
request.open('GET', url, false);
// ----------------------^^^^^
But again, I strongly recommend that you don't do that.
You could either make your XMLHTTPRequest synchronous:
var request = new XMLHttpRequest();
request.open('GET', url, false);
Although as others have pointed out this is not recommended.
Another option would be to wrap your alert in a timeout that defers execution for some small amount of time, enough to give your request time to process:
setTimeout(function() {
// show error and disable form submit if flag == 1
if (flag == 1){
alert(error);
return false;
}
}, 1000);

jquery placeholder while ajax loads dropdown menu

I have a 2 dropdowns, one with a list of countries and one with a list of states. When someone clicks a country, the state dropdown is changed to reflect the ones for that country.
The country dropdown is like this:
<select name="country" id="country" onChange = "states_dropdown(this, 0)">
<option value="001" >United States</option>
<option value="002" >Canada</option>
<option value="003" >Mexico</option>
</select>
And the states/provinces like this:
<select name="state" id="state">
<option value="00101" >Alabama</option>
<option value="00102" >Alaska</option>
<option value="00103" >Arizona</option>
</select>
Obviously, the states change when someone changes the country, with this code:
function state_box(country, user_id) {
var xmlHttp = GetXmlHttpObject();
if (xmlHttp == null) {
alert("Browser does not support HTTP Request");
return;
}
var url = relative_path + 'ajax/states.php';
var action = url + '?country_id=' + country.value;
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) {
document.getElementById('state').innerHTML = xmlHttp.responseText;
}
};
xmlHttp.open("GET", action, true);
xmlHttp.send(null);
}
This all works fine, but the actual problem is that while the server processes the request, the states of the currently selected or default country remain visible. So if someone clicks really fast, he could choose Mexico as the country and Alabama as the state.
The ajax/jquery script states.php that loads the states returns just the option values, that's all.
Is there a way to make it so that while it's loading, it would display:
<option value="">Please wait</option>
and maybe even make the entire box as "disabled" to prevent someone from selecting it?
You can set the dropdown to show a waiting option as the new data loads, you can place this before you make the ajax request.
document.getElementById('state').innerHTML = '<option value="">Please wait</option>';
You can also just disable the dropdown, the advantage of this is that it is reversable(in case the request didn't succeed)
document.getElementById('state').disabled = true;
xmlHttp.onreadystatechange = function() {
if (this.readyState == 4) {
document.getElementById('state').disabled = false;
if (this.status == 200){
document.getElementById('state').innerHTML = this.responseText;
}
}
};
function state_box(country, user_id) {
var xmlHttp = GetXmlHttpObject();
if (xmlHttp == null) {
alert("Browser does not support HTTP Request");
return;
}
var url = relative_path + 'ajax/states.php';
var action = url + '?country_id=' + country.value;
var selectBox = document.getElementById('state'); // save the reference to the element
selectBox.innerHTML = '<option value="">Please wait</option>';
selectBox.disabled = true; // disable the select
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) {
selectBox.innerHTML = xmlHttp.responseText;
selectBox.disabled = false; // enable the select
}
};
xmlHttp.open("GET", action, true);
xmlHttp.send(null);
}
provided the responseText is something like this <option value="00101">city 1</option><option value="00102">city 2</option><option value="00103">city 2</option>
check out this fiddle for reference here

JSP not receiving AJAX response from Servlet

I have a simple jsp page that sends an ajax request to a servlet and awaits a response. Unfortunately, it's not receiving the response after many attempts. The ajax requests are being transmitted but response isn't being received.
As of now, I have a dropdown in my page and a textbox. I am trying to get the value selected in the dropdown to be printed in the textbox on the dropdown's "onchange" event.
Here's my code. Any help regarding this would be very welcome.
JSP PAGE
<script>
function ajaxrequest(){ return new XMLHttpRequest();}
function ac()
{
var myajaxrequest = new ajaxrequest();
if(myajaxrequest==null){alert("AJAX NOT WORKING");}
else
{
alert("AJAX WORKING");
var ind2=document.getElementById("dd1").value;
myajaxrequest.onreadystatechange=connection;
myajaxrequest.open("GET", "../ajaxservlet?dd1="+ind2,true );
myajaxrequest.send(null);
}
}
function connection()
{
if(myajaxrequest.readyState==4)
{
var x=myajaxrequest.responseText;
document.getElementById("result").innerHTML = x;
}
}
</script>
<body>
<form id = "form1" name ="form1" >
<select id="dd1" name="dd1" onchange= "ac()">
<option>Please select </option>
<option>ankur</option>
<option>akshay</option>
</select>
<input type="text" id="result" name="result" />
</form>
</body>
SERVLET :
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("hitting servlet");
String abc = request.getParameter("dd1");
System.out.println(abc);
PrintWriter pw=response.getWriter();
response.setContentType("text/html");
pw.println(abc);
}
The values selected in the dropdown are getting printed in the console but aren't being transmitted back.
Thanks for your time.
myajaxrequest is local to the ac() function since you've used the var keyword. You cannot access it in the connection() function.
Try declaring your connection() function within ac() itself.
Instead of checking the status of readyState, using XHR level 2, you can simply attach a handler to the onload event.
BTW, if native XHR isn't supported ajaxrequest() will throw an error; it won't return null.
Try initializing myajaxrequest globally.

Sending HTML Form Multiple <select> box via POST request with AJAX?

I have an html form with a multiple select box. I can't figure out how to send the values to my php application with AJAX via a post request. It works just fine if I use a GET request and use a single select box but not when I use a multiple select box. The idea is for users to hold control (or command with mac) and select one or more categories. Depending on which categories are selected will determine what other form options will be displayed using AJAX. The select box looks like this:
Edit: SOLVED
<select multiple name="categories[]" onclick="sendCategories(this)">
<option value="0">Category 1</option>
<option value="1">Category 2</option>
<option value="2">Category 3</option>
</select>
My javascript function looks like this:
function sendCategories(sel){
if (window.XMLHttpRequest)
{
xmlhttp=new XMLHttpRequest();
}
else
{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("my_div").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("POST","http://www.mysite.com/update_categories.php",true);
xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
var values = $(sel).serialize();
xmlhttp.send(values);
}
You'll have to generate the query string to send in the POST on your own. Here's the HTML tag to use:
<select multiple name="categories[]" onchange="sendCategories(this);">
And the Javascript function:
function sendCategories(sel){
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
document.getElementById("my_div").innerHTML = xmlhttp.responseText;
}
};
xmlhttp.open("POST","http://www.mysite.com/update_categories.php",true);
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
var values = [], i, j, cur;
for (i = 0, j = sel.options.length; i < j; i++) {
cur = sel.options[i];
if (cur.selected) {
values.push(encodeURIComponent(cur.value));
}
}
if (values.length) {
values = encodeURIComponent(sel.name) + "=" + values.join("&" + encodeURIComponent(sel.name) + "=");
} else {
values = null;
}
xmlhttp.send(values);
}
Note that I changed the event from onclick to onchange, but that's really up to you whether you want this function to run when the element is clicked, or its value is truly changed...it can reduce some unnecessary calls.
This should generate a querystring that is normally used for sending values for a <select> with multiple options selected.
Here's a jsFiddle that demonstrates how the querystring is being generated here: http://jsfiddle.net/kKWQM/
You can do something like this,
<select multiple name="categories[]" onclick="sendCategories(this)">
And Make AJAX using JQuery,
function sendCategories(sel){
var values = $(select).serialize();
console.log (values); // See if you get the serialized data in console.
$.ajax({
type: 'POST',
url: "http://www.mysite.com/update_categories.php"
data: values,
success: function (data) {
document.getElementById("my_div").innerHTML = data;
}
});
}
And FYI, Netscape event binding model is deprecated, you could use the cross browser event binding like this
You can implement the solution however you would like using JS string and array functions. Effectively, the string you need to send to Apache should contain a pattern like:
xxx[]=a&xxx[]=b&xxx[]=c
where the SELECT element's name is xxx[] in your form and a, b, and c are three values the user selected.
So yes, you are repeating a key name as many times as the user selected a different option in the SELECT.
In JS you can use an array of selected options:
selected_options.join("&xxx[]=") to produce that pattern.
jQuery should make this easier for you. Calling .val() on a wrapped select returns an array of the selected values. You just have to post these to the server:
HTML:
<html>
<body>
<form>
<select name="mySelect" multiple="on">
<option value="1">Uno</option>
<option value="2">Dos</option>
<option value="3">Tres</option>
</select>
</form>
<input id="submitButton" type="button" value="Click To Submit"/>
</body>
</html>
JavaScript:
$(function() {
$('#submitButton').click(function() {
var valuesArray = $('select[name=mySelect]').val()
$.ajax({
type: 'POST',
url: '/path/to/php', // your php url would go here
data: { mySelect: valuesArray }
}).done(function(msg) {
// parse response from msg
});
});
});

Categories