Reset other selects based upon on one select (ReactJS) - javascript

The goal here is to make it to where everytime a parent select changes it's value, all children selects get their value reset to default(1st value of empty string).
import React, {Component} from 'react';
class TestingSelects extends Component {
constructor(props) {
super(props);
this.state = {
selectOneValue: "",
selectTwoValue: "",
selectThreeValue: "",
selectFourValue: ""
}
}
selectOneOnChangeHandler = (ev) => {
this.setState({
selectOneValue: ev.target.value,
selectTwoValue: "",
selectThreeValue: "",
selectFourValue: ""
});
}
selectTwoOnChangeHandler = (ev) => {
this.setState({
...this.state,
selectTwoValue: ev.target.value,
selectThreeValue: "",
selectFourValue: ""
});
}
selectThreeOnChangeHandler = (ev) => {
this.setState({
...this.state,
selectThreeValue: ev.target.value,
selectFourValue: ""
});
}
selectFourChangeHandler = (ev) => {
this.setState({...this.state, selectFourValue: ev.target.value});
}
render(){
return (
<div>
<form>
<div>
<select onChange={ev => this.selectOneOnChangeHandler(ev)}>
<option value="">Please Select an Option</option>
<option value="select1option1">select 1 option 1</option>
<option value="select1option2">select 1 option 2</option>
</select>
</div>
{
this.state.selectOneValue === "select1option1" &&
<div>
<select onChange={ev => this.selectTwoOnChangeHandler(ev)}>
<option value="">Please Select an Option</option>
<option value="select2option1">select 2 option 1</option>
<option value="select2option2">select 2 option 2</option>
<option value="select2option3">select 2 option 3</option>
<option value="select2option4">select 2 option 4</option>
<option value="select2option5">select 2 option 5</option>
<option value="select2option6">select 2 option 6</option>
<option value="select2option7">select 2 option 7</option>
</select>
</div>
}
{
(this.state.selectTwoValue === "select2option1" ||
this.state.selectTwoValue === "select2option2" ||
this.state.selectTwoValue === "select2option5" ||
this.state.selectTwoValue === "select2option7") &&
<div>
<select onChange={ev => this.selectThreeOnChangeHandler(ev)}>
<option value="">Please Select an Option</option>
<option value="select3option1">select 3 option 1</option>
<option value="select3option2same">select 3 option 2</option>
<option value="select3option2same">select 3 option 3</option>
</select>
</div>
}
{
this.state.selectThreeValue === "select3option2same" &&
<div>
<select onChange={ev => this.selectFourOnChangeHandler(ev)}>
<option value="">Please Select an Option</option>
<option value="allowed">Yes</option>
<option value="denied">No</option>
</select>
</div>
}
</form>
</div>
)
}
}
export default TestingSelects;
Edit: How to reproduce issue...
[First Select]: select 1 option 1
[Second Select]: select 2 option 1
[Third Select]: select 3 option 1
[Second Select]: select 2 option 2
Here is where the 3rd select should reset to "Please Select an Option"
Does anyone know how to do this?

Everything should work as long as you bind the state to the value props of each <select> element. The reason why your code doesn't work is because you are not binding the value of each select to the component's state.
For instance, this is what you should be doing:
<select onChange={ev => this.selectOneOnChangeHandler(ev)} value={this.state.selectOneValue}>

Related

How to allow the selection ONLY one option for certain values in a multiple selection dropdown list?

