Deselect material-radio-button in Angular 10 on second click [duplicate] - javascript

How can I clear <mat-radio-button> selected on second click
(after it is already selected)
I know I can implement this behavior with checkbox but i need to allow select only one item.
Any help?
My code look like :
<mat-radio-group name="WasFamilyMemberPresent">
<mat-radio-button *ngFor="let item of lookupNoYes" [value]="item.Code" >
{{item.Desc}}
</mat-radio-button>
</mat-radio-group>

** UPDATED ** 10/11/2022
reference Sara's stackblitz answer below.
You can do the following to accomplish this.
Assign a template reference to the button #button and pass it to the component method (click)="checkState(button)"
<mat-radio-button #button class="example-radio-button" *ngFor="let season of seasons" [value]="season" (click)="checkState(button)">
Create a local variable in the component to store the button value for comparison in checkState()
currentCheckedValue = null;
DI Renderer2 to remove focus from the button
constructor(private ren: Renderer2) { }
Wrap logic in setTimeout to put it on the digest cycle, check if local variable exist and if current value equals argument value... if true deselect, remove focus and null local variable... else set local variable for future comparison.
checkState(el) {
setTimeout(() => {
if (this.currentCheckedValue && this.currentCheckedValue === el.value) {
el.checked = false;
this.ren.removeClass(el['_elementRef'].nativeElement, 'cdk-focused');
this.ren.removeClass(el['_elementRef'].nativeElement, 'cdk-program-focused');
this.currentCheckedValue = null;
this.favoriteSeason = null;
} else {
this.currentCheckedValue = el.value
}
})
}
Stackblitz
https://stackblitz.com/edit/angular-c37tsw?embed=1&file=app/radio-ng-model-example.ts

I have simplified Marshal's code here
https://stackblitz.com/edit/angular-c37tsw-zho1oe
I removed setTimeout and Renderer2 import and it would seem to work even without these but with an event.preventDefault().

I'm not sure what answer you are looking for since the angular material radio buttons default behaviour is to only allow one selected item. (This is what i assume you are asking based off of your question)
Are you trying to create behaviour where the user can deselect all radio buttons?

I had the same problem as OP and I tried both the most popular and second most popular answers but neither of them worked for me. I'm using Angular 10 and this post is 4 years old so I hope this answer will help someone else who has my problem.
I noticed that the mat-radio-button was being assigned a class 'mat-radio-checked' when you checked it. The reason I believe that the above 2 answers no longer work is that the value of the button is set before you receive it in the ts file so no matter how you try to assign the _checked value to false it isn't going to work. But changing that class is doable. This method also allows you to deselect the button without having to keep track of any kind of global variable. Here's a generic example:
In the html assign each button a reference variable using the # and an on click event passing the event and button reference.
<mat-radio-group class="radio-group">
<mat-radio-button #option1 class="radio-item" value="New User" (click)="onRadioClick($event, option1)”>New User</mat-radio-button>
<mat-radio-button #option2 class="radio-item" value=“Existing User" (click)="onRadioClick($event, option2)”>Existing User</mat-radio-button>
</mat-radio-group>
Then in the onRadioClick function check to make sure that the button the user clicked has a class 'mat-radio-checked'; if it does then remove the check class and add our own flag marked-unchecked. This way if you uncheck an option then check it again we will know that it has been checked again and can go ahead and add the 'mat-radio-checked' class again.
onRadioClick(event: any, button: any): void {
let targetButton = event.target;
while (targetButton && targetButton.parentNode && targetButton.parentNode.classList) {
targetButton = targetButton.parentNode;
if (targetButton.classList.contains('mat-radio-checked') && !targetButton.classList.contains('marked-unchecked')) {
targetButton.classList.remove('mat-radio-checked');
targetButton.classList.add('marked-unchecked');
break;
}
if (targetButton.classList.contains('marked-unchecked')) {
targetButton.classList.remove('marked-unchecked');
targetButton.classList.add('mat-radio-checked');
}
}
}
For further explanation on this just inspect your mat-radio-button element in your browser and you'll be able to see the mat-radio-checked css class I was talking about and it should become apparent.

Related

Angular Material Checkbox doesn´t change state of checked

