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)
Related
I want to clear/remove/reset select options from dropdown itself and not from external button or allowClear
Let's say the icon of a trash in select option will reset all values:
However, I'm quite stuck on how to reset the value with this my current following code:
import st from "./AddToCartDropdown.module.css";
import {useState} from 'react';
import { Select } from 'antd';
import { DeleteFilled } from '#ant-design/icons';
const { Option } = Select;
function loopStock(n, selectedIndex){
var elements = [];
for(let i = 1; i <= n; i++){
const qty = new String(i);
const resultQty = qty.concat(" in cart");
elements.push(<Option value={i}> <span className={st.addToCartSelect}> {i === selectedIndex ? resultQty : i} </span></Option>);
}
return elements;
}
const AddToCart = () => {
const [selectedIndex, setSelectedIndex] = useState(-1);
const onChange = (newSelectedIndex) => {
setSelectedIndex(newSelectedIndex);
}
return (
<div >
<Select defaultValue="Add to Cart" onChange={onChange} className={st.addToCartDefault} bordered={false}>
<Option value="delete"> <DeleteFilled /> </Option>
{loopStock(5, selectedIndex)}
</Select>
</div>
);
};
export default AddToCart;
When I select the trash icon, it supposed to show me Add to Cart instead of trash icon:
The problem is I'm confused how to set the state after I selected the icon of trash in order to reset all options and go back to Add to Cart default value of Select.
I'm new to React/JavaScript and still learning. After searching all solutions, I think it's the best to create my own question in here. Thanks!
You can make your select as a controlled component by passing a value prop and having a state. set the initial state to null instead of -1 so that we can use the placeholder.
const [selectedIndex, setSelectedIndex] = React.useState(null);
when the selected value is delete we are setting the state to null
const onChange = (newSelectedIndex) => {
if(newSelectedIndex === 'delete'){
setSelectedIndex(null)
}else {
setSelectedIndex(newSelectedIndex)
}
}
Now add the value and placeholder prop in your select.
<Select placeholder="Add to Cart" value={selectedIndex} onChange={onChange} bordered={false}>
<Option value="delete"> <DeleteFilled /> </Option>
{loopStock(5, selectedIndex)}
</Select>
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
I am trying to change a span element when a new option is selected in Javascript.
This is the html code:
<span id="month"></span>
(...)
<option id="plan_option".....
And this is my javascript code that currently just displays a text in when the page loads:
window.onload = function month_freq() {
var id = document.getElementById("plan_option").value;
var freq = '';
if (id == 5144746){
freq = 'ogni mese';
} else{
freq = 'ogni due mesi';
}
document.getElementById("month").innerHTML = freq;
}
So, should I make a new function that is called when option changes or idk.
Any help is appreciated, thanks!
EDIT
So, I try to set it in more context and update it to the current status.
My goal here is to tell the client, relative to the plan that he chooses, on which basis will he pay (monthly or two monthly).
Thanks to #Peter Seliger I updated the code, so I now have this:
Liquid/HTML(1):
<select name="plan_select" id="plan_select">
{% for plan in selling_plan_group.selling_plans %}
<option id="plan_option" data-billing-frequency="{% if plan.id == 5144746 %}ogni mese{% else %}ogni due mesi{% endif %}" value="{{ plan.id }}">{{ plan.options[0].value }}</option>
{% endfor %}
</select>
HTML(2):
<span id="month"></span>
Javascript:
function displayBoundBillingFrequency(evt) {
const elementSelect = evt.currentTarget;
if (elementSelect) {
const selectedOption = elementSelect[elementSelect.selectedIndex];
// `this` equals the bound billing-frequency display-element.
this.textContent = (selectedOption.dataset.billingFrequency || '');
}
}
function mainInit() {
const planOptions = document.querySelector('#plan_select');
const frequencyDisplay = document.querySelector('#month');
if (planOptions && frequencyDisplay) {
const displayBillingFrequency = displayBoundBillingFrequency.bind(frequencyDisplay);
// synchronize display data initially.
displayBillingFrequency({
currentTarget: planOptions,
});
// initialize event listening/handling
planOptions.addEventListener('change', displayBillingFrequency);
}
}
mainInit();
But it still doesn't work. Thanks.
One just wants to listen to the changes of a select element.
Thus one somehow needs to identify this very select element and not so much each of its option elements. The latter one's then do not need to feature either a name- or an id-attribute but a value-attribute instead.
Then one does implement an event handler which does read the currently selected option's value and also does write this very value to the desired/related html-element.
One also needs to provide the event listening/handling to the formerly mentioned select element.
In addition one wants to synchronize the default selected value with the displaying element at load/render time.
Note
For security reasons one does not really want to render a text value via innerHTML ... in this case a textContent write access does the job just fine.
function handleMonthOptionChangeForRelatedDisplay(evt) {
const elementDisplay = document.querySelector('#month');
const elementSelect = evt.currentTarget;
if (elementDisplay && elementSelect) {
const elementSelect = evt.currentTarget;
const selectedIndex = elementSelect.selectedIndex;
elementDisplay.textContent = elementSelect[selectedIndex].value
}
}
function initMonthOptionChange() {
const elementSelect = document.querySelector('#month-options');
elementSelect.addEventListener('change', handleMonthOptionChangeForRelatedDisplay);
}
// window.onload = function () {
// handleMonthOptionChangeForRelatedDisplay({
// currentTarget: document.querySelector('#month-options')
// });
// initMonthOptionChange();
// }
handleMonthOptionChangeForRelatedDisplay({
currentTarget: document.querySelector('#month-options')
});
initMonthOptionChange();
<select name="plan_option" id="month-options">
<option value=""></option>
<option value="Ogni Mese">ogni mese</option>
<option value="Ogni due Mesi" selected>ogni due mesi</option>
</select>
<p id="month"></p>
In case the OP has to render an option-specific text-value different from the option element's value-attribute there was still the approach of providing this information via an option-specific data-attribute in order to keep the handler-implementation as generic (without any additional and case-specific compare-logic) as possible ...
function displayBoundBillingFrequency(evt) {
const elementSelect = evt.currentTarget;
if (elementSelect) {
const selectedOption = elementSelect[elementSelect.selectedIndex];
// `this` equals the bound billing-frequency display-element.
this.textContent = (selectedOption.dataset.billingFrequency || '');
}
}
function mainInit() {
const planOptions = document.querySelector('#plan-options');
const frequencyDisplay = document.querySelector('#plan-billing-frequency');
if (planOptions && frequencyDisplay) {
const displayBillingFrequency = displayBoundBillingFrequency.bind(frequencyDisplay);
// synchronize display data initially.
displayBillingFrequency({
currentTarget: planOptions,
});
// initialize event listening/handling
planOptions.addEventListener('change', displayBillingFrequency);
}
}
mainInit();
<select name="plan_option" id="plan-options">
<option value=""></option>
<option value="541758" data-billing-frequency="ogni mese" selected>First Option</option>
<option value="752649" data-billing-frequency="ogni due mesi">Second Option</option>
<option value="invalid">Invalid Option</option>
</select>
<p id="plan-billing-frequency"></p>
You should check HTMLElement: change event
var planSelectElem = document.getElementById("plan_select"); // <select id="plan_option_select"></select>
planSelectElem.onchange = month_freq;
// OR
planSelectElem.addEventListener("change", month_freq);
I am using antd design in my React app.
Here's a code snippet where I am facing the issues :
<Select
showSearch
optionFilterProp = "children"
placeholder = "Select Company"
value = "{this.state.company}"
name = "company"
onSelect = "{this.handleCompanyChange}"
>
Now it shows the correct value selected if this.state.company is not null. But if this.state.company is empty or null, placeholder doesn't shows up.
How can I solve this issue so that the placeholder appears if value is null?
set this.state.company to be undefined instead of null.
you should update as below:
<Select
showSearch
optionFilterProp = "children"
placeholder = "Select Company"
value = {this.state.company || undefined} ---- update this line
name = "company"
onSelect = "{this.handleCompanyChange}"
>
It should be set to undefined instead of null or "" empty string.
this.props.form.setFieldsValue({
myFieldName: undefined
})
I have faced the the same issue, heres the solution:
Code snippet for ant design select
<Select key="1" value={this.getStateValue()} showSearch allowClear placeholder='Select Weight' onChange={onWeightChange}>
{options}
</Select>
where getStateValue will be this:
getStateValue = () => {
const { value } = this.state;
if (value) {
return value;
}
}
I changed from:
const [value, updateValue] = useState("");
To:
const [value, updateValue] = useState(undefined);
And it worked!
If you are using Form.create() of the Antd then there is another cool way to set/get the value of the form. Note that in this method the components (Select and others) have to be inside a <Form> element. Also the enclosing class should be passed in Form.create() object as props, as shown below:
export default connect(mapStateToProps, mapDispatchToProps)(Form.create()(YourClassName));
This way we have this.props.form available in the props. This will have an important function named getFieldDecorator, as shown below:
const { getFieldDecorator } = this.props.form;
Every Input component must be wrapped inside a , see below:
<FormItem>
{ getFieldDecorator('prefix', {
initialValue: '86',
})(
<Select style={{ width: 70 }}>
<Option value="86">+86</Option>
<Option value="87">+87</Option>
</Select>
);}
</FormItem>
As you can see above, this is more easier way to set initial value to the form elements.
Note that at times when you need to set values of the form elements in functions programatically then you can use setFieldsValue, setFields etc.
Before using getFieldsValue getFieldValue setFieldsValue and so on, please make sure that corresponding field had been registered with getFieldDecorator.
Please refer https://ant.design/components/form/?locale=en-US#Form-fields for more information on coordinated controls.
Example:
componentDidMount() {
if (someCheckHere){
this.props.form.setFieldsValue({
company: userData.companyName
})
}
}
Check the image posted, you need to target the name and try to set it to null if its an empty string, this should work.
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