Check if <div> has been asynchronously loaded with data-url - javascript

I have a JSP with the following <div>:
<div class="articleInfo" data-url="${article.url}/infoSheet"></div>
If there is any data available for the article, then it will be populated inside the <div> like this:
<div class="articleInfo" data-url="${article.url}/infoSheet">
<div class="data">This is data</div>
</div>
If no data is available then the <div> is left as is.
I tried to do a check with jQuery if the "articleInfo" div has any children, but it doesn't, even if I put the check in the end of $(document).ready(function () {} of the last javascript file loaded. I suppose this is due to how the data is loaded with the data-url attribute of the <div>.
How can I check if any data has been populated?

You can use is() with :empty like
$(function(){
// assuming there is single element having class articleInfo
alert($('.articleInfo').is(':empty'));
});
And if your articleInfo div is filled asynchronously then you need to check its data in your ajax callback like,
$.ajax({
url:....
data:...
success:function(data){
if(!data){
// this div url has no data
}
}
});

OK, i suppose You have no callback for this ajax downloading staff, and this operation not leave any signs of doing ajax like data attributes. If so - no callbacks and signs in DOM then my proposition is to do setInterval and in there check divs has data or not:
var checkedCount=0;
var maxCheckCount=5;//we check 5 times
var checkInterval=setInterval(function(){
var $divs=$('div[data-url]');
$divs.each(function(index){
if ( $(this).find("div.data") ){
//our div has data
}else{
//our div has no data ( maybe will be downloaded? )
}
});
checkedCount++;
if (checkedCount==maxCheckCount)
clearInterval(checkInterval);
},1000); //check every 1 sec
So we check 5 times, one on 1 second ( customise it to Your needs). This is not perfect solution, if ajax will be long, then it will stop working before ajax end.
You can also watch changes in DOM:
$('div[data-url]').bind('DOMSubtreeModified', function(e) {
if ($(this).find("div.data")){
//div has data
}else{
//div has no data but in this situation this never calls
}
});

Related

div element hides when load() function is called

I'm working on making ordering by some criterias(e.g. by price, by author) on my jsp page. And using ajax to reload content of div when new sorting option is selected. But when reload function is called, it just hides div on web page. I've checked out, that there are books in session scope needed to be shown and Jquery is included correctly. This is html for choosing criterias to sort by:
<select>
<option id="default">Default</option>
<option id="price">By price</option>
<option id="author">By author</option>
</select>
And here is a code for processing click events for select element:
$(document).ready(function () {
$('select').change(function () {
$( "select option:selected" ).each(function() {
let sortAttr = $('option:selected').attr('id');
$.ajax({
// passing data to servlet
url: 'http://localhost:8080/sort',
type: 'GET',
// sort criteria
data: ({sort: sortAttr}),
// div needed to be reloaded
success: function () {
$('#mydiv').load(' #mydiv');
}
});
})
});
})
And code on jsp page for the div needed to be reloaded:
<div id="mydiv">
<c:forEach var="book" items="${sessionScope.books}">
<div class="col-4"><a href="/home?command=book_details&isbn=${book.ISBN}">
<img src="data:image/jpg;base64,${book.base64Image}">
<h4>${book.title}</h4>
<p>${book.price}$</p>
</a></div>
</c:forEach>
</div>
Any ideas why this happens?
EDIT
Finally, I found out what's happenning. The important thing to notice(especially for me) in .load() function is that whenever we call this function, it actually not just refreshes div content with new data, but makes request to the provided url and on that page(which url we provided) looks for the div selector, gets it's content and then goes back and inserts that content in current div. Notice, that If we don't write url, .load() function will make request to current page (correct me please, If I'm mistaken).
Hope that will help somebody!
First of all, you need to fix the typo in your code. Having space at the beginning of JQuery identifier won't find the required element.
Change this: $('#mydiv').load(' #mydiv');
To this: $('#mydiv').load('#mydiv');
Also, I think you're using it the wrong way.
Check the documentation here
How about
$(function() { // on page load
$('select').on("change", function() { // when the select changes
let sortAttr = $('option:selected', this).map(function() {
return $(this).attr('id')
}).get(); // get an array of selected IDs
if (sortArrr.length > 0) {
$('#mydiv').load('http://localhost:8080/sort?sort=' +
sortAttr.join(',') + // make a comma delimited string
' #mydiv'); // copy myDiv from the result
}
});
})

Updating multiple DIV - tags with a single jQuery script

