Change CSS Style of another HTML file using a form - javascript

I want to change the CSS style of another HTML file using a form. This is what I got so far however, the code isn't working as it won't change the style of the uploaded HTML file.
Here is my main code:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Changing the style of another HTML File</title>
<script type="text/javascript">
function updateSize() {
var nBytes = 0,
oFiles = document.getElementById("uploadInput").files,
nFiles = oFiles.length;
for (var nFileId = 0; nFileId < nFiles; nFileId++) {
nBytes += oFiles[nFileId].size;
}
var sOutput = nBytes + " bytes";
// optional code for multiples approximation
for (var aMultiples = ["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"], nMultiple = 0, nApprox = nBytes / 1024; nApprox > 1; nApprox /= 1024, nMultiple++) {
sOutput = nApprox.toFixed(3) + " " + aMultiples[nMultiple] + " (" + nBytes + " bytes)";
}
// end of optional code
document.getElementById("fileNum").innerHTML = nFiles;
document.getElementById("fileSize").innerHTML = sOutput;
}
function extract() {
var el = document.getElementById("test");
el.style.background = 'green';
el.style.color = 'red';
}
</script>
<body onload="updateSize();">
<form>
<p><input id="uploadInput" type="file" name="myFiles" onchange="updateSize();" multiple> selected files: <span id="fileNum">0</span>; total size: <span id="fileSize">0</span></p>
<p><input type="button" value="Submit" onclick="extract()"></p>
</form>
</body>
</html>
The file which is being uploaded:
<html>
<head>
<style>
#test {
background-color: blue;
color: yellow;
};
</style>
</head>
<body>
<div id="test">This is a div</div>
</body>
</html>
Where I'm I going wrong?

You misunderstand what document refers to, and how file uploads work. Your extract function is indeed called when the user presses the button. (Although it may be pressed when there are no files, what do you do then?)
But even inside the function, document still refers to the same document, the one with <title>Changing the style of another HTML File</title> and the file input form. It looks for an element with id #test, which it cannot find in this document, then fails, because it cannot set the style attribute of a non-existent / null element.
What you seem to want to do is to:
Let the user provide HTML files via the form input.
Parse the uploaded files as HTML.
Edit the CSS contained within (which involves first parsing the CSS, then editing it, then re-encoding it.)
Saving the files.
None of these are simple and they all have their subtleties. Parsing HTML is hard, but there are libraries that can manage this for you. Likewise for CSS. Saving is another problem – do you want to create another file that the user can then download? You cannot modify a user's file – consider if websites could simply modify the contents of your hard disk. It would be a security disaster.
Perhaps the most important question you should ask yourself is – why do you want to do this?

Related

Automatically load csv/txt file from local drive into html page as table Javascript

