I want to use the following function for all the ajax calls in my site:
function ajaxcall(my_url, my_div, my_data)
{
$(my_div).append('<div style="text-align:center; position:absolute; top:0; left:0; width:100%;"><img src="/images/loading.gif" /></div>');
$.ajax({ url: my_url,
data: {data: my_data},
type: 'get',
success: function(output)
{
$(my_div).html(output);
}
});
}
It gets whatever URL I want and updates the DIV I want, so far so good. The problem is I also need to send 1 or more values and want to predict the names of those values.
<select class="formtext" name="car_id" id="car_id" onChange="ajaxcall('/ajax/carsetup.php', '#car_setups', $(this).val() )">
<option value="1">1</option>
<option value="2">2</option>
</select>
<div id="car_setups">select car</div>
So what this does is send my select value to the function, it works, however I don't know how to call that value anything, right now its called data but I want to name it whatever I wish, in this case car_id, dynamically, even worse I might want to send more values in that function's third slot. How would I get around this?
Right now print_r($_GET); gives me:
Array ( [data] => 2622 )
Just do:
data: my_data,
instead of:
data: {data: my_data},
and you can then pass whatever values you look to your AJAX script, e.g.
<select class="formtext" name="car_id" id="car_id"
onChange="ajaxcall('/ajax/carsetup.php', '#car_setups', {car_id: $(this).val()} )">
That said, you should consider attaching that AJAX call from within your JS itself, rather than inline in the HTML:
$('#car_id').change(function() {
ajaxCall('/ajax/carsetup.php', '#car_setups', {car_id: this.value});
});
Related
As that title says, I am attempting to use the same javascript function multiple times on the same page. Basically, I have 2 separate drop downs that call users via ajax so that even new users will be present. (The site is based off not having to always reload.) Anyways, the way I currently have it setup is something like this...
Javascript:
function getAllUsers() {
(function getAllUsers() {
$.ajax({
url: 'staff/getAllUsers.php',
success: function(data) {
$('#getAllUsers').html(data);
},
complete: function() {
// Schedule the next request when the current one's complete
setTimeout(getAllUsers, 5000);
}
});
})();
}
getAllUsers();
function getAllUsers2() {
(function getAllUsers2() {
$.ajax({
url: 'staff/getAllUsers.php',
success: function(data) {
$('#getAllUsers2').html(data);
},
complete: function() {
// Schedule the next request when the current one's complete
setTimeout(getAllUsers2, 5000);
}
});
})();
}
getAllUsers2();
I am sure that doing it like this is unpractical, hence why I am asking for some guidance now.
This is the current HTML setup for it on the dropdowns:
<select class="select2" name="user" id="getAllUsers" required>
<option selected="true" disabled="disabled">Loading Users...</option>
</select>
<select class="select2" name="user" id="getAllUsers2" required>
<option selected="true" disabled="disabled">Loading Users...</option>
</select>
Obviously the Loading Users... option is replaced when the ajax data is loaded.
Again though, I am sure that a better way of doing this exists.
But whenever I try to do something like this with the html... using the same javascript function, the second one just stays at "Loading Users..."
<select class="select2" name="user" id="getAllUsers" required>
<option selected="true" disabled="disabled">Loading Users...</option>
</select>
<select class="select2" name="user" id="getAllUsers" required>
<option selected="true" disabled="disabled">Loading Users...</option>
</select>
I would think that doing it the way I currently do with multiple functions all calling the PHP file constantly can cause load time issues after a while espically if I add more.
Thank you for any assistance!
Both select2's are using the same endpoint, why not just assign the value in the same ajax request?
Something like this will be okay:
function getAllUsers() {
$.ajax({
url: 'staff/getAllUsers.php',
success: data => {
$('#getAllUsers').html(data);
$('#getAllUsers2').html(data);
},
error: err => {
//$('#getAllUsers').html("<option>test</option>");
//$('#getAllUsers2').html("<option>test</option>");
},
complete: () => {
// Schedule the next request when the current one's complete
setTimeout(getAllUsers, 5000);
}
});
}
getAllUsers();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="select2" name="user" id="getAllUsers" required>
<option selected="true" disabled="disabled">Loading Users...</option>
</select>
<select class="select2" name="user" id="getAllUsers2" required>
<option selected="true" disabled="disabled">Loading Users...</option>
</select>
First, you need to understand why it doesn't work for you and then find a solution.
The problem is that, you are using the same element ID in two separate elements, this is not strictly forbidden and will not throw you any errors, but it points to a wrong implementation.
When you are trying to select elements with the ID getAllUsers using jQuery, it knows that there should be only one such element, so it selects only the first one. Any other elements with the same ID are ignored. That's why it worked only for the first one.
Now, let's try to find solutions.
One solution, as Miroslav Glamuzina suggested is correct and works, but not flexible enough.
Another solution would be using a selector that selects multiple element which is not an ID. The best option is to use element's class, that will be unique for your two (or more) select elements. So if you want to add another one in the future, you don't have to touch the JS code, but only the HTML part.
You can do something like this:
HTML
<select class="select2 getAllUsers" name="user" required>
<option selected="true" disabled="disabled">Loading Users...</option>
</select>
<select class="select2 getAllUsers" name="user2" required>
<option selected="true" disabled="disabled">Loading Users...</option>
</select>
(Note that I also changed the name attribute of the second select, to prevent issues in the future)
JavaScript
(function getAllUsers() {
$.ajax({
url: 'staff/getAllUsers.php',
success: function(data) {
$('.getAllUsers').html(data);
},
complete: function() {
// Schedule the next request when the current one's complete
setTimeout(getAllUsers, 5000);
}
});
}());
WARNING!
If you are planning to use this script publicly, you should pay attention on the security issue in this script.
This script is opened for XSS attacks. Because, you are requesting a remote content and applying its content as HTML without any data validations nor escaping.
I would suggest in your case, to generate a JSON in the PHP script, with the list of users and all the data you need, then on the JavaScript, create option elements using the data from the JSON list.
You should do something like this:
Let's say that this is the JSON received from staff/getAllUsers.php:
[
{"id": 14, "name": "User 1"},
{"id": 16, "name": "User 2"},
{"id": 17, "name": "User 3"}
]
JavaScript:
(function getAllUsers() {
$.ajax({
url: 'staff/getAllUsers.php',
success: function(data) {
try {
const list = JSON.parse(data); // Parse JSON from string to object
const selectEl = $('.getAllUsers').empty(); // Clear the content of both `select` elements
for ( let i=0; i<list.length; i++ ) { // Loop through each item in the JSON array
$('<option />') // Create an `option` element
.attr('value', list[i].id) // Set attribute `value` to `option` element
.text(list[i].name) // Set `option` text (this function also escapes any special characters, which prevents potential XSS attacks)
.appendTo(selectEl); // Add `option` element to both `select` elements
}
} catch (e) {
// Report any errors with the JSON parsing process to the developer console.
console.error(e);
}
},
error: function(jqXHR, textStatus, errorThrown) {
// Track any errors received from the server for debugging purposes
console.error(textStatus, errorThrown);
}
complete: function() {
// Schedule the next request when the current one's complete
setTimeout(getAllUsers, 5000);
},
dataType: 'json' // Expect a `json` back from server
});
}());
I hope you can learn something from this.
Good luck!
sorry for asking such a basic question, but i am new to ajax and i couldn't find a documentation (i dont even know the name of this ajax syntax).i understand other parts of this code snippet but i don't know what am i supposed to put in the url part of the $.ajax function. please help
<form method="GET" action="">
<select name="docSpec" id="docSpec">
<option value="Pulmonary" selected="selected">Pulmonary</option>
<option value="Physician">Physician</option>
<option value="General">General</option>
<option value="Cardiologist">Cardiologist</option>
<option value="pediatrics">pediatrics</option>
</select>
</form>
js:
function do_something() {
var selected = $('#docSpec').val();
$.ajax({
this part-- > url: '/you/php/script.php',
type: 'POST',
dataType: 'json',
data: {
value: selected
},
success: function (data) {
$('#my_div').html(data);
}
});
}
this is the javascript! by the way, i am trying to get a selected option value from a <select> ("supposedly on change as a trigger") without having to submit the form.
You can get the selected value of the <select> using
$('#docSpec').val();
You don't need to use ajax for that. Changing the selected option of a <select> will not trigger form submission or reload the page by default.
You can get the value when it is changed using the change() method:
$('#docSpec').change(function(){
alert(this.value); // You can access the new value here
});
I am attempting to populate a jquery form with data from an XML where the XML has an id that will populate a dropdown in the form and upon selection of an id other form fields will be populated. BTW I will not be using PHP
My XML
<XMLReview>
<plan>
<planNumber>773</planNumber>
<Area>Upper Missouri</Area>
<ID>MISSOURI-NUT</ID>
<Name>Missouri River</Name>
<code>10030101</code>
<County>Broadwater</County>
<Station_ID>M09MISSR05</Station_ID>
</plan>
<plan>
<planNumber>774</planNumber>
<Area>Columbia</Area>
<ID>FLAT-STILL-TPA-2013</ID>
<Name>Sheppard Creek</Name>
<Description>- 3A</Description>
<code>17010210</code>
<County>Flathead</County>
<Station_ID>C09SHEPC04</Station_ID>
</plan>
</XMLReview>
The HTML
<form>
<input type="button" id="btnxml" value="XML" onclick="getXML()" />
ID <input type="text" name="ID" id="ID">
planNumber<input type="text" name="Name" id="planNumber">
area<input type="text" name="Area" id="Area">
Name: <input type="text" name="Name" id="Name">
Description: <input type="text" name="Description" id="Description">
Station ID <input type="text" name="Station_ID" id="Station_ID">
<label class="Code-label" for="code">HUC</label>
<select class="select_code" id="code" name="code" data-iconpos="left" data-icon="grid">
<option></option>
<option> 10010001</option>
<option> 10010002</option>
<option> 10020001</option>
</select>
<label class="county-label" for="County">County</label>
<select class="select_county" id="County" name="County" data-iconpos="left" data-icon="grid">
<option></option>
<option> Beaverhead </option>
<option> Big Horn </option>
<option> Blaine </option>
</select>
</form>
The script
<script>
function getXML()
{
$.get("XMLReview.xml", function(data) {
$.ajax({
type: "GET",
url: "XMLReview.xml",
dataType: "xml",
success: function (xml) {
var select = $('#ID');
$(xml).find('plan').each(function () {
var ID = $(this).find('ID').text();
select.append("<option>" + ID + "</option>");
$("#ID").change(function () {
var selectedIndex = $('#ID option').index($('#ID option:selected'));
var newOpt = $(xml).find("values").eq(selectedIndex).find('value').each(function () {
var value = $(this).text();
});
});
}
});
alert(data);});
}
</script>
Unfortunataly this is not working and I don't know why. Can anyone help me please
One or two things:
You are specifying the onclick event inline:
<input type="button" id="btnxml" value="XML" onclick="getXML()" />
Why not keep everything in one place -- since you already are using quite a bit of jQuery. Just add it to the javascript block like this:
<input type="button" id="btnxml" value="XML" />
and
$('#btnxml').click(function() {
getXML();
});
Without checking your javascript/ajax code, this construction is wrong:
function getXML(){
$.get("XMLReview.xml", function(data) { <<======= REMOVE
$.ajax({
type: "GET",
url: "XMLReview.xml",
dataType: "xml",
success: function (xml) {
var select = $('#ID');
$(xml).find('plan').each(function () {
var ID = $(this).find('ID').text();
select.append("<option>" + ID + "</option>");
$("#ID").change(function () {
var selectedIndex = $('#ID option').index($('#ID option:selected'));
var newOpt = $(xml).find("values").eq(selectedIndex).find('value').each(function () {
var value = $(this).text();
}); //END $(xml).find.eq.find.each
}); //END #ID.change
}); //END $(xml).find.each
alert(data);
} //END AJAX.success fn
}); //END $.ajax
}); //END $.get <<=================================== REMOVE
}
It should look like this:
function getXML(){
$.ajax({
type: "GET",
url: "XMLReview.xml",
dataType: "xml",
success: function (xml) {
var select = $('#ID');
$(xml).find('plan').each(function () {
var ID = $(this).find('ID').text();
select.append("<option>" + ID + "</option>");
$("#ID").change(function () {
var selectedIndex = $('#ID option').index($('#ID option:selected'));
var newOpt = $(xml).find("values").eq(selectedIndex).find('value').each(function () {
var value = $(this).text();
}); //END $(xml).find.eq.find.each
}); //END #ID.change
}); //END $(xml).find.each
alert(data);
} //END AJAX.success fn
}); //END $.ajax
}
The extra $.get() wrapper is unnecessary.
Note that $.ajax() and $.get() and $.post() do the same thing. You are using the more structured $.ajax() construction, which is (IMHO) easier to keep things straight.
$.get() simply hard-codes the type="GET" and $.post() hard-codes the type="POST"
Also, I haven't done much with the XML dataType, but I strongly suspect that xml -- in the success function of your AJAX code block, in this context:
success: function (xml) {
//post ajax code here, for eg.
alert(xml);
}
Is a variable that will contain whatever has been ECHOed/printed/etc from the server side script? I don't believe it's an XML object...
Ok there are kind of a lot of things going on here so I figured a fresh implementation would be easier to understand than a series of corrections (I'll try and note places where your understanding of JavaScript might need some work) First a demo. Now the JavaScript:
$('#btnxml').on('click', function() {
var select = $('#ID'),
xml = $($.parseXML($('#XMLData').text())),
plans = xml.find('plan');
plans.each(function () {
var ID = $(this).find('ID').text();
select.append("<option>" + ID + "</option>");
});
$("#ID").change(function () {
var selectedIndex = $('#ID option').index($('#ID option:selected')),
plan = $(plans[selectedIndex]);
$('#planNumber').val(plan.find('planNumber').text());
$('#Area').val(plan.find('Area').text());
$('#Name').val(plan.find('Name').text());
$('#Description').val(plan.find('Description').text());
$('#Station_ID').val(plan.find('Station_ID').text());
$('#code').val(plan.find('code').text());
$('#County').val(plan.find('County').text());
}).trigger('change');
});
And then the HTML
<script type='text/xml' id='XMLData'>
<XMLReview>
<plan>
<planNumber>773</planNumber>
<Area>Upper Missouri</Area>
<ID>MISSOURI-NUT</ID>
<Name>Missouri River</Name>
<code>10030101</code>
<County>Broadwater</County>
<Station_ID>M09MISSR05</Station_ID>
</plan>
<plan>
<planNumber>774</planNumber>
<Area>Columbia</Area>
<ID>FLAT-STILL-TPA-2013</ID>
<Name>Sheppard Creek</Name>
<Description>- 3A</Description>
<code>17010210</code>
<County>Flathead</County>
<Station_ID>C09SHEPC04</Station_ID>
</plan>
</XMLReview>
</script>
<form>
<input type="button" id="btnxml" value="XML" /><br/>
ID <select type="text" name="ID" id="ID"></select><br/>
planNumber<input type="text" name="Name" id="planNumber"><br/>
area<input type="text" name="Area" id="Area"><br/>
Name: <input type="text" name="Name" id="Name"><br/>
Description: <input type="text" name="Description" id="Description"><br/>
Station ID <input type="text" name="Station_ID" id="Station_ID"><br/>
<label class="Code-label" for="code">HUC</label>
<select class="select_code" id="code" name="code" data-iconpos="left" data-icon="grid">
<option></option>
<option>10010001</option>
<option>10010002</option>
<option>10020001</option>
<option>10030101</option>
<option>17010210</option>
</select>
<br/>
<label class="county-label" for="County">County</label>
<select class="select_county" id="County" name="County" data-iconpos="left" data-icon="grid">
<option></option>
<option>Beaverhead</option>
<option>Big Horn</option>
<option>Blaine</option>
</select>
</form>
First, I made these changes to make this easier to demonstrate in JSFiddle, but they don't necessarily match what your final code will be:
I faked the AJAX request (the other answer here gives you a clear explanation of how to properly use jQuery's excellent AJAX helper methods). When rolling this answer into yours you can just assume that all of this is wrapped in a $.get() that fetches your XML remotely.
I also bound the click handled in JavaScript to $('#btnxml') (this is cleaner, but also because JSFiddle doesn't like onclick attributes that point to named functions), this is not strictly wrong it's just cleaner.
Now for the substantive changes:
You are really trying to do two things, populate your $('#ID') selector (which was originally a <input type='text'> which is incorrect, in this code I updated to to a <select>, and then after it's populated you are trying to bind a change event handler. You had these steps inside each other, and I separated them back out. Also programmaticly changing a <select> doesn't trigger a change event automatically, so I appended a .trigger('change') at the end.
It also appears that you are attempting to take the child nodes of the selected plan and update the corresponding input with the same name. You could use the .childNodes property but this will include TextNodes for all of the white-space between XML nodes, and rather than trying to filter them out I thought it would be cleaner to just map them individually. This may not work for you if your HTML and XML are constantly being updated but the next point I'm going to make possibly would prevent a totally automatic approach anyways.
Selecting an option based on a value presents some challenges. jQuery is very smart. If you have a <select> element with a set of options that don't have value attributes and you try and set that <select> element's .val() by a string of one of those <option>s inside that element it will do the right thing. However if there are no elements that match that value then it will silently pass over it. Your XML has code and County values that do not appear in your HTML. I added the missing code values to show you that it is working, but I didn't add them to the County <select>. If you know all of your possible codes and county's and you can update your HTML then this won't be a problem, if instead you want new values to be appended while old values are just selected, then your code will get a little trickier.
At present I have a small web-form that loads AJAXed data really nicely from a drop down menu:
<select name="showcode" id="showcode">
<option value="1"> First Name</option>
<option value="2"> Last Name</option>
</select>
What I would like to do is create the action from a text link such as:
First Name
Last Name
I don't know how to change the .change(function() { JS to correctly perform an action onclick event to make this happen. Below is the JS part. Any thoughts / help would be greatly appreciated.
$(document).ready(function(){
$("#showcode").change(function() {
var usr = $("#showcode").val();
$("#getassociatedprojects").html('Retrieving..');
$.ajax
({
type: "POST",
url: "/client-stories/data.php",
data: "showcode="+ usr,
success: function(msg)
{
$("#getassociatedprojects").ajaxComplete(function(event, request, settings)
{ $(this).html(msg); });
}
Worked it out.
Assigned a rel and class to the <a href>
First Name
Then changed the Javascript call in to:
$('a.topic').click(function() {
var usr = $(this).attr('rel');
Voila. It worked. :)
I have 3 dropdowns that are created via javascript, they call an 'updateTable' function when a choice gets made.
Ultimately I am trying to 'filter' a table of data depending on choices made in the dropdowns. If the user just picks one of the dropdowns I want the other choices to submit at the same time (just with empty data if they are not selected, or the currently selected choice if they had already chosen them).
My updateTables function looks like this:
function updateTables (creativeVal,stationVal,verticalVal)
{
//-----------------------------------------------------------------------
//Send the filter criteria
//-----------------------------------------------------------------------
$.ajax({
url: 'api.php', //the script to call to get data
data: {"creative": creativeVal, "station": stationVal, "vertical": verticalVal}, //insert url arguments here to pass to api.php for example "id=5&parent=6"
dataType: 'json', //data format
success: function(response) //on recieve of reply
{ //Do the following on Success
$('#results').empty();
updateTableRows(response);
} //end of on success
}); //End Ajax call
}; //End Creative Function
My dropdowns look like this:
<!--DROPDOWNS-->
<div id="dropdowns">
<div id="creativesel">
Creative -
<select name="creative-select" id="creative-select" onChange ="updateTables(this.value);">
<option value="" selected="selected">All</option>
</select>
</div>
<div id="stationsel">
Station -
<select name="station-select" id="station-select" onChange ="updateTables(this.value)">
<option value="" selected="selected">All</option>
</select>
</div>
<div id="verticalsel">
Vertical -
<select name="vertical-select" id="vertical-select" onChange ="updateTables(this.value)">
<option value="" selected="selected">All</option>
</select>
</div>
</div> <!--Dropdowns ending-->
No matter which dropdown is selected - the request goes through appending ?creative=whatever_the_user_selected_from_any_of_the_3_dropdowns
Ultimately I want it append something like ?creative=whatever_selection&vertical=whatever_selection&station=whatever_selection so I can get the data on the other end and do what I need to with it.
Am I sending the json request improperly?
How about something like this: http://jsfiddle.net/joeframbach/2XBVv/
I've moved the onchange event to jquery where it belongs, and am pulling all the values from all dropdowns rather than just the one that changed.
html:
<!--DROPDOWNS-->
<div id="dropdowns">
<div id="creativesel">
Creative -
<select name="creative-select" id="creative-select">
<option value="" selected="selected">All</option>
</select>
</div>
<div id="stationsel">
Station -
<select name="station-select" id="station-select">
<option value="" selected="selected">All</option>
</select>
</div>
<div id="verticalsel">
Vertical -
<select name="vertical-select" id="vertical-select">
<option value="" selected="selected">All</option>
</select>
</div>
</div> <!--Dropdowns ending-->
javascript:
$(function() {
$('#dropdowns select').change(function() {
//-----------------------------------------------------------------------
//Send the filter criteria
//-----------------------------------------------------------------------
$.ajax({
url: '/echo/json', //the script to call to get data
data: {"creative": $('#creative-select').val(), "station": $('#station-select').val(), "vertical": $('#vertical-select').val()}, //insert url arguments here to pass to api.php for example "id=5&parent=6"
dataType: 'json', //data format
success: function(response) //on recieve of reply
{ //Do the following on Success
$('#results').empty();
console.log(response);
} //end of on success
}); //End Ajax call
}); //End Creative Function
});
Add the values for the other dropdowns into your onchange call.
updateTables($('#creative-select').val(), $('#station-select').val(), $('#vertical-select').val())
Alternatively, don't pass the parameters in your onChange method and get the values in the updateTable function.