How to generate JQuery calls inside JavaScript FOR loop? - javascript

I need to generate this 4 JQuery calls inside a Javascript Function:
$(".dropdown-menu .1_147").hover(
function() { $("#1_147").show(); },
function() { $("#1_147").hide(); }
);
$(".dropdown-menu .2_147").hover(
function() { $("#2_147").show(); },
function() { $("#2_147").hide(); }
);
$(".dropdown-menu .3_147").hover(
function() { $("#3_147").show(); },
function() { $("#3_147").hide(); }
);
$(".dropdown-menu .4_147").hover(
function() { $("#4_147").show(); },
function() { $("#4_147").hide(); }
);
I've write a Javascript function, the FOR loop only generates the last interaction "4_147". How can I tell the Javascript to generate the 4 JQuery calls?
My current JavaScript:
var submenu_navigation = document.getElementsByClassName("dropdown-menu");
var submenu_navigation_list = submenu_navigation[0].getElementsByTagName('li');
/*console.log(submenu_navigation_list);*/
function generateDropdownMenuMoldura(lis_array) {
for (var item in lis_array) {
var item_class_attr_name = lis_array[item].getAttribute('class');
console.log(item_class_attr_name);
$(".dropdown-menu ." + item_class_attr_name).hover(
function() { $("#" + item_class_attr_name).show(); },
function() { $("#" + item_class_attr_name).hide(); }
);
}
}
generateDropdownMenuMoldura(submenu_navigation_list);
Any clues?
Best Regards,
Update:
I got the solution:
/* Define the Elements that I need to loop */
var submenu_navigation = document.getElementsByClassName("dropdown-menu");
var submenu_navigation_list = submenu_navigation[0].getElementsByTagName('li');
function generateDropdownMenuMoldura(lis_array) {
for (var item in lis_array) {
var item_class_attr_name = lis_array[item].getAttribute('class');
console.log(item_class_attr_name);
(function(item_class_attr_name) {
$(".dropdown-menu ." + item_class_attr_name).hover(
function() { $("#" + item_class_attr_name).show(); },
function() { $("#" + item_class_attr_name).hide(); }
);
})(item_class_attr_name);
}
}
generateDropdownMenuMoldura(submenu_navigation_list);
My question is: How this anonymous function call works? This is a recursion technique?
Best Regards,

How to fix your specific solution was already answered in an other question.
But why so complicated? Judging from the JavaScript you currently have, and assuming everything apart from the scope works fine, a simpler solution would be:
$(".dropdown-menu li").hover(function() {
$('#' + this.className).show();
}, function() {
$('#' + this.className).hide();
});
There is no need to bind a different handler to each of these elements, since they all do basically the same thing.

Take a look at jQuery.each('dropdown-menu') method . It is for loops.
HTML Sample
<ul>
<li>foo</li>
<li>bar</li>
</ul>
jQuery Sample
$( "li" ).each(function( index ) {
console.log( index + ": " + $( this ).text() );
});

Related

Problems with removing item from list

Can anyone tell me why this is not working corectly?
I want a function that will remove list item when I click on it - instead it is removing the whole list.
$(document).ready(function(){
$( "#add-tag" ).on("click", function(x) {
var tag = $("#new-tag").val();
$("#galleries div:first-child").clone().appendTo("#galleries");
$("#galleries-list").append('<li>' + tag + ' gallery: remove</li>');
$("#new-tag").removeAttr("value");
x.preventDefault();
});
$("#galleries-list li a").on("click", function(x) {
var elem = $(this);
$(elem).remove();
});
});
make it
$("#galleries-list li a").on("click", function(x) {
var elem = $(this);
elem.parent().remove(); //since you want to remove the li on click of a
});
it was already a jquery object, you didn't have to make it again.
Working Example: https://jsfiddle.net/Twisty/88t09ma8/2/
JQuery
$(document).ready(function() {
$("#add-tag").on("click", function(x) {
x.preventDefault(); // Keep form from submitting
var tag = $("#new-tag").val();
$("#galleries div:first-child").clone().appendTo("#galleries");
$("#galleries-list").append('<li>' + tag + ' gallery: remove</li>');
});
$(document).on("click", "ul#galleries-list li a", function(x) {
$("#new-tag").val("");
$(this).parent("li").remove();
return false;
});
});
The .on() was not hooking to the dynamically created link, so I had to select it more specifically. Also tag was not defined.

