simplify jQuery selector highlight - javascript

I have over 100 videos and I use a function to highlight the links clicked. The code thought is very long and I feel like there must be a way to simplify it into a for loop or something. Any idea?
var vid_all0 = $('#vid_link0, #vidtop_link0, .vidtop_link0, #vidmob_link0, #link0'); //cache selector
vid_all0.click(function () {
$('[id^=vid_link],[id^=vidtop_link],[id^=vidmob_link], .vidtop_link0').css('background-color', 'inherit');
vid_all0.css('background-color', '#A9CDEB'); //change color of all elements
$('.vidtop_link0').css('background-color', 'inherit');
});
var vid_all1 = $('#vid_link1, #vidtop_link1, #vidmob_link1,#link10'); //cache selector
vid_all1.click(function () {
$('[id^=vid_link],[id^=vidtop_link],[id^=vidmob_link]').css('background-color', 'inherit');
vid_all1.css('background-color', '#A9CDEB'); //change color of all elements
});
var vid_all2 = $('#vid_link2, #vidtop_link2, #vidmob_link2,#link19'); //cache selector
vid_all2.click(function () {
$('[id^=vid_link],[id^=vidtop_link],[id^=vidmob_link]').css('background-color', 'inherit');
vid_all2.css('background-color', '#A9CDEB'); //change color of all elements
});
...
it goes up to 15

Give all those elements the same class, then use all elements with that class like
$(".vidtop").on("click", function()
{
// Do something with their CSS
});

If you can't modify your HTML with a class, something like this should work:
for (var i=1; i=99; i==;) {
$(vid_all + i).click(function () {
$(this).find('[id^=vid_link],[id^=vidtop_link],[id^=vidmob_link]').css('background-color', 'inherit');
});
}

I'm not sure if I understood your code correctly, but this would seem to be a simpler version:
function doStuff(links, additional) {
links.click(function() {
$('[id^=vid_link],[id^=vidtop_link],[id^=vidmob_link]' + (additional ? "," + additional : "")).css('background-color', 'inherit');
links.css('background-color', '#A9CDEB');
if (additional) {
additional.css('background-color', 'inherit');
}
});
}
// vid_all0
doStuff($('#vid_link0, #vidtop_link0, .vidtop_link0, #vidmob_link0, #link0'), $('.vidtop_link0'));
// vid_all1
doStuff($('#vid_link1, #vidtop_link1, #vidmob_link1,#link10'));
// vid_all2
doStuff($('#vid_link2, #vidtop_link2, #vidmob_link2,#link19'));
// etc.

Related

jQuery - Exclude elements from object loop