I´m working with a list of element and filtering the list using pipes, the filter is multi-selection to filter using more than one value, i save the filter in the localstorage to have persistent in the filter after close the window or reload the page, in the mat-checkbox component i use i function in the [checked]="existInArray(color.id, filterColor)" directive to check the checkbox if the value is already in the filter array to check the checkbox, but i have a problem, if the checkbox is checked using the function, the next time i click the checkbox to uncheck it, the checkbox doesnt change the state of checked true to false, only when i clicked a second time change to checked false
Template
<mat-checkbox *ngFor="let color of filterService.getFilter(filterType.FILTER_COLOR).items.ToArray() | filterQuery:filterOptions.color"
[checked]="existInArray(color.id, filterColor)" class="filter-checkbox" [value]="color.id" [hidden]="color.id === '999999'"
(click)="filterBy(filterType.FILTER_COLOR, color.id, filterColor)">
<div class="assigned">
<div class="assigned-avatar text-center" [ngStyle]="{ 'background-color': color?.color?.bgColor }"></div>
<p class="assigned-name">{{ color.name }}</p>
</div>
</mat-checkbox>
Filter.ts
public existInArray(element, array: Array<string>): boolean {
return array.indexOf(element) > -1;
}
public filterBy(filterType: FilterTypeEnum, element: any, array: Array<string>) {
this.toggleInArray(element, array);
this.updateFilterObservable(filterType);
}
Example, as you can see in the image, the checkbox is already checked by default because i use the existInArray function to check if the value of the check already exist in the filter array, if i try uncheck it, the first time doesn´t work, but when i click a second time the checkbox is unchecked, any idea what could be....?
I think the reason is because the [checked] is trigger before i toggle the element from the array, but no idea so far idea how to solved.... any idea.
This is a timing issue of your [checked]="existInArray(color.id)" being out of sync with your click event.... [checked]="existInArray(color.id)" happens before your click. Subscribe to the change event instead.
(change)="toggleInArray(color.id)"
Top_Select: any[] = []; // selection clear when selected... in your ts file
//on the check_click event firing add this make sure you get the index (index_chkbx) in the event
this.Top_Select[index_chkbx] = true;
in you html

select dropdown option based on dropdown option

