Using server side scripting it's as easy as pie to inject data in HTML like this (ASP.NET):
//Assuming theTime is a variable
<h1>the time is, #theTime</h1>
But in JavaScript one basically needs to:
Create an element:
<h1></h1>
Give it an ID:
<h1 id="whatever"></h1>
Create a script tag:
<script></script>
Locate the element by it's ID:
document.getElementById("whatever")
Then use innerHTML to modify it's content:
document.getElementById("whatever").innerHTML = "Hi, " + TheTIme;
Final code:
<h1 id="whatever"></h1>
<script>
document.getElementById("whatever").innerHTML = "Hi, " + TheTime;
</script>
Is it possible to inject values/data in JavaScript as one would do in ASP.NET / PHP?
EDIT: The variable is a JS variable and getting it from the server is under control.
Well you could use some template library like handlebars and use jquery to facilitate the element selection, example:
<div id="target"></div>
<script id="hi-template" type="text/x-handlebars-template">
Hi {{userName}}
</script>
<script type='text/javascript'>
var template = Handlebars.compile($("#hi-template").html());
$('#target').html(template({userName: "bob"}));
</script>
Javascript Templating solves exactly this problem of binding data to HTML elements.
Below are few of the common templating engines used these days:
Underscore.js
Handlebars.js
Mustache.js
If you are looking for something simple, try Micro Templating engine from John Resig
<h1>Hi, #theUsersName</h1>
I've never worked with ASP.NET, but I'm assuming #theUserName is a variable. If that's the case, then a 1 to 1 replacement for that is not possible. However, it's still possible.
I'm not sure how you're getting the username, but I would assume you have some way to get it into a JavaScript variable. In that case, I would suggest something like this:
function changeName(username) {
document.getElementById("username").innerHTML = username;
}
<h1>Hi, <span id="username">StackOverflow</span>!</h1>
<button onclick="changeName('user3088260')">Click to Change the Name</button>
Now, getting the data is a different story, I would assume an AJAX call, in which case you could do something like this
if(xmlhttp.responseText !== ""){
changeName("user3088260");
}
All that other stuff you mentioned in unnecessary.
I will also say the entire idea seems like a poor design choice. If you have a username, I would assume you have a login system. If you have a login system, then you have to validate the user before outputting the page. If you have to validate the user before outputting the page, then you have their username. If you have their username, then put it in the pre-rendered page. No need to use JS after you've outputted the page.
Hopefully that is what you're looking for. If not, I'm sure somebody else will be along shortly with something that does.
One of the easiest javascript template engines to get started with is Underscore. Here is a protected answer from SO explaining how to do it:
How to use underscore.js as a template engine?
As someone says, there are a lot of Javascript templating frameworks. Here you have a few of them:
Handlebars.js
mustache.js
Hogan.js
doT.js
nunjucks
jade
After picking one, you can (for example) do something like this:
<h1>Hi, {{userName}}</h1>
You can see an example of client-side templating working with Angular on this link.
In my application, I need to provide an API (something like the Google Maps javascript API), through which I can send some custom javascript (with some session and request related information) as the response. The javascript is then used to plot some graphs on the UI. I'm using Express with Jade as my templating engine. The code that I'm currently using is:
app.use('/graph',function(req, res){
//send out graph data
var var_name = req.session.var_name //fetch something from session
var graphData = fetchGraphData(req.query.graph); //function that fetches graph data
res.contentType("text/javascript");
res.render(__dirname + '/views/graph.jade', {
title: "Title", queryStr: JSON.stringify({var_name: var_name, graphData: graphData })
});
});
And the jade file:
| some_var_name = {
| initGraph : function(divId){
| //some code here
| var graphData = !{graphData}
| // do something
As a workaround, I have started each line of the jade file with |, so that jade parses the text as plain text, and doesn't add any html tags! It works fine, but is there a cleaner way to do this? The solution may or may not use Jade!
You should look into underscore templates. I think that for generating arbitrary text output it would be somewhat cleaner. Jade is purpose-built for rendering HTML.
You could also try Mustache or Handlebars.
Based on your comment, I see you'd like to keep using res.render for rendering the template. consolodate.js adds support for all major template engines to Express. Including Underscore templates, Handlebars, Mustache and Dust, mentioned by #TheHippo.
You may try to define JavaScript functions you need to send to the browser in a separate module, outside of the template, which is probably more correct way from the "concerns separation" point of view. Also if functions are defined in a separate module they can be used both in the server and in the browser.
Then you can convert the functions to strings using its toString() method either in a function that invokes the template or right inside the template, if it supports plain JavaScript which is the case with underscore, EJS and doT templates (I tried both underscore and EJS and ended up using doT which is not only the fastest but very versatile - check it out):
JS code:
// if you send the same functions you may want to convert them to strings in advance
var data = {
funcStr: func.toString();
};
res.render(view, data);
Template (doT):
<script type="text/javascript">
func = {{= it.funcStr }};
// now you can call it here if you want but I would use
// separate JavaScript files
func();
</script>
I use it to send pre-compliled templates to the browser together with the page on the first page load, but I think it can be used in your case too.
As a side question, why can't you just bundle all these functions in a separate JavaScript module and load them as normal script file?
You can use https://www.npmjs.com/package/rendercustomjs package, it works fine but in ejs templating
I'm interested in using more fine-grained Javascript include files to enhance maintainability. However, I'm missing something. Can I still "overwrite" or include sections from my Razor view context? Let's say my Javascript include is as follows:
function CategoriesViewModel() {
var self = this;
self.searchMode = ko.observable("SEARCH"); // Wire up with Knockout.js
}
But, if this script were inline as part of my .cshtml Razor view, I'd be able to do something like this:
function CategoriesViewModel() {
var self = this;
self.searchMode = ko.observable("SEARCH"); // Wire up with Knockout.js
self.categories = #Html.JSONFor(Model.LookupForCategories.Select(c => c.Text ));
}
(Without the syntax highlighting, I'll point out that I've included a server tag that places some Javascript code/data straight from my server-side ASP.MVC ViewModel.)
If I pull Javascript into separate files and include them, I lose this ability. Is there a feature or technique that I'm missing?
I haven't used it yet myself but you may be interested in the RazorJs nuget package: http://nuget.org/packages/RazorJS
More on the subject from the author here:
http://djsolid.net/blog/razorjs---write-razor-inside-your-javascript-files
Sadly no. This is a common problem when dealing with serverside frameworks and js. You are pretty much stuck with parameterizing, or declaring variables either as globals, or as properties on some shared object.
I typically set up jquery templates in my html files like this:
<script id="some-template" type="text/x-jquery-tmpl">
my template contents go here... with some data: {data}
</script>
then my javascript that needs to use this template would look for it by the id and pass in the needed data:
var template = $("#some-template");
var html = template.tmpl({data: "data goes here..."});
// do something with the 'html' var, like attach it to the DOM
now i'm trying to write jasmine-bdd specs for my javascript. i don't see anything particularly wrong with the way i set up my templates and have my javascript find / expand the template... but i'm not sure how to get jasmine to play nice with this... so...
how can i use jasmine to test my javascript, when my javascript relies on a jquery-template, and the template is defined in my html page directly?
do i have to duplicate my template in a jasmine-jquery fixture? or is there a way to make a jasmine-jquery fixture use my existing html / template definition?
in case anyone is interested, here's how i solved this: http://lostechies.com/derickbailey/2011/09/06/test-driving-backbone-views-with-jquery-templates-the-jasmine-gem-and-jasmine-jquery/
I am a web guy doing mostly Perl server-side stuff, and I'm slowly coming to a few conclusions.
It is far better to do most of your code via Javascript and toss data back and forth via AJAX than it is to hit submit and reload a mostly-identical page
I like jQuery because I like CSS, and it's fun to chain together big long and scary-to-others definitions
There's something to that templating stuff.
You want your HTML elements to look like your HTML elements, and it's easier to define that in HTML:
<div class="sidebar_elem">
TEXT
</div>
Than it is to cobble up the same in Javascript or jQuery:
( '<div/>' )
.attr('id' , 'sidebar_elem' + i )
.addclass( 'sidebar_elem' )
;
( '<a/>' )
.attr('href' , link_url )
.appendTo( '#sidebar_elem' + i )
;
This is to say that I am no longer a templating agnostic, but I don't know which templating tool to believe in. I have looked into some jQuery-based templating plugins, but I have yet to become happy with any of them, in part because the ones I've seen seem to want to put all that code into the page itself, which breaks the "Only markup goes into HTML files, only style goes into CSS files, only code goes into JS files" mantra I keep reciting.
So, I'm looking for a Javascript-based templating tool that would allow me to have my templates in an outside file so I can have one template change cover a series of web pages. If it's jQuery-based, that's great, less stuff I have to learn, but it isn't a deal-breaker.
There are several good ones out there:
Mustache.js
Pure.js
Json Template
If you want a jQuery version, Tempest looks good.
The 2 libs I know that do not mix template coding with HTML markups are chain.js and PURE
chain makes only DOM manipulations.
PURE uses a mix of DOM and innerHTML as the DOM alone can be slow to render bigger templates.
I'm the main contributor of PURE, and we created it to build a web app on the ajax model you describe.
Take a look at this one http://ejohn.org/blog/javascript-micro-templating/. Made by John Resig, creator of jQuery, this one doesn't even need jQuery, and it's freaking small. It also stores templates in script tag (Daniel's answer). Example template:
<script type="text/html" id="user_tmpl">
<% for ( var i = 0; i < users.length; i++ ) { %>
<li><%=users[i].name%></li>
<% } %>
</script>
Maybe you can load them using src attribute if you really need them to be in separate files, which I don't think is a wise idea, because it means additional roundtrip to the server. So at the end, for the sake of optimization, you can store them in separate files, but embed them server side in the page that needs them.
Since there is no well defined API and a best library for templating, I would suggest you choose one that is actively developed. Below, I briefly explained two libraries that are actively being developed.
jQuery team decided that jQuery Templates will no longer be actively developed or maintained, thus I would strongly suggest NOT using it. See this blog entry.
You can use JsRender in accordance with JsViews to take full functionality provided by jQuery Templates and even more like data linking. You can find demos for JsRender and JsViews. I would suggest using these libraries since they are actively being developed by jQuery UI team but be aware that they are still not even beta!
Mustache is another templating solution that is actively being developed and it simplifies templates by combining conditional tags and enumeration tags. It also provides strong features like inverted sections, partials and high order sections with simple syntax. Mustache is also one of the fastest templating solutions See blog by Brian Landau. I, personally, find mustache a good templating solution since it has a simple syntax and performs well.
How about EJS?
Example from their page:
"EJS combines data and a template to produce HTML."
Data:
{title: 'Cleaning Supplies', supplies: ['mop', 'broom', 'duster'] }
Template:
<ul>
<% for(var i=0; i<supplies.length; i++) {%>
<li><%= supplies[i] %></li>
<% } %>
</ul>
Result:
mop
broom
duster
You should check out google closure template. It's completely independent so you can use it with any lib you want. It's a templating tool written in java.
http://code.google.com/closure/templates/docs/helloworld_js.html
It allows you to create a template on the server, run a java "compiler" on it and the output is a javascript function that takes json as its parameter.
{namespace examples}
/**
* Greets a person using "Hello" by default.
* #param name The name of the person.
* #param? greetingWord Optional greeting word to use instead of "Hello".
*/
{template .helloName}
{if not $greetingWord}
Hello {$name}!
{else}
{$greetingWord} {$name}!
{/if}
{/template}
This will generate a function called examples.helloName that can be called like
Their format is very IDE friendly, I get all the HTML syntax highlighting when editing the templates
examples.helloName({name: 'Ana', greetingWord:"Howdy"});
You can call other templates from within templates, it automatically html escapes your data (unless you tell it not to), provides bidirection support.
Another great thing is the fact that the templating tool can also generate java code. So somebody writing an app that must support browsers with scripting disabled can generate the HTML on the server if necessary.
Last but not least, unlike other js templating systems (), the template is parsed on the server, so the client side only has to do the merging of the template and data, the parsing of the template is done as a build step on the server.
http://dev.sencha.com/deploy/dev/docs/?class=Ext.XTemplate is an example of a templating tool that runs completely on the client. There are two problems with this approach, the parsing of the template is done on the client and your html has to be embedded in a javascript string. However, some IDEs (Intellij) will highlight the HTML inside JS strings).
What about JAML Code?
http://github.com/edspencer/jaml
Similar to a few of the above but I believe is a bit more logical...
It is the concept of defining your templates via JSON / JavaScript and then using a function in JavaScript to pass arguments to your template which gets it rendered and returned as an element.
There are implementations around for the various JavaScript Frameworks that exist.
Try out this:
https://www.npmjs.com/package/jlate
use CDN:
<script src="https://cdn.jsdelivr.net/combine/npm/lodash,npm/jlate#0.0.2/jlate/JLate.min.js"></script>
I given below working example where you can replace github template url with your own template sample:
https://raw.githubusercontent.com/webphonix/JLate/main/test_project/template/weblate_loop.html
<div class="row">
<% _.each(names, function(n){ %>
<div class="col-md-6"><%- n.name %></div>
<% }) %>
</div>
var author = [{
name: "Guru"
},
{
name: "Gurudev"
},
{
name: "Test"
},
{
name: "Webphonix"
},
];
$$("#my_temp").jlate({
names: author
});
<script src="https://cdn.jsdelivr.net/combine/npm/lodash,npm/jlate#0.0.2/jlate/JLate.min.js"></script>
<div>
<jlate id="my_temp" src="https://raw.githubusercontent.com/webphonix/JLate/main/test_project/template/weblate_loop.html" type="template">
Loading...
</jlate>
</div>
Try JLate:
https://www.npmjs.com/package/jlate
use version 0.0.2 instead 0.0.1
use below cdn:
<script src="https://cdn.jsdelivr.net/combine/npm/lodash,npm/jlate#0.0.2/jlate/JLate.min.js"></script>
Use a script block.
<script id="someId" type="text/html">
<!-- your template here -->
</script>
and one of many JQuery plugins.
http://weblogs.asp.net/scottgu/archive/2010/05/07/jquery-templates-and-data-linking-and-microsoft-contributing-to-jquery.aspx
I have a templating engine called stencil.js, which I believe is pretty sweet. It works with jQuery via the jquery-haml DOM building engine.
Write your template (which you can put in an external file and decode as JSON):
["%div.sidebar_elem"
["%a", { href: { key:'link' } },
{ key: "text" }
]
]
And run it through stencil along with your data:
$("#parent").stencil(template, { link: "http://example.com", text: "Click me!" });
There are more examples at the stencil.js GitHub project, but I think it's just what you're looking for.
It could use a couple more utility methods, and some code for an unfinished data binding component is still in the master branch, so drop me a comment if you’re interested and I'll see if I can clean it up.
check out ibdom, and some background/history here: Recommended JavaScript HTML template library for JQuery?
Could always go with jQuery-Templates: http://api.jquery.com/category/plugins/templates/
What about http://www.enfusion-framework.org
Stuff like this:
<span template>Our telephone number is {phone}.</span>
<span session>You are logged in as {nickname}.</span>