How to concatenate variables with selectors? - javascript

I'm having problems with this code: https://jsfiddle.net/vitordhers/fm8a14x6/2/
I intend to make subcategories appear if at least one check-box is checked, however when I uncheck the check-boxes, the subcategories don't disappear, since they share the same class with those from the other category.
In order to apply the code to one paragraph only, I tried to concatenate the $this selector with :checked selector, but it doesn't seem to work:
$( "p" ).click(function() {
var $line = $('.l' + $(this).data('value'));
var n = $( $this+"input:checked" ).length;
alert(n);
if(n == 0){
$($line).hide(); //if there are none checked, hide visible elements
} else {
$($line).show(); //otherwise (some are selected) fadeIn - if the div is hidden.
}
});
Could anybody help me in this case? Thanks in advance

$("input:checked", this)
did the trick.

Related

Else Condition not working java script / jquery

I'm new here, can someone please help me...
i have 2 div's #main and #side.
In my #main div i have few check boxes ,
on checked event, i apend my check box label into #side div and add/remove some classes and it's working perfectly
but when i unchecked my input, it's not working not add/remove classes or apend to #main div
here is my code
$('input[type="checkbox"]').change(function() {
if (this.checked) {
$(this).next('label').removeClass("icon");
$(this).next('label').addClass("icon-active");
$(this).next('label').detach().appendTo('#side');
}
else
{ // This condition not working //
$(this).next('label').addClass("icon");
$(this).next('label').removeClass("icon-active");
$(this).next('label').appendTo('#main');
}
});
Thanks in Advance
Here is a full code.
http://jsfiddle.net/o8n1b8z1/4/
First, since you're using jQuery, I suggest you do not use this.checked, but $(this).is(':checked').
However, the reason your code is not working in reverse is because you're moving the .next('label') in DOM on checking the checkbox. So, on unchecking, .next('label') won't exactly return the label, as it is has been moved.
This is how I'd write your function:
$('input[type="checkbox"]').on('change', function(){
var label = $('label[for="'+$(this).attr('id')+'"]'),
checked = $(this).is(':checked');
label.toggleClass("icon icon-active").appendTo(checked?'#side':'#main')
})
Now, another problem with your script is that, on return, it appends the labels to the end of the div, instead of after the checkboxes. To fix that, here's what you should use:
$('input[type="checkbox"]').on('change', function() {
var label = $('label[for="' + $(this).attr('id') + '"]'),
checked = $(this).is(':checked');
label.toggleClass("icon icon-active")[
checked ? 'appendTo' : 'insertAfter'
]($(checked ? '#side' : this));
})
Updated your fiddle
Did some changes to your else statement and it works. The issue is the Label gets shifted out and the else part no longer identifies the Labels anymore.
Here is the fiddle http://jsfiddle.net/o8n1b8z1/5/
else
{ // This condition working //
var id=$(this).attr('id');
var label = $('label[for="' + id + '"]');
label.addClass("icon");
label.removeClass("icon-active");
$( "#"+id ).after(label);
}

Wrap every child divisible by 5 and previous 4 in a div

