Markup and Execution of HTML, CSS and JavaScript from seperate textareas - javascript

I found a code for real time markup for HTML and CSS in different textareas using a jQuery function that outputs in an iframe:
HTML
<div class="container grid">
<form>
<h3>HTML</h3>
<textarea id="html" class="edit"></textarea> // TEXTAREA FOR HTML
<h3>CSS</h3>
<textarea id="css" class="edit"></textarea> // TEXTAREA FOR CSS
</form>
</div>
<div class="output grid">
<iframe></iframe>
</div>
JQUERY for markup
function() {
$(".grid").height($(window).height());
var contents = $("iframe").contents(),
body = contents.find("body"),
styleTag = $("<style></style>").appendTo(contents.find("head"));
$("textarea.edit").keyup(function() {
var $this = $(this);
if ($this.attr("id") === "html") {
body.html($this.val());
} else {
// it had to be css
styleTag.text($this.val());
}
});
})();
What if I wanted another textarea for javascript? I'm guessing you can't execute it in real time so I have to include a button to to run an eval()
But how?

In your HTML you can have another textarea for the javascript code.
In your textarea.edit event handler, you can add another check for javascript and use something like this -
$iframeEl.append(`<script>${textarea.val()}</script>`);
This line would execute your script as well because the browser re parses the document whenever it encounters a DOM change and it would also execute the script tag.
We should anyways refrain on using the eval keyword because it is an expensive operation and is advised not to be used.

Related

Enter a value in a "text/html" script via another script

Maybe this is a naive question but I wonder if there is a way to enter a value in a "text/html" script via another script, something like the following example which, by the way, does not work for me.
<script id="Block" type="text/html">
<input type="text" id="InputID"/>
</script>
<script>
document.getElementById('InputID').value = 'some text';
</script>
Setting the type of a <script> element to text/html is a hack for including some HTML source code in an HTML document without it being rendered so that you can later read the script element and do something with the HTML source code.
const raw_html = document.querySelector("script[type='text/html']").textContent;
This works because normal HTML rules do not apply to a script element, < has no special meaning there (in HTML 4 terms, the script element contains CDATA).
The modern equivalent is the <template> element.
You have no <input> element, so you can't find it in the DOM and you can't set a value to it.
If you want to do that, you first need to add it to the DOM.
const raw_html = document.querySelector("script[type='text/html']").textContent;
const container = document.querySelector("#container");
container.innerHTML = raw_html;
document.getElementById('InputID').value = 'some text';
<script id="Block" type="text/html">
<input type="text" id="InputID"/>
</script>
<div id="container"></div>

HTML not formatted inside div generating error

I have a cfm (ColdFusion) page where I display a #userHTML# variable's content inside my div.
<cfoutput>
<div class="panel panel-default" style="margin-left: 20px; margin-right: 20px;">
<div id="myDiv" class="panel-body">
#userHTML#
</div>
</div>
<br/><br/>
<div class="col-sm-8 col-sm-offset-2">
<!-- Some Code Here -->
</div>
</cfoutput>
Sometimes the #userHTML# variable has invalid HTML. It may contain open <div> tags that are not closed which makes the rest of the code where I have <div class="col-sm-8 col-sm-offset-2"> be inside the top div (id="myDiv")
Is there a way to make this work so that it doesn't matter what the #userHTML# variable contains, it will always have it's content inside the div "myDiv"?
The browser is designed to parse that HTML natively. If you require XML it will apply XML rules and importing incorrectly formated XML will error. If you use HTML, it will automatically correct the errors to the best of its ability (as is the case with all HTML documents.
To achive this you can do (please see comments in code):
// Create a new HTML Document (DOM)
var doc = document.implementation.createHTMLDocument ('', 'html', null);
// Add the body
var body = document.createElementNS('', 'body');
// Place the body into the DOM
doc.documentElement.appendChild(body);
// Get body parsed / corrected
body.innerHTML = "<div>This is a test";
// Now place that content into your existing DOM
document.getElementById('test').innerHTML = body.innerHTML;
// Get rid of the extra DOM
doc = null;
<div id="test">Test Div</div>
If you inspect the output HTML you will see the closing </div> has been added automatically.
You can use JSOUP to clean that HTML.
Get the relevant JAR file from either https://jsoup.org or http://central.maven.org/maven2/org/jsoup/jsoup/ and put it in you lib folder.
Then use JSOUP like
<cfset oJSOUP = CreateObject("java", "org.jsoup.Jsoup" )>
<cfset oJSOUPWL = CreateObject("java", "org.jsoup.safety.Whitelist" ).init()>
#oJsoup.clean(
javaCast( "string", userHTML ),
"http://example.com/",
oJSOUPWL.relaxed().preserveRelativeLinks( true )
)#
This removes unwanted HTML like unclosed DIVs.

Jquery function to change id name continues to run on other pages even thouigh i don't want it to

