I am looping through an AJAX request and adding a list of <li> to a <ul> from the results.
What I am having trouble with is storing DATA being returned from the AJAX request on these items as HTML5 DATA attributes. Here is some example code:
function load_items(json_url, callback) {
// Set a variable to contain all the items
var all_the_items = $('<ul class="all_items_cont"></ul>');
$.ajax({
type: 'GET',
cache:false,
url: json_url,
jsonpCallback: 'jsonCallback',
contentType: "application/json",
dataType: 'jsonp',
success: function(data) {
$.each([].concat(data.item), function(i, post){
// Create An Item
var current_item = $('<li><a>'+ post.title + '</a></li>');
// This is how I tried to add the data... not working
current_item.find('a').data('description',post.description)
// Append Item to <ul>
$(all_the_items).append(current_item);
});
if (typeof callback === 'function') {
callback(all_the_items.html());
}
}
});
}
Ten I call the function and append the HTML to a target <div>:
load_items('http://jsonurl.com',function(html){
$('div#container').append(html)
})
I've found that if I write the DATA into the HTML explicitly than it works just fine, but if I use jQuery to store the data attributes than I cannot retrieve them later.
I can't write the Data Attributes out explicitly in the HTML because sometimes they are an entire JSON feed or really complicated description.
Any ideas?
------ EDIT 5/21/15 3:38pm -------
I am accessing the data using the jQuery data function as such:
$('div#container ul li:first a').data('description')
This is just an example as the code I am actually utilizing is jQuery Droppable and retrieving the content on DROP. This is a lot of unnecessary code for the questions sake.
If I gather your question correctly, what you're trying to do (set arbitrary data on a DOM element, then pull it out as a data-foo="" attribute) isn't something that JQuery was meant to do.
data-foo attributes are not the same as what the .data method sets. Data can flow in one direction, from the attribute to the element's data store (done automagically by JQuery), but not the other way around
If you really want to pull it out as part of the HTML, you'll have to set the data-foo attribute manually.
// attach the data to the DOM element
$(myElement).data('description', post.description);
// set the data-description attribute so we can pull it out as HTML
$(myElement).attr('data-description', post.description);
Another problem I see with your code is that if post.title contains malformed HTML it could break the <a> element when you call $('<a>'+post.title+'</a>').
When setting callback(all_the_items.html()); it will remove the DATA associated with the DOM element and variable and turn it into straight HTML. By changing it to this: callback(all_the_items); it will work.
Related
I have two HTML elements: 1). the div element is a multiple select (it is a predefined widget that automatically creates the multiple select element) and 2). a button that triggers onclick event.
On the JS side, there is the global variable 'prev_selection' which is set to empty array for now. The idea of prev_selection is to remember the array of values in the multiple select div element before user clicks the button. I want to remember the value before and after a click to see what selections have been added/removed.
When the button is clicked, 'sendData()' is called. It gets the selected data from the div element. Then, it performs some operations using the prev_selection to know what the newly selected values are (in the beginning everything is newly selected in the div).
I want to find out the additions/deletions in the selected values between user clicks. For that, I update the prev_selection with 'selected_data' that I get from the div element jut after the click.
But this does not work as expected. There is something happening with the asynchronous Ajax call and I am not able to find a better solution for this. Everytime a click happens you had expect that 'prev_selection' remembers the value before the click but instead when I print it using console.log() (as shown in the code) it already gets updated to the latest selections even before reaching the success function (where it is supposed to get updated).
Thanks in advance! And please let me know if further explanation is required.
<!-- multiple select/deselect div -->
<div id="someSelectionID"></div>
<button id="updateButtonID" onclick="sendData()">Click to send</button>
// at first, no data is selected
var prev_selection = [];
function sendData() {
// get the selected data from the div element "someSelectionID"
let selected_data = $('#someSelectionID').val();
// perform some operations on the selected data
// this operation involves the use of prev_selection
// printing prev_selection already has value of updated click
console.log(prev_selection );
$.ajax({
type: "POST",
url: "<some url>",
dataType: 'json',
contentType: 'application/json;charset=UTF-8',
data: JSON.stringify( < some data > ),
success: function(result) {
console.log(result);
/* once the request is successfully done update the
previous selection to what the current selected data is */
prev_selection = selected_data;
}
});
}
Try this
$.ajax({
type: "POST",
url: "<some url>",
dataType: 'json',
contentType: 'application/json;charset=UTF-8',
data: JSON.stringify( < some data > ),
}
}).then(function(response){
if (response.status === 200){
console.log('succeed');
} else {
console.log('failed')
}
});
So it worked by changing this line
prev_selection = selected_data;
to:
prev_selection = Array.from(selected_data);
Because the prev_selection variable kept changing without me updating, it lead me to believe that it was some kind of reference to value instead of value itself. So just using Array.from to do a shallow copy actually worked.
I can excess a td element from AJAX response but can't change it.
$('#addjob').click(function(){
$.ajax({
type:"POST",
url: 'invoicelist.php',
success: function(response){
$('#forajax').append(response);
$(response).find('.heading').html();
}
});
});
this code works well and selects the text from the <td class='heading'>123</td> but if I want to change this 123 result I write $(response).find('.heading').html('456'); but it doesnt really change anything.
any suggestions?
You're writing the raw HTML into your #forajax container, then creating a new jQuery object with the contents of response. Any changes to the new object will be discarded; they have nothing to do with the HTML you wrote.
Get the object first, modify it, then append:
// create a jQuery object wrapping the returned HTML
var r = $(response);
// update the contents of our new object
r.find('.heading').html('456');
// add the new, updated object to our container
r.appendTo('#forajax');
Change it, then append. That content isn't linked to that variable:
$(response).find('.heading').html('456');
$('#forajax').append(response);
Changing in repsonse will change in the response text but not the appended DOM object. so instead search for dom element where u appended and do there
$('#addjob').click(function(){
$.ajax({
type: "POST",
url: 'invoicelist.php',
success: function(response){
$( '#forajax' ).append(response);
$( '#forajax' ).find('.heading').html( '456' );
}
});
});
My question is as follows: I have started using the $.ajax function with jQuery and I am wondering how I work with the return of an HTML page. The request completes and I can console.log the returned HTML page however I would now like to select a single element from that page. I have had several attempts which included:
$(data).find('p');
$('button').click(function() {
$.ajax(funciton() {
dataType: 'html',.
url: 'localhost/sw',
success: function(data) {
// This is where I would like to select a element or node from the complete
// returned html document
});
});
I know i can simply use .load() which you can provide select criteria but .ajax is the root function to begin with and I would like to learn that way as well for more complicated queries. Second half of this would be should I not be trying to select elements this way and just serve up json or a single key phrase instead of the entire html page? All help is appreciated.
Just pass the returned HTML to jQuery, and treat it like a regular jQuery collection:
$.ajax({
dataType: 'html',.
url: 'localhost/sw',
success: function (html) {
var paragraphs = $(html).find('p');
// Manipulate `paragraphs` however you like. For example:
$(document.body).append( paragraphs );
}
});
Joseph's answer above is correct if you just want to get the objects.But if you want to load the content of that element, you may change this:
var paragraphs = $(html).find('p');
to
var paragraphs = $(html).find('p').html();
Hope it helps.
I'm afraid very similar question has been asked already here, but for some reason it simply outputs "null".
I'm trying to find a div html from an ajax output by id. Below is my script.
// LOAD NAVIGATION
$.ajax({
type: 'POST',
url: 'includes/content/bookingsystem/b_navigation.php',
data: thisButtonType + '=true&loadNav=date',
success: function(output) {
alert(output); // Outputs correctly two divs #navDay, and #navMonth
alert($(output).find('#navDay').html()); // Results into "null"
$('#navDay').html($(output).find('#navDay').html()); // Results in an empty div, since it overwrote the html with 'null' - nothing.
//$('#navDay').replaceWith($('#navDay', output)); // Same here - nada.
//$('#navMonth').html($(output).find('#navMonth').html());
}
});
The first alert(output) results this:
<div id="navDay">Im day nav!</div>
<div id="navMonth">Im month nav!</div>
You need to wrap your two divs in an outer div if you expect to be able to use .find() or $(selector, context) - those functions only find descendent nodes, and you have two sibling nodes in your HTML without a real parent.
You could either do that wrapping server side, or use .wrap().
Furthermore, the .html() function only returns the inner content of your tags, not the tags themselves.
Assuming (based on your use of .replaceWith) that your intention is to replace entire elements, and not just text, I'd go for:
<div>
<div id="navDay">Im day nav!</div>
<div id="navMonth">Im month nav!</div>
</div>
At which point this line from your previously non-working code will work too:
$('#navDay').replaceWith($('#navDay', output));
Try this
// LOAD NAVIGATION
$.ajax({
type: 'POST',
url: 'includes/content/bookingsystem/b_navigation.php',
data: thisButtonType + '=true&loadNav=date',
success: function(output) {
//alert(output); // Outputs correctly two divs #navDay, and #navMonth
//alert($(output).find('#navDay').html()); // Results into "null"
$('#navDay').html($('#navDay', $(output).wrap("<div />")).html()); // Results in an empty div, since it overwrote the html with 'null' - nothing.
//$('#navDay').replaceWith($('#navDay', output)); // Same here - nada.
//$('#navMonth').html($(output).find('#navMonth').html());
}
});
Hello I am using jquery to do some ajax that calls in some data from a database, on the mouseover and element the method runs and I get the expected results, however when I then mouse over another element, the method runs again, however I need to delete the first lot of data from the screen first, this is what I have so far,
$("a.contentlink").mouseover(function(){
var url = $(this).attr("href");
$.ajax ({
url: url,
type: "POST",
success : function (html) {
$('#abstract').append(html);
}
});
});
Can anyone help?
You need to call the empty method first, which removes all children from the matched elements.
For example:
$('#abstract').empty();
Alternatively, you can call the html function, which replaces the contents of the matched element with a string of HTML.
For example:
$('#abstract').html(html);