Angular Material Badge onclick - javascript

I have this element with badge and I would like to add onClick on the badge, but in this case the onClick reacts on the text click, how can I do it ONLY for the badge?
<div matBadge="i" matBadgeOverlap="false" (click)="onClick()">Text with badge </div>

This is an issue that was also raised once to the material team back in 2018 on GitHub.
Answer:
Badges are intended to be for displaying information only and aren't meant to be interactive. Introducing interactions on them would lead to accessibility problems, so this isn't something we would support.

Badge elements have the style 'pointer-events: none', which is why you don't get the click events. You can use Javascript to query the inner implementation element and change this style.
So for the following HTML:
<div id="todo-actions" matBadge="!" matBadgeOverlap="false" matBadgeColor="warn"> </div>
this code will do the trick:
const todoBadge: HTMLElement = document.querySelector("#todo-actions .mat-badge-content");
if (todoBadge) {
todoBadge.style.pointerEvents = "inherit";
}
Note that the .mat-badge-content is the inner element created by the matBadge directive. Using #todo-actions .mat-badge-content ensures that the CSS style is changed for the specific badge element.
Finally, if you're using Angular, put the JS code in your AfterViewInit handler.
Only drawback with this approach is that it's susceptible to break if the matBadge implementation changes as that can happen during major framework overhauls.

You could suround the badge by a span and add the click event listener to it:
<div matBadge="i" matBadgeOverlap="false">Text with <span (click)="onClick()">badge</span></div>

Related

Custom cursor in React should change when hovering over every link

I'm trying to create a custom cursor in React, and want the cursor to change in appearance when it hovers over any link on the page.
I can get this to work on a specific single link by using a ref, like so:
<a href="#" ref={myLink}>My link</a>
And then using this to attach event handlers:
myLink.addEventListener('pointerenter', handlePointerEnter); myLink.addEventListener('pointerleave', handlePointerLeave);
But what I want is for the cursor to change when hovering over every possible link on the page, and I won't always have control over the content of this website so adding refs to every link in this way is obviously unrealistic.
Any help finding a better solution would be hugely appreciated!
Edit:
This is the markup for my custom cursor:
<div ref={cursorSm} className="cursor--sm"></div>
<div ref={cursorLg} className="cursor--lg"></div>
I'm using refs there because I'm using gsap to animate it.
You can use the CSS cursor property.
a {
cursor: some-value
}

how to stop css effects from taking place when I click a button

I have a button in html, that when clicked turns light green. I have figured out that this is due to some css I have included, but I cannot remove it due to the css being needed in other parts of the code. Is there a way I can include some css specific to the button such that for it only, there will be no effects from clicking the button? Ideally I'd like to use css/html only, but if absolutely necessary I can do with javascript/jquery.
That's a simple example:
.active{background-color:green;}
.active:active{background-color:blue;}
.notactive{background-color:green;}
Example 1 (your situation):
<button class='active'>
pressme
</button><br>
Example 2 (change simple class):
<button class='notactive'>
pressme
</button>
<br>
Example 3 (use style):
<button class='active' style="background-color:green!important">
pressme
</button>
At the first example is your case, in the second example i change simple class then :active have no effect, in the third i used !important with style
It seems like you have used ":checked" on button directly.
You can use :checked css on specific ID only. So it will stop affecting for all buttons.
If you haven't used above please mention your CSS here.

How do I target an html element in Angular from another sibling component (skip link)?

I need to target a nested layout component's element from another sibling component. The desired target element is several layers deep within said component. I Have a Header Component that is housing a Skip Link <a></a>. Upon selecting the Skip Link I need to send focus to the aforementioned sibling component's #main-content element, which happens to be a <div></div>. How can I achieve this?
I have tried creating a custom attribute directive. I have tried targeting the element with #ViewChild("main-content"), I can't seem to get the target element to achieve focus, and thus show the border with style changes. Any Advice is greatly appreciated.
Header Component:
...
<a [href]="skipLinkPath" class="skip-link" (click)="skipLink()" tabIndex="0">Skip to Main Content</a>
...
Header Component's TS:
...
#ViewChild('#mainContent') mainContent: ElementRef;
...
skipLink() {
console.log("click event called");
console.log(this.mainContent);
this.mainContent.nativeElement.focus();
}
...
Main Component:
<div class="content-display skip-link-focus" role="main" id="main-content" #mainContent>
<router-outlet></router-outlet>
</div>
You can use a shared service to achive this
SharedService.ts
->
isFocus: Subject<boolean> = new Subject<boolean>();
Create a subject in shared service
Header Component
skipLink() {
this.sharedService.isFocus.next(true);
}
Main Component
create a field
isFocus = false;
in on init method subscribe to service
this.sharedService.isFocus.subscribe(value => {
this.isFocus = value;
});
<div class="content-display skip-link-focus" role="main" [ngClass]={_focused: isFocus} id="main-content" #mainContent>
<router-outlet></router-outlet>
</div>
in css
._focused {
//required css
}
Not entirely sure why the accepted answer is JavaScript based. This can all be achieved with no JS at all in a much simpler fashion and more robust way.
<a [href]="skipLinkPath" class="skip-link" (click)="skipLink()" tabIndex="0">Skip to Main Content</a>
Firstly the skip link shouldn't need a tabindex, if you needed to add that to make the link accessible have a quick look through your code for an issue as links are automatically added to the focus order.
The above could become:
<a [href]="#main-content" class="skip-link">Skip to Main Content</a>
Notice how I changed the href to match the id of your main content div.
<div class="content-display" role="main" id="main-content" #mainContent>
<router-outlet></router-outlet>
</div>
The above will work without needing to handle the focus state yourself (if you want the main div to show that it is focused add tabindex="0" to it, but the above example will still skip the menu with the next tab stop being the first focusable item in your HTML).
What about the URL change using an anchor?
Obviously the above adds a #main-content to your URL, I don't consider that an issue, but if you do, you could intercept the click and use the history API in the browser to stop the URL updating.
Although that may then seem like more work, you then have a functional skip link that works without JavaScript so that whatever no JavaScript fallback your site has is still accessible.
final suggestion
<div class="content-display" role="main" id="main-content" #mainContent>
The above div looks like it could be changed to a <main> element to be more semantically correct as I am assuming you are using HTML5.

