How to add hyperlink in array (Javascript) - javascript

I have a random quote generator script, and I need to add hyperlinks for each quote. The issue - I can't figure out how to accomplish this for the life of me.
I'm a novice in javascript but after searching around, thinking there's an easy solution to my problem, I can't find a workable answer to this.
How do I go about adding a hyperlink in an array? I'd appreciate this. It's probably so simple too.
Here's the page to the random quote generator, and I posted the code below. Thank you. https://www.hscripts.com/scripts/JavaScript/random-quote-generator.php
I posted the code below as well.
<style>
.row {
padding-left: 10px;
background-color: white;
font-family: verdana, san-serif;
font-size: 13px;
}
</style>
<!-- Script by hscripts.com -->
<script type="text/javascript">
var arr = new Array();
arr.push("Javascript is different from Java");
arr.push("Javascript is different from Java");
arr.push("Javascript is different from Java");
arr.push("CSS - Cascading Style Sheet");
arr.push("HTML is a platform independent language");
function rotate() {
var num = Math.round(Math.random() * 3);
add(num);
}
function add(i) {
var chi = document.createTextNode(arr[i]);
var tab1 = document.getElementById("add1");
while (tab1.hasChildNodes()) {
tab1.removeChild(tab1.firstChild);
}
tab1.appendChild(chi);
}
</script>
<!-- Script by hscripts.com -->
<table align=center style="background-color:#C0C0C0">
<tr>
<td background-color:#c0c0c0 align=center width=300 style="font-family:Times New Roman;">
<b>Random Quote Generator</b>
</td>
</tr>
<tr>
<td id=add1 class=row width=300 align=center>Click Next to Display Random message</td>
</tr>
<tr>
<td align=center>
<input type=button value="Next" border=0 onclick="rotate()">
</td>
</tr>
</table>

You can keep html code in your array e.g.
arr.push('CSS');
But I don't prefer mix html code with js.
Look at my solution on JSFiddle https://jsfiddle.net/xoL2bbtd/
I little modified your array and add function
function add(i) {
var chi = document.createElement('a');
chi.textContent = arr[i].text;
chi.setAttribute('href', arr[i].link);
var tab1 = document.getElementById("add1");
if (tab1.hasChildNodes()) {
tab1.removeChild(tab1.firstChild);
}
tab1.appendChild(chi);
}
I create anchor element and set href attribute. In array I keep object which contains text and link property
And one more thing. Create array by using new Array is slower than using []. Check this https://jsperf.com/new-array-vs-literal/15

Related

Displaying HTML Element Count

I'm doing Free Code Camp projects with User Stories requiring a minimum number of different elements.
I came up with the idea of using some of the page to display an element count and thought it would be simple to implement. Famous last words I know.
Spent a few hours reviewing MDN , W3, W3Schools, ... examples and documentation. Also searched here.
I've tried using botj javascript and jQuery and can get results in javascript but they are incorrect. The jQuery stuff doesn't work at all.
<head>
<script src=
"https://code.jquery.com/jquery-2.2.4.min.js">
</script>
<script src=
"https://code.jquery.com/jquery-3.5.0.js">
</script>
</head>
<body>
<!-- much deletia -->
<div class="ToC">
<div>
<table>
<tr>
<th colspan="2">HTML Element Use</th>
</tr>
<tr>
<td>Name</td><td>Count</td>
</tr>
<tr>
<td>Total</td><td><script>document.write(HTMLCollection.length)</script></td>
</tr>
<tr>
<td>p</td><td><script>document.write(document.getElementsByTagName('p').length);</script></td>
</tr>
<tr>
<td>div</td><td><script>document.write($( div ).length;)</script></td>
</tr>
</table>
</div>
</div>
<!-- even more deletia -->
</body>
What am I doing wrong?
var divCnt = document.getElementsByTagName('div').length
var pCnt = document.getElementsByTagName('p').length
var tCnt = document.getElementsByTagName('*').length
document.getElementById('total').innerHTML = tCnt;
document.getElementById('div').textContent = divCnt;
document.getElementById('p').innerHTML = pCnt;
<head>
<script src=
"https://code.jquery.com/jquery-2.2.4.min.js">
</script>
<script src=
"https://code.jquery.com/jquery-3.5.0.js">
</script>
</head>
<body>
<!-- much deletia -->
<div class="ToC">
<div>
<table>
<tr>
<th colspan="2">HTML Element Use</th>
</tr>
<tr>
<td>Name</td><td>Count</td>
</tr>
<tr>
<td>Total</td><td id='total'></td>
</tr>
<tr>
<td>p</td><td id='p'></td>
</tr>
<tr>
<td>div</td><td id='div'></td>
</tr>
</table>
</div>
</div>
<!-- even more deletia -->
</body>
This gets all of the elements from a simple document.querySelectorAll('*') which matches everything. Calling that returns a NodeList, so you want to turn that into an array using Array.from(...).
The next line uses the Array reduce method to turn that array of many elements into a single map.
It does that by using the node tagName as the key into the map, and assigning the node to that key. Actually it has to create an array on the map element first, so it can push all of the similar nodes onto that array.
That is done by using the element type name, such as DIV, as the key into the map. If that's the first time a node type has been seen it creates the array and then, in all cases, pushes the Element into the array.
let allelements = Array.from(document.querySelectorAll('*'));
let result = allelements.reduce(function(map, obj) {
if (map[obj.tagName] == null) {
map[obj.tagName] = [];
}
map[obj.tagName].push(obj);
return map;
}, {});
console.log(result);
<div id="div-one">
<p>one</p>
<p>two</p>
</div>
<div id="div-two">
<p>three</p>
<p>four</p>
<p>five</p>
</div>
You can then iterate the map keys to find how many of each element type there is.
If all you care about is the total element count you can skip reducing the array and just use allelements.length which tells you how many total nodes were selected.
Notice this gets ALL elements! You can limit it to just the <body> elements by first selecting the body and then using querySelectorAll on that.
In this example I've also added summarizing the number of each element type to the console.
let body = document.querySelector('body');
let allelements = Array.from(body.querySelectorAll('*'));
let result = allelements.reduce(function(map, obj) {
if (map[obj.tagName] == null) {
map[obj.tagName] = [];
}
map[obj.tagName].push(obj);
return map;
}, {});
console.log('Resulting map =', result);
console.log('Counts:');
for (tag of Object.keys(result)) {
console.log(tag.toLowerCase(), result[tag].length);
}
<div id="div-one">
<p>one</p>
<p>two</p>
</div>
<div id="div-two">
<p>three</p>
<p>four</p>
<p>five</p>
</div>

