Import HTML to dynamically add elements using JS - javascript

I will be dynamically adding elements to my main index.html using .innerHTML += "<p>example</p>"; However I do not want to store the large html-like string in this .js file, but instead import it from another file example.html
example.html:
<p>example</p>
(It is just a snippet of code and not a standalone html file, but I want to keep the .html extension for linting, autocompletion and general readability)
My attempts:
$(...).load('example.html'): did not work as it replaces of contents of ... with this example instead of appending it
import * from example.html: this and other attempts of importing file failed because of MIME error that text/html cannot be imported
I will be perfectly satisfied with a solution of a method that reads .html as text and returns it as a string (preferably not using AJAX or ES6 as I do not feel confident with them). I would then just use the string in .innerHTML += imported_string; and call it a day.

If I correctly understand what you want to do, you can use FileReader to import the content of a file and convert it to text, for example:
function readFile(event) {
var file = event.target.files[0];
var stream = new FileReader();
stream.onload = function(e) {
var fileContent = e.target.result;
alert(fileContent);
}
stream.readAsText(file);
}
document.getElementById('myFile').addEventListener('change', readFile, false);
<input type="file" accept="html" id="myFile">
The file input is for presentation purposes, you can easily adapt this to your needs.
You should also perform the customary checks, which I ommited for brevity purposes.

Create a fetch request to the file that you want to retrieve. This is, in a basic sense, the same way how a browser would request a html file from the server.
The function below sends a request based on what you input as a file. For example, 'example.html'. It then checks if the request was a success and returns the response as a string. The string can then be appended to your innerHTML.
const getFileAsText = async file => {
const response = await fetch(file);
if (!response.ok) {
throw new Error(`Fetching the HTML file went wrong - ${response.statusText}`);
}
return response.text();
};
You can use it like the example below.
getFileAsText('example.html').then(html => {
document.body.innerHTML += html;
});

Related

NodeJS - How to insert an element in a HTML document using Javascript?

I'm trying to use NodeJS to modify an external HTML file (which is located in the same directory). In my index.js file I write:
fs.readFile('index.html', (err,html)=>{
if(err){
throw err;
}
html.body.innerHTML += '<div id = "asdf"></div>';
});
As index.html is a valid document. But it doesn't look to be reading it properly, as I get as an error:
"TypeError: Cannot read property 'innerHTML' of undefined".
I guess that html is not getting anything as body.
How can I do changes in HTML using JavaScript?
Here is an example using node-html-parse
HTML file
<html>
<body>
<div id="fist">yolo</div>
</body>
</html>
And the nodejs
const fs = require('fs');
const parse = require('node-html-parser').parse;
fs.readFile('index.html', 'utf8', (err,html)=>{
if(err){
throw err;
}
const root = parse(html);
const body = root.querySelector('body');
//body.set_content('<div id = "asdf"></div>');
body.appendChild('<div id = "asdf"></div>');
console.log(root.toString()); // This you can write back to file!
});
There might be better solutions than node-html-parser, considering the amount of downloads. For example, htmlparser2 has much more downloads, but it also looks more complex :)
In order to manipulate an html file the way you'd be able to in a browser, you'll first need to parse it.
Perhaps node-html-parser can be of use? (Or if a few milliseconds of parsing are not a concern and you want some more functionality, the JSDOM package is very popular too.)
innerHTML is a function provided after DOM parsing. Here you are using a string, so you can either use a DOM parser to create the structure or you can just use regex to isolate the part you want to replace and append the text.
html.replace("</body>",'<div id = "asdf"></div></body>');

How can I read file content with react-dropzone?