I have a page that pulls order statuses from a backend system and then shows the status updates on the page. I need to make the page dynamic to load, since now the page takes too long to update at once.
I got my code working so that the HTML page loads up first and then a single status update is loaded on the page.
Components:
index.php -page - basic page w. jQuery code that requests orders_updatestatus.php.
orders_updatestatus.php -page. Pulls info from a backend system and displays info. Receives what order to update via GET.
HTML (index.php - this works)
<div id="updateref"></div>
jQuery: (part of index.php - this works)
<script type="text/javascript">
// Update order status
$(function () {
$.ajax({
url: 'orders_updatestatus.php?reference=100000025',
success: function (data) {
$('#updateref').html(data);
}
});
});
</script>
UPDATED CODE
What I was thinking was that that I need to create a div for every single order so that they could then be updated individually.
$results = $mysqli->query("SELECT reference FROM orders;");
while($row = $results->fetch_assoc()) {
print '<div id="updateref'.$row['reference'].'"></div>';
}
So, with the code above I'll something like this:
<div id="updateref20000"></div>
<div id="updateref20001"></div>
<div id="updateref20002"></div>
<div id="updateref20003"></div>
<div id="updateref20004"></div>
etc..
Everything works great until this point. Now I need your help on building the corresponding jQuery code so that it would update every 'updaterefXX' -div that it sees.
My question is: How to update the following code so that it every updateref -div is updated on the page:
<script type="text/javascript">
// Update order status
$(function () {
$.ajax({
url: 'orders_updatestatus.php?reference=100000025',
success: function (data) {
$('#updateref').html(data);
}
});
});
</script>
Update/clarification: What I need is for the script to pull the orders_updatestatus.php with a GET variable for every div.
Example:
With <div id="updateref1000"> the script requests orders_updatestatus.php?reference=1000 and displays it in <div id="updateref1000"> when ready
With <div id="updateref1001"> the script requests orders_updatestatus.php?reference=1001 and displays it in <div id="updateref1001"> when ready
etc. Thank you!
You can use attribute begins with selector and .each() to iterate all elements having id beginning with "updateref", .replace() to replace portion of id that are not digits to set at query string, set .innerHTML the current element within success callback of $.ajax() call
$("[id^=updateref]").each(function(index, element) {
$.ajax({
url: "orders_updatestatus.php?reference=" + element.id.replace(/\D/g, ""),
success: function(data) {
element.innerHTML = data;
}
});
})

Using jQuery Load Function before DOM Ready

I have a page that renders HTML blocks from another page on the same domain using IDs. My current code:
<div id=”testdiv”></div>
<script>
jQuery(document).ready(function(){
jQuery('#testdiv').load('/references/embed1.html #testdiv2');
});
</script>
While this loads the content correctly, there is a visible lag between the page loading and the jQuery content loading; depending on the DIV contents it sometimes a full second to display then it just pops into place. This is obviously due to the page not attempting to retrieve the HTML content until DOM Ready so I removed the ready function but the Load function doesn’t run. If I use an iFrame instead it appears to load as the browser executes the code but I lose the ability to only include specific DIV IDs and it’s difficult to make it responsive. Looked at $.ajax but apparently Load uses .ajax so it doesn’t look like there will be a difference.
Simply put – how do I load specific DIV ids from another page without waiting for DOM Ready whether jQuery, JavaScript, iFrames or other method? Second question
Thanks
document readywill be triggered until the whole page were loaded, just remove it and .load() will be invoked after #testdiv had finish render on DOM.
here's the example
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<div id="testdiv"></div>
<div id="error"></div>
<script>
$( "#testdiv" ).load( "/references/embed1.html #testdiv2", function( response, status, xhr ) {
alert("Triggered");
if ( status == "error" ) {
var msg = "Err trying to load ";
$( "#error" ).html( msg + xhr.status + " " + xhr.statusText );
}
});
</script>
https://jsfiddle.net/Angel_xMu/rer3yuny/1/
Ajax is not instant, and nothing you do will change that. Therefore, there will always be some form of delay. You can reduce the delay by removing the need for $(document).ready(), however I suspect it still won't be enough to have it do what you were hoping for.
$.get('page.html', function (result) {
// note, you may need to use `.filter` rather than `.find` depending on the structure of `result`
$('#target').html($($.parseHTML(result)).find('#target2'));
});
or leave your code as is minus $(document).ready and move it to after the target div just like in your example.
The only way to completely remove the delay would be to remove the need for using $.ajax by inserting the html directly into the page server-side.

