Out of focus on first onChange event redux-form ( filedarray ) - javascript

When i trying to write something -> loosing focus on first onChange with redux-form ( Field Arrays ). v6.5.0
Method with render
const renderEmails = ({ fields, meta: { touched, error, submitFailed } }) => (
<div className="col-xs-12">
{fields.map((email, index) =>
<div key={index} className="fieldArray-container relative">
<div className="absolute-link left" style={indexStyle}>
{index + 1}
</div>
<button
type="button"
title="Remove rule"
className="btn btn-link absolute-link right"
style={removeButtonStyle}
onClick={() => fields.remove(index)}>
<i className="fa fa-times-circle" />
</button>
<Field
style={inputStyle}
name={`${email}.email`}
type="text"
component={Input}
/>
</div>
)}
<div className="text-center"><button type="button" className="btn btn-link" onClick={() => fields.push({})}>+ Add Employee</button></div>
{(touched || submitFailed) && error && <div className="alert alert-danger">{error}</div>}
</div>
);
Call fieldarray
<FieldArray name="employeeEmails" component={renderEmails} />

Seems like duplicate.
Using redux-form I'm losing focus after typing the first character
Need to hoist it up.

Related

Dynamic input in FieldArray

i have form, inside i have this part of code:
<FieldArray name="items_list" component={renderItemList} explicitProp={id}/>
<div className="buttons mb-4 text-center">
<div className="btn btn-outline-info mt-4" type="button" onClick={() => push('items_list', undefined)}> Añadir Parametros </div>
</div>
outside of the form i have this:
const renderItemList = ({ fields, explicitProp }) => {
return (
<>
{fields.map((member, index) => (
<>
<div className="row mt-4" key={index}>
<div className="col-md-3">
<h4>{index + 1}- Valor de la Lista </h4>
</div>
<Field
className="form-control"
name={`${member}.idResponse`}
type='text'
component={renderIdResponse}
props={explicitProp + '_E_' + Number(index + 1)}
hidden
/>
<div className="col-md-3 mb-4">
<Field
className="form-control"
name={`${member}.title_item`}
type="text"
component="input"
/>
</div>
<div className="col-md-4">
<FieldArray name={`${member}.value_item`} component={renderValueItems} />
</div>
<div className="col-md-1"
onClick={() => fields.remove(index)}
style={{ cursor: 'pointer' }}
>
❌
</div>
</div>
</>
))}
</>
);
};
const renderValueItems = ({ fields, meta: { error } }) => (
<div className="row">
<div>
<button className="btn btn-outline-primary col-md-12" type="button" onClick={() => fields.push()}>Añadir Sinonimos</button>
</div>
{fields.map((valor, index) => (
<div className="mt-3" key={index}>
<div className="row">
<div className="col-md-10">
<Field
className="form-control"
name={valor}
type="text"
component="input"
label={`Sinónimo ${index + 1}`}
/>
</div>
<div className="col-md-2"
onClick={() => fields.remove(index)}
style={{ cursor: 'pointer' }}
> ❌
</div>
</div>
</div>
))}
{error && <li className="error">{error}</li>}
</div>
);
const renderIdResponse = ({props}) => (
console.log(props),
<Field name='texto' {...props} />
);
I would like to get inside the items_list array the object for every item like this:
"items_list": [
{
"idResponse": CA2_3_E_(index + 1)
"title_item": "RESPUESTA 1",
"value_item": [
"SINONIMO 1",
"SINONIMO 2"
]
}
]
but i can not achieve the idResponse. i pass the 'id' in the form like a explicitProp, and then inside the renderItemList i did try to pass directly a value, created with the explicitProp and index to augment the value.
But not works.
I did try to create i component "renderIdResponse" pass the explicitProp like a prop, and inside try to create the value for every object in the array, but i don't know how.
Some idea.
Thanks

Add popup in every item of flatlist in React