I'm trying to learn more about working with files for an upcoming project. Is there a way with react-dropzone that I can run a function when onDrop happens to change the contents of the files I'm uploading? For example, if I'm uploading a word doc that says "Hi everybody" how would I change the content to "Hi Dr. Nick"?
I've tried just accessing the data by using the filereader api after before attempting to make the changes. I tried using filereader right after the opening curly bracket of the async function and wasn't able to get it to work.
import React from 'react';
import Dropzone from 'react-dropzone';
import { graphql } from 'react-apollo';
import gql from 'graphql-tag';
const FileUpload = ({
children, disableClick, channelId, mutate, style = {},
}) => (
<Dropzone
style={style}
className="ignore"
onDrop={async ([file]) => {
const response = await mutate({
variables: {
channelId,
file,
},
});
console.log(response);
}}
disableClick={disableClick}
>
{children}
</Dropzone>
);
const createFileMessageMutation = gql`
mutation($channelId: Int!, $file: File) {
createMessage(channelId: $channelId, file: $file)
}
`;
export default graphql(createFileMessageMutation)(FileUpload);
Any thoughts on how to access and modify the contents of the file are greatly appreciated! Thanks.
onDrop={async ([file]) => {
var reader = new FileReader();
reader.onload = function(e) {
var contents = e.target.result;
displayContents(contents);
};
reader.readAsText(file);
}}
What you can do on frontend is to read file content and display it, all manipulations with file content should be done on server side. Push your file using ajax to your server with list of informations you want to change and use for example in nodeJS fs = require('fs')to make file modifications.
Also please visit this post i see that guys provided some solutions for your problem:
Is it possible to write data to file using only JavaScript?
and here is a fidlle taken from above link: http://jsfiddle.net/o4rhg1xe/1/
In Summary, you can read text file content using code i have provided and then use method from link to create Blob object with content you want and such file can be downlaoded by browser, (see fiddle)
Still in my opinion file modifications shoudl be moved to back-end side, ans i cant see no usecase to make them on frontend side.

Mechanisms for hashing a file in JavaScript

I am relatively new to JavaScript and I want to get the hash of a file, and would like to better understand the mechanism and code behind the process.
So, what I need: An MD5 or SHA-256 hash of an uploaded file to my website.
My understanding of how this works: A file is uploaded via an HTML input tag of type 'file', after which it is converted to a binary string, which is consequently hashed.
What I have so far: I have managed to get the hash of an input of type 'text', and also, somehow, the hash of an uploaded file, although the hash did not match with websites I looked at online, so I'm guessing it hashed some other details of the file, instead of the binary string.
Question 1: Am I correct in my understanding of how a file is hashed? Meaning, is it the binary string that gets hashed?
Question 2: What should my code look like to upload a file, hash it, and display the output?
Thank you in advance.
Basically yes, that's how it works.
But, to generate such hash, you don't need to do the conversion to string yourself. Instead, let the SubtleCrypto API handle it itself, and just pass an ArrayBuffer of your file.
async function getHash(blob, algo = "SHA-256") {
// convert your Blob to an ArrayBuffer
// could also use a FileRedaer for this for browsers that don't support Response API
const buf = await new Response(blob).arrayBuffer();
const hash = await crypto.subtle.digest(algo, buf);
let result = '';
const view = new DataView(hash);
for (let i = 0; i < hash.byteLength; i += 4) {
result += view.getUint32(i).toString(16).padStart(2, '0');
}
return result;
}
inp.onchange = e => {
getHash(inp.files[0]).then(console.log);
};
<input id="inp" type="file">

How to find out charset of text file loaded by input[type="file"] in Javascript

