get clean HTML from emberjs handlebars application - javascript

I've been building a HTML (email/page) composition tool in Ember.js as a way of getting my head round it, I guess it's a sort of WYSIWYG.
A user adds various objects with different values (link, text etc.), the objects can have different templates and be arranged with jQuery UI which feeds back to the controller. What the user sees on screen is actually spot on and I am currently saving and reloading clean JSON from localstorage as a method of persistence.
What I'd really like to do though, is being able to generate a clean HTML version of what the user is seeing. Either from something written into the front end application or by processing the JSON I export on the server side.
I'd like to keep as much in JS, Ember and Handlebars as possible, and Ideally not re-implement too much of my templates/code in different places.
An example of a 'row' in my rendered output is below.
.row-controls is toggled on and off by a global editor toggle.
<script id="metamorph-11-start" type="text/x-placeholder"></script>
<div id="ember507" class="ember-view template-row ui-droppable">
<ul id="ember524" class="ember-view row-controls">
<li class="dragger">drag</li>
<li class="type">type</li>
<li class="edit">edit</li>
<li class="delete">delete</li>
</ul>
<script id="metamorph-12-start" type="text/x-placeholder"></script>
<script id="metamorph-13-start" type="text/x-placeholder"></script>
<h2><a href="http://foo.com/bar" data-bindattr-34="34">
<script id="metamorph-19-start" type="text/x-placeholder"></script>
Link title text
<script id="metamorph-19-end" type="text/x-placeholder"></script>
</a></h2>
<img src="http://foo.com/image.png" data-bindattr-35="35">
<script id="metamorph-20-start" type="text/x-placeholder"></script>
Teaser/synopsis
<script id="metamorph-20-end" type="text/x-placeholder"></script>
Read more
<script id="metamorph-13-end" type="text/x-placeholder"></script>
<script id="metamorph-12-end" type="text/x-placeholder"></script>
</div>
<script id="metamorph-11-end" type="text/x-placeholder"></script>
I guess It might seem like an odd thing to be doing, with limited practical application but I'd like to finish it now I've started :) Also, I think the principles involved in any answer could probably have different application, I just haven't thought of it yet
Thanks! And thanks to the other people on here for answering my previous few questions about Ember.
EDIT
Just be clear, I'm talking about getting output like this
<h2>Link title text</h2>
<img src="http://foo.com/image.png">
Teaser/synopsis
Read more
SOLUTION EDIT
In case anyone finds this link - I've added (to my standard JS version) a check for attr within the attribute loop.
<script>
// ...
return $.each($this[0].attributes, function(index, attr) {
// this bit added
if(!attr) {
return;
}
if (attr.name.indexOf('data-bindattr') === -1) {
return;
}
// ...
</script>
It could have been an error in some other code I had going on, but jQuery was passing 'undefined' as attr in the loop. jQuery seems to want to resolve the whole each function so I couldn't debug exactly what this was. The check seems to be working for me at the moment though.
Not sure how to factor into the particular original coffeescript file I'm afraid.

ghempton from CodeBrief talks a little about it on this awesome post: http://codebrief.com/2012/03/eight-ember-dot-js-gotchas-with-workarounds/
Check tip 7.
Read all of them too, its worth it.
By the way, it's on coffeescript the post, if you need to get the JS version go to http://coffeescript.org/ on the Try Coffeescript tab and convert it!

Related

My div show/ hide code works fine on a static HTML page but doesn't work on a Wordpress 3.5.1 page

This is sort of a condensed version of the code, the real version is too long to post but this is enough to represent the concept. I am using this to switch guitar diagrams based on several choices represented by anchors with the corresponding id in the href="". After spending several days getting it to work just right on a static html page, the script won't work in a Wordpress page which is where I intend to use it. I have tried it with the script in the head or inline (which shouldn't matter) - but either way it will not function. I know that Wordpress and certain plugins use Jquery so there may be a version mismatch causing conflicts. I am not (yet) an expert in javascript but I know there are several ways to skin a cat as the saying goes, I just need to find one that plays nice with Wordpress. Any help would be greatly appreciated...
<script src="http://code.jquery.com/jquery-1.8.3.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
var divswitch = $('div.diagram_container a');
divswitch.bind('click',function(event){
var $anchor = $(this);
var ids = divswitch.each(function(){
$($(this).attr('href')).hide();
});
$($anchor.attr('href')).show();
event.preventDefault();
});
});
</script>
<style>
.diagram {
margin: 0;
width: 100%;
}
.diagram_container {
width: 100%;
}
</style>
<div id="RH_RW_Div" class="diagram_container" style="float:left; display:block;">
<div class="diagram_menu">
<a class="checked" href="#RH_RW_Div"><span class="checkbox_label">Right Handed</span></a>
<a class="unchecked" href="#LH_RW_Div"><span class="checkbox_label">Left Handed</span></a>
</div>
<img class="diagram" src='images/RH_RW.gif' /><br />
</div>
<div id="LH_RW_Div" class="diagram_container" style="float:left; display:none;">
<div class="diagram_menu">
<a class="unchecked" href="#RH_RW_Div"><span class="checkbox_label">Right Handed</span></a>
<a class="checked" href="#LH_RW_Div"><span class="checkbox_label">Left Handed</span></a>
</div>
<img class="diagram" src='images/LH_RW.gif' /><br />
</div>
Wordpress uses by default jQuery.noConflict(). This is to assure that there is no conflict by other libraries using the $ variable. That's why your console says it's not a function.
However, obviously, the jQuery variable still works, and you should use that, and passing to your function the $ variable yourself to enable the shorthand version of jQuery.
So your code should look like this:
jQuery(document).ready(function($){
// Your functions go here
});
My guess is that your Wordpress install or a plugin is already loading up jQuery in the head. Check to see if it exists there, and if it does, don't call it again.
If that doesn't do it and you have this site online, send me the link and I'll take a look.
Calling jQuery twice will often lead to problems. There is also a proper way to load jQuery and override the Wordpress version if you specifically need 1.8.3 (wp_register_script and wp_enqueue_script), but I don't think you need to go down that route yet.

