I can't register Handlebars helper missing - javascript

I can't register Handlebars helper missing
This code below shows you the condition block in the page:
<table class="table table-striped sorting">
<thead>
<tr class="home">
<th>Title</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
{{#each pages}}
<tr id="id_{{this._id}}" class="{{this.slug}}">
<td>{{this.title}}</td>
<td>Edit</td>
{{#checkhomepage home}}
<td></td>
{{else}}
<td><a class="confirmDeletion" href="/admin/pages/delete-page/{{this._id}}">Delete</a></td>
{{/if}}
</tr>
{{/each}}
</tbody>
</table>
And this code below show you my script code block:
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script>
<script>
$('tbody').sortable({
placeholder: "ui-state-hightlight",
update: function () {
var ids = $('tbody').sortable("serialize");
var url = "/admin/pages/reorder-pages";
$.post(url, ids);
}
});
Handlebars.registerHelper('checkhomepage', function (home) {
if(this.title == home){
return true;
}else{
return false;
}
});
});
</script>
in app.js
// view engine
var expressHbs = require('express-handlebars');
var app = express();
app.set('views', __dirname + '/views/');
app.set('view engine', 'handlebars');
var hbs = require('handlebars');
hbs.registerHelper("HelperMissing", function(value, options)
{
return parseInt(value) + 1;
});
app.engine('handlebars', engines.handlebars);
ReferenceError: engines is not defined
engines inside app.js what can i do to solve this problem

You are trying to create a Handlebars Block Helper, but you have a few issues.
In your template, you have the following:
{{checkhomepage home}}
<!-- Home stuff -->
{{else}}
<!-- Non-Home stuff -->
{{/if}}
This will not work because:
Block helpers must begin with a "#" in the opening tag, before the helper name.
The opening and closing helper tags in the template must match, ie. {{#checkhomepage home}}{{else}}{{/checkhomepage}}`.
You are passing the value of home to your helper. However, it is not apparent that there is a home value in the current context, so this value is probably undefined. Perhaps you want to pass the String "home", in which case, you will need to include quotes: {{#checkhomepage 'home'}}.
Next, in order for a block helper to work, you need to use the options argument. In particular, the options arg has an fn function that will render the template nested within the block, as well as an inverse function that will render what is nested in the else block.
The following is the helper re-written to use these options functions. (I have also renamed the home arg to title for clarity:
Handlebars.registerHelper('checkhomepage', function (title, options) {
if (this.title === title) {
return options.fn(this);
} else {
return options.inverse(this);
}
});
I have created a fiddle for your reference.

now i solved my problem
in past i dont set register helper in correct place
i'll post that code to see it
in app.js set helper into hbs caller like this
// view engine setup
app.engine('.hbs' , expressHbs({defaultLayout : 'layout' , extname : '.hbs' , helpers : {
checkhomepage: function (title, options) {
if (this.title === title) {
return options.fn(this);
} else {
return options.inverse(this);
}
},
if you see set helper function inside app.engine(.......,helper:{//here set your function helper like above
finally ill say thank's 76484 :) because he also help me to fix this issue

Related

handlebars i18n helper inside each loop

I am using express handlebars to generate my view but I am having a problem which is that some of the content inside of my view is not translated properly because I am calling the I18n helper inside of an #each helper.
Index.handlebars :
{{#if roomsList}}
{{#each roomsList}}
<section id="roomNumber-{{RoomNumber}}">
<div class="room-status">
<div class="room-number">
<p>{{RoomNumber}}</p>
</div>
<div class="room-description room-status-{{RoomStatus}}">
<p class="clean">{{i18n "clean"}}</p>
<p class="dirty">{{i18n "dirty"}}</p>
<p class="in-progress">{{i18n "in-progress"}}</p>
<p class="to-inspect">{{i18n "to-inspect"}}</p>
</div>
</div>
<span class="clearfix"></span>
</section>
{{/each}}
{{/if}}
JS:
var Handlebars = require('Handlebars');
var i18n = require('i18n');
module.exports = {
//Setup our default layout
defaultLayout: 'default',
//Register handlebars helpers
helpers: {
//Register your helpers
//Helper for multiple languages
i18n: function () {
return i18n.__.apply(this, arguments);
},
__n: function () {
return i18n.__n.apply(this, arguments);
},
section: function (name, options) {
if (!this._sections) this._sections = {};
this._sections[name] = options.fn(this);
return null;
},
breaklines: function(text) {
text = Handlebars.Utils.escapeExpression(text);
text = text.replace(/(\r\n|\n|\r)/gm, '<br>');
return new Handlebars.SafeString(text);
}
}
}
How am I to resolve the issue?
It works for me:
{{#with ..}}{{i18n "to-inspect"}}{{/with}}
This moves the context upward
Easier and easier-to-read solutions are:
{{../i18n "parameter"}}
The solution above also works for dynamic variables

Cannot load Handlebars helper function

I'm trying to create a custom hbs helper and use it in my page for my express.js application. Here is how I do it but it keeps saying :
Missing Helper "if_eq"
My page:
<html>
<head>
<script src="javascripts/handlebars-v4.0.6.js" type="text/javascript"></script>
<script src="javascripts/hbs_funcs.js"></script>
</head>
<body>
{{#if_eq page "home"}}
<li class="active">LOBBY</li>
{{else}}
<li>LOBBY</li>
{{/if_eq}}
</body>
</html>
Here is my hbs js file:
Handlebars.registerHelper('if_eq', function (a, b, opts) {
if (a == b) // Or === depending on your needs
return opts.fn(this);
else
return opts.inverse(this);
});
I fixed this issue by moving the function to the server side like this:
var hbs = exphbs.create({
defaultLayout: 'main', //we will be creating this layout shortly
helpers: {
if_eq: function (a, b, opts) {
if (a == b) // Or === depending on your needs
return opts.fn(this);
else
return opts.inverse(this);
}
}
});
The HBS template was rendered in the backend, but your helper is registered in frontend. Register the helper where you are using it.

How to export data from HTML table to excel using angularjs

I want to export data in my html table to an excel sheet using angularjs on abutton click. I tried a code, but in vain.i m getting the button click event triggered though but nothing else seems to happen
<table class="table table-bordered table-condensed table-hover table-striped" id="tableId">
<tr ng-repeat="mas in vm1 | orderBy:orderByField:reverseSort">
<td>{{::mas.contractNumber}} </td>
<td>{{::mas.planNumber}} </td>
<td>{{::mas.businessErrorMsg }} </td>
<td>{{::mas.systemErrorMsg}} </td>
</tr>
<button class="btn btn-link" ng-click="exportToExcel('#tableId')">
<span class="glyphicon glyphicon-share"></span>Export to Excel
</button>
//controller code
app.controller("ErrorDetailController", [
"$scope", "$location", "$routeParams", "messageService", "errorService", "repositoryService", , "sharedPageService",
function ($scope, $location, $routeParams, messageService, errorService, repositoryService,sharedPageService, **Excel, $timeout**) {
$scope.exportToExcel = function (tableId) { // ex: '#my-table'
debugger;
var exportHref = Excel.tableToExcel(tableId, 'sheet name');
$timeout(function () { location.href = exportHref; }, 100); // trigger download
}
}
]);
app.factory('Excel', function ($window) {
var uri = 'data:application/vnd.ms-excel;base64,',
template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>',
base64 = function (s) { return $window.btoa(unescape(encodeURIComponent(s))); },
format = function (s, c) { return s.replace(/{(\w+)}/g, function (m, p) { return c[p]; }) };
return {
tableToExcel: function (tableId, worksheetName) {
var table = $(tableId),
ctx = { worksheet: worksheetName, table: table.html() },
href = uri + base64(format(template, ctx));
return href;
}
};
})
Use :
<body>{table}</body>
instead of :
<body><table>{table}</table></body> in template variable.
You can use the ng-table-to-csv module to export HTML tables into CSV files (that can be opened in Excel).
As given on the README of that repo, here is the usage:
Getting Started / Usage
Install module via bower (or download the files from the dist folder
in the repo):
shell bower install ng-table-to-csv --save
Add a reference to dist/ng-table-to-csv.js into your HTML pages.
Add ngTableToCsv as a dependency to your module:
js angular.module('your_app', ['ngTableToCsv']);
Add export-csv attribute directive on the table to define a new
csv object on the scope with generate() and link() functions on
them.
Options:
- Use the separator attribute to change the default comma separator into something else (like semicolon).
- Use the export-csv-ignore attribute to set the selector that will be used for prevent tr/th/td to be stringified.
To create an Export button from an anchro tag, use the generate()
and link() functions mentioned above from ng-click and ng-href
attributes of an anchor tag.
See below:
html
<a class="btn" title="Export Table" ng-click='csv.generate()' ng-href="{{ csv.link() }}"
download="myTable.csv">
<i class="glyphicon glyphicon-new-window"></i>  Export
</a>
<table class="table table-bordered" export-csv="csv" separator=";">
<!-- table contents -->
</table>

How to load external html template?

Given HTML code such :
<!-- 2. Anchor -->
<div id="anchor">This div is the <b>#anchor</b>.</div>
<!-- 3. Template -->
<script id="tpl" type="text/template">
{{#people}}
<div><img src="{{photo}}"><b>{{family}} {{name}}</b> — {{title}}, {{place}} : {{introduction}}.</div>
{{/people}}
</script>
Given JS/Handlebars such as :
<!--4. Handlebars.js slingshot -->
//4a.function creation
var slingshot = function (url, tplId, anchor) {
$.getJSON(url, function(data) {
var template = $(tplId).html();
var stone = Handlebars.compile(template)(data);
$(anchor).append(stone);
});
}
slingshot('data.json', '#tpl', '#anchor'); // since url = 'data.json' , we can use both notations.
How to externalize the my 3. Template (#tpl) into a proper .txt text file (or other extension) ? How to load it back ? so I may use the same template into various .html webpages.
Full code : http://bl.ocks.org/hugolpz/8075193 / http://bl.ocks.org/hugolpz/raw/8075193/
Put the following template content into a file named test.handlebars
{{#people}}
<div><img src="{{photo}}">
<b>
{{family}} {{name}}
</b> — {{title}},
{{place}} : {{introduction}}.
</div>
{{/people}}
Write a function which will use the template as below
function getTemplate(name) {
if (Handlebars.templates === undefined || Handlebars.templates[name] === undefined) {
$.ajax({
url : name + ".handlebars",
success : function(data) {
if (Handlebars.templates === undefined) {
Handlebars.templates = {};
}
Handlebars.templates[name] = Handlebars.compile(data);
},
async : false
});
}
return Handlebars.templates[name];
}
In the main program you can write the below statement to insert the template contents into div with id="anchor", as shown below
var Template = getTemplate("test")
this.$("#anchor).append(Template(data));
where data is the contents of a json file or some db query output which will give you the values meant for the following attributes in json format
people, twitter, name, family, photo, title, place, introduction
I'm assuming you have already compiled your template. So you can use the technique I have described in Bootstrapping Multiple Instances of an HandlebarsJS Template Into a Page.
Hook and libs
Place this in your index.html:
<div class="hook" data-json="data/whatever.json"></div>
and the JavaScript libs
<!-- Helper to inject data-set in templates instance -->
<script src="scripts/template-loader.js"></script>
<!-- Get the (compiled) template -->
<script src="scripts/myTemplate.hbs.js"></script>
template-loader.js helper
$(function(){
'use strict';
var compiledTemplate = myApp.Templates['app/templates/myTemplate.hbs'];
$('.hook').each(function(i, h){ # h = current hook
var url = $(h).data('json'); # data-set's url
$.getJSON(url).then(function (json) { # fetch data-set
var tpl = compiledTemplate( json ); # inject data into template
$(h).html(tpl); # inflate template in page
});
});
});
Please read the complete article for further details.

Call methods on mustache variable in a template

I have a mustache template and I would like to call some function on the mustache variables ({{name}} in this case). Specifically, I want to call toLowerCase() method on the name variable.
<tbody>
<script id="mytemplate" type="text/template">
{{#cat}}
<tr data-index="{{age}}-{{name}}"></tr>
{{/cat}}
</script>
</tbody>
I tried looking in the mustache docs but I couldn't find out how to do this. I tried doing
<tr data-index="{{age}}-{{name.toLowerCase()}}"></tr>
<tr data-index="{{age}}-{{name}}.toLowerCase()"></tr>
But I'm not getting what I expect. I render the template with this code which gets triggered on document ready.
$(function() {
$.getJSON('/cats.json', function(data){
var template = $("#mytemplate").html();
var view = Mustache.to_html(template, data);
$("tbody").html(view);
});
})
you need to pass the function as part of the data, like so:
$(function() {
$.getJSON('/cats.json', function(data){
data.lower = function () {
return function (text, render) {
//wrong line return render(text.toLowerCase());
return render(text).toLowerCase();
}
};
var template = $("#mytemplate").html();
var view = Mustache.to_html(template, data);
$("tbody").html(view);
});
})
and the template:
<tr data-index="{{age}}-{{#lower}}{{name}}{{/lower}}"></tr>

Categories

Resources