How can I change table navbar with CSS in an extension?

I am currently developing a Chrome extension for my university and I have done most of the things I want to do but I am having difficulty with one thing is that whenever I try to select the first <table> tag which is the navbar in this link I can't seem to hide it and then add my custom navbar using CSS.
Here is my code (I have included random createtextnode that I want to add to give a sense for what I want do or I am trying to do):
CSS
table:nth-child(1)
{
display:none;
}
JavaScript
var note = document.getElementsByName('stud_login')[0];
var par = document.createElement("div");
var tag = document.createElement("a");
var t1 = document.createTextNode(" Hello! Please try to refresh page again if the verification is not filled properly.");
var t2 = document.createTextNode("Click here");
var t3 = document.createTextNode(" Any suggestions? ");
var br = document.createElement("br");
par.setAttribute("class", "info-msg");
par.appendChild(t1);
tag.setAttribute("href", "http://goo.gl/forms/QI8gPMfKML");
tag.setAttribute("target", "_blank");
tag.setAttribute("id", "rahultag");
par.appendChild(t3);
tag.appendChild(t2);
par.appendChild(tag);
note.parentElement.appendChild(par);
Here is the HTML code i want to target and is the first table that occurs:
<table width="100%" height="15%" border="0" align="center" cellpadding="0" cellspacing="0" background="images/banner_bg3.jpg">
<tr>
<td width="25%" align=left>
<img src="images/vit_logo6.jpg" height="76" width="297">
</td>
<td align=center>
<br>
<font size=5 color=#FFFFFF face="Comic Sans MS">
<b>V-TOP</b><br>Student Login
</font>
</td>
</tr>
</table>
To target the first table, then this would likely give you the desired result
var note = document.getElementsByTagName('table')[0];
If the table is not the first element in its parent, you need to use insertBefore instead of appendChild
note.parentElement.insertBefore(par, note);
Side note:
If the table:nth-child(1) { display: none; } won't work, you could use replaceChild to replace the table with your new element
note.parentElement.replaceChild(par, note);
or simply remove it
note.parentElement.removeChild(note);
Note though, that if you are to remove it, do that after you inserted the new, or else there will be no reference where to insert the new.
If you still need to remove before add, read more here how to get the element to be removed's next sibling: https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore

Adding HTML slideshow to multiple pages (without using frames)

