Javascript string.slice() with negative values - javascript

I am trying to hide or show divs based on the title of the page. This is only required because I can't figure out a better way of passing a value into the page.
Here's the current code in the HTML file:
function toggle(divId) {
var divArray = document.getElementsByTagName("div");
for(i = 0; i < divArray.length; i++){
if(divArray[i].id == divId){
if(divArray[i].style.display != 'none'){
divArray[i].style.display = 'none';
}else{
divArray[i].style.display = '';
}
}
}
}
function togglePayLink() {
var h1Array = document.getElementsByTagName("h1");
for(i = 0; i < h1Array.length; i++){
if(h1Array[i].id == 'Title'){
var title = h1Array[i].innerHTML;
title = title.slice(1);
title = title.slice(-4);
toggle('descr'+ title);
}
}
}
Also in the HTML file is a header with the page title. The %%GLOBAL_PageTitle%% is replaced in server side code that I don't have access to. However, the values will be "$100 Fee" (with different numbers).
<h1 id="Title" class="TitleHeading">%%GLOBAL_PageTitle%%</h1>
Finally, I have a set of hidden divs with id's in the format descr + a number, so if the page title is "$100 Fee" I want to show the div with the id "descr100".
<div id="descr100" style="display:none;width: 75%;"></div>
When the script above runs, I get no error (I'm using chrome's console), but the div does not show. I know the toggle function works because it was previously being used with only a single div on the page that had to be toggled. I wrote the togglePayLink function, which I assume is the issue, but I have no idea how to debug this. I was wondering if the dollar sign in the title could be causing issues, but I would think I would get an error if that were the case.
EDIT: Changed the togglePayLink function to use var instead of string, but I'm getting a typeError when slice() is called.

