How to show the first n number of elements in jQuery? - javascript

I have a page that has 50 elements with the same class "fields" which are all display none at the moment
<div class="fields" style="display:none;">
...
</div>
<div class="fields" style="display:none;">
...
</div>
<div class="fields" style="display:none;">
...
</div>
<div class="fields" style="display:none;">
...
</div>
...
How to I only show the first 3 or whatever number. Plus count them with a count on top like the following example below.
So for example if I needed the first 3 this is what i need the divs to look like
<div class="fields">
<h1>Station 1</h1>
</div>
<div class="fields">
<h1>Station 2</h1>
</div>
<div class="fields">
<h1>Station 3</h1>
</div>
<div class="fields" style="display:none;">
...
</div>
...
So basically only some the number of divs that I need...I already have the number of elements I need to show in this blur statement in the station_count variable. Also notice i need a span tag with the count..any ideas on how to do this
$("#number_station").blur(function(){
var station_count = $(this).val();
//code goes there
});

How to I only show the first 3 or whatever number.
$('div.fields:lt(3)').show();
Plus count them with a count on top
$('div.fields:lt(3)').each(function (index)
{
$('<h1></h1>', {text: 'Station ' + index}).prependTo(this);
}).show();
Demo: http://jsfiddle.net/mattball/TssUB/
Read the jQuery API docs for basic questions like this:
:lt() selector
.prependTo()
jQuery() (for creating new elements)

