HTML file:
<div [hidden]="isshow">
<h1>this is a</h1>
</div>
<div [hidden]="!isshow">
<h1>this is b</h1>
</div>
component.ts:
public get isshow() {
return (this._state === 'ready');
}
The state value is changed by an EventListener, and will change from "connecting" to "ready".
What I want is to show "this is a" at the beginning then change to "this is b"
when state is "ready", but looks it doesn't work.
What should I do? Thanks in advance.
Change your html to the following:
<div *ngIf="isshow">
<h1>this is a</h1>
</div>
<div *ngIf="!isshow">
<h1>this is b</h1>
</div>
You can refer to this answer to see the differences: https://stackoverflow.com/a/43034841/3329836
i think your display:none is override in your style use *ngIf instead
<div *ngIf="isshow">
Just a piece of advice here. Due to some internal shenanigans angular does with it's change detection system it's better not to use getter for binding.
Your
public get isshow() {
return (this._state === 'ready');
}
will be called everytime your component checks for changes (just put console.log there before return (this._state === 'ready'); and you'll see)
it's better to use a pipe or just put the condtion this._state === 'ready' in your binding and this way it'll be called only when this._state actually changes
The same is also true for functions bound to your fields i.e you shouldn't use them in bindings
Try to add [hidden] { display: none; } in your stylesheets (remember it should be added globally). I'm not sure why, but it's kinda look like missing in Angular or there is some problems with it. I've found some old issues about it, but they are closed long time ago, but in plunkr it helped.
Related
A custom directive applied to both components(1/2)-in-spotlight is not working properly when using *ngIf. The issue resolves when I remove the *ngIf and one of the components that would not show in the current situation/"mode".
In the HTML file using the component (original):
<div>
<div>
<div>
<div>
<component1-in-spotlight *ngIf="mode===OptionOne"></component1-in-spotlight>
<component2-in-spotlight *ngIf="mode===OptionTwo"></component2-in-spotlight>
</div>
</div>
</div>
</div>
I found 2 solutions but both aren't effective or proper.
Duplicating the surrounding parent/grandparent components (placing the second case in an <ng-template #elseBlock>) and applying ngIf-else to the top most component (in the oversimplified example, a div) works. But, I'd have a lot of duplicate code and is a terrible solution.
Option 1 (to illustrate since it might be a bit confusing for some). In the HTML file using the component:
<div *ngIf="mode===OptionOne"; else myElseBlock">
<div>
<div>
<div>
<component1-in-spotlight></component1-in-spotlight>
</div>
</div>
</div>
</div>
</ng-template #myElseBlock>
<div>
<div>
<div>
<div>
<component2-in-spotlight></component2-in-spotlight>
</div>
</div>
</div>
</div>
</ng-template>
Using [hidden] on the 2 components instead of *ngIf seems fine. But there is never a case where the hidden component will be toggled to visible, it's decided upon creation and stays using either of the 2 components until it's destroyed. So, it should just only have one of the 2 components in DOM. Not just hiding it. Plus, that means flipping the logic--[hidden]="mode!==OptionOne". For now, it's just 2 options and seems unlikely more would be added, but I can't guarantee that.
--
It may seem like these 2 components are the same, so why not just have 1 component and pass in the mode and let the logic decide within the TS file of that component? Well, they both have different services that are injected into the constructor for the component. I was trying that before finding out and remembering that I can't use this before calling super() to decide which service to send up to the base class the component is extending.
Merging the 2 components and using #Input to get the "mode":
In the HTML file using the component:
<div>
<div>
<div>
<div>
<component-in-spotlight-merged [inputMode]="mode"></component-in-spotlight-merged>
</div>
</div>
</div>
</div>
In the component-in-spotlight-merged TS file--what I tried to do:
export class ComponentInSpotlightMergedComponent extends MyComponentBaseComponent {
#Input() inputMode: MyEnumType;
//...
constructor(
myService1: MyService1,
myService2: MyService2,
){
if(this.inputMode === Option1){
super(myService1);
}
else{
super(myService2);
}
}
//...
}
Using [hidden] can be for a quick fix, but is there a proper way to fix this?
Edit:
Not working meaning: It's a custom directive for tabbing focus between elements and the hotkey logic is binded here. Somehow the hotkey works but the focus is not working as it expected and none of my console.log() are outputted.
Angular 9+
You can use Angular NgSwitch directive as shown below.
<div [ngSwitch]="mode">
<!-- the same view can be shown in more than one case -->
<component1-in-spotlight *ngSwitchCase="option1">...</component1-in-spotlight>
<component2-in-spotlight *ngSwitchCase="option2">...</component2-in-spotlight>
<!--default case when there are no matches -->
<some-element *ngSwitchDefault>...</some-element>
</div>
The fix was to use setTimeout(() => myCallbackFn(), 0); (on my hotkey bind function that is called in ngAfterViewInit in a component class down the line--a view grandchild?).
I was in a rabbit hole of reading other stackoverflow questions and found How do I combine a template reference variable with ngIf? where a comment mentioned that ngIf takes a tick of time to evaluate. I eventually searched and found How to check whether ngIf has taken effect.
So, I will try to make this quick, when I click on the div with the className "question" I want my icon to change from angle-up to angle-down and vice versa (also want to make another div visible / invisible). Things is, I'm currently using this.state.icon, so when I click on one question all the icon change for all the other too (same for the reveal things) Here is my code :
I'm on mobile so i make a pastebin
So, my question is, how can I change the icon and reveal the answer only for the question I click on ?
Thanks in advance for any help ! :)
Blockquote "Things is, I'm currently using this.state.icon, so when I click on one question all the icon change for all the other too (same for the reveal things)"
The problem is that every question shares the same state. The block shown below should be extracted into its own component, and it should be in that component that the state is kept which determines whether to expand the question.
Then, in your parent container, you can just list multiple e.g. <Question /> components, and provide the text for each question/answer.
<div className={styles.category}>
<h2>Cat</h2>
<div className={styles.question}>
<p>Question 1 ?<FontAwesomeIcon className={styles.iconAngle} icon={this.state.icon} /></p>
</div>
{
this.state.showMe
? <div className={styles.answer}>
<className={styles.titleAnswer}>Title 1</h3>
<p>Answer 1 </p>
</div>
: null
}
</div>
Not sure this is exactly what you are looking for but here is my solution
class CommissionData extends Component {
constructor() {
super();
this.showUpArrow = false;
}
onUpdateArrow =()=> {
this.showUpArrow = !this.showUpArrow
}
...your code
}
In this way you can update your icon and div without using state
I tried lots and search numbers of time but I didnt get any solution to disable click on div element. Already question has been asked but they are saying not possible on divs and I want to know only, is there any ways to disable div in angular2
<div>(click)="isDisabled ? $event.stopPropagation() : myClickHandler($event); isDisabled ? false : null"
[class.isDisabled]="isDisabled"></div>
And the old answer not clearly about disabling divs and pointer-events:none is not supported in old version browser also it become editable from network tab
You can use css:
pointer-events:none
Or maybe could do something like:
<div (click)="false; $event.stopPropagation();"> </div>
There are several ways of preventing a click, depends on what you need
The straightforward answer here will be just not to render the function if the element should be disabled. Something like this:
<div (click)="shouldBeDisabled ? null : callYourFunctionHere()"></div>
But a better solution will be to put this condition into your function itself
HTML
<div (click)="callYourFunctionHere()"></div>
TS
const callYourFunctionHere = () => {
if (this.shouldBeDisabled) return
//if statement above is false your general logic will be rendered
}
I created a button
<button type="button" ng-click="chooseOptions()" id="chooseOptionButton" ng-bind="whatToDisplay()"></button>
Which shows a <div ng-show=appearOnChoice>on click and toggles back when clicking again!
$scope.chooseOptions=function(){
$scope.appearOnChoice=!$scope.appearOnChoice;
}
However, I also want this element to hide again, when the user clicks anywhere outside this div
element. How can I do this? I need strictly stick with AngularJS and not use jQuery.
Hope you can help me with that.
EDIT: I tried to adapt some of the events of bootstrap datepicker, but I am not sure how to apply it properly
$scope.$on('datepicker.focus', focusElement);
scope.$watch('isOpen', function(value) {
if (value) {
scope.$broadcast('datepicker.focus');
scope.position = appendToBody ? $position.offset(element) : $position.position(element);
scope.position.top = scope.position.top + element.prop('offsetHeight');
$document.bind('click', documentClickBind);
} else {
$document.unbind('click', documentClickBind);
}
});
var focusElement = function() {
$timeout(function() {
self.element[0].focus();
}, 0 , false);
};
How can I adapt this to my case?!
I think that you dont have to write a function, you can use ng-init to create a model, ng-show to show/hide the div based on the value of the model, and with ng-click change the value of the model. See example below:
var myapp = angular.module('myapp',[]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myapp">
<div ng-init="showDiv = true;" >
<div ng-show="showDiv"> SHOOOOOOOOW </div>
<button ng-click="showDiv = !showDiv;">Click me</button>
</div>
</div>
You can set the model value to be false when the user is clicking everywhere else, and set it again to true when it clicks the button. If you made a fiddle I can help you easier :)
If the DIV has focus, then you can use the ng-blur directive on the DIV to run set appearOnChoice to false. However, if the DIV does not already have focus (which it won't if you are depending on the button to make it visible), you will need to manipulate the DOM in your code (to provide focus) OR create a custom directive to set focus so that the ng-blur directive will work. Check out possibilities for that with this link.
alternatively, you can add an ng-click directive to every clickable object on your view that will hide the DIV when fired. But I don't really think that's the best way to go...
The easiest and cleanest way to handle the click away is to register and event on the document that will remove the element when anything other than it, or its children, are clicked.
For an example of a service that does this see GitHub EnzeyNet/Services
Sorry about the lack of documentation there but after injecting the service you would use it like this.
var divElem
nzService.registerClickAwayAction(function() {
divElem.remove();
}, divElem);
I simply solved it by using a ui bootstrap dropdown. This comes along with an is-open option and closes on click outside.
How can I load div content from external file, but also use a case statement in the process? Might there be something with my Jquery code? Actually.. I'm confused??
JQuery Code:
$('.click-test').click(function() {
switch (this.id) {
case "test":
$('#test').load('external-file.html #test');
break;
case "test2":
etc..
});
html page:
<div class="click-test" id="test">click test</div>
<div id="test">place words from external file here</div>
external file .html
<div id="test">some words</div>
The jquery code is basically correct. The "this" does refer to the HTML element as you suspected and is set. So, your switch is working.
<div class="click-test" id="test">click test</div>
However, you've got 2 div's in your base HTML page that both have the ID of "test". Every ID should be unique on an HTML page (including the content you're loading). So, you'll need to do a bit of refactoring.
You could for example change the HTML to:
<div class="click-test" data-loadid="test">click test</div>
And the JavaScript to:
$('.click-test').click(function() {
switch($(this).attr("data-loadid")) {
This would read from an attribute named 'data-loadid' using the jQuery attribute function. Then you can proceed to load the external div content using load as you had done. (Although, you may want to remove the bookmark as it's unnecessary?)
The this.id referes to nothing, since the this object is the .click-test div which has no ID attribute. Everything else looks fine, except I don't know if there should be a space bar after your .html #test