onClick not working in alert? - javascript

I seem to be doing something wrong trying to listen to an event. I have given an alert in input box but even that doesn't seem to work. What could be the cause for that?
import React from 'react';
class PersonalDetails extends React.Component {
constructor(props) {
super(props);
console.log('PersonalDetails constructor......');
console.log(props);
this._handleTextChange = this._handleTextChange.bind(this);
this._handleSave = this._handleSave.bind(this);
}
_handleTextChange(event) {
this.props.onChange(event);
}
_handleSave(event) {
this.props.onSave(event);
}
render() {
return (
<div >
<h2 className="title" >Your Contact Details </h2>
<h2> Your name </h2>
<label for="Firstname">First Name: </label>
<input name="firstname"
value={this.props.firstname}
type="text"
onChange={this._handleTextChange}>
</input>
<input
type="image"
alt="Confirm"
name="confirm"
src="/myaccount/btnConfirm.gif"
//onClick={this._handleSave}/>
onClick={function(){alert("Hello World!")}}/>
<br/>
<br/>
<div className="line"></div>
</div>
);
}
}
export default PersonalDetails;

Related

Why css file of one component interacted with the css file of another component in ReactJS? How to handle it?

I am trying to make a website template with Reactjs. In the Jumbotron section i make subscription form and in the home section User Entry form. But the css of one component interacted with another's one. How can i handle it?
[1]: https://i.stack.imgur.com/Wd4OQ.png
User EntryJs:-
import React, { Component } from 'react'
import './User Entry.css'
class Form extends Component {
initialState = {
name: "",
age: "",
job: ""
}
state = this.initialState
changeHandler = event => {
const { name, value } = event.target
this.setState({
[name]: value
})
}
render() {
const { name, job, age } = this.state
return (
<form className="form-inline">
<div className="row">
<div className="col-md-3">
<div className="form-group">
<label htmlFor="name">Name:-</label>
<input type="text"
className="form-control"
name="name"
id="name"
value={name}
autoFocus
onChange={this.changeHandler} />
</div>
</div>
<div className="col-md-3">
<div className="form-group">
<label htmlFor="age">Age:-</label>
<input type="text"
className="form-control"
name="age"
id="age"
value={age}
autoFocus
onChange={this.changeHandler} />
</div>
</div>
<div className="col-md-3">
<div className="form-group">
<label htmlFor="job">Job:-</label>
<input type="text"
className="form-control"
name="job"
id="job"
value={job}
autoFocus
onChange={this.changeHandler} />
</div>
</div>
<div className="col-md-3"></div>
</div>
</form>
)
}
}
export default Form
Header JS:-
import React, { Component } from 'react'
import './Header.css'
import { Link, withRouter } from "react-router-dom";
class Header extends Component {
constructor(props) {
super(props)
this.state = {
email: ""
}
}
submitHandler = event => {
event.preventDefault();
alert(`Subscribed Email is : ${this.state.email}`);
}
changeHandler = event => {
this.setState({
email: event.target.value
})
}
render() {
return (
// Navbar Starts
<div>
<div className="row navbar">
<Link to="/" style={{textDecoration:'none'}}><div className="col-md-2 logo">ReactApp</div></Link>
<div className="col-md-6"></div>
<Link to="/" style={{textDecoration:'none'}}> <div className="col-md-1 link"> Home</div> </Link>
<Link to="/about" style={{textDecoration:'none'}}> <div className="col-md-1 link"> About</div> </Link>
<Link to="/counter" style={{textDecoration:'none'}}> <div className="col-md-1 link"> Counter </div></Link>
<Link style={{textDecoration:'none'}}><div className="col-md-1 link">Login</div></Link>
</div>
<div className="jumbotron text-center">
<h1>React-App</h1>
<p>We specialize in <strong>Web Development</strong></p>
{/* Subscribing form starts*/}
<form className="form-inline subscribingForm" onSubmit={this.submitHandler}>
<div className="input-group">
<input type="email"
className="form-control"
value={this.state.email}
onChange={this.changeHandler}
size="80"
placeholder="Email..."
required />
<div className="input-group-btn">
<input type="submit" value="Subscribe" className="subscribingBtn" />
</div>
</div>
</form>
{/* Subscribing form closes*/}
</div>
</div>
)
}
}
export default withRouter(Header);
Where is the .css file loaded, in the root component? It probably is loaded globally and is used on every component.Better use JSS (https://cssinjs.org/?v=v10.3.0)
In general react transpiles all the css and add it in to tag.
And as result you one file css conflicts with other.
If you want to avoid this, you can use modular css.
https://create-react-app.dev/docs/adding-a-css-modules-stylesheet/

How to call Promise.all in a handler function in React.js

I have two API calls that I am trying to make based on the input;
api.js
import axios from 'axios';
export const getWeather = input => {
};
export const getForecast = input => {
};
And in my React component:
import React, { Component } from 'react';
import WeatherDisplay from './WeatherDisplay';
import * as api from '../utils/api';
import dataTracker from '../utils/dataTracker';
import '../scss/app.scss';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
input: '',
weatherFromInput: null,
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
componentDidMount() {
console.dir(dataTracker);
}
handleChange(event) {
this.setState({
input: event.target.value,
});
}
// prettier-ignore
handleSubmit(event) {
event.preventDefault();
var promises = Promise.all(api.getWeather(this.state.input), api.getForecast(this.state.input))
promises.then(function(input) {
this.setState({ weatherFromInput: input[0], input: '' });
console.log("input", input[0]);
}.bind(this));
}
render() {
return (
<div className="container">
<div className="container">
<form name="weatherApp" onSubmit={this.handleSubmit}>
<h2>Open Weather App</h2>
<div className="row">
<div className="one-half column">
<label htmlFor="insertMode">Insert your location</label>
<input
name="zipcode"
className="u-full-width"
placeholder="please enter city or zipcode"
type="text"
autoComplete="off"
value={this.state.input}
onChange={this.handleChange}
/>
</div>
<div className="one-half column">
<label htmlFor="showMin">show minimum</label>
<input type="checkbox" />
<label htmlFor="showMax">show maximum</label>
<input type="checkbox" />
<label htmlFor="showMean">show mean</label>
<input type="checkbox" />
</div>
</div>
<div className="row">
<div className="two-half column">
<input type="submit" value="Submit" />
</div>
</div>
</form>
</div>
<div className="container">
<div className="row">
<div className="twelve columns">
{this.state.weatherFromInput !== null ? <WeatherDisplay weather={this.state.weatherFromInput} /> : null}
</div>
</div>
</div>
</div>
);
}
}
I get this error:
App.js:77 Uncaught (in promise) TypeError: undefined is not a function
Any help will be appreciated!
I believe Promise.all() needs an array, so:
var promises = Promise.all(api.getWeather(this.state.input), api.getForecast(this.state.input))
should be
var promises = Promise.all([api.getWeather(this.state.input), api.getForecast(this.state.input)])