I am new to the site (and coding) so please bear with me!
I am trying to add the following clickable slideshow to my site in a way that means I can change the images in one file (HTML or JS) and this be reflected on every page on which the slideshow is called:
<table border="0" cellpadding="0">
<td width="100%">
<img src="image1.bmp" width="200" height="200" name="photoslider"></td>
</tr>
<tr>
<td width="100%">
<form method="POST" name="rotater">
<div align="center">
<center><p>
<script language="JavaScript1.1">
var photos=new Array()
var text=new Array()
var which=0
var what=0
photos[0]="image1.bmp"
photos[1]="image2.bmp"
photos[2]="image3.bmp"
text[0]="Image One"
text[1]="Image Two"
text[2]="Image Three"
window.onload=new Function("document.rotater.description.value=text[0]")
function backward(){
if (which>0){
window.status=''
which--
document.images.photoslider.src=photos[which];
what--
document.rotater.description.value=text[what];
}
}
function forward(){
if (which<photos.length-1){
which++
document.images.photoslider.src=photos[which]
what++
document.rotater.description.value=text[what];
}
else window.status='End of gallery'
}
function type()
{
alert("This textbox will only display default comments")
}
</script>
<p><input type="text" name="description" style="width:200px" size="50">
<p><input type="button" value="<<Back" name="B2"
onClick="backward()"> <input type="button" value="Next>>" name="B1"
onClick="forward()"><br />
</p>
</center>
</div>
</form>
</td>
</tr>
Currently I have used:
<script type="text/javascript" src="images.js"></script>
in the relevant html div. to call a simple .js file which displays the images in one long list, e.g.
document.write('<p>Image One</p>')
document.write('<img src="image1small.png" alt=Image One; style=border-radius:25px>')
document.write('<p>Image Two</p>')
document.write('<img src="image2small.png" alt=Image Two; style=border-radius:25px>')
I have tried every way I can think of, and searched many posts on here to try and get the slideshow to display within the same div. I have copied the html code into the .js file and appended it with document.write on every line, I have tried / on every line, I have tried 'gettingdocument.getElementById', but nothing works!
The slideshow code itself is fine; if I put this directly onto each page then it works correctly, I just can't seem to 'link' to this code and have it run so anything appears.
Please provide the simplest possible solution for this, without any need to install jquery plugins, or use anything other than basic HTML and JS.
There were alot of small bugs, i fixed them for you. you didn't put a semicolon after your javascript statements, tey aren't neccesary but it's cleaner code, you didn't exit alot of html tags
<table border="0" cellpadding="0">
<tr>
<td width="100%">
<img src="image1.bmp" width="200" height="200" name="photoslider">
</td>
</tr>
<tr>
<td width="100%">
<form method="POST" name="rotater">
<div align="center">
<center>
<p>
<p id="description" style="width:200px" size="50"></p>
<p><a onClick="backward()"><img src="imageback.png" alt="back" />Back Image</a>
<p><a onClick="forward()"><img src="forward.png" alt="forward" />Forward Image</a>
</p>
</center>
</div>
</form>
</td>
</tr>
Javascript:
(function() {
var photos=[];
var text= [];
var which=0;
var what=0;
photos[0]="image1.bmp";
photos[1]="image2.bmp";
photos[2]="image3.bmp";
text[0]="Image One";
text[1]="Image Two";
text[2]="Image Three";
document.getElementById('description').innerHTML = text[0]
backward = function(){
if (which>0){
which--;
window.status='';
what--;
console.log(which);
document.images.photoslider.src=photos[which];
document.getElementById('description').innerHTML = text[what];
}
}
forward = function(){
if (which < (photos.length-1)){
which++;
console.log(which);
document.images.photoslider.src=photos[which];
what++;
document.getElementById('description').innerHTML = text[what];
}
else {
document.getElementById('description').innerHTML = 'End of gallery';
}
}
function type()
{
alert("This textbox will only display default comments")
}
})();
And last but not least i've created the fiddle to show you it's working:
http://jsfiddle.net/45nobcmm/24/
You can create a javascript file that search for an element and change the innerHTML of the element to the slideshow you want to show.
For example this could be the script:
var slideshow = document.getElementById('slideshow');
slideshow.innerHTML = 'Your slideshow html';
and your main html page should have a slideshow div.
but you need to know that it's not the best solution, you should learn PHP or another back-end language and than you could use include('page.html'); for example

How to print a HTML Data which is in a String

