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
Related
I got this code from w3schools. I have edited it and it is connected to a php file which displays all messages whenever a person is selected. The problem is when i change add a new message to the database, it isnt shown unless i change the person, or select the same person again. I wanted to add a periodic function that automatically sends request to db.php after every second and displays all updated messages. But as i dont have much knowledge of AJAX, here i am. can anyone edit the code and do it. Thanks
<html>
<head>
<script>
function showUser(str) {
if (str == "") {
document.getElementById("txtHint").innerHTML = "";
return;
} else {
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else {
// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("txtHint").innerHTML = this.responseText;
}
};
xmlhttp.open("GET","db.php?q="+str,true);
xmlhttp.send();
}
}
</script>
</head>
<body>
<form>
<select name="users" onchange="showUser(this.value)">
<option value="">Select a person:</option>
<option value="1">Peter Griffin</option>
<option value="2">Lois Griffin</option>
<option value="3">Joseph Swanson</option>
<option value="4">Glenn Quagmire</option>
</select>
</form>
<br>
<div id="txtHint"><b>Person info will be listed here...</b></div>
</body>
</html>
Add an id to the select element.
<select name="users" id="users" onchange="showUser(this.value)">
Add the following code just before the body closing tag:
<script>
setInterval(function(){
var e = document.getElementById("users");
var selectedId = e.options[e.selectedIndex].value;
showUser(selectedId);
}, 3000);
</script>
It will send the request after every 3 seconds and will update the content.
What you want to achieve is called polling via AJAX - a better way to go would be Web-Realtime. Technologies in this context are WebSockets or Server-Sent-Events which got introduced in 2014 with HTML5.
A polling javascript module based on Jquery for your needs could look like:
var Polling = (function ($scope) {
var doPoll;
var _callback = function (res) {
console.log(res);
};
var start = function start(url, params, cb, period) {
period = period || 5000;
doPoll = true;
if (cb && typeof cb == 'function') {
_callback = cb;
}
_poll(url, params, period);
};
var stop = function () {
doPoll = false;
};
function _poll(url, params, period) {
Object.assign(params, {polling: true});
$.post(url, params)
.done(function (res) {
_callback(res);
if (!doPoll) return;
setTimeout(function () {
_poll(url, params, period)
}, period);
});
}
return {
start: start,
stop: stop
}
})();
After including jquery and the above script to start polling behaviour (sending a post request every 5th second) simply do:
Polling.start("path-to-your-php-file.php",
{"your": "param"},
function (response) {
// handle the response here
console.log(response);
}
);
To stop it do:
Polling.stop();
Try it out here:
I added a userChanged() function to handle the onchange event of the <select> element. In the function I check to see if the repeating interval has been set and if it is then clear it and set a new one. The interval is set to go off every 1 second, and it passes the variable str into the function showUser(str).
Here is the code:
<html>
<head>
<script>
var timer = false;
function userChanged(str)
{
// if timer is not false it means it is set
if(timer)
{
clearInterval(timer);
timer = false;
}
// When str is '' that means the user has selected 'Select a person:'
if(str != '')
{
timer = setInterval(showUser, 1000, str);
}
else document.getElementById("txtHint").innerHTML = "";
}
function showUser(str)
{
if (window.XMLHttpRequest)
{
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
}
else
{
// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function()
{
if (this.readyState == 4 && this.status == 200)
{
document.getElementById("txtHint").innerHTML = this.responseText;
}
};
xmlhttp.open("GET","db.php?q="+str,true);
xmlhttp.send();
}
</script>
</head>
<body>
<form>
<select name="users" onchange="userChanged(this.value)">
<option value="">Select a person:</option>
<option value="1">Peter Griffin</option>
<option value="2">Lois Griffin</option>
<option value="3">Joseph Swanson</option>
<option value="4">Glenn Quagmire</option>
</select>
</form>
In my code, when a select box is changed, a js function (ConfirmDelete) is called which asks the user if they are sure they want to change the select box. If the user selects no, it will return false and would normally stop the execution.
My problem is that I also have another AJAX/JS function defined after this that is waiting for the select box to be changed and if it is, it sends details to a php script which adds a record into a mysql database.
I'd like to know if there is anyway that I can stop the AJAX/JS code from running after a user has selected No.
The JS function
function ConfirmDelete()
{
var x = confirm("Are you sure?");
if (x)
return true;
else
return false;
}
The AJAX/JS function
$( ".dropdown" ).change(function() {
var request = new XMLHttpRequest();
var id = this.value;
var content = this.name;
request.open("POST", "samefile.php", true);
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.onreadystatechange = function () {
if(request.readyState == 4 && request.status == 200) {
var return_data = request.responseText;
alert (return_data);
}
}
request.send("id="+id+"&content="+content);
window.location.reload();
window.location.reload();
}
);
The HTML Select box
<select class="dropdown" name="09:00-1-0-16-05-26" Onchange="return ConfirmDelete();">
<option class="co0es0sp1fd1oo0fs0" value="47">mike berry</option>
<option value="cancel-47">Cancel</option></select>
The order of the html is
JS Function defined in header
HTML code
AJAX/JS Script tag after
The AJAX/JS function
$( ".dropdown" ).change(function() {
if(!ConfirmDelete()) return; // right here, use this to confirm
var request = new XMLHttpRequest();
var id = this.value;
var content = this.name;
request.open("POST", "samefile.php", true);
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.onreadystatechange = function () {
if(request.readyState == 4 && request.status == 200) {
var return_data = request.responseText;
alert (return_data);
}
}
request.send("id="+id+"&content="+content);
window.location.reload();
window.location.reload();
}
);
Adding onchange event directly in HTML does not solve the problem.
Use this instead;
I am puzzled about this. I have two XMLHttpRequests that operate on Select elements of my HTML file (each one operates on a different Select element right when the HTML file is loaded). I am using a callback function as was recommended on W3CSchools. If my variable xmlHttp is defined outside of my callback function, only the second request works, and the first one gets deleted before it has a chance to finish. If I put 'var' in front of it the same thing happens. However, if my variable is inside the function with 'var' in front of it, then absolutely nothing happens. I have narrowed it down to where to the line that says "HERE!!!!!" is where the program seems to hang. I know the loadXMLDoc function does not actually finish because when I put an alert outside of it, nothing happens. I am supposing it has something to do with the 'if' part and the program not being able to recognize xmlHTTP, even though it was locally defined. I am still pretty new to JavaScript and just want to be able to run multiple XMLHttpRequest objects at once without them getting in each other's way but also without the page hanging. Any ideas why this does not work?
HTML:
<form>
<select id="stateSelectCities">
<!-- Will be populated with MySQL -->
</select>
<select id="citySelect">
<option>Select a State</option>
</select>
<br />
<br />
<select id="stateSelectCounties">
<!-- Will be populated with MySQL -->
</select>
<select id="countySelect">
<option>Select a State</option>
</select>
<p id="xmltest"></p>
<p id="currentState"></p>
<p id="sc"></p>
<p id="rs"></p>
<p id="st"></p>
</form>
JavaScript:
<script type="text/javascript">
function loadXMLDoc(method, data, url, cfunc) {
var xmlHTTP = new XMLHttpRequest();
xmlHTTP.onreadystatechange = cfunc;
xmlHTTP.open(method, url, true);
if (data) {
xmlHTTP.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlHTTP.send(data);
} else {
xmlHTTP.send();
}
}
function returnStateListForCounties() {
loadXMLDoc('GET', null, "stateslist.xml", function() {
document.getElementById('countySelect').disabled = true;
if (xmlHTTP.readyState == 4 && xmlHTTP.status == 200) {
// Read the XML Data and Populate Counties States Menu
var response = xmlHTTP.responseXML;
var states = response.getElementsByTagName('state');
for (i = 0; i < states.length; i++) {
var option = document.createElement('option');
option.innerHTML = states[i].childNodes[0].nodeValue;
option.setAttribute('onmouseup', 'returnCounties(this.innerHTML)');
document.getElementById("stateSelectCounties").add(option);
}
}
//document.getElementById("sc").innerHTML = 'statusCode: ' + xmlHTTP.status;
//document.getElementById("rs").innerHTML = 'readyState: ' + xmlHTTP.readyState;
//document.getElementById("st").innerHTML = 'statusText: ' + xmlHTTP.statusText;
})
}
function returnStateListForCities() {
loadXMLDoc('GET', null, 'stateslist.xml', function() {
document.getElementById('citySelect').disabled = true;
// HERE!!!!!
if (xmlHTTP.readyState == 4 && xmlHTTP.status == 200) {
// Read the XML Data and Populate Cities States Menu
var response = xmlHTTP.responseXML;
var states = response.getElementsByTagName('state');
for (i = 0; i < states.length; i++) {
var option = document.createElement('option');
option.innerHTML = states[i].childNodes[0].nodeValue;
option.setAttribute('onmouseup', 'returnCities(this.innerHTML)');
document.getElementById("stateSelectCities").add(option);
}
}
document.getElementById("sc").innerHTML = 'statusCode: ' + xmlHTTP.status;
document.getElementById("rs").innerHTML = 'readyState: ' + xmlHTTP.readyState;
document.getElementById("st").innerHTML = 'statusText: ' + xmlHTTP.statusText;
})
}
//returnStateListForCounties();
returnStateListForCities();
</script>
The problem here is xmlHTTP variable which is defined inside loadXMLDoc function and try to use again inside returnStateListForCounties function, I'll do it like this:
function loadXMLDoc(method, data, url, cfunc) {
var xmlHTTP = new XMLHttpRequest();
xmlHTTP.onreadystatechange = function() {
if (xmlHTTP.readyState == 4 && xmlHTTP.status == 200)
{
cfunc(xmlHTTP.responseXML); //Call passed func with the resulting XML
}
};
xmlHTTP.open(method, url, true);
if (data) {
xmlHTTP.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlHTTP.send(data);
} else {
xmlHTTP.send();
}
}
This way you encapsulate the data recovery.
i have got following code working well for dropdown menu but as you can see second value (next_val=250f3) is static. i want to make is dynamic should change on click.
<script type="text/javascript">
function showUser(str)
{
if (str == "")
{
document.getElementById("txtHint").innerHTML = "";
return;
}
if (window.XMLHttpRequest)
{
xmlhttp = new XMLHttpRequest();
}
else
{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
document.getElementById("txtHint").innerHTML = xmlhttp.responseText;
}
}
xmlhttp.open("GET", "productlistajax.php?q=" + str + "&next_val=250f3", true);
xmlhttp.send();
}
</script>
here is the drop down menu code.
<select id="maxDaysSinceAdded" name="shorting" onchange="showUser(this.value)">
<option selected='selected' value="1">Most Recent</option>
<option value="2">Lowest Price</option>
<option value="3">Highst Price</option>
</select>
how to use button to pass value live above drop down menu
<button type="button" name="buttonpassvalue" onclick="">Value</button>
thanks
You are calling showUser() on the change event of select tag. So in this case, you will have to read the value from the script itself before sending the ajax request.
You can modify your code as
var buttonValue = document.getElementsByName('buttonpassvalue').item(0).value;
xmlhttp.open("GET", "productlistajax.php?q=" + str + "&next_val=" + buttonValue, true);
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
});
});
});