Redux-Form: Delete field data when specific option is selected - reactjs

I have an address form that has a United States option and an International option. When the U.S. option is selected a state drop down appears. When the International option is selected, the state drop down disappears.
My issue is when a state is selected, the form data for the state option doesn't get removed when the international option is selected and I do a POST to my service.
Is there a way for me to make sure an empty string is sent when international is selected, and not the previous data.
Below is the code for my radio group field to select U.S. or International.
<Field
component={RadioGroup}
name={countryCodeName}
choices={[
{
label: 'U.S. or U.S. Territory',
value: 'USA'
},
{
label: 'International',
value: 'international'
}
]}
label="Location"
/>
Below is the code for the state only on usa selection. I use formValueSelector from redux-form to accomplish this.
{hasInternationalValue === 'USA' && (
<Field
component={Select}
name={stateName}
label="State"
options={stateOptions}
/>
)}

I ended up solving this issue by using Redux-Form's change() function.
change(form:String, field:String, value:String)
Saves the value to the field.
Inside the form:
this.props.changeFormValue('fieldValue', data);
Inside the container:
changeFormValue: (key, value) => {
dispatch(change('formName', key, value));
}

Related

How to pass dynamic custom option id to the react-select option?

I'm facing the issue on the react-select package.
I'm going to pass the id to the every options in the Select component from the react-select component.
My code looks like bellow.
var options = [
{id: 'lease', label: 'Lease', id: 'ownership-details-option-lease'},
{id: 'own', label: 'own', id: 'ownership-details-option-own'}
]
I'm going to add the id to the option in the react-select component.
<Select
name='ownershipstatus'
onChange={(e) => {}
...
}
options={options}
/>
Your 'option' objects cannot have two id keys. Object keys must be unique, or the last defined will overwrite the first.
You have two props, getOptionLabel: (option:Object) => String and getOptionValue: (option:Object) => String that you use to define "this is the displayed value and this is the actual value".
pseudocode:
<Select
getOptionLabel={(option) => option.customLabel}
getOptionValue={(option) => option.id}
value={someValueState}
onChange={({target: {value}}) => setSomeValueState(value)}
{...otherProps}
/>
The value you pass in to your control should equate to the 'value' of an option. Are you trying to set an explicit 'id' on options in your list? Why? Are you attempting to write unit testing? If so, use react-select-event and #testing-library/react. You won't need those id's. If it's something else, give us a valid use case.

React admin select input default empty value

I am using react admin's select input& I am currently on version 3.13 and this version allows the attribute 'allowEmpty' to show an extra empty field in the selection dropdown. Also we can use 'initialValue' prop to set the initial value for the inputs. But is there a way to set the empty value as default value selected for my dropdown?
In my case one of the values from the possible choices is getting defaulted
Can you elaborate on your problem? When you have set the allowEmpty prop, the SelectInput should be empty by default. I was able to reproduce the desired behavior with the follwing code:
<SelectInput
source="test"
label="Test"
allowEmpty
choices={[
{ id: "1", name: "yo" },
{ id: "2", name: "yoyo" }
]}
initialValue="" // This line can be omitted
/>
One problem I could think of would be when you have set default values for the <Form /> component you're using, <SimpleForm /> per default.

How to add a filter in react-admin List populated by unique values within the list?

