Use Templating on JavaScript Files - javascript

I'm in the most interesting position where I would like to template my JavaScript files server-side to include and remove certain parts based on an object. Given an object like so:
var obj = {
"includeA": true,
"includeB": false,
"includeC": true
}
I would like the ability to include/exclude certain parts of said JS file. For example:
if (obj.includeA) {
// This is some code from A
}
if (obj.includeB) {
// This is some code from B
}
Would produce either a string or a file that looks like:
// This is some code from A
I've looked into some basic options, one of the foremost ideas that came to mind was to simply use if statements in JS. This code however looks rather terrible, and considering there will be upto 1,000 lines of this, not suitable at all:
var string = ""
if (obj.includeA) {
string += "This is one line \n"
string += "This is another line \n"
}
// etc.
This produces the right output, but the repetitiveness of the string += makes me detest it. I then decided to package it up into a function:
var string = ""
function call(line) {
string += line + "\n"
if (obj.includeA) {
call("This is one line")
call"This is another line)
}
// etc.
But that seems only slightly better. Is there any sort of templating engine (imagining something similar to Jade), that allows templating of text blocks like this?

Related

Writing beautiful JSON using multiple line strings?

Context
For personal use, im creating a small project that documents my learning about data structures. I want to dynamically pull strings from a JSON file into a custom Vue component that displays code that can be run and edited in the browser by the user.
The Probem
I find the above image far easier to, not only type, but also to read, than something like this (including variations including escape strings on a single line):
"BasicArithmic" : "var a = 1;var b = 2;var c = a + 5*b;return c;"
Ultimately i just want to be able to type the string out as multiple lines inside the code so that i'm not wasting my time trying to work out what code is supposed to do.
Clarification
Im passing in code as a string to an eval(), since i couldn't work out how to pass code between components and THEN convert the code to a string.
Use ` instead of "
console.log(`
a = 1;
b = 2;
`
)
Or you could add \ to the end of each line:
x = { "BasicArithmic" : "\
var a = 1;\
var b = 2;\
var c = a + 5*b;\
return c;\
"}
console.log(x.BasicArithmic);

Correct way to convert your JavaScript function into a string so it can be inserted into innerHTML

This is what I am doing: I am building a fun in house API Voting System. I am using a client side snippet insert onto page
Like this:
<script src="domain.com/api/scripts/main.js"></script>
<div id="content-wrap" id="ac1e435e-c564-48f8-9f45-338616e7a789"></div>
Now in my main .JS I do all ajax request and modify the #content-wrap with creating new elements and inserting additional JS required to run Voting System.
However big issue I am experiencing is when I write JavaScript that I need to insert into #content-wrap I am currently writing it like this:
script.innerHTML = "$(someting).on('click', funciton(){"
+ "$.ajax({type: 'post',"
+ " url: '" + base + "/api/request', data: $('form').serialize(), "
+ "success: function(response){";
As you can see that can cause lot of issues as I build on it.
What is better way to accomplish this or is there a way i can just write my script / code and do something like this.
script.innerHTML = ConvertToString(script.js) OR ConvertToString(function X);
ConvertToString is just an expression I am using to explain what I would like to do instead of what I am doing.
Thank you, I am open to any suggestions.
I also must do this in plain JavaScript or with jQuery library so any suggestions to use VueJs, AngularJS or React will be considered as future references.
Thank you again
Additional explanation:
I would like to insert into my script element JavaScript snippet. But my snippet is about 30 lines long currently and might get bigger with time so it is very difficult to code with all the + " code " on every line that I write so that it can be inserted with innerHTML into element and executed on Client end.
So I would instead like to do something like this
element.innerHTML = mysnippetcode // but with out using + "" on each line like shown above
OR
element.append(snippet)
I hope this makes it little more clear
Solution that worked for me was using back ticks to wrap my sinppet and insert it into innerHTML of the element..
Just use the function's name without the () to convert it to a string:
function foo() {
var a = 10;
var b = 20;
var c = a + b;
return c;
}
document.write(foo);
The document.write will result in this string:
function foo() { var a = 10; var b = 20; var c = a + b; return c; }
If you only want the function's body, then you could just normally remove the first and last characters of the string.
I am not entirely sure this is what you wanted, if not, please make yourself more clear.
Alternatively, you could do an eval([insert function code here]) and there would be no need to add the code to the innterHTML of the script, read up on that function if you haven't heard of it.
Or if you want to create a function from a string, you can use new Function([name] ,[function body string]) if you need arguments you have to sandwich them between the 2 parameters.
But my snippet is about 30 lines long currently and might get bigger with time > so it is very difficult to code with all the + " code " on every line that I
write
You can use template literals if you want multi-line strings in Javascript, you simply have to replace your quotes with backticks.
See this MDN page if you are interested, or even this StackOverflow answer.

How to compare two strings within a single line in java script

I got the String as :-Time in Queue,Item Type, Status,Type,Name, 22days, Document,Idle,Default,test4.
Now I have to compare status and its corresponding values as idle.
How to pick these two words in a single line and compare using java script.
If the structure is fixed, you could, for example, split the string
var result = "-Time in Queue,Item Type, Status,Type,Name, 22days, Document,Idle,Default,test4".split(",")[7] === 'Idle';
But I think you need something else, it is just unclear from the description. Probably if you added some context and described why you need this (why it must be single line, where the data came from, how they are really structured etc.), you could get a better answer.
...is there a line-break there, somewhere?
...you could do something like:
var string = "Time in Queue,Item Type,Status,Type,Name, 22days,Document,Idle,Default,test4",
pieces = string.split(","),
match = pieces[2].trim() === "Status" && pieces[6].trim() === "Idle";
...of course, .trim doesn't work on old browsers, but you can write something similar, easily.
If you really, really want to go golfing, you could do something like:
var string = "Time in Queue,Item Type,Status,Type,Name, 22days,Document,Idle,Default,test4",
reg = /[^,]+,[^,]+,\s*Status\s*,[^,]+,[^,]+,[^,]+,[^,]+,\s*Idle\s*/i;
reg.test(string);
This will tell you if "..., ..., Status, ..., ..., ..., ..., Idle" happens in the string, where "..." is any set of characters which isn't a comma.
If that's not what you mean, then you need to get more specific, here.

How to display raw JSON data on a HTML page [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
JSON pretty print using JavaScript
I'd like to display my raw JSON data on a HTML page just as JSONview does. For example, my raw json data is:
{
"hey":"guy",
"anumber":243,
"anobject":{
"whoa":"nuts",
"anarray":[
1,
2,
"thr<h1>ee"
],
"more":"stuff"
},
"awesome":true,
"bogus":false,
"meaning":null,
"japanese":"明日がある。",
"link":"http://jsonview.com",
"notLink":"http://jsonview.com is great"
}
It comes from http://jsonview.com/, and what I want to achieve is like http://jsonview.com/example.json if you use Chrome and have installed the JSONView plugin.
I've tried but failed to understand how it works. I'd like to use a JS script (CSS to highlight) to custom format my raw JSON data which is retrieved by ajax and finally put it on a HTML page in any position like into a div element. Are there any existing JS libraries that can achieve this? Or how to do it?
I think all you need to display the data on an HTML page is JSON.stringify.
For example, if your JSON is stored like this:
var jsonVar = {
text: "example",
number: 1
};
Then you need only do this to convert it to a string:
var jsonStr = JSON.stringify(jsonVar);
And then you can insert into your HTML directly, for example:
document.body.innerHTML = jsonStr;
Of course you will probably want to replace body with some other element via getElementById.
As for the CSS part of your question, you could use RegExp to manipulate the stringified object before you put it into the DOM. For example, this code (also on JSFiddle for demonstration purposes) should take care of indenting of curly braces.
var jsonVar = {
text: "example",
number: 1,
obj: {
"more text": "another example"
},
obj2: {
"yet more text": "yet another example"
}
}, // THE RAW OBJECT
jsonStr = JSON.stringify(jsonVar), // THE OBJECT STRINGIFIED
regeStr = '', // A EMPTY STRING TO EVENTUALLY HOLD THE FORMATTED STRINGIFIED OBJECT
f = {
brace: 0
}; // AN OBJECT FOR TRACKING INCREMENTS/DECREMENTS,
// IN PARTICULAR CURLY BRACES (OTHER PROPERTIES COULD BE ADDED)
regeStr = jsonStr.replace(/({|}[,]*|[^{}:]+:[^{}:,]*[,{]*)/g, function (m, p1) {
var rtnFn = function() {
return '<div style="text-indent: ' + (f['brace'] * 20) + 'px;">' + p1 + '</div>';
},
rtnStr = 0;
if (p1.lastIndexOf('{') === (p1.length - 1)) {
rtnStr = rtnFn();
f['brace'] += 1;
} else if (p1.indexOf('}') === 0) {
f['brace'] -= 1;
rtnStr = rtnFn();
} else {
rtnStr = rtnFn();
}
return rtnStr;
});
document.body.innerHTML += regeStr; // appends the result to the body of the HTML document
This code simply looks for sections of the object within the string and separates them into divs (though you could change the HTML part of that). Every time it encounters a curly brace, however, it increments or decrements the indentation depending on whether it's an opening brace or a closing (behaviour similar to the space argument of 'JSON.stringify'). But you could this as a basis for different types of formatting.
Note that the link you provided does is not an HTML page, but rather a JSON document. The formatting is done by the browser.
You have to decide if:
You want to show the raw JSON (not an HTML page), as in your example
Show an HTML page with formatted JSON
If you want 1., just tell your application to render a response body with the JSON, set the MIME type (application/json), etc.
In this case, formatting is dealt by the browser (and/or browser plugins)
If 2., it's a matter of rendering a simple minimal HTML page with the JSON where you can highlight it in several ways:
server-side, depending on your stack. There are solutions for almost every language
client-side with Javascript highlight libraries.
If you give more details about your stack, it's easier to provide examples or resources.
EDIT: For client side JS highlighting you can try higlight.js, for instance.
JSON in any HTML tag except <script> tag would be a mere text. Thus it's like you add a story to your HTML page.
However, about formatting, that's another matter. I guess you should change the title of your question.
Take a look at this question. Also see this page.

Limit the number of characters rendered by a Mustache.js tag

Is there any way in Mustache of limiting the number of characters a Mustache tag generates?
eg
template = "<li>{{my_tag}}</li>"
data = {
"my_tag" : "A very long string that needs to be abbreviated to fit into the available space."
}
Now when I render my tag I want to abbreviate the long string by showing only the first 10 chars follwed by an ellipsis. I looked into using a lambda function (as described in the Mustache docs) like so...
template = "<li>{{#limitLength}}{{my_tag}}{{/limitLength}}</li>"
data = {
"limitLength" : function() {
return function(text) {
return text.substr(0,10) + '...';
}
},
"my_tag" : "A very long string that needs to be abbreviated to fit into the available space."
}
but unfortunately the {{my_tag}} tag doesn't get expanded. The Mustache manual states:
The text passed is the literal block, unrendered. {{tags}} will not
have been expanded - the lambda should do that on its own.
.. but I can't imagine how to do this without using the Mustache.to_html() function and when I try to use it like so...
eg
data = {
"limitLength" : function() {
return function(text) {
return Mustache.to_html(text,data).substr(0,10) + '...';
}
},
"my_tag" : "A very long string that needs to be abbreviated to fit into the available space."
}
... it fails silently (the recursive use of the data object is possibly to blame here)
Does anyone know of any other way of achieving this without resorting to a javascript/jQuery function, I'd like to implement it just using Mustache if possible.
Your function actually gets called with two arguments: the unrendered text and a render function which can be used to render your text, keeping the current context.
data = {
"limitLength" : function() {
return function(text, render) {
return render(text).substr(0,10) + '...';
}
},
"my_tag" : "A very long string that needs to be abbreviated to fit into the available space."
}

Categories