Loading local text file to simpleMDE - javascript

Lately I have started using simpleMDE in my website, and I ran into a problem loading a local text file to my markdown editor, using a input button.
I was also unable to delete the previous data and change it to "".
I built my website using flask, and I am using flask simpleMDE to load simpleMDE to my website.
my code:
hello.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Flask-SimpleMDE example</title>
{{ simplemde.css }}
{{ simplemde.js }}
</head>
<body>
<div>
<input type="file">
<textarea>
Some Markdown Text Here
</textarea>
</div>
<script>
let input = document.querySelector('input')
let textarea = document.querySelector('textarea')
// This event listener has been implemented to identify a
// Change in the input section of the html code
// It will be triggered when a file is chosen.
input.addEventListener('change', () => {
let files = input.files;
if (files.length == 0) return;
/* If any further modifications have to be made on the
Extracted text. The text can be accessed using the
file variable. But since this is const, it is a read
only variable, hence immutable. To make any changes,
changing const to var, here and In the reader.onload
function would be advisible */
const file = files[0];
let reader = new FileReader();
reader.onload = (e) => {
const file = e.target.result;
// This is a regular expression to identify carriage
// Returns and line breaks
const lines = file.split(/\r\n|\n/);
textarea.value = lines.join('\n');
};
reader.onerror = (e) => alert(e.target.error.name);
reader.readAsText(file);
});
var simplemde = new SimpleMDE({
autofocus: true,
autosave: {
enabled: true,
uniqueId: "MyUniqueID",
delay: 1000,
},
});
</script>
</body>
</html>
my app:
from flask import Flask, render_template,request
from flask_simplemde import SimpleMDE
app = Flask(__name__)
app.config['SIMPLEMDE_JS_IIFE'] = True
app.config['SIMPLEMDE_USE_CDN'] = True
SimpleMDE(app)
#app.route('/')
def hello():
return render_template('hello.html')
if __name__ == '__main__':
app.run(debug=True)
When I try running the file without the flask, I obviously can't see the simplemde but seeing the textarea and able to load a text file into it using the input button, and when running the flask app I am able to see the simpleMDE but unable to load a text file into it.
any suggestings?

Related

correct javasript code execution in flask

I tried to use click on button:
#app.route("/")
def test_edition_open():
return render_template("index.html")
my index.html file is:
<script type="text/javascript" src="{{ url_for('static', filename='script.js') }}"></script>
The main part is just two buttons:
<div class = "counter">
<button class = "minus">-</button>
<div class = "result">1</div>
<button class = "plus">+</button>
</div>
I tried to make My script.js file work in flask. The code is very simple, it should add numbers by clicking on button:
const plus = document.querySelectorAll('.plus');
const minus = document.querySelectorAll('.minus');
const result = document.querySelectorAll('.result');
function min()
{
return function (ev)
{
if (ev.target.nextElementSibling.innerHTML > 0)
{
return --ev.target.nextElementSibling.innerHTML;
}
}
}
function pl()
{
return function (ev)
{
return ++ev.target.previousElementSibling.innerHTML;
}
}
minus.forEach(function (dominus)
{
dominus.addEventListener('click', min());
})
plus.forEach(function (doplus)
{
doplus.addEventListener('click', pl());
})
In https://playcode.io this code worked well. How should I solve this problem?
Make sure that script file successfully connected to html file. to check this add console.log("File Connected") in your script.js file. Then open your browser console to check that console message is logged correctly. If not then try to linked your static file correctly. How to set static_url_path in Flask application
Or you can put your Javascript code in html file using script tag.
Something like this:
<script> your javascript code here</script>

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>

Error 400 in Flask "The browser (or proxy) sent a request that this server could not understand."