How to merge server-side templating and AJAX to maximize reusability

Consider the following general issue before I go to the specific problem: You use server-side templating (e.g. Smarty) to generate a page in a particular way depending on a particular state. However, you can also change the state and update that page dynamically using Javascript. How do you construct such a system that does not involve replicating one's work in both Javascript and PHP?
Now, for the specific question that relates to the above. I have a navigation bar for an educational website. Depending on the URL provided by the user, you can be at various levels of navigation: field, subject, course, section, lesson. For example, if the user accesses the following index.php?field=Social_Sciences, the following XML will be returned and parsed by PHP and sent to Smarty such that the appropriate subjects are listed:
<subjects>
<subject>
<id>81</id>
<name>Sociology</name>
<description>Sociology</description>
<path>/data/material/Social_Sciences/Sociology/</path>
</subject>
<subject>
<id>82</id>
<name>Economics</name>
<description>Economics</description>
<path>/data/material/Social_Sciences/Economics/</path>
</subject>
</subject>
Similarly, if a user goes to index.php?field=Social_Sciences&subject=Economics, PHP would parse the following and send it to Smarty:
<courses>
<course>
<id>65</id>
<name>Introduction to Microeconomics</name>
<description>Introduction to Microeconomics</description>
<path>
/data/material/Social_Sciences/EconomicsIntroduction_to_Microeconomics/
</path>
</course>
<course>
<id>66</id>
<name>Introduction to Macroeconomics</name>
<description>Introduction to Macroeconomics</description>
<path>
/data/material/Social_Sciences/EconomicsIntroduction_to_Macroeconomics/
</path>
</course>
</courses>
Now, the problem is the user can also dynamically navigate using AJAX--that is, they can click through the navigation without reloading the page. That means the navigation XML then has to be parsed by jQuery, which means I have to write the same code to parse the XML twice--once in PHP and once in Javascript. After this system proved unwieldy, I started only using AJAX even on the initial load but this is sub-optimal in terms of speed and number of requests. (If you think this is trivial, there are other examples of such issues in my code.) How can one continue to use PHP templating and dynamic AJAX updating without re-writing the same parsing code twice in both languages?
JSON
If you're php actions were returning JSON objects, then I would recommend jQuery's beta product .template()
In a perfect world, you're in html 5 and can send the jQuery.template() parser equivalents of your smarty work from the server outright, as found on pandora.com's html 5 enabled player if you look at the bottom of the page source. it will kind of look like this:
<!DOCTYPE html>
<html>
<head>
<!--- pilfered from jQuery.com's demo linked above --->
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#aControl").click(function(event){
$.get("/your/url").success(function(text, response, jQxhr){
$("#iWillPrintACourseTemplate").tmpl(response).appendTo("#tbodyDestination");
}).error(function(text, response, jQxhr){
});
});
});
</script>
</head>
<body>
<script id="iWillPrintACourseTemplate" type="text/x-jquery-tmpl">
<tr class="detail"><td><p>stuff : ${id} - ${}</p><p>${description}</p><p>${path}</p></td></tr>
</script>
<div><a id="aControl" href='#'>click me</a></div>
<table>
<thead/>
<tfoot/>
<tbody id="tbodyDestination">
</tbody>
</table>
</body>
</html>
not html 5
then you have to move the jQuery html 5 <script type='text/x-jquery-tmpl'/> declaration into your javascript via a $.template("name", html with templating ${} in it); i would get the html with templating ${} stuff via an ajax call. Why? I would try to keep your html templates server side. to allow easy translation between a SMARTY template and a jQuery.Template() should their syntax ever diverge.

