Implementing Redux Form FieldArray in admin-on-rest - admin-on-rest

My schema has a field which is an unlimited array of textfields. I want to do exactly what the example here at the end shows: http://redux-form.com/6.5.0/docs/api/FieldArray.md
const renderSubFields = (member, index, fields) => (
<li key={index}>
<button
type="button"
title="Remove Member"
onClick={() => fields.remove(index)}/>
<h4>Member #{index + 1}</h4>
<Field
name={`${member}.firstName`}
type="text"
component={renderField}
label="First Name"/>
<Field
name={`${member}.lastName`}
type="text"
component={renderField}
label="Last Name"/>
</li>
)
const renderMembers = ({ fields }) => (
<ul>
<button type="button" onClick={() => fields.push({})}>Add Member</button>
{fields.map(renderSubFields)}
</ul>
)
I imagine this is a fairly common thing to do but I don't see anything like this in the AOR docs or demo. Are there any examples that I'm missing?

I think you meant EmbeddedManyInput that desribed in https://github.com/marmelab/admin-on-rest/issues/695

Related

OnClick of Button , Need to Display the Modal using React Typescript

I have two Components, onClick on Button from "Button Component", I need to Perform Open & Close Operations of that Modal,
But my Modal is in "Dropdown component"... There is No Relation between Button and Dropdown Components, Now How Can I send Onclick event from "Button Component" to "Dropdown component" , and use there to Perform Open & Close Operations of that Modal...
My Button Component
const Button:React.FC = () => {
const [cancel, setcancel] = useState<boolean>(false)
const onCancel=(event: React.MouseEvent<HTMLButtonElement>)=>{
setcancel(true);
}
return (
<button className='btn btn-dark' onClick={onCancel}>Button</button>
)
}
export default Button
My Dropdown component
const Dropdown: React.FC = () => {
const data = inputs;
return (
<>
<div className='form-group'>
<div className="col-4">
<select className="form-select" aria-label="Disabled select example">
<option selected>Select an Option</option>
{data.purpose.map((items) => (
//console.log(items.value);
<option>{items.value}</option>
))}
</select>
</div>
</div>
<div className="modal">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title">Modal title</h5>
<button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div className="modal-body">
<p>Do YOu need any Changes</p>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" className="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</>
)
}
export default Dropdown
Here is APP.tsx
function App() {
return (
<div className="App">
<h1>LordShiva</h1>
<Dropdown />
<Button/>
</div>
);
}
export default App;
Make states in App.js
const [isModal,setIsModal] = UseState(false);
Now pass setIsModal in props of Button Component in your app.js file
<Button passedFunc={()=>setIsModal(!isModal)}/>
Now get this passedFunc in Button Component parameters in props and call it on onClick of button like onClick={() => props.passedFunc()}
Now pass isModal state in your DropDown Component,
<Dropdown show={isModal} />
Now get this show property in your dropdown components props.And then wrap the modal code like that :
{props.show ? <div className="modal">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title">Modal title</h5>
<button type="button" className="btn-close" data-
bs-dismiss="modal" aria-label="Close"></button>
</div>
<div className="modal-body">
<p>Do YOu need any Changes</p>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-secondary"
data-bs-dismiss="modal">Close</button>
<button type="button" className="btn btn-
primary">Save changes</button>
</div>
</div>
</div>
</div> : null}
Note: you can destructure props too.

How can I save the value from radio input as boolean?

