a few questions regarding innerHTML - javascript

I am converting an old programmer's joke program created here in Brazil that is simmilar to MIT's SCIgen but using artistic jargon instead of businnes gibberish.
As the program is far too old (geocities era old) it uses lots of document.write instead of innerHTHML of course.
First question is, is it safe to place like tons of code inside of innerHTMLs? As the original program loads 4 sets of arrays with every possible piece of text that can be combined to form a pseudo-essay, this is a piece of code:
new_window.document.write("<body bgcolor=\"#000000\">");
new_window.document.write("<body text=\"#00FF00\">")
new_window.document.write("<p align=\"center\"><b>"+atitle+"</b><hr></p>");
firstshot = 1;
paragraph = 0;
while(lines > 0) {
if (firstshot == 1) {
if (lines % 101 == 0 && lines % 19 == 0) {
new_window.document.write(tab0.chr(1,0)+tab0.chr(0,1)+tab3.chr(0,0)
.....
...
this continues in a inch long non nested chunk of code, the entire code is here http://jsfiddle.net/jmqdx09g/
I'm experimenting and this is what I got so far:
<body>
<div id="target"></div>
<div id = "myDiv"></div>
<span id = "mySpan"></span>
<br>
<button id="restore">restore</button>
<p> </p>
<form name="form1" method="post" action="">
<input type="submit" name="remove" id="remove" value="remove">
</form>
<p> </p>
</body>
<script type = "text/javascript">
var message =
'<li>Home</li>'+
'<li>About</li>'+
'<li>Contact</li>'+
'<li>Works</li>'+
' <li>Projects</li>'+
'<li>Curriculum</li>'
var message2 =
'<div class="content">'+
'<iframe src="/yourpage.html" frameborder="0" width="600" height="650" scrolling="no">'+
'<p>Your browser does not support iframes.</p>'+
'</iframe></div>'
document.getElementById("myDiv").innerHTML = message; // use innerHTML for block and inline HTML elements
document.getElementById("remove").addEventListener("click", function ()
{
document.getElementById("myDiv").innerHTML = message2;
});
document.getElementById("restore").addEventListener("click", function ()
{
document.getElementById("myDiv").innerHTML = message;
});
and it works as expected which is load a few html stuff, on a press of a button stuff is replaced by an iframe
is the iframe the best solution for this or replacing the entire html with js is the way to go?
the
var message =
'somecode'+
'somecode'+
looks safe until now, but as far as I get into the converting, am I going to have headaches or this method is straight forward as it looks like?
should I use window.onload instead of replacing the content holder div?

My two cents worth...
Is it safe to place like tons of code inside of innerHTMLs?
Safe, yes... Easily maintainable, no. Front end code is for the client so if they choose to hack themselves let them... Of course anything that is sent back to the server should be sanitised and not trusted, but that is a completely different issue.
In my opinion the greatest problem is maintainability.
Next the JS, refactor this into a separate file, start caching variables makes the code easier to look at.
Finally, do you need the iFrame? Or a new window? Couldn't you simply append the "artistic jargon" to the bottom of the current html? Thus saving the headache of the iframes.
I am a complete advocate of non-jQuery, but maybe for you using jQuery's HTML editing API might be a great idea. Could help to abstract some issues into a more readable and maintainable form. Then again, vanilla JS is really awesome and if it can be done that way its a great way to learn.

Related

How can I get an HTML tag’s value to send an HTML.Action()

I have these lines of code:
<span
class="close-modal"
onclick="#Html.Action("SaveNotes", "CallCenter", new { activityId = item.callIdKey, noteText = "test1" })">
×
</span>
Notes: <br />
<textarea name="paragraph_text" rows="5" style="width:90%">
#item.NoteText
</textarea>
I would like to replace test1 from the noteText route variable and instead change it to whatever the value in the <textarea> tag is.
Is there an elegant way of doing this without writing a giant block of jQuery code?
#Html.Action() renders a partial view as an HTML string during page processing (on the server side). It doesn't exist any more in the markup, once the page is sent to the browser. You can't do what you are trying to do this way. At the very least, I'm sure you don't want to render a partial view inside the onclick event of your <span> tag.
Why not instead use an HTML helper for the <textarea> tag? Then you can get whatever value the user typed into it on the server code. You'll want to make the form post itself back to the server on the close-modal element:
<span class="close-modal" onclick="$('form').submit()">×</span>
<form method="post" action="#Url.Action("SaveNotes", "CallCenter", new { activityId=item.callIdKey }">
Notes: <br />
#Html.TextArea("noteText", item.NoteText, new { rows="5", style="width:90%" })
</form>
This assumes you have jQuery already (a common assumption with ASP.NET). You may not need the <form> tags if you already have a form on your page.
A #gunr2171 notes in the comments, the only way to dynamically update a link once it's been rendered to the browser is via some form of client-side scripting, typically JavaScript. In your case, I'd recommend doing something like this:
<span
class="close-modal"
data-href-template="#Url.Action("SaveNotes", "CallCenter", new {activityId = item.callIdKey, noteText="{note}"})"
>
×
</span>
Note: As #HBlackorby notes in his answer, you shouldn't be using #Html.Action() here; I assume you meant #Url.Action().
This way, your JavaScript has a template (data-href-template) that it can work against with a clearly defined token ({note}) to replace, instead of needing to parse the URL in order to identify where the previously replaced text is. Otherwise, you potentially end up in a scenario where you type e.g. CallCenter into your <textarea /> and it's now an ambiguous reference that you can't just blindly replace. Or, worse, you type 'a' and it's really ambiguous.
If you are already using jQuery on your site, the actual replacement might be done using something along the lines of:
$(document).ready(function () {
$('span.close-modal').click(function() {
var noteInput = $('textarea[name="paragraph_text"]');
var encodedNote = encodeURI(noteInput.text());
var template = $(this).data("href-template");
var targetUrl = template.replace("{note}", encodedNote);
window.location.href = targetUrl;
});
});
You can also do this without jQuery, obviously—and should if you're not already depending on it. The point is to illustrate that this doesn't necessarily need to be a "giant block of jQuery code". In fact, this could be done in just a few lines—and probably should be. I deliberately broke it out into multiple steps and variables for the sake of readability.

parse <script> tag with js/jQuery

I have a HTML page where a user is able to edit a HTML resource (using ACE Editor). Within this HTML source, there is a <script>-tag, which does some pretty basic stuff.
Is there any elegant solution to parse the script tag in order to (e.g.) evaluate the variables used within the script tag? For "normal" tags I use parseHTML() to have the html as a jQuery object.
From this example, I would like to retrieve the value of $myVal (which is "f00") and write it to #myLabel:
<textarea id="myScript" rows="5" readonly>
<script>
$myVal = "f00";
</script>
</textarea>
<label id="myLabel">Hello</label>
$(function(){
$scriptVar = $('#myScript').text;
// parse the $scriptVar
// retrieve the value of, $myVal, write it to #myLabel
//$myParsedValue = ???
//$('#myLabel').text('bar!');
});
And here is the fiddle: https://jsfiddle.net/stepdown/jqcut0sn/
Is this possible at all? I don't really care about vanilla js, jQuery, regex or maybe even an external library for that purpose.
Thanks to #JeremyThille, who pointed me to the right direction. I found out, what I want to achieve is possible through jQuerys $.globalEval() - see the official documentation.
Basically what globalEval() does: it runs the script which is written in the <textarea> and makes the variables / functions globally accessible.
IMPORTANT: this implies, that syntax errors (etc) by the user will break the evaluation, and sequential functionality could be flawed. Also, the new variables are GLOBAL, so basically a user could rewrite scripts on the hosting page. (In my case both problems are of minor importance, since this is an internal application for trained users - they also have syntax highlighting through the amazing ACE editor. But I wanted to make sure to point it out. Also, there are several articles regarding the risks/ouch-moments when using eval()...)
I updated the fiddle to achieve what I wanted: https://jsfiddle.net/stepdown/Lxz7q6uv/
HTML:
<textarea id="myScript" rows="5" readonly>
$myVal = "f00";
</textarea>
<hr />
<label id="myLabel">Hello</label>
Script:
$(function(){
var myScriptContent = $('#myScript').text();
$.globalEval(myScriptContent);
console.log($myVal);
$('#myLabel').text($myVal);
});

Is using custom HTML tags and replacing custom tags with outerHTML okay?

Is it alright to define and use custom tags? (that will not conflict with future html tags) - while replacing/rendering those by changing outerHTML??
I created a demo below and it seems to work fine
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<script type="text/javascript" src="jquery.min.js"></script>
</head>
<body>
<div id="customtags">
<c-TextField name="Username" ></c-TextField> <br/>
<c-NameField name="name" id="c-NameField"></c-NameField> <br/>
<c-TextArea name="description" ></c-TextArea> <br/>
<blahblah c-t="d"></blahblah>
</div>
</body>
<script>
/* Code below to replace the cspa's with the actual html -- woaah it works well */
function ReplaceCustomTags() {
// cspa is a random term-- doesn;t mean anything really
var grs = $("*");
$.each(grs, function(index, value) {
var tg = value.tagName.toLowerCase();
if(tg.indexOf("c-")==0) {
console.log(index);
console.log(value);
var obj = $(value);
var newhtml;
if(tg=="c-textfield") {
newhtml= '<input type="text" value="'+obj.attr('name')+'"></input>';
} else if(tg=="c-namefield") {
newhtml= '<input type="text" value="FirstName"></input><input type="text" value="LastName"></input>';
} else if(tg=="c-textarea") {
newhtml= '<textarea cols="20" rows="3">Some description from model</textarea>';
}
obj.context.outerHTML = newhtml;
}
z = obj;
});
}
if(typeof(console)=='undefined' || console==null) { console={}; console.log=function(){}}
$(document).ready(ReplaceCustomTags);
</script>
</html>
Update to the question:
Let me explain a bit further on this. Please assume that JavaScript is enabled on the browser - i.e application is not supposed to run without javascript.
I have seen libraries that use custom attributes to define custom behavior in specified tags. For example Angular.js heavily uses custom attributes. (It also has examples on custom-tags). Although my question is not from a technical strategy perspective - I fail to understand why it would strategically cause problems in scalability/maintainability of the code.
Per me code like <ns:contact .....> is more readable than something like <div custom_type="contact" ....> . The only difference is that custom tags are ignored and not rendered, while the div type gets rendered by the browser
Angular.js does show a custom-tag example (pane/tab). In my example above I am using outerHTML to replace these custom tags - whilst I donot see such code in the libraries - Am I doing something shortsighted and wrong by using outerHTML to replace custom-tags?
I can't think of a reason why you'd want to do this.
What would you think if you had to work on a project written by someone else who ignored all common practices and conventions? What would happen if they were no longer at the company to find out why they did something a certain way?
The fact that you have to just go through with JavaScript to make it work at all should be a giant red flag. Unless you have a VERY good reason to, do yourself a favor and use the preexisting tags. Six months from now, are you going to remember why you did things that way?
It may well work, but it's probably not a good idea. Screen readers and search engines may have a hard/impossible time reading your page, since they may not interpret the JavaScript. While I can see the point, it's probably better to use this template to develop with, then "bake" it to HTML before putting it on the server.

Javascript if url then image

Hello,
I do not know very much about javascript, not much at all to be specific, and i'm french (this means sorry for my english).
since i don't know a lot about html and everything, i'm just changing the css and html on tumblr existing theme (i know it's not the very best solution but it's working for me and i'm improving slowly my knowledge about this world)
so in tumblr you have several pages already created like the one that regroup all your post with the same tag, this page is called http://myblog.tumblr.com/tagged/mytag
Here is my problem : i would like to change the header for each of these pages !
I don't have access to the php code (wich seemed to be the best solution...)
here is when i have one header :
<body>
<div id="header">
<img src="{image:Header}"/>
</div>
</body>
i have code the css so that my header looks fine to me
to answer my problem, i tried javascript :
<body>
<div id="header">
<script>
var image = new Array("{image:Header}", "http://static.tumblr.com/my-other-image.jpg")
if(document.URL.indexOf("/") >= 0) {
image.src = "{image:Header}"
}
if(document.URL.indexOf("/tagged/mytag1") >= 0) {
image.src = "http://static.tumblr.com/my-other-image.jpg"
}
</script>
</div>
</body>
obviously it didn't work, and you may be laughing watching what i wrote...
since i only have 3 or 4 pages i'd like to change, i'm ok with the "dirty solution" with too much code, and i just think that i need an "else" for all the other pages !
Thank you for telling me how to make it work and sorry to take some of your time for a simple thing like this wich may not be even possible. and sorry for talking about my life in my terrible english.
Thank you
you must create a image element, then append to the dom:
<body>
<div id="header"></div>
<script>
var uris = ["{image:Header}", "http://static.tumblr.com/my-other-image.jpg"];
var image = document.createElement("img");
if (document.URL.indexOf("/") >= 0) {
image.src = uris[0]
}
if (document.URL.indexOf("/tagged/mytag1") >= 0) {
image.src = uris[1]
}
document.getElementById("header")
.appendChild(image);
</script>
</body>

Razor syntax in JavaScript code block

I want to know if it is a good practice to use razor in JavaScript code. For example:
<script type="text/javascript">
var variable = #some.Id
</script>
Or it's better to create hidden value and then take it with JavaScript, like this?
<input type="hidden" id="someId" value"#some.Id" />
<script type="text/javascript">
var variable = $('#someId').val();
</script>
EDIT:
#{
var formVariables = serializer.Serialize(new
{
id = Model.Id,
name = Model.Name,
age = Model.Age
});
<input type="hidden" id="header_variables" value="#formVariables"/>
<script type="text/javascript" src = "/Scipts/..."></script>
}
Is this good solution?
I personally would go with an extension of the 2nd option and create a seperate .js file. The reason being, if you delegate work out to a 3rd party to take care of the jquery/javascript parts of the UI, then they need not have any sight of the backend functionality.
There are a variety of ways to use html5 attributes (i.e. data-attribute='foo') on the inputs which would allow you to 'decorate' your inputs with a cargo of properties which could be parsed inside the external .js file.
A very brief example:
in your view:
<input type='text' id='myId' data-action='#Url.Action("MyAction")' class='myClass' />
in your .js file:
var targetAction = $('#myId').attr('data-action');
this gives complete separation between the .js and the views. It does require a degree of planning of course.
Hope this helps
Razor will be parsed at server-side and replaced by relevant output. Therefore, in my opinion it is totally indifferent, if you place it in Javascript or HTML - at client side only the output value will be visible. Thus, in the above example I would choose the first option (place it directly in JS), since you will not have the otherwise unnecessary hidden input field.
I don't think there is a correct answer to this question; only pros and cons.
Pros of using Razor in Javascript
Script is bound to your view model; so model changes will get picked up automatically, and errors will get caught at compile time.
Cons
Script is mixed with markup, contrary to web design best practices (put script at the bottom so that it will never break your page).
Script cannot be compiled/minified, because, again, it's mixed in with your markup.

Categories