I want to read user's file and gave him modified version of this file. I use input with type file to get text file, but how I can get charset of loaded file, because in different cases it can be various... Uploaded file has format .txt or something similar and isn't .html :)
var handler = document.getElementById('handler');
var reader = new FileReader();
handler.addEventListener('click', function() {
reader.readAsText(firstSub.files[0], /* Here I need use a correctly charset */);
});
reader.addEventListener("loadend", function() {
console.dir(reader.result.split('\n'));
});
In my case (I made a small web app that accepts subtitle .srt files and removes time codes and line breaks, making a printable text), it was enough to foresee 2 types of encoding: UTF-8 and CP1251 (in all cases I tried – with both Latin and Cyrillic letters – these two types are enough). At first I try encoding with UTF-8, and if it is not successful, some characters are replaced by '�'-signs. So, I check the result for presence of these signs, and, if found, the procedure is repeated with CP1251 encoding. So, here is my code:
function onFileInputChange(inputDomElement, utf8 = true) {
const file = inputDomElement.files[0];
const reader = new FileReader();
reader.readAsText(file, utf8 ? 'UTF-8' : 'CP1251');
reader.onload = () => {
const result = reader.result;
if (utf8 && result.includes('�')) {
onFileInputChange(inputDomElement, false);
console.log('The file encoding is not utf-8! Trying CP1251...');
} else {
document.querySelector('#textarea1').value = file.name.replace(/\.(srt|txt)$/, '').replace(/_+/g, '\ ').toUpperCase() + '\n' + result;
}
}
}
You should check out this library encoding.js
They also have a working demo. I would suggest you first try it out with the files that you'll typically work with to see if it detects the encoding correctly and then use the library in your project.
The other solutions didn't work for what I was trying to do, so I decided to create my own module that can detect the charset and language of any file loaded via input[type='file'] / FileReader API.
You load it via the <script> tag and then use the languageEncoding function to retrieve the charset/encoding:
// index.html
<script src="https://unpkg.com/detect-file-encoding-and-language/umd/language-encoding.min.js"></script>
// app.js
languageEncoding(file).then(fileInfo => console.log(fileInfo));
// Possible result: { language: english, encoding: UTF-8, confidence: { language: 0.96, encoding: 1 } }
For a more complete example/instructions check out this part of the documentation!

Converting multiple files into HTML (from Markdown)?

I'm currently working on a small project in which I want to convert couple (or more) Markdown files into HTML and then append them to the main document. I want all this to take place client-side. I have chose couple of plugins such as Showdown (Markdown to HTML converter), jQuery (overall DOM manipulation), and Underscore (for simple templating if necessary). I'm stuck where I can't seem to convert a file into HTML (into a string which has HTML in it).
Converting Markdown into HTML is simple enough:
var converter = new Showdown.converter();
converter.makeHtml('#hello markdown!');
I'm not sure how to fetch (download) a file into the code (string?).
How do I fetch a file from a URL (that URL is a Markdown file), pass it through Showdown and then get a HTML string? I'm only using JavaScript by the way.
You can get an external file and parse it to a string with ajax. The jQuery way is cleaner, but a vanilla JS version might look something like this:
var mdFile = new XMLHttpRequest();
mdFile.open("GET", "http://mypath/myFile.md", true);
mdFile.onreadystatechange = function(){
// Makes sure the document exists and is ready to parse.
if (mdFile.readyState === 4 && mdFile.status === 200)
{
var mdText = mdFile.responseText;
var converter = new showdown.Converter();
converter.makeHtml(mdText);
//Do whatever you want to do with the HTML text
}
}
jQuery Method:
$.ajax({
url: "info.md",
context: document.body,
success: function(mdText){
//where text will be the text returned by the ajax call
var converter = new showdown.Converter();
var htmlText = converter.makeHtml(mdText);
$(".outputDiv").append(htmlText); //append this to a div with class outputDiv
}
});
Note: This assumes the files you want to parse are on your own server. If the files are on the client (IE user files) you'll need to take a different approach
Update
The above methods will work if the files you want are on the same server as you. If they are NOT then you will have to look into CORS if you control the remote server, and a server side solution if you do not. This question provides some relevant background on cross-domain requests.
Once you have the HTML string, you can append to the whatever DOM element you wish, by simply calling:
var myElement = document.getElementById('myElement');
myElement.innerHTML += markdownHTML;
...where markdownHTML is the html gotten back from makeHTML.

Categories