Blazor: Button OnClick event triggered when calling StateHasChanged - button

I'm working on my first Blazor project for training purpose, and I'm facing a page lifecycle behavior that I can explain.
Starting with the Blazor App Server project template, I have added a simple page on witch I place some button on like this
<button class="col-1 btn btn-light btn-sm bg-transparent navButton" onclick="#GotoNext()">Next</button>
protected async Task GotoNext()
{
// Some code ..
}
But for some reason all button onclick event get triggered on page load and each time the method StateHasChanged get call.
How's that?
How to work around this?
Is this normal?
So much question ...
Thanks to you for reading

OK I figure it out.
My event registration wasn't good.
The event should be assign like
#onclick="GotoNext"
NOT like
onclick="#GotoNext()"

Related

Google One Tap signout

I am implementing Google One Tap in my website, however I am unable to prevent the popup from spawning immediately after the logout. I know I could manually set a cookie for that, however the official documentation suggests to add the class g_id_signout to any link or button used for the logout. In my menu I have this entry:
<li>
<a id="public-logout" class="g_id_signout" href="#logout"> <wk:text
name="public_area.logout"/></a>
</li>
but the popup still shows immediately after the logout. For reference, the "X" button on the One Tap popup triggers the cooldown regularly. Any idea?
Is the link dynamically created after Google One Tap library loaded?
If that's the case, the library cannot add correct event handler to this link.
You can try to add the click event handler by yourself with the example code below:
<li>
<a id="public-logout" onclick="google.accounts.id.disableAutoSelect(); return true;" href="#logout"> <wk:text
name="public_area.logout"/></a>
</li>
Or, you can bind the click event hander by JavaScript code.
More details at: https://developers.google.com/identity/one-tap/web/reference/js-reference#google.accounts.id.disableAutoSelect

How would one close previously opened NgbDropdowns when new NgbDropdowns are opend using the enter key?

