what ng-directives to be used when converting a button that uses id - html

I am working on converting a html to angular js and one of the issue i have is, a button on the page uses ID and based of that id there is a div class that runs set of texts to be displayed accordingly.
Code that we have is something like this.
Continue
From the HTML page when the user clicks on the button continue... below code will be executed.
<div class="ContinueClicked">
text.......
</div>
I am trying to figure out a way to see how i can make it work with angular js. So when the user is clicking on the continue button, the page should display the content in div continueClicked. Should i be using any directive here? please help.

You have to adhere to AngularJS principles and conventions. Angular uses Directives for most of the DOM transformations, and Bindings for constant DOM and Model updates (two-way data bindings.)
In your case scenario you might want to have the following DOM elements (inside a Controller inside an ng-app Module, see AngularJS docs):
<!-- The button with the event handler as ng-click directive -->
<button ng-click="isContinue = true">Show continue content</button>
<!-- The content wrap with ng-show directive -->
<div class="ContinueClicked" ng-init="isContinue = false" ng-show="isContinue">
My content to be shown
</div>
You can also read and practice basic concepts following the Angular Tutorial.

Related

*ngIf causing custom directive to not work properly

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.

How to share anchor links with angular components on angular 14?

I have a component menu which contains a few anchor tags. Each tag brings the user to that respective page section. I am trying to share the same anchor tag among the other components.
For example, I have two more HTML components called homepage.component.html and details.component.html. For each I call the menu.component.html by its selector. Both homepage and details html components have an id for the section I wanna scroll to. Here's how it looks like:
menu.component.html
Go to content
for both homepage.component.html and details.component.html
<div class="home-content" id="content"> Here comes more code </div>
It should work just like in a non-dynamic html project, however, when the anchor tag is clicked, the url redirects to '' (which is the first/default page) and then it shows the content for the first page, instead of the current componenet I am on.
I have tried creating a function where I get the current url and using the router.navigate, I pass the parameters indicating the fragment:
menu.component.ts
currentRoute: string
scrollToItem(){
this.currentRoute = this.router.url
this.router.navigate([this.currentRoute], {fragment: 'content'})
}
menu.component.html
<a (click)="scrollToItem()">Go to content</a>
However, this function adds the id #content to the url each time the anchor tag is clicked, redirecting the user to my 404 page.
I wanted to know if there is a way to use an anchor tag on the menu.componenet.html, while all the items that have "content" as their ids in different components are going to be displayed. Hopefully I made my question clear. If there is still questions about how the error occurs I can create and shate a stackblitz project. Thanks in advance :)

The best way to make the view, a read-only of routeroutlet 's sections in angular ts

I am trying to make the mid-section to be read only and just enabling the button "OPEN".
I have the below original code. "router-outlet" renders the combination of several feature components. And I do not want to disable each and every elements or feature components
<div="row mid-section">
<router-outlet></router-outlet>
</div>
<div class="row">
<button class="btn btn-default"> OPEN </button>
</div>
I tried by adding as below:
<div="row mid-section" readonly="readonly">
But it still allows to edit and click on button inside mid-section div.
I would really appreciate your help. Thank you!
The HTML readonly property doesn't work like that. Its only for form fields and must be on that actual DOM element.
https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/readonly
Without seeing more of your code, I can't really give a better answer than these 2 options.
Option 1, a shared service that has that read only property. You could have a service, that has a behavior subject that you can update from the parent component. The inner components would all need to have that service injected, and do something appropriate when the value changes.
Option 2, you would need a container component that has a new boolean input, and it would need to pass that value down to all the children components (which would also need an input).

Vue.js Form submits immediately shown with v-if

Am building a Wordpress plugin and am Using Vue Js.
I set up a variable that will be set to true on a button click
Then another div which is a modal that will remaining hidden with v-if as long as the variable is false. The is also a form in the div modal(pop up)
The problem is that once the value changes, on button pressed, the form submits immediately.
This has been happening but I usually ignore it because there was always a required field which will prevent the form from submitting automatically.
Vue.js Data object
{
selected_to_show : false,
}
The modal div
<div v-if="selected_to_show === true" class='mp-modal'>
<form on:submit.prevent="xhrSubmit()">
<form>
</div>
<button v-on:click="selected_to_show = true"></button>
This works but once the modal opens, the form submits immediately.
Note: There is only two button elements in the form where are all set to type="button"
The target is to prevent the form from submitting automatically when shown
If any one still uses this approach to re-render vue apps, my advice is, don't.
The best way to re-render the app is by doing
this.forceUpdate();
This will re-render the vue app instead of modifying data properties of the vue instance which are utilized during rendering.
However, don't overuse it.
Most times when your view is not re-rendering naturally, its probably because you are doing something wrong.

Selenium cannot find the element loaded from embedded html

So I'm trying to hit this "Review Agreement" button:
which has the following html code:
<section class="col-33 text-right">
<button class="anchor-button bordered" ng-click="onClickReviewAgreement()">Review Agreement</button>
</section>
BUT apparently it's loaded from another resource, so findElement(By.*) doesn't work on it - I've also tried By.xpath("/html/body/ul/li[2]/notification-bar/ul/li/section[1]/section[2]/button")-. All the related code I'm getting in View Page Sources is:
<!-- Agreement form modal -->
<ui-modal
ui-modal-id="ui.modals.agreementFormModal"
ui-modal-class="takeover agreement"
ui-modal-controller="AgreementFormController"
ui-modal-template-url="paths.templates + '/components/forms/tpl.agreement-form.html'"
ui-modal-has-dimmer="true">
</ui-modal>
Is there any way I can select these kinds of elements?
You should be able to bind to ng-click="onClickReviewAgreement()" using css. It should be unique and css is a better and more efficient alternative to xpath
Try using css to find the element and click thereafter -
WebElement buttonElement = driver.findElement(By.cssSelector('[ng-click="onClickReviewAgreement()"]'));
buttonElement.click();