jQuery onclick function: Undefined is not a function

Edit: I guess part of this is an issue of me being inexperienced with Drupal. I added a javascript file to site.info, so that it will be added to every page. This is all the file contains:
(function ($){
$("#ctl00_btnSearch001").on("click", function(){
var searchVal = $("#ctl00_txtSearch").val();
window.location.href = "http://www.mywebsite.org/search/?sa=Search&q=" + searchVal;
});
})(jQuery);
When the site loads, it gets compiled into this larger script, which looks like this in the debugger:
(function ($) {
Drupal.behaviors.titlebar = {
init: function(context, settings) {
// Using percentage font size to easily increase/decrease page font size
var baseFontSize = 100;
$('.pgc-font-size a').click(function() {
if($(this).hasClass('increase')) {
if(baseFontSize < 150)
baseFontSize += 20;
$('.pg-content-body p').css('font-size', baseFontSize+'%');
} else {
if(baseFontSize > 70)
baseFontSize -= 10;
$('.pg-content-body p').css('font-size', baseFontSize+'%');
}
});
// Print button
$('.pgc-print a').click(function() {
window.print();
})
}
};
}(jQuery));
// There's a problem with our jQuery loading before the ingested site's
// jQuery which is causing jQuery plugins to break (the "once" plugin in this case).
// I'm using this workaround for now
jQuery(function() {
Drupal.behaviors.titlebar.init();
});;
(function ($) {
Drupal.behaviors.giftTypes = {
init: function() {
// Gift details accordion
$('.pg-gift-details .accordion-items').css('display', 'none');
$('.pg-gift-details .accordion-switch').click(function(){
if($(this).hasClass('open')) {
$(this).find('span').removeClass('icon-arrow-up').addClass('icon-arrow-down');
$('.pg-gift-details .accordion-items').slideUp('slow');
$(this).html($(this).html().replace('Hide', 'Show More'));
$(this).removeClass('open');
} else {
$(this).find('span').removeClass('icon-arrow-down').addClass('icon-arrow-up');
$('.pg-gift-details .accordion-items').slideDown('slow');
$(this).html($(this).html().replace('Show More', 'Hide'));
$(this).addClass('open');
}
})
}
}
}(jQuery));
// There's a problem with our jQuery loading before the ingested site's
// jQuery which is causing jQuery plugins to break (the "once" plugin in this case).
// I'm using this workaround for now
jQuery(function() {
Drupal.behaviors.giftTypes.init();
});;
(function ($){
$("#ctl00_btnSearch001").on("click", function(){
var searchVal = $("#ctl00_txtSearch").val();
alert(searchVal);
window.location.href = "http://www.mywebsite.org/search/?sa=Search&q=" + searchVal;
});
})(jQuery);
;
You can see my little script at the bottom there. It says there's something wrong with the first line, but I'm not sure what the problem is. What change would I need to make to my javascript file to make sure it compiles right?
I'm probably overlooking a really simple type, but I can't see what's wrong with my jQuery.
This is the part that's not working:
(function ($){
$("#ctl00_btnSearch001").on("click", function(){
var searchVal = $("#ctl00_txtSearch").val();
window.location.href = "http://www.website.org/search/?sa=Search&q=" + searchVal;
});
})(jQuery);
I have jQuery on my site, I know I do because this it's used earlier in the code with no problem. The error is showing in the debugger on the first line, '$("#ct100_btnSearch001").on("click", function(){ '. Here is a larger section of the script page:
(function($) {
Drupal.behaviors.giftTypes = {
init: function() {
// Gift details accordion
$('.pg-gift-details .accordion-items').css('display', 'none');
$('.pg-gift-details .accordion-switch').click(function() {
if ($(this).hasClass('open')) {
$(this).find('span').removeClass('icon-arrow-up').addClass('icon-arrow-down');
$('.pg-gift-details .accordion-items').slideUp('slow');
$(this).html($(this).html().replace('Hide', 'Show More'));
$(this).removeClass('open');
} else {
$(this).find('span').removeClass('icon-arrow-down').addClass('icon-arrow-up');
$('.pg-gift-details .accordion-items').slideDown('slow');
$(this).html($(this).html().replace('Show More', 'Hide'));
$(this).addClass('open');
}
})
}
}
}(jQuery));
jQuery(function() {
Drupal.behaviors.giftTypes.init();
});;
(function($) {
$("#ctl00_btnSearch001").on("click", function() {
var searchVal = $("#ctl00_txtSearch").val();
alert(searchVal);
window.location.href = "http://www.mywebsite.org/search/?sa=Search&q=" + searchVal;
});
})(jQuery);;
Try to install jQuery update Module.
If you are using Drupal 6, you are not be able to use on function.
One option is to include your custom version of jQuery in your page.tpl.php, another option (not recommended) is to use live, but now is deprecated.
You can bind a function to an event use two way:
1.use bind() method and the event name as the first argument
$( "#foo" ).bind( "click", function() {
alert( "User clicked on 'foo.'" );
});
or
2.just use the event method
$( "#foo" ).click( function() {
alert( "User clicked on 'foo.'" );
});
The problem of your code is that there isn't a on event.
ref http://api.jquery.com/category/events/mouse-events/
If ctl00_btnSearch001 is a correct id for what ever you are trying to click. Try changing it to this:
(function ($){
$(document).on("click", "#ctl00_btnSearch001", function(){
var searchVal = $("#ctl00_txtSearch").val();
window.location.href = "http://www.mywebsite.org/search/?sa=Search&q=" + searchVal;
});
})(jQuery);

Bind JQuery event to html created after pageload via jquery

I am developing a jquery module for add delete edit view etc.
My problem is when page load complete, a list of items populate. After selecting an item this item's subitems loaded via jquery and html built, appended. But on this table event not fired up. Jquery Live is no longer available. Instead "On" is not working.
I tried :
$(document).on('click', selector , function () { foo(); });
But when a button is clicked it triggers other buttons as well.
My code is below.
I have a working code except links on table which loaded by jquery.
var myModule = {
el: {
listbutton: $('#list-button'),
listcontainer: $('#list'),
detailbutton: $(".item-detail"),
deletebutton: $(".item-delete"),
editbutton: $(".item-edit")
},
init: function() {
...
myModule.el.listbutton.on("click",myModule.getMainData);
},
getMainData: function() {
...
success: function(data) {
myModule.BuildTable(data.Value.DataList);
}
...
},
BuildTable: function (hws) {
var c = "";
c += "<table>";
$.each(hws, function() {
c +=
'<tr>' +
'<td>' + this.Title + '</td>' +
'<td></td>' +
'<td></td>' +
'<td></td>' +
'<tr>';
});
c += "</table>";
myModule.el.listcontainer.empty().append(c);
myModule.TableLinks();
},
itemDetails: function () {
alert("Detail clicked");
},
itemDelete: function () {
alert("Delete clicked");
},
itemEdit: function () {
alert("Edit clicked");
},
TableLinks: function () {
$(document).on('click', myModule.el.detailbutton, function () { myModule.itemDetails(); });
$(document).on('click', myModule.el.deletebutton, function () { myModule.itemDelete(); });
$(document).on('click', myModule.el.editbutton, function () { myModule.itemEdit(); });
},
};
myModule.init();
Can you try following:
TableLinks: function () {
$(document).on('click',
".item-detail",
function (ev) {
myModule.itemDetails();
ev.stopPropagation();
}
);
$(document).on('click',
".item-delete",
function (ev) {
myModule.itemDelete();
ev.stopPropagation();
});
$(document).on('click',
".item-edit",
function (ev) {
myModule.itemEdit();
ev.stopPropagation();
});
},
you need the delegation
$("selector on which item is added").on("click", "new item selector", function(){
});
ON and Delegate
You have to do something like this to use the "on" method.
$("table").on("click", myModule.el.detailbutton, myModule.itemDetails());
UPDATE: Just noticed, you have to used a selector not a jQuery object in the second parameter.
So $("table").on("click", ".item-detail", myModule.itemDetails());
your approach using on is exactly what you need, but should have been bit more careful on constructing the element object
el: {
listbutton: '#list-button',
listcontainer: '#list',
detailbutton: ".item-detail",
deletebutton: ".item-delete",
editbutton: ".item-edit"
},
and use it like this
init: function () {
$(myModule.el.listbutton).on("click", myModule.getMainData);
},
what you did is
TableLinks: function () {
$(document).on('click', myModule.el.detailbutton, function () { myModule.itemDetails(); });
...
},
which is similar to and which is wrong
TableLinks: function () {
$(document).on('click', $(".item-detail"), function () { myModule.itemDetails(); });
....
},
working fiddle

Object screenoff in "onmouseover"

The code below shows a window when mouse is over a link. I wonder how to make this window appear on top of the word when it doesn't "fit" on the screen.
function showLayer(obj){
var div = document.getElementById(obj).style;
div.display = "block";
}
if i understand your question, here is some jquery to help (also replaces showLayer())
$(document).on("mouseenter", '#myElement', function () {
$("#" + obj).toggle();
});
$(document).on("mouseout", '#myElement', function () {
$("#" + obj).toggle();
});
$(document).on("mousemove", '#myElement', function (i) {
$("#" + obj).offset(function () {
return {left: i.pageX, top: i.pageY}
});
});
im not sure how you get the value for obj, so you would have to edit to your specific needs.

Trying to condense javascript into for loop

I've got the following code that I am trying to condense to a for loop but am having no luck:
$("#motion1-sub1-1").hover( function () {
$("#motion1-sub1-1 div").show();
},
function () { $("#motion1-sub1-1 div").hide();
}
);
$("#motion1-sub1-2").hover( function () {
$("#motion1-sub1-2 div").show();
},
function () { $("#motion1-sub1-2 div").hide();
}
);
$("#motion1-sub1-3").hover( function () {
$("#motion1-sub1-3 div").show();
},
function () { $("#motion1-sub1-3 div").hide();
}
);
$("#motion1-sub1-4").hover( function () {
$("#motion1-sub1-4 div").show();
},
function () { $("#motion1-sub1-4 div").hide();
}
);
$("#motion1-sub1-5").hover( function () {
$("#motion1-sub1-5 div").show();
},
function () { $("#motion1-sub1-5 div").hide();
}
);
Here's the for loop code that have to condense the above code:
for (var i = 1; i <= 5; i++) {
$("motion1-sub1-" + i).hover( function () { $("motion1-sub1-" + i + "div").show();
},
function () { $("motion1-sub1-" + i + "div").hide();
}
);
}
No need for a for-loop, just bind to those elements that have a certain id pattern, and use this to reference them from within the hover functions:
$("[id^='motion1-sub1-']").hover(
function(){
$("div", this).show();
},
function(){
$("div", this).hide();
}
);
I don't know what type of element we're binding to, but you should provide that tag as part of the selector. For instance, if this is a div we're hovering, modify the selector to include that:
$("div[id^='motion1-sub1-']")
Or an even shorter, more DRY version:
$("[id^='motion1-sub1-']").on("mouseenter mouseleave", function(e){
$("div", this).toggle( e.type === "mouseenter" );
});
How about giving all your divs a class of motion-sub and then doing
$(".motion-sub").hover(function() {
$(this).show() }, function() { $(this).hide(); }
});
You're missing a space on motion1-sub1-x div selector right before the div
$("motion1-sub1-" + i + " div")

Categories

Resources