Hide same elements in a list - javascript

I have a problem I want to solve with jQuery. In a list, I want to check if two items have the same text, and if so I want to delete the second one.
I am not really sure how to go about it.
The markup is simple, kinda like this
<ul>
<li>Text1</li>
<li>Text2</li>
<li>Text1</li>
<li>Text3</li>
<li>Text3</li>
<li>Text4</li>
<ul>
I cannot use an active/inactive class because this list is dynamic and I don't know in advance how it's going to be populated.
Any idea?

$.inArray for a tmp array would work.
$(document).ready(function(){
var tmparr = [];
$('.list li').each(function(i,item){
if($.inArray($(this).text(), tmparr) >= 0){
$(this).remove();
}else{
tmparr.push($(this).text());
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="list">
<li>Text1</li>
<li>Text2</li>
<li>Text1</li>
<li>Text3</li>
<li>Text3</li>
<li>Text4</li>
<ul>

You can achieve this e.g. like this:
var unique = {};
$('li').each(function() {
var txt = $(this).text();
if (unique[txt])
$(this).remove();
else
unique[txt] = true;
});
Fiddle
As explanation: unique is initialized as object. While each() iterates over all li elements, the if (unique[txt]) is true in case it was previously set to true for the text of the li currently processed. In this case the current li will be removed. If not, unique[txt] for the text of the current li is set to true and added to unique. As it might not be clear what unique finally contains: { Text1=true, Text2=true, Text3=true, Text4=true }

You will need to iterate over your li elements and store their text in an array. If the text for the ith element is already in the array, skip it. Once you have an array of unique text strings, remove all li elements and generate new ones from the information in your array.

http://jsfiddle.net/k255o52e/1/
$('ul li').each(function () {
var txt = $(this).text();
// finds all LI that contain the same text
// excludes the first element
var $li = $('li:contains("' + txt + '"):not(:first)');
// and removes the other
$li.remove();
})
UPDATE:
$('ul li').each(function () {
var txt = $(this).text();
var $li = $('li:contains("' + txt + '"):not(:first)').filter(function(index)
{
return $(this).text() === txt;
});
$li.remove();
})

Related

Get all the data of a loop in JavaScript [duplicate]

I have an html list something like this:
<li id="tag">red</li>
<li id="tag">yellow</li>
<li id="tag">blue</li>
How can I get the content of these li tags using jQuery?
For example;
$tags = red, yellow, blue
You can use jQuery.map()
Live Demo
texts = $('li').map(function(){
return $(this).text();
}).get().join(',');
var $tags = $("li").map(function(){
return $(this).text();
}).get().join(",");
Here, have a fiddle: http://jsfiddle.net/KTted/2/
First, you should change your id="tag" to class="tag", as you can't have multiple elements with the same id.
You can build an array of the values:
var content = [];
$("li").each(function (element) {
content.push[$(element).text()];
});
Or as others have pointed out, you can use map:
var content = $("li").map(function() {
return $(this).text();
}).get().join(",");

How do you fill a text field based on dynamically generated links?

The gist of it is that I have a dynamically generated drop down based off an array in JQuery. I have a text field next to it that should output an answer based on what was selected in the array.
<ul>
<li>
Vendor Contacts
<ul class="vendor_list">
</ul>
</li>
<input id="vendor_contact" type="text" />
</ul>
This is the HTML that I set up and here's the Javascript:
var vendors = ['vendor1, vendor2, vendor3'];
var contact_info = ['email1','email2','email3']
var vList = $('ul.vendor_list');
$.each(vendors, function (i)
{
var li = $('<li/>')
.addClass('menu_item')
.attr('role', 'menuitem')
.appendTo(vList);
var aaa = $('<a/>')
.addClass('vendors')
.text(vendors[i])
.appendTo(li);
});
What I think is the next step is:
$("#vendor_list").on('click', '.vendors', function () {
$("vendor_contact")val($(contact_info[i]))
Needless to say, I mind's pretty warped around this one. I'm starting to get into jQuery and just want to see how I can fill the text box in.
First, you have missing quotation marks in your vendors array:
var vendors = ['vendor1', 'vendor2', 'vendor3'];
Next, you should use class selector, not id on your .vendor_list element:
$(".vendor_list").on('click', '.vendors', function () {
// ...
Next, missing # sign, as you're selecting the element by its id:
$("#vendor_contact")val(//...
(by $("vendor_contact") you're trying to select a not existing tag <vendor_contact>)
Last thing, use something like data attribute to determine the actual selection:
$.each(vendors, function(i){
var li = $('<li/>')
.addClass('menu_item')
.attr('role', 'menuitem')
.appendTo(vList);
var aaa = $('<a/>')
.addClass('vendors')
.text(vendors[i])
// add 'data-id' attr:
.data('id', i)
.appendTo(li);
});
final JS:
$(".vendor_list").on('click', '.vendors', function () {
$("#vendor_contact").val(contact_info[$(this).data('id')]);
});
JSFiddle Demo

Populating ul list with index

I am having trouble populating a ul li with its index value.
My HTML below.
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
My JS below.
$('document').ready(function(){
var indexus = $('li').index();
$('li').each(function(){
$('li').html(indexus);
});
});
JS Fiddle: http://jsfiddle.net/kuJWc/407/
I want to populate the li with its appropriate li index value, but I can only end up getting the index value of the latest (in this case 3). How would I go about looping in each index value so that each li shows the value of its own index number?
you should do like this:
$('li').each(function(){
$(this).html($(this).index());
});
you were adding the index to all the li.. so istead of $(this) inside of the each, you were using $('li'). which adds the last value li index to all of them.
Try this:
$('document').ready(function(){
$('li').each(function(){ // iterate through each `li`
var $li = $(this); // get the current `li` element
var index = $li.index(); // get the current `li` index
$li.html(index); // set the `li`'s html to the index value
});
});
I added some comments to help you understand what each step does, I hope that helps!
What about this:
$('document').ready(function(){
var indexus = $('li');
for (var i = 0; i <= indexus.length; i++) {
$(indexus[i]).html(i);
}
});
Here it works.
You can get an array of the ul's children and then iterate over each of the children with something like this:
var arr = $('ul').children();
for (var i = 0; i < arr.length; i++){
$(arr[i]).html(i);
}

Issue with adding UL markup for LI

This sounds simple, and it should be, but it doesn't seem to be so cut and dry...
I have a list of li elements..
<li>Text here</li>
<li>Text here</li>
<li>Text here</li>
What I want to do is find the 1st one, add <ul> before it. Find the last one, add </ul>
It sounds simple but stay with me...
First I tried this:
$('li').each(function(i,obj) {
var x = $(this);
if(x.prev().prop('tagName')!=='LI') x.before('<ul>')
if(x.next().prop('tagName')!=='LI') x.after('</ul>')
});
Which evolved into this:
$('li').each(function(i,obj) {
var x = $(this);
$.fn.outerHTML = function(){
var x = $(this);
x.wrap('<p/>')
var html = x.parent().html();
x.unwrap();
return(html);
}
alert(x.outerHTML());
if(x.prev().prop('tagName')!=='LI') x.html('<ul>'+x.outerHTML())
if(x.next().prop('tagName')!=='LI') x.html(x.outerHTML()+'</ul>')
});
The 1st code places an empty UL before the 1st LI (closing tag and all)
The 2nd wraps only the 1st LI.
It goes down the list 1, 2, 3 and seems to report back properly... something (possibly jQuery) seems to be altering my code somewhere along the way. Can anyone shed some insight here?
Fiddle to fiddle with: http://jsfiddle.net/yr67N/
Update:
As you can see from the code, the lis must be grouped together. wrapAll won't work here.
Just tried this on your fiddle and it appears to work:
var collectedLi = [];
$('li').each(function(){
collectedLi.push(this);
if(!$(this).next().is('li')){
$(collectedLi).wrapAll('<ul/>');
collectedLi = []
}
});
For every li it will check if the next element is also an li, if not it will wrap the current collection in a ul and then empty the collection to continue the loop.
Just realized that the above code will also wrap already wrapped li tags, here is a solution that will handle this:
var collectedLi = [];
$('li').each(function(){
collectedLi.push(this);
if(!$(this).next().is('li')){
if(!$(this).parent().is('ul')){
$(collectedLi).wrapAll('<ul/>');
}
collectedLi = []
}
});
How about:
$('li').wrapAll('<ul/>');
Fiddle
var ul,
tname;
$('li').each(function(i, el){
tname = $(el).prev().prop('tagName');
if(String(tname) !== 'UL'){
ul = $('<ul></ul>');
$(el).before(ul[0]);
}
$(this).appendTo(ul);
});
fiddle

How to find number of <ul> inside each div

I have a large file of this form [similar div's throughout]. I want to be able to select a div, find the number of ul's in it and traverse through each of them to get value of each li in it.
<div class="experiment">
<div class="experiment-number">5</div>
<ul class="data-values">
<li><div></div> 14</li>
<li><div></div> 15</li>
</ul>
<ul class="data-values">
<li><div></div> 16</li>
</ul>
</div>
I have tried looping through all experiment divs, then select the uls, but it selects all the ul in the page, not only the ones under current div.
$('experiment ul').eq('$i');
Your HTML is currently incorrect, since you're simply starting new <div> and <ul> elements rather than closing the existing ones. Ignoring that because it's trivial to fix, we'll move on to the real issue.
You need to select all of the <div class="experiment"> elements, then iterate through them. To do that you can use the .each() function. It might look something like this:
var experiments = $('.experiment'); // all of them
experiments.each(function(i, val) { // will iterate over that list, one at a time
var experiment = $(this); // this will be the specific div for this iteration
console.log("Experiment: " + experiment.find('.experiment-number').text());
// outputs the experiment number
console.log("Experiment ULs: " + experiment.find('ul').length);
// number of <ul> elements in this <div>
var total = 0;
experiment.find('ul.data-values li').each(function() {
total += parseInt($(this).text(), 10);
});
console.log("Experiment total: " + total);
// outputs the total of the <li> elements text values
});
Take a look at this jsFiddle demo.
to get all the ul inside div.experiment
var ul = $('.experiment').find('ul');
and to get all li elements inside each ul found above
ul.each(function(list) {
var li = $(list).find('li');
});
$('.experiment').each(function() {
var cnt = $(this).children('ul').length;
$(this).find('.experiment-number').text(cnt);
});
First of all you need to work out the correct selector for each DIV.
The selector you want is:
".experiment"
Notice the . to denote a class selector.
This will allow you access to each DIV element. If you then want to loop though each of these, you can do so like this:
$(".experiment").each(function(){
var div = $(this);
var elementsInThisDiv = div.find("ul");
//you now have a list of all UL elements in the current DIV only
var numberOfElements = elementsInThisDiv.length;
//you now have a count of UL elements belonging to this DIV only
//you can loop the UL elements here
$(elementsInThisDiv).each(function(){
var ul = $(this);
//do something with the UL element
//like get the LI elements...
var liElements = ul.find("li");
});
});
IMPORTANT: There is also an error with your HTML, you need to close your <ul> elements correctly using </ul>

Categories

Resources