I want to make a dropdown menu with the following options. I want be able to select a select multiple value for option A, B, and C, but disable multiple selection if option D is selected. How can I do that? Thanks.
<label>Choose an option:</label>
<select required multiple>
<option>Please select</option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">C</option>
</select>
Remove the other selected options if "D" is selected, otherwise allow multiple select (do nothing).
document.addEventListener("mouseup", checkMultiple);
function checkMultiple(evt) {
const selectr = evt.target.closest(`select`);
if (selectr && selectr.querySelector(`[value='D']:checked`)) {
[...selectr.options].forEach(v => v.selected = v.value === `D`);
}
}
/*
Note: the above is a shortened version of
the function in the original answer:
function checkMultiple(evt) {
if (!/option/i.test(evt.target.nodeName)) {
return true;
}
const selector = evt.target.parentNode;
const options = [...selector.querySelectorAll("option")];
if (options.find(v => v.value === "D").selected) {
options
.filter(v => v.value !== "D")
.forEach(v => v.selected = false);
}
}
*/
<label>Choose an option:</label>
<select required multiple>
<option>Please select</option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
</select>
let arr = [];
document.querySelector('#product_attr_ids').onchange = function(e) {
if (this.querySelectorAll('option:checked').length <= 1) {
arr = Array.apply(null, this.querySelectorAll('option:checked'));
} else {
Array.apply(null, this.querySelectorAll('option')).forEach(function(e) {
e.selected = arr.indexOf(e) > -1;
});
}
}
<p>The html of selections with multiple set to true.</p>
<p>Pressing command + click will not allow you to choose more than one option</p>
<p>Javascript. You can chnage the <strong>('option:checked').length <= 1) </strong> to whatever number you want, peraps you want your users to choose only 2 or 3 options.</p>
<label>Choose an option:</label>
<br />
<select id="product_attr_ids" required multiple>
<!-- Prevent user from select first blank option -->
<option disabled>Please select</option>
<option value="A">Attribute 1</option>
<option value="B">Attribute 2</option>
<option value="C">Attribute 3</option>
<option value="D">Attribute 4</option>
</select>

Remove first element, when multiple clicks on selectbox

when user chooses an option in selectbox a new box is triggered.
But supposed user changes his opinion and choose a new option, the former selectbox does not vanish.
How can I make the “wrong” selectbox – first choice – vanish.
I have a working example at codepen to illustrate the issue.
When user makes a decision with “Choose Option” he calls the hotelchecker function, so that a second selectbox appears “Option based on previous choice”. When he than reconsider his choice and choose again from “Choose option” - how can I prevent, that I have multiple second selectboxes?
Here is my HTML:
<div id="selectbox">
<select class="selectstyled" id="change">
<option value="0">Choose Option</option>
<option value="1">Option1</option>
<option value="2">Option2</option>
</select>
</div>
Here my JS:
[let changeUse = document.getElementById("change");
changeUse.addEventListener("change", hotelchecker);
function hotelchecker() {
if (changeUse.value == 1) {
document.getElementById("selectbox").insertAdjacentHTML("afterend", `
<div id = "selectbox">
<select class = "selectstyled"
id = "changeHotel">
<option value="0">Option based on previuos choice</option>
<option value="1">Further choice 1</option>
<option value="2">Further choice 2</option>
<option value="3">Further choice 3</option>
</select>
</div>
`)
}
if (changeUse.value == 2) {
document.getElementById("selectbox").insertAdjacentHTML("afterend", `
<div id = "selectbox">
<select class = "selectstyled"
id = "changeHotel">
<option value="0">Option based on previuos choice</option>
<option value="1">Further choice 1</option>
<option value="2">Further choice 2</option>
<option value="3">Further choice 3</option>
</select>
</div>
`)
}
};][1]
I thought about running a querySelectorAll "changeHotel" and if it is >0 to remove existing element but I always get "undefined".
You need to add selectbox with unique id.
then on change event clear your selectedbox element.
try below solution.
let changeUse = document.getElementById("change");
changeUse.addEventListener("change", hotelchecker);
function hotelchecker() {
var element = document.getElementById('selectbox1');
if (typeof(element) != 'undefined' && element != null)
{
element.parentNode.removeChild(element);
}
var element2 = document.getElementById('selectbox2');
if (typeof(element2) != 'undefined' && element2 != null)
{
element2.parentNode.removeChild(element2);
}
if (changeUse.value == 1) {
document.getElementById("selectbox").insertAdjacentHTML("afterend", `
<div id = "selectbox1">
<select class = "selectstyled"
id = "changeHotel">
<option value="0">Option based on previuos choice</option>
<option value="1">Further choice 1</option>
<option value="2">Further choice 2</option>
<option value="3">Further choice 3</option>
</select>
</div>
`)
}
if (changeUse.value == 2) {
document.getElementById("selectbox").insertAdjacentHTML("afterend", `
<div id = "selectbox2">
<select class = "selectstyled"
id = "changeHotel">
<option value="0">¿En qué Hotel?</option>
<option value="4">Hotel 1 auf Granni</option>
<option value="5">Hotel 2 auf Granni</option>
<option value="6">Hotel 3 auf Granni</option>
</select>
</div>
`)
}
};
<div id="selectbox">
<select class="selectstyled" id="change">
<option value="0">Choose Option</option>
<option value="1">Option1</option>
<option value="2">Option2</option>
</select>
</div>
Too much hardcoding, I would suggest to do it in beautiful way, create element for second option
<div id="selectbox">
<select class="selectstyled" id="change">
<option value="0">Choose Option</option>
<option value="1">Option1</option>
<option value="2">Option2</option>
</select>
<select class="selectstyled" id = "secondSelection"></select>
</div>
and script is
let changeUse = document.getElementById("change");
changeUse.addEventListener("change", hotelchecker);
const optionsSets = {
0: [],
1: [
{ value: '0', text: 'Option based on previuos choice'},
{ value: '1', text: 'Further choice 1'},
{ value: '2', text: 'Further choice 2'},
],
2: [
{ value: '0', text: '¿En qué Hotel?'},
{ value: '4', text: 'Hotel 1 auf Granni'},
{ value: '5', text: 'Hotel 2 auf Granni'},
],
}
function hotelchecker() {
const secondSelection = document.getElementById("secondSelection")
secondSelection.innerHTML =
optionsSets[changeUse.value].map(({ value, text }) =>
`<option value="${value}">${text}</option>`
).join('')
secondSelection.style.display = +changeUse.value ? 'block' : 'none'
}
hotelchecker()