I'm a newbie to NgbDropdown and related ng-bootstrap code, and I'm having trouble figuring out how to close all previous NgbDropdowns when a new one is opened using the enter key.
I've created a number of NgbDropdowns on a page in my Angular project, and I find that when I click from dropdown button to dropdown button, the previously opened dropdown closes; however, if I TAB from an open dropdown to another dropdown button and use the enter key to open the second dropdown, as may be needed for accessibility, the first dropdown does NOT close. I am left with two drop-downs overlaying each other.
This sequence can be duplicated on the main NgbDropdown example page at https://ng-bootstrap.github.io/#/components/dropdown/examples: on a different button (First example at the top.)
Sequence:
1. Tab to "Toggle Dropdown"
2. Hit the enter key to open the dropdown
3. Tab through the dropdown options, pluse one more time, so that you've
tabbed to the "toggle drop-up" button.
4. Hit the enter key
5. Both dropdowns will be open simultaneously.
Screen Shot
So apparently the code that closes previous dropdowns on click doesn't work when the enter key is pressed on a different button. Not finding much documentation about what can be done with the various Ngb objects in typescript, I am left not knowing how to close all previous dropdowns when a new dropdown is opened with the enter key. All I can think of doing is:
1) Loop over all dropdowns in the ts file, closing them prior to opening the latest. If this is the best solution, I do not see any way to loop over a collection of open drop-downs. Is there such an object/array available to me as part of the NgbSolution, or would I have to add each to an array on my own?
2) Trigger the click event when the enter key is pressed on a button. Again, I am unaware of how to have one event trigger another on an NgbDropdown object.
Any pointers would be appreciated. I've not posted my code here because it is the same as the basic example referenced above.
For your suggestion #1 (loop over all dropdowns and close them), you can implement it as follows:
In your HTML, declare each dropdown as a DOM variable using Template Reference Variables (the # syntax):
<div ngbDropdown class="d-inline-block" #dd1="ngbDropdown">
...
</div>
Add a click handler to the button as follows. This allows you to pass in a reference to the dropdown to the function called by the click handler:
<button class="btn btn-outline-primary" id="dropdownBasic1" ngbDropdownToggle (click)="closeOthers(dd1)">Toggle dropdown</button>
The complete HTML for a dropdown should look like this:
<div ngbDropdown class="d-inline-block" #dd1="ngbDropdown">
<button class="btn btn-outline-primary" id="dropdownBasic1" ngbDropdownToggle (click)="closeOthers(dd1)">
Toggle dropdown
</button>
<div ngbDropdownMenu aria-labelledby="dropdownBasic1">
<button ngbDropdownItem>Action - 1</button>
<button ngbDropdownItem>Another Action</button>
<button ngbDropdownItem>Something else is here</button>
</div>
</div>
Add the following as a class variable of your Typescript component. This allows you to reference all the dropdowns displayed in the component from the Typescript file:
#ViewChildren(NgbDropdown) dropdowns: QueryList<NgbDropdown>;
Add a click function to your Typescript component:
closeOthers(clickedDropdown: NgbDropdown) {
// Close all dropdowns
this.dropdowns.toArray().forEach(el => {
el.close();
});
// Open the dropdown that was clicked on
clickedDropdown.open();
}
Now whenever you click on a dropdown (or select it by tabbing and pressing return) it will call the closeOthers function which will:
Close all dropdowns
Open the dropdown that was clicked
Please see this StackBlitz for a working demo.
#Dordrecht - the approach I would take for the functionality mentioned in your comment below would be to create a service as follows:
export class ModalNotificationService {
private _closeModals: Subject<void> = new Subject<void>();
private _closeModals$: Observable<void> = this._closeModals.asObservable();
public emitCloseModalEvent() {
this._closeModals.next();
}
get closeModals$(): Observable<void> {
return this._closeModals$;
}
}
This service would be injected into any component that has modals and those components would subscribe to the observable closeModals$ and then close the modals in their own component. Modify the closeOthers method to call the new service's emitCloseModalEvent method to notify all the other components.

How to call a function inside a data-bind?

How to call the getStatus() function again inside this view code snippet after clicking a button?
The only thing that works form me is if I refresh the whole page.
<div id="statusContainter"data-bind="css:$data.getStatus('Rendered Approval')"> </div>
Basically, I want the getStatus('Rendered Approval') to fire if I click a button. The function is firing during initial rendering of the page. But I don't want to refresh the whole page to fire the function
Assuming getStatus is a knockout observable the code you have there sets the value, but only once. To get the value of an observable you call the function with no argument.
It sounds like you meant to do this:
<div id="statusContainter"data-bind="css:$data.getStatus()"> </div>
<button data-bind="click: $data.getStatus.bind($data, 'Rendered Approval')">Click to Refresh</button>
Update:
As #Brother Woodrow mentioned, the click binding expects a function for the handler. Passing parameters to the handler can be accomplished by wrapping it in a function literal or by using the this function as described in Note 2 here.

CSS Loading on click of submit button

I am building an advanced search form, and upon submit of criteria it brings back search results.
I wanted to implement a page loader for this, so on submit it then triggers the loading of the page
This tutorial works for the page itself
https://www.w3schools.com/howto/howto_css_loader.asp
Can anyone help me make this work when the submit button is clicked instead?
You can use JavaScript to show your loader when your submit button is clicked by adding at to the button directly
<input type="submit" onclick="document.getElementById(ID_OF_YOUR_LOADER).style.display='initial';">
or in a separate script-Tag:
<script>
document.getElementById(ID_OF_YOUR_SUBIMT_BUTTON).onclick=function(){
document.getElementById(ID_OF_YOUR_LOADER).style.display='initial';
}
</script>
Your loader would look like this:
<div id="ID_OF_YOUR_LOADER" class="loader" style="display:none"></div>

How to add Mate Listeners using Action Script

in one of my forms, I have used the following code for adding Mate Listeners
<mate:Listener type="{DBEvent.Update_Result}" receive="{onUpdateResults(event)}"/>
I am displaying this form as a popup. What happening is, for the first time, onUpdateResults method executed only once as expected. Then i close the popup and reopened it. This time onUpdateResults method called twice, then next 4time and so on...
After so much of googling, i found that Mate Listeners are still active, even though we remove/close the popup. I tried weak references, close the popup using PopupManager.RemovePopup and so on. Nothing worked.
Then i thought of registering and unregistering the mate listeners manually using action script. So, i have tried the following code
var _listener:Listener= new Listener();
_listener.addEventListener(DBEvent.Update_Result,onUpdateResults);
to unregister...
_listener.removeEventListener(DBEvent.Update_Result,onUpdateResults);
But this is also not working.
Please somebody help me fix this issue.
Try this.
Create runtime popup windows in main application:
PopUpManager.createPopUp(this, MyPopUp, true);
MyPopUp - mx:TitleWindow from MyPopUp.mxml
Add any listeners in OnInit in MyPopUp.mxml:
_listener.addEventListener(DBEvent.Update_Result, onUpdateResults);
Close popup when you click any button (button's click event or any):
PopUpManager.removePopUp(this);

Resources