AngularJS: translate and multiple ng-bind-html values - javascript

In my app I try to concat two strings: email and some text.
But I have a trouble, I need text part translateable "on the fly" so I wrote:
$scope.textUnsubscribe = 'SUCESSFULL_UNSUBSCRIBE';
in view:
<h4 ng-bind-html="textUnsubscribe | translate"></h4>
sure I can do (email + text):
<h4 ng-bind-html="userEmail"></h4>
<h4 ng-bind-html="textUnsubscribe | translate"></h4>
but then I have style bug...
Can I somehow put into one ng-bind-html two scope variables? one is "static" and second is translateable?
like:
<h4 ng-bind-html="userEmail, (textUnsubscribe | translate)"></h4>

If it's only simple string like email. You don't need ng-bind-html, ng-bind will be enough. Adding -html make ng-bind less safer. Anyway ng-bind can be used multiple times. If you have a "style bug" with it, it comes from your HTML (you have multiple h4).
Anyway, you can do it on a simple ng-bind like this :
<h4 ng-bind="userEmail +' '+ (textUnsubscribe | translate)"></h4>

Related

ng-bind-html doesn't connect different things in once (not even with $sce.trustAsHtml() )

I am trying to connect some different html code to my view with ng-bind-html.
I already added ngSanitize
Firstly I am using ng-for by ui-select-choices
<ui-select-choices repeat="test in dataTest>
. and I want to bind test.name with some Html
<small> ( {{ TEST_BTN | translate }}) </small>
The Test_BTN is being used for Translation purpose there fore I can't leave it out from code.
when I try to use them all in ng-bind-html nothing will be shown
when I try to use them all in ng-bind the html code will be shown.
when I try to use ng-bind andng-bind-html seperetly , ng-bind-html html won't be shown.
How am I suppose to fix this?
EDIT : I am trying to show the result in a new div with ng-if
something like : <div data-ng-if="test.isSomething" ng-bind="test.name" ng-bind-html="' <small>({{'BTN_ADD' | translate}})</small>'" ></div> (Which doesnt show the ng-bind-html part )
EDIT 2 :
I deleted the {{ }} from data-ng-bind-html and used the translation explicitly with the $translate service in my controller.
And It worked.
You can't use ng-bind and ng-bind-html on the same element, and you can't use {{}} in either one of them. It's not necessary to concatenate the <small> tag inside the ng-bind-html, it should be in the template itself. And you have some syntax error nested-quotes issues in your ng-bind-html clause.
It's not clear to me from your description which of test.name, TEST_BTN or BTN_ADD you actually intend to use; I'm going to assume you really want test.name here but if one of those other variables contains the HTML you're trying to embed, just substitute its name in place of test.name:
<div ng-if="test.isSomething">
<small ng-bind-html="test.name | translate"></small>
</div>

Angular ng-if for checking empty string not working

In my view, I have the below code to display some data from angular scope variables. The first two lines work fine. They display data from the scope variables but the line from ng-if does not display. What is wrong with my ng-if condition?
<div ng-controller="PaymentCtrl">
<h3>Payment successfully posted {{PaymentID}}</h3>
<h3> Receipt number {{ReceiptNumber}} </h3>
<div ng-if="{{ReceiptNumber}}">
<h3>Receipt generated with receipt number {{ReceiptNumber}}</h3>
</div>
</div>
As mentioned, ngIf takes an expression.
<ANY ng-if="expression"> ... <ANY>
See the AngularJS expression docs for more information on what this entails exactly. In your example, you are instead supplying an interpolated value. Try the following...
<div ng-if="ReceiptNumber">
<h3>Receipt generated with receipt number {{ReceiptNumber}}</h3>
</div>
JSFiddle Link - demo comparing both wrong and correct appreach

$scope variables shortcuts in AngularJs Templates