One dropdown field leading to updated values for another dropdown field

I have two drop downs, when dropdown-1 is changed, selected option of dropdown-2 should be changed to the same as dropdown-1
Dropdown-1:
<div className="select-style-right joiner-select">
<select className="selectalljoiners" onChange={this.handleMainSelectChanged} value={this.state.selectedJoinerValue}>
<option value="">Select</option>
<option value="Permanent">Permanent</option>
<option value="Probationary">Probationary</option>
<option value="Contractual">Contractual</option>
<option value="Intern">Intern</option>
</select>
</div>
Dropdown-2:
<div className="select-style-right joiner-select">
<select className={index} value={this.state.selectedJoinerValue}>
<option value="">Select</option>
<option value="Permanent">Permanent</option>
<option value="Probationary">Probationary</option>
<option value="Contractual">Contractual</option>
<option value="Intern">Intern</option>
</select>
</div>
handleMainSelectChanged:
handleMainSelectChanged = (e) => {
thisclass.setState({
selectedJoinerValue: e.target.value
})
}
New to React, don't know how to achieve this. Please help out.
If one of dropdowns changed the second one will take same selected option.
https://jsfiddle.net/b1atetou/
class Example extends React.Component {
constructor() {
super();
this.state = { value: "" }
}
handleDropDownChage = (event) => {
this.setState({value: event.target.value});
}
render() {
return (
<div>
<div>
<select onChange={this.handleDropDownChage} value={this.state.value}>
<option value="">Select</option>
<option value="Permanent">Permanent</option>
<option value="Probationary">Probationary</option>
<option value="Contractual">Contractual</option>
<option value="Intern">Intern</option>
</select>
</div>
<div>
<select onChange={this.handleDropDownChage} value={this.state.value}>
<option value="">Select</option>
<option value="Permanent">Permanent</option>
<option value="Probationary">Probationary</option>
<option value="Contractual">Contractual</option>
<option value="Intern">Intern</option>
</select>
</div>
</div>
);
}
}

setState when changing value on a <select>