Display element from other page on my site with .document.getElementById

I have been searching about this subject now for quite a few days. And could not find a working or conclusive answer.
What I want to do, is to simply display the (styled) summary of the latest blog entry (from the blog page on my own site) in a div container on the front page of my site (which is not my blog). All active links of that mirrored blog entry ideally lead to the appropriate section of my blog page. That is however not a must, as long as the entire entry can link to the blog page.
Each blog entry summary on the blog summary page has a unique ID, sorted by numbers (e.g. unique-ID-51 (latest) unique-ID-50 (the one before) etc.)
I was thinking of doing so with the document.getElementById JS command.
I would have to point the JS function to a relative location (../blog_folder/blog_summary.html) with maybe the .window.location.assign
command, than grab the (styled) contents of the latest element and display that on my front page.
But I have no idea how that code would look in reality. Can you point me in the right direction?
Thank you !!!!!!!
M.
You could add jQuery to your page and use a simple construction:
$('.result-container').load('path/to/your/file.html #id_of_element_to_fetch');
An example chunk of code:
...
<body>
<div class="result-container">There will be your content from some file.</div>
<p>
<a class="result-loader" href="#"></a>
<script type="text/javascript">
$(".result-loader").click(function() {
//Replace path/to/your/file.html and #id_of_element_to_fetch with appropriate values
$('.result-container').load('path/to/your/file.html #id_of_element_to_fetch');
return false;
});
</script>
</p>
</body>
...
And that string somewhere inside the <head> tag:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
An example chunk of code with an autostart feature:
...
<body>
<div class="result-container">There will be your content from some file.</div>
<p>
<a class="result-loader" href="#"></a>
<script type="text/javascript">
$(document).ready(function() { //Launches the code below right after the initialization event
//Replace path/to/your/file.html and #id_of_element_to_fetch with appropriate values
$('.result-container').load('path/to/your/file.html #id_of_element_to_fetch');
return false;
});
</script>
</p>
</body>
...
I assume you are using a hidden iframe?
This for example will thet the height of the style.. there are other things in the style
this.container.getElementsByTagName("YOUuniqueID")[0].style.(STYLE)
But you have to put an unique ID in the iframe
Try and use the built in debuggers in IE or Chrome to find what you want...
You can take a look at this for maybe some more info(its for cross domain) but there could be something taht helps you. You might even consider using jquery to access that data.
Yet Another cross-domain iframe resize Q&A

Should I use template or return full code in jquery AJAX?

I am currently working on a project that lets users post comments with jquery and ajax. So far it is using Json and retunring several items, username, comment text, user photo url, comment ID number and stuff like that, I then need to use some sort of template to make all this data go into the correct div's before adding it all to the screen.
I am new to using javascript so this is a hard task for me. I am now considering the easy route.
Just have my PHP backend script return the whole block of code, div's and everything in place but I am wondering is this a bad idea? More importantly is it a bad idea with json?
Here is an example of a block of code that needs to be added to the screen when a comment is posted
<li class="admin" id="comment-1371">
<div class="photocolumn">
<!-- START Photo block -->
<div class="imageSub" style="width: 100px;">
<img class="male" src="http://cache2.mycrib.net/images/image_group34/0/39/T_653807517aff2b1f5662d865b40d87d527c8eb.jpg" alt="Something" width="100"/>
<div class="blackbg"></div>
<div class="label">JasonDavis</div>
</div>
<!-- END Photo block -->
</div><!-- END photocolumn -->
<div class="commenttext">
<p>02/12/3009</p>
<p>sample text for comment area!</p>
</div>
<!-- END COMMENTTEXT -->
</li>
I would say it depends on the situation/application. For instance I would use json and templating for a flight/hotel etc result screen. Why return 50k's worth of the same markup when a 4k json object will do and will allow for rapid clientside sort/filter. If you dont need quick clientside filtering/sorting then responding with dom fragments is ok. Horses for courses.
I don't see a problem with returning HTML via AJAX. A bonus of this is that you can generate most of the HTML in a view in PHP and still keep things fairly clean.
Tokenizing your data into an object is nice for re-use but can be overkill for a one-off.
Go the easy route, I can see no reasons of going with JSON array.

How do you write Valid XHTML 1.0 Strict code when you are using javascript to fill an element that requires a child?

