onChange not rendering in React - javascript

We are working on a project where we are using boxes, and need one of the select boxes to perform an action when the user selects an item from the list. This is our first time touching React, let alone building a project, so we are stumped at this point. What we are using for the onChange code is as follows:
var React = require('react');
var ReactPropTypes = React.PropTypes;
var ProgramSelectorComponent = React.createClass({
propTypes: {
allPrograms: ReactPropTypes.array.isRequired
},
_updateProgram: function(e) {
this.setState({
value: "TEST"
});
},
render() {
var Programs = this.props.allPrograms;
var options = Programs.map(function (prog) {
return <option key={ prog.program_id } value={ prog.program_id } >
{ prog.program_name }
</option>;
});
return (
<select className="form-control margin-bottom" name="Program" id="programSelect" ref="progRef" onChange={this._updateProgram} >
<option value="select">Select</option>
{options}
</select>
)
}
});
module.exports = ProgramSelectorComponent;
I know that rendering does work in the <select> tag as I can add something like data-test-id="test" and that renders properly, but for some reason, the onChange is not showing in the code, and therefore, not working.
Like I said, we are all new to this, so any help would be greatly appreciated.

In your select tag try: <select value={this.state.value}>
This is a good read about controlled vs uncontrolled components: https://facebook.github.io/react/docs/forms.html

Related

Keeping selected language in dropdown after page reload using cookies