Going forward, you should probably just assign a unique class to the page using %%GLOBAL_PageTitle%%. This way you can show/hide elements using CSS.
<div class="page %%GLOBAL_PageTitle%%">
For pages that BigCommerce doesn't give access to the HTML of the h1 for each individual page (ex. Web Pages, Account, Cart), I usually run this script on page load to strip the page title of spaces and other characters, and assign a specific class to the page element.
var catName = $('.TitleHeading').text();
var catName = catName.replace(/ /g, '');
var catName = catName.replace(/'/g, '');
var catName = catName.replace(/&/g, '');
var catName = $.trim(catName);
$('.page').addClass(''+catName+'');
The way your doing it seems a bit over the top, but if it was setup this way by someone else, I understand.

The problem is here:
String title = h1Array[i].innerHTML;
In Javascript, all variables are set with var (except for functions, which can be set other ways). So it would be:
var title = h1Array[i].innerHTML;
Additionally, you probably have to define it outside the for loop, in which case you would omit the "var" when you are setting it in the for loop:
<script language="javascript">
var title;
function togglePayLink() {
var h1Array = document.getElementsByTagName("h1");
for(i = 0; i < h1Array.length; i++){
if(h1Array[i].id == 'Title'){
title = h1Array[i].innerHTML;
title = title.slice(1);
title = title.slice(-4);
toggle('descr'+ title);
}
}
}
</script>
Edit: If you only use it in the for loop, but use it in different iterations, then I'm not sure if it can be defined locally. I'd still define it globally, though.

title.slice(-4) was giving me the last four digits of the string instead of everything before the last four digits like I thought it would. toggling the non-existent 'descrFee' div was not doing anything.

Related

Remove class based on elements but not others

I have these sections on this side scrolling site. And want to add a class which will change styling depending if you're on a certain section.
I'm working on this function. The top is what determines the section of the side scroller you are viewing.
The let variables and below is where it stops working. I'm trying to have it so if a nonHome ID section is clicked, for example "slide-1", then add the class 'nav-visibilty'. If they are a match "slide-2" and "slide-2" then remove said class. Am I close?
https://codepen.io/mikayp-the-styleful/pen/NWPxoXR?editors=1111
setTimeout(function(){
for (i=0; i < nonHome.length; i++ ){
if (nonHome[i].id != nonHomeID){
nonHome[i].classList.add("nav-visibility");
console.log('add')
} else{
nonHomeID.classList.remove("nav-visibility");
console.log('rem')
}
}
I am still not totally clear on the behavior that you want, but there are two errors in the code that can be fixed:
It seems like you are always using 'slide-2' instead of the slideId in your event handler.
As mentioned in a comment, nonHomeID is being used incorrectly in your comparison (it is either a string or an element, but you are using it as if it was a string in the if condition, and as the element in the else branch.) Here I have kept it as an element and renamed it for clarity.
Fixing these errors results in code that applies the nav-visibility class to all slides except the one selected by the button. Is that the desired behavior?
let nonHome = document.querySelectorAll(".slide-container section");
let nonHomeSelected = document.getElementById(slideId);
var i;
setTimeout(function() {
for (i = 0; i < nonHome.length; i++) {
if (nonHome[i] != nonHomeSelected) {
nonHome[i].classList.add("nav-visibility");
console.log("add");
} else {
nonHome[i].classList.remove("nav-visibility");
console.log("rem");
}
}
}, 1000);
Edit to add: If the goal is to add nav-visibility to all only the specific slideId, you should not be adding in a loop, i.e. you need to pull your check for whether the slide is Home outside the loop. There are conceptually two steps here: remove the class from all elements that are no longer to have it, then add the class to the element that needs it.
let slideToAddVisibilityTo = document.getElementById(slideId)
let homeSlide = document.getElementById('slide-2')
let allSlides = document.querySelectorAll(".slide-container section")
for (let i = 0; i < allSlides.length; ++i)
allSlides[i].classList.remove('nav-visiblity')
if (slideToAddVisibilityTo != homeSlide)
slideToAddVisibilityTo.classList.add('nav-visibility')
Just hide them all, then show the clicked one:
function showSection(id) {
var sections = document.getElementsByTagName("section");
for(var i=0; i<sections.length; i++) sections[i].classList.remove("nav-visibility");
var current = document.getElementById(id);
current.classList.add("nav-visibility");
}
Example: showSection("foo") will remove nav-visibility from all sections, then add it to the section with id foo.

Formatting a href link with appendChild, setAttribute, etc

I am attempting to populate a list with href links via javascript.
Here is an example of the html I would like to create:
<li> Complete blood count</li>
Where "#modal-one" displays a pop up.
I have used the following and several other iterations to try and create this dynamically:
<script>
var listItem = [];
function createTestList() {
var tests = results.tests; //an array to tests to populate list
var i;
var j;
for (i = 0; i < tests.length ; i++ ){
listItem[i] = document.createElement("li");
var node = document.createTextNode(tests[i].name);
listItem[i].appendChild(node);
listItem[i].setAttribute("href", "#modal-one");
addOnClick(i);
//var element = document.getElementById("div1");
//element.appendChild(listItem[i]);
document.body.appendChild(listItem[i]);
console.log(listItem[i]);
};
};
function addOnClick(j) { //this is separate to handle the closure issue
listItem[j].onclick = function() {loadModal(j)};
};
</script>
However, this code (and several others) produce:
<li href='#modal-one'>Complete Blood Count</li> //note missing <a>...</a>
It appears there are several ways to achieve this, but nothing seems to work for me...
You are never actually adding in an anchor tag. You are creating a list-item (li), but you are adding an href to that list-item rather than adding an anchor node to it with that href. As such, the browser just thinks you have a list-item with an href attribute.
Consider using the following instead:
<script>
var listItem = [];
function createTestList() {
var tests = results.tests; //an array to tests to populate list
var i;
var j; // Never actually used in function. Consider omitting
for (i = 0; i < tests.length ; i++ ){
// create the list item
listItem[i] = document.createElement("li");
// Create the anchor with text
var anchor = document.createElement("a");
var node = document.createTextNode(tests[i].name);
anchor.appendChild(node);
anchor.setAttribute("href", "#modal-one");
// Set the onclick action
addOnClick(i, anchor);
// Add the anchor to the page
listItem[i].appendChild(anchor);
document.body.appendChild(listItem[i]);
console.log(listItem[i]);
};
};
// Modified "addOnClick" to include the anchor that needs the onclick
function addOnClick(j, anch) { //this is separate to handle the closure issue
anch.onclick = function() {loadModal(j)};
};
</script>
A couple things to note:
I have modified your addOnClick() function because it is the anchor element that needs the onclick, not the list item.
I have added in the creation of an anchor element rather than simply creating a list item and adding the href to that.
I do not see creating a element, change code to:
var aNode=document.createElement("a");
aNode.innerText=tests[i].name;
aNode.setAttribute("href", "#modal-one");
listItem[i].appendChild(aNode);
You can change also click method, to use it on a not on li
function addOnClick(j) {
listItem[j].querySelector("a").addEventListener("click",function(e) {
e.preventDefault();//this prevent for going to hash in href
loadModal(j);
});
};
Okay. I missed the anchor tag. My bad...
Spencer's answer came close, but I had to make few changes to get it work in my instance.
The final working code (and honestly I am not sure why it works) is:
<script>
var listItem = [];
function createTestList() {
var tests = results.tests;
var i;
//var j;
for (i = 0; i < tests.length ; i++ ){
// create the list item
listItem[i] = document.createElement("li");
// Create the anchor with text
var anchor = document.createElement("a");
anchor.setAttribute("href", "#modal-one");
var node = document.createTextNode(tests[i].name);
anchor.appendChild(node);
// Set the onclick action
addOnClick(i);
// Add the anchor to the page
listItem[i].appendChild(anchor);
document.getElementById("demo").appendChild(listItem[i]); //added the list to a separate <div> rather than body. It works fine like this.
console.log(listItem[i]);
};
};
function addOnClick(j) { //this is separate to handle the closure issue
//didn't need the additional code beyond this
listItem[j].onclick = function() {loadModal(j)};
};
</script>
Thanks to all and Spencer thanks for the thoroughly commented code. It helps!!!

js How to add href + text onclick

I need to pass (using javascript) text inside span to href
<div class='tableCell'><span>information</span></div>
<div class='tableCell'><span>contact</span></div>
<div class='tableCell'><span>about</span></div>
for example when i click to about link must be example.com/tag/about/
Here is my Answer. I'm using Javascript to manipulate the DOM to add a new element with the href equal to the inner text within the span element.
I hope you find this answer helpful.
Thanks.
var spans = document.getElementsByTagName('span')
var baseUrl = 'http://example.com/tag/'
for(var i=0; i<spans.length; i++)
{
var curElement = spans[i];
var parent = curElement.parentElement;
var newAElement = document.createElement('a');
var path = baseUrl+curElement.innerHTML;
newAElement.setAttribute('href', path);
newAElement.appendChild(curElement);
parent.appendChild(newAElement)
}
DEMO
The simplest way:
$( "span" ).click(function() {
var link = 'http://yousite.com/tag/'+ $(this).text().replace(/ /, "-")+"/";
window.location.href= link.toLowerCase();
});
DEMO
http://codepen.io/tuga/pen/yNyYPM
$(".tableCell span").click(function() {
var link = $(this).text(), // will provide "about"
href = "http://example.com/tag/"+link; // append to source url
window.location.href=href; // navigate to the page
});
You can try the above code
You do not have links but span in your html. However, you can get build the href you want and assign it to an existing link:
$('div.tableCell').click(function(){
var href = 'example.com/tag/' + $(this).find('span').text();
})
Lets work with pure javascript, I know you want to use jQuery but I am really sure too many people can't do this without looking in to web with pure javascript. So here is a good way.
You can follow it from jsFiddle
var objectList = document.getElementsByClassName("tableCell");
for(var x = 0; x < objectList.length; x++){
objectList[x].addEventListener('click', function(){
top.location.href = "example.com/tag/" + this.childNodes[0].innerHTML;
});
}
Lets work on the code,
var objectList = document.getElementsByClassName("tableCell");
now we have all element with the class tableCell. This is better than $(".tableCell") in too many cases.
Now objectList[x].addEventListener('click', function(){}); using this method we added events to each object.
top.location.href = "example.com/tag/" + this.childNodes[0].innerHTML; with this line if somebody clicks to our element with class: We will change the link to his first child node's text.
I hope it is useful, try to work with pure js if you want to improve your self.
Your Method
If you always are going to have the url start with something you can do something like this. The way it is set up is...
prefix + THE SPANS TEXT + suffix
spaces in THE SPANS TEXT will be converted to -
var prefix = 'http://example.com/tag/',
suffix = '/';
$('span').click(function () {
window.location.href = prefix + $(this).text().replace(' ', '-').trim().toLowerCase() + suffix;
//An example is: "http://example.com/tag/about-us/"
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='tableCell'><span>Information</span></div>
<div class='tableCell'><span>Contact</span></div>
<div class='tableCell'><span>About</span></div>
You can adjust this easily so if you want it to end in .html instead of /, you can change the suffix. This method will also allow you to make the spans have capitalized words and spaces.
JSBIN

Dynamically add new element and change its content

I want to "copy" a certain elements and the change some of the text inside them with a regex.
So far so good: (/w working fiddle - http://jsfiddle.net/8ohzayyt/25/)
$(document).ready(function () {
var divs = $('div');
var patt = /^\d\./;
var match = null;
for (i = 0; i < divs.length; i++) {
match = ($(divs[i]).text().match(patt));
$(divs[i]).text($(divs[i]).text().replace(match[0], "5."));
}
});
HTML
<div>1. peppers</div>
<div>2. eggs</div>
<div>3. pizza</div>
This works exactly the way I want it, but I want to add some of the content dynamically, but when I try to change the content of the copied divs, nothing happens.
Please refer to this fiddle:
http://jsfiddle.net/8ohzayyt/24/
I have put some comments, to be more clear what I want to achieve.
I thing that your problem is that you're not passing an element to your changeLabel function, but just a string.
Look at this solution: http://jsfiddle.net/8ohzayyt/26/
Here is the line I changed to make your code work:
var newContent = $("<hr/><div id='destination'>" + $("#holder").html() + "</div>");
I just wrapped your HTML in $(). this creates an element from the string.
try:
var newContent = $("<hr/><div id='destination'>" + $("#holder").html() + "</div>");
EDIT:
Brief explanation What I've done.
In order to make $(el).find('div'); work changeLabel() needs an element. Instead of passing newContent as a string doing the above will make it pass as an element which will make $(el).find('div'); work.

Create link in an html table with javascript

I am using the following code to add columns dynamically to a html table:
var tblHeadObj = window.opener.document.getElementById("maintable").tHead;
var j=0;
while(j < fname.length)
{
if(tblHeadObj != null)
{
for(var h = 0; h < tblHeadObj.rows.length; h++)
{
var newTH = window.opener.document.createElement('th');
tblHeadObj.rows[h].appendChild(newTH);
//newTH.innerHTML='[th]row:'+h+'cell:'+(tblHeadObj.rows[h].cells.length-1)
}
}
var tblBodyObj = window.opener.document.getElementById("maintable").tBodies[0];
//for(var i = 0; i < tblBodyObj.rows.length; i++) {
var newCell=tblBodyObj.rows[0].insertCell(-1);
var newCell=tblBodyObj.rows[0].insertCell(-1);
// newCell.innerHTML = (tblBodyObj.rows[0].cells.length - 1)
newCell.innerHTML= fname[j];
j++;
}
Now i want to make columns as link.How can i do that?
Thanks
As others have noted, it is quite unclear what you mean by "make columns as link". However, we as a community have become accustomed to making guesses about the real problem and providing a solution based on that assumption. As we gain experience tackling more and more unclear questions, our ESP skill become more honed.
It appears that you are creating an HTML table via DOM methods. I will assume that you want to create a link within the created tablecell and here is my suggestion:
Use the same createElement method to create any elements you need. For instance, a link (anchor) can be created with the following code:
var link = document.createElement("a");
link.setAttribute("href", "http://www.microsoft.com")
link.className = "someCSSclass";
// For IE only, you can simply set the innerText of the node.
// The below code, however, should work on all browsers.
var linkText = document.createTextNode("Click me");
link.appendChild(linkText);
// Add the link to the previously created TableCell.
newCell.appendChild(link);
Alternatively, you can also set the innerHTML of the TableCell as #Anonymous has suggested.
If you're trying to put the cell contents into an anchor, then one way is to change
newCell.innerHTML= fname[j];
to
newCell.innerHTML= ''+fname[j]+'';
where whatever is a variable holding an appropriate string.
Beware that the contents of fname[j] are all inline (eg, not tables or blocks like div, headings, forms -- but form inputs are okay) or the anchor will be closed by most browsers prematurely. If need be, you could put the anchor only around parts of the cell's contents, but the easiest way to do that would depend on what the contents are.
This are all good but I needed an image in the link so here is that code:
cell[k] = document.createElement('td');
var link = document.createElement('a');
link.setAttribute('href', "http://www.ilovethismusic.com");
link.setAttribute('target', "_blank");
var newimg = document.createElement('img');
newimg.src = "http://www.ilovethismusic.com/Views/Images/bg_header.jpg";
newimg.alt = "imageMissing";
newimg.width = "95";
newimg.height = "45";
newimg.border = "0";
link.appendChild(newimg);
cell[k].appendChild(link);

Categories

Resources