In my controller I assign:
$scope.currentThing.data
And in my template sometimes I need
currentThing.data.response[0].hello
and sometimes
currentThing.data.otherStuff[0].goodbye
//or
currentThing.data.anotherThing[0].goodMorning
So I was wondering if it is possible to create a shortcut for this variables straight in the templates, something like:
{{response = currentThing.data.response[0]}}
So that I can use it like this {{response.hello}}.
In general, is it possible to assign temporary variables from the template? I don't need to have any data-binding, I would need them only for generating the template and then they can disappear forever
You can do that in controller like here: http://jsbin.com/moyuhe/1/edit
app.controller('firstCtrl', function($scope){
$scope.currentThing = {
data: [
{response:[
{hello:1},
{hello:2}
]}
]
};
$scope.temp = $scope.currentThing.data[0];
});
HTML:
<div ng-controller="firstCtrl">
{{temp.response |json }}
</div>
You might be able to use ngInit: https://docs.angularjs.org/api/ng/directive/ngInit
Although it seems that using it outside of ngRepeat is frowned upon.
<div ng-init="myvar = currentThing.data.response[0]">
<span>{{myvar.hello}}</span>
</div>
I haven't tested it like this but that's the closest thing I can think of that may solve your problem.
Yes, it is possible using syntax like
{{ variable = ( expression ) }}
anywhere in HTML template (not just ng-init as some suggest).
It is exceptionally useful in cases when you need to use a calculated variable more times - it does not need to be calculated each time.
Some example
<!-- can use it before -->
<p> Calculated value is {{calculated}} </p>
<div ng-repeat=" item in calculated = ( allItems | filter1 | filter2 | filter3 ) ">
{{item}}
</div>
<!-- can use it after-->
<p> Calculated value is still {{calculated}} </p>
Edit: so in your case
{{response = ( currentThing.data.response[0] ) }}

Trying to set a default background picture using Angular.js

