Add empty image tag with jQuery - javascript

I have a menu with sub menus and there is a + and _ image for about and close sub menus.
The problem that the menu that not have sub its align is different than other and to fix that must add image to the li that have no image close and open to fix the align here a screenshot for what I mean
This mean is create demoniacally with js here the code I can't fix it with css because it will effect the whole menu here the code
$(function () {
//this function to get , show and hide sub menu from this menu by use menu Id
$('.daymanicPageMenu').delegate('img', 'click', function () {
var checkSubMenuFound = $(this).parent().children(".daymanicPageSubMenu").length;
if (checkSubMenuFound != 0) {
//remove this div show fast
$(this).parent().children(".daymanicPageSubMenu").slideUp("fast", function () {
$(this).parent().children("img").attr('src', 'http://localhost:53188/Content/Images/CollectionImages/image.png');
$(this).remove();
});
} else {
$(this).parent().append("<div class='daymanicPageSubMenu'></div>");
var subMenuDiv = $(this).parent().children(".daymanicPageSubMenu");
//get menu Id to get sub menu by Ajax
var menuId = $(this).data('stuff');
// ajax request
$.ajax({
url: "GetSubMenu",
data: { menuId: menuId },
type: 'POST',
async: false,
success: function (data) {
subMenuDiv.append(data);
}
});
//show this div fast
subMenuDiv.hide().slideDown("fast", function () {
$(this).parent().children("img").attr('src', 'http://localhost:53188/Content/Images/CollectionImages/image2.png');
});
}
});
//List Indexing function
$('.listIndexing').delegate('label', 'click', function () {
var currentpage = $('.liIndexing').html();
var parent = $(this).parent();
var parentParent = parent.parent();
var removeClassLabel = parentParent.find('li[name=' + currentpage + ']');
removeClassLabel.children('label').removeClass("liIndexing");
if ($(this).html() == "Next") {
currentpage++;
var pagecount = $(this).attr('name');
}
else if ($(this).html() == "Prev") {
currentpage--;
} else {
currentpage = $(this).data('stuff');
}
if (currentpage < 1) { currentpage = 1; }
if (currentpage > pagecount) { currentpage = pagecount; }
//get list Id to get List News by Ajax
var newListdiv = $("#newsPage");
// ajax request
$.ajax({
url: "News",
data: { listId: currentpage },
type: 'POST',
async: false,
success: function (data) {
newListdiv.empty().append(data);
}
});
var addClassLabel = parentParent.find('li[name=' + currentpage + ']');
addClassLabel.children('label').addClass("liIndexing");
});
$("#newsPageListIndex li:eq( 1 )").children("label").addClass("liIndexing");
var tn1 = $('.mygallery').tn3({
skinDir:"skins",
imageClick:"fullscreen",
image:{
maxZoom:1.5,
crop:true,
clickEvent:"dblclick",
transitions:[{
type:"blinds"
},{
type:"grid"
},{
type:"grid",
duration:460,
easing:"easeInQuad",
gridX:1,
gridY:8,
// flat, diagonal, circle, random
sort:"random",
sortReverse:false,
diagonalStart:"bl",
// fade, scale
method:"scale",
partDuration:360,
partEasing:"easeOutSine",
partDirection:"left"
}]
}
});
});

to fix the align I must add image to the li
You, you don't need to. Use CSS for aligning them properly. Also, for a nested list menu you should actually nest list elements.

Related

Javascript foreach loop calls ajax several times

So I am trying to create to do list with several boards. Each board have add item button. If I click add item button it opens modal where to insert task info. But if I click add item button several times and then insert info to modal and press save ajax fires as many times i clicked add item button. How can I prevent from that?
var addNewItems = document.querySelectorAll("#addNewItem");
var addNewSubmits = document.querySelectorAll("#listItemSave");
addNewItems.forEach(function(addNewItem) {
addNewItem.addEventListener("click", function(e) {
var newItemModal = this.nextElementSibling;
newItemModal.classList.toggle("hidden");
var addNewBtn = newItemModal.querySelector("#listItemSave");
//current board
var board = this.closest("div.list");
//current list
var list = board.querySelector(".todo--items");
addNewBtn.addEventListener ("click", function(e) {
//current board id
var boardId = board.dataset.boardid;
//current title
var title = newItemModal.querySelector("#listTitle");
var titleValue = title.value;
//current content
var content = newItemModal.querySelector("#listTextarea");
var contentValue = content.value;
$.ajax({
type: "POST",
url: "add.php",
data: { content: contentValue , title: titleValue , listid: boardId },
success: function(data, textStatus, jqXHR) {
$("#todoItems-" + id + "").append(data);
}
});
});
});
});
You could use a variable, lets say busy, to validate that an AJAX request isn't already on going.
You could set this variable in the beforeSend callback of AJAx and then updated it back to false in the finally callbac :
var addNewItems = document.querySelectorAll("#addNewItem");
var addNewSubmits = document.querySelectorAll("#listItemSave");
addNewItems.forEach(function (addNewItem) {
addNewItem.addEventListener("click", function (e) {
var newItemModal = this.nextElementSibling;
newItemModal.classList.toggle("hidden");
var addNewBtn = newItemModal.querySelector("#listItemSave");
//current board
var board = this.closest("div.list");
//current list
var list = board.querySelector(".todo--items");
var busy = false;
addNewBtn.addEventListener("click", function (e) {
//current board id
var boardId = board.dataset.boardid;
//current title
var title = newItemModal.querySelector("#listTitle");
var titleValue = title.value;
//current content
var content = newItemModal.querySelector("#listTextarea");
var contentValue = content.value;
if (!busy) {
$.ajax({
type: "POST",
url: "add.php",
beforeSend: () => {
busy = true;
}
data: {
content: contentValue,
title: titleValue,
listid: boardId
},
success: function (data, textStatus, jqXHR) {
$("#todoItems-" + id + "").append(data);
},
complete: () => {
busy = false;
}
});
}
});
});
});
This is a pretty simple solution but it works.
You can use addNewBtn.onclick = function () {} instead to overlap the previous listener in this case.
But it's not recommended to register listeners inside another listener. Try to move it out of there.