I found a lot of good suggestions on how to load a csv/txt file into a html page into a table, but none of the solutions are working for me. Here is the code I am working with. I have both files located in my C: drive and basically would like to load this csv/txt file and show it on as a table in index.html. Thanks so much!
data.txt
heading1,heading2,heading3,heading4,heading5
value1_1,value2_1,value3_1,value4_1,value5_1
value1_2,value2_2,value3_2,value4_2,value5_2
index.html
<!DOCTYPE html>
<!-- saved from url=(0014)about:internet -->
<html lang="en">
<html>
<head>
<title>Test</title>
</head>
<body>
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
type: "GET",
url: "data.txt",
dataType: "text",
success: function(data) {processData(data);}
});
});
function processData(allText) {
var allTextLines = allText.split(/\r\n|\n/);
var headers = allTextLines[0].split(',');
var lines = [];
for (var i=1; i<allTextLines.length; i++) {
var data = allTextLines[i].split(',');
if (data.length == headers.length) {
var tarr = [];
for (var j=0; j<headers.length; j++) {
tarr.push(headers[j]+":"+data[j]);
}
lines.push(tarr);
}
}
\\ alert(lines);
}
</script>
</body>
</html>
You can't access local files with JS. That would be serious security vulnerability, because you could send a malicious webpage to a user, which would download their files and send them to someone. As midrizi mentioned in the comments, you'll need a server to download files from there.
As others have noted, you can't automatically read a local file into the browser.
But you can prompt the user to select a file, using the <input type="file"> element.
Once a file has been selected via that input, it can be read via JavaScript.
<label for="file">Select a Text File:</label><br />
<input id="file" type="file" /><br/>
<button onclick="readFile()">Read File</button><br/>
let input = document.getElementById('file');
let contents = document.getElementById('contents');
function readFile () {
let file = input.files[0];
const reader = new FileReader();
reader.onload = function (evt) {
console.log('reader.onload');
contents.innerHTML = String(evt.target.result);
};
reader.readAsText(file);
}
If you can modify the data.txt a bit you can just load it as another script file without need for a server.
Change data.txt to this
var data = `heading1,heading2,heading3,heading4,heading5
value1_1,value2_1,value3_1,value4_1,value5_1
value1_2,value2_2,value3_2,value4_2,value5_2`
And load it as a javascript file before your actual script
<script type="text/javascript" src="data.txt"></script>
Then you can use the variable data which holds your file content without any ajax call.
There is no way you can retrieve a local file if you don't serve it, as pointed out in the comments to your question.
There are approaches you can take to that, though. If you can't serve it by any means, you could create a GitHub repo and upload your file there. Then you can use the link to your raw file:
And you can also take steps to automate that, but it should be easy enough committing your file locally whenever you update it and push it to GitHub. Just in case you're not familiar with Git and GitHub, here's a handy ref.
A word of caution: unless you have total control over the characters that you include in your CSV, parsing them by naively splitting commas like that might result in ugly stuff if the values within contain commas themselves. Some CSV files also come with extra stuff in the beginning of the file (like the sep indicator in the first row, which defines what character to interpret as separator). You may completely ignore these warnings if you're producing the CSV yourself.
Also I noticed your function does not take care of building the actual table, so I changed it so it does. I also used Fetch API to retrieve the data:
<!DOCTYPE html>
<!-- saved from url=(0014)about:internet -->
<html lang="en">
<html>
<head>
<title>Test</title>
</head>
<body>
<script type="text/javascript">
function processData(csv) {
let data = csv.split(/\r\n|\n/).map(v => v.split(','));
let headers = data.shift();
let table = document.createElement('table');
let thead = document.createElement('thead');
table.appendChild(thead);
thead.innerHTML = '<tr><th>' + headers.join('</th><th>') + '</th></tr>';
let tbody = document.createElement('tbody');
table.appendChild(tbody);
for (let row of data) {
tbody.innerHTML += '<tr><td>' + row.join('</td><td>') + '</td></tr>';
}
document.body.appendChild(table);
}
// I uploaded the CSV to a personal repo for this example,
// but you CAN use a local file as long as you *serve* it
fetch("https://raw.githubusercontent.com/gyohza/test/master/so/data.txt")
.then(res => res.text())
.then(text => processData(text));
</script>
</body>
</html>

inject several hundred of images into divs