To be honest, I have never touched Javascript before today. On basic search I have seen a few scripts use the change function but the samples seem very specific (using .indexOf and changing numbers/text boxes doesn't apply here).
removed
You can ignore the code that's there. essentially what I'm looking for is when 1 (disease) becomes yes, 6 option is changed to patient, and if 6 (poster_type) value = patient then 7 is selected as yes.
If someone could walk me through the change function that'd be fine too.
removed
Code and explanation below
So, the code says whenever disease dropdown is changed
if its selected value is "1"
change the poster_type dropdown to Patient.
change the patient_exp dropdown to "1"
else
change the poster_type dropdown to Unknown.
change the patient_exp dropdown to "0"
$("select[name='disease']").change(function(){
if($("select[name='disease']").val() == "1"){
$("select[name='poster_type']").val("Patient");
$("select[name='patient_exp']").val("1");
}
else
{
$("select[name='poster_type']").val("Unknown");
$("select[name='patient_exp']").val("0");
}
});
For change in value of poster_type dropdown,
if current selected value in poster_type is Patient
set value of patient_exp dropdown to "1"
else
set value of patient_exp dropdown to "0"
$("select[name='poster_type']").change(function(){
if($("select[name='poster_type']").val() == "Patient")
{
$("select[name='patient_exp']").val("1");
}
else
{
$("select[name='patient_exp']").val("0");
}
});
Basically you need to bind to the change event:
$('select[name=disease]').on('change', function(e){
// here the user have changed the value
});
Then you can get current value with val():
$('select[name=disease]').val();
// yes or no
Val is also the method you use to change an input value:
$('input[name=myInput]').val('newVal');
So you're looking for something like this:
$('select[name=disease]').on('change', function(e){
if($('select[name=disease]').val() === 'yes'){
$('input[name=myInput]').val('my-new-value');
}
});

Material Design Slide Toggle does not have event.StopPropagation, what should I use?

The Slide Toggle in Material Design does not have a stopPropagation event, because the "MdSlideToggle.prototype._onChangeEvent" already calls stopPropagation. What should I be using, instead?
<md-slide-toggle (change)="changeToggle($event, activityType.isActive)" checked="activityType.isActive" value="activityType.activityTypeId" mdTooltip="{{!!activityType.isActive ? 'Active' : 'Inactive'}}" mdTooltipPosition="left"></md-slide-toggle>
public changeToggle(event: MdSlideToggleChange, originalValue){
if (this.hasChange && event.checked !== originalValue){
event.stopPropagation();
//Results in error: [ts] Property 'stopPropagation' does not exist on type 'MdSlideToggleChange'.
} else {
this.hasChange = !this.hasChange;
}
}
I can use a regular event, but that gets an exception saying "event.stopPropagation is not a function".
For the moment, I'm changing that line to:
event.source.checked = !event.checked;
The same is true of event.preventDefault. I need to require the user to save the change, before changing another value on the page, because "business requirements".
Is just changing the value of "checked" back to what it was, the right thing to do? Is there a better way to do this?
"I need to require the user to save the change, before changing
another value on the page"
I know this is off topic, but this pertains to your "business requirements"
If you are saying that the user has to press a separate button in order to confirm the value of the mat-slide-toggle then you should not be using a mat-slide-toggle.
You should be using a checkbox.
mat-slide-toggles are good for 1-off actions, turning a light on or off, not asking if you want the light to be on or off.
Its an action, not a question.
Checkboxes are better suited for questions.

Need help with javascript regarding radiobuttons

I want to disable the radiobutton the second time it is clicked..I want to put some code in the head..that when a radiobutton is clicked the second time,, it isnt marked anymore..
I want to check and uncheck the radiobutton with each click.
Note: I generate 20 radiobuttons dynamically
Take into account that it is a Radiobutton that is run on the server:
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.radiobutton.aspx
UPDATE: This is the only event that the RadioButton (asp WebControl run at="server") has:
protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
{
var rad = (CheckBox)sender;
if (rad.Checked)
{
rad.Checked = false;
}
}
I can uncheck it after each post back..but unless a post back doesnt happen, i cant select and deselect it.. Thats the problem!! :(
I think you should keep with the standard use of RadioButtons, by saying this - use CheckBoxes instead, and clear all checkboxes if a different one is clicked...so when a checkbox is clicked the second time the standard uncheck will occur.
if i get you right then
all u need is a flag attribute of how many times u have clicked on the radio button and each time u click the radio the attribute increased by 1 and check the attribute every click if its 2nd time then disable the radiobutton
so you need to generate ur radiobuttons like this
<input type='radio' onclick='radioClick(this);' how_many_clicked='0' id='whatever id u need' name='whatever name u need' />
and create ur function in the head like the following
function radioClick(e) {
var flag = e.getAttribute('how_many_clicked');
var times = Number(flag);
times += 1;
e.setAttribute('how_many_clicked', times.toString())
if (times > 1) {
e.checked = false;
e.setAttribute('how_many_clicked', "0");
}
else {
e.checked = true;
}
}
Id create an empty array. For every radiobutton you create, add its ID to the array as the key and set its value to 0. This will be the count for the specific button. Whenever a radiobutton is clicked, check the buttons ID against the array, if its less than 2, increment it. If not, disable the current button.
EDIT : didn't realize you were checking if it was already checked, thoguht it was the number of times checked.
$("#id").is(":checked")
Should suffice
Another note ...if all you're doing is disabling an element from being accessed by the user, you should handle this event on the client side. You'll be using unnecessary server callback for functionality easily achievable via javascript. Use jquery click event handlers which can be generic enough for you not to have to use identifiers, making the job that much easier.
Cheers

Altering a page from a Greasemonkey script whenever a specific <option> is selected

While writing a GreaseMonkey script using jQuery and "tamtam", a question arose in my mind.
There is a page (which I can't edit) having a <select> element with four options. Option 2 is preselected.
<select id="idname" name="namename">
<option>Option1</option>
<option selected="selected">Option2</option>
<option>Option3</option>
<option>Option4</option>
</select>
Now I'd like to call the script when Option1 is selected. Option1 leads to another site I want to insert my script.
How would I write something like:
if (Option1 is selected) {
perform the script
}
Would something like the following work?
if(document.getElementById("idname").getElementsByTagName("option")[0].onselect == true){
perform the script
}
If not, can you post a reference helping me?
Edit
I was able to create a function and an event handler.
function myCompute(Event) {
with (this) {
var myTest = value;
if (value == "option1") {
$("#tabelle").show();
}
else {
$("#tabelle").hide();
}
}
}
Event handlers:
$("#option-type").change (myCompute);
$("#tabelle").hide();
It works as follows:
By choosing option 2,3 or 4 the table is hidden. By choosing option 1 the table is shown.
By visiting the site option 2 is selected most of the time and nothing is shown.
Now I got the case that option 1 is selected by visiting the site and no table appears, too. My idea was that the table should be shown when option1 is preselected.. I think that an EventHandler is missing.
Like you, Brock Adams, said.
$("#option-type option:first").select (myCompute);
$("#option-type").change (myCompute);
$("#tabelle").hide();
If I bind the function with $("#tabelle").hide();, the table is hidden from the very beginning. By changing the options to option1 the table is shown. How can I show the table when option 1 is selected and how can I hide the table when option 2,3,4 are selected?
Trying option:first results in an "unknown pseudo-element" error.
Update:
Ok, if I understand the revised question, the code now works as intended except when option 1 starts as selected. (PS, the id's of the given code should be edited to match up.)
If that's true, then just change this line:
$("#tabelle").hide();
.
To this:
if ($("#option-type")[0].selectedIndex == 0 )
$("#tabelle").show();
else
$("#tabelle").hide();
In Greasemonkey, you can't set event handlers that way due to sandbox protection. See Common Pitfalls in Greasemonkey.
Also, with jQuery, there are easier ways to select that element.
Something like: $("#idname option:first").select (YourEventHandler) should work.
Where:
function YourEventHandler (Event)
{
//YOUR CODE HERE
//Note: Event is a variable passed automatically to all event handlers, you often just ignore it.
}
Handy jQuery reference.
You can use the .selectedIndex property to get which one's selected, like this:
if(document.getElementById("idname").selectedIndex === 0) { //option 1
//perform the script
}
It's a 0-based index, so 0 is Option 1 in your example markup, you can test/play with it here.
I'm unclear from the question, but if you want this on the change event, it'd look like this:
document.getElementById("idname").onchange = function() {
if(this.selectedIndex === 0) {
//perform the script
}
};
You cant test it here.

Categories