I've been working on this JSFiddle to practice my understanding of jquery, but now I'm stuck.
How do you wrap a child element in a div to follow this pattern: child elements 1-5, then child elements 6-10, then child elements 11-15, and so on?
I'm working on a tally counter, so I want every 5 tallies to cluster together. That way, I can more easily select the last child and apply a class to make it rotate, in order to "cross out" the previous 4 tallies.
edit: (To clarify: I've been looking into selecting by index and by nth-child/nth-of-type, but those methods can only really grab the fifth element, or maybe even multiples of five? It doesn't grab the previous divs, too.)
edit 2: (So, you can actually use those selectors! I figured I was getting something wrong. It's always something simple.)
$(".button").click(function() {
var $button = $(this);
var oldValue = $button.parent().find("input").val();
if ($button.text() == "+") {
var newVal = parseFloat(oldValue) + 1;
} else {
// Don't allow decrementing below zero
if (oldValue > 0) {
var newVal = parseFloat(oldValue) - 1;
} else {
newVal = 0;
}
}
$("#counternumber").val(newVal);
});
$("#plus").click(function() {
var tally = "<div class='tally'>I</div>";
$("#dummy").append(tally)
});
$(function(){
$('#scratchpad.tally:nth-of-type(5)').wrap('tallyfamily');
});
JSFiddle.
Here is a general solution to wrap elements in groups of 5:
$(".holder > div:nth-child(5n-4)")
.addClass("first-of-group")
.each(function(){
$(this).nextUntil(".first-of-group")
.addBack()
.wrapAll("<div class='wrapper'>");
})
.removeClass("first-of-group");
http://jsfiddle.net/nJJM8/1/
Basically, :nth-child(5n-4) gets the first element in each group of 5. Then a class is temporarily added to keep track of these. nextUntil is used to find all elements up until the next element with that class. And finally wrapAll is used to wrap the matched elements in a div.
EDIT: Even easier:
var $divs = $(".holder > div");
for (var i = 0; i < $divs.length; i += 5) {
$divs.slice(i, i + 5).wrapAll("<div class='wrapper'>");
}
http://jsfiddle.net/kMzeN/1/
You're almost there, but a couple of things to note. You will only call your "wrap" function once, as it's outside of the click event. If you are dynamically adding, then you'll want to call it each time.
Secondly, with the HTML in your fiddle, you will never get the 5th record because you are appending your selector is looking for the 5th element with ID "scratchpad" with the class of tally. You'd need to change your selector to something that looks for all tallies, like so:
$(".tally:nth-of-type(5)").css('color', 'red');
I've updated the fiddle you were working on, and my code highlights each 5th record, so you can see what's going on. You were close, but you'll also want to add to your "nth-of-type" selector the use of "n", this way it gets every 5th record, not just the 5th one. So the full function becomes this
$("#plus").click(function() {
var tally = "<div class='tally'>I</div>";
$("#dummy").append(tally);
$(".tally:nth-of-type(5n)").css('color', 'red');
});
Fiddle: http://jsfiddle.net/Hfz9L/16/
To rotate (or apply any other property) to each 5th element, you don't even need to wrap them. Just specify a css class using the nth-of-type(5n) and it will affect every 5th element.
#scratchpad .tally:nth-of-type(5n) {
display: inline-block;
transform:rotate(20deg);
-ms-transform:rotate(20deg); /* IE 9 */
-webkit-transform:rotate(20deg); /* Opera, Chrome, and Safari */
}
Here is your fiddle updated: http://jsfiddle.net/Hfz9L/20/
Check this Working Demo Fiddle
$("#plus").click(function() {
var tally = "<div class='tally'>I</div>";
$("#dummy").append(tally);
$('#scratchpad .tally:nth-of-type(5n+1)').prevUntil('span').wrapAll('<span style="margin-right:5px;color:red;text-decoration:line-through;"></span>');
});
$('#scratchpad .tally:nth-of-type(5n+1)').prevUntil('span').wrapAll('<span style="margin-right:5px;color:red;text-decoration:line-through;"></span>');
Some changes:
$('#scratchpad .tally:nth-of-type(5n+1)') and not $('#scratchpad.tally:nth-of-type(5)'). - .tally is the child of #scratchpad ; selector to be used :nth-of-type(5n+1)
Use .wrapAll() - to wrap the selected elements in a <span> or any other element.
.prevUntil() - get all the previous elements.
You can make a for loop and do this:
for(i=1;i<=noOfChildElements/5;i++)
{
$('.child:nth-child('+i+'), .child:nth-child('+(i+1)+'), .child:nth-child('+(i+2)+'), .child:nth-child('+(i+3)+'), .child:nth-child('+(i+4)+')').wrapAll("<div />");
}
Basically I'm going through the child elements in the for loop and at every turn of the loop I'm selecting the 5 next child elements and wrapping them in a div using the .wrapAll() function. Hope this helps.

Limit Selected Divs to 5?

i'm currently selecting divs using this:
$(".gridbox").click(function () {
$(this).toggleClass("selected");
var isSelected = $(".gridbox.selected").length > 0;
$("#button").toggle(isSelected);
});
});
Is there any way I can limit the number of selected Divs to 5? I have tried:
var isSelected1 = $(".gridbox.selected").length < 3;
if (typeof isSelected1 !== 'undefined') {
alert("You have selected the maximum amount.");
}
But that doesn't seem to work. If anyone has any ideas that'd be greatly appreciated!
Also I am presently selecting divs using:
<div onclick="clicked(this);" class="gridbox" id="1"></div>
Is there anything I can put anywhere to disable a certain ID from being selected?
Many thanks in advance!
Cheers
This seems to achieve what you are looking for:
jsFiddle example
$(".gridbox:not(#disabled)").click(function () {
if ($('.selected').length < 5 || $(this).hasClass('selected')) {
$(this).toggleClass("selected");
}
});
It will limit the selection to 5 of any elements with class .gridbox. Not just the first 5 elements.
With usage of :not, you are unable to select an element with an id of "disabled" in this example.

