Antd: set default value / setFieldsValue for Cascader when opening Modal - reactjs

I have Antd's Cascader like this:
When I click on Edit button it open modal as below.
const showModal = (record) => {
console.log('record', record); // this is current record which has existing value to be displayed in cascader
form.setFieldsValue(record);
setVisible(true);
};
how do I feed initial values or existing values to Cascader?
<Cascader
defaultValue={['zhejiang', 'hangzhou', 'xihu']}
options={propertyOptions}
loadData={loadCompanies}
onChange={onChange}
changeOnSelect
/>
using defaultValue prop like does not seem to work.
When I load propertyOptions, it loads with values like
property1,
property2
When I click on property1 it loads children dynamically.
so selected value is e.g. property1 > company1
but When I click on Edit modal it has only parent values. (children won't be there as I load them on parent click).
When I click on modal it has the whole item data so maybe I can use it to show like hardcoded value or something?
UPDATE:
This is how I fill propertyOptions
function setPropertiesAsOptions(propertiesQuerySnapshot) {
propertiesQuerySnapshot.forEach((doc) => {
options.push({
value: doc.id,
label: doc.data().propertyName,
isLeaf: false,
});
});
setPropertyOptions(options);
}

Is there propertyOptions has value names like zhejiang or other?
In your case this data should work properly as options
const options = [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
},
],
},
],
},
];
So it's mean that value name should be the same as params in defaultValue

Related

How to get select option label in addition to its value in react antd form?

I used antd-form-builder to create a form. The form contains select field (dropdown). I used form.getFieldValue("task") to get the value of selected option, I also need to get the label of selected option. how can I get it by clicking on a button?
const meta = (
fields: [
{
key: "task",
label: "Task",
widget: "select",
widgetProps: { showSearch: true },
options: [
{ label: "Pre-filter Replacement", value: 1 },
{ label: "Oil Change", value: 2 },
],
},
]
)
const handleClick = () => {
let taskValue = form.getFieldValue("task")
}
<Form form={form} onValuesChange={forceUpdate} onFinish={onFinish}>
<FormBuilder meta={meta} form={form} />
<Button onClick={handleClick}>Done</Button>
</Form>
You can use labelInValue prop to get the value along with selected option label.
Pass labelInValue: true, in widgetProps
const meta = {
fields: [
{
key: "task",
label: "Task",
widget: "select",
widgetProps: {
showSearch: true,
labelInValue: true,
},
options: [
{ label: "Pre-filter Replacement", value: 1 },
{ label: "Oil Change", value: 2 },
],
},
],
};
Now task value will not be a number buy an object containing label, value, key, disabled.
You can follow the Select API Documentation

How to append html element in array of objects ( specific key value) in React Js

I want to use Google material icon like <span className="material-icons">settings</span> in my object value. Below is sample code (array of objects). Have to add above span as value of 'icon' key?
Google material icon reference link
let buttonData = [
{
label: "",
classNames: "headerButton",
icon: faBrush,
title: "Design",
onClick: (e) => {
this.setState({ ActiveButton: "Design" });
},
dropdownList: [["Design"]],
contextMenuStyle: "listGroupBottom",
contextListStyle: "lisItemBottom",
},
{ }, {} ]
Tried below code in icon
icon: '<span className="material-icons">settings</span>'
icon: "<span className="material-icons">settings</span>"

Antd Cascader component value/defaultValue showing ID instead of label