Launch modal in modal

I want to launch a modal in a modal. It's actually working, but if I open the 2nd modal in the 1st modal, the 2nd modal appears, but behind the 1st modal and the scroll bar disappear, when I close the 1st modal: modal
The JavaScript is in my modal PHP file.
How can I solve this problem?
Javascript
$(document).ready(function() {
$('.relations').click(function(e) {
var checkBoxes = $("input[name=case]");
var checkedBoxes = checkBoxes.filter(":checked");
if (checkedBoxes.length === 0) {
return false;
}
e.preventDefault();
var insert = [];
$('.checkboxes').each(function() {
if ($(this).is(":checked")) {
insert.push($(this).val());
}
});
insert = insert.toString();
var data_id = $(this).attr("id");
$.ajax({
url: "nodes.php",
method: "post",
dataType: "json",
data: {
data_id: data_id,
insert: insert
},
success: function(data) {
$('#moreInfo').html(data);
$('#dataModal').modal("show");
var nodeDatas = new vis.DataSet();
nodeDatas = data;
$.ajax({
method: "post",
dataType: "json",
url: "edges.php",
data: {
data_id: data_id
},
success: function(data) {
var edgeDatas = new vis.DataSet();
edgeDatas = data;
var myDiv = document.getElementById("moreInfo");
data = {
nodes: nodeDatas,
edges: edgeDatas
};
var options = {
};
var network = new vis.Network(myDiv, data, options);
}
});
}
});
});
});
I'm assuming that the second modal is moreInfo div, if that's correct, you need to make few css changes for that element to appear on top of the first modal, using z-index:99999; maybe more, and also for the scrollbar to appear you need another css property overflow:scoll;
I hope this helps!

Previous divs with jQuery does not work after Ajax call

I have two scripts:
The first one is image carousel. It uses jQuery slick slider.
The second one is an Ajax script that loads contents as page scrolls down.
Here is my code:
function slider () {
var $arrows = $('.arrows');
var $next = $arrows.children(".slick-next");
var $prev = $arrows.children(".slick-prev");
var slick = $('.your-class').slick({
appendArrows: $arrows
});
$('.slick-next').on('click', function (e) {
var i = $next.index( this )
slick.eq(i).slickNext();
});
$('.slick-prev').on('click', function (e) {
var i = $prev.index( this )
slick.eq(i).slickPrev();
});
}
$(document).ajaxComplete(slider);
Below is the scroll content load with Ajax:
$(document).ready(function(){
function slider () {
var $arrows = $('.arrows');
var $next = $arrows.children(".slick-next");
var $prev = $arrows.children(".slick-prev");
var slick = $('.your-class').slick({
appendArrows: $arrows
});
$('.slick-next').on('click', function (e) {
var i = $next.index( this )
slick.eq(i).slickNext();
});
$('.slick-prev').on('click', function (e) {
var i = $prev.index( this )
slick.eq(i).slickPrev();
});
}
$(document).ajaxComplete(slider);
var flag = 0;
$.ajax({
type: "GET",
url: "getdata.php",
data: {
'offset': 0,
'limit': 10
},
success: function(data){
$('.rowmasonry').append(data);
flag += 10;
},
});
$(window).scroll(function(){
if($(window).scrollTop() >= $(document).height() - $(window).height()-500){
$.ajax({
type: "GET",
url: "getdata.php",
data: {
'offset': flag,
'limit': 10
},
success: function(data){
$('.rowmasonry').append(data);
flag += 10;
},
});
}
});
});
The problem is that the first 10 contents that are loaded work properly. However, as I scroll down, and another 10 contents come, the first 10 contents that were loaded do not respond.
How do I bind the image slider to Ajax, so that all contents on the page work with jQuery?
Thanks for your help.
You are just appending new elements to DOM. In order to update slick you need to reInit slick carousel or if you are sure about the slide markup then you can use slickAdd method provided by plugin.
$.ajax().done(function(data){
$('.your-class').slick('slickAdd', data);
});
ref: http://kenwheeler.github.io/slick/

