I am trying to separate some JS code that is embedded in to a HTML file. I do not own this code, it is for a remote support landing page but I'm not sure how to separate them out.
I have tried copying the JS code in to a different .js file and then adding the script tags to link but no luck.
<script type="text/javascript" src="https://www.islonline.net/webapi/api.js?
libs=join"></script>
<div class="isl-connect-form">
<form id="isl-connect-form" action="#" method="get" onsubmit="return
isl_connect();">
<fieldset>
<legend>Enter your session code and click Connect</legend>
<div>
<label for="isl-code-field">Session code</label>
<input type="text" name="code" id="isl-code-field" value="" />
</div>
<input type="submit" name="submit" value="Connect" />
</fieldset>
</form>
<div id="isl-feedback"></div>
</div>
<script type="text/javascript">
function isl_connect() {
var doc = document,
f = doc.getElementById('isl-connect-form'),
r = doc.getElementById('isl-feedback'),
is_msie = navigator.userAgent.indexOf('MSIE') >= 0,
b = null;
ISLOnline.Join.getSessionInfoByCode(
f.code.value,
function (info) {
r.className = 'isl-success';
r.innerHTML = 'Connecting to session ' +
info.getAttribute('sessionCode');
if (is_msie) {
r.innerHTML += ', please click the button below:<br />';
r.appendChild(doc.createElement('br'));
var b = doc.createElement('input');
b.type = 'button';
b.name = 'join';
b.value = 'Start';
b.onclick = function () {
info.join();
};
r.appendChild(b);
} else {
info.join();
}
},
function (error) {
r.className = 'isl-error';
r.innerHTML = 'Invalid session code!';
/* comment the line above and uncomment the line below if you
wish to
display the error that is sent by the server */
//r.innerHTML += error.getDescription();
}
);
return false;
}
Create a new JS file and put the original full javascript within it then load it after the islonline.net API call. I have shown an example.
<script type="text/javascript" src="https://www.islonline.net/webapi/api.js?libs=join"></script>
<div class="isl-connect-form">
<form id="isl-connect-form">
<fieldset>
<legend>Enter your session code and click Connect</legend>
<div>
<label for="isl-code-field">Session code</label>
<input type="text" name="code" id="isl-code-field" value="" />
</div>
<input type="submit" name="submit" value="Connect" />
</fieldset>
</form>
<div id="isl-feedback"></div>
</div>
<!-- your new external JS file -->
<script type="text/javascript" src="https://www.example.com/path/to/your/file.js"></script>
Your new Javascript file will contain the original JS code, with a slight modification to help separate HTML and JavaScript by using addEventListener instead of onsubmit:
document.getElementById('isl-connect-form').addEventListener('submit', function isl_connect(event) {
if (typeof event.preventDefault == 'function') event.preventDefault();
var doc = document,
f = this,
r = doc.getElementById('isl-feedback'),
is_msie = navigator.userAgent.indexOf('MSIE') >= 0,
b = null;
ISLOnline.Join.getSessionInfoByCode(
f.code.value,
function (info) {
r.className = 'isl-success';
r.innerHTML = 'Connecting to session ' +
info.getAttribute('sessionCode');
if (is_msie) {
r.innerHTML += ', please click the button below:<br />';
r.appendChild(doc.createElement('br'));
var b = doc.createElement('input');
b.type = 'button';
b.name = 'join';
b.value = 'Start';
b.onclick = function () {
info.join();
};
r.appendChild(b);
} else {
info.join();
}
},
function (error) {
r.className = 'isl-error';
r.innerHTML = 'Invalid session code!';
/* comment the line above and uncomment the line below if you wish to
* display the error that is sent by the server
*/
//r.innerHTML += error.getDescription();
}
);
return false;
});
Related
I have been struggling for a couple days to build a simple interface for my colleagues to record every customer interaction. They will input the following:
Name of Customer (Autocomplete feature, from a superset of all names in a column in the spreadsheet)
Date of Interaction
Summary of the Interaction
Prospects (Hot, Warm, Tepid, Cold)
My problem is in getting the Autocomplete working.
I have seen threads where #Tanaika has beautifully laid down the Server Side, HTML+JS, etc. but I am unable to get this to work. My files are attached. Thanks for your time!
HTML+JS
<!DOCTYPE html>
<html>
<head>
<style>
label {
display: inline-block;
width: 150px;
}
</style>
<base target="_top">
<script>
function submitForm() {
google.script.run.appendRowFromFormSubmit(document.getElementById("feedbackForm"));
document.getElementById("form").style.display = "none";
document.getElementById("thanks").style.display = "block";
}
</script>
</head>
<body>
<datalist id="datalist">
<?!
var url = "https://docs.google.com/spreadsheets/d/13Ms0Cny3f-XaXS26s5AnrDT4H9c8p8OKRfwxPIQ9_CU/edit#gid=16760772";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Pipeline");
var rng = ws.getRange('D2:D')
var rangeArray = rng.getValues();
var filArray = rangeArray.filter(function (el) {return el[0] != ""}).flat(); // Modified
console.info("hello read the data");
for (var i = 0; i < datalist.length; i++) { !?>
<option value="<?= datalist[i] ?>">
<?! } !?>
</datalist>
<div>
<div id="form">
<h1>Record Interaction</h1>
<form id="feedbackForm">
<label for="name">Parent Name</label>
<input type="text" id="name" name="name" list="datalist"><br><br>
<label for="doi">Date of Interaction</label>
<input id="today" type="date" name="doi"><br><br>
<label for="feedback">Interaction Summary</label>
<textarea rows=4 cols=35 id="feedback" name="feedback">Enter Interaction Summary Here...
</textarea><br><br>
<div>
<label for="temperature">Likely Candidate?</label><br>
<input type="radio" id="Hot" name="temperature" value="Hot">
<label for="yes">Hot</label><br>
<input type="radio" id="Warm" name="temperature" value="Warm">
<label for="yes">Warm</label><br>
<input type="radio" id="Tepid" name="temperature" value="Tepid">
<label for="yes">Tepid</label><br>
<input type="radio" id="Cold" name="temperature" value="Cold">
<label for="no">Cold</label><br><br>
<input type="button" value="Submit Interaction" onclick="submitForm();">
</form>
</div>
</div>
<div id="thanks" style="display: none;">
<p>Thank you for speaking to our customers!</p>
</div>
</body>
</html>
CODE.GS
function onOpen() {
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.createMenu('Customer Engagement')
.addItem('Record Interaction', 'showDialog')
.addToUi();
}
function showDialog() {
var html = HtmlService.createHtmlOutputFromFile('RecordInteraction.html')
.setWidth(400)
.setHeight(600);
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.showModalDialog(html, 'Please Enter Details');
}
function readData() {
var url = "https://docs.google.com/spreadsheets/d/13Ms0Cny3f-XaXS26s5AnrDT4H9c8p8OKRfwxPIQ9_CU/edit#gid=16760772";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Pipeline");
var rng = ws.getRange('D2:D')
var rangeArray = rng.getValues();
var filArray = rangeArray.filter(function (el) {return el[0] != ""}).flat(); // Modified
console.info("hello read the data")
return filArray;
}
function activateSheetById(sheetId) {
//Access all the sheets in the Google Sheets spreadsheet
var sheets = SpreadsheetApp.getActive().getSheets();
//Filter out sheets whose Ids do not match
var sheetsForId = sheets.filter(function(sheet) {
return sheet.getSheetId() === sheetId;
});
//If a sheet with the Id was found, activate it
if(sheetsForId.length > 0)
sheetsForId[0].activate();
}
function appendRowFromFormSubmit(form) {
var row = [form.name, form.doi, form.feedback, form.temperature];
console.info("Appending Row");
activateSheetById(2059810756);
SpreadsheetApp.getActiveSheet().appendRow(row);
}
function makeUL(array) {
// Create the list element:
var namelist = document.createElement('ul');
for (var i = 0; i < array.length; i++) {
// Create the list item:
var item = document.createElement('li');
// Set its contents:
item.appendChild(document.createTextNode(array[i]));
// Add it to the list:
list.appendChild(item);
}
// Finally, return the constructed list:
return namelist;
}
Modification points:
In your HTML, the template is used. In this case, please use createTemplateFromFile instead of createHtmlOutputFromFile.
The scriptlet of <?!= ... ?> is Force-printing scriptlets (like printing scriptlets except that they avoid contextual escaping.). Ref
I thought that these are the reasons for your issue. When these points are reflected to your script, it becomes as follows.
Modified script:
Google Apps Script side:
From:
function showDialog() {
var html = HtmlService.createHtmlOutputFromFile('RecordInteraction.html')
.setWidth(400)
.setHeight(600);
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.showModalDialog(html, 'Please Enter Details');
}
To:
function showDialog() {
var html = HtmlService.createTemplateFromFile('index.html');
html.data = readData();
SpreadsheetApp.getUi().showModalDialog(html.evaluate().setWidth(400).setHeight(600), 'Please Enter Details');
}
Here, your function of readData() is used.
HTML and Javascript side:
From:
<datalist id="datalist">
<?!
var url = "https://docs.google.com/spreadsheets/d/###/edit#gid=16760772";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Pipeline");
var rng = ws.getRange('D2:D')
var rangeArray = rng.getValues();
var filArray = rangeArray.filter(function (el) {return el[0] != ""}).flat(); // Modified
console.info("hello read the data");
for (var i = 0; i < datalist.length; i++) { !?>
<option value="<?= datalist[i] ?>">
<?! } !?>
</datalist>
To:
<datalist id="datalist">
<? data.forEach(e => { ?>
<option value="<?= e ?>">
<? }); ?>
</datalist>
Reference:
HTML Service: Templated HTML
Example of making suggestions to a email dialog
html:
<div id="emaildialog">
Recipient Search:<br />
<input id="rec" type="text" oninput="getSuggestions();" placeholder="Enter Search String slowly. Yellow=accessing server" size="50" /><br />
Suggestions:<br />
<div id="sugdiv" style="width:100%;background-color:#ffffff;"></div>
Recipients:<br />
<textarea id="recipients" cols="50" rows="4" placeholder="Sent to first recipient. Remaining recipients are blind copied."></textarea><br />
Message:<br />
<textarea id="msg" cols="50" rows="4" placeholder="Enter message to send with the attachments." >This is a copy of our apps Final Report.</textarea><br>
<input type="button" id="send" value="Create PDF and Send Email" onClick="createAndSendReport();" />
</div>
Javascript(With JQuery):
function updateDiv(vA){
var s='';
for(var i=0;i<vA.length;i++){
s+='<input type="button" id="btn-' + i + '" onClick="selectRecipient1(\'btn-' + i + '\')" value="' + vA[i][0] + '" />';
}
$('#sugdiv').html(s);
}
function getSuggestions(){
var txt=$('#rec').val();
if(txt.length>0){
$('#rec').css('background','yellow');
google.script.run
.withSuccessHandler(function(vA){
$('#rec').css('background','white');
//updateSelectList(vA);
updateDiv(vA);
})
.getSuggestions(txt)
}else{
updateSelectList([]);
}
}
Google Apps Script:
function getSuggestions(s){
if(s){
var vA=[];
var cA=getAllContacts();
for(var i=0;i<cA.length;i++){
if(cA[i].toString().toLowerCase().indexOf(s.toLowerCase())>-1){
vA.push([cA[i][0]]);
}
}
}
return vA;
}
This code is about 5 years old. It's still running in the original application
Already tried everything from different references but, I can't get it to work. I intended to use it for google photo submission form. I just want my text inputs and textarea to clear after it successfully uploaded everything.
Here's the whole HTML code.
<form id="uploaderForm">
<label for="uploaderForm">Photo Upload Form</label>
<div>
<input type="text" name="applicantName" id="applicantName"
placeholder="Your Name">
</div>
<div>
<input type="text" name="gradesection" id="gradesection"
placeholder="Your Grade Level & Section">
</div><br>
<div>
You can select multiple Photos upload!<br>
<br>
<input type="file" name="filesToUpload" id="filesToUpload" multiple>
<br><br>
<input type="button" value="Submit" onclick="uploadFiles()">
</div>
</form>
<br>
<br>
<div id="output"></div>
<script>
var rootFolderId = 'xxxxxxxxxxxxxxxxxxx';
var numUploads = {};
numUploads.done = 0;
numUploads.total = 0;
// Upload the files into a folder in drive
// This is set to send them all to one folder (specificed in the .gs file)
function uploadFiles() {
var allFiles = document.getElementById('filesToUpload').files;
var applicantName = document.getElementById('applicantName').value;
if (!applicantName) {
window.alert('Missing applicant name!');
}
var gradesection = document.getElementById('gradesection').value;
if (!gradesection) {
window.alert('Missing Grade & Section!');
}
var folderName = applicantName + ' - ' + gradesection;
if (allFiles.length == 0) {
window.alert('No file selected!');
} else {
numUploads.total = allFiles.length;
google.script.run.withSuccessHandler(function(r) {
// send files after the folder is created...
for (var i = 0; i < allFiles.length; i++) {
// Send each file at a time
uploadFile(allFiles[i], r.folderId);
}
}).createFolder(rootFolderId, folderName);
}
}
function uploadFile(file, folderId) {
var reader = new FileReader();
reader.onload = function(e) {
var content = reader.result;
document.getElementById('output').innerHTML = 'uploading '
+ file.name + '...';
//window.alert('uploading ' + file.name + '...');
google.script.run.withSuccessHandler(onFileUploaded)
.uploadFile(content, file.name, folderId);
}
reader.readAsDataURL(file);
}
function onFileUploaded(r) {
numUploads.done++;
document.getElementById('output').innerHTML = 'uploaded '
+ r.fileName + ' (' + numUploads.done + '/'
+ numUploads.total + ' files).';
if (numUploads.done == numUploads.total) {
document.getElementById('output').innerHTML = 'All of the '
+ numUploads.total + ' files are uploaded';
numUploads.done = 0;
}
}
</script>
The form upload and displays the response to the user.
I want to reset the form so, the form resets to its original state, so when the user upload another file it wont upload the same file again. Right now, the submission message stays and I have no clue on how to reset the form.
I am new to javascript and I have no clue on what to call to rest the form, any idea? TIA Guys :)
As your code snippet only contains input, You can find all inputs using querySelectorAll and reset its value.
Example below. When you click the button it resets all the input.
function resetAllInput() {
const allInput = document.querySelectorAll('input');
allInput.forEach( input => {
input.value = "";
})
}
function uploadFiles() {
console.log('uploading files');
resetAllInput();
console.log('Resetted all inputs');
}
<form id="uploaderForm">
<label for="uploaderForm">Photo Upload Form</label>
<div>
<input type="text" name="applicantName" id="applicantName" placeholder="Your Name">
</div>
<div>
<input type="text" name="gradesection" id="gradesection" placeholder="Your Grade Level & Section">
</div><br>
<div>
You can select multiple Photos upload!<br>
<br>
<input type="file" name="filesToUpload" id="filesToUpload" multiple>
<br><br>
<input type="button" value="Submit" onclick="uploadFiles()">
</div>
</form>
You can assign null value to your input element:
const reset = () => {
let fileInput = document.getElementById('file-input');
fileInput.value = null;
}
<input type="file" id="file-input">
<button onclick="reset()">Reset</button>
I have a typical Google App Html form that records the data entered in a spreasheet.
Here are the files.
HTML Form:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<?!= include("css");?>
</head>
<body>
<h2>Feedback Form</h2>
<div id="message"></div>
<!--- BUTTON New registration --->
<br /><input id="button-responder" type ="button" value = "New registration"
onclick="submitResponder('button-responder'),
submitTransition('message');" style="display:none;" />
<!--- FORM --->
<form id="my-form">
<br /><input id="name" type="text" name="name" placeholder="Your Name">
<br /><input id="email" type="email" name="email" placeholder="Your Email">
<br /><textarea id="comment" rows="10" cols="40" name="comment"></textarea>
<!--- BUTTON submitForm --->
<br /><input id="btn" type="button" value="Submit"
onclick="submitForm(this.parentNode),
document.getElementById('my-form').style.display='none',
submitResponder('button-responder'),submitTransition('message');" />
</form>
<?!= include("test-js");?>
</body>
</html>
Google Script:
function doGet(request) {
return HtmlService.createTemplateFromFile('index')
.evaluate();//not all caps but it has to match the name of the file and it doesn't - Change to PAGE
}
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename)
.getContent();
}
function submitData(form) {
var subject='New Feedback';
var body=Utilities.formatString('name: %s <br />Email: %s<br />Comment: %s', form.name,form.email,form.comment);
var folderId = "my-folder-ID"; // Please set the folder ID. // Added
var blob = Utilities.newBlob(body, MimeType.HTML, form.name).getAs(MimeType.PDF); // Added
var file = DriveApp.getFolderById(folderId).createFile(blob); // Added
return Utilities.formatString('name: %s <br />Email: %s<br />Comment: %s<br />
PDF: <a target="_blank" href="%s">see your PDF file</a>',
form.name,form.email,form.comment,file.getUrl());
function userClicked(userInfo){
var url = "https://docs.google.com/spreadsheets/d/my-spreadsheet-ID";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Data");
ws.appendRow([userInfo.name, userInfo.email, userInfo.comment]);
}
test-js
<script>
function submitForm(form) {
google.script.run
.withSuccessHandler(function(value){
document.getElementById('message').innerHTML = value;
document.getElementById('name').value = '';
document.getElementById('email').value = '';
document.getElementById('comment').value = '';
})
.submitData(form);
}
function submitResponder() {
var x = document.getElementById("button-responder");
var xx = document.getElementById("my-form");
var xxx = document.getElementById("message");
if (x.style.display === "none") {
x.style.display = "block";
xx.style.display = "none";
xxx.style.display = "block";
} else {
x.style.display = "none";
xx.style.display = "block";
xxx.style.display = "none";
}
}
function submitTransition() {
setTimeout(function() {
document.getElementById('message').style.color = 'blue';}, 2500);
}
document.getElementById("btn").addEventListener("click",doStuff);
function doStuff(){
var userInfo = {}
userInfo.name = document.getElementById("name").value;
userInfo.email = document.getElementById("email").value;
userInfo.comment = document.getElementById("comment").value;
google.script.run.userClicked(userInfo);
document.getElementById("name").value= "";
document.getElementById("email").value= "";
document.getElementById("comment").value= "";
}
</script>
css:
<style>
#message {
color: transparent;
}
</style>
QUESTION
Now in Google Script file function
function submitData (form)
and in test-js file function
function doStuff ()
they do their job well but with a latency of around 2.5s
then for Google Script to file the function
return Utilities.formatString
can show the result (name - email - comment - PDF Url)
its conclusion must be awaited, 2.5s.
Functions in variables.
In test-js file function
function submitResponder ()
makes the fields linked to the ID (message) visible with variables
name: example-name
email: example-email
comment: example-comment
PDF: see your example-PDF file
and the field linked to the ID (button-responder)
"New registration" button
Then upon loading the index.html page
the form and the "submit" button are shown,
edit the fields by clicking on submit
the form is hidden, the "New registration" button appears
and after about 2.5s the edited fields (name-email ....) also appear.
Click on the button "New registration" below
the form reappears as at the beginning, clearly not with a reload page, but simply with
display = "none"
display = "block"
Now here's the problem I can't solve:
By re-editing the fields and clicking again on submit-form
the fields edited the previous time appear again immediately
name: example-name
email: example-email
comment: example-comment
PDF: see your example-PDF file
and after about 2.5s they update with the new edited fields
name: new-name
email: new-email
comment: new-comment
PDF: see your new-PDF file
Now with the function
function submitTransition () {
setTimeout (function () {
document.getElementById ('message'). style.color = 'blue';}, 2500); }
and with style
#message { color: transparent; }
I'm trying to find a solution to delay (hide) the display of the old fields until the new ones are updated.
It is certainly not the right way.
I hope I have been clear in the explanation, your help will be very much able.
Thanks in advance.
You want to show the texts and button of "New registration" after "submit" button was clicked and the script of submitData was finished.
If my understanding is correct, how about this modification?
The reason of your issue is that google.script.run is run with the asynchronous process. By this, before the script of submitData is finished, document.getElementById('my-form').style.display='none', submitResponder('button-responder') and submitTransition('message') are run.
Modified script:
Please modify your script as follows.
From:
<br /><input id="btn" type="button" value="Submit"
onclick="submitForm(this.parentNode),
document.getElementById('my-form').style.display='none',
submitResponder('button-responder'),submitTransition('message');" />
To:
<br /><input id="btn" type="button" value="Submit" onclick="submitForm(this.parentNode)" />
And
From:
function submitForm(form) {
google.script.run
.withSuccessHandler(function(value){
document.getElementById('message').innerHTML = value;
document.getElementById('name').value = '';
document.getElementById('email').value = '';
document.getElementById('comment').value = '';
})
.submitData(form);
}
To:
function submitForm(form) {
google.script.run
.withSuccessHandler(function(value){
document.getElementById('message').innerHTML = value;
document.getElementById('name').value = '';
document.getElementById('email').value = '';
document.getElementById('comment').value = '';
document.getElementById('my-form').style.display='none'; // Added
submitResponder('button-responder'); // Added
submitTransition('message'); // Added
})
.submitData(form);
}
And, by above modification, you can also remove setTimeout as follows.
From:
function submitTransition() {
setTimeout(function() {
document.getElementById('message').style.color = 'blue';}, 2500);
}
To:
function submitTransition() {
document.getElementById('message').style.color = 'blue';
}
Reference
Class google.script.run (Client-side API)
google.script.run is an asynchronous client-side JavaScript API available in HTML-service pages that can call server-side Apps Script functions.
If I misunderstood your question and this was not the result you want, I apologize.
First of all , I have no idea of javascript, I got this code from a tutorial.
I am developing a website in ruby , and to do that I need to make a form of payment. I'm currently using the API Mango.
I have the following code:
<form id="form" action="/pay" method="POST">
<fieldset>
<div>
<label for="ccv">Código de seguridad</label>
<input type="text" id="ccv" required>
</div>
</fieldset>
<input type="submit" value="Pagar ahora!">
</form>
<div id="errores">
</div>
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://js.getmango.com/v1/mango.js"></script>
<script>
var PUBLIC_API_KEY = 'public_test_u3wbj4jctik1k2u8qtnajhvn82h590ue';
Mango.setPublicKey(PUBLIC_API_KEY);
var submission = false;
var $form = $('#form');
$form.on('submit', function(event) {
if (submission) {
return false;
}
submission = true;
var cardInfo = {
'ccv': $('#ccv').val()
};
Mango.token.create(cardInfo, handleResponse);
return false;
});
function handleResponse(err, data) {
submission = false;
//Here I put an error message that's displayed in html
if (err) {
...
}
var token = data.uid;
var $hidden = $('<input type="hidden" name="token">');
$hidden.val(token);
$form.append($hidden);
$form[0].submit();
}
</script>
How I can capture that error and show it in html ?
function handleResponse(err, data) {
submission = false;
//Here I put an error message that's displayed in html
if (err) {
...
}
var token = data.uid;
var $hidden = $('<input type="hidden" name="token">');
$hidden.val(token);
$form.append($hidden);
$form[0].submit();
}
this function - is an event handler for Response,obviously. First param is error and if this will be passed your if(err) code block will be executed.
As i see - you use JQuery, so in this place you can Insert some code, which will show error into your form.
For example $('form').append('<div class="error">Some error occurs</div>');
You could try something like
$('body').append($errorp);
I am building a rich text editor and want to autosave the text in the iframe.
I have multiple code parts and snippets which – taken by itself – are working perfectly but I am failing to assemble them correctly. LIVEDEMO
Here is a graphic of what I want to achieve:
I have an editable iFrame which is my text editor. The innerHTML of this iFrame should be loaded into a textarea hidden under the iframe and the content of the textarea should be saved in the localStorage regularly.
The iFrame code works.
<script>
function iFrameOn() {
richTextField.document.designMode = 'On';
}
function iBold() {
richTextField.document.execCommand('bold', false, null);
}
function iUnderline() {
richTextField.document.execCommand('underline', false, null);
}
function iItalic() {
richTextField.document.execCommand('italic', false, null);
}
function iFontSize() {
var size = prompt('Enter a size 1-7', '')
richTextField.document.execCommand('FontSize', false, size);
}
function iForeColor() {
var color = prompt('Define a basic color or apply a hexadecimal color code for advanced colors:', '')
richTextField.document.execCommand('ForeColor', false, color);
}
function iHorizontalRule() {
richTextField.document.execCommand('InsertHorizontalRule', false, null);
}
function iUnorderedList() {
richTextField.document.execCommand('InsertUnorderedList', false, "newUL");
}
function iOrderedList() {
richTextField.document.execCommand('InsertOrderedList', false, "newOL");
}
function iLink() {
var linkURL = prompt('Enter the URL for this link:', 'http://')
richTextField.document.execCommand('CreateLink', false, linkURL);
}
function iUnLink() {
richTextField.document.execCommand('UnLink', false, null);
}
function iImage() {
var imgSrc = prompt('Enter image location:', '');
if(imgSrc != null){
richTextField.document.execCommand('insertimage', false, imgSrc);
}
}
</script>
<body onLoad="iFrameOn();">
<h2>Text Editor</h2>
<form action="my_parse_file.php" name="myform" id="myform" method="post" onLoad="autosave_form();">
<fieldset>
<p>Entry Title: <input name="title" id="title" type="text" size="80" maxlength="80" /></p>
<p>Entry Body:<br />
<div id="wysiwyg_cp" style="padding: 8px; width: 700px;">
<input type="button" onClick="iBold()" value="B" />
<input type="button" onClick="iUnderline()" value="U" />
<input type="button" onClick="iItalic()" value="I" />
<input type="button" onClick="iFontSize()" value="Text Size" />
<input type="button" onClick="iForeColor()" value="Text Color" />
<input type="button" onClick="iHorizontalRule()" value="HR" />
<input type="button" onClick="iUnorderedList()" value="UL" />
<input type="button" onClick="iOrderedList()" value="OL" />
<input type="button" onClick="iLink()" value="Link" />
<input type="button" onClick="iUnLink()" value="UnLink" />
<input type="button" onClick="iImage()" value="Image" />
</div>
<textarea style="display: none;" name="myTextArea" id="myTextArea" cols="100" rows="14"></textarea>
<iframe name="richTextField" id="richTextField" style="border: #000000 1px solid; width: 700px; height: 300px"></iframe>
</p><br />
<input name="myBtn" type="button" value="Submit Data" onClick="javascript:submit_form();"/>
</fieldset>
</form>
</body>
The autosaver also works – but only with the textarea and not the iFrame.
// get the state of the form
function getFormState() {
var fields = document.getElementsByTagName('form')[0].elements;
if (fields.length == 0){return};
for (var i = 1; i <= fields.length-1; i++) {
var name = fields[i].getAttribute('name');
if (name in localStorage && localStorage[name] !== null) {
fields[i].value = localStorage[name];
}
}
}
// save the state of the form
function saveFormState() {
var fields = document.getElementsByTagName('form')[0].elements;
if (fields.length == 0){return};
var populated = false;
for (var i = 1; i <= fields.length-1; i++) {
var name = fields[i].getAttribute('name');
if (fields[i].value != '' && fields[i].getAttribute('type') != 'submit') {
localStorage[name] = fields[i].value;
populated = true;
}
}
// display the time form data was saved (optional)
if (populated) {
var date = new Date();
var hours = date.getHours();
var mins = date.getMinutes();
var secs = date.getSeconds();
hours = (hours < 10) ? '0' + hours : hours;
mins = (mins < 10) ? '0' + mins : mins;
secs = (secs < 10) ? '0' + secs : secs;
var msg = '[Form data was saved at ' + hours + ':' + mins + ':' + secs + ']';
var timecont = document.getElementById('time_container');
if (timecont !== null) {
timecont.innerHTML = msg;
}
else {
timecont = document.createElement('span');
timecont.setAttribute('id', 'time_container');
timecont.appendChild(document.createTextNode(msg));
document.getElementsByTagName('fieldset')[0].appendChild(timecont);
}
}
}
// run the above functions when the web page is loaded
window.onload = function () {
// check if HTML5 localStorage is supported by the browser
if ('localStorage' in window && window['localStorage'] !== null) {
// get the form state
getFormState();
// save the state of the form each 15 seconds (customizable)
setInterval('saveFormState()', 15 * 1000);
}
}
And now I need some binding code which loads the innerHTML of the iFrame routinely into the textarea.
function autosave_form() {
var theForm = document.getElementbyID('myform');
theForm.elements["myTextArea"].value = window.frames['richTextField'].document.body.innerHTML;
setTimeout(yourFunction, 5000);
}
So where are my fellacies? Or what did I overlook? Please help.
LIVEDEMO
You're not using the interface on the iframe object correctly. To get the content of an iframe on the same domain, you need to go through the contentWindow field. For example:
function read_iframe() {
return window.frames['richTextField'].contentWindow.document.body.innerHTML;
}
Remember that you cannot read the content of an iframe on another domain.
You can find complete docs on the HTMLIFrameElement's methods and fields at https://developer.mozilla.org/en/docs/Web/API/HTMLIFrameElement
Edited!
It seems like iframe is the common way of creating html editors.
I am sure that the explanations here will assist you.
~~~
I am not sure you can access the iframe's innerHTML since it would be cross-site scripting, which is prohibited for security reasons. Access the iframe content using javascript might result in access denied errors.