Currently my code iterates through each <li> within a <td> cell and applies a class to the <li>. I've now added <a> tags in between each <li> and am having problems accessing the <a>. I essentially want to add a class to each <a> tag rather than the <li>.
HTML
<td style='padding: 0;' bgcolor='#FAFAFA'>
<ul class='doctorList'>
<li id='1'><a style='text-decoration: none;'>Curly</a></li>
<li id='2'>Larry</li>
<li id='3'>Moe</li>
</ul>
</td>
JavaScript
function mapBookedAppointmentsToCalendar()
{
var bookedAppointmentsArray = <?php echo json_encode($mappingIdArray) ?>;
var table = document.getElementById("tbl_calendar");
for (var i = 0, row; row = table.rows[i]; i++) {
for (var j = 0, col; col = row.cells[j]; j++) {
var li = col.querySelectorAll("li");
for (var k = 0; k < li.length; k++) {
for (var a = 0; a < bookedAppointmentsArray.length; a++)
{
if (li[k].id == bookedAppointmentsArray[a])
{
li[k].className = "colorRed booked";
break;
} else
{
li[k].className = "colorGreen";
}
}
}
}
}
}
Did you try using the query selector to find those <a> ?
var li = col.querySelectorAll("#tbl_calendar li a");
for (var k = 0; k < li.length; k++) {
for (var a = 0; a < bookedAppointmentsArray.length; a++)
{
if (li[k].id == bookedAppointmentsArray[a])
{
li[k].className = "colorRed booked";
break;
} else
{
li[k].className = "colorGreen";
}
}
}
You don't need to use table to access it. Just keep in mind getElementsByClassName method:
u = document.getElementsByClassName('doctorList');
for (i = 0; i < u.length; i++){
l = u[i].getElementsByTagName('li');
for (j = 0; j < l.length; j++){
l[j].className = 'red';
}
}
Checkout this demo
If you don't need ancient browsers support, you can do this:
var ul = document.querySelector('ul.doctorList');
var li = ul.querySelectorAll('li');
// convert the node list to an array
li = [].slice.call(li);
li.forEach(function(element) {
if (element.id === '1') {
var a = element.querySelector('a');
a.className = 'red';
}
});
var ul = document.querySelector('ul.doctorList');
var li = ul.querySelectorAll('li');
// convert the node list to an array
li = [].slice.call(li);
li.forEach(function(element) {
if (element.id === '1') {
var a = element.querySelector('a');
a.className = 'red';
}
});
.red {
color: red;
}
<td style='padding: 0;' bgcolor='#FAFAFA'>
<ul class='doctorList'>
<li id='1'><a style='text-decoration: none;'>Curly</a></li>
<li id='2'>Larry</li>
<li id='3'><a style='text-decoration: none;'>Moe</a></li>
</ul>
</td>
Related
I tried to translate my web page using js but my code is not working here my code
<div class="navLan">
EN
<!-- <hr> -->
RU
<!-- <hr> -->
UZ
</div>
where user select languages and i used key to give attr to the element like this
<div class="listGroup">
<a href="#row3" class="hvr-grow nav-link lang" key='about'>About</a>
Courses
<a href="#row5" class="nav-link lang" key='reg'>Registration</a>
<a href="#row6" class="nav-link lang" key='news'>News</a>
<a href="#row7" class="nav-link lang" key='feedback'>Feedback</a>
<a href="#row8" class="nav-link lang" key='contact'>Contacts</a>
<div class="hr"></div>
</div>
at the end of the code in script tag i gave translation like this
var arrLang = {
'menu-item_en': {
'about':'About',
'courses':'Courses',
'reg':'Registration',
'news':'News',
'feedback':'Feedback',
'contact':'Contacts'
},
'menu-item_ru': {
'about':'About',
'courses':'Courses',
'reg':'Registration',
'news':'News',
'feedback':'Feedback',
'contact':'Contacts'
},
'menu-item_uz': {
'about':'Biz Haqimizda',
'courses':'Kurslar',
'reg':'Ro\'yxatdan o\'tmoq',
'news':'Yangiliklar',
'feedback':'Fikr-Mulohaza',
'contact':'Aloqa'
}
}
finally my js file here
function change_language(id) {
var lang = id;
document.cookie = "lang=" + lang + ";";
var elementss = document.getElementsByClassName('lang');
var placeholders = document.getElementsByClassName('placeholders');
if (document.cookie.split(';').filter(function (item) {
return item.indexOf('lang=menu-item_en') >= 0
}).length) {
for (let i = 0; i < elementss.length; i++) {
elementss[i].innerHTML = arrLang['menu-item_en'][elementss[i].getAttribute('key')];
}
for (let g = 0; g < placeholders.length; g++){
placeholders[g].setAttribute('placeholder', arrLang['menu-item_en'][placeholders[g].getAttribute('key')]);
}
} else if (document.cookie.split(';').filter(function (item) {
return item.indexOf('lang=menu-item_uz') >= 0
}).length) {
for (let i = 0; i < elementss.length; i++) {
elementss[i].innerHTML = arrLang['menu-item_uz'][elementss[i].getAttribute('key')];
}
for (let g = 0; g < placeholders.length; g++){
placeholders[g].setAttribute('placeholder', arrLang['menu-item_uz'][placeholders[g].getAttribute('key')]);
}
} else {
for (let i = 0; i < elementss.length; i++) {
elementss[i].innerHTML = arrLang['menu-item_ru'][elementss[i].getAttribute('key')];
}
for (let g = 0; g < placeholders.length; g++){
placeholders[g].setAttribute('placeholder', arrLang['menu-item_ru'][placeholders[g].getAttribute('key')]);
}
}
};
(function () {
var elementss = document.getElementsByClassName('lang');
var placeholders = document.getElementsByClassName('placeholders');
var inputs = document.getElementsByClassName('inputs');
if (document.cookie.split(';').filter(function (item) {
return item.indexOf('lang=menu-item_en') >= 0
}).length) {
for (let i = 0; i < elementss.length; i++) {
elementss[i].innerHTML = arrLang['menu-item_en'][elementss[i].getAttribute('key')];
}
for (let g = 0; g < placeholders.length; g++){
placeholders[g].setAttribute('placeholder', arrLang['menu-item_en'][placeholders[g].getAttribute('key')]);
}
for (let j = 0; j < inputs.length; j++){
inputs[j].setAttribute('value', arrLang['menu-item_en'][inputs[j].getAttribute('key')]);
}
} else if (document.cookie.split(';').filter(function (item) {
return item.indexOf('lang=menu-item_uz') >= 0
}).length) {
for (let i = 0; i < elementss.length; i++) {
elementss[i].innerHTML = arrLang['menu-item_uz'][elementss[i].getAttribute('key')];
}
for (let g = 0; g < placeholders.length; g++){
placeholders[g].setAttribute('placeholder', arrLang['menu-item_uz'][placeholders[g].getAttribute('key')]);
}
for (let j = 0; j < inputs.length; j++){
inputs[j].setAttribute('value', arrLang['menu-item_uz'][inputs[j].getAttribute('key')]);
}
} else {
for (let i = 0; i < elementss.length; i++) {
elementss[i].innerHTML = arrLang['menu-item_ru'][elementss[i].getAttribute('key')];
}
for (let g = 0; g < placeholders.length; g++){
placeholders[g].setAttribute('placeholder', arrLang['menu-item_ru'][placeholders[g].getAttribute('key')]);
}
for (let j = 0; j < inputs.length; j++){
inputs[j].setAttribute('value', arrLang['menu-item_ru'][inputs[j].getAttribute('key')]);
}
}
})();
anyone can correct me please?
Most likely when HTML is rendering you probably don't have change_language function, so onclick="change_language(this.id)" binds anything to onclick. Let's try to add addEventListener using javascript.
Here is a working example: https://jsfiddle.net/jugrae2z/
How can I sort an unordered list alphabetically while retaining outer html? My current setup sorts the list alphabetically, however it only rearranges the inner html of the list elements rather than the entire element, which is a problem because within the tag i have event based script calls that are specific to each element. The list elements themselves are added by script from an xml document.
Here's the html:
var xhttp;
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
onLoad(this);
}
};
xhttp.open("GET", "stocks.xml", true);
xhttp.send();
function onLoad(xml) {
var x, i, txt, xmlDoc;
xmlDoc = xml.responseXML;
txt = "<ul id = stocksymbols>";
var StockList;
x = xmlDoc.getElementsByTagName("Stock");
for (i = 0; i < x.length; i++) {
symbol = x[i].getAttribute('symbol');
txt += "<li onmouseover=\"mouseOver('" + symbol + "')\" onmouseout=\"mouseOut()\">" + symbol + "</li>";
}
document.getElementById("stockList").innerHTML = txt + "</ul>";
sortList("stocksymbols");
}
function sortList(ul) {
if (typeof ul == "string")
ul = document.getElementById(ul);
var lis = ul.getElementsByTagName("LI");
var vals = [];
for (var i = 0, l = lis.length; i < l; i++)
vals.push(lis[i].innerHTML);
vals.sort();
for (var i = 0, l = lis.length; i < l; i++)
lis[i].innerHTML = vals[i];
}
function mouseOver(target) {
stockInfoDiv = document.getElementById("stockInfo");
stockInfoDiv.innerHTML = target;
}
function mouseOut() {
stockInfoDiv.innerHTML = "";
}
h2 {
color: Navy;
}
li {
font-family: monospace;
font-weight: bold;
color: Navy;
}
li:hover {
font-family: monospace;
font-weight: bold;
color: red;
}
<html>
<head>
<title></title>
</head>
<body>
<h2>List of Stocks:</h2>
<div id="stockList">
</div>
<br />
<br />
<br />
<div id="stockInfo">
</div>
</body>
</html>
Instead of lis[i].innerHTML = vals[i];, sort the lis list and do ul.appendChild(lis[i]). This will remove the current li from its position in the DOM and append it to the end of the ul. I'm assuming the only li elements are direct children of the ul.
function sortList(ul) {
var ul = document.getElementById(ul);
Array.from(ul.getElementsByTagName("LI"))
.sort((a, b) => a.textContent.localeCompare(b.textContent))
.forEach(li => ul.appendChild(li));
}
sortList("stocksymbols");
<ul id=stocksymbols>
<li>AAA</li>
<li>ZZZ</li>
<li>MMM</li>
<li>BBB</li>
</ul>
<ul id="mylist">
<li id="list-item3">text 3</li>
<li id="list-item4">text 4</li>
<li id="list-item2">text 2</li>
<li id="list-item1">text 1</li>
</ul>
<script>
var list = document.getElementById('mylist');
var items = list.childNodes;
var itemsArr = [];
for (var i in items) {
if (items[i].nodeType == 1) { // get rid of the whitespace text nodes
itemsArr.push(items[i]);
}
}
itemsArr.sort(function(a, b) {
return a.innerHTML == b.innerHTML
? 0
: (a.innerHTML > b.innerHTML ? 1 : -1);
});
for (i = 0; i < itemsArr.length; ++i) {
list.appendChild(itemsArr[i]);
}
</script>
So lets do it with the XML, build an array, sort the array, and than build the lis.
var symbols = xmlDoc.getElementsByTagName("Stock");
var items = [];
for (var i = 0; i < symbols.length; i++) {
items.push(symbols[i].getAttribute('symbol')); //build array of the symbols
}
var lis = items.sort() //sort the array
.map( function(txt) { //loop over array
return "<li>" + txt + "</li>"; //build the li
}).join(""); //join the indexes as one string
console.log(lis); //the lis in a string.
Hello i want to remove "Have you served in the military ?" and "No" if Answer is "No" but when it will "Yes" than it should show.
Whatever i have tried but it's not working
<script type="text/javascript">
(function(){
for(i = 0; (a = document.getElementsByTagName("td")[i]); i++){
if(document.getElementsByTagName("span")[i].innerHTML.indexOf('Have you served in the military') > -1){
document.getElementsByTagName("td")[i].style.display = "none";
}
}
})();
</script>
You could use child of the element or just do a find replace or even hide and show.
You can get all td elements like you already did and than get the span elements inside them:
var tds = document.getElementsByTagName('TD');
for (var i = 0, l = tds.length; i != l; ++i) {
var spans = tds[i].getElementsByTagName('SPAN');
for (var j = 0, l2 = spans.length; j != l2; ++j) {
var span = spans[j];
if ((span.textContent = span.innerText).indexOf('Have you served in the military') != -1) {
span.style.display = 'none';
break;
}
}
}
EDIT: OP wants to only delete the span if there is a td with the content "No" (also delete the td element)
var tds = document.getElementsByTagName('TD');
var tdsLength = tds.length;
var answerNoFound = false;
for (var i = 0; i != tdsLength; ++i) {
var td = tds[i];
if ((td.textContent = td.innerText) == 'No') {
td.style.display = 'none';
answerNoFound = true;
break;
}
}
if (answerNoFound)
for (var i = 0; i != tdsLength; ++i) {
var spanFound = false;
var spans = tds[i].getElementsByTagName('SPAN');
for (var j = 0, l = spans.length; j != l; ++j) {
var span = spans[j];
if ((span.textContent = span.innerText).indexOf('Have you served in the military') != -1) {
span.style.display = 'none';
spanFound = true;
break;
}
}
if (spanFound)
break;
}
It looks like you have an application form and document probably has more spans, some outside the td elements, so you don't get correct selection of spans versus td.
So when you are comparing span content, it is most likely not the span that is inside your looped td.
<script type="text/javascript">
(function(){
for(i = 0; (a = document.getElementsByTagName("td")[i]); i++){
if(a.getElementsByTagName("span")[0].innerHTML.indexOf('Have you served in the military') > -1){
a.style.display = "none";
}
}
})();
</script>
I changed the if statement to select span inside your looped td, that should do it.
So, i have this javascript code:
function check(x) {
elements = document.getElementsByClassName(x);
for (var i = 0; i < elements.length; i++) {
elements[i].style.backgroundColor = "yellow";
}
}
With this code, i can change the backgroundColor of anything with any class in my html page.
I have many "a" tags with differents class, for example:
<a class="1" onclick="check(this.className)">text 1</a>
<a class="2" onclick="check(this.className)">text 2</a>
<a class="3" onclick="check(this.className)">text 3</a>
<a class="4" onclick="check(this.className)">text 4</a>
And when I click on then I can change background color.
My problem is when I try to save this change in localStorage. I´m wanting to save the background color change to, on load page, check if users have clicked to change background color or not, for example:
function check(x) {
elements = document.getElementsByClassName(x);
for (var i = 0; i < elements.length; i++) {
elements[i].style.backgroundColor = "yellow";
}
if (localStorage[x] != "yellow") {
elements[i].style.color = "yellow";
localStorage[x] = "yellow";
} else {
elements[i].style.color = "";
localStorage[x] = "";
}
}
window.onload = function() {
if (localStorage[x]) {
elements[i].style.backgroundColor = localStorage[x];
}
}
This is the way i found to highlight text user think is interting and he wants to mark, but this is not working.
Can someone helps me with this?
You can do something like
function check(x) {
var elements = document.getElementsByClassName(x);
for (var i = 0; i < elements.length; i++) {
elements[i].style.backgroundColor = "yellow";
}
var colors = localStorage.getItem('colors');
colors = colors ? colors.split(',') : [];
if (colors.indexOf(x) == -1) {
colors.push(x);
localStorage.setItem('colors', colors.join(','));
}
console.log(colors, localStorage.getItem('colors'))
}
window.onload = function () {
var colors = localStorage.getItem('colors');
if (colors) {
colors = colors.split(',');
for (var i = 0; i < colors.length; i++) {
check(colors[i])
}
}
}
Demo: Fiddle
Put everything in a for loop:
function check(x) {
elements = document.getElementsByClassName(x);
for (var i = 0; i < elements.length; i++) {
elements[i].style.backgroundColor = "yellow";
if (localStorage[x] != "yellow") {
elements[i].style.color = "yellow";
localStorage[x] = "yellow";
} else {
elements[i].style.color = "";
localStorage[x] = "";
}
}
}
window.onload = function() {
var elements = document.getElementsByClassName("a");
for (var i = 0; i < elements.length; i++) {
if (localStorage[x]) {
elements[i].style.backgroundColor = localStorage[x];
}
}
}
Note that i have document.getElementsByClassName("a") in the second loop, replace "a" with whatever class that all your tags share.
I have a TODO list app with an Unordered list. Within it I have a few list items. The li classes are high,medium,low. I would like li's with the class high to be placed before li's with the class medium and last ones with low.
<ul id="tasks">
<li id="item3" class="priority low"><span></span><span>This is a low priority task</span></li>
<li id="item4" class="priority high"><></span><span>This is a high priority task</span></li>
<li id="item5" class="priority low"><span></span><span>This is another Low</span></li>
<li id="item7" class="priority medium"><span></span><span>And now a Medium</span></li>
</ul>
So the li with id of item4 should be first and then it should be item7 and then the li's with class low after.
Here's a pure JS version of #ŠimeVidas jQuery solution.
var tasks = document.querySelector('#tasks'),
items = document.querySelectorAll('#tasks > li');
for (var i = 0, arr = ['high', 'medium', 'low']; i < arr.length; i++) {
for (var j = 0; j < items.length; j++) {
if (~(" " + items[j].className + " ").indexOf(" " + arr[i] + " "))
tasks.appendChild(items[j]);
}
}
Assuming you can use jQuery, and assuming your list is not very big, and assuming you've only got these three fixed types with no plans on changing this, I'd probably just dump the whole set into memory, clear out the list, then put them back in the list in order. Something like:
jQuery(document).ready(function() {
var i;
var items = jQuery("#tasks li");
var lowItems = [];
var medItems = [];
var highItems = [];
for (i = 0; i < items.length; ++i) {
var jqItem = jQuery(items[i]);
if (jqItem.hasClass("low")) lowItems.push(jqItem);
if (jqItem.hasClass("medium")) medItems.push(jqItem);
if (jqItem.hasClass("high")) highItems.push(jqItem);
}
var tasks = jQuery("#tasks");
tasks.html("");
for (i = 0; i < highItems.length; ++i) {
tasks.append(highItems[i]);
}
for (i = 0; i < medItems.length; ++i) {
tasks.append(medItems[i]);
}
for (i = 0; i < lowItems.length; ++i) {
tasks.append(lowItems[i]);
}
});
Try this:
$(function(){
var sorter = [],
tasks = $('#tasks');
$('li.priority').each(function(){
var $this = $(this),
priority = $this.hasClass('high') ? 3 : ($this.hasClass('medium') ? 2 : 1);
sorter.push({
el : this,
priority : priority
});
}).detach();
sorter.sort(function(a, b){
return a.priority - b.priority;
});
$.each(sorter, function(){
tasks.append(this.el);
});
});
With no jquery:
<ul id="tasks">
<li id="item3" class="priority low"><span></span><span>This is a low priority task</span></li>
<li id="item4" class="priority high"><></span><span>This is a high priority task</span></li>
<li id="item5" class="priority low"><span></span><span>This is another Low</span></li>
<li id="item7" class="priority medium"><span></span><span>And now a Medium</span></li>
</ul>
<script type="text/javascript">
var tasks = document.getElementById("tasks");
var liElements = tasks.getElementsByTagName("li");
var lowPriority = [];
var mediumPriority = [];
var highPriority = [];
var removal = [];
for (var i = 0, len = liElements.length; i < len; i++) {
if (liElements[i].getAttribute("class").indexOf("low") > -1) lowPriority.push(liElements[i].cloneNode(true));
if (liElements[i].getAttribute("class").indexOf("medium") > -1) mediumPriority.push(liElements[i].cloneNode(true));
if (liElements[i].getAttribute("class").indexOf("high") > -1) highPriority.push(liElements[i].cloneNode(true));
removal.push(liElements[i]);
}
for (var i = 0, len = removal.length; i < len; i++ ) {
var liItem = removal[i];
liItem.parentNode.removeChild(liItem);
}
for( var i = 0, len = lowPriority.length; i < len; i++){
tasks.appendChild(lowPriority[i]);
}
for (var i = 0, len = mediumPriority.length; i < len; i++) {
tasks.appendChild(mediumPriority[i]);
}
for (var i = 0, len = highPriority.length; i < len; i++) {
tasks.appendChild(highPriority[i]);
}
</script>
Here's another jQuery–less option:
// Just a helper
function toArray(obj) {
var result = [];
for (var i=0, iLen=obj.length; i<iLen; i++) {
result[i] = obj[i];
}
return result;
}
// Uses querySelectorAll, but could use getElementsByTagName instead
function sortByPriority(id) {
var nodes;
var el = document.getElementById(id);
if (el) {
nodes = toArray(el.querySelectorAll('li.priority'));
nodes.sort(function(a, b) {
function getIndex(el) {
return el.className.indexOf('low') != -1? 1 :
el.className.indexOf('medium') != -1? 2 :
el.className.indexOf('high') != -1? 3 :
0; // default
}
return getIndex(b) - getIndex(a);
});
for (var i=0, iLen=nodes.length; i<iLen; i++) {
el.appendChild(nodes[i]);
}
}
}
It uses a few more lines that a jQuery (or perhaps any library) based solution but you don't have to load several thousand lines of library either.
Also, this runs about 5 times faster in Firefox and IE 9 and 10 times faster in Chrome than a jQuery solution (see http://jsperf.com/sortelementlist).
With pure JavaScript, and simple code!
var tasks = document.getElementById("tasks");
var lis = tasks.getElementsByTagName("li");
var lisarr = Array.prototype.slice.call(lis);
var priority = function(e){
var prio = {low: 0, medium: 1, high: 2};
return prio[e.getAttribute("class").match(/low|high|medium/)[0]];
};
lisarr.sort(function(a,b){
var ap = priority(a), bp = priority(b);
return bp - ap;
});
tasks.innerHTML = lisarr.reduce(function(prev, current){
return prev + current.outerHTML;
}, '');