confusion in jquery parents selector with hasClass function

var allChecked = $('.inboxCheckbox:checked');
if(allChecked.length > 0){
var messageIds = new Array();
var parentRow = null;
allChecked.each(
function(){
parentRow = $(this).parents('tr');
if(!(parentRow.hasClass('gradeA'))){
parentRow.addClass('gradeA');
increaseUnreadMessage();
}
parentRow = null;
messageIds.push($(this).val());
}
);
}else{
showInsMessage('<b class="redTxt">Please Select At Least One Message</b>');
}
i have multiple rows with once checkbox in each row... i was trying to add class gradeA to each row if checkbox is checked.... i do not want to call addClass if it already has class gradeA.... when i select multiple rows then it adds class to only one row. does that mean
lets say i have three rows with checkbox in each row and i select each checkbox when i run
$(':checked').each(
$(this).parents('tr')
)does it select all the rows with checked boxes or only the specfic parent row.... my assuption was it only gives the specific parent row..... if it gives specific row then it should work .. but once i add a class to parent row and move to another row then parentRow.hasClass('gradeA') return true... i am confused now if it checks all the row with checkboxes then is there any way to select specific parent row......
Thanks for reading
Would be nice to see the markup, are there more tables nested?
However,
parentRow = $(this).closest('tr');
should be a better choice.
API says that .parents() method search through all ancestors of the elements.
.parent() travels only a single level up the DOM tree.
If your checkbox is a direct child (not a deep descendant) of 'tr' then you can try
parentRow = $(this).parent('tr');
Your code should work. I suspect that the problem is happening because your function increaseUnreadMessage() is throwing an error, which is causing the rest of the each() loop to be skipped.
But, to answer your specific question: yes, you can select all rows (<td>s) that contain checked checkboxes. Using jquery's :has selector, like this:
var allCheckedRows = $('tr:has(.inboxCheckbox:checked)');
from there, of course, you can just use addClass() to apply your classname to all of them:
allCheckedRows.addClass('gradeA');
of course, you've got other things going on in your each() loop, so you probably can't throw out the each() entirely. As I said above, your code works... but something like this might be cleaner, and easier to understand.
var messageIds = new Array();
var allCheckedRows = $('tr:has(.inboxCheckbox:checked)');
allCheckedRows.addClass('gradeA');
allCheckedRows.find('.inboxCheckbox').each( function() {
var cb = $(this);
increaseUnreadMessage();
messageIds.push( cb.val() );
});
if( messageIds.length === 0 ) {
showInsMessage('<b class="redTxt">Please Select At Least One Message</b>');
}
BTW, I think you can do it more jQuerish style :
var messageIds = [];
$('tr.youTrs').toggleClass('gradeA', function () {
var checkbox = $(this).find('.inboxCheckbox');
if (checkbox.is(':checked')){
messageIds.push(checkbox.val());
return true;
}
else{
showInsMessage('<b class="redTxt">Please Select At Least One Message</b>');
return false;
}
});

Renumbering numerically ordered div ID's when adding one in the middle with Javascript

I'm developing an application with javascript. What I need is to have divs with id's (1,2,3...) and be able to insert a div between, for example, 2 and 3, with jquery, and then have that be the new three, and three becomes four, four becomes five, etc. I've got the div insertion working, I just need to know how to reorder the divs. Any ideas?
After you inserted the new div, you can do this:
var i = 1;
$('div').each(function() {
$(this).attr('id', i++);
});
Replace $('div') by your own selector.
Remember also that, depending on which version of HTML you use, id's can't start with a number.
You can't start IDs with a numeric value, but regardless of that you'd do something like
// set a data value in the div you have just inserted into the dom and set a variable theID to the current ID you have just inserted.
$(this).data('inserted', true);
var theID = $(this).attr('id'); // this will be 3.
// now to update the other divs.
$('div').each(function() {
if($(this).attr('id') >= theID && !$(this).data('inserted')){
$(this).attr('id', $(this).attr('id') + 1);
}
});
// now set the data inserted to false for future updates
$('div#3').data('inserted', false);
$(function() {
reorder();
$('#click').click(function() {
$('<h2>hello world blah!</h2>').insertAfter('.content h2:eq(1)');
reorder();
});
});
function reorder() {
$('.content h2').each(function(i) {
$(this).attr('id', 'order_'+(i+1));
// alert( parseInt(this.id.split('_')[1]) ); // this is the id #
});
};
I'm pretty sure that you get things back in DOM order from jQuery selectors, so couldn't you just find the parent element, select the child <div> elements, and then .each() through the list?

Categories

Resources