Say that I want to add a dollar sign to a Handlebars output:
${{price}}
When price actually evaluates into a number, the final output looks good: $100
But when price hasn't been defined yet, the output is just a lonely dollar sign $ which looks odd just sitting by itself on the page.
I can define the Handlebars helper to include the dollar sign:
Handlebars.registerHelper('priceWithDollarSign', function() {
return( "$" + totalPrice );
});
But then I need to define a second helper to display it without a dollar sign:
Handlebars.registerHelper('priceWithoutDollarSign', function() {
return totalPrice;
});
Would it be possible to just do it inside the Handlebars expression itself?
{{"$" + price}} for when I want the dollar sign.
{{price}} for when I don't want the dollar sign.
In this way, when price hasn't been defined the output is just blank and doesn't look odd on the page.
I figured out how to do it for this dollar sign case. I guess I can extrapolate this out to other similar situations.
Handlebars.registerHelper("formatToCurrency", function(number, plain) {
if (number && plain) {
return number; //return the plain number
} else if (number && plain == null ) {
return ("$" + number); //return the number with $ sign
} else {
return null; //return nothing
}
});
If I do
{{formatToCurrency price null}}
I get 100
If I do
{{formatToCurrency price}}
I get $100
If price is undefined, it is just blank.
Related
I am trying to style just the decimals to look just like this:
Didn't had success, I guess that I need to make my own filter, tried but didn't had success either, I guess it is because I am using it inside a state.
Here the code I am using for the number:
<h2><sup>$</sup>{{salary | number:0}}<sub>.00</sub></h2>
Inside the .app iam using this scope:
$scope.salary = 9000;
Thing is, number can be whatever the user salary is, it get the number from an input, in other places I have more numbers with decimals too.
Possible solutions:
Extract only the decimals from value and print them inside de
tag.
Use a filter to do this?
Use a directive that will split the amount and generate the proper HTML. For example:
app.directive('salary', function(){
return {
restrict: 'E'
, scope: {
salary: '#'
}
, controller: controller
, controllerAs: 'dvm'
, bindToController: true
, template: '<h2><sup>$</sup>{{ dvm.dollar }}<sub>.{{ dvm.cents }}</sub></h2>'
};
function controller(){
var parts = parseFloat(this.salary).toFixed(2).split(/\./);
this.dollar = parts[0];
this.cents = parts[1];
}
});
The easiest solution would be to split out the number into it's decimal portion and the whole number portion:
var number = 90000.99111;
console.log(number % 1);
Use this in your controller, and split your scope variable into an object:
$scope.salary = {
whole: salary,
decimal: salary % 1
}
Protip: Using an object like this is better than using two scope variables for performance
In Meteor we have the '#index' operator to get the index value of the iteration. But I wanted to get the total number of iterations then print that number on the page. So the page at top might read the total number of boys in a group.
For example, I might have something like:
Total = {{#each StudentMale}} {{formatMaleCount #index}} {{/each}}
and a register helper just to add 1 to the number
Template.registerHelper('formatMaleCount', function (count) {
return count + 1;
});
and this would print:
Total = 1234567
I'd like to have:
Total = 7
Coming up short on how to do this. I tried to have the helper put the values in an array, but this wouldn't work since a new array is produced on each iteration.
StudentMale is presumably an array or cursor, so in a new helper:
If it's an array:
arrayLength( array ) {
return array.length;
}
Or if it's a collection:
studentMaleLength() {
return StudentMales.find().fetch().length;
}
Then just call your helper.
What I need to do is use either collection-2 or another package to automatically create a new order number, incremented from the last order number used.
i.e. Starting off with PO123456, when I save this order, the next time I make a new PO, it automatically generates the number PO123457.
I've been looking for a good example or tutorial, but I'm not able to find one.
Using konecty:mongo-counter in conjuntion with aldeed:collection2 and aldeed:simple-schema should be pretty straightforward. In your schema definition try:
POnumber: { type: String, autoValue: function(){
if ( this.isInsert ){ // restrict to when inserting a document
var currentNumber = incrementCounter('purchase order'); // this will use mongo-counter
// WARNING: you can only ever get as rich as 10M POs!!
var zeroPad = "000000" + currentNumber; // pad with 6 zeros
zeroPad = zeroPad.substr(zeroPad.length-7); // restrict to 7 places
return 'PO' + zeroPad; // prefix with 'PO'
} else if ( this.isSet ){
this.unset(); // prevent attempts to change the number
}
}
MomentJS has option "referanceTime" - http://momentjs.com/docs/#/displaying/calendar-time/ and it displays datetime like this Last Monday 2:30 AM
Problem is when I have date without time - it displays Last Monday 0:00 AM - how get rid of time when date hasn't got it?
Very similar to my answer here but slightly more advanced.
I believe the only way to customize calendar time is by using a custom locale. In your case, you need to use a custom function.
Here's a somewhat complex, but complete way to do it:
// Factory-type function that returns a function.
// Used to set argument (fstr) without using `bind` (since bind changes `this`)
var stripZeroTime = function (fstr) {
return function () {
if (this.format("H:mm:ss") === "0:00:00") { // if midnight
return fstr.replace("LT", "") //remove time
.replace("at", "") //remove at
.replace(/\s+/g, ' ').trim(); //strip extra spaces
}
return fstr;
}
}
moment.locale('en-cust', {
calendar: {
lastDay: stripZeroTime('[Yesterday at] LT'), // Default format strings
sameDay: stripZeroTime('[Today at] LT'),
nextDay: stripZeroTime('[Tomorrow at] LT'),
lastWeek: stripZeroTime('[last] dddd [at] LT'),
nextWeek: stripZeroTime('dddd [at] LT'),
sameElse: stripZeroTime('L')
}
});
Demo with test cases
A simpler way would be to just strip off the 0:00:00 when it's midnight.
function stripMidnight(m){
if(m.format("H:mm:ss") === "0:00:00"){
return m.calendar().replace("0:00:00","");
}else{
return m.calendar();
}
}
Since 2.10.5 we can define our own render engine by invocation (second parameter of calendar function) - http://momentjs.com/docs/#/displaying/calendar-time/
But now we can use only strings not function to define pattern
I'm trying to use jsonPath and the pick function to determine if a rule needs to run or not based on the current domain. A simplified version of what I'm doing is here:
global
{
dataset shopscotchMerchants <- "https://s3.amazonaws.com/app-files/dev/merchantJson.json" cachable for 2 seconds
}
rule checkdataset is active
{
select when pageview ".*" setting ()
pre
{
merchantData = shopscotchMerchants.pick("$.merchants[?(#.merchant=='Telefora')]");
}
emit
<|
console.log(merchantData);
|>
}
The console output I expect is the telefora object, instead I get all three objects from the json file.
If instead of merchant=='Telefora' I use merchantID==16 then it works great. I thought jsonPath could do matches to strings as well. Although the example above isn't searching against the merchantDomain part of the json, I'm experiencing the same problem with that.
Your problem comes from the fact that, as stated in the documentation, the string equality operators are eq, neq, and like. == is only for numbers. In your case, you want to test if one string is equal to another string, which is the job of the eq string equality operator.
Simply swap == for eq in you JSONpath filter expression and you will be good to go:
global
{
dataset shopscotchMerchants <- "https://s3.amazonaws.com/app-files/dev/merchantJson.json" cachable for 2 seconds
}
rule checkdataset is active
{
select when pageview ".*" setting ()
pre
{
merchantData = shopscotchMerchants.pick("$.merchants[?(#.merchant eq 'Telefora')]"); // replace == with eq
}
emit
<|
console.log(merchantData);
|>
}
I put this to the test in my own test ruleset, the source for which is below:
ruleset a369x175 {
meta {
name "test-json-filtering"
description <<
>>
author "AKO"
logging on
}
dispatch {
domain "exampley.com"
}
global {
dataset merchant_dataset <- "https://s3.amazonaws.com/app-files/dev/merchantJson.json" cachable for 2 seconds
}
rule filter_some_delicous_json {
select when pageview "exampley.com"
pre {
merchant_data = merchant_dataset.pick("$.merchants[?(#.merchant eq 'Telefora')]");
}
{
emit <|
try { console.log(merchant_data); } catch(e) { }
|>;
}
}
}