Handlebars: Calling a helper within a call to another helper? - handlebars.js

So I have 2 helpers, #hex works correctly when used separately, and #rgb also works correctly when a color has been passed directly. However, ideally, I'd like to use my #hex helper within the call to the #rgb helper but I'm not having much luck. Here's what I have so far.
Helper within helper - Doesn't work as expected:
{{#rgb {{#hex color}}{{/hex}} -0.25}}
Example of what is expected of the above:
{{#rgb #abc123 -0.25}}
Is this achievable within handlebars or would it be easier if I wrote a new helper that included both my #rgb helper and #hex helper?

You can do this with parentheses rather than curly brackets:
{{helper1 (helper2 var1) var2}}
Example:
// dummy helpers
Handlebars.registerHelper('rgb', function(color, opacity) {
return color + ' ' + opacity;
});
Handlebars.registerHelper('hex', function(color) {
return color + 'hexified';
});
// now in template
var template = '{{rgb (hex color) -0.25}}';
Handlebars.compile(template)({color: 'green'});
//Outputs "greenhexified -0.25"
Subexpressions docs

{{outer-helper (inner-helper 'abc') 'def'}}

Related

SASS/SCSS variable not working with CSS variable assignment

I have the following SCSS code:
#mixin foo($bar: 42) {
--xyzzy: $bar;
}
bar {
#include foo;
}
I would expect that I get CSS variable --xyzzy set to 42 on all bar elements. Instead of this, I get CSS stating bar { --xyzzy: $bar; }. The variable was not interpreted. I would need to use #{…} syntax instead to get the variable set.
Is this a feature of the SCSS/SASS? A bug? Can I get the interpretation working without enclosing the variable name in #{…}?
Actual result:
bar {
--xyzzy: $bar;
}
Expected:
bar {
--xyzzy: 42;
}
It's not a bug, it's how the Sass compiler works regarding CSS custom properties, known as CSS variables. The syntax #{…} is called interpolation, and it is the only way to inject dynamic values into a custom property. Here is a quote from the doc:
CSS custom properties, also known as CSS variables, have an unusual declaration syntax: they allow almost any text at all in their declaration values. What’s more, those values are accessible to JavaScript, so any value might potentially be relevant to the user. This includes values that would normally be parsed as SassScript.
Because of this, Sass parses custom property declarations differently than other property declarations. All tokens, including those that look like SassScript, are passed through to CSS as-is. The only exception is interpolation, which is the only way to inject dynamic values into a custom property.
That's the reason why you have that behavior, and only doing so works:
#mixin foo($bar: 42) {
--xyzzy: $bar; // does not work
--xyzzy: #{$bar}; // works
}

Is there a better way to do this in handlebars?

Im using handlebars to spit out some static pages using a partial like so:
{{> component/card size="small" title="Card Title" }}
Now depending on the "size" of the card required, i need to set some different tailwind classes. Im currently doing it like so, but there must be a better way? Adding the class to the container and writing css is not an option.
{{setVariable "additionalHeadingClass" "text-5 md:text-6 mb-4"}}
{{#ifEquals size "small"}}
{{setVariable "additionalHeadingClass" "text-4 mb-1"}}
{{/ifEquals}}
{{#ifEquals size "large"}}
{{setVariable "additionalHeadingClass" "text-4 sm:text-5 md:text-8 mb-4"}}
{{/ifEquals}}
<h3 class="text-primary font-bold {{#root.additionalHeadingClass}}">{{title}}</h3>
and heres the helper im using:
Handlebars.registerHelper("setVariable", function (varName, varValue, options) {
if (!options.data.root) {
options.data.root = {};
}
options.data.root[varName] = varValue;
});
My opinion is that there is too much code in your template for what it actually does. Despite the intimidating number of lines, we really just want to map a size to a string of class names. I would also advise against the setVariable because I find it harder to think about when we creating a side-effect by manipulating a variable on our context object. I would much prefer a more functional-style helper, where we just give it the size and it returns the class names string.
I would create such a helper using a simple switch:
Handlebars.registerHelper('additionalClasses', function(size) {
switch (size) {
case 'large':
return 'text-4 sm:text-5 md:text-8 mb-4';
case 'small':
return 'text-4 mb-1';
default:
return 'text-5 md:text-6 mb-4';
}
});
And then we may reduce our template to the much simpler:
<h3 class="text-primary font-bold {{additionalClasses size}}">{{title}}</h3>
I have created a fiddle for reference.

Template literal not working correctly with Tailwind CSS

I am passing in a Hex Colour into a prop and attempting to set the background of an element with it. Here is my code:
let cardColourRGB: string;
if (cardColour) {
cardColourRGB = "[" + cardColour + "]";
console.log(cardColourRGB);
} else {
cardColourRGB = "white/50"
}
In the return function:
<div className={`bg-${cardColourRGB}`}></div>
Passing in some colours work, but others don't. For example, passing in #AAA32E as the prop does not set the colour, but setting the colour directly works:
<div className={`bg-[#AAA32E]`}></div>
Why could this be?
According to the official documentation of the tailwind.css it is not preferred to have such classNames
As document says:
The most important implication of how Tailwind extracts class names is that it will only find classes that exist as complete unbroken strings in your source files.
If you use string interpolation or concatenate partial class names together, Tailwind will not find them and therefore will not generate the corresponding CSS:
Don't construct class names dynamically
<div class="text-{{ error ? 'red' : 'green' }}-600"></div>
Instead, make sure any class names you’re using exist in full
<div class="{{ error ? 'text-red-600' : 'text-green-600' }}"></div>
So , for your case, use the following code:
<div class="{{ cardColour ? 'bg-[#AAA32E]' : 'bg-white-50' }}"></div>
Hope it helps!
TailwindCSS doesn't allow you to generate classes dynamically. So when you use the following to generate the class…
`bg-${cardColourRGB}`
…TailwindCSS will not pick that up as a valid TailwindCSS class and therefore will not produce the necessary CSS.
Instead, you must include the full name of the class in your source code. You can return the full value like this
let cardColourRGB: string;
if (cardColour) {
cardColourRGB = "bg-[" + cardColour + "]";
console.log(cardColourRGB);
} else {
cardColourRGB = "bg-white/50"
}
where cardColourRGB is your value you are passing .
By doing it this way, the entire string for every class is in your source code, so TailwindCSS will know to generate the applicable CSS.
Read more: https://tailwindcss.com/docs/content-configuration#class-detection-in-depth

How to add colors to a string in typescript in angular 5

I am trying to display my data in Green color I tried with different methods but still it is not getting populated.
if(typeof(this._serverList)!="undefined"){
var apparr=this._ApplicationList.find(x=>x.appNm==app);
let strlist1=this._serverList.filter(i=>i.envId==envId&&i.appId==apparr.appId).map(x=>x.serverName);
if(typeof(strlist1)!="undefined"){
strlist1.forEach(line=>{
if(line!="")
line.fontcolor("green"); //HERE IS PROBLEM, NOT POPULATING
list+='.'+line+'\n';
});
}
return list;
}
Your problem is using the fontcolor() method - that's old and won't work in HTML5:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fontcolor
If you are rendering the HTML properly from this string, then you should be able to easily achieve this by just assigning some hardcoded HTML to it (that's all fontcolor() does). So instead of doing line.fontcolor(color), you could just replace that line with:
line = '<p style="color: #000">' + line + '</p>
Or use template strings, etc.
document.getElementById('red-text').innerHTML = '<p style="color: red">hello!</p>';
<div id="red-text"></div>

Using Css to Clear TextBox Text/value

I was wondering, if it was possible to clear a text box with a css code rather than using javascript ?
This isn't possible with CSS, only with JS:
Event handler function:
addEvent(document.getElementById('IDHERE'), "focus",
function() {
clearText('IDHERE');
});
Event listener function:
//addEvent listener
function addEvent(obj, type, fn) {
if (obj.addEventListener) {
obj.addEventListener(type, fn, false);
} else {
if (obj.attachEvent) {
obj["e" + type + fn] = fn;
obj[type + fn] = function() {
obj["e" + type + fn](window.event);
};
obj.attachEvent("on" + type, obj[type + fn]);
}
}
}
ClearText function:
//Clear on focus function
function clearText(id) {
document.getElementById(id).value = "";
}
This is pure JS, no libraries needed here, very fast and x-browser compatible :)
You cannot use CSS to manipulate the DOM. In other words: this is not possible.
With CSS one cannot change a document, only the look and behaviour of the document but that's it.
This is impossible. CSS is for presentation only, HTML is for the information and structure and javascript is for DOM manipulation. You will have to use Javascript or one of its libraries to do this :)
can be done, but just in a visual way, it wont actually go, but wont be shown too
there can be many tricks, one can be to set the text color same as the background of your text box, disable selection.
but if you want it to be completely gone you need to use javascript

Resources