How to make a call on click of 'Next' and decide to progress or not using CDKStepper? - angular-material-stepper

I would like to programmatically move to the next step in
I have a button bar component with the steppers controls:
<button id="cancel"
*ngIf="showCancelButton"
(click)="cancelWasClicked()">
Cancel
</button>
<button id="previous"
*ngIf="showPreviousButton"
(click)="previousWasClicked()" matStepperPrevious>
Previous
</button>
<button id="next"
*ngIf="showNextButton"
(click)="nextWasClicked()" matStepperNext>
Next
</button>
When I click the next button, I want to trigger some external validations which the result will manage if moving to the next step is what we want.
From the documentation, there is a next method but not sure where this method is available if I have a setup like this:
<mat-step>
<someComponent></someComponent>
<button-bar-component></button-bar-component> <!-- Contains the stepper buttons>
</mat-step>
<mat-step>
<someOtherComponent></someOtherComponent>
<button-bar-component></button-bar-component> <!-- Contains the stepper buttons>
</mat-step>
etc..
I saw a similar question here: Can I programmatically move the steps of a mat-horizontal-stepper in Angular / Angular Material
Issue with this is I do not have access to the id of the stepper within my button bar. Can I pass the ID as an input somehow and call stepper.next?

Solved my problem by passing my "stepper" as an input into the button bar component. This gave the button bar component access to the stepper API so I can do other logic on the button click.

Related

Radio Button group created using Designer doesn't trigger the changeValueEvent

I have added Radio Button group by using Vaadin designer to my view :
<vaadin-radio-group value="Line" id="vaadinRadioGroup" style="margin-left: var(--lumo-space-s);">
<vaadin-radio-button name="Line" style="flex-grow: 0; align-self: stretch;" checked>
Line
</vaadin-radio-button>
<vaadin-radio-button name="Heatmap" checked>
Heatmap
</vaadin-radio-button>
<vaadin-radio-button name="Both" checked>
Both
</vaadin-radio-button>
</vaadin-radio-group>
And in my java code :
vaadinRadioGroup.addValueChangeListener(radioButtonEvent -> {
System.out.println("The event is triggered.......")
});
The change in the radio button value does not trigger the changeValueEvent. Anything I am missing here??
A bit closer look revealed the problem: with a radio button group you can't declare the data in the design itself if you want to be able to use it from the Java side as well. You should do that from the Java side using e.g. setItems() or adding a DataProvider. If you do that, the individual radio buttons won't be visible when you look at the design, but they'll be there when you run the application.

Reading child element when parent is focused - accessability

I am using the mat-tab-group from https://material.angular.io/components/tabs/overview.(used complex labels approach with ng-template)
The tab contains a name of the tab and a button to close the tab.
Whenever i focus the tab, it reads both aria-labels of name and a button. When tab is focused, it should read only the name but not the close button aria label. When tab is focused currently and then clicking on tab will focus the close button, at this time it should read the close button aria label.
How to do this ?
Code:
<mat-tab-group dynamicHeight [(selectedIndex)]="activeTabIndex" (selectedTabChange)="changetab($event)">
<mat-tab *ngFor="let tab of Tabs; let i = index" [label]="tab.name" [attr.sortColumn]="tab.sortBy" [attr.sortOrder]="tab.sortOrder"
[attr.viewId]="tab.id" [attr.viewObjectID]="tab.viewObjectId" attr.aria-label="{{tab.name}}">
<ng-template mat-tab-label>
<div class="tab-container">
<div class="somestyle">
<span class="tab-name" [matTooltip]="tab.name">{{tab.name}}</span>
</div>
<button mat-icon-button tabindex="0" id="{{tab.id}}" class="close-btn" (keyup)="closeTab($event,view)" (click)="closeTab($event,view)" attr.aria-label="{{closetab}}">
<mat-icon class="material-icons">cancel</mat-icon>
</button>
</div>
</ng-template>
</mat-tab>
The output of this : I am using "jaws" for screen reading tool. When we focus on tab, it reads tab name and close button label ( attr.aria-label="{{tab.name}}" and attr.aria-label="{{closetab}}").
Do you need to use aria-label at all?
The WAI-ARIA Practices document has this at the top of its "Read Me First" section:
No ARIA is better than Bad ARIA
The mat-tab-group examples simply use a text node inside the tab (which is a button with role="tab") for the accessible name. That should be adequate. Let the visual label be the accessible name, if possible.
The only reason you should use aria-label on a button is if the accessible name should be different from the button label. e.g. in cases where only an icon or unicode glyph is used as the visual label, in place of human-readable text.
In all other cases, just put the accessible name in a text node inside the button. (You may of course wrap it in span or other inline elements - as the mat-tab-group example does, if you need more refined styling).
This is true of other GUI controls too, although the visual label mechanism differs between element types. (e.g. The <input> element needs a corresponding <label>, which is both visible and understood by screenreaders because of the for attribute.)
If you must use aria-label, make sure it is on the element that gets focus, otherwise the screen readers will each try to guess what you want the accessible name to be, with unpredictable results. I suspect this is what you are experiencing.
Also, if I am not mistaken, you are adding the 'body' of the tab (including the close box) to the focusable tab itself. This is not the correct structure. Again, let the mat-tab-group example be your guide.
You should be able to overwrite what is read on focusing the entire tab, if you add an aria-label="Your preferred text here" to the tab element.

Adding child elements to submit button. E.g. a span within the button

