Get .length of NEW dynamically added div - javascript

6 items are added onload using ajax. Each click, 6 items are being appended.
I want to hide #load-more button if newly added items are less than 6.
How to find the count of newly added items?
I use .length but all items are being counted.
Thanks for your help.
var max = 6;
var NewItems = $(".items").length;
if (NewItems > max) {
$("#load-more").hide();
} else {
$("#load-more").show();
}
var max = 6;
var start = 1;
var winloc = window.location;
$(window).bind('hashchange', function() {
if (winloc.hash === "" || winloc.hash === "#home") {
homeurl = `https://mailliw88.blogspot.com/feeds/posts/default?start-index=${start}&max-results=${max}&alt=json-in-script`;
loadList(homeurl);
}
}).trigger('hashchange')
function more() {
start += max;
loadList(`https://mailliw88.blogspot.com/feeds/posts/default?start-index=${start}&max-results=${max}&alt=json-in-script`);
}
function loadList(url) {
$.ajax({
url: url,
type: 'get',
dataType: "jsonp",
success: function(data) {
if (data.feed.entry) {
datas = data.feed.entry;
var entry = data.feed.entry;
for (var i = 0; i < entry.length; i++) {
postTitle = entry[i].title.$t;
items = '<div class="items"><h2>' + postTitle + '</h2></div>';
document.getElementById('showlists').innerHTML += items;
}
}
var newItems = $(".items").length;
if (newItems > max) {
$("#load-more").hide();
} else {
$("#load-more").show();
}
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='showlists'></div>
<div id='load-more' onclick="more()">
load more
</div>

Change:
var newItems = $(".items").length;
if (newItems > max) {
To:
if (data.feed.entry.length < 6)
The variable "max" will be out of scope for your "success" method since it's defined outside of it and is an integer type, so you will need to either directly add it, or use an object, like:
var max = {entries: 6};
...
if (data.feed.entry.length < max.entries)

You could add data attributes to the new items with an incrementing id so the final html would look like
<div data-load="1"></div>
<div data-load="1"></div>
...
<div data-load="2"></div>
...
and then in you're js
$(`div[data-load="${Math.max(...$('div').map(item => parseInt(item.attr("data-load"))))}"`)
would get all the latest ajax elements

Related

Instantiate the value of an array from one function to a different function in jquery

I want to get the result of a jquery function attached to an id and change e.g
<script>
$('#dateID').change(function(){
var bookday = $(this).val();
$.post('getDates.php',{postbookday:bookday},
function(data){
var array = JSON.parse("[" + data + "]");
var list = [];
var newArray = array.flat([2]);
for (var i = 0; i < newArray.length; i++) {
list.push(newArray[i]);
};
if (list.length>96) {
alert("Sorry, day fully booked!");
}
else{
function selectedTime(list) {
return [a, b, c];
}
var result = selectedTime(list);
var myArray = [];
for (var i=0; i < result[2].length; i++) {
if (result[2][i] === '09:00') {
myArray.push(['09:00','10:00']);
}
if (result[2][i] === '10:00') {
myArray.push(['10:00','11:00']);
// here is myArray
}
}
}
});
});
</script>
and then use it as the input in another different function below:
$('#disableTimeRangesExample').timepicker(
{
'disableTimeRanges': myArray
}
);
How do I get myArray in the next function? considering that it is not static.
You have two options:
1. save the variable in outer scope:
var myArray;
$('#selectedDate').change(function(
...some computations...
myArray = [['1pm', '2pm']];
});
$('#disableTimeRangesExample').timepicker({
'disableTimeRanges': myArray
});
2. save in jQuery data
$('#selectedDate').change(function(
...some computations...
$(this).data('array', [['1pm', '2pm']]);
});
$('#disableTimeRangesExample').timepicker({
'disableTimeRanges': $('#selectedDate').data('array') || []
});
As a side note you will probably also need to update timepicker on each change.
EDIT: to update time picker on change of the input you need to put this inside change event:
$('#dateID').change(function(){
var bookday = $(this).val();
$.post('getDates.php',{postbookday:bookday},
function(data){
var array = JSON.parse("[" + data + "]");
var list = [];
var newArray = array.flat([2]);
for (var i = 0; i < newArray.length; i++) {
list.push(newArray[i]);
};
if (list.length>96) {
alert("Sorry, day fully booked!");
}
else{
function selectedTime(list) {
return [a, b, c];
}
var result = selectedTime(list);
var myArray = [];
for (var i=0; i < result[2].length; i++) {
if (result[2][i] === '09:00') {
myArray.push(['09:00','10:00']);
}
if (result[2][i] === '10:00') {
myArray.push(['10:00','11:00']);
// here is myArray
}
}
$('#disableTimeRangesExample').timepicker(
'option', {'disableTimeRanges': myArray}
);
}
});
});
$('#disableTimeRangesExample').timepicker();

Clear Marker Layers (Leaflet )

I am using Leaflet library and stuck with following issue:
To generate Map i am calling map function on button click.
So on each generatemap function call, I want to clear pregenerated markers.
function generatefilterrecord(orgid,defservice,defavail,defowner,defhealthfacility) {
$("#content1").hide();
$("#map1").show();
$("#mapA1").hide();
$("#footer").hide();
jQuery('#sel').html('');
$(".w3-card-4").remove();
var addressjoin=[],ouid=[],availspecialitiesjoin,availspecialities=[],avaialabilityjoin,name=[],address=[],pincode=[],village=[],mobile=[],special=[],notspecial=[],hfacilities=[],nothfacilities=[],schemes=[],notschemes=[],contactpname=[],contactpnumber=[];
var toAdd,spec=[],email=[],specialjoin,notspecialjoin,notspec=[],owner=[],notowner=[],hfacilitiesjoin,nothfacilitiesjoin,schemesjoin,notschemesjoin,hfschemes=[],nothfschemes=[];
var healthfac="",ownership=[],availspecialiti=[];
var arrayMap = [];latitude=[];longitude=[];
$.getJSON("../../api/analytics/events/query/tzR46QRZ6FJ.json?stage=o6ps51YxGNb&dimension=pe:THIS_YEAR&dimension=ou:"+orgid+"&dimension=l8VDWUvIHmv&dimension=KOhqEw0UKxA&dimension=xjJR4dTmn4p&dimension=wcmHow1kcBi&dimension=pqVIj8NyTXb&dimension=g7vyRbNim1K&dimension=Gx4VSNet1dC&dimension=bUg8a8bAvJs&dimension="+defservice+"&dimension="+defavail+"&dimension="+defowner+"&dimension="+defhealthfacility+"&dimension=ZUbPsfW6y0C&dimension=CAOM6riDtfU&dimension=YL7OJoQCAmF&dimension=vJO1Jac84Ar&dimension=kF8ZJYe9SJZ&dimension=tNhLX6c7KHp&dimension=bVENUe0eDsO&displayProperty=NAME", function (data) {
console.log("../../api/analytics/events/query/tzR46QRZ6FJ.json?stage=o6ps51YxGNb&dimension=pe:THIS_YEAR&dimension=ou:"+orgid+"&dimension=l8VDWUvIHmv&dimension=KOhqEw0UKxA&dimension=xjJR4dTmn4p&dimension=wcmHow1kcBi&dimension=pqVIj8NyTXb&dimension=g7vyRbNim1K&dimension=Gx4VSNet1dC&dimension=bUg8a8bAvJs&dimension="+defservice+"&dimension="+defowner+"&dimension="+defhealthfacility+"&dimension=jXCd8k2841l&dimension=RkP5neDLbHv&dimension=avHST8wLPnX&dimension=txl9e6UJFP4&dimension=ZUbPsfW6y0C&dimension=CAOM6riDtfU&dimension=YL7OJoQCAmF&dimension=vJO1Jac84Ar&dimension=kF8ZJYe9SJZ&dimension=tNhLX6c7KHp&dimension=bVENUe0eDsO&displayProperty=NAME");
var constants={key:name, value: value}
analyticsMap = calculateIndex(data.headers,analyticsMap);
if(data.rows.length==0)
{
alert("No result found for above selection");
}
for(var k=0;k<data.rows.length;k++){
arrayMap["special"] = special;
arrayMap["name"] = name;
arrayMap["address"] = addressjoin;
arrayMap["pincode"] = pincode;
arrayMap["village"] = village;
arrayMap["mobile"] = mobile;
arrayMap["notspecial"] = notspecial;
arrayMap["hfacilities"] = hfacilities;
arrayMap["nothfacilities"] = nothfacilities;
arrayMap["schemes"] = schemes;
arrayMap["notschemes"] = notschemes;
arrayMap["contactpname"] = contactpname;
arrayMap["contactpnumber"] = contactpnumber;
arrayMap["availspecialities"] = availspecialities;
arrayMap["ownership"] = ownership;
arrayMap["ouid"] = ouid;
for (var j=0;j<analyticsMap.length;j++){
if (analyticsMap[j].index > 0){
var value = data.rows[k][analyticsMap[j].index];
if (value == "1"){
value = data.headers[analyticsMap[j].index].column;
}
if (!value || value == "0"){
value = "";
}
if(arrayMap[analyticsMap[j].arrayName]){
arrayMap[analyticsMap[j].arrayName].push(value);
}
}
}
specialjoin = myJoin(special);
availspecialitiesjoin = myJoin(availspecialities);
notspecialjoin = myJoin(notspecial);
hfacilitiesjoin = myJoin(hfacilities);
nothfacilitiesjoin = myJoin(nothfacilities);
schemesjoin = myJoin(schemes);
notschemesjoin = myJoin(notschemes);
spec.push(specialjoin);
notspec.push(notspecialjoin);
owner.push(hfacilitiesjoin);
availspecialiti.push(availspecialitiesjoin);
notowner.push(nothfacilitiesjoin);
hfschemes.push(schemesjoin);
nothfschemes.push(notschemesjoin);
availspecialities=[];
special = [];
notspecial = [];
hfacilities = [];
nothfacilities = [];
schemes = [];
notschemes = [];
}
var header = {
"Authorization": "Basic " + btoa( "homepage" + ':' + "Homepage123#123" )
};
for (var i = 0; i < name.length; i++) {
$.ajax({
async: false,
type: "GET",
dataType: "json",
contentType: "application/json",
header: header,
url: '../../api/organisationUnits/' + ouid[i] + '.json?fields=[id,name,coordinates]',
success: function (response) {
var coordinates = JSON.parse(response.coordinates);
latitude.push(coordinates[0]);
longitude.push(coordinates[1]);
},
error: function (response) {
}
});
}
for (var i = 0; i < name.length; i++) {
if(ownership[i]=="Public")
{
L.marker([longitude[i], latitude[i]], {icon: blueMarker}).addTo(map1).bindPopup(name[i]+","+"</br><strong>Contact:</strong> "+ mobile[i]+ ",</br> <strong>Schemes:</strong>"+hfschemes[i]+", </br><strong>Availabilities:</strong> "+availspecialiti[i]).openPopup();
}
else if(ownership[i]=="Private")
{
L.marker([longitude[i], latitude[i]], {icon: redMarker}).addTo(map1).bindPopup(name[i]).openPopup();
}
}
});
}
Here map never generates but if i remove marker.clearLayers(); then it is coming fine but problem is it appends every result so I want to clear the last generated markers.
Instead of adding the markers directly to your map, add them to a L.LayerGroup
Whenever you want, you can remove your markers calling the clearLayers method
var layerGroup = L.layerGroup().addTo(map);
// create markers
L.marker().addTo(layerGroup);
// remove all the markers in one go
layerGroup.clearLayers();
You can use this
$(".leaflet-marker-icon").remove();
$(".leaflet-popup").remove();
All simple:
map.eachLayer((layer) => {
layer.remove();
});
from https://leafletjs.com/reference-1.0.3.html#map-event
as the code provided by psyopus removes every layer (base maps, markers..etc); I needed just to remove the markers, the marker layer object has key of'_latlng'. Thus, I check if the object has it, so remove it:
map.eachLayer((layer) => {
if(layer['_latlng']!=undefined)
layer.remove();
});
Disclaimer: I dont know if there are other layer objects with this parameter key.

jquery html(array) doesn't insert all items in array

When I run the javascript code below, it load specified amount of images from Flickr.
By var photos = photoGroup.getPhotos(10) code, I get 10 images from cache.
Then, I can see the object has exactly 10 items by checking console.log(photos);
But actual image appeared on the page is less than 10 items...
I have no idea why this work this way..
Thank you in advance.
<html>
<head>
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
<script>
var PhotoGroup = function(nativePhotos, callback) {
var _cache = new Array();
var numberOfPhotosLoaded = 0;
var containerWidth = $("#contents").css('max-width');
var containerHeight = $("#contents").css('max-height');
$(nativePhotos).each(function(key, photo) {
$("<img src='"+"http://farm" + photo["farm"] + ".staticflickr.com/" + photo["server"] + "/" + photo["id"] + "_" + photo["secret"] + "_b.jpg"+"'/>")
.attr("alt", photo['title'])
.attr("data-cycle-title", photo['ownername'])
.load(function() {
if(this.naturalWidth >= this.naturalHeight) {
$(this).attr("width", containerWidth);
} else {
$(this).attr("height", containerHeight);
}
_cache.push(this);
if(nativePhotos.length == ++numberOfPhotosLoaded)
callback();
})
});
var getRandom = function(max) {
return Math.floor((Math.random()*max)+1);
}
this.getPhotos = function(numberOfPhotos) {
var photoPool = new Array();
var maxRandomNumber = _cache.length-1;
while(photoPool.length != numberOfPhotos) {
var index = getRandom(maxRandomNumber);
if($.inArray(_cache[index], photoPool))
photoPool.push(_cache[index]);
}
return photoPool;
}
}
var Contents = function() {
var self = this;
var contentTypes = ["#slideShowWrapper", "#video"];
var switchTo = function(nameOfContent) {
$(contentTypes).each(function(contentType) {
$(contentType).hide();
});
switch(nameOfContent) {
case("EHTV") :
$("#video").show();
break;
case("slideShow") :
$("#slideShowWrapper").show();
break;
default :
break;
}
}
this.startEHTV = function() {
switchTo("EHTV");
document._video = document.getElementById("video");
document._video.addEventListener("loadstart", function() {
document._video.playbackRate = 0.3;
}, false);
document._video.addEventListener("ended", startSlideShow, false);
document._video.play();
}
this.startSlideShow = function() {
switchTo("slideShow");
var photos = photoGroup.getPhotos(10)
console.log(photos);
$('#slideShow').html(photos);
}
var api_key = '6242dcd053cd0ad8d791edd975217606';
var group_id = '2359176#N25';
var flickerAPI = 'http://api.flickr.com/services/rest/?jsoncallback=?';
var photoGroup;
$.getJSON(flickerAPI, {
api_key: api_key,
group_id: group_id,
format: "json",
method: "flickr.groups.pools.getPhotos",
}).done(function(data) {
photoGroup = new PhotoGroup(data['photos']['photo'], self.startSlideShow);
});
}
var contents = new Contents();
</script>
</head>
<body>
<div id="slideShow"></div>
</body>
</html>
I fix your method getRandom() according to this article, and completely re-write method getPhotos():
this.getPhotos = function(numberOfPhotos) {
var available = _cache.length;
if (numberOfPhotos >= available) {
// just clone existing array
return _cache.slice(0);
}
var result = [];
var indices = [];
while (result.length != numberOfPhotos) {
var r = getRandom(available);
if ($.inArray(r, indices) == -1) {
indices.push(r);
result.push(_cache[r]);
}
}
return result;
}
Check full solution here: http://jsfiddle.net/JtDzZ/
But this method still slow, because loop may be quite long to execute due to same random numbers occurred.
If you care about performance, you need to create other stable solution. For ex., randomize only first index of your images sequence.

How to add dynamically HTML element using JavaScript and Firefox Add-on SDK

I am developing a simple add-on with Firefox SDK that allows the user to review the stored data.
I would like to show the items in a panel with a table. The table is created dynamically with the data incoming from the data-base. Firstly, In the JavaScript code I create the items with their properties, then I create a table with the properties as row and I append the items with the value of each properties.
I have some problems: the table has only the item's name as first row and the properties name as first column without the value in the cells. It seems that the code is not executed in order, but it seems that the faster functions are executed first.
This is the code:
self.on('message', function() {
var container = $('#container');
container.empty();
items = [];
self.port.emit('getItem');
});
self.port.on('items', function(response) {
var ok = 0;
var items = [];
var table = $('#tableContainer #table').clone();
var container = $('#container');
table.append("<tr id=first><th> </th></tr>");
var json = eval('('+ response + ')');
for (var i = 0, len = json.length; i < len; ++i) {
var item = {
id: json[i],
properties: []
};
items.push(item);
}
items.forEach ( function(item) {
table.find('#first').append("<th id="+item.id+">"+item.id+"</th>");
self.port.emit('detailsItem', item.id);
self.port.on('details'+item.id, function(response) {
var details = eval('('+ response + ')');
var description = [];
ndet = details.length;
var len = details.length;
for (var i = 0; i < len;) {
var detail = {
dimension : details[i].dimension,
value : details[i].value
}
description.push(detail);
++i;
}
item.properties = description;
});
});
self.port.emit('getDimension');
self.port.on('dimension', function(response) {
var dimensions = eval('('+ response + ')');
for(var cont = 0, l = dimensions.length; cont < l; ++cont) {
table.append("<tr id=dimension"+cont+"><td>"+dimensions[cont]+"</td></tr>");
items.forEach( function(item) {
var prop = [];
prop = item.properties;
var lun = prop.length;
for( var p =0;p < lun;) {
if(item.properties[p].dimension == dimensions[cont]) { table.find('#dimension'+cont).append("<td>"+item.properties[p].value+"</td>");
}
else {
table.find('#dimension'+cont).append("<td> --- </td>");
}
++p; }
});
};
});
container.append(table);
});

My javascript doesn't run without alert

I am having a problem with a block of my code, this section creates boxes of chocolates based on what a user chooses in a previous step and what data is pulled from the database in the api script.
the problem is that it doesn't work without the alert('hi') in it. if i take that out it will just create an empty box without dropping the flavors in it, the flavor the flavors are inserted with the createFlavorArray function.
var product = new Array();
var price = new Array();
var size = new Array();
$(function () {
$.ajax({
type: 'POST',
url: 'phpscripts/api.php',
data: "",
dataType: 'json',
success: function(rows)
{
count = 0;
for (var i in rows)
{
var row = rows[i];
product[count] = row[0];
price[count] = row[1];
size[count] = row[2];
count++;
}
}
});
});
//b = box
//o = option that is inside the box
//nextBoxId is the box id
//nextFlavorId is the option or flavor id
var nextBoxId = 1;
var nextFlavorId = 1;
var orderCap = 0;
var subTotal = 0;
var numOfChocolates = 0;
var numOfBoxes = 0;
$(document).ready(function(){
while (halfPoundBoxes > 0) {
$("#boxes").append('<div id="b'+nextBoxId+'"></div>');
$('#b'+nextBoxId).addClass('div-table-selection');
$('#b'+nextBoxId).append($('#minusBox').clone().attr('id', "m"+nextBoxId));
$('#b'+nextBoxId).append('<div style="display:table-row"></div>');
//call the function to loop through and create the number of flavor options needed
var x = 0;
alert('hi');
while(x < product.length){
if ('1/2lb Box' == product[x]) {
createFlavorArray(size[x], nextBoxId);
subTotal += price[x] * 1;
$('#b'+nextBoxId).attr('title', product[x]);
}
x++;
}
//clone the delete box button and make it visible
$('#m'+nextBoxId).show(500);
$('#b'+nextBoxId).append("<br />");
if (orderCap == 0) {
$('#boxes').append('<div id="msg"><p>If you wish to add another box to your order select the size and click +1 Box.</p></div>');
}
$("#m"+nextBoxId).click(function() {
$(this).parent().remove();
orderCap--;
//if they're ordering zero boxes hide the order button
//remove total price
//remove the message
if (orderCap == 0)
{
document.getElementById('orderBtn').style.display = "none";
$("#msg").remove();
$("#totalPrice").empty();
}
if (orderCap < 10)
{
$("#cap").remove();
$("#addBox").show(500);
}
var y = 0;
while (y < product.length) {
if ('1/2lb Box' == product[y]) {
subTotal -= price[y] * 1;
numOfChocolates -= size[y] * 1;
}
y++;
}
$('#totalPrice').html("<p>Sub Total: " + subTotal + "</p>")
//subtract the new
$('#finalpaypal').val(subTotal);
});
nextBoxId++;
orderCap++;
numOfBoxes++;
$('#totalPrice').html("<p>Sub Total: " + subTotal + "</p>")
halfPoundBoxes--;
}
The reason your code is working only when using an alert(), is that the alert() action is giving your jQuery AJAX request a few seconds to return a value to your success() call back function.
You should move any code which is affected by your callout function, into the callout function also, so that this code runs in the correct order.
Alternatively you could not run your AJAX request asynchronosly by adding async:false, but as #Rocket has commented, this isn't recommended.
$.ajax({
async: false,
You need to put the code in a function and run it after the ajax success is finished
...
$(function () {
$.ajax({
type: 'POST',
url: 'phpscripts/api.php',
data: "",
dataType: 'json',
success: function(rows)
{
count = 0;
for (var i in rows)
{
var row = rows[i];
product[count] = row[0];
price[count] = row[1];
size[count] = row[2];
count++;
}
do_after_ajax();
}
});
});
function do_after_ajax(){
while (halfPoundBoxes > 0) {
$("#boxes").append('<div id="b'+nextBoxId+'"></div>');
$('#b'+nextBoxId).addClass('div-table-selection');
....
}
It looks like you're trying to operate on markup returned by your ajax. That code needs to be moved into the success callback of the ajax request. The reason the alert call makes it work is simply that it delays everything else long enough for the page to finish loading.

Categories