I need to save the value selected from the input as a boolean to the database. In this way, the other button I use registers as 0 1 in the yield database. How can I save true as false. Note: it saves false no matter what you choose to the database. It has not changed before or after this procedure.
"showinrow": $(".message_sh:checked").val(),
<div class="btn-group btn-group-toggle" data-toggle="buttons">
<label class="btn btn-primary active">
<input type="radio" class="message_sh" name="options1" value="True"> True
</label>
<label class="btn btn-primary">
<input type="radio" class="message_sh" name="options1" value="False" checked=""> False
</label>
</div>
As i say in the comment you can compare value with the string 'True';
$(".message_sh:checked").val() === 'True
Demonstration
$('.submit').on('click', function(){
const isTrue = $(".message_sh:checked").val() === 'True'
if(isTrue){
alert('This is true')
}else{
alert('This is false')
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="btn-group btn-group-toggle" data-toggle="buttons">
<label class="btn btn-primary active">
<input type="radio" class="message_sh" name="options1" value="True"> True
</label>
<label class="btn btn-primary">
<input type="radio" class="message_sh" name="options1" value="False" checked=""> False
</label>
<button class="submit">submit</button>
</div>

Add and Remove dom elements using alpine JS

I am trying to build a custom add and remove entire div element from an array using alpine JS, here is my code which is working but instead of removing from the exact remove button click it will remove the last one on the array.
HTML
<div x-data="addRemove()">
<template x-for="(field, index) in fields" :key="index">
<div>
<input type="text" name="txt1[]" class="form-input">
<button type="button" class="btn btn-danger btn-small" #click="removeField(index)">×</button>
</div>
</template>
<button type="button" #click="addNewField()">+ Add Row</button>
</div>
JAVASCRIPT
return {
fields: [],
addNewField() {
this.fields.push({});
},
removeField(index) {
this.fields.splice(index, 1);
}
}
Found a solution, this is what I did.
HTML
<div x-data="addRemove()">
<template x-for="(field, index) in fields" :key="field.id">
<div>
<input type="text" name="txt1[]" class="form-input">
<button type="button" class="btn btn-danger btn-small" #click="removeField(field)">×</button>
</div>
</template>
<button type="button" #click="addNewField()">+ Add Row</button>
</div>
JAVASCRIPT
function addRemove() {
return {
fields: [],
addNewField() {
this.fields.push({id: new Date().getTime() + this.fields.length});
},
removeField(field) {
this.fields.splice(this.fields.indexOf(field), 1);
}
}
}
You've to set the 'key' with a unique value in the looping.
<div x-data="{data: []}">
<div #click="data.push({ randomNumber: new Date().getTime()})">(Click Here To Add New Data)</div>
<template x-for="(item, index) in data" :key="index">
<div>
<span x-text="item.randomNumber"></span>
<span #click="data.splice(index, 1)">Remove</span>
</div>
</template>
</div>
online test: https://codepen.io/yuxufm/pen/YzLoxvE

Redux Form FieldArrays autofill

I'm using a field array which consists of email fields. It looks like this:
{fields.map((member, index) => (
<li key={index}>
<div className="form-group d-flex align-items-start">
<Field
name={`${member}.email`}
type="email"
component={renderField}
placeholder="Email"
/>
</div>
</li>
))}
On Chrome, when you autofill one field with a stored email, it autofills the rest with the same email.
For the time being, I've turned off autocomplete, but this is not working. I would like a better way to do this, so that users can autofill a given field, but the rest of them are not autofilled.

FieldArrays in a separate component

I'm using redux-form v6.0.1. I created a component similar to that from documentation example: http://redux-form.com/6.0.1/examples/fieldArrays/
Following the code below from the example, can I move all the fields and action buttons rendering inside <li key={index}> to the separate component to enforce that bind or arrow functions are not used (https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md)?
const renderMembers = ({ fields }) => (
<ul>
<li>
<button type="button" onClick={() => fields.push({})}>Add Member</button>
</li>
{fields.map((member, index) =>
<li key={index}>
<button
type="button"
title="Remove Member"
onClick={() => fields.remove(index)}/>
<h4>Member #{index + 1}</h4>
<Field
name={`${member}.firstName`}
type="text"
component={renderField}
label="First Name"/>
<Field
name={`${member}.lastName`}
type="text"
component={renderField}
label="Last Name"/>
<FieldArray name={`${member}.hobbies`} component={renderHobbies}/>
</li>
)}
</ul>
)
Thank you,
Darek.
Can I move all the fields and action buttons rendering inside <li key={index}> to the separate component to enforce that bind or arrow functions are not used?
Sure. Have you tried it and run into a problem?
I have a very complicated form with a lot of arrays fields inside, and I know that arrow functions are very bad for performance.
Thats why instead of
{fields.map((member, index) =>
<li key={index}>
<button
type="button"
title="Remove Member"
onClick={() => fields.remove(index)}/>
<h4>Member #{index + 1}</h4>
<Field
name={`${member}.firstName`}
type="text"
component={renderField}
label="First Name"/>
<Field
name={`${member}.lastName`}
type="text"
component={renderField}
label="Last Name"/>
<FieldArray name={`${member}.hobbies`} component={renderHobbies}/>
</li>
)}
I tried somethind like that:
{fields.map((member, index) =>
<li key={index}>
<Fields
names={`[${member}.firstname`, `${member}.lastName`]}
component={RenderNames}
index={index}
/>
</li>
)}
const RenderNames = (fields) => {
const removeItem = () => {
fields.remove(index);
}
return (
<button
type="button"
title="Remove Member"
onClick={removeItem}
/>
// how to get 'firstname' and 'lastname' here?
)
}
but couldn't get fields object in a way described in documentation

Resources