Load Html Content if not exist JQuery AJAX

I have a page with 3 buttons. >Logos >Banners >Footer
When any of these 3 buttons clicked it does jquery post to a page which returns HTML content in response and I set innerhtml of a div from that returned content . I want to do this so that If I clicked Logo and than went to Banner and come back on Logo it should not request for content again as its already loaded when clicked 1st time.
Thanks .
Sounds like to be the perfect candidate for .one()
$(".someItem").one("click", function(){
//do your post and load the html
});
Using one will allow for the event handler to trigger once per element.
In the logic of the click handler, look for the content having been loaded. One way would be to see if you can find a particular element that comes in with the content.
Another would be to set a data- attribute on the elements with the click handler and look for the value of that attribute.
For example:
$(".myElements").click(function() {
if ($(this).attr("data-loaded") == false {
// TODO: Do ajax load
// Flag the elements so we don't load again
$(".myElements").attr("data-loaded", true);
}
});
The benefit of storing the state in the data- attribute is that you don't have to use global variables and the data is stored within the DOM, rather than only in javascript. You can also use this to control script behavior with the HTML output by the server if you have a dynamic page.
try this:
HTML:
logos<br />
banner<br />
footer<br />
<div id="container"></div>
JS:
$(".menu").bind("click", function(event) {
event.stopPropagation();
var
data = $(this).attr("data");
type = $(this).attr("type");
if ($("#container").find(".logos").length > 0 && data == "logos") {
$("#container").find(".logos").show();
return false;
}
var htmlappend = $("<div></div>")
.addClass(type)
.addClass(data);
$("#container").find(".remover-class").remove();
$("#container").find(".hidde-class").hide();
$("#container").append(htmlappend);
$("#container").find("." + data).load("file_" + data + "_.html");
return false;
});
I would unbind the click event when clicked to prevent further load requests
$('#button').click(function(e) {
e.preventDefault();
$('#button').unbind('click');
$('#result').load('ajax/test.html ' + 'someid', function() {
//load callback
});
});
or use one.click which is a better answer than this :)
You could dump the returned html into a variable and then check if the variable is null before doing another ajax call
var logos = null;
var banners = null;
var footer = null;
$(".logos").click(function(){
if (logos == null) // do ajax and save to logos variable
else $("div").html(logos)
});
Mark nailed it .one() will save extra line of codes and many checks hassle. I used it in a similar case. An optimized way to call that if they are wrapped in a parent container which I highly suggest will be:
$('#id_of_parent_container').find('button').one("click", function () {
//get the id of the button that was clicked and do the ajax load accordingly
});

Select tags within a string using jQuery

I have my website getting a value as a result of an ajax call. After that, I would like to insert that result (a string) into a tag. However, I would like to insert that result in a way that (1) it must have opacity = 0, then (2) it will slideDown() so the whole content list being pushed down using animation, and finally (3) change opacity = 1. Imagine this is just like a Facebook message list insert process
The way I am planning to do this is to return the result string from ajax to opacity=0 first. However, I don't know how to use jQuery to select a tag from within a string. I know jQuery only select from the DOM. So how to do this? Any advice?
Thanks
I'd consider putting the return value inside a SPAN. Hide the container that will hold it. Set the opacity of the SPAN to 0, then add the result to it and put it in the container. Once that is done, slide the container down and animate showing the result in the callback to the slideDown method.
$.ajax({
...
success: function(data) {
var container = $('#container').hide();
$('<span />').css( 'opacity', 0 )
.html(data.result)
.appendTo(container);
container.slideDown('normal', function() {
$(this).( 'span:first' )
.animate( { 'opacity': 1.0 } );
});
}
...
});
Hide() is a jquery function, meaning that only works on a jquery object, so you have to first inject the html in the DOM, and then call hide() on the DOM element.
$('#msgList').load (url,data,function(html){
var $this = $(this); // cache $(this) for performance
$this.hide().html(html); // inject the html in the DOM
$('#aa', $this).hide(); // hide #aa
$this.show(); // reveal the messageList
});
The following will make the ajax call using the simple .get() wrapper.
Then the callback function will load the response into a jquery object and find the tag you want.
It then hides this tag and appends it to a div container.
Finally it will slide it down.
//do ajax call
$.get( url, function(html) {
//load html into a jQuery object, find the tag by id then hide it
var $el = $(html).filter('#someId').hide();
//append element to the dom and slide it down
$el.appendTo('#someDiv').slideDown('slow');
});

Categories

Resources