I’m using ember-bootstrap 5.1.1 to construct a form. I am using the radio form.element and a checkbox form.element. The checkbox items depends on what was selected in radio form.element (basically similar to a filtered or cascading select). When an option is selected in the radio control, I want to call an event handler that filters the items displayed in the checkboxes.
I have some code that invokes the event handler as expected, the parameter passed to the event handler (an Event object) doesn’t contain the value of the selected radio button. How can i get the value of the selected radio button when the ‘change’ event handler is called?
Here’s a simplified version of the ember-bootstrap form template:
I would recommend using another pattern. Your pattern has the disadvantage of needing to manually synchronize the state of selected item in the radio form element and the items disabled in the checkboxes. Trying to manual synchronize those states is adding technical complexity, which is not needed. Instead you could derive the items, which should be disabled in the checkboxes based on the selected element in the radio form element.
That example is not production ready yet. E.g. it is missing needed reset of selectedTerroritory when selectedLanguage changes. But I hope it’s enough to demonstrate the concept.
Thank you for your suggestion. I appreciate opportunities to learn different ways of doing things. To help me be more certain about what you mean, what is the technical complexity that your approach eliminates and how does it eliminate it? I’ve included the final-ish code we’ve settled on for this form. Can you point to which lines/approaches you’d change? Thank you.
export default class ItemsCreateController extends Controller {
@tracked selectedCategory = '';
@tracked selectedKeywords = [];
@service store;
//Event handler when a new category is selected
@action
onRadioButtonChange(event) {
// clear the selected keywords list
this.selectedKeywords = [];
//because selectedCategory is tracked, changes to that
// field cause the 'keywordsForCategory' getter to be called as well
this.selectedCategory = event.target.parentNode.innerText;
}
//returns an array of keywords that are specific to the selectedCategory.
get keywordsForCategory() {
if (this.selectedCategory === '') return;
const cat = this.store
.peekAll('category')
.findBy('name', this.selectedCategory);
const keysOfCategory = [];
cat.keywords.map((keyword) => {
keysOfCategory.push(keyword);
});
return keysOfCategory.sort(function (a, b) {
const textA = a.value.toUpperCase();
const textB = b.value.toUpperCase();
return textA < textB ? -1 : textA > textB ? 1 : 0;
});
}
}
<BsForm @formLayout="vertical" @model={{this}} as |form|>
<form.element @controlType="radio" @label="Category" @property="radio" @options={{@model}} @optionLabelPath="name"
{{on "change" this.onRadioButtonChange}} />
<div class="d-flex flex-column mb-3">
{{#unless this.selectedCategory}}
<span class="placeholder-tag-content">Select a category to see available tags.</span>
{{/unless}}
{{#each this.keywordsForCategory as |keyword index|}}
<label class="tag-checkbox-container d-flex align-items">
<div class="order-2">{{keyword.value}}</div>
<Input id="test-checkbox-{{index}}" @type="checkbox" {{on "input" (fn this.onCheckedkeyword)}} />
<div class="checkmark order-1"></div>
</label>
{{/each}}
</div>
</BsForm>