Add list items letter separator - javascript

I have i 'asc' list of names, i'd like to add a letter so it would be look like something like this:
<li>Abram</li>
<li>Amanda</li>
<li>Bernard</li>
<li>Fox</li>
to
<div>A:</div>
<li>Abram</li>
<li>Amanda</li>
<div>B:</div>
<li>Bernard</li>
<div>F:</div>
<li>Fox</li>
any ideas?

Since you're using jquery, you can do something like this:
var currentLetter, prevLetter = null;
$("li").each(function() {
currentLetter = $(this).find("a").text()[0];
if (currentLetter != prevLetter)
{
$("<div>").text(currentLetter).insertBefore($(this));
}
prevLetter = currentLetter;
});
http://jsfiddle.net/Uw9L4/
Though technically you shouldn't be putting a div inside of a ul (even though it totally renders fine). I would go with inserting li without an anchor to maintain semantics.

Related

Jquery: Replace a part of each attribute [duplicate]

Do someone know what is the best way to replace some string inside a onclick attribute ?
I need to get the current value and replace some text inside parameters.
Exemple, I have this link:
My link
And I want this:
My link
In other words, I want something like this:
$('a').attr('onclick', $(this).attr('onclick').replace('1', '2'));
And I know I can do this, but I need something dynamic retreiving the values of current element:
$("a").attr('onClick', "myfunction('parameter2a','parameter2b')");
Finally it working when I made a simple demo: http://jsfiddle.net/GkWhh/4/
Thank you for your solutions !
$('a[onclick]').attr('onclick', function(i, v){
return v.replace(/1/g, '2');
});
http://jsfiddle.net/cj9j7/
If you need something more dynamic do not use onclick attributes, changing onclick attributes is hackish, you can use click method instead.
var param = 1;
$('a').click(function(){
// ...
if ('wildguess') {
param = 1;
} else {
param++;
}
})
sounds like a really bad idea but anyway - you can access the string value of the onlick attribute using something like that:
$('a').each(function() { this.attributes.onclick.nodeValue = this.attributes.onclick.nodeValue.replace('1', '2'); })
You can do this: http://jsfiddle.net/SJP7k/
var atr = $('a').attr('onclick');
var str = atr.split('1');
var natr = str.join('2');
$('a').attr('onclick',natr);

javascript hash tag linking

I'm trying to modify this porfolio script here: http://themes.iki-bir.com/webpaint/multipage/full/portfolio.html
It uses urls like #entry-12 (using the index number of the element to deeplink the item) and I'd like to change it to #this-is-an-item
updateURLParameter(thumb.attr("data-event-id"));
//updateURLParameter("entry-"+thumb.index());
It sets the name here (which works fine)... now it's whatever.html#this-is-an-item
But now I need to change the behaviour when they link in from the URL (as it no longer works since it's still looking for the index number instead of a name).
var deeplink = getUrlVars("#");
// DEEPLINK START IF NECESSARY
if (deeplink[0].split('entry-').length>1) {
var thmb = parseInt(deeplink[0].split('entry-')[1],0)+1;
$container.find('.item:nth-child('+thmb+')').click();
$container.find('.item:nth-child('+thmb+')').addClass("active").children('a').children('div').fadeIn(300);;
}
I'm just not sure how to do the last part, so it looks for the data-event-id instead of the index?
<li class="item installation 2013-10-13" data-event-id="installation-opening-whispering-in-the-leaves"... </li>
Try this:
var deeplink = getUrlVars("#");
var $elem;
// v--- this can be changed to .find('.item) if needed.
$container.children('.item').each(function() {
// you can use .data(...) instead of .attr("data-...")
if ($(this).data("event-id") == deeplink[0])
$elem = $(this);
});
if ($elem) {
$elem.click()
.addClass("active")
.children('a')
.children('div')
.fadeIn(300);
}
Simply iterate over all the elements in $container with the class .item, and check if the data-event-id matches the one in the URL hash. If it does, store it, and do your operations afterwards.

Stmixing string with array variable to assign an id for an element in javascript

I´m trying to mix a string to assign variable(array) I don´t know what´s wrong I can not get it work.
in php I will send array of id to javascript via json_encode();
I will get like :key= 1, 2, 3 etc.
Here is aline of those div:
text
Then in javascript with a conditon like this:
$("#swas"+key).removeClass('colorme');
function xx(key, arr) {
for (var v in arr) { //LOOP
var k = arr[v];
if ($("#swas" + k) != key) {
$("#swas" + k).addClass('colorme');
}
}
}
What have I done wrong ?
UPDATE
The reason I want to mix "swas" with array because in php page there´re alot of div that name
swas1, swas2, swas3, swas4.........>etc
And "key" is the id of current div that will be clicked. and "key" value : 001, 002, 003, 004 etc
What I want to do is to make the other div (that´s not the current div )to not change color.
that´s why I have to mix the word "swas" with the "key" in javascript.
UPDATE2
Now It work with script above but new probelm, it not remove the class when clicked :S
UPDATE3
Now everything just work fine after I move the $("#swas"+key).removeClass('colorme');
To the bottom :) S
You mention swas1 swas2 etc, but then you mention arr being 001 002 etc. These will not match.
It would be so much easier if you used jquery
$('#swas' + k).addClass('colorme');
You can use something like Firebug to ensure that your selection is correct.
If you want to use javascript then test to see if the Div already has a class before appending
var el = document.getElementById('hello');
if(el) {
el.className += el.className ? ' someClass' : 'someClass';
}

