angularjs: how to disable directive for a specific element - javascript

I want to show a code snippet of how to use a directive. However, the directive exists in this application, so when I have
<pre>
<code>
<bar-foo>bar foo</bar-foo>
</code>
</pre>
I'm using highlight.js, but angular doesn't care much and applies the directive to the bar-foo element. How can I disable the directive for that specific element ?

You are looking for ng-non-bindable:
<pre ng-non-bindable>
<code>
<bar-foo>bar foo</bar-foo>
</code>
</pre>

What I would is to add an attribute to <bar-foo> element like <bar-foo data-is-disabled="{{true}}" >. In the directive I would add at the very top of the link method:
if ($scope.$eval(attrs.isDisabled)) return ;`
If I needed to make sure to clear all content probably before return I could do something like:
element.replaceWith('')

Related

Display other content along with innerHTML

I have a component where it renders the tags depends on the data passed as shown below:
<ng-container>
<ng-container [ngSwitch]="tag">
<p *ngSwitchCase="'p'" [innerHTML]="_getString()"></p>
<h1 *ngSwitchCase="'h1'" [innerHTML]="_getString()"></h1>
<h2 *ngSwitchCase="'h2'" [innerHTML]="_getString()"></h2>
<h3 *ngSwitchCase="'h3'" [innerHTML]="_getString()"></h3>
<h4 *ngSwitchCase="'h4'" [innerHTML]="_getString()"></h4>
<span *ngSwitchCase="'span'" [innerHTML]="_getString()"></span>
<code *ngSwitchCase="'code'" [innerHTML]="_getString()"></code>
<time *ngSwitchCase="'time'" [innerHTML]="_getString()"></time>
</ng-container>
I want to render an icon beside each text whenever required.
<span *ngIf="icon" class="css-{{icon}}" role="presentation"></span>
If I put the icon tag in between each tag, it gets replaced by the innerHTML data.
Is there any way I can render both the icon(using ng-content or something like that because I dont want to write the icon html inside every element) and innerHTML data?
I am new to Angular world so trying to learn. Any help would be appreciated.
Thank you.
It seems that your question is not specific for Angular, but a JavaScript behavior.
innerHTML gets or sets the HTML or XML markup contained within the element. So it means that it replaces whatever content was there to start with.
(https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML)
I think you can try using insertAdjacentHTML() instead - this should add HTML to the element that's already present there in the DOM.
Check the syntax and examples here: https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML
Try passing the icon wrapped in a span tag to _getString() method. configure your method such that it returns the icon and the text
E.g
getString(icon){
return <span> ${icon} </span> your string here
}
in this case every time you call _getString pass the desired icon

Unable to target element using protractor's binding locator

<div class="apiRequestDisplay ng-scope">
<pre class="ng-binding">GET</pre>
<pre class="ng-binding">v1/securityprofiles/{securityProfileID} </pre>
</div>
I need to target the text that says v1/securityprofiles/{securityProfileID}. I inspected the element on the webpage to obtain the HTML at the top. As you can see it doesn't show ng-bind = to anything it just shows it as part of a class.
I thought that was a little weird but I used inspect Angular Scope (firefox add-on) to verify the binding to be docsEndpoint.Endpoint.HttpVerb however when I put it into the protractor syntax:
var route1 = element(by.binding('docsEndpoint.Endpoint.UriTemplate'));
expect(route1).toBe('v1/securityprofiles/{securityProfileID}');
and run it nothing happens. What am I missing?
I know I can probably select it using CSS selectors and I probably will if I have to but I really want to know why it isn't working.
You should not expect an element itself, get it's text via getText() and use toEqual():
expect(route1.getText()).toEqual('v1/securityprofiles/{securityProfileID}');

append as html in angular

I want to append the value as html in angular
<div class="storycontent" ng-class="{show: show}">
{{review.name}}: {{review.story}}
</div>
Here in the {{review.story}} I will have value like <b>hello</b><i>something</i> etc
The problem is its displaying the content as <b>hello</b><i>something</i> instead of hellosomething (ie the styling is not applied)
I have to use jQuery to do this
$(".content").each(function () {
$(this).html($(this).text())
});
How can i directly append as .html() instead of .text() in angular?
You don't even need Jquery for that. ng-bind-html can do the trick by himself.
<div class="storycontent" ng-class="{show: show}">
{{review.name}}:
<span ng-bind-html="review.story"></span>
</div>
Moreover, it's also better to add this on your controller when you get the value. Because without this, ng-bind-hmtl isn't safe.
$scope.review.story = $sce.trustAsHtml($scope.review.story);
Note : $sce have to be injected in your controller. It's not available directly with angularJS.
.controller('ControllerName', ['$scope', '$sce', function($scope, $sce) {...
You can use directive ngBindHtml, more info here: https://docs.angularjs.org/api/ng/directive/ngBindHtml
Also you have to remeber that before binding html you have to ensure Angular that it is safe. You can use ngSanitize for it and $sce.trustAsHtml function:
https://docs.angularjs.org/api/ng/service/$sce#trustAsHtml
use ng-bind-html="expression"
expression is your html here
You can use ng-bind-html in angular.
By Docs: ng-bind-html
Evaluates the expression and inserts the resulting HTML into the
element in a secure way. By default, the resulting HTML content will
be sanitized using the $sanitize service. To utilize this
functionality, ensure that $sanitize is available, for example, by
including ngSanitize in your module's dependencies (not in core
Angular). In order to use ngSanitize in your module's dependencies,
you need to include "angular-sanitize.js" in your application.
Use: ng-bind-html="review.story">
Refer docs

angularjs directive: not replace nor transclude

I need to append a directive's template AFTER an input field. The original input field needs to remain - I can't just create a duplicate of it. My thought for this was to, in the controller, use jQuery to add a DIV after the input field, and add an attribute for the directive to the div. However, in practice, that doesn't work - the div is created and added, but the directive doesn't activate.
The problem, I know, is that the jQuery-added div is not yet recognized by the angularjs controller - it appears AFTER angularjs runs over the controlled html.
I know that part of the problem is that you're not supposed to use jQuery in the controller, but I honestly can't think of another way to do it. Is there some way to cause the angularjs controller to look at this new div?
The original HTML looks like the following.
<input name="generatedString_1234567890">
I run jquery over the page to add a controller to the body. The relevant code looks similar to this:
jQuery('body').attr('ng-controller','MainCtrl');
angular.module('app',['DataTools']);
angular.element(document).ready(function(){
angular.bootstrap(document, ['app']);
});
Inside the angularjs, I run a resource to get a json string containing the relevant changes to the DOM, in terms of attributes that need to get added to the inputs and certain understood flags that require specific coding. The relevant task I'm trying to accomplish looks like this, where $(this) is the input field for the DOM.
jQuery(document).find('input.FormField,select.FormField').each(function(){
// Inside a case statement based on certain flags
var d = $('<div/>');
d.attr("ng-model", 'adors.'+label);
// Relevant code that adds attributes to the div - including the required directives
$(this).hide().after(d);
}
I am trying to create code that looks more like this (VERY GENERIC):
<input name="generatedString_1234567890" ng-hide="true" ng-model="input.uniqueKey">
<div special-input="time" ng-model="input.uniqueKey">
<select ng-repeat="hour in hours">
<select ng-repeat="minute in minutes">
</div>

How to style angular text blocks

I have a status var in a scope of a controller.
Whenever my rest PUT succeeds I append a message to this js variable.
I show it in my template using {{status}}
How can I style this? I tried inserting <br> tags in this text but they just show up as regular text and dont insert a new line. How can I also bold certain tag?
In order for HTML to be rendered, use ng-bind-html
<div ng-bind-html="status"></div>
P.S. Don't forget to import ngSanitize module into your app.
You can also take a look at
https://docs.angularjs.org/api/ng/directive/ngClass
about ng-class directive
Why not use a tag or a tag to wrap your {{status}}, and add to the tag an id or classes with styles?

Categories