So I am using the Antd Cascader component (for the first time, having used Antd Select for most other things for the past few months). However, it isn't quite working yet. I have the options basically like this (but with a lot more options, only 3 levels deep tho like this):
const options = [
{
label: 'Base 1',
value: 'base_1',
children: [
{
label: 'Middle a',
value: 'middle_a',
children: [
{
label: 'Foo',
value: 'd57b2b75-4afa-4a16-8991-fc736bce8cd5',
},
{
label: 'Bar',
value: 'd12b2b75-4afa-4a16-8991-fc736bce8cec',
}
]
},
{
label: 'Middle b',
value: 'middle_b',
children: [
{
label: 'Baz',
value: 'd32b2b75-4afa-4a16-8991-fc736bce8cdd',
},
{
label: 'Quux',
value: 'dabb2b75-4afa-4a16-8991-fc736bce8ced',
}
]
}
]
},
{
label: 'Base 2',
value: 'base_2',
children: [
{
label: 'Middle a',
value: 'middle_a',
children: [
{
label: 'Helo',
value: 'd32bce75-4afa-4a16-8991-fc736bce8cdd',
},
{
label: 'World',
value: 'dabbac75-4afa-4a16-8991-fc736bce8ced',
}
]
}
]
}
]
I configure the component like this:
<Cascader
options={options}
getPopupContainer={trigger => trigger.parentNode}
multiple={multiple}
displayRender={label => {
return label.join(' / ');
}}
value={defaultValue}
// eslint-disable-next-line #typescript-eslint/no-explicit-any
onChange={(val: any, options: any) => {
if (multiple) {
const ids = serializeCascaderOptionValues(options);
onChange?.(ids, options);
} else {
onChange?.(val[2] ? String(val[2]) : undefined, options);
}
}}
showSearch={{
filter: (input: string, path) => {
return path.some(
option =>
String(option?.label).toLowerCase().indexOf(input.toLowerCase()) >
-1
);
},
}}
/>
Where, here, value or defaultValue I am passing in an array like ['d32bce75-4afa-4a16-8991-fc736bce8cdd'], which maps to Base 2 / Middle a / Helo. When I select the value Base 2 / Middle a / Helo from the UI, it shows correctly in the input like that. But when I save it and refresh the page (persisting to the backend, and pass in value={value} like value={['d32bce75-4afa-4a16-8991-fc736bce8cdd']}, it shows the ID hash in the input instead of the nice string Base 2 / Middle a / Helo. When I log displayRender={label...}, the label is showing the [ID-hash], rather than an array of like ['Base 2', 'Middle a', 'Helo']. What am I doing wrong, how do I get it to show properly?

How to mark options as selected

How can i set selected atribute to options inside of <SelectArrayInput> component? I have not realized how to set selected atribute yet.
I have already tried to put there a attribute selected, but it doesnt seem to work.
const tec = [
{ name: "Apple", id: 1, selected: true},
{ name: "Facebook", id: 2 },
{ name: "Netflix", id: 3 },
{ name: "Tesla", id: 4 },
];
const ReferrenceSelectBox = ({ source, record = {} }) => <SelectArrayInput choices={ tec } />;
ReferrenceSelectBox.propTypes = {
label: PropTypes.string,
record: PropTypes.object,
source: PropTypes.string.isRequired,
};
export default ReferrenceSelectBox;
I expect the output of <SelectArrayInput> with already selected options.
I am not able to get a code sandbox working with react-admin, but from the documentation it looks like it is using the Select from Material-ui as the base.
In Material-UI you can pass the values to be selected as a prop: value which takes an array of the ids that you want.
So, in your case, instead of having selected attribute, you can create another array which captures the selectedIds and pass it as value prop and it should work.
const tec = [
{ name: "Apple", id: 1},
{ name: "Facebook", id: 2 },
{ name: "Netflix", id: 3 },
{ name: "Tesla", id: 4 },
];
const selectedTec = [1];
const ReferrenceSelectBox = ({ source, record = {} }) => <SelectArrayInput value={ selectedTec } choices={ tec } />;
ReferrenceSelectBox.propTypes = {
label: PropTypes.string,
record: PropTypes.object,
source: PropTypes.string.isRequired,
};
export default ReferrenceSelectBox;

How to make array type schema objects appear one in a row? react-jsonschema-form

I am using react-jsonschema-form to create a form. Single components are displaying fine but array components are coming in a row. How Can I make them appear one array object in a row so that everytime I click Add button , new array object is rendered in new row. Code is as follows:
const schema = {
type: "object",
properties: {
Name: { type: "string", title: "Name", default: "A new Task" },
Title: { type: "object", properties: { First: { type: "string" }, Second: { type: "string" } } },
XYZ: { type: "array", items: { type: "object", properties: { Third: { type: "string" }, Forth: { type: "boolean", enum: [true, false], enumNames: ["True", "False"] } } } }
}
}
const uiSchema = {
"ui:order": ["Name", "Title", "Done"],
Name: { "ui:widget": "textarea" },
Title: { First: { "ui:widget": "textarea" }, Second: { "ui:widget": "textarea" } },
XYZ: { items: { Third: { "ui:widget": "textarea" }, Forth: { "ui:widget": "radio", "ui:options": { inline: true } } }, "ui:options": { orderable: false, removable: true, inline: false } }
}
Form Code is as Follows:
<Form schema={schema}
// formData = {defaultData}
uiSchema={uiSchema}
onChange={log("changed")}
onSubmit={SubmitRoutine}
onError={ErrorRoutine}
/>
As shown in the following picture Array XYZ objects are fixed width and displaying next to each other. I want them full width and every object in new row. I am using React and Bootstrap4
Also very time I have to even add first object by clicking Plus button. I want first object to appear itself. Please let me know how may I fix it. Thanks
Checkout this library. It allows laying out your form using bootstrap-grid.
It could be achieved with pure CSS, provided there is no need to reflect order in the model:
/* class of a wrapping element */
.array-item-list {
display: flex;
/* column, column-reverse, row, row-reverse */
flex-direction: column-reverse;
}

Resources