So I am using this code to loop through the DOM and locate all elements that match and then add a class to the elements:
var timeDif = 0;
setTimeout(function(){
$('.panel-main').each(function () {
var $el = $(this);
setTimeout(function () {
$el.addClass('boingInUp');
},200 * timeDif);
timeDif++;
});
}, 1000);
what I need to know how to do is exclude any elements that have an inline style of " style="display: none; ". Is this possible?
Thank you in advance.
Depending on your complete use case, you should use the jQuery visibility selector.
$('.panel-main:visible').each(function() {
...
}
This continues to work for elements that have that inline style, regardless if you show them or not.
Documentation
Use this
var timeDif = 0;
setTimeout(function(){
$('.panel-main').each(function () {
var $el = $(this);
if($el.is(':visible')){
setTimeout(function () {
$el.addClass('boingInUp');
},200 * timeDif);
}
timeDif++;
});
}, 1000);
...
$('.panel-main:visible').each(function () {
...
}
Why not just use the selector
$('.panel-main:visible')
which will only return visible items

Javascript loop not creating jquery controls correctly

I would like to replace:
var linuxControls = ["CreateLinuxUser", "EditLinuxUser", "DeleteLinuxUser", "Export"];
$("#dlgCreateLinuxUser").dialog({autoOpen: false});
$("#btnCreateLinuxUser").click(function () {
$("#dlgCreateLinuxUser").dialog("open");
});
$("#dlgEditLinuxUser").dialog({
autoOpen: false
});
$("#btnEditLinuxUser").click(function () {
$("#dlgEditLinuxUser").dialog("open");
});
$("#dlgDeleteLinuxUser").dialog({autoOpen: false});
$("#btnDeleteLinuxUser").click(function () {
$("#dlgDeleteLinuxUser").dialog("open");
});
$("#dlgExport").dialog({autoOpen: false});
$("#btnExport").click(function () {
$("#dlgExport").dialog("open");
});
with:
for (i = 0; i < linuxControls.length; i++) {
var strDlg = "#dlg" + linuxControls[i];
var strBtn = "#btn" + linuxControls[i];
$(strDlg).dialog({autoOpen: false});
$(strBtn).click(function () {
$(strDlg).dialog("open");
});
}
However it is only creating the last control "Export." As looping constructs and string building goes, it all looks fine. Is there something weird with jquery that is preventing this?
Use a closure loop so that i won't be changed at runtime, can do that with jQuery each.
$.each(linuxControls, function(i) {
var strDlg = "#dlg" + linuxControls[i];
var strBtn = "#btn" + linuxControls[i];
$(strDlg).dialog({autoOpen: false});
$(strBtn).click(function () {
$(strDlg).dialog("open");
});
});
Since you're jQuery already why not try something similar to this:
$('.linux-control').click(function() {
$('#' + $(this).data('dialog')).dialog("open");
});
<button type="button" id="btnCreateLinuxUser" class="linux-control" data-dialog="dlgCreateLinuxUser">Create User</button>
Edit
The above snipped binds .click() to all .linux-control classes. It then looks for the data-dialog attribute and creates a jQuery selector to open your dialog. In the instance above the button contains dlgCreateLinuxUser in the data-dialog attribute of the element. No loops needed since the .click() function is bound only to element that fires it but listens for all elements with the class .linux-control.

How to Show Dynamically Added Element

I'm trying to create tooltips with title attribute and jQuery but can't find method to show dynamically added element.
HTML
some page
CSS
.tooltip {
    …
display: none; /* I's needed for hard coded tooltips */
…
}
jQuery
$(function () {
if (window.matchMedia('(min-width: 980px)').matches) {
$('.dfn').hover(
function () {
var el = $(this);
var txtTitle = el.prop('title');
el.append('<p class="tooltip">' + txtTitle + '</p>');
                //That's it. My tooltip has been created, but it has not been shown
$(el + ' .tooltip').show('fast');
el.data('title', el.prop('title'));
el.removeAttr('title');
}, function () {
$(el + ' .tooltip').hide('fast').remove();
el.prop('title', el.data('title'));
}
);
}
});
As mentioned by others, $(el + ' .tooltip').show('fast'); is probably wrong.
The el is an object, not a string to concat', one way is to use el.find('.tooltip').show().
The other way is to use the context option: $('.tooltip', el).show();
You need to have correct code to find new element:
$('.tooltip', el).show('fast');
Your current one probably endup searching for something like [object] .tooltip or similar string depending on how JavaScript decides to convert HTML element to string.
As others have mentioned el.find('.tooltip').show() and el.find('.tooltip').hide().remove(); solve the problem.
Also, in HandlerOut function, you el was not declared. Fiddle here
$(function () {
//if (window.matchMedia('(min-width: 980px)').matches) {
$('.dfn').hover(
function () {
var el = $(this);
var txtTitle = el.prop('title');
el.append('<p class="tooltip">' + txtTitle + '</p>');
//That's it. My tooltip has been created, but it has not been shown
el.find('.tooltip').show()
el.data('title', el.prop('title'));
el.removeAttr('title');
}, function () {
var el = $(this);
el.find('.tooltip').hide().remove();
el.prop('title', el.data('title'));
}
);
//}
});

jQuery switching between more than two classes

I've already posted a question about jQuery toggle method here
But the problem is that even with the migrate plugin it does not work.
I want to write a script that will switch between five classes (0 -> 1 -> 2 -> 3 -> 4 -> 5).
Here is the part of the JS code I use:
$('div.priority#priority'+id).on('click', function() {
$(this).removeClass('priority').addClass('priority-low');
});
$('div.priority-low#priority'+id).on('click' ,function() {
$(this).removeClass('priority-low').addClass('priority-medium');
});
$('div.priority-medium#priority'+id).on('click', function() {
$(this).removeClass('priority-medium').addClass('priority-normal');
});
$('div.priority-normal#priority'+id).on('click', function() {
$(this).removeClass('priority-normal').addClass('priority-high');
});
$('div.priority-high'+id).on('click', function() {
$(this).removeClass('priority-high').addClass('priority-emergency');
});
$('div.priority-emergency'+id).on('click', function() {
$(this).removeClass('priority-emergency').addClass('priority-low');
});
This is not the first version of the code - I already tried some other things, like:
$('div.priority#priority'+id).toggle(function() {
$(this).attr('class', 'priority-low');
}, function() {
$(this).attr('class', 'priority-medium');
}, function() {
...)
But this time it only toggles between the first one and the last one elements.
This is where my project is: strasbourgmeetings.org/todo
The thing is that your code will hook your handlers to the elements with those classes when your code runs. The same handlers remain attached when you change the classes on the elements.
You can use a single handler and then check which class the element has when the click occurs:
$('div#priority'+id).on('click', function() {
var $this = $(this);
if ($this.hasClass('priority')) {
$this.removeClass('priority').addClass('priority-low');
}
else if (this.hasClass('priority-low')) {
$this.removeClass('priority-low').addClass('priority-medium');
}
else /* ...and so on... */
});
You can also do it with a map:
var nextPriorities = {
"priority": "priority-low",
"priority-low": "priority-medium",
//...and so on...
"priority-emergency": "priority"
};
$('div#priority'+id).on('click', function() {
var $this = $(this),
match = /\bpriority(?:-\w+)?\b/.exec(this.className),
current = match && match[0],
next = nextPriorities[current];
if (current) {
$this.removeClass(current).addClass(next || 'priority');
}
});
[edit: working demo]
Assuming you have 'priority' as the default class already on the element at the initialization phase, this will cycle through the others:
$('div#priority' + id)
.data('classes.cycle', [
'priority',
'priority-low',
'priority-medium',
'priority-normal',
'priority-high',
'priority-emergency'
])
.data('classes.current', 0)
.on('click', function () {
var $this = $(this),
cycle = $this.data('classes.cycle'),
current = $this.data('classes.current');
$this
.removeClass(cycle[current % cycle.length])
.data('classes.current', ++current)
.addClass(cycle[current % cycle.length]);
});
I have tried myself to do this with the sole help of toggleClass() and didn't succeeded.
Try my method that declares an array with your five classes and toggles dynamically through
them.Do adapt to your own names.
//variable for the classes array
var classes=["one","two","three","four","five"];
//add a counter data to your divs to have a counter for the array
$('div#priority').data("counter",0);
$(document).on('click','div#priority',function(){
var $this=$(this);
//the current counter that is stored
var count=$this.data("counter");
//remove the previous class if is there
if(($this).hasClass(classes[count-1])){
$(this).removeClass(classes[count-1]));
}
//check if we've reached the end of the array so to restart from the first class.
//Note:remove the comment on return statement if you want to see the default class applied.
if(count===classes.length){
$this.data("counter",0);
//return;//with return the next line is out of reach so class[0] wont be added
}
$(this).addClass(classes[count++]);
//udpate the counter data
$this.data("counter",count);
});
//If you use toggleClass() instead of addClass() you will toggle off your other classes.Hope is a good answer.

How to select child from parent by class starting with $(this)

I'm creating a custom jQuery plugin to add a few images above an input box. The highlight class are working perfectly, but I need help with the selectors on the .toggle() for showing and hiding the INPUTBANNER class.
jQuery.fn.inputmenu = function() {
function createInputMenu(node) {
$(node).bind('focus', function() {
$(this).parent().toggleClass('highlight');
//SHOW INPUTBANNER CLASS
$(this).parent().('.inputbanner').toggle();
});
$(node).bind('blur', function() {
$(this).parent().toggleClass('highlight');
//HIDE INPUTBANNER CLASS
$(this).parent().('.inputbanner').toggle();
});
$(node).parent().append('<div class="inputbanner">some images here</div>');
}
return this.each(function() {
createInputMenu(this);
});
};
This seems to be what you are after, you don't have to go back up to the parent and then go back down to the .inputbanner to select it, since inputbanner is a sibling you can just do:
// use .prev() if the element is before
$(this).next('.inputbanner')
Also as a side note, you should wrap your plug-in like so (so that there are no collisions with the $ identifier)
(function($) {
$.fn.inputmenu = function() {
// plugin implementation here
}
})(jQuery);
i'd like to see the state of your DOM / html markup to test it out, but try this:
jQuery.fn.inputmenu = function () {
return this.each(function () {
var $node = $(this);
$node.parent().append('<div class="inputbanner" style="display:none">some images here</div>');
var $nodeImageContainer = $node.parent().find('div.inputbanner').eq(0);
$node.bind('focus', function () {
//SHOW INPUTBANNER CLASS
$nodeImageContainer.addClass('highlight').show();
})
.bind('blur', function () {
//HIDE INPUTBANNER CLASS
$nodeImageContainer.removeClass('highlight').hide();
});
});
};

Categories