I'm scratching my head how to combine results of 2 jQuery ajax calls which return the results into the same DOM element. Here is my setup:
there are 2 calls: one from a list of foods and second from a list of ingredients
both calls return a list of ingredients
the idea is to make a shopping list (ingredients to buy) based on 2 sources (list of foods and list of ingredients)
user can create shopping list either by selecting foods (ingredients are retrieved from the database) or he can select ingredients directly from a list of ingredients
Problem: these 2 calls are working fine each on its own. But the problem is that result from one call is always replacing the result from the second call and vice-versa.
var postUrl = "http://localhost:8000/ingredients/";
var ingrUrl = "http://localhost:8000/ingrs/";
var selectedFoods = [];
var selectedIngrs = [];
$('.foods a').click(function(event){
clickedLink = $(this).attr('id');
if (selectedFoods.indexOf(clickedLink) != -1) {
var index = selectedFoods.indexOf(clickedLink);
selectedFoods.splice(index, 1);}
else {
selectedFoods.push(clickedLink);
};
var jsonFoods = JSON.stringify(selectedFoods);
$.ajax({
url: postUrl,
type: 'POST',
data: jsonFoods,
dataType: 'html',
success: function(result){
$('.ingredients').html(result);
}
});
});
$('.ingr-list a').click(function(event) {
clickedIngr = $(this).attr('id');
if (selectedIngrs.indexOf(clickedIngr) != -1) {
var index = selectedIngrs.indexOf(clickedIngr);
selectedIngrs.splice(index, 1);}
else {
selectedIngrs.push(clickedIngr);
};
var jsonIngrs = JSON.stringify(selectedIngrs);
$.ajax({
url: ingrUrl,
type: 'POST',
data: jsonIngrs,
dataType: 'html',
success: function(result){
$('.ingredients').html(result);
}
});
});
I tried to play around with this line $('.ingredients').html(result); using append instead of html but that won't work because the user should be able to take ingredients off the list (see the if conditions in both functions).
Just use different containers for them
<div class="ingredients">
<div id="first"></div>
<div id="second"></diV>
</div>
Then set the .html() of $("#first") and $("#second") instead of .ingredients
Use .append
$('.ingredients').append(result);
see if this is the answer underscore js template
what you need to do is not passing html back, but passing json back, and using js template to render it at the browser.
some fake code:
var global_ingredients = [];
var list = "<% _.each(ingredients, function(ingredient) \
{ %> <li><%= ingredient.name %></li> <% }); %>;";
$.post('', postdata, function(ingredients){
global_ingredients.push(ingredients);
// here you could also eliminate duplicated ingredients,
// sort the ingredients, do whatever you likes
var new_html = _.template(list, global_ingredients);
$('.ingredients').html(new_html);
});
Related
Alright guys I'm trying to make a filter system for posts using ajax and a select box. I am able to get the value from the select box no problem. But my issue is that when I try to include the selected value in my PHP file it doesn't do anything. I have a file called public_wall.php. This file contains PHP, Javascript, and HTML. How can I refresh this div whenever a user selects a different filter option? Basically I need the selected value to be passed onto my public_wall.php file and then I want to plug it into the PHP function that fetches the posts thats's in the same file and then I want to refresh that same file to display the filtered results. Here is my Javascript code.
$("#postRatings").on("click", function(e) {
selectedRatingFilter = $("#postRatings option:selected").val();
var dataString = "timeFilter="+selectedRatingFilter;
jQuery.ajax({
type: "POST",
url: site_url+"public_wall.php",
data: dataString,
dataType: "json",
cache: false,
success: function(response){
hideSpinner();
jQuery('#postsPagingDiv').remove();
jQuery('#wsc_midbox').html(jQuery(response.htmls).fadeIn(400));
setpost_ids(response.all_post_id);
jQuery('#paging_in_process').val(0);
}
});
});
When the dataType is set to "json" nothing happens. But when it is set to html it prints some javascript code. Please help. The PHP file is too large to include here, but it basically contains PHP, HTML, and Javascript and some PHP functions that do sql queries. What is the best way to achieve a filter mechanism for my setup?
And on the public_wall.php file I want to get the value like so:
$ratingFilter = isset($_REQUEST['timeFilter']) ? intval($_REQUEST['timeFilter']) : 0;
And then plug it into the PHP function that fetches the posts which is in the public_wall.php file also so that I can filter the posts based on the selected value. And then finally I want to refresh the public_wall.php file with the new results. I hope that makes sense. Please help.
This is the output when I set my dataType to "html"
<script>
function refreshPosts() {/* only posts comments likes and count updated. */
var posts = jQuery("#all_post_id").val();
var arrays = posts.split(',');
var dataString = "postids="+posts;
jQuery.ajax({
type: "POST",
url: site_url+"includes/update_wall.php",
data: dataString,
dataType: "json",
cache: false,
success: function(response) {
var x = response;
//############ skip posts whose comments are being read by users
var ExemptedPostsIDs = jQuery("#exemptedPostsID").val();
var ExemptedArray = ExemptedPostsIDs.split(',');
ExemptedArray = ExemptedArray.sort();
//////////////
for (i=0; i<arrays.length; i++) {
var val = 'row'+arrays[i];
if(x[val]) {
if(!inArray(arrays[i], ExemptedArray))
jQuery("#ajax_wall_"+arrays[i]).html(x[val]);
} else {
jQuery('#PostBoxID'+arrays[i]).parent().fadeOut(500);
}
}
}
});
}
function inArray(needle, haystack) {
var length = haystack.length;
for (var i = 0; i < length; i++) {
if(haystack[i] == needle) return true;
}
return false;
}
function refreshWall() {/* loads new posts real time */
var posts = jQuery("#all_post_id").val();
var pageUsing = jQuery('#pageUsing').val();
var dataString = "update_posts=1&postids="+posts+'&pagex='+pageUsing;
jQuery.ajax({
type: "POST",
url: site_url+"public_wall.php",
data: dataString,
dataType: "json",
cache: false,
success: function(response) {
if(response.all_post_id) {
jQuery('#wsc_midbox').prepend(jQuery(response.htmls).fadeIn(400));
setpost_ids(response.all_post_id);
}
}
});
}
</script>
I suggest you keep the form with select element and any JavaScript on the outer frame.
Via ajax, only load the results to a seperate DIVision below that.
When you put an Ajax response to a div, any JavaScript inside it will not be executed.
For the best throughput with Ajax, you should consider loading a json response via Ajax and create HTML elements on the client side. That way it becomes much easier to pull additional variables to front-end JS from server side along with the same request/response.
But that becomes bit difficult when you have a template engine in the back-end. You can still send the HTML content in a json value, so you can easily pass the "all_post_id" as well..
I have a one-page structured website. I am trying to use Ajax to update my data on user demand.
I am trying to figure out how to structure my ajax code, so that it will be flexible to my in and outputs = I want to run different function depending on the clicked link, and I want to return the right output to the right div.
HTML links:
<a href="#page-a" class="dbLink" data-variable="funcA">
<a href="#page-b" class="dbLink" data-variable="funcB">
<div id="page-a">
<div id="a-result"></div>
</div>
<div id="page-b">
<div id="b-result"></div>
</div>
JS, ajax (I am passing a data-variable along the link to controle the action):
$(document).on("click", ".dbLink", function(e) {
e.preventDefault();
var theAction = $(this).attr("data-variable");
$.ajax({
url: 'ini/functions.php',
data: { action: theAction },
type: 'post',
dataType: 'json',
success: function(resp){
if(resp.data){
$(resp.target).html(resp.data);
}
}
});
});
functions.php:
include 'dbconnect.php';
function funcA($mysqli){
$result = $mysqli->query("select * from database");
$row = mysqli_fetch_assoc($result);
echo $row['column'];
}
function funcB($mysqli){
$result = $mysqli->query("select * from database2");
$row = mysqli_fetch_assoc($result);
return $row['column'];
}
if (isset($_POST['action'])) {
$resp = null;
switch($_POST['action']) {
case "funcA":
$resp->data = funcA($mysqli);
$resp->target = "#page-a";
break;
case "funcB":
$resp->data = funcB($mysqli);
$resp->target = "#page-b";
break;
default:
break;
}
echo json_encode($resp);
}
add another data-* variable set to the id of the place you want to output the data. To control the format of the returned data provide the dataType option in the ajax options, and of course make sure the pointed to url actually outputs that type of data. dataType It will tell jQuery how to parse the incoming data.
var theContainer = $(this).attr("data-container");
...
dataType:"json" //or text, or xml etc etc
success: function(data){
//if data is upposed to be json
//and datType is set to json
//data will be an object, same with xml
//process data how you need to
$("#"+theContainer).html(whateverYouHaveDone);
}
If you need to control the target of the returned data within your php script then turn your returned data into json and send the selector for the target to it
$resp = new stdClass;
switch($_POST['action']) {
case "funcA":
$resp->data = funcA($mysqli);
$resp->target = "#someContainer";
break;
case "funcB":
$resp->data = funcB($mysqli);
$resp->target = "#someContainer";
break;
default:
break;
}
echo json_encode($resp);
Then in your ajax success
success: function(resp){
if(resp.data){
$(resp.target).html(resp.data);
}
}
And of course set dataType:"json"
To return just the mysql row, do the same thing as above but in the ajax success resp.data will be an object. So just access the properties of resp.data with the column names of the row
success: function(resp){
if(resp.data){
//if say you have a column named "username"
var username = resp.data.username;
}
}
$(document).on("click", ".dbLink", function(e) {
e.preventDefault();
var theAction = $(this).attr("data-variable");
var target = $(this).attr('href');
$.ajax({
url: 'ini/functions.php',
data: { action: theAction },
type: 'post',
success: function(data){
$(target).html(data);
}
});
});
there are many ways to do this.
I see you have understood the custom data-* attributes. I would add one more attribute: data-target=""
<a href="#page-a" class="dbLink" data-variable="funcA" data-target="a-result">
<a href="#page-b" class="dbLink" data-variable="funcB" data-target="b-result">
<div id="page-a">
<div class="a-result"></div>
</div>
<div id="page-b">
<div class="b-result"></div>
</div>
Then inside your JQuery, you do like you do with your data-variable, only that you add the new data-* attribute:
$(document).on("click", ".dbLink", function(e) {
e.preventDefault();
var theAction = $(this).attr("data-variable");
var theTarget = $( this ).attr("data-target");
$.ajax({
url: 'ini/functions.php',
data: { action: theAction },
type: 'post',
success: function(){
/* Here you have to change the data[] to match the JSON return from your PHP-script. You can of course do it without JSON, but I would use http://www.php.net/manual/en/function.json-encode.php on an array from PHP.*/
$("input[class="+ theTarget +"]").html( data["foo"][0]["bar"] );
}
});
});
If you want to play with a real life example, I made this fiddle for another guy on stack overflow a while back: http://jsfiddle.net/Olavxxx/Mu66h/
Put a number in the left box (like 5006), it's postal codes. The target then is the postal adress in the right input box. The concept is very much the same as you are after, with data-targets.
I can't seem to understand how to update a div of items after a category is selected. I've got this far and am now confused. How to get the values from the view into the controller to make the query?
//get <li> clicked and display the items in that category
$(document).ready(function() {
$('#test li').click(function() {
var selector = "input[name='" + $(this).id + "value']";
var catID = $(selector).val();
$.ajax({
url: "...",
type: "get",
data: {//return all the item info},
success: function(data) {
//update div contents here?
}
});
});
});
Partial to be updated upon which category is clicked
#foreach (var item in Model)
{
<ul>
<li>#item.item_name</li>
<li><input type="hidden" class="item_id" value="#item.ID" /></li>
</ul>
}
Controller
public ActionResult PartialTwo( int id)//how to pass category id?
{
var query = from d in db.Items
where d.catId==id
orderby d.dateAdded
select d;
var results = query;
return PartialView("_FullInfoPartial", results);
//returns items in the clicked category
}
instead of two li
<li>#item.item_name</li>
<li><input type="hidden" class="item_id" value="#item.ID" /></li>
you can just use one in order to decrease dom size if it is not required
<li data-id="#item.ID">#item.item_name</li>
and you can get the partial view result with $.get easily
$("#test li").on("click",function(){
var requestPage = "/PartialTwo?id=" + $(this).data("id");
$.get(requestPage, function(result){
$("#content").html(result); // where you want to put the result
});
});
I've answered a very similar question over here, though the example was using PHP. The basic idea is the same however. your MVC4 will return some data type that will be turned into HTML (the easiest way is to just return straight HTML) and then you will append this HTML value to a DOM element (in this case, the div item of your choice).
the JQuery would look similar too:
var request = $.ajax({
type: "POST",
url: "example.php",
data: data_obj,
dataType: "html"
}).done(function(msg) {
$("#example_element").append(msg);
}
Attempting to load a "div" as dynamic content is returned
Use Ajax.BeginForm as follows,
#using (Ajax.BeginForm("Index", "Home", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "youDivId" }))
Using the above and making your controller returning Patial View will update your div with the partial view result.
I've managed to refresh whole pages or single elements with Ajax. However, i am now trying to update my article-comments on the go.
I have an articles page, which outputs all the articles. Beneath each article, there is a table which outputs the comments belonging to the article, and a form to write a new comment.
How do i refresh each of these tables at the same time?
I've been looking at this, but i can't get it implemented correctly:
$(document).ready(function(){
//ajax.php is called every second to get view count from server
var ajaxDelay = 1000;
var ids = [];
$('[id^="zone-"]').each( function() {
ids.push( this.id );
});
setInterval(function(){
$.ajax({
url: 'ajax.php',
dataType: 'json',
type: 'get',
data: { refresh: 'hits', ids: ids },
success: function(data) {
for (var key in data) {
var div = $('#zone-' + key).html( data[key] );
}
}
});
}, ajaxDelay);
});
jQuery AJAX live update on multiple elements on the same page
I'm trying to load some ajax content into a table, unfortunately it's only loading the last row multiple times instead of loading each new rows.
This is the code I'm using:
function periodicRefresh()
{
$.ajax({
type: 'GET',
url: 'include/ajaxActions.php',
data: "action=displayLastEvent",
success: function(msg){
var newid = msg;
current = $("#list tr:first").get(0).id;
if(newid != current){
while (current<newid)
{
current++;
addToList(current);
}
}
}
});
}
function addToList(x)
{
$.ajax({
type: 'GET',
url: 'include/ajaxActions.php',
data: "action=displayRow&row="+x,
success: function(msg){
$("#list").prepend(msg);
$("#list tr:first").highlightFade({
speed:3000
});
lastrow = x-20;
$('#'+lastrow).remove();
}
});
}
displayLastEvent returns the id of the last row.
displayRow returns the last row
You need to push your xmlHttps into an array or abstract data type, which you can then attach events handlers. Seems jquery doesn't do that for you.
I would address this issue by encouraging you to change your approach since it looks like you're likely making more AJAX requests than necessary whenever more rows need to be added to the list (2+ instead of just 2).
I would update include/ajaxActions.php?action=displayRow to accept a CSV of ids (or whatever it is you're passing in), and returning a set of row data, instead of data for just one row.
I think that:
current = $("#list tr:first").get(0).id;
return always the same result as jQuery remember only the page when it was first loaded.
For example, if you have a single tr[id=0]:
pass 1 : current = 0; msg = 1 -> 1 tr prepended with id = 1;
pass 2 : current is always 0 (not 1); msg = 1 -> 1 tr prepended with id = 1;
...
what you should do, is make jQuery recognize your page structure after adding your messages, or store the last index in a different way: using hidden input for example:
HTML:
<input type="hidden" value="0" id="lastId"/>
script:
initialize #lastId value when the page is loaded:
$(document).ready(function(){
$("#lastId").val(0);//or by using your displayLastEvent action
});
modify periodicRefresh to read #lastId value:
function periodicRefresh()
{
$.ajax({
type: 'GET',
url: 'include/ajaxActions.php',
data: "action=displayLastEvent",
success: function(msg){
var newid = msg;
var current = $("#lastId").val();
if(current<newid) $("#lastId").val(newid);
if(newid != current){
while (current<newid)
{
current++;
addToList(current);
}
}
}
});
}