I would like to know how to add several hundred images in divs but automatically. I have a folder with the images and I want to know if there is a technique to avoid copying and pasting the same code.
For example: <img src="img/01.png">
the idea is to inject this code into the divs and change the names of the images: 01.png, 02.png, 03.png...
Thanks for the help.
You can generate the html using javascript if you run this html page it'll display the tags for the first 99 images.
<!DOCTYPE html>
<html>
<head>
<title>Hello</title>
</head>
<body>
<p id="my_output"></p>
<script>
let escapeHTML = function (aValue) {
return (
aValue.replace(/>/g, '>').
replace(/</g, '<').
replace(/"/g, '"')
)
}
let myOutput = document.querySelector('#my_output')
for (let i = 1; i < 100; ++i) {
let paddedIndex = ('0' + i).slice(-2)
myOutput.innerHTML += escapeHTML('<img src="img/' + paddedIndex + '.png">') + '<br>'
}
</script>
</body>
</html>
You can then copy paste the output into your code.

RSS giving me unclosed tag link, couldn't get the innerHTML

I'm doing a study using a RSS, but the Web Site gives me a RSS with an unclosed tag then I couldn't get the innerHTML of this tag.
I don't know how to resolve the problem with jquery and make the tag closed or a possible solution like this.
Here is the code :
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" content="xml">
<script type="text/javascript" src="api/jquery.js"></script>
</head>
<body>
<p id="someElement" visibility="hidden"></p>
<p id="anotherElement"></p>
<script type="text/javascript">
var x = new XMLHttpRequest();
x.open("GET", "http://www.lemonde.fr/rss/une.xml", true);
x.onreadystatechange = function () {
if (x.readyState == 4 && x.status == 200)
{
var doc = x.responseXML;
var string = (new XMLSerializer()).serializeToString(doc);
$("#someElement").append(string);
alert("test");
var tag = document.getElementsByTagName("item");
for(var i = 0, max = tag.length; i < max; i++){
var htmli = tag[i];
//alert(htmli.innerHTML);
//uncomment the alert to see the xml got from the rss
var title = htmli.getElementsByTagName("title")[0].innerHTML;
var link = htmli.getElementsByTagName("link")[0].innerHTML;
var description = htmli.getElementsByTagName("description")[0].innerHTML;
var toAdd = "<ul><li> title : " +title+"</li><li> link : "+ link +" </li><li> description :"+description+" </li></ul>";
$("#anotherElement").append(toAdd);
}
}
};
x.send(null);
</script>
</body>
</html>
Any solution to this?
I have jquery in a folder named api.
Thanks a lot !!
(I notice that while you include jQuery in a script tag, you're not actually using it in your code. It's much better practice to use jQuery's functionality to manage AJAX requests and serialization, if you're going to use it at all, as they cover many more situations and browser versions. I'd also recommend retrieving jQuery from a CDN rather than hosting it yourself. jQuery has had the ability to parse XML natively since 1.5. The following was written using 1.12.)
I ran into the same issue with unclosed tags in an RSS feed and came up with a terrible solution to it. I have not tested this cross-browser and would not recommend incorporating it into production code, but it worked to solve a one-time problem for me.
The idea is to take the raw output of the RSS item's text, cram it into the jQuery HTML parser, and then manually inspect its output until we get to an item that it thinks might have been an HTML <link> tag. Because we know the RSS link tag isn't closed, the next thing it encounters should be parsed as an HTML Text object, which we can extract for our permalink URL.
Here's how I would rewrite your script to take better advantage of jQuery and incorporate my hack. (I'm assuming you have set up CORS or something else so that you can actually retrieve the feed from lemonde.fr cross-domain.)
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" content="xml">
<script type="text/javascript" src="//code.jquery.com/jquery-1.12.4.min.js"></script>
</head>
<body>
<p id="someElement" visibility="hidden"></p>
<p id="anotherElement"></p>
<script type="text/javascript">
(function($, window, document) {
function fetchFeed(url) {
// use jQuery to handle AJAX
$.get(url, function(data) {
// parse XML result with jQuery
var $XML = $(data);
$XML.find("item").each(function() {
// ensure that we have a jQuery-wrapped _this_ object and
// create a new object with the properties we want
var $this = $(this),
item = {
title: $this.find("title").text(),
description: $this.find("description").text(),
link: ""
};
// since the XML parser will treat the unclosed <link> as valid,
// we instead send the raw output to the HTML parser and tell it do to its best
var $redigested = $($this.html());
// jQuery should produce an array of HTML DOM objects
for (var i = 0; i < $redigested.length; i++) {
// if we found an HTMLLinkElement--a <link> tag--followed by a Text element, that's our URL
if ($redigested[i] instanceof HTMLLinkElement && $redigested.length >= i + 1 && $redigested[i + 1] instanceof Text) {
item.link = $redigested[i + 1].data;
break;
}
}
console.log("link: " + item.link);
var toAdd = "<ul><li> title: " + item.title + "</li><li> link: " + item.link + " </li><li> description: " + item.description + " </li></ul>";
$("#anotherElement").append(toAdd);
});
});
}
$(function() {
// call the fetch function on DOM ready
fetchFeed("http://www.lemonde.fr/rss/une.xml");
});
})(jQuery, window, document);
</script>
</body>
</html>

Scrape html with js

I'm trying to get the html of www.soccerway.com. In particular this:
that have the label-wrapper class I also tried with: select.nav-select but I can't get any content. What I did is:
1) Created a php filed called grabber.php, this file have this code:
<?php echo file_get_contents($_GET['url']); ?>
2) Created a index.html file with this content:
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<meta charset=utf-8 />
<title>test</title>
</head>
<body>
<div id="response"></div>
</body>
<script>
$(function(){
var contentURI= 'http://soccerway.com';
$('#response').load('grabber.php?url='+ encodeURIComponent(contentURI) + ' #label-wrapper');
});
var LI = document.querySelectorAll(".list li");
var result = {};
for(var i=0; i<LI.length; i++){
var el = LI[i];
var elData = el.dataset.value;
if(elData) result[el.innerHTML] = elData; // Only if element has data-value attr
}
console.log( result );
</script>
</html>
in the div there is no content grabbed, I tested my js code for get all the link and working but I've inserted the html page manually.
I see a couple issues here.
var contentURI= 'http:/soccerway.com #label-wrapper';
You're missing the second slash in http://, and you're passing a URL with a space and an ID to file_get_contents. You'll want this instead:
var contentURI = 'http://soccerway.com/';
and then you'll need to parse out the item you're interested in from the resulting HTML.
The #label-wrapper needs to be in the jQuery load() call, not the file_get_contents, and the contentURI variable needs to be properly escaped with encodeURIComponent:
$('#response').load('grabber.php?url='+ encodeURIComponent(contentURI) + ' #label-wrapper');
Your code also contains a massive vulnerability that's potentially very dangerous, as it allows anyone to access grabber.php with a url value that's a file location on your server. This could compromise your database password or other sensitive data on the server.