I need to add create a button with the output of something like
<button class="my-btn" action="${nextAction}" disabled="${nextDisabled}">
<span class="next-icon">Next</span>
</button>
I can use the below code to output the button fine, but I can't figure out how to add the span within it.
<g:actionSubmit name="next" value="${nextText}" class="my-btn" action="${nextAction}" disabled="${nextDisabled}"/>
Any ideas?
You won't be able to do this with the g:actionSubmit because it doesn't allow a body to be included in the tag. The button element allows spans just fine. I use this technique quite a bit and in fact, a lot of the Bootstrap markup for things like Button Dropdowns embed spans in buttons for images.
I think what you'll need to do is just give a name to the button and submit the form to a single action then use the name of the button to determine what logic you need to perform.
<g:form action="save" controller="foo">
<button name="action1">Action 1</button>
<button name="action2">Action 2</button>
</g:form>
def save() {
if (params.action1) {
} else if (params.action2) {
}
}
Something like that anyway.

JQuery Mobile - Refreshing a Button After Changing It's Content

Is there a reason why the click handler is removed from my button after calling the button() method on it. I am changing the content of my buttons, and as a result I need to refresh them. I noticed refresh does not work, so I tried the button method.
This will restyle my "button", but I lose my click event.
How can I accomplish both?
http://jsfiddle.net/RQZG8/2/
And here is the code:
$("[data-role=button]").html("hello world").button();
$("[data-role=button]").click(function(){
alert("i have been clicked");
});
My big issue is that I have a div which is acting as a button. I want to change the content of the div, but I want to be able to have it continue to look like a button while keeping it's behavior.
Try this: $("[data-role=button] .ui-btn-text").html("hello world"); otherwise the padding is lost.
First of all IMHO, given your example that goes with the question (when you change only caption of a button), there is no much point to use a div as a button when jQM gives you a lot of standard choices.
All of these:
<button>Button element</button>
<input type="button" value="Button" />
<input type="submit" value="Submit Button" />
will be automatically enhanced by jQM to buttons without even specifying data-role="button".
And you can of course use a link as a button
Link button
Now if you still want to use your div as a button you don't need to specify data-role="button" just call button() plugin. That will create all necessary markup for you and your original div will be preserved as hidden.
<div id="button1">By button<div>
$("div#button1").button();
To refresh a button after you changed its caption you need to call refresh method:
$("div#button1").html("Hello World").button("refresh");
Now to normally handle the click event of a particular button (if it's not the only one on the page) you probably need more specific selector than just the data-role=button attribute. id would be perfect for that. So instead of
$("[data-role=button]").click(function(){...});
do
$("div#button1").click(function(){...});
And lastly you most certainly know that, but I didn't see it in your jsfiddle, so I just mention that you better put your code in one of the jQM page handlers. pageinit is recommended way to go.
$(document).on("pageinit", "#page1", function(){
...
});
Here is jsFiddle.

jQuery mobile : correct way to use button?

I'm starting with jQuery mobile and have some problems with my buttons.
The web application is a shopping list. It displays a list of items to shop and in the footer buttons on actions I can perform on the items.
The actions are:
increment number of items to buy
decrements number of items to buy
move item up in list
move item down in list
add new item
delete item
modify item text description
The actions are implemented in javascript and works fine. The problems I have is with controlling the buttons and the associated actions.
By experience, I have see that for the increment and decrement it is more convenient to have a button with an active state, for the other operations it is preferable to have a selected item and apply the action on the selected item when the button is pressed. When adding an item, the item would be inserted before the selected item, and if pressed when no item is selected, the new item is appended to the list.
I would also like to have 2 modes. In one mode, only the increment and decrement buttons are shown and the user can update the number of items in its list. In the other mode the user is modifying its list. It is in the second mode that the selected item is required.
I managed to associate a default action my item lists by using the .on() method as a delegate.
$('#itemList').on( "click", ".item", function(evt)
{ ctrl.doAction($(evt.currentTarget)); });
Here is the html code I use to test the first mode.
<!-- footer -->
<div data-role="footer" data-position="fixed" class="ui-bar" id="btnBar" >
Plus
Minus
</div>
<!-- /footer -->
What should I put as href value ? I don't want the page to be reloaded. In some examples I see "#".
This is how I associate the action to the button:
$('#btnPlus').on( "tap", function(evt)
{ ctrl.doAction = ctrl.increment; });
Another problem I have is that there is no feedback on the button click action. When I click a button I would expect to have it highlighted for a short time. This doesn't happen.
The browsers have also different behaviors. In firefox, the clicked button gets a blue halo apparently showing that it has the focus. But the button isn't displayed as active.
If I put "#!" as href (don't know what it means) on Android, the clicked button is shown active.
Should I use click or tap as event type ? How could I write click or tap ?
How could I implement a two state button displayed as active and inactive ?
How is an action button used : always displayed inactive and feedback when pressed ?
I solved the problem my self.
to switch between sets of buttons in the footer, I create multiple footers in my HTML document with style="display:none" in the hidden footers. The one without this will be shown. I assigned a specific id to each footer so that I can write $("#footer1").hide(); $("#footer2").show();
I have buttons to switch between footers. The footer switching event handler must be called with the "mouseup" event. This is required for it to work on the iPad and Android phones.
To change appearance, don't use .button() as suggested here. Use:
$("#myButton")
.removeClass( "ui-btn-up-a ui-btn-down-a ui-btn-hover-a" )
.addClass("ui-btn-up-b")
.attr( "data-theme", "b" );
Note: There was a bug in my code which caused desperate hair pulling

Resources