The problem is:
There is a landing page, a language switch added with ant design, specifically, through Select / Option. The translation was done via i18react lib.
So, it is necessary that when the page is reloaded, the selected language is displayed in the dropdown itself, and not reset to the default Language.
I know what can be done through document.cookie. But how? Well, I'll put languages ​​in cookies. And then, how to screw them into this Select so that the display of the selected language is saved on reboot?
My code is here and I don't know what to do.
const Option = Select.Option;
function ChangeLanguageDropdown({}) {
const {i18n} = useTranslation();
const changeLanguage = (lang) => {
i18n.changeLanguage(lang);
};
Cookies.set('ru', 'Русский', { expires: 7 });
Cookies.set('en', 'English', { expires: 7 });
return (
<div>
<Select defaultValue={"Language"} style={{ width: 110}} onChange={changeLanguage}>
<Option value="ru">{i18next.t("Русский")}</Option>
<Option value="en">{i18next.t("English")}</Option>
</Select>
</div>
const {useState} = React
const { Select } = antd
const { Option } = Select;
const ChangeLanguageDropdown = ({}) => {
const [lang, setLang] = useState('en' /* Cookie.get('path.to.cookie') */);
const changeLanguage = (lang) => {
setLang(lang);
/* Cookie.set('path.to.cookie', lang); */
/* call i18n.changeLanguage(lang); */
};
return (
<div><div>{lang}</div>
<Select defaultValue={lang} style={{ width: 500}} onChange={changeLanguage}>
<Option value="ru">"Русский"</Option>
<Option value="en">"English"</Option>
</Select>
</div>);
}
ReactDOM.render(<ChangeLanguageDropdown />, document.body)
Note that I've removed all i18n related code as well as Cookie lib (your setup of Codepen was #R%T$). Next time, start with some example that actually works (e.g. https://codepen.io/mugiseyebrows/pen/ExyJJQQ?editors=1111)

How to disable 2 options in multiselect dropdown and grayout that option

Hi i have used Angular8 and bootstrap 4. I have used bootstrap multi-select dropdown, i need to get the PL Marketing and CL Marketing as disabled and grayed out. i have tried in all ways but not able to disable and gray out that option.
TS:
ngOnInit() {
this.initEoForm();
setTimeout(() => {
$("#multiselectUser")
.multiselect({
buttonWidth: "400px"
})
.on("change", e => {
let selectedFilename = $("#multiselectUser").val();
selectedFilename = selectedFilename.filter(function(
item,
index,
inputArray
) {
return inputArray.indexOf(item) == index;
});
let selectedName = selectedFilename
? selectedFilename.toString()
: "";
this.getSelectedRoles(selectedName);
});
}, 100);
setTimeout(() => {
$('#assignedRoles option[value="124"]').prop("disabled", true);
$('#assignedRoles option[value="123"]').prop("disabled", true);
});
}
HTML:
<select name="user" id="multiselectUser" multiple="multiple" (change)="selecteduser($event)" [(ngModel)]="selectedUsers" >
<option *ngFor="let field of user" [value]="field.id" >
{{field.label}}</option>
</select>
DEMO
I would recommend instead of editing the UI with jQuery to modify the user[] that is visualized in the *ngFor and add a field called disabled. Then in your template you can do the following
<select name="user" id="multiselectUser" multiple="multiple" (change)="selecteduser($event)" [(ngModel)]="selectedUsers" >
<option *ngFor="let field of user" [disabled]="field.disabled" [value]="field.id" >
{{field.label}}</option>
</select>
And your typescript should be changed like so
// From
setTimeout(() => {
$('#assignedRoles option[value="124"]').prop("disabled", true);
$('#assignedRoles option[value="123"]').prop("disabled", true);
});
// To
setTimeout(() => {
this.user = this.user.map(x => {
return {
...x,
disabled: [123, 124].includes(x.id)
};
});
Here is also a demo on stackBlitz (im using your example as base)
// Answer for the comments
You can add a custom class like so and apply whatever styles you need
<option *ngFor="let field of user" [ngClass]="{'disabled-option': field.disabled}" [disabled]="field.disabled" [value]="field.id" >
{{field.label}}</option>
And in order to enable the options, you just have to iterate over the fields again and change the disabled state
** Important
Because you are using third party linrary for the select you must add you styles in the root .css files for them to take effect.
Also because of the library you are using you should re-initialized the select component in order for it to re-render the options with their new state.
Look again at the stackblitz i had provided

Ember simple array to display in component

Simple array in an component, that it will be display in a selector tag. I'm not being able to make it to work. The firstSelector doesn't display anything.
In the component.js:
sortPropertiesAsc: ['value:asc'],
selectors: ['model.modelObjects', 'model.location'],
firstSelector: function(){
const firstGroupObjects = this.get('selectors')[0];
return Ember.computed.sort(firstGroupObjects, 'sortPropertiesAsc');
}.property(),
In the component.hbs
<select onchange={{ action 'selectBrand' value="target.value" }}>
<option value="" >Select company</option>
{{#each firstSelector as |company|}}
<option value={{company.id}} selected={{eq brand company.id}}> {{company.value}}</option>
{{/each}}
</select>
if I write the firstSelector like this in the component.hbs, it will work:
firstSelector: Ember.computed.sort('model.modelObjects', 'sortPropertiesAsc'),
How can I write it like the other way(as a function)
I'm not sure all that's at play in your setup, but one thing I noticed off the bat was if you want your computed property to fire based on changes to selectors, you'd want something like this.
firstSelector: Ember.computed('selectors', function() {
const firstGroupObjects = this.get('selectors.firstObject');
return Ember.computed.sort(firstGroupObjects, 'sortPropertiesAsc');
})
If sortPropertiesAsc changes values you'd want to add it in too
firstSelector: Ember.computed('selectors', 'sortPropertiesAsc', function() {
const firstGroupObjects = this.get('selectors.firstObject');
return Ember.computed.sort(firstGroupObjects, 'sortPropertiesAsc');
})

Changing a Parent's State in React.js

I have a big analytics page. At the top, there are some form elements to choose what you'd like to see the report about.
Below that are some graphs and tables.
So I have the hierarchy set up like this:
Page
Otherstuff1
Report
Setting1
Setting2
Graph1
Graph2
Table
Otherstuff2
I think the state of this report should be held in the Report component, as it's the lowest component that contains everything that needs access to this state.
So how can I update the state of Report when there is a change in Setting1?
Here's a simplified version of my code, relevant to the question.
var Report = React.createClass({
getInitialState: function() {
return {
dateRange: "not changed",
}
},
changeDateRange: function(event) {
console.log("changed");
this.setState({dateRange: "changed"});
},
render: function() {
return (
<div>
<ReportDateRange change={this.changeDateRange}/>
{this.state.range}
</div>
);
}
});
var ReportDateRange = React.createClass({
render: function() {
return (
<select className="form-control" id="historicalRange"
onChange={this.props.change}>
<option value="yesterday">Yesterday</option>
<option value="week">Last week</option>
<option value="fortnight">Last fortnight</option>
<option value="month" selected>This month</option>
</select>
)
}
});
This code runs, and it does log in the console that something changed, but it does not update the state of Report. I think it might be updating the state of ReportDateRange instead.
The control flow looks right to me.
I think what you've got wrong is how you've referenced the state variable.
In your render() function you reference this.state.range but elsewhere that variable is dateRange not range.

What is the proper way to get the value of a React <select> element?

Say I have the following React element (example fiddle here):
var Hello = React.createClass({
getInitialState: function() {
return {parsed: false};
},
_parseEvent: function(event) {
var parser1 = event.currentTarget.selectedOptions[0].value;
var parser2 = event.target.value;
var parser3 = event.nativeEvent.srcElement.value;
if (parser1 && parser2 && parser3)
this.setState({parsed: true});
},
render: function() {
var parsing = "parsing worked";
return (
<div>
<select
onChange={this._parseEvent}>
<option value="----">----</option>
<option value="Yes">Yes</option>
<option value="No">No</option>
</select>
<p>
{ this.state.parsed ?
{parsing}
: null}
</p>
</div>
);
}
});
React.render(<Hello name="World" />, document.getElementById('container'));
I'm using three ways of parsing the value of the <select> element. The first does not work on IE 10, and I know it's a bug per my question here. However, of the other two ways, parser2 or parser3, which is the proper way to get the value of a <select> element in React? Why? Thanks for any help!
Use what you would use in a W3C compatible browser:
event.target.value
This is also agnostic to the type of the form control element.
While the other answer works just fine, if you're looking for a React way, then this can be accomplished by using refs.
Assign a ref to the select:
<select onChange={this._parseEvent} ref="select">
<option value="----">----</option>
<option value="Yes">Yes</option>
<option value="No">No</option>
/select>
Get the DOM node via ref:
var node = React.findDOMNode(this.refs.select)
Get the value via DOM node:
var value = node.value;
Here's an updated fiddle to demonstrate: https://jsfiddle.net/ve88383c/4/

Categories