Select List not working in ReactJS

I am facing a problem with the select list the onChange event is not being triggered. I can't set the value selected from the select list in this.state variable. Any help will be appreciated.
class SelectActivity extends React.Component{
render(){
return (
<select value={this.props.value} onChange={() =>{this.props.onSelect()}}> {this.props.items.map((item,index) =>{
return <option value={index}>{item}</option>})}
</select>
)
}
}
class Form extends React.Component{
constructor(props){
super(props)
this.state = {first:"",last:"",activity:0,restriction:{a:false,b:false,c:false}}
this.handleChange = this.handleChange.bind(this)
}
handleChange(event){
this.setState({[event.target.name]:event.target.value},()=>{console.log(this.state)})
}
handleCheck(key) {
return function (event) {
var restriction = Object.assign({},this.state.restriction);
restriction[key] = event.target.checked;
this.setState({restriction:restriction},()=>{console.log(this.state)});
}.bind(this);
}
render(){
return(
<form>
<div>
First Name<input name="first" value={this.state.first} onChange={this.handleChange}/>
</div>
<div>
Last Name<input name="last" value={this.state.last} onChange={this.handleChange}/>
</div>
<div>
<input type="checkbox" checked={this.state.restriction.a} onChange={this.handleCheck("a")}/>
<label>a) Dietarty Restriction</label>
</div>
<div>
<input type="checkbox" checked={this.state.restriction.b} onChange={this.handleCheck("b")}/>
<label>b) Physical Disablities</label>
</div>
<div>
<input type="checkbox" checked={this.state.restriction.c} onChange={this.handleCheck("c")}/>
<label>c) Medical Needs</label>
</div>
<div>
<SelectActivity name="activity" items={["Science Lab","Swimming","Painting","Cooking"]} value={this.state.activity} onSelect={this.handleChange}/>
</div>
</form>
)
}
}
ReactDOM.render(
<Form/>,
document.getElementById("root")
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.min.js"></script>
<div id="root"></div>
You are not sending the event that is triggered on change of your select input, but you are just calling the function with
onChange={ () => {this.props.onSelect()} }
Also, you didn't have any name assigned to your select input.
Please update your select input to:
<select
value={this.props.value}
name={this.props.name}
onChange={this.props.onSelect} // assigning the function, so it can be trigged with all argument
>
{
this.props.items.map((item,index) => {
return <option value={index}>{item}</option>
})
}
</select>
class SelectActivity extends React.Component{
render(){
return (
<select value={this.props.value} name={this.props.name} onChange={this.props.onSelect}> {this.props.items.map((item,index) =>{
return <option value={index}>{item}</option>})}
</select>
)
}
}
class Form extends React.Component{
constructor(props){
super(props)
this.state = {first:"",last:"",activity:0,restriction:{a:false,b:false,c:false}}
this.handleChange = this.handleChange.bind(this)
}
handleChange(event){
this.setState({[event.target.name]:event.target.value},()=>{console.log(this.state)})
}
handleCheck(key) {
return function (event) {
var restriction = Object.assign({},this.state.restriction);
restriction[key] = event.target.checked;
this.setState({restriction:restriction},()=>{console.log(this.state)});
}.bind(this);
}
render(){
return(
<form>
<div>
First Name<input name="first" value={this.state.first} onChange={this.handleChange}/>
</div>
<div>
Last Name<input name="last" value={this.state.last} onChange={this.handleChange}/>
</div>
<div>
<input type="checkbox" checked={this.state.restriction.a} onChange={this.handleCheck("a")}/>
<label>a) Dietarty Restriction</label>
</div>
<div>
<input type="checkbox" checked={this.state.restriction.b} onChange={this.handleCheck("b")}/>
<label>b) Physical Disablities</label>
</div>
<div>
<input type="checkbox" checked={this.state.restriction.c} onChange={this.handleCheck("c")}/>
<label>c) Medical Needs</label>
</div>
<div>
<SelectActivity name="activity" items={["Science Lab","Swimming","Painting","Cooking"]} value={this.state.activity} onSelect={this.handleChange}/>
</div>
</form>
)
}
}
ReactDOM.render(
<Form/>,
document.getElementById("root")
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.min.js"></script>
<div id="root"></div>

MDC-web not working as expected

import React, { Component } from "react";
import { MDCTextfield, MDCTextfieldFoundation } from "#material/textfield";
import { MDCFormField, MDCFormFieldFoundation } from "#material/form-field";
class Material extends React.Component {
constructor(props) {
super(props);
this.state = {};
this.textfield_ = new MDCTextfieldFoundation(
document.querySelector(".mdc-textfield")
);
}
componentDidMount() {
const textfield = new MDCTextfield(
document.querySelector(".mdc-textfield")
);
}
render() {
return (
<div>
<form>
<div className="mdc-textfield">
<input type="email" id="" className="mdc-textfield__input" />
<label htmlFor="email" className="mdc-textfield__label">
Email address1
</label>
</div>
<div className="mdc-textfield">
<input type="email" id="email" className="mdc-textfield__input" />
<label htmlFor="email" className="mdc-textfield__label">
Email address3
</label>
</div>
</form>
</div>
);
}
}
export default Material;
this is my page Material.js in my project and here i'm using material-components-web library.I want input to animate which was working fine.
but i wanted to use two inputs with same animation.i used two identical div of class mdc-textfield.But now only 1st div with class mdc-textfield is working fine but 2nd shows no animation.please help
This is because document.querySelector(".my_class") returns the first elements that it finds with "my_class". You can uses different ref names for the textfiels like this:
componentDidMount() {
const textfield_email = new MDCTextfield(this.refs.textfield_email);
const textfield_name = new MDCTextfield(this.refs.textfield_name);
}
...
<label ref="textfield_email" className="mdc-textfield ">
<input name="email" className="mdc-textfield__input" onChange={this.handleChange} value={this.state.email} />
<span className="mdc-textfield__label">Email</span>
</label>
<label ref="textfield_name" className="mdc-textfield ">
<input name="name" className="mdc-textfield__input" onChange={this.handleChange} value={this.state.name} />
<span className="mdc-textfield__label">Name</span>
</label>
I usually wrap the MDC Components in React JS Components. Here would be a very stripped down example for a textfield:
import React from 'react';
import { MDCTextfield } from '#material/textfield/dist/mdc.textfield';
class Textfield extends React.Component {
componentDidMount() {
const textfield = new MDCTextfield(this.refs.textfield);
}
static defaultProps = {
label: "",
className: "",
name: "",
onChange: function() {}
}
render() {
return (
<div className={this.props.className}>
{/* Text field component */}
<label ref="textfield" className="mdc-textfield " id={this.props.id} >
<input name={this.props.name} className="mdc-textfield__input" onChange={this.props.onChange} value={this.props.value} />
<span className="mdc-textfield__label">{this.props.label}</span>
</label>
</div>
);
}
}
export default Textfield
Then use like this:
<Textfield onChange={this.handleChange} value={this.state.value} label="email" name="email"></Textfield>
EDIT
If you want to use MDC with ReactJS and want an easy life, I would suggest using: RMWC (https://github.com/jamesmfriedman/rmwc) and hopefully soon the official React Wrapper from Google (https://github.com/material-components/material-components-web-react)

Keep code DRY on create/edit form

I have a few inputs that are used in my form for both create and update. I decided to make them a component.
// used for CRU on the event record
import React from 'react';
class Form extends React.Component {
render() {
return (
<div className="slds-form">
<div className="slds-form-element">
<label className="slds-form-element__label">Assigned To</label>
<div className="slds-form-element__control">
<input ref={(input) => this.assigned = input} type="text" className="slds-input" disabled/>
</div>
</div>
<div className="slds-form-element">
<label className="slds-form-element__label">Related To</label>
<div className="slds-form-element__control">
<input ref={(input) => this.related = input} type="text" className="slds-input" disabled/>
</div>
</div>
<div className="slds-form-element">
<label className="slds-form-element__label">Location</label>
<div className="slds-form-element__control">
<input ref={(input) => this.location = input} type="text" className="slds-input" />
</div>
</div>
<div className="slds-form-element">
<label className="slds-form-element__label">Event Start</label>
<div className="slds-form-element__control">
<input ref={(input) => this.start = input} type="text" className="slds-input" />
</div>
</div>
<div className="slds-form-element">
<label className="slds-form-element__label">Event End</label>
<div className="slds-form-element__control">
<input ref={(input) => this.end = input} type="text" className="slds-input" />
</div>
</div>
<div className="slds-form-element">
<label className="slds-form-element__label">Contact</label>
<div className="slds-form-element__control">
<input ref={(input) => this.contact = input} type="text" className="slds-input" disabled/>
</div>
</div>
<button type="button" className="slds-button slds-button--neutral">Cancel</button>
<button type="submit" className="slds-button slds-button--brand">{this.props.buttonLabel}</button>
</div>
);
}
}
export default Form;
I then attempted to use this component in my <Create /> component.
// used for Create on the event record
import React from 'react';
import Form from './Form';
class Create extends React.Component {
createEvent(e) {
console.log("createEvent() has fired.");
e.preventDefault();
const event = {
assigned: this.assigned.value,
related: this.related.value,
location: this.location.value,
start: this.start.value,
end: this.end.value,
contact: this.contact.value
}
console.log(event);
}
render() {
return (
<form onSubmit={(e) => this.createEvent(e)}>
<Form buttonLabel="Create" />
</form>
);
}
}
export default Create;
When I try to hit the Create button on my <Create /> component I get an error
Uncaught TypeError: Cannot read property 'value' of undefined
at Create.createEvent (webpack:///./src/components/Event/Create.js?:42:32)
at onSubmit (webpack:///./src/components/Event/Create.js?:59:27)
at Object.ReactErrorUtils.invokeGuardedCallback (webpack:///./~/react/lib/ReactErrorUtils.js?:70:16)
at executeDispatch (webpack:///./~/react/lib/EventPluginUtils.js?:89:21)
at Object.executeDispatchesInOrder (webpack:///./~/react/lib/EventPluginUtils.js?:112:5)
at executeDispatchesAndRelease (webpack:///./~/react/lib/EventPluginHub.js?:44:22)
at executeDispatchesAndReleaseTopLevel (webpack:///./~/react/lib/EventPluginHub.js?:55:10)
at Array.forEach (native)
at forEachAccumulated (webpack:///./~/react/lib/forEachAccumulated.js?:25:9)
at Object.processEventQueue (webpack:///./~/react/lib/EventPluginHub.js?:231:7)
I then check the console and see the refs belong in my <Form /> component, and not my <Create /> component.
Is there a way to pass the refs from my child component, <Form />, to its parent, <Create />?
That's a lot of refs! Good news, you really don't need them, at all. As a very very general rule, you should only be using refs if you are interacting with an external library that doesn't "understand" React (d3, Greensock, TinyMCE, etc).
Tackling it in an uncontrolled way can be done like:
const User = (props) => (
<div>
<input name="foo" className="form-control" />
<input name="foo2" className="form-control" />
<button type="submit" className="btn btn-primary">{props.buttonLabel}</button>
</div>
);
class App extends React.Component {
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
}
onChange(e) {
this.setState({
[e.target.name]: e.target.value,
});
}
onSubmit(e) {
e.preventDefault();
console.log(this.state);
}
render() {
return (
<div className="container">
<br />
<form onChange={this.onChange} onSubmit={this.onSubmit}>
<User buttonLabel="Create"/>
</form>
</div>
);
}
};
ReactDOM.render(<App />, document.getElementById('app'));
Codepen example:
http://codepen.io/cjke/pen/zNXxga?editors=0010

Categories

Resources