jQuery removes first div only once

I have a function:
function removeDiv() {
var topmost = jQuery('.xx');
var totContent = topmost.find('.zz').length;
var $target = jQuery('.xx').find('.zz').eq(0);
if(totContent > 5) {
$target.hide('slow', function(){ $target.remove(); });
}
}
I use it in my ajax call, to remove extra div then there are more than 5, hovewer it remove first div only once!
And this is how ajax call looks:
function saveClubs(array) {
for(i=0; i<array.length; i++) {
var id = array[i];
jQuery.ajax({
type: "GET",
async: true,
url: 'index.php?option=com_events&task=club.save&id=' + id,
dataType: 'json',
success: function(data) {
jQuery('.xx').append('<div class="zz">'+data+'</div>');
removeDiv();
}
});
}
}
Any ideas ?
This is Paul Roub's answer, posted as an answer rather than a comment:
The likely problem is that since you're doing a bunch of ajax calls in a loop, they tend to complete at the same time, and so you end up repeated fading out the same element (since it's still there until it's done fading).
The minimal changes fix would be to, say, add a class as you're fading it out:
function removeDiv() {
// Get the container (I take it there's only one .xx element)
var topmost = jQuery('.xx');
// Get the child elements that aren't fading
var zz = topmost.find('.zz').not('.fading');
// Too many?
if(zz.length > 5) {
// Yup, add 'fading' to the first one and fade it out
// Note that there's no need for the $target variable
zz.eq(0).addClass('fading').hide('slow', function(){ $(this).remove(); });
}
}
The problem is this:
var $target = jQuery('.xx').find('.zz').eq(0);
It's always 0 index.
function removeDiv(x) {
var topmost = jQuery('.xx');
var totContent = topmost.find('.zz').length;
var $target = jQuery('.xx').find('.zz').eq(x);
if(totContent > 5) {
$target.hide('slow', function(){ $target.remove(); });
}
}
function saveClubs(array) {
for(i=0; i<array.length; i++) {
var id = array[i];
jQuery.ajax({
type: "GET",
async: true,
url: 'index.php?option=com_events&task=club.save&id=' + id,
dataType: 'json',
success: function(data) {
jQuery('.xx').append('<div class="zz">'+data+'</div>');
removeDiv(i);
}
});
}
}
LIVE EXAMPLE HERE
NOTE
IN the Fiddle above, try to change this var $target = jQuery('.xx').find('.zz').eq(x); harcoding the value of x to 0 and it'll happen just once.

jQuery on or live?

I recently deployed an infinite scroll to an app that I have build and found that sometimes I need to click twice for something to happen.
My app has likes, and once the dom had loaded, i need to click on the like button twice before it changes, then once i click on the other ones it's okay but I always have to click once for the app to almost "wake up"
Is there a better solution?
$(document).ready(function() {
function runUpdate(url, item) {
$.ajax({
type: "GET",
url: url,
cache: false,
success: function(data){
if (data == '200') {
removeAddColor(item);
}
}
});
}
$('.mini-like').live('click', function(){
$('.mini-like').toggle(
function() {
var item = $(this);
var href = item.attr('href');
runUpdate(href, item);
},
function() {
var item = $(this);
var rel = item.attr('rel');
runUpdate(rel, item);
}
);
});
function removeAddColorFollow(item) {
var href = $(this).attr('href');
var rel = $(this).attr('rel');
if (item.hasClass('btn-success')) {
$(item).removeClass('btn-success').attr('href', href).attr('rel', rel);
$(item).find('i').removeClass('icon-white');
} else {
$(item).addClass('btn-success').attr('href', rel).attr('rel', href);
$(item).find('i').addClass('icon-white');
};
}
});
Well unless I'm completely wrong, you only attach the toggle event to .mini-like after it has been clicked once. Try to just replace
$('.mini-like').live('click', function() {...
With
$(function() {...
To attach the toggle event handler on document ready instead of on click
The code $('.mini-like').live('click',... should be placed inside $(document).ready()
You can use .on in place of .live. As .on is a new method and .live is deprecated now you should use .on
UPDATE
The re-written version will be
$(document).ready(function(){
$('.mini-like').on('click', function(){
$('.mini-like').toggle(
function() {
var item = $(this);
var href = item.attr('href');
runUpdate(href, item);
},
function() {
var item = $(this);
var rel = item.attr('rel');
runUpdate(rel, item);
}
);
});
});
function runUpdate(url, item) {
$.ajax({
type: "GET",
url: url,
cache: false,
success: function(data){
if (data == '200') {
removeAddColor(item);
}
}
});
}
function removeAddColorFollow(item) {
var href = $(this).attr('href');
var rel = $(this).attr('rel');
if (item.hasClass('btn-success')) {
$(item).removeClass('btn-success').attr('href', href).attr('rel', rel);
$(item).find('i').removeClass('icon-white');
} else {
$(item).addClass('btn-success').attr('href', rel).attr('rel', href);
$(item).find('i').addClass('icon-white');
};
}

Categories

Resources