Add class to first child using javascript

is there any reason this chain does not work? It does not add the class:
document.getElementsByTagName('nav')[0].firstChild.className = "current"
It should return the first child of the nav element which is an <a> which does not happen.
Thanks for your help!
That's because you have text nodes between nav and a. You can filter them by nodeType:
var childNodes = document.getElementsByTagName('nav')[0].childNodes;
for (var i = 0; i < childNodes.length; i++) {
if (childNodes[i].nodeType !== 3) { // nodeType 3 is a text node
childNodes[i].className = "current"; // <a>
break;
}
}
It may seem strange but, for example, if you have the following markup:
<nav>
<a>afsa</a>
</nav>
Here's a DEMO.
Why does this happen? Because some browsers may interpret the space between <nav> and <a> as an extra text node. Thus, firstChild will no longer work since it'll return the text node instead.
If you had the following markup, it'd work:
<nav><a>afsa</a></nav>
You can simply document.querySelectorAll to select the list.
use "firstElementChild" to get first child node and add class.
const firstChild = document.querySelectorAll('nav').firstElementChild;
firstChild.classList.add('current');
The statement:
document.getElementsByTagName('nav')[0].firstChild.className = "current"
is somewhat fragile as any change in the assumed document structure breaks your code. So more robust do do something like:
var links,
navs = document.getElementsByTagName('nav');
if (navs) links = nav[0].getElementsByTagName('a');
if (links) links[0].className = links[0].className + ' ' + 'current';
You should also have robust addClassName and removeClassName functions.
Jquery can make this very easy:
$("#nav:first-child").addClass("current");

Can't get javascript/jquery to sort elements correctly more than one time

I have child divs that I'm trying to sort based on a jquery .data() value that I give them that is just a single number. This code works perfectly, but only once, after that I can't figure out how the heck it's sorting them. Here is a simplified version:
var myArray = $('#container div').get();
myArray.sort(function(x,y) {
return $(x).data('order') - $(y).data('order');
});
$('#container').empty().append(myArray);
I've tried so many other different methods of sorting, other plugins, etc., and I can't get anything to work right. This is as close as I can get. I just have this running on a jquery change event.
Here is the whole thing in case I'm doing something stupid elsewhere:
$('#attorneyFilter').change(function() {
//get array of links for sorting
var myArray = $('#attorneyBlocks div').get();
var selectedArea = $(this).val();
//sort alphabetically when "all" is selected
if (selectedArea == 'all') {
$('#attorneyBlocks div').show();
myArray.sort(function(a,b) {
return $(a).text() > $(b).text() ? 1 : -1;
});
//filter attorneys based on practice area and then assign its order# to the div with data, getting all values from the div's class
} else {
$('#attorneyBlocks div').hide().each(function() {
var attorneyArea = $(this).attr('class').split(', ');
for (var i=0;i<attorneyArea.length;i++) {
var practiceArea = attorneyArea[i].split('-');
if (selectedArea == practiceArea[0]) {
$(this).show().data('order',practiceArea[1]);
}
}
});
//sort based on order, the lower the number the higher it shows up
myArray.sort(function(x,y) {
return $(x).data('order') - $(y).data('order');
});
}
//append order back in
$('#attorneyBlocks').empty().append(myArray);
});
And a link to the page in question
Here's a jsFiddle with this working using .detach() instead of .empty() to keep the data.
http://jsfiddle.net/shaneblake/Tn9u8/
Thanks for the link to the site, that made it clear.
It seems to me you never clear out the data from the prior time. You hide everything but maybe something like this will solve your problem (here I set everything hidden to the bottom, you can clear it or use a different value -- as long as it is not the same as any sort key):
$('#attorneyBlocks div').hide().data('order',999999).each(function() {
var attorneyArea = $(this).attr('class').split(', ');
for (var i=0;i<attorneyArea.length;i++) {
var practiceArea = attorneyArea[i].split('-');
if (selectedArea == practiceArea[0]) {
$(this).show().data('order',practiceArea[1]);
}
}
});
Also, the code on the server is missing the 2nd line you have above:
var myArray = $('#attorneyBlocks div').get();
The problem is the change event is tied to the original items. After the sort you make all new items. They don't have any event tied to them. You will need to use .live()
Eventually figured it out, the data values from hidden divs were screwing with my sorting, so I changed my sorting code to only pay attention to :visible divs and that did the trick. Doh! Thanks for your help everyone.

Categories