I'm running my site through the W3C's validator trying to get it to validate as XHTML 1.0 Strict and I've gotten down to a particularly sticky (at least in my experience) validation error. I'm including certain badges from various services in the site that provide their own API and code for inclusion on an external site. These badges use javascript (for the most part) to fill an element that you insert in the markup which requires a child. This means that in the end, perfectly valid markup is generated, but to the validator, all it sees is an incomplete parent-child tag which it then throws an error on.
As a caveat, I understand that I could complain to the services that their badges don't validate. Sans this, I assume that someone has validated their code while including badges like this, and that's what I'm interested in. Answers such as, 'Complain to Flickr about their badge' aren't going to help me much.
An additional caveat: I would prefer that as much as possible the markup remains semantic. I.E. Adding an empty li tag or tr-td pair to make it validate would be an undesirable solution, even though it may be necessary. If that's the only way it can be made to validate, oh well, but please lean answers towards semantic markup.
As an example:
<div id="twitter_div">
<h2>#Twitter</h2>
<ul id="twitter_update_list">
<script type="text/javascript" src="http://twitter.com/javascripts/blogger.js"></script>
<script type="text/javascript" src="http://twitter.com/statuses/user_timeline/stopsineman.json?callback=twitterCallback2&count=1"></script>
</ul>
</div>
Notice the ul tags wrapping the javascript. This eventually gets filled in with lis via the script, but to the validator it only sees the unpopulated ul.
Thanks in advance!
The following fragment is valid XHTML and does the job:
<div id="twitter_div">
<h2 class="twitter-title">Twitter Updates</h2>
<div id="myDiv" />
</div>
<script type="text/javascript">
var placeHolderNode = document.getElementById("myDiv");
var parentNode = placeHolderNode.parentNode;
var insertedNode = document.createElement("ul");
insertedNode .setAttribute("id", "twitter_update_list");
parentNode.insertBefore( insertedNode, placeHolderNode);
parentNode.remove(placeHolderNode);
</script>
<script type="text/javascript" src="http://twitter.com/javascripts/blogger.js"></script>
<script type="text/javascript" src="http://twitter.com/statuses/user_timeline/stopsineman.json?callback=twitterCallback2&count=5"></script>
Perhaps you could use javascript to write the initial badge HTML? You'd probably only want the badge code to be inserted in your document if javascript were available to populate it, right?
You'd just need to make sure your document writing happens before the javascript for your various badges.
Could you give a specific example of the HTML / link to a page with the invalid code?
The solutions might be different for each badge. In Twitter's case, you can just write your own callback function. Here's an example based on their badge code:
<div id="twitter_div">
<h2>#Twitter</h2>
<div id="twitter_update_list"></div>
</div>
<script type="text/javascript">
function updateTwitterCallback(obj)
{
var twitters = obj;
var statusHTML = "";
var username = "";
for (var i = 0; i < twitters.length; i++)
{
username = twitters[i].user.screen_name;
statusHTML += ('<li><span>' + twitters[i].text + '</span> <a style="font-size:85%" href="http://twitter.com/' + username + '/statuses/' + twitters[i].id + '">' + relative_time(twitters[i].created_at) + '</a></li>');
}
document.getElementById('twitter_update_list').innerHTML = '<ul>' + statusHTML + '</ul>';
}
</script>
<script type="text/javascript" src="http://twitter.com/javascripts/blogger.js"></script>
<script type="text/javascript" src="http://twitter.com/statuses/user_timeline/stopsineman.json?callback=updateTwitterCallback&count=1"></script>
I put a <li> with "display:none" in the <ul> Tag:
<ul id="twitter_update_list"><li style="display:none;">A</li></ul>
<script type="text/javascript" src="http://twitter.com/javascripts/blogger.js"></script>
<script type="text/javascript" src="http://twitter.com/statuses/user_timeline/01241.json?callback=twitterCallback2&count=1"></script>
This does not disturb the script and in this case it works,
and I think its not a "undesirable solution" :)
At some point the page becomes valid, right? That's the only time it can really be validated.
I'm not sure a non-trivial page will remain valid at every point during its construction if it's constructed with a lot of DOM scripting.
This might not be the most popular opinion on this topic, but...
Don't worry about 100% validation. It's just not that big of a deal.
The point of validation is to make your markup as standard as possible. Why? Because browsers that are given markup that doesn't conform to the spec (eg, markup that does not validate) do their own error checking to correct it and display the page the way you intended it to look to the user. The quality of the browsers error checking varies, yadda-yadda-yadda, it's better to have valid markup... But it's not even your code that's causing the validation to fail! The people who wrote those badges probably tested them in multiple browsers (and you should do the same, of course), if they work as expected then just leave it at that.
In short, there's no prize for validating :)

Categories