So, I am trying to follow this tutorial https://www.youtube.com/watch?v=eCz_DTtUBfo
about flask usage with my ML model. The part of loading the model works, but when I try to initialize it, it just doesn't work. Maybe I have some error in my writing.
I hope anyone could help me :c
Here is my Flask code:
from keras.preprocessing.image import img_to_array
from flask import request
from flask import jsonify
from flask import Flask
app = Flask(__name__)
def get_model():
global model
model = load_model('pecuscope_model.h5')
print(" * Model loaded!")
def preprocess_image(image, target_size):
if image.mode != "RGB":
image = image.convert("RGB")
image = image.resize(target_size)
image = img_to_array(image)
image = np.expand_dims(image, axis=0)
return image
print(" * Loading Keras model...")
get_model()
#app.route("/predict", methods=["GET","POST"])
def predict():
message = request.get_json(force=True)
encoded = message['image']
decoded = base64.b64decode(encoded)
image = Image.open(io.BytesIO(decoded))
processed_image = preprocess_image(image, target_size=(229, 229))
prediction = model.predict(processed_image).tolist()
response = {
'prediction': {
'mosquito': prediction[0][0],
'abeja': prediction[0][1]
}
}
return jsonify(response)
and my html:
<!DOCTYPE html>
<html>
<head>
<title>PecuScope Prediction</title>
<style>
* {
font-size:30px;
}
</style>
</head>
<body>
<input id="image-selector" type="file">
<button id="predict-button">Predict</button>
<p style="font-weight:bold">Predictions</p>
<p>Mosquito: <span id="mosquito-prediction"></span></p>
<p>Abeja: <span id=abeja-prediction"></span></p>
<img id="selected-image" src=""/>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
let base64Image;
$("#image-selector").change(function() {
let reader = new FileReader();
reader.onload = function(e) {
let dataURL = reader.result;
$('#selected-image').attr("src", dataURL);
base64Image = dataURL.replace("data:image/jpg;base64,","");
console.log(base64Image);
}
reader.readAsDataURL($("#image-selector")[0].files[0]);
$("#mosquito-prediction").text("");
$("#abeja-prediction").text("");
});
$("#predict-button").click(function(event){
let message = {
image: base64Image
}
console.log(message);
$.post("http://10.142.0.2:5000/predict", JSON.stringify(message),
function(response){
$("#mosquito-prediction").text(response.prediction.mosquito.toFixed(6));
$("#abeja-prediction").text(response.prediction.abeja.toFixed(6));
console.log(response);
});
});
</script>
<body>
<html>
I thought that could be a problem with indentation, or with spaces, I don't know. I'm very disappointed with myself. I can't follow a tutorial :c
Dunno if it's the reason, but at least you forgot " at html file body:
Abeja: span id=abeja-prediction"

export plotly as self-contained html in JavaScript

In JavaScript, how to export plotly plot as a self-contained html file? Just like in R, we can use saveWidget function. How to do it with JavaScript?
Edit
I tried to use
var a = document.body.appendChild(
document.createElement("a")
);
a.download = "export.html";
a.href = "data:text/html," + document.getElementById("myDiv").innerHTML;
a.click();
But it does work well because it loses all the event, etc.
https://codepen.io/anon/pen/XqZqWX
You can download plotly.js and then call Plotly.newPlot method.
Here are step details.
Get plotly script text
async function getPlotlyScript() {
// fetch
const plotlyRes = await fetch('https://cdn.plot.ly/plotly-latest.js')
// get response as text
return await plotlyRes.text()
}
Get plotly chart data
We need to pass the current chart state in Plot.newPlot method. If the chart data and layout are not controlled by your code, don't worry. The DOM element where plotly builds the chart contains data and layout.
function getChartState () {
const el = document.getElementById('your plotly container id')
return {
data: el.data, // current data
layout: el.layout // current layout
}
}
Compose HTML
Now we have everything to compose our HTML. Don't forget to:
add charset="utf-8" because plotly script has special characters.
escape closing script tag to make browser consider it as a string, not as a tag
async function getHtml() {
const plotlyModuleText = await getPlotlyScript()
const state = getChartState()
return `
<head>
<meta charset="utf-8" />
</head>
<script type="text/javascript">
${plotlyModuleText}
<\/script>
<div id="plotly-output"></div>
<script type="text/javascript">
Plotly.newPlot(
'plotly-output',
${JSON.stringify(state.data)},
${JSON.stringify(state.layout)}
)
<\/script>
`
}
Download HTML document
async function exportToHtml () {
// Create URL
const blob = new Blob([await getHtml()], { type: 'text/html' })
const url = URL.createObjectURL(blob)
// Create downloader
const downloader = document.createElement('a')
downloader.href = url
downloader.download = 'export.html'
// Trigger click
downloader.click()
// Clean up
URL.revokeObjectURL(url)
}
exportToHtml()

Parse Uploaded CSV file using D3.js