This behavior is happening on a intranet website structured for computer based training. I am using a function to change "id" name of a div using jquery on the fly on a single page.
$('#frameTextBg').attr('id','frameTextBg-horz');
It works fine. The problem is that when I navigate to another page, this functions continues to run and any page with div name #frameTextBg is being renamed to frameTextBg-horz.
I navigate to other pages using jquery to load pages inside a div. Note "var NextPage" is declared in each page by the authoring programs html export:
function NextPage() {
$('#content').load(nextPage)
};
How can I stop this function from running on other pages?
Thanks in advance.
Mark
Here are portions of the html markup relevant to the "outside" container that will load each page inside a div named #content.
...
<body class="mainBody" onLoad="resizeCBT();">
<div id="container">
<div id='content'></div>
<div id="footer">
<p id="footerP">LessonName</p>
<div id="footerPG">00 of 00</div>
<div id="footerNav"></div>
<div id="footerID" style="display:block" ></div>
<div id="control" name="control"><div>
</div>
<script type="text/javascript">
$('#content').load("Menu-0.htm");
$( "#control" ).load( "interface/control.htm #select1" );
document.getElementById('control').style.display="none";
</script>
</body>
...
Next are portions of the markup for a single page that runs the function to rename the id:
...
<script type="text/javascript">
var frame_id = 95675
var graphic_1 = "20.png"
var graphic_2 = ""
var nextPage = "a.htm"
var prevPage = "c.htm"
var thisPage = "b.htm"
var menuTitle = ""
var frameTitle = "title"
var sequence = 20
var totalFrames = 26
var manifestName = "No_Flash"
var instructText = ""
var audioFilename = ""
function runAfterPgLoad() {
$('#frameTextBg').attr('id','frameTextBg-off');
}
</script>
</head>
<body>
<div id="header">
<div id="header1"><h1 id="header1t">headerOne</h1></div>
<div id="header2"><h1 id="header2t">HeaderTwo</h1></div>
<div id="header3"></div>
</div>
<div id="GRAPHIC"><img src="20.png"></div>
<div id="TEXT" class="text">Text here.</div>
<div id="frameTextBg"></div>
<script type="text/javascript">
function NextPage() {
$('#content').load(nextPage)
};
function PrevPage() {
$('#content').load(prevPage)
};
document.getElementById('footerID').innerHTML = frame_id;
document.getElementById('footerPG').innerHTML = sequence + " of " + totalFrames;
if (typeof runAfterPgLoad == 'function') {
runAfterPgLoad();
}
</script>
</body>
</html>
Other pages DO NOT have the function:
function runAfterPgLoad() {
$('#frameTextBg').attr('id','frameTextBg-off');
}
Note that some markup has been omitted because this material cannot be disclosed. Sorry if I accidentally cut off any relevant markup.
You're using ajax to replace PARTS of your page. since you're not reloading the entire page, or using a normal "click to go to next page" system, that function will keep working until you tell it to stop, e.g.
var stop_it_already = false;
if (!stop_it_already) {
$('#frameTextBg').attr('id','frameTextBg-horz');
}
This isn't a definitive answer, because I'm still unclear about how exactly NextPage gets called.
You should never have different HTML elements with the same id. Since it's not something you're meant to do, I'm not even sure the specification for HTML says what should happen, so your page may behave differently on different browsers. Does $('#frameTextBg') represent all frameTextBg elements? Or does the browser only let it be one element and, if so, which one?
I used to work on a project which involved embedding lots of not-quite-identical copies of a website in another website. We had to change all the id attributes to CSS classes. Then, assuming all the frameTextBg elements are in different sections of the website, we could write $('.section-1 .frameTextBg'), $('.section-2 .frameTextBg'), etc.
Note "var NextPage" is declared in each page by the authoring programs html export
My client-side javascript is a little rusty, but I think that any declaration not inside a function definition just goes in the global scope anyway. This could cause problems with the latest copy of NextPage running instead of an earlier one. (But I can't tell because I don't see where NextPage is called from.)
You say you're reloading part of the page. Do you really need to reload the part with the <script> element?

Dynamically generated script not working

I have a contenteditable div where you type javascript which gets outputted into an empty script tag.
<div contenteditable="true" id="script-generator"></div>
<div id="save-script">Save</div>
<script type="text/shorthand" id="script">
</script>
So you write your script in the div, click save and I have some JS which gets the html of the contenteditable div and adds it to an empty script tag.
$('#save-script').click(function() {
var script = $('#script-generator').html();
$('#script').html(script);
});
So far this works. But the generated script has no effect. The browser must not recognise the script because it wasn't there on page load? How do I make the script take effect without reloading the page?
Note: The type/shortand on the script is because I'm using a plugin which converts shortand words into actual Javascript. So the user would just need to write shorthand into the contenteditable div, and the plugin would convert that to JS. This might be adding to the problem?
I don't think it works to modify an existing <script> element. If you want the script to be executed you need to add a new element.
$('#save-script').click(function() {
var script = $('#script-generator').html();
$("#script").text(script);
ShortHand.parseScripts();
});
Correct - you need to create the script tag to have it execute after load.
$('head').append($('<script />', {html: script}));
...which means you can remove your empty script tag.
I have set up a test that's similar to what you have been looking for. Take a look and see if that helps.
Working Demo
Test code:
<div id="script" style="display:none">
alert(4+4);
</div>
<input id="sLoad" type="button" value="Load/Execute Script" />
$('#sLoad').click(function(){
//You may want to append to the head
$('<script/>').append( $('#script').html() ).appendTo('#script');
});

output with javascript/jquery

I have a script that runs within the body. How can I make it output directly after itself. Similar to echo in php.
e.g.
<div id="text">Text</div>
<div id="someotherdiv">
The text above says
<script>
$('#text').html().echo?;
</script>
</div>
You're looking for document.write, like this:
document.write($('#text').html());
EDIT: document.write will only work while the page is loading (as opposed to in an event handler or timer).
To append content later, use jQuery:
$('#someotherdiv').append($('#text').html());

Categories