Javascript error as unexpected end of input - javascript

I am trying to save my file but getting error on append the default html base structure
$('#saveHTML').click(function() {
var html = $('#editor').val();
// Append the default HTML base structure
html = `<!DOCTYPE html><html><head><title>HTML File</title></head><body>' + html + '</body></html>`;
// Write your code to save HTML file here.
// Generate a random filename
var filename = Math.random().toString(36).substr(2, 9);
// Create a temporary element
var tmpElement = document.createElement('a');
// Set temporary element attributes
tmpElement.download = filename + '.html';
tmpElement.href = 'data:text/html;charset=utf-8,' + encodeURIComponent(html);
// Simulate click on the temporary element
tmpElement.click();
// Remove the temporary element
document.body.removeChild(tmpElement);
// Show success message
alert('HTML file saved successfully!');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea id="editor"></textarea>
<button id="saveHTML">Click</button>
what I am doing wrong here please help to solve
getting below error
Uncaught SyntaxError: Unexpected end of input at line no 3

Related

Problems accessing a dictionary/json in a javascript function to populate a table

Overview:
I am creating a web page using Python and generating both html as well as javascript in my code. Additionally, I am parsing through csv files and converting their table data to html. I want to be able to click on a line of text and the associated table data for that text would then be loaded into an iframe on the currently active web page. The problem I am having, is that my javascript function is not recognizing the key I send it to retrieve the corresponding table data. If I manually enter the key to return the table data, the correct data is returned - though the table doesn't load. However, if I generate the key programmatically, it returns as 'undefined' even though the strings appear to be identical.
Goal:
I need to figure out if there is something wrong with either the syntax, or the format of the key I am using to try and retrieve the table data. Secondly, I need to figure out why the table data is not being correctly loaded into my iframe.
Example:
import pandas
opening_html = """<!DOCTYPE html><h1> Test</h1><div style="float:left">"""
table_html = pandas.DataFrame({'Col_1':['this', 'is', 'a', 'test']}).to_html()
tables_dict = {'test-1 00': table_html}
java_variables = "%s" % json.dumps(tables_dict)
table_frame = """<iframe name="table_frame" style="position:fixed; top:100px; width:750; height:450"></iframe>"""
test_link_text = """ test-1<br>"""
java = """<script type='text/javascript'>
var table_filename = """ + java_variables + ";"
java += """function send_table_data(obj) {
var t = obj.text + ' 00';
alert(t)
//This line below will not work
var table_data = table_filename[t];
//But this line will return the correct value
var table_data = table_filename['test-1 00'];
alert(table_data);
//This line should load the data, but does nothing
document.getElementsByName('table_frame').src = table_data;
}
</script>"""
html_text = """<head>
<link rel="stylesheet" href="style.css">
</head>""" + test_link_text + table_frame + """<body>""" + "</div>" + java + '</body>'
with open('test_table_load.html', 'w') as w:
w.write(html_text)
EDIT: I did just figure out that for some reason there was a default space at the beginning of the var t - so using trim() seemed to fix that. Now, the only issue left is why the data doesn't load into the table.
It looks like you figured out your typo with the space that was messing with your key, so this is for your second question.
Your code
So to get your table to populate in the iframe you need to fix three things:
To edit the HTML contents of your iframe you should be setting the .srcdoc element, not .src
The document.getElementsByName() function will return an array of HTML elements so in order to get the element you want you should do one of the following:
(recommended) switch to using document.getElementById and use id='table_frame' in your iframe tags
select the first element of the array by using document.getElementsByName('table_frame')[0]
The anchor tag that you're using as the trigger for your function is redirecting you back to the original HTML page, stopping you from seeing any of the changes your javascript function is making. A simple solution to this is to switch to using a <button> element in place of <a>.
Here is what your code looks like with the fixes:
import pandas
import json
opening_html = """<!DOCTYPE html><h1>Test</h1><div style="float:left">"""
table_html = pandas.DataFrame({'Col_1':['this', 'is', 'a', 'test']}).to_html()
tables_dict = {'test-1 00': table_html}
java_variables = "%s" % json.dumps(tables_dict)
table_frame = """<iframe id="table_frame" style="position:fixed; top:100px; width:750; height:450"></iframe>"""
test_link_text = """<button href='' onclick="send_table_data(this);"> test-1</button><br>"""
java = """<script type='text/javascript'>
var table_filename = """ + java_variables + ";"
#for the button, innerText needs to be used to get the button text
java += """function send_table_data(obj) {
var t = obj.innerText + ' 00';
alert(t)
//This line below will not work
var table_data = table_filename[t];
//But this line will return the correct value
var table_data = table_filename['test-1 00'];
alert(table_data);
//This line should load the data, but does nothing
document.getElementById('table_frame').srcdoc = table_data;
}
</script>"""
html_text = """<head>
<link rel="stylesheet" href="style.css">
</head>""" + test_link_text + table_frame + """<body>""" + "</div>" + java + '</body>'
with open('test_table_load.html', 'w') as w:
w.write(html_text)
Other Recommendations
I strongly suggest looking into some python frameworks that can assist you in generating your website, either using HTML templates like Flask, or a library that can assist in generating HTML using Python. (I would recommend Dash for your current use case)

ContentTools - How can I pass additional data from a DIV to the payload object, to be passed into the POST array?

I use ContentTools for my content editor/PHP CMS.
I'm trying to pass additional values from a "editable div" to the POST array (then it will be stored in a database).
The script uses Javascript to get the data and to make the call to my server side code.
Relevant JS code for the saving process:
// Collect the contents of each editable region into a FormData instance
payload = new FormData();
//payload.append('__page__', window.location.pathname);
payload.append('page_id', page_id); // Page ID from the Meta Property
for (name in regions) {
payload.append(name, regions[name]);
//payload.append('template', 'template');
}
// Send the updated content to the server to be saved
onStateChange = function(ev) {
// Check if the request is finished
if (ev.target.readyState == 4) {
editor.busy(false);
if (ev.target.status == '200') {
// Save was successful, notify the user with a flash
if (!passive) {
new ContentTools.FlashUI('ok');
}
} else {
// Save failed, notify the user with a flash
new ContentTools.FlashUI('no');
}
}
};
xhr = new XMLHttpRequest();
xhr.addEventListener('readystatechange', onStateChange);
xhr.open('POST', 'update-page.php'); // Server side php file, which will catch the $_POST array.
xhr.send(payload);
Below you see an example editable div which will be in the POST array when page is saved after editing.
Note that the div has additional custom html tags 'data-template'.
<div id="content_4" class="content" data-template="5" data-editable data-name="1">
This is some example website text.
This is some other example website text.
</div>
I'm trying to pass along the values from "data-template".
What I've tried so far does not work:
// Added in: editor.addEventListener('saved', function (ev) {
var template = document.querySelector("div[data-template]"); // Get Template name from editable div
// Or
var template = document.getElementsByTagName("[data-template]")[0].getAttribute('[data-template]');
// Added in: the For In Loop
for (name in regions) {
payload.append(name, regions[name]);
payload.append('template', template); // added but does not work
}
Also, I don't want to use the div ID as value to be passed on.
I'm still trying other ways, but my JavaScript knowledge is not (yet!) as strong as my PHP knowledge.
Does someone know a solution to this issue?
There must be simple solution to get the value from the data-template, passed on to the POST (only the data-template value of the changed content in the div).
Right?
You can select the template data for each region by selecting the region's DOM element by it's editable name (e.g data-name):
for (var name in regions) {
// Select the region DOM element
var regionDOM = document.querySelector('[data-name="' + name + '"]');
// Get the `data-template` attribute
var tpl = regionDOM.getAttribute('data-template');
// Add the region HTML and template to the payload
payload.append(name, regions[name]);
payload.append('template_' + name, tpl);
}
The reason you get no value for for template at all in your code is that you're calling the getAttribute method with the CSS selector and not just the attribute name you want, e.g .getAttribute('[data-template]') should be .getAttribute('data-template').
The other difference in the code I've posted is that the template for each region is saved. If it will be the same template for all regions then you could modify the code to be:
for (var name in regions) {
// Select the region DOM element
var regionDOM = document.querySelector('[data-name="' + name + '"]');
// Get the `data-template` attribute
var tpl = regionDOM.getAttribute('data-template');
// Add the region HTML and template to the payload
payload.append(name, regions[name]);
}
// Set the template value for the payload to that of the last region
// found.
payload.append('template', tpl);

Unable to display background image using javascript on qualtrics

For starters, I have absolute no knowledge with javascript. I am trying to display a background image extracted from a url address on just a page of the questionnaire on qualtrics with the following codes:-
Qualtrics.SurveyEngine.addOnload(function()
{
<div id="divtest">Hello</div>
<img id="imgtest" />
<img id="imgreal" src="http://webneel.com/wallpaper/sites/default/files/images/01-2014/2-flower-wallpaper.jpg" />
var string = 'http://webneel.com/wallpaper/sites/default/files/images/01-2014/2-flower-wallpaper.jpg';
document.getElementById("divtest").style.backgroundImage = "url('" + string + "')";
document.getElementById("imgtest").src = string;
});
But I got the following error message:-
Invalid JavaScript! You cannot save until you fix all errors: Unexpected token <
How do I go about fixing this?
You cannot add HTML directly in javascript code, you have to create into body section of your page, or if you need to create elements via code you have to use createElement
var _div = document.createElement('div');
_div.id = 'divtest';
_div.innerHTML = 'Hello';
_div.style.backgroundImage = "url('" + string + "')";
document.getElementsByTagName('body')[0].appendChild(_div); // to place as child of body
or
document.getElementById('[ID of parent element]').appendChild(_div); // to place as child of other element.

How do I convert escape characters in Javascript to a .txt file?

I have an HTML file that is using Javascript to do file I/O operations on a .txt file, via an ActiveXObject (only works in Internet Explorer, on Windows OS).
There is a text input box on the HTML page, and a button. The button calls a function onclick to write the text entered to the end of the .txt file. There is also a textarea on the HTML page, in which the modified contents of the .txt file are copied and pasted into. All of this is working so far...
So, I want to insert tabs and new-lines into the .txt file, from my HTML page with Javascript. I am using this line to copy the .txt file contents into the textarea, initialized in a variable:
var newText = oldText + "\n" + document.getElementById("userInput").value;
Of course, the escape character \n works on the HTML page, and not in the .txt file...
So how do I encode new lines, and tabs as well, into a parsable format for the .txt file? I have tried using the escape() method on ANSI values found here, and on ASCII values found here, but with no luck.
Here is my code so far:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>New Web Project</title>
</head>
<body>
<p>
Enter some text here:
<input type = "text" id = "userInput" />
</p>
<input type = "button" value = "submit" onclick = "main();" />
<br />
<hr />
<br /><br /><br />
<textarea id = "textHere" rows = 25 cols = 150></textarea>
<script type = "text/javascript">
// executes all code from this function to prevent global variables
function main()
{
var filePath = getThisFilePath();
var fileText = readFile(filePath);
writeFile(filePath, fileText);
} // end of function main
function getThisFilePath()
{
var path = document.location.pathname;
// getting rid of the first forward-slash, and ending at the last forward-slash to get rid of file-name
var correctPath = path.substr(1, path.lastIndexOf("/") );
var fixedPath = correctPath.replace(/%20/gi, " "); // replacing all space entities
return fixedPath;
} // end of function getThisFilePath
function readFile(folder)
{
var fso = "";
var ots = "";
var oldText = "";
try
{
fso = new ActiveXObject("Scripting.FileSystemObject");
// in the same folder as this HTML file, in "read" mode (1)
ots = fso.OpenTextFile(folder + "writeToText.txt", 1, true);
oldText = ots.ReadAll();
ots = null;
fso = null;
}
catch(e)
{
alert("There is an error in this code!\n\tError: " + e.message);
exit(); // end the program if there is an error
}
return oldText;
} // end of function readFile
function writeFile(folder, oldText)
{
var fso = "";
var ots = "";
var newText = oldText + "\n" + document.getElementById("userInput").value;
try
{
fso = new ActiveXObject("Scripting.FileSystemObject");
// in the same folder as this HTML file, in "write" mode (2)
ots = fso.OpenTextFile(folder + "writeToText.txt", 2, true);
ots.Write(newText);
ots.Close();
ots = null;
fso = null;
}
catch(e)
{
alert("There is an error in this code!\n\tError: " + e.message);
exit(); // end the program if there is an error
}
setText(newText); // with the function below
} // end of function writeFile
// called from the function writeFile
function setText(textFile)
{
document.getElementById("textHere").value = textFile;
} // end of function setText
</script> <!-- end of javascript -->
</body>
</html>
Windows expects "\r\n" as linebreaks. I'm quite sure you would find them in your textarea's value as well (after hitting enter). They will get automatically inserted when you set a value with "\n", and most libraries (like jQuery) do replace them with "normal" linebreaks when reading the value.
However, I would expect a file read/write with only "\n" to work, and when you load the file's text into your textarea they should show up. MS Notepad might have problems showing them.

Use jQuery to get the file input's selected filename without the path

I used this:
$('input[type=file]').val()
to get the file name selected, but it returned the full path, as in "C:\fakepath\filename.doc". The "fakepath" part was actually there - not sure if it's supposed to be, but this is my first time working with the filename of file uploads.
How can I just get the file name (filename.doc)?
var filename = $('input[type=file]').val().split('\\').pop();
or you could just do (because it's always C:\fakepath that is added for security reasons):
var filename = $('input[type=file]').val().replace(/C:\\fakepath\\/i, '')
You just need to do the code below. The first [0] is to access the HTML element and second [0] is to access the first file of the file upload (I included a validation in case that there is no file):
var filename = $('input[type=file]')[0].files.length ? ('input[type=file]')[0].files[0].name : "";
Get path work with all OS
var filename = $('input[type=file]').val().replace(/.*(\/|\\)/, '');
Example
C:\fakepath\filename.doc
/var/fakepath/filename.doc
Both return
filename.doc
filename.doc
Chrome returns C:\fakepath\... for security reasons - a website should not be able to obtain information about your computer such as the path to a file on your computer.
To get just the filename portion of a string, you can use split()...
var file = path.split('\\').pop();
jsFiddle.
...or a regular expression...
var file = path.match(/\\([^\\]+)$/)[1];
jsFiddle.
...or lastIndexOf()...
var file = path.substr(path.lastIndexOf('\\') + 1);
jsFiddle.
Here is how I do it, it works pretty well.
In your HTML do:
<input type="file" name="Att_AttributeID" onchange="fileSelect(event)" class="inputField" />
Then in your js file create a simple function:
function fileSelect(id, e){
console.log(e.target.files[0].name);
}
If you're doing multiple files, you should also be able to get the list by looping over this:
e.target.files[0].name
maybe some addition for avoid fakepath:
var fileName = $('input[type=file]').val();
var clean=fileName.split('\\').pop(); // clean from C:\fakepath OR C:\fake_path
alert('clean file name : '+ fileName);
How about something like this?
var pathArray = $('input[type=file]').val().split('\\');
alert(pathArray[pathArray.length - 1]);
This alternative seems the most appropriate.
$('input[type="file"]').change(function(e){
var fileName = e.target.files[0].name;
alert('The file "' + fileName + '" has been selected.');
});
Does it have to be jquery? Or can you just use JavaScript's native yourpath.split("\\") to split the string to an array?
<script type="text/javascript">
$('#upload').on('change',function(){
// output raw value of file input
$('#filename').html($(this).val().replace(/.*(\/|\\)/, ''));
// or, manipulate it further with regex etc.
var filename = $(this).val().replace(/.*(\/|\\)/, '');
// .. do your magic
$('#filename').html(filename);
});
</script>
Get the first file from the control and then get the name of the file, it will ignore the file path on Chrome, and also will make correction of path for IE browsers. On saving the file, you have to use System.io.Path.GetFileName method to get the file name only for IE browsers
var fileUpload = $("#ContentPlaceHolder1_FileUpload_mediaFile").get(0);
var files = fileUpload.files;
var mediafilename = "";
for (var i = 0; i < files.length; i++) {
mediafilename = files[i].name;
}
Here you can call like this
Let this is my Input File control
<input type="file" title="search image" id="file" name="file" onchange="show(this)" />
Now here is my Jquery which get called once you select the file
<script type="text/javascript">
function show(input) {
var fileName = input.files[0].name;
alert('The file "' + fileName + '" has been selected.');
}
</script>
var filename=location.href.substr(location.href.lastIndexOf("/")+1);
alert(filename);
We can also remove it using match
var fileName = $('input:file').val().match(/[^\\/]*$/)[0];
$('#file-name').val(fileName);

Categories