I'm trying to render a form with data stored in the database. If I remove the form and wrap the PositionSingle input fields in a div the data renders correctly however I'm unable to make any changes. When I wrap the inputs in a form the component doesn't render.
I'm new to react with meteor so any assitance is appreciated.
Path: PositionSingle.jsx
render() {
return (
<form className="new-position" onSubmit={this.addPosition.bind(this)}>
<input
type="text"
ref="title"
placeholder="Position title"
defaultValue={this.props.position.title} />
<input
type="text"
ref="company"
placeholder="Company"
defaultValue={this.props.position.company} />
<button type="submit">Submit</button>
</form>
)
}
Path: PositionWrapper.jsx
render() {
return (
<div>
{this.positions().map( (position)=>{
return <PositionSingle key={position._id} position={position} />
})}
</div>
)
}
This is a very old question, so I don't know if you still have the same project, even, but I like to make sure there are no loose ends if I can. That error looks like what #ThaiTran said, that you don't have addPosition defined in PositionSingle. After you add that, that error should go away. Did that work?
Related
I tried to add a required element (when the box become red if not text is inside) on my form but without success, I installed react-strap, Bootstrap. when I apply many changed it didn't work for no reason
and it's just not moving if someone know why I would be happy.
render() {
return (
<div>
<form class="needs-validation" novalidate>
<InputGroup size="sm">
<InputGroupAddon addonType="append" className="m-2">
<Input
className="form-control"
placeholder="Add a new To-Do. "
onChange={(e) => this.updateInput(e.target.value)}
value={this.state.input}
onKeyPress={this.handleKeyPress}
required
/>
<Button
color="primary"
size="sm"
className="add-todo"
onClick={this.handleAddTodo}
>
Add
</Button>
</InputGroupAddon>
</InputGroup>
</form>
</div>
);
}
export default connect(null, { addTodo })(AddTodo);
// export default AddTodo;
What you are doing is passing required as a prop to your class Input. You need to add the html tag when the field renders, i.e. in Input.js:
return (
<input ... required={this.props.required}>
)
i think you should add the 'is-invalid' class to the input element if that field is empty.
https://getbootstrap.com/docs/4.0/components/forms/?#server-side
I am using a template based form in angular. I also use bootstrap (v4) and I wish to show some validation messages when the form was submitted.
This is my form:
<form [ngClass]="{'was-validated': wasValidated}">
<div class="form-group">
<label for="name">Name</label>
<input type="text" id="name" name="name" class="form-control" [(ngModel)]="category.name" #name="ngModel" required maxlength="100"/>
<div *ngIf="name.invalid" class="invalid-feedback">
<div *ngIf="name.errors.required">
Name is required.
</div>
</div>
</div>
<button type="submit" class="btn btn-success" (click)="save()">Save</button>
</form>
My component looks as follows:
category: Category;
wasValidated: boolean = false;
ngOnInit() {
this.reset();
}
save() {
this.wasValidated = true;
this.categoriesService.createCategory(this.category).subscribe(
() => {
this.notificationService.add(notifications.category_saved, {name: this.category.name});
this.reset();
},
() => this.notificationService.add(notifications.save_category_failed)
);
}
reset() {
this.wasValidated = false;
this.category = {} as Category;
}
This works, but I have a feeling it's overly complex and more like a workaround rather than the right way. What is the best way to accomplish this?
Note: the class was-validated must be present on the form element in order to show the div with class invalid-feedback. I'm using this: https://getbootstrap.com/docs/4.0/components/forms/#validation
Note 2: I have currently no mechanism yet to prevent form submission on error. I'd like to know a good solution for that as well!
With the answer from #Chellappan V I was able to construct the solution I wanted.
I have applied to following changes:
First added #form="ngForm" to the form tag in the template. Secondly I changed the ngClass expression to reference the submitted state of the form, rather than referring to a boolean which was set to true manually when form was submitted. Last but not least I pass the form in the submit method on the save button.
<form novalidate #form="ngForm" [ngClass]="{'was-validated': form.submitted}">
<!-- form controls -->
<button type="submit" class="btn btn-success" (click)="submit(form)">Save</button>
</form>
In the component I injected the template variable in the component with #ViewChild.
#ViewChild("form")
private form: NgForm;
The submit method now takes a form parameter of type NgForm which is used to check if the form was valid before sending a request to the backend:
submit(form: NgForm) {
if (form.valid) {
this.categoriesService.createCategory(this.category).subscribe(
() => {
this.notificationService.add(notifications.category_saved, {name: this.category.name});
this.reset();
},
() => this.notificationService.add(notifications.save_category_failed)
);
} else {
this.notificationService.add(notifications.validation_errors);
}
}
Finally the reset method resets the form and the model so it can be re-entered to submit a next instance:
reset() {
this.form.resetForm();
this.category = {} as NewCategoryDto;
}
How do I apply any type of CSS to redux-form Field components? className and class are silently ignored:
<div>
<label>Name</label>
<div>
<Field
className="form-input"
name="formContactName"
component="input"
type="text"
placeholder="Person to contact"
/>
</div>
</div>
I was able to the apply the styles by creating a custom component:
<div>
<label>Name</label>
<div>
<Field
name="formContactName"
component={ customInput }
/>
</div>
</div>
but that's a major PITA and also largely negates the gains of using redux-form in the first place. Am I missing something? Note I added the className assignments directly in the custom component - I realize I can send them through as props in Field.
I tried setting input styles globally but they were ignored as well. The redux-form website docs tell you everything you need to know to use the rig but make no mention of CSS that I can see...
Thanks,
JB
Edit: this is not a duplicate - the answer pointed to uses a custom input component. As stated above, I can get that to work, but then there's really no need for redux-form in the first place.
#Jay: I was able to get this to work with a custom component by grabbing the code from the online docs:
class MyCustomInput extends Component {
render() {
const { input: { value, onChange } } = this.props
return (
<div>
<label htmlFor="formContactName" className="col-sm-2 control-label">Name:</label>
<div className="col-sm-10">
<input
id="formContactName"
placeholder="Person to contact"
className="form-control"
type="text"
/>
</div>
</div>
)
}
}
and then, in the redux-form Form code:
<div>
<label>Name</label>
<div>
<Field
name="formContactName"
component={ MyCustomInput }
/>
</div>
</div>
The bootstrap settings via className worked fine using this method.
All your custom props would be passed to the input component, so you can do
const CustomTextField = props => {
const { input, label, type, meta: { touched, error }, ...other } = props
return (
<TextField
label={label}
type={type}
error={!!(touched && error)}
helperText={touched && error}
{ ...input }
{ ...other }
/>
)
}
And then you can pass any props, including className to the CustomTextField
<Field
name="some"
component={CustomTextField}
className="css-applied"
/>
I have a react component in meteor with a webform in. The following code works fine and prints hello addtile in the console:
export default class NewTileForm extends Component {
addTile(event){
event.preventDefault();
console.log("hello addtile")
}
render(){
return(
<div>
<form className="tile-new" onSubmit={this.addTile.bind(this)}>
<input type="text"
ref="tile"
placeholder="Tile Title"/>
</form>
</div>
)
}
}
However, if I try to add a input to the webform I get no response from the console log:
export default class NewTileForm extends Component {
addTile(event){
event.preventDefault();
console.log("hello addtile")
}
render(){
return(
<div>
<form className="tile-new" onSubmit={this.addTile.bind(this)}>
<input type="text"
ref="tile"
placeholder="Tile Title"/>
<input type="text"
ref="company"
placeholder="Tile Company"/>
</form>
</div>
)
}
}
What am I missing?
This is "a browser thing" - you can't submit a form with the enter key and without a submit or button. No it's not react specific. To be honest, not sure why it worked with one - not sure the caveat there.
Anywho, Stackoverflow has lots of answers about tackling this issue (when you remove react as the problem):
Submitting a form by pressing enter without a submit button
I was just playing around a bit with Meteor.js when I ran into this strange issue, I have a form with two textfields, but somehow my event is not listening to the submit.
When I remove one textfield, everything works fine ...
Below is my template for the form:
<template name="new_timer">
<div class="timer timer--empty">
<form id="new_timer">
<input type="text" name="timer__name" class="timer__name" placeholder="Timer name">
<input type="text" name="timer__description" class="timer__description" placeholder="Timer description">
</form>
</div>
</template>
And on the client side:
Template.new_timer.events({
'submit form': function(e) {
console.log('new timer');
e.preventDefault();
}
})
This doens't seem to work, however when I change my template to the following, it works
<template name="new_timer">
<div class="timer timer--empty">
<form id="new_timer">
<input type="text" name="timer__name" class="timer__name" placeholder="Timer name">
</form>
</div>
</template>
Am I just overlooking something very basic here?
You might add an event like
'keyup form': function(e) {
if (e.keyCode === 13) {
// do something
}
}
Basically using a submit in a single page application is not adapted. In this kind of application everything is event based, you never reload a page so you never really 'submit' a form.
The 'form' tag becomes useless, most of developers (including me) are keeping it by habit but it is not required.
It is a bit late for an answer, I hope it can help somebody else!
I had similar problem, submit event does not work with more inputs without this:
<input type="submit" hidden="hidden">