Rendering template within context in Handlebars - handlebars.js

Is it possible to render a template, or even just a partial, from within the context passed to a top level template? It seems like this might require recursive rendering, but maybe I'm missing something.
The example below demonstrates this using Bootstrap.
Say this is my top level template:
<div class="panel">
<div class="panel-body">
{{{description}}}
</div>
</div>
And my context is:
{
description: "\
Some text before the warning.\
<div class=\"alert alert-warning\" role=\"alert\">\
<span class=\"glyphicon glyphicon-warning-sign\" aria-hidden=\"true\"> </span>\
My warning here.\
</div>\
Some text after the warning."
}
What I'd like to do is separate the alert into a partial for a number of reasons:
Arbitrary placement within surrounding text
Can make partials for types other than warning (danger, info, etc.)
Can add as many as needed interspersed in the context string
For these reasons, it seems like it's not possible to put it into the top level template.
The partial would look something like this:
<script id="partial-warning-template" type="text/x-handlebars-template">
<div class="alert alert-warning" role="alert">
<span class="glyphicon glyphicon-warning-sign" aria-hidden="true"> </span>
{{{warning-message}}}
</div>
</script>
Once this is in place, I would be able to use it like so:
{
description: "\
Some text before the warning.\
{{> partial-warning-template \"My warning here.\"}}\
Some text after the warning.\
{{> partial-warning-template \"Now adding a second warning.\"}}"
}
Maybe I'm missing something fundamental - is there a more idiomatic way of doing this?

You won't be able to include the partial blocks in the description value and expect them to be evaluated as partials by the top level template method; the entire description string will be spat out as a single literal string.
What you would need to do is to have the partials evaluated before you pass the context object with description to the top level template method.
If you have pre-compiled your partial in something like the following manner:
Handlebars.registerPartial('warn', Handlebars.compile(document.getElementById('partial-warning-template').innerHTML));
Then you will be able to call this partial when you construct your description string:
{
description: 'Some text before the warning.' +
Handlebars.partials.warn({ 'warning-message': 'My warning here.' }) +
'Some text after the warning.' +
Handlebars.partials.warn({ 'warning-message': 'Now adding a second warning.' })
}

Related

Add CSS to ScalaHelpers