I would like to add a popup form in each item in the Flatlist, and the item is actually a card.
My problem is that every time, I clicked the button, the popup shows but, when my mouse moves out of the card, instead of showing the original one, it shows another popup whose parent is the whole page.
I know the problem should be that I need not set the variable setPopup properly. But I don't know how to fix it.
When my mouse is on the card:
enter image description here
When my mouse is out of the card, the popup will move up and its position will be based on the whole page:
enter image description here
Thank you!
This is my code.
const [buttonPopUp, setButtonPopUp] = useState(undefined);
const renderItem = (item, index) => {
return(
<Card key={index} style={{width: '20rem'}}>
<CardImg className='galleryPics' top src={galleryPic.img} alt="..."/>
<CardBody>
<PopUpEditGallery
gallery={item}
index = {index}
trigger={buttonPopUp}
setTrigger={setButtonPopUp}
>
Edit
</PopUpEditGallery>
<CardTitle className='cardTitle'>{item.title}</CardTitle>
<CardText className='cardText'>{item.description}</CardText>
<Button className="btn-round btn-icon" color="primary" size='sm' onClick={()=> setButtonPopUp(index)}>Edit</Button>
</CardBody>
</Card>
);
}
return (
<div>
<div>
<Header/>
</div>
<div className="container">
<div className="row">
<div className='col-7'>
<ul>
<FlatList
list={values.gallery}
renderItem={renderItem}/>
</ul>
</div>
</div>
</div>
</div>
)
code for popup
return (props.trigger != undefined) ? (
props.trigger == props.index &&
<div className='popup'>
<div className='popupInner'>
<form onSubmit={handleSubmit(onSubmit)}>
<FormGroup>
<Label>Title</Label>
<Input
type="text"
placeholder={prev.title}
onChange={val => props.setTitle(val.target.value, prev.idx)}
/>
</FormGroup>
<Button className="btn-round btn-icon" color="primary" size='sm'>
Submit
</Button>
<Button className="btn-round btn-icon" color="default" size='sm'>
Cancel
</Button>
</form>
</div>
</div>
): "";

redux form - how can i show input before click add button?

I tried this tutorial: https://redux-form.com/6.1.1/examples/fieldarrays/ but I want to show "first name" and "last name" inputs before clicking the "add member" button. I mean, when the page is first opened, the two inputs will already be shown and the user will press the button whenever the user wants to add extra input. how can I do that?
import React from 'react'
import { Field, FieldArray, reduxForm } from 'redux-form'
import validate from './validate'
const renderField = ({ input, label, type, meta: { touched, error } }) => (
<div>
<label>{label}</label>
<div>
<input {...input} type={type} placeholder={label}/>
{touched && error && <span>{error}</span>}
</div>
</div>
)
const renderMembers = ({ fields, meta: { touched, error } }) => (
<ul>
<li>
<button type="button" onClick={() => fields.push({})}>Add Member</button>
{touched && error && <span>{error}</span>}
</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>
)
const renderHobbies = ({ fields, meta: { error } }) => (
<ul>
<li>
<button type="button" onClick={() => fields.push()}>Add Hobby</button>
</li>
{fields.map((hobby, index) =>
<li key={index}>
<button
type="button"
title="Remove Hobby"
onClick={() => fields.remove(index)}/>
<Field
name={hobby}
type="text"
component={renderField}
label={`Hobby #${index + 1}`}/>
</li>
)}
{error && <li className="error">{error}</li>}
</ul>
)
const FieldArraysForm = (props) => {
const { handleSubmit, pristine, reset, submitting } = props
return (
<form onSubmit={handleSubmit}>
<Field name="clubName" type="text" component={renderField} label="Club Name"/>
<FieldArray name="members" component={renderMembers}/>
<div>
<button type="submit" disabled={submitting}>Submit</button>
<button type="button" disabled={pristine || submitting} onClick={reset}>Clear Values</button>
</div>
</form>
)
}
export default reduxForm({
form: 'fieldArrays', // a unique identifier for this form
validate
})(FieldArraysForm)

Adding comment using react and node

