Handlebar block helper doesn't work as it should - ember.js

I try to use the code from Defining a block helper with Handlebars to create a block helper. http://jsfiddle.net/6Jaya/ by #danii shows that it should work. But it doesn't. I get the following output:
Is this a bug or do I miss something?
app.js
App = Ember.Application.create();
Handlebars.registerHelper('link', function(options) {
var result = '<a href="http://www.example.com">'
+ options.fn(this)
+ '</a>';
console.log(result);
return new Handlebars.SafeString(result);
});
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Example</title>
</head>
<body>
<script type="text/x-handlebars">
<p>
{{#link}}
<img src="http://placekitten.com/50/50">
{{/link}}
</p>
</script>
</body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="js/handlebars.js"></script>
<script type="text/javascript" src="js/ember.js"></script>
<script type="text/javascript" src="js/app.js"></script>
</html>

Why don't you just use? Is there a specific reason for this?
Handlebars.registerHelper('link', function(value) {
var result = '<a href="http://www.example.com">'
+ value
+ '</a>';
console.log(result);
return new Handlebars.SafeString(result);
});

Related

Ember - Missing helper action for HBS files

I have written a html with a div.
I have two hbs files. I rendered one as partial and other as normal. I am not able to invoke action on the templates. I am getting missing helper error.
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ember Starter Kit</title>
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div id="holder">
</div>
<script src="js/libs/jquery-v1.11.1.js"></script>
<script src="js/libs/handlebars-v1.3.0.js"></script>
<script src="js/libs/ember-v1.6.1.js"></script>
<script src="js/libs/ember-data.js"></script>
<script src="js/app.js"></script>
</body>
</html>
JS:
var data={title: "My New Post", body: "This is my first post!"};
function getTemplate(templateName,hbsPath,type){
$.ajax({
url: hbsPath, //ex. js/templates/mytemplate.handlebars
cache: true
}).done(function (src) {
if (type === "partial") {
Handlebars.registerPartial(templateName, $(src).html());
} else {
template = Handlebars.compile($(src).html());
temp=template(data);
$("#holder").append(temp);
}
});
}
getTemplate("dummy","/Test/templates/dummy.hbs","partial");
getTemplate("dummy","/Test/templates/application.hbs");
App = Ember.Application.create({});
App.Router.map(function(){
this.resource('dummy');
});
App.ApplicationController=Ember.ObjectController.extend({
needs:['dummy'],
actions:{
refresh: function(){
alert("application template refresh");
}
}
});
App.DummyController=Ember.ObjectController.extend({
actions:{
refresh: function(){
alert("dummy template refresh");
}
}
});
HBS:
application.hbs:
<script id="application" type="text/x-handlebars-template">
{{> dummy}}
</script>
dummy.hbs:
<script type="text/x-handlebars" data-template-name='dummy'>
<div {{action 'refresh' target="controllers.dummy"}}>
Refresh
</div>
<div {{action 'refresh'}}>
Refresh
</div>
</script>
The code in ur demo and the code in question are different. Here is a fixed demo based on the code in ur question.
Fixing the demo u provide may need you to include the vanilla handlebars library as ember is now using HTMLBars which is built on top of handlebars but a bit different.
Em.Handlebars.compile is now actually using HTMLBars compile method. You can see here.
You may need to use something like https://github.com/rwjblue/broccoli-ember-inline-template-compiler

Trying to get QUnit working with Emberjs

I'm trying to setup ember-testing with QUnit to test my Ember.js application.
My problem is the app isn't rendering on the QUnit test page, and thus the visit('/') function isn't working.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>MKTS Tests</title>
<meta name="viewport" content="width=device-width" />
<link rel="stylesheet" href="./bower_components/qunit/qunit/qunit.css">
<!--
<link rel="stylesheet" href="./css/foundation.css">
<link rel="stylesheet" href="./css/app.css">
-->
<style type="text/css">
#qunit-fixture, #app-root {
position: relative;
top: 0;
left: 0;
width: auto;
height: auto;
}
</style>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<!-- Libraries (Dependencies) -->
<script src="../app/bower_components/requirejs/require.js"></script>
<script src="../app/bower_components/jquery/dist/jquery.min.js"></script>
<script src="../app/bower_components/handlebars/handlebars.js"></script>
<script src="../app/bower_components/ember/ember.js"></script>
<script src="../app/bower_components/ember-data/ember-data.js"></script>
<!-- App and Templates -->
<script src="../app/scripts/app.js"></script>
<script src="../app/scripts/models/fleets.js"></script>
<script src="../app/scripts/routes/application_route.js"></script>
<script src="../app/scripts/routes/index_route.js"></script>
<script src="../app/scripts/router.js"></script>
<script src="../app/scripts/store.js"></script>
<!-- Test Helpers -->
<script src="./support/test_helper.js"></script>
<!-- Test Library -->
<script src="./bower_components/qunit/qunit/qunit.js"></script>
<script src="./spec/integration.js"></script>
<script src="./spec/unit.js"></script>
</body>
</html>
integration.js
test('hello world', function() {
//debugger;
//expect(1);
MarketSetupAdminUi.reset();
visit("/").then(function() {
var title = find('title');
equal(title.text(), 'Market Setup Tool', 'Title check');
});
});
test-helper.js
(function (host) {
var document = host.document;
var App = host.MarketSetupAdminUi;
var testing = function(){
var helper = {
container: function(){
return App.__container__;
},
controller: function( name ){
return helper.container().lookup('controller:' + name);
},
path: function(){
return helper.controller('application').get('currentPath');
}
};
return helper;
};
Ember.Test.registerHelper('path', function() {
return testing().path();
});
Ember.Test.registerHelper('getFoodController', function() {
return testing().controller('food');
});
// Move app to an element on the page so it can be seen while testing.
document.write('<div id="test-app-container"><div id="ember-testing"></div></div>');
App.rootElement = '#ember-testing';
App.setupForTesting();
App.injectTestHelpers();
function exists(selector) {
return !!find(selector).length;
}
}(window));
I updated the app to Ember 1.10.0 and Ember-data beta.15.
I'm planning to regenerate the app using Ember-CLI, which appears to have better testing.

Making an ajax call and loading the string return by that call into a label in emberJS

I am new to EmberJs. I want to make an ajax call which returns a string. And once I get the data from the ajax call, I want to load the data into a label. Where can I find a simple example for same.
Here's a simple version of what you're asking:
//js
App = Ember.Application.create();
App.IndexView = Ember.View.extend({
didInsertElement: function() {
Em.run.later(function() {
$.getJSON('http://baconipsum.com/api/?callback=?', {
'type': 'meat-and-filler',
'start-with-lorem': '1',
'paras': '3'
},
function(baconGoodness) {
if (baconGoodness && baconGoodness.length > 0) {
$("#bacon").html('');
for (var i = 0; i < baconGoodness.length; i++)
$("#bacon").append('<p>' + baconGoodness[i] + '</p>');
$("#bacon").show();
}
});
}, 800)
}
});
/*css*/
html,
body {
margin: 20px;
}
<!-- html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ember Starter Kit</title>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/normalize/2.1.0/normalize.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars-v1.3.0.js"></script>
<script src="http://builds.emberjs.com/tags/v1.6.1/ember.js"></script>
</head>
<body>
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
<div id="bacon">Loading bacon...</div>
</script>
</body>
</html>
As I have no clue what your application looks like, I'll just assume you have a view somewhere in your app that has a template with an html element with an id. If this is not your scenario.. that's fine, use the idea presented here and try to apply in your project.
For this sample, I created an index view with the following template:
<script type="text/x-handlebars" data-template-name="index">
<div id="bacon">Loading bacon...</div>
</script>
It only has a div called #bacon which I'm putting the response from some ajax request into.
Then in the IndexView class I added a handler for didInsertElement with an ajax request. This means that right after the Index view gets inserted into the DOM, it will fire this request.
App.IndexView = Ember.View.extend({
didInsertElement: function() {
Em.run.later(function() {
$.getJSON('http://baconipsum.com/api/?callback=?', {
'type':'meat-and-filler',
'start-with-lorem':'1',
'paras':'3'
},
function(baconGoodness) {
if (baconGoodness && baconGoodness.length > 0) {
$("#bacon").html('');
for (var i = 0; i < baconGoodness.length; i++) {
$("#bacon").append('<p>' + baconGoodness[i] + '</p>');
}
$("#bacon").show();
}
});
}, 800);
}
});
Another approach would be through the Route. You could have that ajax request in the model hook of your route, and then you can simply use handlebars expressions in your template. Something like this:
App = Ember.Application.create();
App.IndexRoute = Ember.Route.extend({
model: function() {
return $.getJSON('http://baconipsum.com/api/?callback=?', {
'type': 'meat-and-filler',
'start-with-lorem': '1',
'paras': '3'
});
}
});
html,
body {
margin: 20px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ember Starter Kit</title>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/normalize/2.1.0/normalize.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars-v1.3.0.js"></script>
<script src="http://builds.emberjs.com/tags/v1.6.1/ember.js"></script>
</head>
<body>
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
<div>{{model}}</div>
</script>
</body>
</html>
That div doesn't need an id anymore, since we are using the controller's model property in the template:
<script type="text/x-handlebars" data-template-name="index">
<div>{{model}}</div>
</script>
Then the route implementation goes like this:
App.IndexRoute = Ember.Route.extend({
model: function() {
return $.getJSON(
'http://baconipsum.com/api/?callback=?', {
'type':'meat-and-filler',
'start-with-lorem':'1',
'paras':'3'
});
}
});
If this code doesn't apply to your scenario, try explaining it a little better. It really depends on what you are doing. Please follow the tutorials, read blogs, watch screen cats... keep your self up to date (not just ember).
This could have been done differently.. in many ways.. so it really depends on what you're doing.

Simple app in Ember.js

I am new in Ember and trying to create a simple application based on the tutorial provided by Ember website and videos.
In the sample below I would like to display two tabs Tab1 and Tab2; when switching to Tab1 it should have "Jan" and "Feb"; when switching to Tab2 it should have "Mar" and "Apr". I can switch between tabs but there is no content in any of them, there are no errors in the console.
Please help me understand why the tab content is empty.
Thanks!
Here is my index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ember test</title>
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/style.css">
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.no- icons.min.css" rel="stylesheet">
</head>
<body>
<script type="text/x-handlebars">
<div class="navbar">
<div class="navbar-inner">
<ul class="nav">
<li>{{#link-to 'tab1'}}Tab1{{/link-to}}</li>
<li>{{#link-to 'tab2'}}Tab2{{/link-to}}</li>
</ul>
</div>
</div>
{{outlet}}
</script>
<script type="text/x-handlebars" id="tab1">
<p>{{field1}}</p>
<p>{{field2}}</p>
</script>
<script type="text/x-handlebars" id="tab2">
<p>{{field3}}</p>
<p>{{field4}}</p>
</script>
<script src="js/libs/jquery-v1.11.1.js"></script>
<script src="js/libs/handlebars-v1.3.0.js"></script>
<script src="js/libs/ember-v1.6.1.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/showdown/0.3.1/showdown.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.1.0/moment.min.js"></script>
<script src="js/app.js"></script>
</body>
</html>
Here is app.js
App = Ember.Application.create();
var tab1 = {
field1: "Jan",
field2: "Feb"
};
var tab2 = {
field3: "Mar",
field4: "Apr"
};
App.Router.map(function() {
this.resource('tab1');
this.resource('tab2');
});
App.tab1Route = Ember.Route.extend({
model: function() {
return tab1;
}
});
App.tab2Route = Ember.Route.extend({
model: function() {
return tab2;
}
});
Ember conventions mandate the name of the classes for your routes. Your Route classes must be named App.Tab1Route and App.Tab2Route, not App.tab1Route and App.tab2Route. The case of the class names is important.
The rest of your code seems fine!

Defining a block helper with Handlebars

I'd like to define a block helper that puts the text in the block into a tag. I used an example from http://handlebarsjs.com/block_helpers.html as a start but my code doesn't work. What do I have to change to get test as the output of this block helper?
app.js
App = Ember.Application.create();
Handlebars.registerHelper('link', function(options) {
var result = '' + options.fn(this) + '';
return Handlebars.SafeString(result);
});
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Example</title>
</head>
<body>
<script type="text/x-handlebars">
<p>
{{#link}}
test
{{/link}}
</p>
</script>
</body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="js/handlebars.js"></script>
<script type="text/javascript" src="js/ember.js"></script>
<script type="text/javascript" src="js/app.js"></script>
</html>
Just a couple of details (EDITED):
You just need to create a new instance of Handlebars.SafeString before returning it. Please check #muistooshort's jsfiddle here with a working example of what you are trying to achieve.
Block helpers are a little bit more complex and used when is needed to invoke a section of a template with a different context. If it is not your case, you could use the syntax for regular Handlebars helpers. (I'll leave the following code here for future reference, although it's not relevant in this case)
Declare helper in app.js:
Ember.Handlebars.registerHelper('link', function(value) {
var result = '' + value + '';
return new Handlebars.SafeString(result);
});
In index.html replace your current template with:
<script type="text/x-handlebars">
<p>
{{link test}}
</p>
</script>
Hope this helps!