for a bit of context I'm trying to make a component navigation menu for my react app. Essentially each dropdown value is equivalent to some components. The way I was going to do this is like follows:
Dropdown menu
<form>
<label htmlFor="#endpointSelect">Endpoint:</label><br/>
<select value={moduleValue} id="endpointSelect" onChange={() => activateModuleValue()}>
<option value="1"> Latest </option>
<option value="2"> Convert </option>
<option value="3"> Historical </option>
<option value="4"> Time Series </option>
<option value="5"> Fluctuation </option>
<option value="6"> Carat </option>
<option value="7"> Lowest-Highest </option>
</select>
</form>
And this is the activateModuleValue()
const [module, setModule] = useState();
// set the module value
const activateModuleValue = () => {
console.log(moduleValue);
}
Eventually there will be a method with a bunch of if statements indicating 1 = <Latest/>, 2 = <Convert/>, etc.
What I was having issues with is correctly grabbing the option values. Using onChange in general I've noticed it returns the value FROM the element I'm changing from instead of changing TO.
Another approach that I'm currently trying is using the value={moduleValue}. Essentially on dropdown select the moduleValue state should change, and ideally I'd have something along the lines of:
useEffect(() => {
activateModule();
}, [moduleValue]);
Where the intent would be to call on the "setActiveComponenet" method whenever the state for moduleValue changes
As an answer to my own question, you have to first set the state and then separately associate state with a component:
// set the module value
const activateModuleValue = (e) => {
setModuleValue(e)
}
// set the module
const activateModule = () => {
if(moduleValue == 1){
setModule(<Latest/>)
}
Related
I want to filter a list of movies based on their categories by selecting them using a select menu (select tag), I could do it with a button using on click event it works, but when I want to replace it buy multi-select by changing the event to onChange the filter didn't work.
what do you think?
Thank you
//filter movies based on their categories, this function is created in App.js, it has been passed as props to my CategoriesFilter components
const filterMovie = (category) => {
const filterMovie = MoviesData.filter((movie)=> movie.category === category);
setMoviesList(filterMovie);
}
// this my components
const CategoriesFilter = ({categories, filterMovie}) => {
return (
<div>
<select >
{categories.map((category, index)=> {
return (
<option key={index} onChange={()=> filterMovie(category)}>{category}</option>
)
})}
</select>
</div>
)
}
There are a few options.
You can probably build a custom multi select dropdown component with checkboxes for each item.
You can use third party npm packages like react-select. https://www.npmjs.com/package/react-select
I would suggest you to use the react-select.
You can also use select tag with multiple attribute. But it won't work the way you want it to.
<select name="cars" id="cars" multiple>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
To select multiple items, you'll have ctrl + click the items
Multiple select is <select multiple/>
onchange event is not associated with each option, it is an event of select element.
In React JSX, I wrote below component:
<select //...
onChange={event => {alert(event.target); //setState}}
>
<option id=1>one</option>
<option id=2>two</option>
</select>
The alert gives me select element. How can I access selected option without jQuery? I am trying to setState on the id, and do corresponding searches and other things.
Instead of an id on select option, provide the value attribute you can then access it as event.target.value.
<select
onChange={event => {
alert(event.target.value);
}
}>
<option value="1"> one</option>
<option value="2"> two</option>
</select>
CodeSandbox
You wouldn’t typically access the value directly through the event target. Either bind the control value to component state or store a reference on the parent component... then you can access the value when the event is fired.
See: https://stackoverflow.com/a/47842562/1306026
You can access selected option like:
var elm = event.target;
console.log(elm.options[elm.selectedIndex]);
and then access its value or text like:
console.log(elm.options[elm.selectedIndex].value)
DEMO (change the option to see result):
function setState() {
var elm = event.target;
console.log(elm.options[elm.selectedIndex]);
console.log(elm.options[elm.selectedIndex].value);
}
<select onChange="setState()">
<option id=1>one</option>
<option id=2>two</option>
</select>
i want to create 2 select option which the content of the other one selected option based to previous option. here is my html
<div class="col-sm-2">
<select class="form-control" ng-model="y">
<option value="1">a</option>
<option value="2">b</option>
</select>
</div>
<div class="col-sm-2">
<select class="form-control" ng-model="z">
<option ng-repeat = "x in list" value="{{x.idproduct}}">{{x.descproduct}}</option>
</select>
</div>
but there is error, the other select option wont showing the option like in this picture
here is my js file
if ($scope.y === 1) {
$scope.list = [
{idproduct:"13", descproduct:"cc"},
{idproduct:"14", descproduct:"dd"}
];
}
if ($scope.y === 2) {
$scope.list = [
{idproduct:"15", descproduct:"ee"}
];
}
You need to bind the change event so that your list gets updated at the time that your value is updated. Plus your === can cause an issue. With === your string value is being compared to integers 1 and 2.
Here is a plunker: ng-change for change in dropdown
<select class="form-control" ng-model="y" ng-change="updateList()">
<option value="1">a</option>
<option value="2">b</option>
</select>
$scope.updateList()={
if ($scope.y == 1) {
$scope.list = [
{idproduct:"13", descproduct:"cc"},
{idproduct:"14", descproduct:"dd"}
];
}
if ($scope.y == 2) {
$scope.list = [
{idproduct:"15", descproduct:"ee"}
];
}
}
The value of your option is String value="2"
And you're comparing it to an Integer if ($scope.y === 2)
You should compare it like if ($scope.y === '2') or if (parseInt($scope.y) === 2)
Create a function and put your Js code in that function and call function on ng-change of the first dropdown. Here you if condition executes once during app initialization. So by triggering ng-change we can call function and update the lists based on the selection.
This is using react. The problem in a nutshell is that I have two select menus in a form (as part of the same component) and I want selecting one to set the options of the other.
One select shows months and one shows days in that selected month. Depending on which month is selected the days should show the correct number for that month (so 31 days in the days select if "January" is selected in month, 28 if "February" and so on).
I cannot get the initial value to change in response to the select. I can log the correct value but what actually appears in the days select never updates from its initial state.
Some code...
I trigger with:
<select defaultValue="Jan" onChange={() => { setMonthNumber(this.refs["month"]["value"]) }} ref="month">
setMonthNumber is an action:
export const setMonthNumber = (monthNumber) => {
store.dispatch({type:'GUEST_INFORMATION_SET_MONTH', message:monthNumber});
}
The reducer that handles that action is:
const initialState = {
currentMonth: "Jan"
};
const guestInformationEditReducer = (state = initialState, action) => {
let localState = merge({}, state);
switch (action.type) {
case 'GUEST_INFORMATION_SET_MONTH':
localState.currentMonth= action.message;
return localState;
}
return state
};
export default guestInformationEditReducer;
I aggregate my reducers and in that file I set (leaving out other reducers):
export default {
guestInformationEditComponent: guestInformationEditReducer
}
and then in my component (named GuestInformationEdit) I connect things with:
const getGuestInformationComponentProps = state => {
return {
month: state.guestInformationEditComponent.currentMonth
}
}
export default connect(getGuestInformationComponentProps)(GuestInformationEdit);
In my component's render method I access the value with:
const days = this.getDaysFromMonth(this.props.month);
getDaysFromMonth is simply a switch that builds a collection of jsx options like:
days.push(<option key={stringNum} value={stringNum}>{stringNum}</option>);
so that I end up with an array of options with the correct values depending on the selected month. This all works (logging shows the correct values). My problem... when I add {days} to my jsx like so:
<select defaultValue="1">
{days}
</select>
I only ever get 31 days, the value set by the initialState in the reducer. It never changes in the view in spite of changing in any console logs I may try. Why? What am I doing wrong/missing? Also, is all of this really necessary for such a change? It seems wickedly complex for such a simple thing.
**edit
In my component I have this outputting the selects:
<BootstrapFormGroup model="guestModel.BirthMonth" classes="col-xs-12 col-md-1 extra-four-percent" formLabel="Birth Month">
<select defaultValue="Jan" onChange={() => { setMonthNumber(this.refs["month"]["value"]) }} ref="month" className="form-control">
<option value="Jan">Jan</option>
<option value="Feb">Feb</option>
<option value="March">March</option>
<option value="April">April</option>
<option value="May">May</option>
<option value="June">June</option>
<option value="July">July</option>
<option value="Aug">Aug</option>
<option value="Sept">Sept</option>
<option value="Oct">Oct</option>
<option value="Nov">Nov</option>
<option value="Dec">Dec</option>
</select>
</BootstrapFormGroup>
{days}
<BootstrapFormGroup model="guestModel.BirthDay" classes="col-xs-12 col-md-1 extra-four-percent" formLabel="Birth Day">
<select defaultValue="1" className="form-control">
{days}
</select>
</BootstrapFormGroup>
See those two instances of {days}? With my above code the first one updates correctly in response to onChange of the month select, the second one does nothing except display the initial state and then never update.
I'm trying to make it so when a select box within a div changes, it will grab values from both that select box and one other one that I've yet to add, but I don't know how to go about it.
I currently have this code
<select id='selMag' onchange='getSelMag(this)'>
<option value='0.0>Select Minimum Magnitude</option>
<option value='1.0'>1.0</option>
<option value='2.0'>2.0</option>
<option value='3.0'>3.0</option>
<option value='4.0'>4.0</option>
<option value='5.0'>5.0</option>
<option value='6.0'>6.0</option>
<option value='7.0'>7.0</option>
<option value='8.0'>8.0</option>
<option value='9.0'>9.0</option>
<option value='10.0'>10.0</option>
</select>
function getSelMag(sel) {
value = Number(sel.value);
console.log(window.value);
}
This, as it is right now, works fine from grabbing it from the , but I would like to add another one and put them inside a container div, and make it so when either one changes it will grab the values from both of them, add both strings together, and convert them into a number. I plan to make it so the select box above will not have the decimal values and just be 1, 2, etc. and have the second box be .1, .2, etc. so when they are added together, it will show 1.1, 1.2, etc.
Presumably, the select is in a form. To be successful, form controls must have a name, so:
<select id='selMag' name='selMag' onchange='getSelMag(this)'>
Adding a name nearly always obviates the requirement for an ID. If the other select also has a name:
<select name='selMag2'>
and it belongs to the same form as the first, you can reference it from the getSelMag function via the form:
function getSelMag(sel) {
// Always declare variables
var value = Number(sel.value);
// Access them from the appropriate scope
console.log(value);
// Reference the other select using named properties of the form
var otherSelect = sel.form.selMag2;
// Do stuff with it
var otherValue = otherSelect.value;
}
Note that all form controls have a form property that references their parent form, and that the controls belonging to a form can be accessed via the form's elements collection.
Those with names (and in some browsers those with IDs) can be accessed as named properties of the form and of the elements collection, and also by index in the collection.
It seems that you want to concatenate the values with a period between, so the function might look like:
function getSelMag(sel) {
var value0 = sel.form.selMag.value;
var value1 = sel.form.selMag2.value;
console.log(value0 + '.' + value1);
}
and the HTML:
<form>
<select name="selMag" onchange="getSelMag(this);">
<option value="0" selected>0
<option value="1">1
<option value="2">2
</select>
<select name="selMag2" onchange="getSelMag(this);">
<option value="0" selected>0
<option value="1">1
<option value="2">2
</select>
</form>
Use the answer from this link to get the value of other select box in getSelMag() function
Get selected value in dropdown list using JavaScript?
as follows:
function getSelMag(sel) {
value = Number(sel.value);
console.log(window.value);
var e = document.getElementById("selMag2");
var option2 = e.options[e.selectedIndex].text;
//do whatever u want
}
You can make another function say x() that will be called for other select box you make and access the value of first select box from that
<select id='selMag2' onchange='x(this)'>
as
function getSelMag2(sel) {
value = Number(sel.value);
console.log(window.value);
var e = document.getElementById("selMag");
var option1 = e.options[e.selectedIndex].text;
//do whatever u want
}
Hope this helps