In my project i have a couple of radio button groups where they have some extra information attached to them as you can see here:
<div>
<div class="option">
<input type="radio" name="Letters" value="a" />
<a>Letter A</a>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
<div class="option">
<input type="radio" name="Letters" value="b" />
<a>B</a>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
<div class="option">
<input type="radio" name="Letters" value="c" />
<a>C</a>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
<div class="option">
<input type="radio" name="Letters" value="d" />
<a>D</a>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
</div>
It works if i click on the radio button dot, but I want to be able to click on the parent div and change the value. I read that this can be done via @onchanged
on the parent div, but I've only encountered JS snippets of how to do it.
How would I do this?
You could use <label>
elements instead of <div>
elements to propagate the click event to the inputs. No code required!
<label class="option">
<input type="radio" name="Letters" value="c" />
<a>C</a>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</label>
From the docs:
Alternatively, you can nest the
<input>
directly inside the<label>
, in which case the for and id attributes are not needed because the association is implicit:
https://blazorfiddle.com/s/sr414t1n
Note: I have added a little bit of CSS to the .option
class to render labels as block elements. The hover styling is just to show when the click will have an effect on the <label>
elements.
.option {
display: block;
}
.option:hover {
background-color: #ccc;
cursor: pointer;
}
Note: strictly speaking, placing block elements inside inline elements is not allowed/recommended. Your dev pipeline / coding standards may or may not allow you to place a <p>
inside a <label>
.
To style the outer label you could bind to a property that stores the selected option and then set a class based on that.
I have created a new demo showing this: https://blazorfiddle.com/s/56k8tfav.
I have created a RadioOption
class to represent each radio option. I am then setting the selected option in the local Selected
property in the @onchange
event handler. This can be used for setting the selected
CSS class on the relevant option.
This is just a pretty quick mockup to demonstrate one approach - you can choose to implement in whatever way you prefer.
@foreach (var option in Options)
{
<label class="option @(Selected == option ? "selected" : null)">
<input type="radio" name="Letters" value="@option.Value"
@onchange="@(() => Selected = option)" />
<a>@option.Label</a>
<p>@option.Text</p>
</label>
}
(Edit: the CSS solution posted on your other question uses the :has
CSS selector and is a cleaner implementation from a pure CSS point of view. You still might want to use my technique for cleaning your markup).