I'm new to Angular.js and I'm running into a problem. I'm using ng-repeat to iterate through a list of news items. Each item has a Title and Body, but will have an optional picture url that will be used as the background.
I can get the news item elements with picture URLs to display when there is a url present. See sample code below.
<li class="news-item col-md-6" ng-repeat="announcement in news.announcements | limitTo:8" ng-style="{'background-image': 'url({{announcement.Url}})'}">
I need to set the announcement.Url value to a default background picture URL when announcement.Url is NULL or Undefined. Not sure how I can go about this.
Any help would be much appreciated.
Thanks!
<li class="news-item col-md-6" ng-repeat="announcement in news.announcements | limitTo:8" ng-style="{'background-image': 'url({{announcement.Url || \'path to default image\'}})'}">
Anything between {{ and }} is an angular expression (similar to javascript itself as far as a beginner is concerned). You can simply include the || operator (a logical OR) and put the path to your default image in a string after that. If announcement.Url is null or undefined then it will be "falsy" and the latter half of the OR conditional will be used.
Edit: Notice that I escaped the string delimiters (\') because they are already nested inside a string that uses those delimiters.

How to handle strings containing HTML using Angular-Translate?

Is there a way to tell angular and angular-translate to handle strings which contains HTML content.
I have add_card-title = "To make ordering even quicker, <span class="nowrap">add a card now</span>" as my Lang string. When i use it in my template by writing <p>{{'add_card-title' | translate}}</p> I get string as it is.
Output: To make ordering even quicker, <span class="nowrap">add a card now</span>
expected output: To make ordering even quicker, add a card now
I know i can use ng-html-bind-unsafe but it is not helping.
Not working:
<p ng-html-bind-unsafe="{{'add_card-title' | translate}}"></p>
Is there any way to achieve it?
Here is my plunker: http://plnkr.co/edit/nTmMFm9B94BmbTgo2h8H?p=preview
For reference you can see this issue: https://github.com/PascalPrecht/angular-translate/issues/173
note: i do not want to invlove controller to handle it.
You can do this out of box with angular-translate 2.0 these days.
<p translate="{{ 'PASSED_AS_INTERPOLATION' }}"></p>
works wonders for me.
You have to use the ng-bind-html directive without curly braces ({{ }})
To know the configuration needed in order to use that directive (ngBindHtml), follow this link: https://docs.angularjs.org/api/ng/directive/ngBindHtml
After ngSanitize is included, the following code should work:
<p ng-bind-html="'add_card-title' | translate"></p>
This works for me... the HTML is interpreted for nice styling (e.g. bold, italics, etc.)
<p translate="translationId"></p>
However, I also needed to ensure that I wasn't using escape strategy in the provider setup. That messed me up for a while.
Works: $translateProvider.useSanitizeValueStrategy( 'sanitize' );
Nope: $translateProvider.useSanitizeValueStrategy( 'escape' );
https://angular-translate.github.io/docs/#/guide/19_security
Using: angular-translate v2.13.1
You can use <p [innerHTML]="'add_card-title' | translate"></p>
I have found the solution.
I was using AngularJS v1.2.0-rc.3 which has got ng-html-bind-unsafe deprecated. Now angular has ng-bind-html instead of ng-html-bind-unsafe. But one has to inject angular-sanitize as a dependency to get it working.
I replaced
<p ng-html-bind-unsafe="{{'add_card-title' | translate}}"></p>
with
<p ng-bind-html="'{{'add_card-title' | translate}}'"></p>
and things started working.
By default AngularJS escape and code it displays for safety reasons, you need to tell angular of the strings you don't want to escape, in older times before AngularJS 1.2 developers could do that by using ng-bind-html-unsafe but in AngularJS 1.2 that has been deprecated.
To use html tags in strings, in AngularJS 1.2+, you need to download angular-sanitize module and include it in your application dependencies.
Any string contains html code you can display it by using ng-bind-html Automatically uses $sanitize, in your case it will be ng-bind-html="'add_card-title' | translate"
For reference:
On Medium
AngularJS Documentation
Here are many ways to mix up html (along with scope variables, along with interpretion if you need things like ng-click in your html translations):
http://plnkr.co/edit/OnR9oA?p=preview
<div>{{'TESTING1_SIMPLE_VAR_REPLACE' | translate: '{name: "John Smith", username: "john.smith12"}'}}</div>
<div translate='TESTING1_SIMPLE_VAR_REPLACE' translate-values='{ name: "Jake Smith", username: "jake-smith-101" }'></div>
<div translate="TESTING1_SIMPLE_VAR_REPLACE_NA" translate-value-name="{{name}}" translate-value-username="{{username}}" translate-default="Hello {{name}} ({{username}})"></div>
<br/><br/>
<div>{{'TESTING1_SIMPLEHTML' | translate}}</div><!-- doesn't compile the html -->
<div translate="TESTING1_SIMPLEHTML" translate-default='DEFAULT(not used since there is a translation): This <b>translation</b> has a link.'></div><!-- this and below compile the html -->
<div translate="TESTING1_SIMPLEHTML_NA" translate-default="DEFAULT(used since translation not available): This <b>translation</b> has a <a href='http://google.com' target='_blank'>link</a>."></div>
Uses ng-bind-html and sanitize: <div ng-bind-html="'TESTING1_SIMPLEHTML' | translate"></div>
<br/><br/>
<div translate="TESTING2_SCOPE" translate-values="{timer: timer}" translate-default="DEFAULT(not used since there is a translation): Seconds: <a href='http://google.com' target='_blank'>{{timer}} seconds</a>."></div>
<div translate="TESTING2_SCOPE" translate-value-timer="{{timer}}"></div>
<div translate="TESTING2_SCOPE_NA" translate-default="DEFAULT(used since translation not available): Seconds: <a href='http://google.com' target='_blank'>{{timer}} seconds</a>."></div>
<br/><br/>
<div compile-unsafe="'TESTING3_COMPILE' | translate"></div><!-- old way to do before angular 2.0-->
<div translate="TESTING3_COMPILE" translate-compile></div>
<div translate="{{'TESTING3_COMPILE_SCOPE'}}" translate-compile translate-value-name="{{name}}" translate-value-username="{{username}}" ></div> <!-- not sure of advantage of this style, but saw an example of it -->
<div translate="TESTING3_COMPILE_SCOPE" translate-compile translate-value-name="{{name}}" translate-value-username="{{username}}" ></div>
<div translate="TESTING3_COMPILE_SCOPE" translate-compile translate-values='{ name: "Jake Smith", username: "jake-smith-101" }' ></div>
"lng_pageFooter" : "Copyright © • 2018 • My Company • Powered by My Company™"
...
$translateProvider.useSanitizeValueStrategy('escape');
....
app.filter('trusted', ['$sce', function($sce) {
var div = document.createElement('div');
return function(text) {
div.innerHTML = text;
return $sce.trustAsHtml(div.textContent);
};
}])
....
<span ng-bind-html="'lng_pageFooter' | translate | trusted"></span>
I tried both your answers and none of them worked on 1.0.7 so for everyone that's working pre 1.2 you can do it like this
<p ng-html-bind-unsafe="'add_card_title' | translate"></p>
Simply use innerHtml. Eg <p [innerHtml]="'lorem.ipsum' | translate"></p>

Categories

Resources