How do i add some CSS to the Scala Helpers, and is it possible to remove the "Required" and "Numeric" text under the textfield?
#inputText(advForm("weeknr"))
#inputText(advForm("jaar"))
#inputText(advForm("datum"))
--------------------EDIT 1------------------
When I add my own CSS, im not getting the error warnings that i used to get when I try to upload an empty form, the text used to turn red. This is the code I changed
MyPlainFieldConstructor.scala.html(only 2 lines of code):
#(elements: helper.FieldElements)
#elements.input
advPlaatsen2.scala.html:
Added this line of code
#implicitField = #{ FieldConstructor(myPlainFieldConstructor.f) }
and this is how i placed the CSS(Foundation 5):
<div class="row collapse">
<div class="small-2 columns">
<span class="prefix">Email</span>
</div>
<div class="small-4 left columns">
#inputText(advForm("email"),
'id -> "right-label",
'placeholder -> "")
</div>
</div>
This way the forms looks how I want it to look but it doesnt show me errors and it doesnt even upload my files
but when i remove this line of code:(which is above the #import helper._)
#implicitField = #{ FieldConstructor(myPlainFieldConstructor.f) }
the form works as it should but looks really bad:
To customize the html and styles of a field you can write your own field constructor. Take a look to play docs here.

How do i get an onload function on the body for a specific template using meteor.js?

I'm trying to get the following behavior for a certain template:
<body onload="someInitFunction();">
Let's say i have the following markup (i'm using mrt router, not iron-router, for {{renderPage}}):
// Main Template
<head>
<title>meteorite-knowviz</title>
</head>
<body>
{{> header}}
<div class="container-fluid">
<div class="row">
{{renderPage}}
</div>
</div>
{{> footer}}
</body>
That renderPage is the secondTemplate:
<template name="secondTemplate">
{{#if currentUser}}
<div class="col-md-2">
<div class="list-group">
<a class="list-group-item" href="{{render thirdTemplate please...}}">Third Template</a>
<a class="list-group-item" href="{{render fourthTemplate please...}}">Fourth Template</a>
</div>
</div>
// In this case let's say thirdTemplate gets rendered
{{render the choice taken above please...}}
{{/if}}
</template>
And within this template, depending on which link was clicked on, (in this case the third) there will finally be a thirdTemplate, which will show a data visualization with some help by a javascript framework, which will be in need of a <body onload="initFunction();">in order to display the data:
<template name="thirdTemplate">
<div class="col-md-5">
<h2>THIS!! section needs a "<body onload="initFunction();"> in order to work" ></h2>
</div>
<div class="col-sm-5">
<h2>Some other related content here</h2>
</div>
</template>
To sum up i have three questions:
1a. How could i get the third template to get a <body onload="initFunction();">
2a. In which way can i render different templates within the secondTemplate?
2b. Can i use a {{renderPage}} within this template even though this template is the renderedPage in the main template or should i do it in some other way?
In order to get the <body onload="initFunction();"> i had to do the following:
First add the following function to a .js file in the client folder:
Template.thirdTemplate.rendered = function() { // Template.thirdTemplate.created - also worked.
$('body').attr({
onload: 'init();'
});
}
This however got me an error saying that initFunction is not defined. In an standard html page my could work just fine, but in meteor i had to change my function from:
function initFunction(){
//what ever i wished to do
}
To:
init = function() {
//what ever i wished to do
}
Regarding the rendering of pages, iron-routing is the way to go since the router add on is not under development any more.
1a. How could i get the third template to get a <body
onload="initFunction();">
You probably want to call initFunction when the third template has been rendered, so just put your call to it in the rendered callback.
Template['thirsTemplate'].rendered = function(){
initFunction()
}
2a. In which way can i render different templates within the
secondTemplate?
2b. Can i use a {{renderPage}} within this template even though this
template is the renderedPage in the main template or should i do it in
some other way?
Listen for clicks on the links, and when one happen you manually render the desired template (possible with Meteor.render, if you need reactivity) and add it to the right node in the document. See this question.
It may be possibly to achieve with router (I don't know that package).
I think that what you want to use is the created callback, that will be called each time your template is created, and not the rendered callback, that would be called each time a change has caused the template to re-render.
Template.thirdTemplate.created = function(){
initFunction()
}
See the documentation for templates for other types of callbacks: http://docs.meteor.com/#templates_api

Handlebars.js pass html in expression

Handlebar template
<div>
{{contentText}}
</div>
JS
var contentText = {contentText: "<table><tr><td>Some Data<\/td><\/tr><\/table>"}
Handle bars render displays the HTML as string rather than rendering the HTML.
Where am I going wrong ?
From the fine manual:
Handlebars HTML-escapes values returned by a {{expression}}. If you don't want Handlebars to escape a value, use the "triple-stash", {{{.
So if you want to put contentText straight into the template as-is then you want:
<div>
{{{contentText}}}
</div>
in your template.
Demo: http://jsfiddle.net/ambiguous/f7LJ5/

angular js dom manipulation with directives

I am trying to use angular directives to dynamically replace an html portion of a portlet of a page.
The html portlet has 2 sections embedded. The top part has the heading which is obtained from a different backend service
<div class="headerdiv">
<h3 class='headerclass'> Object Heading </h3>
</div>
The content is loaded in to a different section
<div id="objectDiv" ng-controller="ObjectCtrl">
<div ng-show="object.title" mydirective><b>{{object.title}} </b></div>
<div element-trigger><b>{{object.name}} </b></div>
<div element-trigger><b>{{object.description}} </b></div>
</div>
The controller loads the details successfully
The new directive added is
app.directive('mydirective', function(){
return function(scope, elem, attrs){
//obtain old header
var oldHeader = angular.element( '.headerdiv .headerclass' );
//get the new header
//replace old header with new header
}
});
I need to dynamically change the heading in headerdiv with the object.title value . Note that the new directive is bound to the filed that is listening to the object.title div.
I dont think this is the right use of directive, as the directive should be used to affect the functionality of element on which it is defined in most of the cases.
What you can try to do is in ObjectCtrl define a watch on title property, and then broadcast the message
$scope.$watch('object.title',function(newValue) {
$rootScope.$broadcast('titleChanged',newValue); //You can pass any object too
});
If you header is contained inside a controller catch the event
$scope.$on('titleChanged',function(args) {
//Code to handle the title update
});
The html for header should have binding expression for title
<div class="headerdiv">
<h3 class='headerclass'> {{title}} </h3>
</div>
Note: I am not sure about the structure of the html but this all would not be required if the header and the content inside the ObjectCtrl are using the same\shared model (object).

Rails - Error CSS styles

New to rails, and am experimenting with changing default layouts.
It seems that the .field_with_errors class is always being added to my forms, when a field causes a validation error. The default scaffold CSS defined field_with_errors as:
.field_with_errors {
padding: 2px;
background-color: red;
display: table;
}
My question is: Why even use this .field_with_errors? Where is it even coming from? Same with a div with ID of notice to print success messages. Where is this coming from?... From my research both of these coming somewhere from ActionView::Helpers.
But what if I wanted to use my own custom styles for these? Do I have to write my own .fields_with_errors and notice classes in my application.css.scss file? I tried this and it works... But why do I have to jail myself to those class names? What if I wanted to call them something else? Can I do this?
Secondly, let's say I have my own custom CSS classes now (assuming it's possible -- which I hope it is)... What if I wanted to apply a bootstrap style to them? For example, bootstrap would use <div class="alert alert-success"> where Rails' scaffold would default to using <div id="#notice">... How can I make such changes in the most elegant way without simply making my own style with the same CSS code as Twitter's alert alert-success.... Isn't there a way in SASS (or through Rails somehow) to say, Success messages are printed with XYZ style and error fields are printed with ABC style... Like maybe in some config file?
Thanks!
Can I do this? yes.
The extra code is being added by ActionView::Base.field_error_proc. If you want to call something else and you're not using field_with_errors to style your form, You should override it in config/application.rb
config.action_view.field_error_proc = Proc.new { |html_tag, instance|
"<div class='your class'>#{html_tag}</div>".html_safe
}
Restart your server
Secondly, If you want to apply a bootstrap style to them, You can save your selection style on application_helper.rb
module ApplicationHelper
def flash_class(level)
case level
when :notice then "alert alert-info"
when :success then "alert alert-success"
when :error then "alert alert-error"
when :alert then "alert alert-error"
end
end
end
create file layouts/_flash_message.html.erb and paste this :
<div>
<% flash.each do |key, value| %>
<div class="<%= flash_class(key) %> fade in">
×
<%= value %>
</div>
<% end %>
</div>
and to call the flash you just render in view
<%= render 'layouts/flash_messages' %>
Example
On accounts_controller.rb create action
def create
#account = Account.new(params[:account])
if #account.save
# using :success if #account.save
flash[:success] = "Success."
redirect_to accounts_url
else
flash[:alert] = "Failed."
render :new
end
end
Put on top of accounts/index.html.erb and on top of form in accounts/_form.html.erb
<%= render 'layouts/flash_messages' %>
Result on index :
<div class="alert alert-success">
<button type="button" class="close" data-dismiss="alert">×</button>
Success.
</div>
Result on form :
<div class="alert alert-error">
<button type="button" class="close" data-dismiss="alert">×</button>
Failed.
</div>
#anonymousxxx answer seems to be correct in my opinion.
I would recommend you to use the twitter-bootstrap-rails gem (https://github.com/seyhunak/twitter-bootstrap-rails) for your css. check out the readme on github, this gem is really convenient.

Resources