I'm building a website and considering using pure dynamic pages, i.e. no html files and everything is handled by a router in javascript and the DOM elements are all created and inserted to the document by javascript.
I'm just wondering whether it's a good idea. IMHO, events can be attached to DOM elements when they are created, which may make the code more readable. And the static and dynamic parts might be better incorporated. But the page format may become unclear. And I'm not so sure whether performance will be compromised.
Is anyone aware of any websites that actually use this approach?
Thanks a lot!
The question is a bit vague, but you're probably looking for something like any number of the new-age JavaScript front-end MVC frameworks:
http://angularjs.org/
http://meteor.com/
http://backbonejs.org/
etc.
Try pure, a javascript library, which separates representation(HTML) and logic(js), making the code clear and easy to understand.
It also supports integration with major javascript libraries.
pure.js Example
HTML template
<div class="hello">
<span class="who"></span>
</div>
Rendering directive
{
"span.who":"who"
}
JSON Data
{
"who":"Hello Wrrrld"
}
The resulting HTML
<div class="hello">
<span class="who">Hello Wrrrld</span>
</div>
Related
I have a web application where a lot of inline javascript is used. For example:
<input type="button" id="btn1" onclick="return test();">
I want to separate javascript code from the UI by placing it in a separate file or inside the script tag. Including javascript event attachment. For example instead of the above I'd have:
<input type="button" id="btn1">
and in the script section I'd us:
<script type="text/javascript>
btn1.onclick = function() {
test();
}
</script>
or
<script type="text/javascript>
if (btn1.addEventListener){
btn1.addEventListener('click', test, false);
}else if (btn1.attachEvent){
btn1.attachEvent('onclick', test );
}
</script>
Why do I want to do that? I like separating my UI from the business logic and database, that's my general approach. Also it is better from performance standpoint, as external javascript can be easier cached by browsers. Another reason - it is more secure. My question is whether this is worth the hassle of changing the application, removing all the inline javascript?
I'd appreciate if someone gave me some pointers, some links to articles - I have been searching the web and found some conflicting information. Would appreciate to hear some opinions
From the maintenance point of view is much easier to have at least two separate files: html and js. After that you can have a separation between UI, business logic and data. You can check this question for more information on design patterns.
I'm fully in favor of separating JS code from markup, mostly for maintenance reasons and clarity of intent. As you pointed out, it's also better from a caching perspective.
I would go one step further and suggest that you would also benefit from a framework (pick your poison, there are plenty of good options, but jQuery is a good place to start as it's very well documented and handles a lot of the boilerplate stuff like your example has (browser differences, etc).
All that said, one part of your question made me curious. In what way do you think having javascript in a separate file will make your pages more secure?
I just started looking at plates, as many people are talking about it.
There are some examples for plates with little html snippets, but not really a full-blown template file. So I am wondering how I can separate especially the layout into a layout.html file and the content distributed into several content.html files?
Also, I'd like to know if there are some strategies for multi-language-sites in flatiron.js/plates?
Thanks!
You can do the seperation pretty easily. You can write a function which binds given string into a layout. Now all you need to do is form the string using plates.bind (this is the content) and pass it to that function which uses plates.bind on the layout.html
Example: https://github.com/flatiron/flatiron/blob/scaffolding/lib/flatiron/plugins/plates.js#L64-66
Update: after another day of digging
into this issue, I have found that the
current jQuery template lib provides
no way to do this. this article
describes a good approach.
I would still like to hear of any
additional thoughts on doing this. The
article linked above requires that the
returned string of templates be
inserted into the DOM. Seems as though
leaving the DOM out of this would be
ideal, and less overhead on the
browser. Imagine a large page, with
multiple composite templates that may
not get used. Although, maybe because
the templates are wrapped in a script
tag, there is only a single DOM item per template? Come on, let's
hear some thoughts...
Using jQuery template libs, what's the best way to combine multiple, related, relatively small templates together? Do you need a single <script> tag for each individual template? What about in the case of dynamically pulling these templates via AJAX? Can I combine these templates somehow?
Consider the following:
<script id="movieTemplate" type="text/x-jquery-tmpl">
{{tmpl "#titleTemplate"}}
<tr class="detail"><td>Director: ${Director}</td></tr>
</script>
<script id="titleTemplate" type="text/x-jquery-tmpl">
<tr class="title"><td>${Name}</td></tr>
</script>
Now because these two templates are very closely related (and one depends on the other) it would make sense to consolidate these into a single AJAX call, and get them both at once. I have a few ideas, but I'd like to know if there is common/best way to do this? Currently I pull in a chunk of HTML, and then do a .find() to get the specific peice of HTML for a template... e.g.:
var templatePackage = fancyAjaxCalltoGetTemplates();
"templatePackage" might then look like this:
<div id="templatePkg">
<div id="movieTemplate">
{{tmpl "#titleTemplate"}}
<tr class="detail"><td>Director: ${Director}</td></tr>
</div>
<div id="titleTemplate">
<tr class="title"><td>${Name}</td></tr>
</div>
</div>
I could then do:
var titleTemplate = jQuery.template('titleTemplate', $(templatePackage).find('#titleTemplate') );
and
var movieTemplate = jQuery.template('movieTemplate', $(templatePackage).find('#movieTemplate') );
...let me know what you think... what would you do?
I like the referenced article in your update, except the assumption that you can't cache templates unless you insert them into the DOM. From the jQuery.tmpl documentation,
"To cache the template when using markup that is obtained from a string (rather than from inline markup in the page), use $.template( name, markup ) to create a named template for reuse. See jQuery.template()."
Using this, we can build a javascript template management system that allows us to load as many templates at a time as we need while keeping the DOM clean. On the client, keep a hash of template objects by name. You can use your favorite object based javascript pattern here, but I would think the structure could be like this:
templates[templateName] = {
templateMarkup: markupFromServer,
loadedAt: Date.now(),
compiledTemplateFunction: jQuery.template( templateName, markupFromServer )
}
Then use the templates to generate HTML like this:
templates['unique-name'].compiledTemplateFunction(inputData)
Then, build an unload mechanism to free up memory:
function unload(templateName) {
delete templates[templateName];
delete jquery.template[templateName];
}
Most importantly, you now have a method of storing multiple templates so you can make requests like: $.get('/TemplateManagement/Render', arrayOfTemplateNamesToLoad, loadManyTemplatesSuccess) to load multiple templates at a time. The only thing we need is a controller TemplateManagement that will take an array of template names as an input and return JSON that pairs a template name with its markup. There are a few ways to do this but it seems to me the most convenient is to define partial views for each template. In ASP.NET MVC 3, you can use this technique and RenderPartial to emit each template's markup into a JSON response. You can either name the partial views the same as the templates or map the names in some custom way.
OK, I read the article you reference in this post. As I see it, his way is probably one of the best ways to load up the template page(s). The only thing I don't like is the asynchronous problems that could crop up, esp. if you need to immediately do some templating before the async get returns... plus any binding issues that could happen before it returns something. In several projects I have done I use his "ancient" SSI (server side includes), but I just use something even easier like:
<% Response.WriteFile("this_page_template_file.html"); %>
You could put it anywhere where you'd place a tag. Like he says, just put in only the templates you need, or maybe include two templates: one is a "base" template with commonly-used items and the second one would have the page-specific ones with template references {{tmpl}}.
Is this even close to an answer? ;-)
[First off, great question. I love this topic]
I have no experience with the plugin "jquery-template-libs", but there is a particular lightweight javascript template plugins that are becoming almost a standard and plays very nicely with jQuery, which is probably better suited for the task than JTL, Mustache:
https://github.com/janl/mustache.js
It's got something that's called a "partial" which is essentially a way to include smaller templates within another one. Which sounds like it will help you out a lot.
On top of that there is a library called ICanHaz.js:
http://icanhazjs.com/
ICanHaz essentially extends Mustache to include built in functionality for templates and works incredibly well.
Mustache/ICanHaz allow you to add templates by variable, by a json call or by using tags. The choice is yours.
I know this is an old question but you might want to take a look at Closure-Templates. They provide the kind of functionality you're after with the added advantage of being compiled into JavaScript at compile-time instead of at run-time in each user's browser.
If you do decide to look into using them then I'd suggest using plovr for building them.
I am trying to find a way to add content to a div that is defined in my application.html.haml file from individual view files. The reason I want to do this is because I have a sidebar that is always present and is defined in the template, but I would like to have content specific to each page included in the sidebar. Would this be done best with javascript or is there some ruby on rails trick that I can use to make this easier?
I would use the content_for helper (Rails Guide) (API).
In haml, this would look something like:
(layout template)
#sidebar= yield :sidebar
(page template)
-content_for :sidebar do
...your content here
If you work with professional designers who handle the views, it may be easier over the long term to have rather repetitive view code. Some people have a hard time searching through partials and "seeing" how they all fit together. I've found it easier with those people to let them manage the whole shebang and update more than one file if they need to. Optimal? Not to us as programmers, but designers are more often used to seeing most of the HTML in one or three files rather than 20. :)
use partials as much as possible to keep your code DRY
this link helps you
http://guides.rubyonrails.org/layouts_and_rendering.html
What UI patterns do you usually use in JavaScript?
By UI patterns I mean best practices to be used to build and organize UI, generated/managed from JavaScript (apart from libraries like jQuery or YUI).
For example, if you came from .NET world you are familiar with MVC (Model-View-Controller) patterns family. In the world of WinForms and ASP.NET you will meet Model-View-Presenter. In WPF most likely you will find MVVM (Model-View-ViewModel) approach.
And what about JavaScript?
Patterns are usually language-agnostic. If a pattern has value, barring certain edge cases it will have value regardless of what language or technology you're using. Take MVC. The concept of separating the model from the view from the controller has value regardless of whether the model is implemented with an RDBMS or some other technology, whether the view is HTML or Swing or X.
Where you see certain patterns applied more in one technology than another, it usually just means that the developers of the technology had a particular approach that they supported more fully than others.
JavaScript itself doesn't impose any particular pattern on you. Some JavaScript frameworks, like YUI or Dojo or Glow will tend to lead you one direction more than another.
At the end of the day, look at the problem you're solving, the resources and experience you have, and follow the patterns that make sense.
I'd like to recommend Ross Harmes & Dustin Diaz's book, Pro JavaScript Design Patterns, definitely the best resource on this subject, and definitely worth a read.
There’s also a very interesting article on JavaScript MVC in the latest issue of A List Apart.
A good approach to building GUI application is that of browser:
using markup for UI layout
using javascript UI logic
using CSS for UI styling
Most of modern GUI frameworks (ExtJS, Dojo etc) offer APIs that greatly help building GUI in JavaScript solely. But there is another GUI framework Ample SDK that brings the before mentioned separation of concerns. It allows for using XML-based languages (XHTML, XUL, SVG) for layout, CSS for style and DOM APIs for UI logic.
To orchestrate a client-side GUI application you can use either MVC or a little bit more advanced pattern PAC, as for the former - there is a PureMVC implementation available
Take a look at the following snippet (only concerns UI logic, not app logic, to be built with MVC/PAC):
index.html
<script type="application/ample+xml">
<xul:tabbox onselect="fOnSelect(event)"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<xul:tabs>
<xul:tab label="checkbox" />
<xul:tab label="textbox" />
<xul:tab label="datepicker" />
</xul:tabs>
<xul:tabpanels>
<xul:tabpanel>
<xul:checkbox />
</xul:tabpanel>
<xul:tabpanel>
<xul:textbox />
</xul:tabpanel>
<xul:tabpanel>
<xul:datepicker />
</xul:tabpanel>
</xul:tabpanels>
</xul:tabbox>
</script>
index.css
#namespace xul url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
xul|tab:focus {
color: red;
}
index.js
function fOnSelect(oEvent) {
alert(oEvent.currentTarget.selectedItems.length)
}
As i know there are no specific patterns for Javascript yet. But I think there is a potential for something like widgets(component) approach. Since mainly we use javascript to empower our html code. It is logically that we should connect our every javascript object to html tag. So here we have something like Model(jsObject)+View(HTMLrepresentation). To get MVC we need controllers and we have Events for this. In this case we will have incapsulated easily extensibel component.
for example:
// this is a part of some FormValid.js
<script>
function FormValid(){
}
FormValid.prototype.validate=function(){...}
</script>
//this is our HTML
<form id="form1"...onsubmit="this.jsObject.validate();">
</form>
<script>
//all the following stuff could be solved in one line, but you need to create some helper. Like Components.Attach("FormValid").to("form1");
var newObj=new FormValid()
var form=document.getElementById("form1");
from.jsObject=newObj;
newObj.htmlObj=form;
</script>
Also I have an idea of using template engines like Zparser to separate view and model. I am developing js library for this, so I am in this question right now.
We have core object with view method. All our classes have it like a prototype at he end. This method gets templates property of class and using some templates parser generates HTML basing on our model. This HTML is inserted in htmlObj node so the VIEW of our object is updated. This is basically an idea and our code becomes:
// this is a part of some FormValid.js
<script>
function FormValid(){
}
Components.extendCore(FormValid);
FormValid.prototype.validate=function(){...}
</script>
FormValid.prototype.templates={
main:'<form class="form1"...onsubmit="this.jsObject.validate();">...</form>'
}
//this is our HTML
<div id="form1"></div>
<script>
Components.Attach("FormValid").to("form1");
</script>
I still think last one inline <script> should be there and it is not mixing logic with representation because this is component - solid piece. It have no meaning one without another. Actually this should be a part of application. Something like html of component(in las one example is div) should be defined and wrapped with component which will automatically add script and ids.
Now. I showed you 2 examples and i will explain why second is too specific. All stuff is in accessibility and performance(and memory leaks). If you will refresh all html of component frequently - it will blink, also you will need to set up all dynamic events back and check everything for memory leaks. But the main problem if JS will fail - your application will show nothing.
So i prefer to have choice between those two:) and use everything on their places.
Check out a site called quince. I am not sure how many patterns here are javascript ui patterns. But this is a pretty good resource for ui patterns
Patterns aren't always language agnostic. A lot of classic design patterns are pointless in JavaScript because we don't need a lot of the workaround that they solve in stricter langauge paradigms.
The reason MVC isn't such a hot fit for client-side web development, however is more situational.
First of all I think time and pain have proven that typical web applications are best treated as two separate applications. The one that happens on the browser and the one that happens on the server. The fewer dependencies you establish between the two, the more flexible, maintainable and easier web apps have been to modify in my experience.
The M is business logic (which people tend to incaccurately conflate with "database layer" IMO).
The problem with MVC in that scenario is that we don't want to expose business logic on the client-side and attempting to munge the whole app into one hideous http-divide-hiding construct has proven painful as I mentioned.
Very similar patterns where you separate data or "view model" concerns can work fairly well, however.