How would I count the number of elements with the attribute of "selected" if the selected attribute is added dynamically on click?
Here is how I'm adding the "selected" attribute:
var $li = $('.swrt_checkbox_button');
$li.on('click', function(){
var $el = $(this);
$el.toggleClass('checkbox-selected');
$el.attr('selected', function(index, attr){
return attr == "selected" ? null : "selected";
});
});
So, what I want to achieve is, if all my elements have the selected attr, then I want to do something, in this case, disable another UI element.
The problem I'm having is this, if I check to see if the attr is selected within the click it works:
if($el.is("[selected]")) {
console.log('yes');
}
This logs inside the click function but not outside it. So how can I say:
If all elements have "selected" attr { do stuff }?
Obviously I can't do it within the click because the $el is pointing to "this".
Any help or advice you can offer would be much appreciated.
Thanks
Since $li refers to the entire list, just compare how many have the selected attribute:
var totalElems = $li.length;
var selectedElems = $('.swrt_checkbox_button[selected]').length;
if (totalElems == selectedElems) {
//All selected
}
You can stick this at the end of your click event, so it'll run each time.
You could add a little line at the ewnd of your click, after activating a selection. Just check if there are any unselected elements left, if not, then run whatever you need.
// Check if there are any unselected left.
if(!$('.swrt_checkbox_button:not([selected])').length){
// Do the all-are-selected thing
}
Here's a quick implementation:
$('li').click(function(e){
e.preventDefault();
$(this).toggleClass('selected');
if(!$('li:not(.selected)').length) alert('all are selected')
})
li {
display: block; widht: 100px; height: 100px;l
}
li.selected { background: red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
I would like to not that selected is not a prop that should be used on li elements. Just use a class here.
This is how I would do it:
$("#sel").click(function () {
$("input:not(:checked)").first().prop("checked", "checked");
if ($("input[type='checkbox']").length == $("input[type='checkbox']:checked").length) {
alert("All selected :)");
}
});
Here is the JSFiddle demo
Thanks to everyone who commented. Here is what I did to make it work using tymeJV's solution:
function addCheck() {
var $li = $('.swrt_checkbox_button');
$li.on('click', function(){
var $el = $(this);
$el.toggleClass('checkbox-selected');
$el.attr('selected', function(index, attr){
return attr == "selected" ? null : "selected";
});
var totalElems = $li.length;
var selectedElems = $('.swrt_checkbox_button[selected]').length;
if (totalElems == selectedElems) {
$('.checkboxes-btn').removeAttr("disabled");
} else {
$('.checkboxes-btn').attr("disabled", "disabled");
}
});
}
addCheck();
Probably could be cleaner but it works so thanks!
Related
I am working on the two ul lists. What I need is if someone click on the list item in list1, it will check if the 2nd list contains the clicked element or not. If it does not contain the element then copy it else just return.
What I have done so far is I am moving the elements successfully between the list but if I apply a check on it everything stops working.
Here is the link of jsfiddle.
$().ready(function() {
var classHighlight = 'highlight';
var $thumbs = $('ul li').on("click", function(e) {
//e.preventDefault();
debugger;
$thumbs.removeClass(classHighlight);
$(this).addClass(classHighlight);
});
$('#select1').on("dblclick", "li", function() {
//if($("#select2").has($(this))
//return;
//else
$(this).clone().appendTo('#select2').removeClass('highlight');
});
$('#select2').on("dblclick", "li", function() {
$(this).remove();
});
$('#add').click(function() {
$('#select1.highlight').clone().appendTo('#select2').removeClass(classHighlight);
});
$('#remove').click(function() {
$('#select2.highlight').remove();
});
});
If you un comment the above lines in code everything stop working.
Can any one please help me with this?
Thanks
Try this check:
var check = function(li) {
return $("#select2 li").filter(function(i, li2) {
return $(li2).text() == $(li).text();
}).length > 0;
};
Demo
As you're using clone(), you can't compare the new cloned element using is() or has() with the orignal one, because it is a new element, it isn't the same, as stated in clone's docs:
Create a deep copy of the set of matched elements
So it's a copy.
You have a missing paren.
This if($("#select2").has($(this)) should be this if($("#select2").has($(this))).
Also you can just pass this: if($("#select2").has(this))
And you have to check length: if($("#select2").has(this).length)
Using jquery.collapsible.js I notice that the tabindex does not change when expanded/closed. I nearly have a solution but would appreciate it if someone could improve on this piece of code as I am sure there is a better way to do this.
$('.collapsible').each(function() {
$('.collapsible').on('click',function(e) {
if($('div').hasClass('collapsible collapse-open')) {
$('.collapsible.collapse-open').attr("tabIndex", 0);
} else {
$('.collapsible.collapse-close').attr("tabIndex", -1);
}
});
});
The problem is the tabindex only changes on the second click and then the 0,-1 order is wrong.
If you're just looking for a better way, and your solution already works, you could simplify it with this. You don't need to loop through each .collapsible with the each function just to add the click event handler.
$(".collapsible").on('click', function (e) {
var self = $(this);
var tabIndex = self.hasClass("collapse-open") ? 0 : -1;
self.attr("tabIndex", tabIndex);
});
This will select any element with the class collapsible, bind the click event, and then check if that element has the collapse-open class to determine which tab index to apply.
Thanks to Ihan for the more efficient script. It is working now I just had to change the default class from 'collapse-open' to 'collapse-close'.
$(".collapsible").on('click', function (e) {
var self = $(this);
var tabIndex = self.hasClass("collapse-close") ? 0 : -1;
self.attr("tabIndex", tabIndex);
});
I want to add an event listener to my unordered list elements with jQuery. When one of the list elements are clicked another unordered list is checked whether it has the clicked element from the former list, more correctly the clone of it, a list element with same text. If the latter list has it nothing happens, however if it does not have it, a copy of it is added to this latter unordered list.
I try to achieve it with each() but cannot manage to success the conditional append() and the case of starting with an empty selecteds list.
I need the latter list, selecteds, be empty once.
How can this be achieved?
$("ul#list li").on("click", function(event) {
var t = $(event.target).text();
if ($("ul#selecteds li").length == 0) {
$("ul#selecteds").append("<li></li>");
}
$("ul#selecteds li").each(function(index) {
var s = $(this).text();
if (s !== t) {
console.log("he");
$(event.target).clone().appendTo($("ul#selecteds"));
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="selecteds">
</ul>
<ul id="list">
<li>asdf</li>
<li>qwer</li>
<li>zxcv</li>
</ul>
You have the right idea, but you can't add a clone every time an element in the "selected" list doesn't match.
Also, you don't need to say e.g. ul#selecteds - ids are unique, and sufficient on their own.
$("#list li").on("click", function(event) {
var t = $(this).text(); // the clicked text
var exists = false; // is it already selected?
$('#selecteds li').each(function() {
if ($(this).text() == t) {
exists = true; // found a match
return false; // stop looking
}
});
// no match? add one
if (! exists) {
$('<li>').text(t).appendTo('#selecteds');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul id="selecteds">
</ul>
<ul id="list">
<li>asdf</li>
<li>qwer</li>
<li>zxcv</li>
</ul>
I want to select two elements and when I click the button element I want them to swap place, how would I do that? I've searched and looked for similar answers, but most of them only swap the element up or down.
I'm thinking something like:
$('button').click(function(){
$('#item 1 .selected-item').removeClass('.selected-item').appendTo('#item2');
$('#item 2 .selected-item').removeClass('selected-item').appendTo('#item1');
});
But I don't know how to start, it should look something like this:
http://jsfiddle.net/tLNAh/1/ (my fiddle)
try this.
http://jsfiddle.net/tLNAh/3/
$("button").on("click", function() {
$first = $(".selected:eq(0)");
$second = $(".selected:eq(1)");
var tempText = $first.text();
$first.text($second.text());
$second.text(tempText);
$("#instructionText").text("Instructions: choose an item");
});
With your markup do this:
$("button").on("click", function() {
$('.selected').insertBefore($('ul:eq(1) li:first'));
});
Demo
Or you can update to this:
$("button").on("click", function() {
if($('.selected').closest('ul').index() < $('.selected').closest('ul').siblings('ul').index()){
$('.selected').insertBefore($('ul:eq(1) li:first'));
}else{
$('.selected').insertBefore($('ul:eq(0) li:first'));
}
});
Updated fiddle
Chk this : fiddle link
Provide id to your ul :
<ul id="item1">
<ul id ="item2">
And try this :
$("button").on("click", function() {
$("#instructionText").text("Instructions: choose an item");
$('#item1 .selected').removeClass('selected').remove().appendTo('#item2');
$('#item2 .selected').removeClass('selected').remove().appendTo('#item1');
});
$("body").on("click","li", function(e) {
$(this).toggleClass("selected");
$("#instructionText").text("Instructions: choose the item to change place with");
});
You have to get index of list elemet and use this:
http://jsfiddle.net/faceleg/FJt9X/2/
var swapElements = function(siblings, subjectIndex, objectIndex) {
// Get subject jQuery
var subject = $(siblings.get(subjectIndex));
// Get object element
var object = siblings.get(objectIndex);
// Insert subject after object
subject.insertAfter(object);
}
$(function() {
swapElements($('li'), 0, 1);
});
Try this:
function swapItems(first, second) {
var sibling = first.next();
if (sibling.length) {
first.insertBefore(second);
second.insertBefore(sibling);
} else {
sibling = first.prev();
if (sibling.length) {
first.insertBefore(second);
second.insertAfter(sibling);
} else {
var parent = firstItem.parent();
first.insertBefore(second);
second.appendTo(parent);
}
}
}
Updated fiddle
Edit: I updated the fiddle, now you have to click the button to swap items.
I have a list view in html which has headers and child elements. I have implemented jquery script to filter the header and child elements, but the problem is when I search the child elements, I get that specific child element with other elements in it also. The actual result should be (suppose I search "xxx" in the searchbox, the output should be the header element and the child-xxx element only which is not happening). I get the xxx result with other child element-aaa also. Please help. I have attached the jsfiddle link "My Test Fiddle"
$("#search").keyup(function(){
var SEARCHWORD = this.value;
$("#list li").each(function(){
if($(this).
text().toUpperCase().
indexOf(SEARCHWORD.toUpperCase()) >=0)
$(this).show();
else
$(this).hide();
});
});
I've modified your fiddle to include a combination of CSS and JS to accomplish what you want. One of your complications is that you want the header to show if any of the siblings match. So you cannot hide the header based on a non-match because there may be a different sibling match.
Second is that multiple siblings could potentially match. This means you can't just show/hide siblings based on a match. If both siblings match you need to show both, and any code that hides siblings could potentially hide a previous match.
I've added CSS code to do the showing/hiding based on matches and the event that the user is searching something (so clearing the box will reshow everything). Then the JS just sets or removes the 'hit' class.
#list.searching h3, #list.searching li > p { display: none }
#list.searching li > p.hit, #list.searching li.hit h3 { display: block }
The JS
var theList = $('#list');
$("#search").keyup(function(){
var SEARCHWORD = this.value;
// remove all hits each time
theList.find('.hit').removeClass('hit');
if (SEARCHWORD) {
// if a search term make sure the list is marked
theList.addClass('searching');
} else {
// remove searching mark
theList.removeClass('searching');
}
$("#list li p").each(function() {
// case-insensitive matching
if (this.innerText.toLowerCase().indexOf(SEARCHWORD.toLowerCase()) > -1) {
$(this).addClass('hit').parent().addClass('hit');
} else {
$(this).removeClass('hit');
}
})
});
Here is the updated fiddle http://jsfiddle.net/gS4AS/4/
Try this:
$("#search").keyup(function () {
var SEARCHWORD = this.value;
$("#list li").each(function () {
$(this).hide();
$('p:contains(' + SEARCHWORD + ')').closest('li').show();
$('p:contains(' + SEARCHWORD + ')').show().siblings('p').hide();
if (SEARCHWORD == "") {
$('#list').find('p:hidden').show();
}
});
});
Fiddle
You have to add this condition to show back the hidden elems:
if (SEARCHWORD == "") {
$('#list').find('p:hidden').show();
}
Updated Fiddle
As per your latest dom structure with tables and tds update to this code:
$("#search").keyup(function () {
var SEARCHWORD = this.value;
$("#list tr").each(function () {
$(this).hide();
$('td:contains(' + SEARCHWORD + ')').closest('tr').show();
if (SEARCHWORD == "") {
$('#list').find('tr:hidden').show();
}
});
});
Updated Fiddle with table structure.