I'm trying to build a website where users can comment on a given post. i want to display comment when Button is pressed. All work fine, but i want to show/hide comment when i click comment button. I'm using comment button inside map function so all the elements are executing it. how to show/hide comment for individual element? Please Help.
render() {
return (
<div className="container">
{this.state.queries.map((item, key) => {
return (
<div key={key}>
<hr />
<div className="list-group-item list-group-item-secondary row ">
<div className="authorName">{item.name}</div>
<div>{item.description}</div>
<hr />
<div>
<button
className="btn btn-info"
data-toggle="collapse"
data-target="#demo"
onClick={() => {
return fetch("/queries/" + item._id)
.then(Response => Response.json())
.then(data => {
this.setState({ comment: data.comments });
});
}}
>
Comment
</button>
<div id="demo" className="collapse">
<br />
<form
className="commentForm"
action={"http://localhost:5000/queries/" + item._id}
method="POST"
>
<input
type="text"
className="form-control"
placeholder="Write a comment..."
name="comment"
/>
<button className="btn btn-lg btn-primary btn-block">
Post
</button>
</form>
<br />
<div>
{this.state.comment.map((commentItem, key) => {
return (
<div className="list-group-item list-group-item-success">
<span className="authorName">
{commentItem.author}
</span>
{commentItem.text}
</div>
);
})}
</div>
</div>
</div>
</div>
</div>
);
})}
</div>
);
}
JSONfrom server at 'localhost:5000/queries/'+item._id
{
"comments": [
{
"_id": "5b5eadeeb415381598bdc825",
"text": "sfsdfsd",
"__v": 0
},
{
"_id": "5b5ecbe5b415381598bdc827",
"text": "hii from alex",
"__v": 0
},
{
"_id": "5b5ecd9ed8f72736c830a311",
"text": "asdad",
"__v": 0
}
],
"_id": "5b5ea97f7fb6e02d58b80dba",
"name": "ram#gmail.com",
"description": "Is axios still in use?",
"__v": 3
}
First, I would highly recommend reading the Thinking in React part of react documentation. You are facing these problems because you are not leveraging/using the power of encapsulation that React components bring.
Root Cause: You have multiple places where you can show comments, however you are maintaining them in a single state, so one will always override for others.
From looking at your code, it looks like you may be aiming for the following structure:
Container -
- Posts
- Comments
Container would be responsible for showing all the "posts" --> this.state.queries.map functionality.
Each Post can be responsible for rendering its own comments. That way, even if you have multiple posts, each is responsible for their own comment section.
So your post component can look like:
class Post extends React.Component{
state = {
comments: []
}
render() {
let {item, key} = this.props;
return (<div key={key}>
<hr />
<div className="list-group-item list-group-item-secondary row ">
<div className="authorName">{item.name}</div>
<div>{item.description}</div>
<hr />
<div>
<button
className="btn btn-info"
data-toggle="collapse"
data-target="#demo"
onClick={() => {
return fetch("/queries/" + item._id)
.then(Response => Response.json())
.then(data => {
this.setState({ comment: data.comments });
});
}}
>
Comment
</button>
<div id="demo" className="collapse">
<br />
<form
className="commentForm"
action={"http://localhost:5000/queries/" + item._id}
method="POST"
>
<input
type="text"
className="form-control"
placeholder="Write a comment..."
name="comment"
/>
<button className="btn btn-lg btn-primary btn-block">
Post
</button>
</form>
<br />
<div>
{this.state.comment.map((commentItem, key) => {
return (
<div className="list-group-item list-group-item-success">
<span className="authorName">
{commentItem.author}
</span>
{commentItem.text}
</div>
);
})}
</div>
</div>
</div>
</div>
</div>)
}
And your Container can be:
render() {
return (
<div className="container">
{this.state.queries.map((item, key) => {
return (<Post item={item} key={key} />)

Redux Form Field Arrays-initializing a field array with a specific length

I would like for my form component to start off with a field array with 3 empty fields. Can anyone explain how to initialize it this way?
I'm going off the example provided in the documentation here: https://redux-form.com/7.0.4/examples/fieldarrays/
Here, we can see that originally, we have no fields, and only when we click on the relevant button do we add them, by calling onClick={() => fields.push({})}.
I'd like to start off with three fields and allow the user to add more. Calling fields.push in ComponentDidMount doesn't work. How do I initialize the fields object with a specific length?
FieldArraysForm.js
import React from 'react'
import { Field, FieldArray, reduxForm } from 'redux-form'
import validate from './validate'
const renderField = ({ input, label, type, meta: { touched, error } }) =>
<div>
<label>
{label}
</label>
<div>
<input {...input} type={type} placeholder={label} />
{touched &&
error &&
<span>
{error}
</span>}
</div>
</div>
const renderHobbies = ({ fields, meta: { error } }) =>
<ul>
<li>
<button type="button" onClick={() => fields.push()}>
Add Hobby
</button>
</li>
{fields.map((hobby, index) =>
<li key={index}>
<button
type="button"
title="Remove Hobby"
onClick={() => fields.remove(index)}
/>
<Field
name={hobby}
type="text"
component={renderField}
label={`Hobby #${index + 1}`}
/>
</li>
)}
{error &&
<li className="error">
{error}
</li>}
</ul>
const renderMembers = ({ fields, meta: { error, submitFailed } }) =>
<ul>
<li>
<button type="button" onClick={() => fields.push({})}>
Add Member
</button>
{submitFailed &&
error &&
<span>
{error}
</span>}
</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>
const FieldArraysForm = props => {
const { handleSubmit, pristine, reset, submitting } = props
return (
<form onSubmit={handleSubmit}>
<Field
name="clubName"
type="text"
component={renderField}
label="Club Name"
/>
<FieldArray name="members" component={renderMembers} />
<div>
<button type="submit" disabled={submitting}>
Submit
</button>
<button type="button" disabled={pristine || submitting} onClick={reset}>
Clear Values
</button>
</div>
</form>
)
}
export default reduxForm({
form: 'fieldArrays', // a unique identifier for this form
validate
})(FieldArraysForm)
Thanks to the Redux Form team:
https://github.com/erikras/redux-form/issues/3640
Basically, the way it's done is to pass in an array of initial values to the form when you connect and export it, something like this:
export default reduxForm({
form: "foo",
initialValues: {
rockSingers: ['Axl Rose', 'Brian Johnson']
},
onSubmit: values => {
window.alert( "Submited: \n" + JSON.stringify( values, null, 2 ) );
}
})( MyForm );

Categories

Resources