I am new to jQuery and I am trying to iterate through a list of strings after making an ajax call to a controller. In this controller, I am returning a list of strings and I want to iterate over this list in jquery and present it to the screen. Here is my code.
This is my controller
[HttpPost]
public ActionResult GetComments() {
var cmts = ex.GetComments(psts, psons);
var lstCmt = ex.GetCommentsList(cments, psons);
return Json(lstCmt);
}
This is my view:
<div>
<button id="ldBtn" class="btn btn-primary">Load</button>
</div>
<div id="cments">
</div>
<script src="~/Scripts/jquery-3.2.1.js"></script>
<script>
$(document).ready(function() {
$("#ldBtn").on('click', function(evt) {
$("#cments").empty();
$.ajax({
type: "POST",
dataType: "html",
url: '#Url.Action("GetComments")',
data: {},
success: function(lists) {
//Something needs to be fixed here
$.each(lists, function(i, name) {
$('#comments').append('<p>' + name.Value + '</p>');
});
}
});
});
});
</script>
When I return the list, I am getting a huge string. How do I fix this?
Thanks in Advance
There's a couple of issues in your JS code. Firstly you're telling jQuery to expect a HTML response in the dataType setting. This is why you see the response as a string. This should be changed to JSON instead, that way jQuery will deserialise the response for you.
Secondly you're attempting to concatenate a Value property on each item in the list, yet they are strings (as you state you're returning a List<string> from your action), and will not have that property. You can simply append the name itself. Try this:
$("#ldBtn").on('click', function(evt) {
$("#cments").empty();
$.ajax({
url: '#Url.Action("GetComments")',
type: "POST",
dataType: 'json',
success: function(comments) {
$('#cments').append('<p>' + comments.join('</p><p>') + '</p>');
}
});
});
I assume the #comments/#cments discrepancy is only due to amending parts of your code when creating the question.
Also note that I simplified the append() logic so that it appends all comments in a single call, which should be slightly faster.
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 the following code, checkboxes are being generated by php based on the number of objects. There is one checkbox per object, and the code in the foreach that generates these is as follows (NOTE: this part is working fine, my problem is below):
"<input type='checkbox' name='markAsUnread' id='markRead' value='$sms->id' class='markAsUnread'>",
Here is the jQuery script that I am trying to use to mark any of the "clicked" boxes as "read". This particular script works when the first box is clicked at any time, but I need it to work for any of the boxes clicked (second, third, etc). I only need it to work on one at a time, but I need it to do so with any one selected.
<script type="text/javascript">
var myEl = document.getElementById('markRead');
myEl.addEventListener('click', function() {
var bloop = $('#markRead').val();
$.ajax({
type: 'POST',
url: '/link/to/route',
data: {sms: bloop},
success: function(data) {
window.location = '/foo/bar';},
contentType: "application/json",
dataType: 'json'
});
}, false);
</script>
I assume that it is not working because it is only grabbing the first box, so what needs to be changed to make it work with any of the selected checkboxes?
That should not work. If you repeatedly create elements with the same id, you violate html rules. There can only be one.
Instead of applying the function to only one element, identified with an ID, as
var myEl = document.getElementById('markRead');
ask for all elements with the name "markRead":
var myElements = document.getElementsByName('markRead');
which gives you an array to iterate over.
Additionally change your jquery-selector from
$('#markRead')
to
$("[name=markRead]")
Also, make sure that id-values are actually unique within one html document.
try following script and check
<script type="text/javascript">
$(function(){
var myElements = $('input[name=markAsUnread]');
myElements.click(function() {
var bloop = $('input[name=markAsUnread]:checked').val();
$.ajax({
type: 'POST',
url: '/link/to/route',
data: {sms: bloop},
success: function(data) {
window.location = '/foo/bar';},
contentType: "application/json",
dataType: 'json'
});
}, false);
});
</script>
Also, remove ID attribute from your generated checkboxes or make it Unique instead of having same value for all elements.
So I solved it, iterating over the elements and adding a click listener within the iterator seemed to do the trick:
$(function(){
var myElements = document.getElementsByName('markAsUnread');
$.each(myElements, function (index){
$(this).on("click", function(){
$.ajax({
type: 'POST',
url: '/foo/bar',
data: {sms: $(this).val()},
success: function(data) {
window.location = '/back/home';},
contentType: "application/json",
dataType: 'json'
});
});
});
});
I also removed IDs from the PHP generated checkboxes, as I wasn't using them.
I have two buttons on the form I'm getting, this first piece of coce allow me to know which was the button clicked by getting the id of it.
var button;
var form = $('.register_ajax');
$('#vote_up, #vote_down').on("click",function(e) {
e.preventDefault();
button = $(this).attr("id");
});
and this other send the form data through AJAX using the info already obtained from the button using the script above.
form.bind('submit',function () {
$.ajax({
url: form.attr('action'),
type: form.attr('method'),
cache: false,
dataType: 'json',
data: form.serialize() + '&' + encodeURI(button.attr('name')) + '=' + encodeURI(button.attr('value')) ,
beforeSend: function() {
//$("#validation-errors").hide().empty();
},
success: function(data) {
if(data.message == 0){
$("#fave").attr('src','interactions/favorite.png');
$("#favorite").attr('value',1);
console.log(data.errors);
}
if(data.message == 1)
{
$("#fave").attr('src','interactions/favorite_active.png');
$("#favorite").attr('value',0);
}
if(data.message == "plus")
{
$("#vote_up").attr('class','options options-hover');
$("#vote_down").attr('class','options');
console.log(data.message);
}
if(data.message == "sub")
{
$("#vote_down").attr('class','options options-hover');
$("#vote_up").attr('class','options');
console.log("sub");
}
},
error: function(xhr, textStatus, thrownError) {
console.log(data.message);
}
});
return false;
});
The problem is that the data is not being passed to the ajax function, the button info is being saved on the button var, but it's not being obtained at time on the ajax call to work with it (or at least that is what I think). I'd like to know what can I do to make this work, any help appreciated.
1st edit: If I get the button data directly like button = $('#vote_up'); it doesn't work either, it only works if I get the button directly like this but without using the function.
2nd edit: I found the solution, I posted below.
var button is in the scope of the .on('event', function(){})
You need to declare the variable in the shared scope, then you can modify the value inside the event callback, i.e.
var button,
form = $('.register_ajax');
$('#vote_up, #vote_down').on("click",function(e) {
e.preventDefault();
button = $(this).attr("id");
});
You are being victim of a clousure. Just as adam_bear said you need to declare the variable outside of the function where you are setting it, but you are going to keep hitting these kind of walls constantly unless you dedicate some hours to learn the Good Parts :D, javascript is full of these type of things, here is a good book for you and you can also learn more from the author at http://www.crockford.com/.
I Found the solution, I just changed a little bit the click function like this:
var button;
var form = $('.register_ajax');
var data = form.serializeArray();
$('#vote_up, #vote_down').on("click",function(e) {
e.preventDefault();
button = $(this).attr("id");
data.push({name: encodeURI($(this).attr('name')), value: encodeURI($(this).attr('value'))});
form.submit();
});
using e.preventDefault(); and form.submit(); to send the form. also I changed the data.serialize to serializeArray(); because it's more effective to push data into the serializeArray(). in the second script I just changed the data.serialize() and used the data variable that I already filled with the serializeArray() and the data.push():
form.bind('submit',function () {
alert(button);
$.ajax({
url: form.attr('action'),
type: form.attr('method'),
cache: false,
dataType: 'json',
data: data,
//here goes the rest of the code
//...
});
return false;
});
it worked for me, it solved the problem between the click and submit event that wasn't allowing me to send the function through ajax.
Understand already done process for single object and single data, which is working pretty cool.
1) output from the PHP Server encoded into JSON format.
JSON OUTPUT:
{"product_id":"1","sku":"FGDGE43","set":"4","type":"simple","categories":["2"],"websites":["1"],"type_id":"simple","name":"Honey","description":"Where sweetness belong.","short_description":"Sweetness.","weight":"100.0000","old_id":null,"news_from_date":null,"news_to_date":null,"status":"1","url_key":"hgjjhgjh","url_path":"hgjjhgjh.html","visibility":"4","category_ids":["2"],"required_options":"0","has_options":"0","image_label":"Honey","small_image_label":"Honey","thumbnail_label":"Honey","created_at":"2014-02-10 14:36:54","updated_at":"2014-02-19 11:37:07","country_of_manufacture":null,"price":"43.0000","group_price":[],"special_price":null,"special_from_date":null,"special_to_date":null,"tier_price":[],"minimal_price":null,"msrp_enabled":"2","msrp_display_actual_price_type":"4","msrp":null,"enable_googlecheckout":"1","tax_class_id":"0","meta_title":null,"meta_keyword":null,"meta_description":null,"is_recurring":"0","recurring_profile":null,"custom_design":null,"custom_design_from":null,"custom_design_to":null,"custom_layout_update":null,"page_layout":null,"options_container":"container2","gift_message_available":null,"0":{"file":"\/h\/o\/honey.jpg","label":"Honey","position":"1","exclude":"0","url":"http:\/\/127.0.0.1\/magento\/media\/catalog\/product\/h\/o\/honey.jpg","types":["image","small_image","thumbnail"]}}
2) Now
I can fetch above mentioned SINGLE JSON object through jQuery and dynamically change the content of the page.
$(document).ready( function() {
alert('bhoom : oh yea its coming');
$.ajax({
type: 'POST',
url: 'http://127.0.0.1/midserver.php',
data: 'id=testdata',
dataType: 'text',
cache: false,
success: function(data) {
var json = $.parseJSON(data);
$('#pname').html(json.name);
$('#pdesc').html(json.description);
$('#pprice').html(json.price);
$('#pweight').html(json.weight);
},
});
});
This is working fine.
Here come my Question
How can i fetch two or more object through JS or JQ and create dynamic elements though JS/JQ or any other mechanism and then put this data in dynamically generated elements.
i.e : for below mentioned JSON object ?
[{"product_id":"1","sku":"FGDGE43","set":"4","type":"simple","categories":["2"],"websites":["1"],"type_id":"simple","name":"Honey","description":"Where sweetness belong.","short_description":"Sweetness.","weight":"100.0000","old_id":null,"news_from_date":null,"news_to_date":null,"status":"1","url_key":"hgjjhgjh","url_path":"hgjjhgjh.html","visibility":"4","category_ids":["2"],"required_options":"0","has_options":"0","image_label":"Honey","small_image_label":"Honey","thumbnail_label":"Honey","created_at":"2014-02-10 14:36:54","updated_at":"2014-02-19 11:37:07","country_of_manufacture":null,"price":"43.0000","group_price":[],"special_price":null,"special_from_date":null,"special_to_date":null,"tier_price":[],"minimal_price":null,"msrp_enabled":"2","msrp_display_actual_price_type":"4","msrp":null,"enable_googlecheckout":"1","tax_class_id":"0","meta_title":null,"meta_keyword":null,"meta_description":null,"is_recurring":"0","recurring_profile":null,"custom_design":null,"custom_design_from":null,"custom_design_to":null,"custom_layout_update":null,"page_layout":null,"options_container":"container2","gift_message_available":null},[{"file":"\/h\/o\/honey.jpg","label":"Honey","position":"1","exclude":"0","url":"http:\/\/127.0.0.1\/magento\/media\/catalog\/product\/h\/o\/honey.jpg","types":["image","small_image","thumbnail"]}],{"product_id":"2","sku":"asdf654a6sd5f4","set":"4","type":"simple","categories":[],"websites":["1"],"type_id":"simple","name":"Butter","description":"Buttery Buttery Buttery","short_description":"Buttery Buttery ","weight":"100.0000","old_id":null,"news_from_date":null,"news_to_date":null,"status":"1","url_key":"butter","url_path":"butter.html","visibility":"4","category_ids":[],"required_options":"0","has_options":"0","image_label":"butter","small_image_label":"butter","thumbnail_label":"butter","created_at":"2014-02-25 11:35:49","updated_at":"2014-02-25 11:53:10","country_of_manufacture":null,"price":"100.0000","group_price":[],"special_price":null,"special_from_date":null,"special_to_date":null,"tier_price":[],"minimal_price":null,"msrp_enabled":"2","msrp_display_actual_price_type":"4","msrp":null,"enable_googlecheckout":"1","tax_class_id":"0","meta_title":null,"meta_keyword":null,"meta_description":null,"is_recurring":"0","recurring_profile":null,"custom_design":null,"custom_design_from":null,"custom_design_to":null,"custom_layout_update":null,"page_layout":null,"options_container":"container2","gift_message_available":null},[{"file":"\/b\/u\/butter.jpg","label":"butter","position":"1","exclude":"0","url":"http:\/\/127.0.0.1\/magento\/media\/catalog\/product\/b\/u\/butter.jpg","types":["image","small_image","thumbnail"]}]]
So,
what i've tried to create 'dynamic content and putting data in that' is here.
$(document).ready( function() {
alert('bhoom : oh yea its coming');
$.ajax({
type: 'POST',
url: 'http://127.0.0.1/test2.php',
data: 'id=testdata',
dataType: 'text',
cache: false,
success: function(data) {
// asumming that server returns more than one products
// in JSON Object.
// So iterate over this JSON Object through .each JQuery
// function.
var divHtml;
var productDiv = $("#productDetailsDiv");
//its reference
$(data).each(function(index, value) {
// Take Html of productTemplate Div in divHtml variable.
divHtml = $('#productsTemplate').html();
// Fill divHtml with values
divHtml.find('#pname').html(value['name']);
divHtml.find('#pdesc').html(value['description']);
divHtml.find('#pimage').html(value['url']);
divHtml.find('#pprice').html(value['price']);
divHtml.find('#pweight').html(value['weight']);
// Add divHtml to productDiv
$("#productDetailsDiv").children().add(divHtml);
// Loop for next value in data
});
},
});
});
So, Am I making mistake to fetching complicated JSON object or there is a code went wrong with jQuery?
Any help or suggestion will be appreciated.
Regards.
try the block with query $.each
$.each(data, function(index, item) {
$('#pname').html(item.name);
$('#pdesc').html(item.description);
$('#pprice').html(item.price);
$('#pweight').html(item.weight);
});
here pname, pdesc... etc,. you need to update with dynamic elements
You can user jquery each function to achieve this:
$(document).ready( function() {
alert('bhoom : oh yea its coming');
$.ajax({
type: 'POST',
url: 'http://127.0.0.1/midserver.php',
data: 'id=testdata',
dataType: 'text',
cache: false,
success: function(data) {
var json = $.parseJSON(data);
$.each(json, function(index, element){
$('#pname').html(element.name);
$('#pdesc').html(element.description);
$('#pprice').html(element.price);
$('#pweight').html(element.weight);
});
},
});
});
Thanks for your suggestion.
I find out that the JSON object i'm getting through PHP server as an output, is in multi-dimensional array. So for the shake of the simplicity, at server side, we have to generate one-dimensional array of JSON object as an output to be fetched and manipulated at client-side.
Now We can do stuff like generating dynamic content on through JS/JQ on HTML page and render(fill-in) the data with the same.
Regards.