JQuery to expand all collapsible sections of a page (from external website)

The page contains multiple sections. Each section is represented by a TD block (see code below), the actual page would show a ">" icon (hovering over it shows the a href: javascript:void(0)), and when manually clicked, it would expand the section by a POST call to the endpoint from the SPAN block.
<td id="abc-parent" data-column="parent" data-row="abc" class="mt-cell mt-center">
<a href="javascript:void(0)">
<span class="a-declarative" data-action="myitable-fetch-rows" data-myitable-fetch-rows="{"endpoint":"/hz/inventory/variation?parentRecord=abc","rowId":"abc"}">
<div class="mt-variation-icon mt-variation-expand"/>
</span>
</a></td>
I am looking to create a bookmarklet containing a line of JQuery. And when called, it would expand all collapsible sections of a page.
What I mean is something like this (note this does not achieve what I described above):
javascript:jQuery('.a-declarative').each(function(i,e){e.click()})
I think you are looking for the "Trigger" function:
.trigger( eventType [, extraParameters ] ) Description: Execute all handlers and behaviors attached to the matched elements for the given event type.
https://api.jquery.com/trigger/
So your code above should be something like:
$('.a-declarative').trigger('click');
Use at your own risk as this is not a very stable way to trigger events.
Create a global class .active for all the expandable areas (make sure they all have it, even if you have to add it after another class="another active")
Assure .active is the expanded state. Then call it like below.
$('.item').toggleClass('active');
Simple jsfiddle demo of this.
If for some reason you can't alter the mark-up to make a global active class, you may have to call it with all the 'expanded selectors' (but should be no reason for this)
$('.item').toggleClass('active expanded open');
For help on the bookmarklet aspect; this is a cool link that should help you out; but all you should be doing is defining the above in a function and then trigger with a .click() event.
Update! I just sent another pointer via comment section below; but you know you can add a class .active via jQuery to all the toggles that share same class or ID. But you will still have to investigate how the toggles were built on this external website for you to incorporate the expanded state with your new .active state. There is no way for use to know this as you didn't post that code; but it's typically found in the .css pretty easily.
$('td').find('.mt-center').addClass('active');

How to add event handlers to DIVS with CSS classes containing a particular string?

I want to be able to add some onclick event handlers to some DIV elements which are styled by CSS classes matching a particular string. The DIVS would be for a particular type of image which represents something called a Work Center in Discrete Event Simulation that I want users to be able to click on, change some settings, and run the simulation again.
I'm using a system that was developed ages ago that handles these images like so:
<div id="Decision__1" class="S8DisplayObject Image__for__Decision__1" style="top:35px; left:579px; width:118px; height:71px;"><div id="Decision__1_textData_2" class="S8Web-TextData" style="left:-136px; top:-12px;"><div class="noTextWrap">0</div></div><div class="sb_block_display"></div></div>
<div id="Decision__2" class="S8DisplayObject Image__for__Decision__2" style="top:35px; left:579px; width:118px; height:71px;"><div id="Decision__2_textData_2" class="S8Web-TextData" style="left:-136px; top:-12px;"><div class="noTextWrap">0</div></div><div class="sb_block_display"></div></div>
So it incrementally assigns a number to each class, and in this case, the string I would want to compare would be Image__for__Decision. Unfortunately I can't really delve into how these CSS classes are named, as they are part of a much larger conversion process.
Any tips would be greatly appreciated!
You can use the "attribute contains" selector:
$("div[class*='Image__for__Decision']").click(function() {
console.log("click!");
});
James beat me to the punch, but I think for this I prefer the "starts-with" selector.
var yourDivs = $("div[class^='Image__for__Decision']");
His code also shows how you can set up the event handler.
var imageDivs = $('div[class*="Image_for_Decision"]');
Documentation

Categories

Resources