how to create a dynamic array in javascript based on the number of files in same directory

I have a static page, which I'm using for viewing pictures, and the javascript does the slide show; however, I would like to dump the pictures in same directory and when page is opened, the javascript will create an array with all the pictures without me having to edit the array for every scenario.... is this possible?... I know javascript has some security restrains when it comes to read from local filesystem. here's the static page and javascript
<!doctype html>
<html lang="en">
<head>
<title>Picture Show</title>
<link type="text/css" rel="stylesheet" href="stylesheet.css" />
<script type="text/javascript" src="slideshow.js"></script>
</head>
<body>
<!-- Insert your content here -->
<div id="container">
<div id="header">
<h1>Slide Show</h1>
<a id="link" href="javascript:slideShow()"></a>
</div>
<div id="slideShow">
<img name="image" alt="Slide Show" src="pics/0.jpg" />
</div>
</div>
</body>
</html>
javascript
//javascript code for slideshow
//pictures
var imgs = [ "pics\/0.jpg", "pics\/1.jpg", "pics\/2.jpg", "pics\/3.jpg", "pics\/4.jpg", "pics\/5.jpg" ];
var imgNum = 0;
var imgsLength = imgs.length-1;
var time = 0;
//changing images function
function changeImg(n) {
imgNum += n;
//last position of array
if (imgNum > imgsLength) {
imgNum = 0;
}
//first position of array
if (imgNum < 0) {
imgNum = imgsLength;
}
//console.log(images.tagName);
document.image.src = imgs[imgNum];
return false;
}
//slideshow function
function slideShow() {
var tag = document.getElementById('link').innerHTML;
if(tag == "Stop") {
clearInterval(time); //stoping slideshow
document.getElementById('link').innerHTML = "Start";
document.getElementById('link').style.background = "yellow";
}
else { //all other cases come here
time = setInterval("changeImg(1)", 4000);
document.getElementById('link').innerHTML = "Stop";
document.getElementById('link').style.background = "green";
}
}
window.addEventListener('load', slideShow);
It's not possible to automatically read a directory with in-browser javascript because of security issues. You have two options here:
Make a multiple file input and let the user select the images to display. He could just use "ctrl+a" inside a directory to select everything ... of course this is bad cuz it requires a file select for every slideshow.
or...
Make a server side application that will upload the files or a list with their path. This will do the trick just the way you want, but the application must be installed and running on the machine in order to work. This could be easily achieved with nodejs and I bet you will find a module that will help you.

Categories