While the other answers will work, I recently discovered and love the jQuery slice() method.
$(".fields").slice(0, 3).each(function(index) {
// Do whatever you want to the first three elements
}

With
$(".fields").each(function() {
//do whatever like count then show/hide
});
you can iterate over the hidden divs. So with a simple variable you can start/stop whenever you need.

Related

Remove repeated after 1st occurrence

I'm trying to clean up the results presented on my HTML file with Jquery. I want to keep removing words that are repeated more than one time.
A quick example
Accents Australian
Accents English (RP)
Dance Hip Hop
Dance Jazz
It should be output as
Accents
Australian
English (RP)
Dance
Hip Hop
Jazz
My original HTML looks like this
<div role="list" class="skill-items">
<div role="listitem" class="skill-item">
<div class="skill-category">Accents</div>
<div>Australian</div>
</div>
<div role="listitem" class="skill-item">
<div class="skill-category">Accents</div>
<div>English (RP)</div>
</div>
<div role="listitem" class="skill-item">
<div class="skill-category">Dance</div>
<div>Hip Hop</div>
</div>
<div role="listitem" class="skill-item">
<div class="skill-category">Dance</div>
<div>Jaz</div>
</div>
</div>
I tried my best but I'm not landing in a good place
$('.skill-category').text(function(index, oldText) {
return oldText.replace($(this).parent().next().find('.skill-category').text(), '');
})
Any suggestion?
Please check below working code:
const category = [...document.querySelectorAll('.skill-item > .skill-category')];
const texts = new Set(category.map(x => x.innerHTML));
category.forEach(category => {
if(texts.has(category.innerHTML)){
texts.delete(category.innerHTML);
}
else{
category.remove()
}
})
As per you question and shared HTML above is the working code for the same and if you add more similar things it will help.
Please let me know if you find any issues
Your question can be broken into two problems:
You want to group the elements with the same value for .skill-category
You want to change <div> elements into a list.
Grouping the elements could by done like so:
For every category, take a look at the previous element.
Does it contain the same category? If not, then continue to the next category.
If so, take everything after .skill-category (in your example HTML, that's a single <div>. Cut-and-paste it at the end of the aforementioned previous element.
For the second problem:
Changing an element (<div> to <li>) is not possible. You can create a new <li> and move what's inside the <div> into it. Of course, you'll need a <ul> that wraps the <li>s as well.
Take the .skill-category elements
Find all the content that follows the category (in your case, 1+ <div> elements)
Put the contents of the matched elements into a new <li>.
Put all the <li>s of a single category into a <ul>.
Remove the matched elements (in your case, the <div>(s)) since we've moved all their content to a different node. They're now empty tags and useless.
Put the <ul> after the .skill-category.
// Grouping the results.
$('.skill-category').each(function() {
// Get the previous .skill-item and find the category.
var prev = $(this).parent().prev('.skill-item').find('.skill-category');
// Check if the previous category === this category.
var same = !!(prev.length && prev.text() === $(this).text());
if (!same) {
return; // Do nothing.
}
// Take every element after the category and move it to the
// previous .skill-item.
prev.after($(this).nextAll());
// Then remove the now-empty category.
// All content has been moved to the previous element, after all.
$(this).parent().remove();
});
// Wrapping the contents of a category in a list.
$('.skill-category').each(function() {
var list = $('<ul></ul');
// Find everything after the category.
$(this).nextAll().each(function() {
// Create a <li> and move the child elements to it.
// Then add the <li> to the <ul>.
$('<li></li>').append($(this).contents()).appendTo(list);
}).remove(); // remove the now empty elements.
// Add the list to current .skill-category.
$(this).append(list);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div role="list" class="skill-items">
<div role="listitem" class="skill-item">
<div class="skill-category">Accents</div>
<div>Australian</div>
</div>
<div role="listitem" class="skill-item">
<div class="skill-category">Accents</div>
<div>English (RP)</div>
</div>
<div role="listitem" class="skill-item">
<div class="skill-category">Dance</div>
<div>Hip Hop</div>
</div>
<div role="listitem" class="skill-item">
<div class="skill-category">Dance</div>
<div>Jaz</div>
</div>
</div>

JS and querySelectorAll

A querySelectorAll question, most likely a silly one, but I don't see the solution.
I have something like the following
<div id="main_0"> ... </div>
<div id="main_1"> ... </div>
<div id="main_1_minor"> ... </div>
<div id="main_2"> ... </div>
<div id="main_2_minor"> ... </div>
.
.
I wish to select all and only those div's without minor.
I tried
var pattern = new RegExp('^main_\\d');
var elSelected = document.querySelectorAll('div[id^=main_]');
elSelected.filter(elt => pattern.test(elt.id)));
but clearly it is not enough. I am not sure how to formulate by RegEx that the id value has to terminate with a digit. I tried something like RegExp('^main_\\d$'); but I did not get it right.
You can use the :not() selector with the "attribute ends with" selector.
"div:not([id$=minor])"
If it should also verify that the id starts with main_, then you can add that too as you show in your question.
"div[id^=main_]:not([id$=minor])"
So this says "select all div elements where the id starts with main_ and does not end with minor".
If minor is not necessarily at the end, then you can use id*=minor for "contains" instead.
document.querySelectorAll("div[id^=main_]:not([id$=minor])")
.forEach(el => el.style.color = "red");
<div id="main_0"> main </div>
<div id="main_1"> main </div>
<div id="main_1_minor"> main ends with minor </div>
<div id="main_2"> main </div>
<div id="main_2_minor"> main ends with minor </div>
The filter won't work for NodeList, cast to array first. Also if you already selected all main divs the simplest regex would be enough.
var pattern = new RegExp(/\d+$/);
var elSelected = Array.prototype.slice.call(document.querySelectorAll('div[id^=main_]'));
elSelected.filter(elt => pattern.test(elt.id)).forEach(function(elt){
elt.style.backgroundColor = "yellow";
});
<div id="main_0">main_0</div>
<div id="main_1">main_1</div>
<div id="main_1_minor">main_1_minor</div>
<div id="main_2">main_2</div>
<div id="main_0_minor">main_0_minor</div>

jQuery - get index of element, restricted to class

Given the following html:
<div class="my-container">
<div class="x">
Link 1
</div>
<div class="x">
Link 2
</div>
<div class="x">
Link 3
</div>
<div class="x y">
Link 4
</div>
<div class="x">
Link 5
</div>
<div class="x y">
Link 6
</div>
<div class="x">
Link 7
</div>
</div>
Which elements get the y class - is a dynamic thing, which changes during runtime based on different user interactions.
On mouse over an anchor (I can assume that the anchor is in a div with the y class, because only those are visible), I need to get the index of it's container (that div with the y class), but restricted to that y class.
Meaning:
mouseover on "Link 4" should tell me: 0 (first element with class y)
mouseover on "Link 6" should tell me: 1 (second element with class y)
.index() doesn't help me here
EDIT:
#Kevin B
I've read the docs, but couldn't make it work. The closest thing I could find there was to pass a collection to .index(), which I've tried. But didn't work (also, their example for the collection is with vanilla js document.getElementById - that didn't work for me, need to work with classes; tried to adapt: myCollection = $(this).closest('.my-container').children('.y') and passed that to .index(), and it didn't work).
I wouldn't post without google-ing first and also going through the docs, don't know why the down vote (not pointing any fingers, I'm not assuming I know who's is it). Just because I said ".index()" doesn't help me"? Well, I've tried whatever I understood I could do with it, and couldn't make it happen. That's why I posted.
As said in the comments, index is exactly what you need:
$(document).ready(function() {
//mousein
$("a").hover(function(){
var parent = $('.my-container').eq(2); // the 3rd "my-container"
console.log(parent.find('.y a').index(this)); //-1 if elm doesnt exist
},
//mouseout
function(){
})
});
As said in the comments, index is exactly what you need:
$(document).ready(function() {
//mousein
$("a").hover(function(){
console.log($(this).index('.y a')); //-1 if elm doesnt exist
},
//mouseout
function(){
})
});
var count = 1;
$(".my-container div").on('mouseover',function(){
if ($(this).attr("class").indexOf('y') > -1){
alert(count + "th mouseover on y class");
count++;
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="my-container">
<div class="x">
Link 1
</div>
<div class="x">
Link 2
</div>
<div class="x">
Link 3
</div>
<div class="x y">
Link 4
</div>
<div class="x">
Link 5
</div>
<div class="x y">
Link 6
</div>
<div class="x">
Link 7
</div>
</div>

filtering and sorting divs

I have been looking for a robust and simple way to sort my casestudies but after a couple of hours and a search of stack overflow i could not find a way to filter casestudies the way I want.
Basically I will give each casestudy three categories (year produced, type of project and name) using css classes, for example the markup would look something like this
<div class="name1 home 2013"></div>
<div class="name2 work 2012"></div>
<div class="name3 home 2012"></div>
<div class="name4 charity 2012"></div>
<div class="name5 home 2010"></div>
<div class="name6 work 2007"></div>
Then I want to have buttons so you can choose which category you want to sort the casestudies by. So something like.
<div class="button" id="year">Sort by Year</div>
<div class="button" id="alpha">sort Alphabetically</div>
<div class="button" id="type">sort by type</div>
This is where I am getting stuck. What javascript function can i create so that if you click the button "sort by year" it will create a mark up that looks like this. eg sorting all the casestudies in to divs with casestudies of the same year.
<div>
<div class="name1 home 2013"></div>
</div>
<div>
<div class="name2 work 2012"></div>
<div class="name3 home 2012"></div>
<div class="name4 charity 2012"></div>
</div>
<div>
<div class="name5 home 2010"></div>
</div>
<div>
<div class="name6 work 2007"></div>
</div>
I would use data attributes to make the filtering easier.
<div class="name1 home" data-year="2013">2013</div>
<div class="name2 work" data-year="2012">2012</div>
<div class="name3 home" data-year="2012">2012</div>
<div class="name4 charity" data-year="2012">2012</div>
<div class="name5 home" data-year="2010">2010</div>
<div class="name6 work" data-year="2007">2007</div>
The using JQuery and array.map (could be replaced with a foreach if you want older browser support)
var studies = $('[data-year]')
studies.map(function(index, el) {
var $el = $(el)
year = $el.attr('data-year')
if($('#' + year).length == 0){
$(document.body).append(
$('<div>').attr('id', year)
.css('margin-bottom', '20px')
)
}
$('#' + year).append(el)
})
what this does is take all the elements with a data-year attribute, foreach element check to see if a div with the id of that elements year exists. If it doesn't create one and append it to the body. Then it appends the element into the year container.
see this jsfiddle

jQuery to check if ID value has a number

Is there a way in jQuery to check if an ID value (Ex. id="number1") contains a number?
The idea would be:
if (ID has a number which will come from a variable) then do something.
this is what I came up with so far but it only works with the first div:
$("#tabsstyle li a").bind("click", function () {
var numSlide = $(this).attr("rel");
if ($('#slidesContainer div').attr('id').match(numSlide) ) {
$('#slidesContainer div').fadeIn();
}
numSlide will store a number coming from one of the 'a' clicked and check that number will be included in the id value of '#slidesContainer div', once that checked then the right div will fadeIn.
HTML structure below:
<div id="slidesContainer">
<div id="n1" class="slide">
<h2>Web Development Tutorial</h2>
<p><button class="test">N1</button></p>
</div>
<div id="n2" class="slide">
<h2>Grunge Brushes, Anyone?</h2>
<p><button class="test">N2</button></p>
</div>
<div id="n3" class="slide">
<h2>How About Some Awesome Grunge Textures?</h2>
<p><button class="test">N3</button></p>
</div>
<div id="n4" class="slide">
<h2>'Tis the End, My Friend.</h2>
<p><button class="test">N4</button></p>
</div>
</div>
var id = $('#element').attr('id'); // #element will replace
// with your desired selector
id.match(/[0-9]/g)
Checking
if( id.match(/[0-9]/g) ) {
// do something
}
You can take a look at the following jquery plugin
https://github.com/jquery/globalize
That handles "numbers" a number can be an integer or a decimal, and a decimal number has different representations based on the culture :)
You can use javascript to build a function with test and a regular expression to check if a string contains a number.
function hasNumber(t){
//regular expression: /\d/g
return /\d/g.test(t);
}
And then use jQuery to check the value of the attribute id
alert (hasNumber($('#checkMe').attr('id')))

Categories