I have a Print button in my Project. I am using JavaScript to print the data. I have a variable as data_to_print which contains the HTML which is to be print. The problem is that when i hit the print button the print dialog window of windows does not open. I am not able to find whats the problem, can any one help me.
Below is my Code:
function print_all()
{
var xx='<html>
<head>
<style>...</style>
</head>
<body>
<center>
<div>
<table><thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Address</th>
<th>DOB</th>
</tr><thead>
<tr>
<td>1</td>
<td>John</td>
<td>Mumbai</td>
<td>15 August</td>
</tr>
<tr>
<td>2</td>
<td>John2</td>
<td>Mumbai2</td>
<td>18 August</td>
</tr>
</table>
</div>
</center>
</body>
<html>';
var content_vlue = xx;
content_vlue=content_vlue.replace("[Print]", "");
var docprint=window.open("","","");
docprint.document.open();
docprint.document.write('<html><head>');
docprint.document.write('<style> .table{border-collapse:collapse;}.table tr
th{border:1px solid #000!important;color:#000;}.table tr th
a{color:#000!important;}.table tr td{border:1px solid #000!important;}</style>');
docprint.document.write('</head><body><center>');
docprint.document.write('<div align="left">');
docprint.document.write(content_vlue);
docprint.document.write('</div>');
docprint.document.write('</center></body></html>');
docprint.document.close();
docprint.focus();
}
The reason for your trouble is quit simple. You forgot to add the method .print();.
When I understand your right, then do following:
function print_all()
{
...
docprint.document.close();
docprint.focus();
//This line was missing
doc.print();
}
Addationaly two advices:
First:
As steo wrote, if you want to print long string in Javascript, concatinate it with the plus sign. The browsers don't accept line breaks within strings.
Second:
When I used your definition for the link <a title="Print" onClick="print_all();" class="no-bord btnlite" target="_blank">print</a> it did open the opener page also in a new tab. Another effect ourccur when I opend the site in IE. The effect: he didn't marked this line as clickable link.
To solve these, use this line <a title="Print" href="#" onClick="print_all();return false;" class="no-bord btnlite" target="_blank">print</a> .

Adding row in a table with javascript = strange result in Chrome and safari

I've got to add a new row with it's content populated from an ajax query when I click on any row present. Everything is working well in ie8, ff3.6, opera11, but in chrome10 and safari5 the row are always shown as the first row even if the HTML code is well ordered.
the javascript use is here:
jQuery('.tx_tacticinfocours_pi1_cour_line').click(function (){
if(running==false){
running=true;
jQuery('.cour_detail_temp_inner').slideUp(500, function () {
jQuery(this).parents('.cour_detail_temp').remove();
});
var td=jQuery(this).after('<tr class="cour_detail_temp"><td colspan="8" style="padding: 0pt;"><div class="cour_detail_temp_inner" style="display: none;"></div></td></tr>');
td=td.next().find('.cour_detail_temp_inner');
var url=jQuery(this).find('.tx_tacticinfocours_pi1_detail_link a').attr('href');
td.load(url,function(){
jQuery(this).slideDown(500,function(){running=false;});
});
}
});
and here is the HTML (it's typo3 template):
<table class="tx_tacticinfocours_pi1_liste" border="0" cellspacing="0" cellpadding="0">
<tr>
<th>###TITRE_WEB###</th>
<th>###TITRE_PDF###</th>
<th>###TITRE_DETAILS###</th>
<th>###TITRE_SIGLE###</th>
<th>###TITRE_TITRE###</th>
<th>###TITRE_ENLIGNE###</th>
<th>###TITRE_ENSEIGNANT###</th>
<th>###TITRE_RESPONSABLE###</th>
</tr>
<!-- ###COURS### begin -->
<tr class="tx_tacticinfocours_pi1_cour_line">
<td class="tx_tacticinfocours_pi1_link"><!-- ###COURS_LINK### begin -->###COURS_WEB_IMAGE###<!-- ###COURS_LINK### end --></td>
<td class="tx_tacticinfocours_pi1_link"><!-- ###PDF_LINK### begin -->###PDF_IMAGE###<!-- ###PDF_LINK### end --></td>
<td class="tx_tacticinfocours_pi1_link tx_tacticinfocours_pi1_detail_link"><!-- ###DETAILS_LINK### begin -->###DETAILS_IMAGE###<!-- ###DETAILS_LINK### end --></td>
<td class="tx_tacticinfocours_pi1_sigle" nowrap>###COURS_SIGLE###</td>
<td class="tx_tacticinfocours_pi1_titre">###COURS_TITRE###</td>
<td class="tx_tacticinfocours_pi1_enligne">###COURS_ENLIGNE###</td>
<td class="tx_tacticinfocours_pi1_enseignant" nowrap>###COURS_ENSEIGNANT###</td>
<td class="tx_tacticinfocours_pi1_responsable" nowrap>###COURS_RESPONSABLE###</td>
</tr>
<!-- ###COURS### end -->
have you got any idea why it's doing so or any work around?
I'm not sure, but try turning:
var td=jQuery(this).after(...)
to: var td=jQuery('<tr class="cour_detail_temp"><td colspan="8" style="padding: 0pt;"><div class="cour_detail_temp_inner" style="display: none;"></div></td></tr>').appendTo(this);
I think what you've got there is more of a css problem than a javascript problem.
I stumbled upon this today. Turns out the "main rows" in my table had display:block, which makes the new ones that have display:table-row end up on top even if they're mingled in the HTML. Having display:table-row on the "main rows" leaves the inserted ones in place. Go figure! (Safari only)
Not sure this is the problem, but instead of:
var td=jQuery(this).after(...)
try this:
var td=jQuery(this).parent().after(...)

Categories

Resources