Probably a newbie question, but can't quite connect the dots. I have a filter component in a List:
const BrandFilter = (props) => (
<Filter {...props}>
<SearchInput source="q" alwaysOn />
<RadioButtonGroupInput source="active" alwaysOn label="" choices={[
{ id: 'true', name: 'Active' },
{ id: 'false', name: 'Inactive' },
{ id: ' ', name: 'All' },
]} />
<QuickFilter source="pursue" label="Pursue" resettable />
<SelectInput label="Status" source="status" optionText="status" />
</Filter>
);
The SelectInput doesn't show anything in the dropdown list. Not sure if it's possible but I'd like to show a dropdown list with unique status values that appear in the records. Status does not have an FK relationship; its just a text field that anything can be entered into. But, I'd still like the user to be able to see the values in the dropdown and select one. Possible? Thanks.
UPDATE
I tried to add a unique list of statuses as a reference record by modifying the api to accept a new end point: /brands/statuses and returning a unique list of statuses. It did work in populating the Status dropdown list.
App.js:
<Resource
name="brands/statuses" />
Brand.js (Filter component)
<ReferenceInput source="status" reference="brands/statuses" perPage={25}>
<SelectInput label="Status" source="status" optionText="status" />
</ReferenceInput>
However, I got an error that at least one record didn't have an id. I remembered that react expects records to have an id. So, as a hack, I added the id of the first brand record to the sql:
SELECT fpb.id, fpb.status FROM lookabout.fgm_product_brand fpb WHERE fpb.status IS NOT NULL GROUP BY fpb.status ORDER BY fpb.status
That resulted in getting a list of statuses in the filter dropdown. However, when I clicked on one of them, it sent the id of the status (which was actually just the id of a brand record) and returned no results:
http://localhost:3010/brands/find?limit=15&page=1&orderBy=id&orderDir=ASC&filter={%22active%22:%22%20%22,%22status%22:2}
Close, but not quite. I feel I'm forcing something because I'm not quite getting it. Or, working against how react-admin was meant to operate?? Any suggestions would be welcome. Thanks.
FINAL UPDATE
Got it to work. Rather than use the id of the brand record as a substitute status id, I just used the status itself. So, the sql in the api now reads:
SELECT fpb.status AS id, fpb.status FROM lookabout.fgm_product_brand fpb WHERE fpb.status IS NOT NULL GROUP BY fpb.status ORDER BY fpb.status
That gives the result set an id that is unique and that is then used in when passing the filter criteria. The HTTP GET request now looks like:
http://localhost:3010/brands/find?limit=15&page=1&orderBy=id&orderDir=ASC&filter={%22active%22:%22%20%22,%22status%22:%22Potential%22}
And that returns the expected results. Thanks to all for your help.
I see two solutions:
First, probably the best but with more work, is create new api endpoint, e.g, yourResourceStatuses or yourResource/statuses, which returns distinct uniques values for the status field, then reference this new resource with a ReferenceInput as your SelectInput parent:
<Filter>
....
<ReferenceInput source="status" reference="resourceStatuses">
<SelectInput label="Status" source="status" optionText="status" />
</ReferenceInput>
<Filter/>
You need also to declare such resource under Admin, only with name prop, allowing react-admin to initialize it's redux stores.
<Admin>
....
<Resource name="resourceStatuses"/>
</Admin>
If you are using SQL, this can be as simple as
SELECT DISTINCT status from 'table';
The second, probably will make appear duplicate status values on the dropdown, but would require less work if your api support text search on the status field. Is chaging the SelectInput for a AutocompleteInput and wrapping it with a ReferenceInput with the same resource.
<Filter>
....
<ReferenceInput
source="status"
reference="yourResource"
filterToQuery={searchText => ({ status: searchText })}
>
<AutocompleteInput label="Status" optionText="status" />
</ReferenceInput>
<Filter/>
Have you tried wrapping it with a <ReferenceInput /> component? Otherwise it appears you have to define select options.
According to the docs, wrapping it with ReferenceInput should pull the options automatically based on source:
https://marmelab.com/react-admin/Inputs.html#selectinput
Scroll to the end of the text referencing SelectInput and you'll see this:
Tip: If you want to populate the choices attribute with a list of related records, you should decorate <SelectInput> with <ReferenceInput>, and leave the choices empty:
import { SelectInput, ReferenceInput } from 'react-admin';
<ReferenceInput label="Author" source="author_id" reference="authors">
<SelectInput optionText="last_name" />
</ReferenceInput>
If that doesn't work, maybe you can fetch the data and define your options from there. For reference:
<SelectInput source="category" allowEmpty emptyValue={null} choices={[
{ id: 'programming', name: 'Programming' },
{ id: 'lifestyle', name: 'Lifestyle' },
{ id: 'photography', name: 'Photography' },
]} />

React select - different labels for dropdown list and for input field

Is it possible (by default) to specify one label for react-select dropdown options and have another label
be displayed in input field after one of the dropdown options has been selected.
For example, if I have following object:
{label: "David Smith", selectLabel: "Dave", value: 1}
Is it possible by default to have it so label is displayed in the dropdown list and after I make a selection that selectLabel is displayed in input field?
By saying "default" I mean if there is a prop somewhere or something that would allow me to specify values for dropdown list and input field separately?
So basically I'm looking to get something like this:
and after selection occurs I want "Dave" (and not "David Smith") to be shown in the input field:
You can use the formatOptionLabel to achieve this result.
<Select
name="color"
options={colourOptions}
formatOptionLabel={(option, { context }) => {
/* context can be either `menu` or `value`
menu - dropdown
value - value displayed
*/
return context === 'menu' ? option.label : option.color;
}}
/>
Codesandbox
Docs

react bootstrap multiselect default value

I am using react-bootstrap-multiselect for my project. I need to pass a default value to it before loading. Does react-bootstrap-multiselect have an API to pass a default selected value(s)?
<Multiselect
onChange={this.handleMultiSelect}
value={this.props.multiSelectData}
data={this.props.multiSelectData}
buttonWidth="10
multiple
/>
I want to pass a dynamic value, which will depend on a user click.
Thanks
For everyone who comes across this question again:
<Form.Control as="select" multiple defaultValue={['FOO', 'BAR']}>
<option>FOO</option>
<option>NOT SELECTED</option>
<option>BAR</option>
</Form.Control>
You can simply set an array as defaultValue.
In the example above FOO and BAR are selected.
To do this, set the selected attribute to true for the "data" parameter (in your case, this is an array for the required element this.props.multiSelectData). An example can be found at this link.
An example of an array for the "data" parameter with a default value:
var mass = [
{
value: -777,
label: 'No data',
selected: true
},
{
value: 888,
label: 'data 888'
}
]

Resources