Elegant way to show href based on condition - html

I have to show an <a> tag. But depending on whether a value exists or not, I need to set href.
This is what I have:
<a ng-show="source.element!=0" "href="#/resource/{{source.a}}/{{source.b}}/val">
{{source.element}})
</a>
<a ng-show="source.element==0" "href="">{{source.element}}</a>
If source.element is 0 , then nothing should happen on clicking on the value of source.element (href="")
Else, the page must be redirected according to the href.
Is there a better way to do this since this duplicates code?
Thanks..

create a method in scope
$scope.getUrl = function(source){
return source.element==0 ? '#' : '#/resource/'+source.a+'/'+source.b+'/val';
}
then call from view
<a ng-href="{{getUrl(source)}}">
{{source.element}})
</a>
For angular markup it's better to use ngHref .
Becuse if user click on href before angular load it'll go the wrong address.

You can use ng-if
<div ng-if="source.element!=0"><a ng-href="your-url">{{sourceElement}</a></div>
<div ng-if="source.element==0"><a ng-href="">{{sourceElement}}</a></div>
ngif Documentation

Use ng-switch to reduce the number of watches and code duplication:
<span ng-switch="source.element">
<a ng-switch-when="0">
{{source.element}}
</a>
<a ng-switch-default ng-href="#/resource/{{source.a}}/{{source.b}}/val">
{{source.element}}
</a>
</span>

In your controller:
$scope.source.url = $scope.source.element === 0 ? '' : '#/resource/' + $scope.source.a + '/' + $,scope.source.b + '/val';
And in your markup
<a "ng-Href={{source.url}}>{{source.element}}</a>

Create a directive with two attributes like condition and url:
app.directive('anchor', function() {
return {
scope: {
condition: '=expr',
url: '#',
prompt: '#'
},
restrict: 'AE',
replace: 'true',
template: '<div>' +
'<div ng-if="condition">' +
'<a ng-href="{{url}}">{{prompt}}</a>' +
'</div>' +
'<div ng-if="!condition">{{prompt}}</div>' +
'</div>'
};
});
<anchor expr="1 === 1" url="#/test" prompt="test" />
The jsfiddle link.

Related

Can I use anchor tags to jump to different locations on different pages in Angular?

I'm using anchor tags in my navbar to send users to different sections on the about page. Problem is, it only works if I'm already in the about page. It doesn't jump to the specific location I want it to when I click on those links in my navbar from other pages (like for example, homepage).
This is my navbar.html:
<mat-menu #aboutMenu="matMenu">
<button mat-menu-item>
About
</button>
<button mat-menu-item>
Token
</button>
<button mat-menu-item>
Team
</button>
</mat-menu>
And this is my about.html:
<a name="about">
<h1>About</h1>
</a>
.
.
.
<a name="token">
<h2>Token Details</h2>
</a>
.
.
<a name="team">Team Members</a>
I solved using the following code:
.html:
<a [routerLink]="'/about-us'" fragment="about" (click)="onAnchorClick()"> About </a>
.ts:
onAnchorClick ( ) {
this.route.fragment.subscribe ( f => {
const element = document.querySelector ( "#" + f )
if ( element ) element.scrollIntoView ( true )
});
}
I solved it with the help of #davimargelo's answer like this:
navbar.html
<button
mat-menu-item
[routerLink]="'/about-us'"
fragment="token"
(click)="onAnchorClick()"
class="button__mat--menu"
>
Token
</button>
navbar.ts
onAnchorClick() {
this.route.fragment.subscribe((f) => {
const element = document.querySelector('#' + f);
if (element) element.scrollIntoView(true);
});
}
about-us.html
<a name="token">
<h2 id="token-details">Token Details</h2>
</a>
To navigate to another page on clicking a button just use angular event binding syntax.The event binding listens to the click event of the button and calls its respective method in the component.ts file.
Refer link for more understanding:
https://angular.io/guide/event-binding

select span text with jquery

I have this html code, I want get span text when click in reply, but I have multiple of this code in my page and this select only first item, this is my code
<div class="display-comment" style="margin-right: 10px">
<div class="userProfileImageForComment">
<img src="{{asset('profile-media/'.$comment->user->profileimg)}}" alt="">
</div>
<span id="userName">{{ $comment->user->username }}</span>
<p>{{ $comment->comment }}</p>
<div class="comentActionAndDate">
<span>
{{ jdate($comment->created_at)->ago() }}
</span>
<a id="reply">
reply
</a>
</div>
and script is
<script>
$('#reply').click(function(){
var username = "#" + $('#userName').text() + " ";
$('#comment').val('');
$('#comment').val(username);
$('#comment').after( "<input type=\"hidden\" name=\"comment_id\" value=\"{{ $comment->id }}\" />" )
});
</script>
you can do get your span text with this comnmand:
$('#userName')[0].innerText
anything else?
var spanText = $(".comentActionAndDate span").html();
I assume this is for a comments thread though, in which case you should use relative finding to locate the text.
$('#reply').click(function(){
var spanText = $(this).find(".comentActionAndDate").children("span").html();
// Other stuff you might want to do
});
You also should not be using an ID for that reply button if it is being generated more than once. You should also be using a <button> not an <a> tag as the a tag is used for links.
The most correct approach would be to use a function onclick of the reply button:
<button onclick="getSpan(this);">reply</button>
JS:
function getSpan(ele) {
var spanText = $(ele).find(".comentActionAndDate").children("span").html();
// Other stuff you might want to do
}

How to give multiple conditions in *ngIf statement in angular 6?

My navigation bar,
<div *ngIf = ("path == '/login'" && "path == '/home'") class="tabs-header-nav">
<a routerLink="/login" class="nav-link active">login</a>
<a routerLink="/bb" class="nav-link">home</a>
<a routerLink="/" class="nav-link">CC</a>
</div>
<div *ngIf = ("path == '/aa'" || "path == '/bb'") class="tabs-header-nav">
<a routerLink="/aa" class="nav-link active">aa</a>
<a routerLink="/bb" class="nav-link">bb</a>
<a routerLink="/" class="nav-link">CC</a>
</div>
Likewise I have 5 to 6 navigation bar in my html. Now I need to display a particular navigation bar for particular page. Single if condition ( *ngIf = "path === '/aa'" ) seems to be working, where if I give multiple conditions it is not working. Could you please help me on this?
You should go for ngSwitch that takes multiple values
<div [ngSwitch]="path">
<div *ngSwitchCase="'/login'">...</div>
<div *ngSwitchCase="'/home'">...</div>
</div>
I have created a Stackblitz demo here
I think you are doing mistake in *ngIf quotations
If you have data that may in every time be different, mostly you use of If. but if is not ok in every where. It is better that you use of switch-case in your code like:
public string TestSwitchCase(string value)
{
switch (value)
{
case "John":
return null;
case "Jack":
return "Jack";
default:
break;
}
return null;
}
Now in angular, there is best way to do this in HTML code. this is ngSwitch and use like:
<container-element [ngSwitch]="switch_expression">
<some-element *ngSwitchCase="match_expression_1">...</some-element>
<some-element *ngSwitchCase="match_expression_2">...</some-element>
<some-other-element *ngSwitchCase="match_expression_3">...</some-other-element>
<ng-container *ngSwitchCase="match_expression_3">
<!-- use a ng-container to group multiple root nodes -->
<inner-element></inner-element>
<inner-other-element></inner-other-element>
</ng-container>
<some-element *ngSwitchDefault>...</some-element>
</container-element>
For more information See: This
GoodLuck.
[SOLUTION] : Simply use "&&" operator to add multiple conditions in *ngIf -
//TypeScript File - demo.ts
//Declaration
flag: any;
temp_array = [];
//Assignment
this.flag = true;
this.temp_array = [1,2];
<!--HTML File - demo.html-->
<div *ngIf="flag && temp_array.length>0">
Both *ngIf conditions passes
</div>

How do I get the ng-show to work inside an AngularJS directive?

I'm having trouble getting ng-show to work inside my directive template. I'm using AngularJS 1.6.4. The Chrome debugger shows the successful change from ng-show="true" to ng-show="false" in the final DOM. But the element stays hidden when set to true. It appears this is because AngularJS adds a ng-hide class to the list in the element, but does not remove this when ng-show changes to true. Maybe AngularJS does not evaluate at this stage? How do I get this to show/hide properly?
I've been playing around with this for a while and have tried may different approaches including using the loading parameter directly instead of using the scoped showspinner. I've also tried omitting the mustaches (AngularJS expression) in the directive template like so: ng-show="showspinner" but this makes it worse by just rendering to ng-show="showspinner" instead of ng-show="false".
Following is my code.
The $ctrl.result is loaded asynchronously while the $ctrl.resultsLoading is set to true, when the results are done loading it's set to false:
<report-tile
title="My Report Item"
value="{{$ctrl.result.count|number:0}}"
loading="{{$ctrl.resultsLoading}}">
</report-tile>
This is my ReportTileDirective.js
(function(angular) {
"use strict";
angular
.module("app")
.directive(
"reportTile",
["$templateCache", "$compile" ,function($templateCache, $compile) {
return {
restrict: "EA",
scope: {
title: "#",
value: "#",
loading: "#"
},
link: function (scope, element, attribues) {
scope.showspinner = false;
scope.$watch("loading",
function () {
scope.showspinner = attribues.loading;
console.log("watching::loading::" + attribues.loading);
});
},
templateUrl: "app/directives/ReportTileDirective.html"
};
}]);
}(window.angular));
This is my ReportTileDirective.html
<div class="col-sm-4 col-md-3 col-lg-2 col-padding">
<div class="panel panel-default">
<div class="panel-heading tile-title">
<strong>{{title === '' ? 'Loading' : title}}</strong>
</div>
<div class="panel-body" style="text-align: right">
<strong>
<i ng-show="{{showspinner}}" class="fa fa-refresh fa-spin"></i>
{{value === '' ? 0 : value}}
</strong>
</div>
</div>
Finally this is the rendered DOM (as shown in the Chrome debugger Elements tab) when loading is done and it switches to true, the ng-hide is not removed:
<i ng-show="true" class="fa fa-refresh fa-spin ng-hide"></i>
Please help! Thank you!
I found my question is a duplicate of this one and thanks to #CodeWarrior's answer I was able to fix this. I can remove the whole link: section and use the loading parameter directly if: I bind it with = instead of # and then get rid of the expression syntax, so that this is evaluated in the directive rather than beforehand.
So my directive usage changes to:
<report-tile
title="My Report Item"
value="{{$ctrl.result.count|number:0}}"
loading="$ctrl.resultsLoading"> <!-- notice no mustaches here -->
</report-tile>
and my directive JavaScript file changes to:
(function(angular) {
"use strict";
angular
.module("app")
.directive(
"reportTile",
["$templateCache", "$compile" ,function($templateCache, $compile) {
return {
restrict: "EA",
scope: {
title: "#",
value: "#",
loading: "=" /* notice the = binding */
},
templateUrl: "app/directives/ReportTileDirective.html"
};
}]);
}(window.angular));
Then finally my directive template changes to:
<div class="col-sm-4 col-md-3 col-lg-2 col-padding">
<div class="panel panel-default">
<div class="panel-heading tile-title">
<strong>{{title === '' ? 'Loading' : title}}</strong>
</div>
<div class="panel-body" style="text-align: right">
<strong>
<i ng-show="loading" class="fa fa-refresh fa-spin"></i> <!-- notice to mustaches here -->
{{value === '' ? 0 : value}}
</strong>
</div>
</div>

Passing double quotes to Jscript

insertText is java script that accepts two string paramters
I need to pass two strings
first parameter:
<img src="
second
">
I just cant figure out how to pass double quote as parameter
This works
<a onClick="insertText('<em>', '</em>'); return false;">Italic</a>
This does not
<a onClick="insertText('<img src=/"', '/">'); return false;">Image</a>
Prints '); return false;">Image
You want to use \ rather than /
The escape character for JavaScript is \, not /. So try this:
<a onClick="insertText('<img src=\"', '\">'); return false;">Image</a>
Update:
The solution above doesn't work, because the double-quotes "belong" to the HTML and not to the JavaScript, so we can't escape them in the JavaScript code.
Use this instead:
<a onClick="insertText('<img src=\'', '\'>'); return false;">Image</a> // --> <img src='...'>
or
<a onClick='insertText("<img src=\"", "\">"); return false;'>Image</a> // --> <img src="...">
Since you are using jQuery, why don't you do it the jQuery way?
insertText = function(a, b) {
// your insertText implementation...
};
$('a').click(function() { // use the right selector, $('a') selects all anchor tags
insertText('<img src="', '">');
});
With this solution you can avoid the problems with the quotes.
Here's a working example: http://jsfiddle.net/jcDMN/
The Golden Rule for that is reversing the quotation which means I use the single quotation ' inside the double quotation " and vice versa.
Also, you should use the backslash symbole to espape a special character like ' and ".
For example,
the following commands should work as they apply the rules mentioned above...
<a onClick="insertText('<em>', '</em>'); return false;">Italic</a>
or
<a onClick='insertText("<em>", "</em>"); return false;'>Italic</a>
or
<a onClick="insertText('<img src=\"', '\">'); return false;">Image</a>
or
<a onClick='insertText("<img src=\'", "\'>"); return false;'>Image</a>
I hope this helps you ...
You need to escape it.
<a onClick="insertText('<img src=\"', '\">'); return false;">Image</a>