So i am trying to learn Ajax with jQuery, to retrieve some information. At the moment, I have problem to get the information. My code is very simple at the moment, just because I want to learn how it works. This is my HTML code.
<h2>Hello world</h2>
<p id="response"></p>
My jQuery code:
$(function(){
$('h2').on('click', function() {
$.ajax({
url: "ajax.php",
type: "get",
datatype: "json",
success: function(data){
$.each(data, function(i, key){
$("#response").html(key['name'])
});
},
error: function(data){
console.log("tjohejsan");
}
})
});
});
So when I click on h2 it should retrieve data. What I want is to make a call from my database to get information about the users.
So my php code looks like this:
$sql = "SELECT * FROM moment2";
$result = mysqli_query($db,$sql) or die("Fel vid SQL-fråga");
$array = array();
while($row = $result->fetch_assoc())
{
$array[] = $row;
}
echo json_encode($array);
At this point, this is where it fails. I don't know really where the problem is. Because I want an associative array.
I would appreciate it if you could assist me, because as I mentioned, I don't really know how to solve it from here.
Thanks in advance!
EDIT: I realised I had a typo while writing this. changing data['name'] to key['name']
You have issue in the jquery each function. Replace the success function as
success: function(data){
$.each(data, function(i, key){
$("#response").html(key['name'])
});
},
It is because jquery each function has key and value as argument, so only replace "data" by "key" in your this line: $("#response").html(data['name'])
There are a couple places that you are going to run into trouble with this. Here is a JSFiddle for you to reference with my tips below:
https://jsfiddle.net/MrProvolone/zgw9ymv3/2/
There are a few things to consider...
1). Your returned data needs to be converted using parseJSON(), which is a built in jQuery function. This will convert your JSON string into a JavaScript object.
2). When you are looping through your object, you need to include the number (i) that you are trying to access
3). Because we are making a new object variable, we don't need the "key" designator in your $.each() function call... so it becomes $.each(data, function(i){}); instead of $.each(data, function(i, key){});
3). When you are trying to write out your html, you must grab what is already in the container, then add your new html to it, and finally write it all back out to the container.
Here is a step by step:
Instead of:
success: function(data){
$.each(data, function(i, key){
$("#response").html(key['name'])
});
}
We need to add the parsing (and remove the "key" variable per #3 above) so it becomes this:
success: function(data){
var parsed = jQuery.parseJSON(data);
$.each(data, function(i){
$("#response").html(key['name']);
});
}
Now we have a new variable to work off of (parsed) so we need to change both the $.each line, and the .html() line to make sure it uses that new variable....
So this:
$.each(data, function(i, key){
$("#response").html(key['name']);
});
Becomes this:
$.each(parsed, function(i){
$("#response").html(parsed['name']);
});
But that still won't work. We are looping through the object, so when we try to access a value, we have to specify which element in the object we are trying to get to. So anywhere in your loop that looks like this:
parsed['keyname']
becomes this:
parsed[i]['keyname']
So now we have:
$.each(parsed, function(i){
$("#response").html(parsed[i]['name']);
});
At this point you should be getting some html in your container. However, you will notice that you are only getting the value of the last row of your data. That is because you are overwriting ALL of your html in the container in each loop, instead of adding to what is already there. We need to make a new variable to fix this. So this:
$.each(parsed, function(i){
$("#response").html(parsed[i]['name']);
});
Becomes this:
$.each(parsed, function(i){
var oldhtml = $("#response").html();
$("#response").html(oldhtml + '<br>' + parsed[i]['name']);
});
Now you will see each result, with a html line break between each one.
Hope this helps!
In your js, on the success callback, you are using the wrong data, and not appending the data retrieved to the html Tag
Here is an essai
success: function(data){
if(typeof data != "object"){
data = JSON.parse(data);
}
$.each(data, function(i, key){
$("#response").append(key['name'])
});
}
Related
I have a jquery function that sends some data to a method and receives a simple json from the php (the json returns the data sent through get).
$("#filter").submit(function() {
$.ajax({
data:$("form").serialize(),
type: $(this).attr("get"),
url:"get.php",
success: function(response){
$("#rez").html(response);
}
});
return false;
});
This is the json I get
{"list1":["bike","car","bus"],"list2":["1 seat","4 seas","10 seats"],"list3":["cheap","medium","expensive"],"list4":["green energy","bio","petrol"]}
I tried to iterate through it like this:
$.each(response, function(index, val)
{
alert(response[index]);
});
Also, tried this:
alert(val);
How can I iterate through it and make a simple alert?
The goal is to append each item to the "#rez" paragraph. But for now, I just want to iterate through the json and can't figure it out.
ALSO!
I have another json like this:["first val","second val"] how do I iterate this? Tried the above methods and none worked.
Before you start to loop you have to parse the JSON string into an Object and in this case you can do it using something like this:
var obj = JSON && JSON.parse(response) || $.parseJSON(response);
$.each(obj, function(index, val) {
// ...
});
If you don't provide the data type like dataType:"json" in your ajax params object then you have to explicitly parse the string to an object. Read more abour $.parseJSON here.
I had similar issues and used this:
for (var key in someObject) {
if (someObject.hasOwnProperty(key)) {
var something = someObject[key];
console.log(something)
}
}
Basically using "for"-loop here.
To begin with I am building a complete CRM running Ajax and there is a lot to this, so please be patient and read the whole thing.
I have an ajax script returning several json arrays. When I display the return value from my php script I get this:
[{"packages":{"id":"1","name":"Land Line"}},{"packages":{"id":"2","name":"Cellular w\/Alarm.com"}},{"packages":{"id":"3","name":"Home Automation"}}]
What I am trying to do is separate the arrays so I can make a select drop down from it. Before anyone says anything, yes I know how to do that my itself, but I am needing the form this script is populating to be a select dropdown or a complete filled in form based off of the id going into another script. It is a bit confusing, so don't ding me for it please.
Here is the PHP script alliance_form.php:
$equip = "SELECT * FROM packages WHERE brand='$brand'";
if($db->query($equip) === false) {
trigger_error('Wrong SQL: ' . $query . ' Error: ' . $db->error, E_USER_ERROR);
} else {
$result = $db->query($equip);
$array = array();
foreach($result as $r) {
$array[] = array(
"packages" => array(
"id" => $r['id'],
"name" => $r['name']
)
);
}
echo json_encode($array);
}
Here is the jquery going to the PHP form and coming back to input the information:
$.ajax({
type: "POST",
url: "/crm/alliance_form.php",
data: dataString,
success: function(msg)
{
$("#package-form").html(msg);
$.each(msg.packages, function(i, object) {
$.each(object, function(index, value) {
alert(value);
});
});
},
error: function(error)
{
$(".error").html(error);
}
});
This is part of an ordering system of a CRM, so this script is checking the database for existing orders under the id. If the id is there then it is supposed to come back with the order information and I populate the form. If not it will give a select dropdown to select a package which then populates an empty form. That is the gist of what I am on right now.
Here is the question: Why can't I get a response from JQuery on the each() loop on this. One return comes back with a regular array, and this one is a nested array.
I'm not quite clear on what you're asking, but here are my thoughts on this:
You've got .packages in the wrong place. Instead of this:
$.each(msg.packages, function(i, object) {
$.each(object, function(index, value) {
...
You should have written this:
$.each(msg, function(i, object) {
$.each(object.packages, function(index, value) {
...
Better yet, you could just get rid of packages altogether. It's an unnecessary level in the JSON structure.
Also, I don't think jQuery knows that the response is JSON. For this to work, you need either dataType: 'json' in the list of arguments to $.ajax, or something on the server to set the MIME type appropriately.
I'm also concerned about $("#package-form").html(msg);, because msg is not an HTML string.
You should try something like this (Example)
msg = $.parseJSON(msg); // parse JS to object
$.each(msg, function(i, object) {
$.each(object.packages, function(index, value) {
console.log(value);
});
});
Instead of $.each(msg.packages, function(i, object){...}) because msg is an array of objects and in your given example there are three objects right now and each object has a packages item (nested object) which contains id and name.
Update : You can also use, just one loop (Example)
msg = $.parseJSON(msg); // parse JS to object
$.each(msg, function(i, object) {
console.log(object.packages.id);
console.log(object.packages.name);
});
Sorry guys, I threw out my back and couldn't get to my code from home.
Anyways I tried both solutions you provided, and I have been looking at this for a while but neither worked. I have this updated to:
$("#brand").click(function () {
var brand = $(this).attr('rel');
$("#order-form").empty();
var contact_id = $("#contact_id").val();
var dataString = "contact_id=" + contact_id +"&brand=" + brand + "";
//alert("test");
$.ajax({
type: "POST",
url: "/crm/alliance_form.php",
data: dataString,
//dataType: "json",
success: function(msg)
{
//$("#package-form").html(msg);
$.each(msg, function(i, object) {
if(msg.packages) {
$("#package-form").append("<select>");
$.each(object.packages, function(index, value) {
$("#package-form").append('<option value="'+value+'">'+index+'</option>');
});
$("#package-form").append('</select>');
}
});
},
error: function(error)
{
$(".error").html(error);
}
});
});
This just returns nothing not even a blank select box. The $("#package-form").html(msg); is just so I can see the output how the php script is sending it back. The if statement is just to run a verification to see if the array has a nested array with packages in it. I need the return function to do a certain action if it does. Very Important!
As for the dataType: 'json', line in the ajax, it doesn't give me a return value if I have that placed in it. But when I remove it, it will display the array.
Nothing has been changed in the PHP file besides moving the query like suggested.
Ok guys. I got the answer! I have it like this:
$("#brand").click(function () {
$("#order-form").empty();
$("#package-form").empty();
var msg = '[{"packages":{"1":"Land Line"}},{"packages":{"2":"Cellular w\/Alarm.com"}},{"packages":{"3":"Home Automation"}}]';
var newData = JSON.parse(msg);
var newSelect = "<select>";
$.each(newData, function(i, ob) {
$.each(ob.packages, function(index, value) {
newSelect += '<option value="'+index+'">'+value+'</option>';
});
});
newSelect += "</select>";
$("#package-form").append(""+newSelect+"");
});
Here is the fiddle: http://jsfiddle.net/M78vE/
I have a problem with my JQuery script. I am making a 2d chat where people have their own figure like Habbo hotel, but the JQuery script that is suppose to move the figures is bugging.
I think it is easier to show the problem:
Click here to see the problem
I am using the following script to update the figures:
function UpdateRoom() {
var data = 'roomId='+roomId;
$.ajax({
type: "GET",
url: "chatfunctions/updateroom.php",
dataType: 'json',
data: data,
success: function(data){
$.each(data, function(i, data) {
var temp = parseInt(data.field);
$('#f' + temp).append('<div class="user" id="'+charId+'" />');
});
}
});
}
The #f+temp is the id of the field that the figure should be places at. The charId is the id of the figure.
And then I am calling the script every 500 miliseconds:
window.setInterval(function() {
UpdateRoom();
}, 500 );
Im not sure if this is enough code and example for you guys to help me. If not please tell me if I need to provide more for you to help me. My guess is that it is the .append(); function that is used wrong, but I'm no expert in JQuery.
You are only continuing to append but not replacing anything.
Try to either use .html() or .empty().
$.each(data, function(i, data) {
var temp = parseInt(data.field);
$('#f' + temp).html('<div class="user" id="'+charId+'" />');
});
or
$.each(data, function(i, data) {
var temp = parseInt(data.field);
$('#f' + temp).empty(); // clear out all content
$('#f' + temp).append('<div class="user" id="'+charId+'" />');
});
not knowing your code you might need to move the call to .empty() outside your each loop.
I'm not sure if there is any way to do this or not, but this would solve so many of my problems if there is a simple solution to this.
What I need/want to be able to do is return HTML and JSON in my success of ajax request. The reason being, I want to request a file and return all of that page, but I also want to be able to return a specified set of information from the page in json, so I can use it for other things.
This is what I'm doing now:
$.ajax({
type: "POST",
url: "inc/"+page+".php",
data: "id="+encodeURIComponent(pageID),
success: function(html){
$("body > .container").html(html);
}
});
This is what I'd like to be able to do:
$.ajax({
type: "POST",
url: "inc/"+page+".php",
data: "id="+encodeURIComponent(pageID),
success: function(html){
$("body > .container").html(html);
$("title").html(json.PageTitle)
}
});
on the page that is being returned, I would specify what I want the title to be. (For instance, if it's a profile, I would return the user's name)
HTML and data wrapped in JSON
You can do it by returning a 2 element JSON array.
The first element contains HTML and the second element contains another JSON array with the data inside. You just need to unwrap it carefully without breaking anything.
Serverside
$html = '<div>This is Html</div>';
$data = json_encode(array('page_title'=>'My Page'));
$response = array('html'=>$html, 'data'=>$data);
echo json_encode($response);
Clientside
//Ajax success function...
success: function(serverResponse){
$("body > .container").html(serverResponse.html);
var data = JSON.parse(serverResponse.data);
$("title").html(data.page_title)
}
Note 1: I think this is what #hakre meant in his comment on your question.
Note 2: This method works, but I would agree with #jheddings that its probably a good idea to avoid mixing presentation and data. Coding karma will come back to bite.
Trying to mix the retun value to contain presentation and data seems like a potential for confusion. Why not split it into two calls and fetch the data on success of the other?
Something like:
$.ajax({
type: "POST",
url: "inc/"+view_page+".php",
data: "id="+encodeURIComponent(pageID),
success: function(html) {
$("body > .container").html(html);
$.ajax({
type: "POST",
url: "inc/"+data_page+".php",
data: "id="+encodeURIComponent(pageID),
success: function(json) {
$("title").html(json.PageTitle);
}
});
});
You also have the option of including the data in html5 data attributes
For instance, if you're returning a list of Animals
<ul id="ZeAnimals" data-total-animals="500" data-page="2">
<li>Cat</li>
<li>Dog</li>
...
</ul>
You can then collect the data you require using
$('#ZeAnimals').data('total-animals')
Sometimes separating your request into two different ajax calls makes sense also.
You may use a library that does that automatically, like http://phery-php-ajax.net. Using
Phery::instance()->set(array(
'load' => function(){
/* mount your $html and $json_data */
return
PheryResponse::factory()
->json($json_data)
->this() // points to the container
->html($html);
}
))->process();
$(function(){
var $container = $('body > .container');
$container.phery('make', 'load'); // or $container.phery().make('load')
$container.bind('phery:json', function(event, data){
// deal with data from PHP here
});
$container.phery('remote');
});
You may, as well, use phery.views to automatically load a portion of the site automatically, without having to worry about client-side specific code. You would have to put a unique ID on the container, container in this example:
$(function(){
phery.view({
'#container': {}
});
});
Phery::instance()->views(array(
'#container' => function($data, $params){
/* do the load part in here */
return
PheryResponse::factory()
->render_view($html)
->jquery('.title')->text($title);
}
))->process();
I have this for loop in jquery
$(document).ready(function() {
for(i=0; i<counter; i++)
{
dataCounter = i;
$.ajax({
url: 'file.php',
dataType: 'json',
data: dataCounter,
error: function(){
alert('Error loading XML document');
},
success: function(data){
$("#contents").html(data);
}
});
}
});
And then I want to bring in my dataCounter into the file.php as a variable and have it change each time so I can get different records in mysql in file.php, am I doing this right? How would the php portion look like? I know how pass variables to a php file with this method if I had a form, but I don't have a get or a post form to work with. Also, my variables are going to change.
Can someone help me? Thank you!
While I don't recommend running an ajax query inside of a loop, I am wiling to explain the data option for $.ajax(). Ideally, you pass an object as the data option, and it is translated by jQuery into a query string where each object property name is a key and its value is the value:
data: {
count: dataCounter
}
becomes
?count=1
in the query string of the ajax request if datacounter is equal to 1.
In PHP you would access it as $_GET['count'].
data needs to be a key-value pair, not just a value as you have it here. Try something like: (not tested)
$.ajax({
url: 'file.php',
dataType: 'json',
data: ({dataCounter : dataCounter}),
error: function(){
alert('Error loading XML document');
},
success: function(data){
$("#contents").html(data);
}
});