I'm new to d3.js so I know this might seem as a silly question to some so please bear with me. I'm trying to parse a csv file which a user uploads and print it's output in the console. I'm able to parse the CSV file when I provide the absolute path of the CSV file but when I try doing the same with file upload functionality I'm not getting any output in the console..
Working Javascript Code..
var dataset = [];
d3.csv("sample.csv", function(data) {
dataset = data.map(function(d) { return [ d["Title"], d["Category"], d["ASIN/ISBN"], d["Item Total"] ]; });
console.log(dataset[0]);
console.log(dataset.length);
});
Console Output...
["Men's Brooks Ghost 8 Running Shoe Black/High Risk Red/Silver Size 11.5 M US", "Shoes", "B00QH1KYV6", "$120.00 "]
8
New HTML code..
<input type="file" id="csvfile" name="uploadCSV"/>
<br/>
<button onclick="howdy()">submit</button>
Modified Javascript Code(not working)..
var myfile = $("#csvfile").prop('files')[0];
var reader = new FileReader();
reader.onload = function(e) {
var text = reader.result;
}
reader.readAsDataURL(myfile);
var dataset = [];
d3.csv(reader.result , function(data) {
dataset = data.map(function(d) { return [ d["Title"], d["Category"], d["ASIN/ISBN"], d["Item Total"] ]; });
console.log(dataset[0]);
console.log(dataset.length);
})
Since there was no official documentation on how to handle user uploaded CSV file I can't figure out where I'm going wrong..Is there a way I can use HTML5 file reader?? Please help..
You are close but you don't need to and can't call d3.csv on a reader.result. d3.csv makes an async AJAX call to retrieve a CSV file from a server. You already have the file contents and just want to parse, so use d3.csv.parse.
Full working example:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3#3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
</head>
<body>
<input type="file" onchange="loadFile()" />
<script>
var reader = new FileReader();
function loadFile() {
var file = document.querySelector('input[type=file]').files[0];
reader.addEventListener("load", parseFile, false);
if (file) {
reader.readAsText(file);
}
}
function parseFile(){
var doesColumnExist = false;
var data = d3.csv.parse(reader.result, function(d){
doesColumnExist = d.hasOwnProperty("someColumn");
return d;
});
console.log(doesColumnExist);
}
</script>
</body>
</html>
This is for d3-csv#3
<!-- https://www.jsdelivr.com/package/npm/d3-dsv -->
<script src="https://cdn.jsdelivr.net/npm/d3-dsv#3.0.1/dist/d3-dsv.min.js" integrity="sha256-IrzYc2a3nTkfvgAyowm/WKmIGdVCMCcccPtz+Y2y6VI=" crossorigin="anonymous"></script>
<input type="file" accept=".csv">
<button>test button</button>
<script>
const testData = `owner,repo,"branch name"
foo,demo,master
boo,"js awesome",sha1123456
`
document.querySelector(`input`).onchange = async e => {
const input = e.target
const file = input.files[0]
const reader = new FileReader()
reader.readAsText(new Blob(
[file],
{"type": file.type}
))
const fileContent = await new Promise(resolve => {
reader.onloadend = (event) => {
resolve(event.target.result)
}
})
const csvData = d3.csvParse(fileContent)
console.log(csvData)
}
document.querySelector(`button`).onclick = e => {
const csvData = d3.csvParse(testData)
console.log(csvData)
}
</script>
The below link may help you know the implementation of csvParse
csv.js : The csv, tsv(tab) are dependent by dsv.js
dsv.js
If you just load the CSV only then do not import the whole JS. (instead of the d3-csv.js)
https://cdn.jsdelivr.net/npm/d3#7.0.1/dist/d3.min.js
https://cdn.jsdelivr.net/npm/d3-dsv#3.0.1/dist/d3-dsv.min.js
This is an old question and I think we have to clarify some points.
How to load a local csv file
How to link the loaded file with D3
1. Load a file is very simple just check this example:
const fileInput = document.getElementById('csv')
const readFile = e => {
const reader = new FileReader()
reader.onload = () => {
document.getElementById('out').textContent = reader.result
}
reader.readAsBinaryString(fileInput.files[0])
}
fileInput.onchange = readFile
<div>
<p>Select local CSV File:</p>
<input id="csv" type="file" accept=".csv">
</div>
<pre id="out"><p>File contents will appear here</p></pre>
Here we have a simple input element with type="file" attribute, this lets us to pick a csv file. Then the readFile() function will be triggered whenever a file is selected and will call the onload function after reading the file as a binary string.
2. I recommend to use readAsDataURL() to integrate it with d3 like this:
const fileInput = document.getElementById('csv')
const previewCSVData = async dataurl => {
const d = await d3.csv(dataurl)
console.log(d)
}
const readFile = e => {
const file = fileInput.files[0]
const reader = new FileReader()
reader.onload = () => {
const dataUrl = reader.result;
previewCSVData(dataUrl)
}
reader.readAsDataURL(file)
}
fileInput.onchange = readFile
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div>
<p>Select local CSV File:</p>
<input id="csv" type="file" accept=".csv">
</div>
<pre id="out"><p>File contents will appear here</p></pre>
To integrate the loaded file we call previewCSVData() and pass the file then we parse it using d3.csv() method. Also lets use await because it is an asynchronous call.
Note:
d3.csv internally uses fetch and works for any type of URL, (httpURL, dataURL, blobURL, etc...)

Categories