I have two <select> inputs. I want to set the attribute as "disable" one of them at a specific value option from the other <select>.
The first one is:
<select ref="selectOption">
<option selected value="1" >Option 1</option>
<option value="2" >Option 2</option>
</select>
<select ref="selectTime" disabled={this.state.disabled}>
<option value="a" >January</option>
<option value="b" >Febreaury</option>
</select>
So, my idea is to set the state of the 2nd <select> as false when the option value = 2 from the first <select>
How can I do it? Or is there another way without react that I can do it? or with props? I'm pretty confused. I tried to do something like:
var option= ReactDom.findDOMNode(this.refs.selectOption).value;
if( option == '2' ) this.setState({disabled:true});
But it's not working. Tried to put it in componentDidUpdate but the component is not updating when I select a new value from the select, so that won't work. Ideas please.
EDIT:
I also have this solution with jquery but I want to use Reactjs.
$('#selectOption').change(function() {
$('#selectTime').prop('disabled', false);
if ($(this).val() == '2') {
$('#selectTime').prop('disabled', true);
}
})
I'm pretty confused on how to use ReactDom.findDOMNode(this.refs.selectOption) instead the jquery selectors
Here is a minimal example of how you could accomplish this, add an onChange event handler to your first select, setState in the event handler based on the value:
handleChange(event) {
let value = event.target.value;
this.setState({
disabled: value == '2'
});
}
render() {
return (
<div>
<select ref="selectOption" onChange={(e) => this.handleChange(e)}>
<option selected value="1" >Option 1</option>
<option value="2" >Option 2</option>
</select>
<select ref="selectTime" disabled={this.state.disabled}>
<option value="a" >January</option>
<option value="b" >Febreaury</option>
</select>
</div>
)
}
That would be the react way to achieve this:
export default class Test extends Component{
constructor(props) {
super(props)
this.state = {
selectOptionValue: '1'
}
}
handleOnChange = (e) => {
this.setState({
selectOptionValue: e.target.value
})
}
render(){
return (
<div>
<select defaultValue = "1" onChange={this.handleOnChange}>
<option value="1" >Option 1</option>
<option value="2" >Option 2</option>
</select>
<select disabled={ this.state.selectOptionValue === '2' }>
<option value="a" >January</option>
<option value="b" >Febreaury</option>
</select>
</div>
)
}
}
How about onChange event from this ? For your convenience:
class FlavorForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: 'coconut'};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('Your favorite flavor is: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Pick your favorite La Croix flavor:
<select value={this.state.value} onChange={this.handleChange}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
If you want to keep it simple and use pure javascript, you could just use the following snippet.
document.querySelector('select[ref="selectOption"]').addEventListener('change', function(e) {
document.querySelector('select[ref="selectTime"]').disabled = (e.target.value === '2') ? true : false;
})
<select ref="selectOption">
<option selected value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
<select ref="selectTime">
<option value="a">January</option>
<option value="b">Febreaury</option>
</select>
Here's another approach to define which state variable needs to be set.
state = { someStateVariable : "" }
render() {
return (
<select onChange={event => this._setSelected({ someStateVariable: event.target.value })}>
<option value="1">One</option>
...
</select>
);
}
_setSelected = newState => {
this.setState(newState)
}
Step 1 - Create state and set initial value an empty string
const [category,setCategory] = useState('');
Step 2 Map youre options and check id in the option value === select value then set selected to true
const renderedResults = results.map((result) => {
const selected = category === result.id ? "true" : '';
return (
<option selected={selected} key={result._id} value={result._id}>{result?.name}</option>
);
});
Step 3
<select
onChange={(e) => {
setCategory(e.target.value);
}}
className="form-select"
aria-label={"Default select example"}
>
<option value="">Select a category</option>
{renderedResults}
</select>

Multiple select elements - Handle with jQuery when select an option from all of them

I have two select elements with some options. What I want to do is to handle this with jquery so as I can get the values of them only when options have values.
<div class="panel-heading">
<select id="loading-by-tag">
<option value="" disabled selected> -- Select Subject --</option>
<option value="value1">Selection 1</option>
<option value="value2">Selection 2</option>
</select>
<select id="loading-by-sub-tag">
<option value="" disabled selected> -- Select Subject --</option>
<option value="value1">Selection 1</option>
<option value="value2">Selection 2</option>
</select>
</div>
If I want to handle with one select element only I use .on('change', function() with select element and it works, but with multiple select element how can I do it.
You should check if selectedIndex is not 0 for all your select elements.
$(document).on('change', 'select', function () {
var allChanged = true;
// check if there is any other select element which was not changed
$('select').each(function () {
if (this.selectedIndex == 0) {
allChanged = false;
}
});
// if all select elements have been changed
if (allChanged) {
alert('BOTH CHANGED');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="panel-heading">
<select id="loading-by-tag">
<option value="" disabled selected> -- Select Subject --</option>
<option value="value1">Selection 1</option>
<option value="value2">Selection 2</option>
</select>
<select id="loading-by-sub-tag">
<option value="" disabled selected> -- Select Subject --</option>
<option value="value1">Selection 1</option>
<option value="value2">Selection 2</option>
</select>
</div>
Just a side note, use .filter() :
$('select').change(function() {
var m = $(this).siblings('select').addBack();
var n = m.filter(function(){
return $(this).val() == null && $(this)
});
if ( !n.length ) alert('both selected')
});
DEMO

Categories

Resources