React Custom Attributes from Event Object Show Up as Undefined - reactjs

I am a beginner learning React and have been trying to create two TextField's with MUI where I have two strings in the state to store the subject and number both as strings. I want to use one function to change the state of either the subject or number based on which TextField is changed. I created a custom attribute called data-id in each TextField and called console.log(event.target.dataset.id); within my handleSearchChange(event){...} function. For some reason each time I type a value into either TextField it just says undefined in the console.
Some resources I have tried
https://reactjs.org/docs/events.html
https://www.pluralsight.com/guides/how-to-access-custom-attributes-from-aevent-object-in-react
https://www.codegrepper.com/code-examples/javascript/react+get+data+attribute+from+element
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import { TextField } from '#mui/material';
class ClassSearch extends React.Component {
constructor(props) {
super(props);
this.handleSearchChange = this.handleSearchChange.bind(this);
};
handleSearchChange(event){
console.log(event.target.dataset.id);
}
render() {
return(
<div>
<h1>Classes Search</h1>
<TextField
onChange={this.handleSearchChange}
data-id = "subject"
type = "search"
id="outlined-basic"
variant="outlined"
/>
<TextField
onChange={this.handleSearchChange}
data-id = "number"
type = "search"
id="outlined-basic"
variant="outlined"
defaultValue={this.state.number}
/>
</div>
);
}
}
ReactDOM.render(
<React.StrictMode>
<ClassSearch />
</React.StrictMode>,
document.getElementById('root')
);

Related

TextField Material-ui are not working properly reactjs and windows 10

I am trying to replicate TextField example from material-ui this is how is suppose to be
This is how should be
but i got this
[marks in red is to show extra line that all TextFiel has2
do you know the reasons?
Please write a component like TextFieldExample and use this in app Component.
import React from 'react';
import TextField from '#material-ui/core/TextField';
export default function TextFieldExample(props) {
return (
<TextField id="standard-basic" label={props.label} variant={props.variant} />
);
}
Here is the App Component Code that includes how you can use TextFieldExample Component. Here you can pass label and variant as an props and use it in TextFieldExample Component
import React from "react";
import ReactDOM from 'react-dom'
import TextFieldExample from "./TextFieldExample";
class App extends React.Component {
render() {
return (
<div>
<TextFieldExample label="Standard"/>
<TextFieldExample label="Filled" variant="filled" />
<TextFieldExample label="Outlined" variant="outlined" />
</div>
);
}
}
ReactDOM.render(<App/>, document.getElementById("root"));
export default App;
I include the output image for your understanding.

Add basic controls eg label and text box to people picker with react in Sharepoint Online

I have the code below to render a people picker in Sharepoint online using the React Framework. How do I add basic controls such as labels, textboxes and buttons.
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '#microsoft/sp-core-library';
import { Label } from 'office-ui-fabric-react/lib/Label';
import { TextField } from 'office-ui-fabric-react/lib/TextField';
import { getId } from 'office-ui-fabric-react/lib/Utilities';
export interface IPnPPeoplePickerWebPartProps {
description: string;
}
export default class PnPPeoplePickerWebPart extends
BaseClientSideWebPart<IPnPPeoplePickerWebPartProps> {
public render(): void {
const element: React.ReactElement<IPnPPeoplePickerProps > = React.createElement(
PnPPeoplePicker,
{
description: this.properties.description,
context: this.context
}
);
ReactDom.render(element, this.domElement);
}
Here is the code for a label. I just don't know where to insert it. It doesn't work in the render method.
export const LabelBasicExample = () => {
// Use getId() to ensure that the ID is unique on the page.
// (It's also okay to use a plain string without getId() and manually ensure uniqueness.)
const textFieldId = getId('anInput');
return (
<div>
<Label>I'm a Label</Label>
<Label disabled={true}>I'm a disabled Label</Label>
<Label required={true}>I'm a required Label</Label>
<Label htmlFor={textFieldId}>A Label for An Input</Label>
<TextField id={textFieldId} />
</div>
);
};
I suggest you create a new react component to wrap your components.
Also, your render() method in the first block of code is a little strange... Look at the second block, there's no call to ReactDom.render.
Usually that call is only on my index.tsx file. Something like this:
ReactDOM.render(<App />, document.getElementById('root'));
So inside the App.tsx (in the component render method) I would do something like this:
return (
<div>
<mycomponent1/>
<mycomponent2/>
<pnpcomponent/>
... many other components...
</div>)

ReactComponent Button value won't render on my react app

I've got a simple React App going on. My index.js file looks, of course, like this:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();
Going deeper, my App.js file declares an App extends Compoennt class, which contains my to-be-rendered elements and their functions:
import React, { Component } from "react";
import logo from "./SmartTransit_logo.png";
import MyButton from "./components/MyButton";
import "./App.css";
import { isWallet, helloWorld } from "./services/neo-service";
class App extends Component {
state = {
inputValue: ""
};
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Smart Transit Live Demo</h1>
</header>
<div style={{ width: 500, margin: "auto", marginTop: 10 }}>
<MyButton
buttonText="My Button"
onClick={ params => {helloWorld();}}
/>
</div>
</div>
);
}
}
export default App;
And the declaration of MyButton from /components/MyButton:
import React, { Component } from "react";
import PropTypes from "prop-types";
class MyButton extends Component {
render() {
return (
<button className="MyButton"
value = {this.props.buttonText}
>
{this.props.children}
</button>
);
}
}
MyButton.propTypes = {
buttonText: PropTypes.string.isRequired,
onClick: PropTypes.func.isRequired,
};
export default MyButton;
Finally, the declaration for helloWorld() is done like so (NOTE: neon-js is an npm package I'm using):
import { wallet } from "#cityofzion/neon-js";
export function isWallet(address) {
console.log(wallet.isAddress(address));
return wallet.isAddress(address);
}
export function helloWorld() {
console.log("Hello world");
return 1;
}
My problem is that the resulting Button doesn't get its value text rendered, and although it gets the CSS code for it just fine, it appears empty!
Not only that, but pressing it doesn't log a "Hello World" in the console, as it should, so it's even disconnected from its onClick function.
Any idea on what I'm doing wrong?
Buttons don't receive a "value" prop. The text inside of the button element is what gives it its text.
The button does appear to accept children to use as button text, but no children is actually being passed down to it. this.props.children is the content between JSX tags when the component is rendered.
React doesn't add the event handlers to elements automatically. You have to pass them along yourself in order for them to be properly triggered.
With that in mind, here's how you should render your button in App:
<MyButton onClick={() => helloWorld()}>
My Button
</MyButton>
And here's how MyButton's code should look:
class MyButton extends Component {
render() {
return (
<button className="MyButton" onClick={this.props.onClick}>
{this.props.children}
</button>
)
}
}
As you can see, the buttonText prop is no longer required; that's what the children prop is for.
You need to define super(props) in class constructor when you are going to use this.props
constructor(props) {
super(props);
}
Define this in MyButton component.
The problem is, you are not calling onClick method from mybutton component and button take it's value between it's opening and closing tag.
Use this code:
this.props.onClick()}> {this.props.buttonText}

Controlled TextField loosing focus after every character from keyboard

Whenever I input a character into the field the focus goes away.
How do I correct that?
"use strict"
import React from "react";
import createReactClass from "create-react-class";
import RaisedButton from 'material-ui/RaisedButton';
import TextField from 'material-ui/TextField';
import {Card, CardActions, CardHeader, CardMedia, CardTitle, CardText} from 'material-ui/Card';
export var Config = createReactClass({
setConfig: function() {
localStorage.serverUrl=this.owner.state.serverUrl;
location.reload();
},
setUrl: function(evt) {
this.owner.setState({serverUrl: evt.target.value});
},
render: function() {
var {owner}=this.props;
this.owner=owner;
return <div>
<CardTitle title={__("Server")} />
<CardText>
<TextField id="serverUrl" floatingLabelText={__("Server URL")} value={owner.state.serverUrl} onChange={this.setUrl} />
</CardText>
<CardActions>
<RaisedButton label={__("Apply")} onTouchTap={this.setConfig} />
</CardActions>
</div>;
}
});
There are of course other elements on the root of the application (the actual logic is a bit more complicated, here only the structure):
<MuiThemeProvider muiTheme={muiTheme}>
<div>
<AppBar title={__("Demo")}
iconElementRight={right}
onRightIconButtonClick={this.logon}
onLeftIconButtonClick={this.toggleMenu} />
<Drawer open={this.state.menuOpen}
docked={false}
onLeftIconButtonTouchTap={this.toggleMenu}
onTouchTap={this.toggleMenu}>
<RaisedButton onTouchTap={this.toggleMenu} label={__("Menu")} />
<Menu>
<MenuEntry owner={this} value="/config" title={__("Server")} />
<MenuEntry owner={this} value="/logon" title={__("Logon")} />
<Divider />
<MenuEntry owner={this} value="/about" title={__("About")} />
</Menu>
</Drawer>
<Paper>
<Config owner={this} />
</Paper>
</div>
</MuiThemeProvider>;
Here the implementation MenuEntry
"use strict";
import React from "react";
import createReactClass from "create-react-class";
import MenuItem from 'material-ui/MenuItem';
export var MenuEntry=createReactClass({
onChange: function() {
this.owner.setState({menuOpen: false, systemMenuOpen: false, location: this.value});
},
render: function() {
var {title, owner, value, color}=this.props;
this.owner=owner;
this.value=value;
var selected=(owner.state.location==value);
return <MenuItem checked={selected} onTouchTap={this.onChange} backgroundcolor={color}>
{title}
</MenuItem>;
}
});
Versions:
Material-UI: 0.20
React: 16.2.0
Browser: Chrome 63.0.3239.123 (Mac & Windows & Android)
FF 57.0.4 (Mac & Windows)
As mentionned in material-ui docs about the onChange prop of <TextField> :
Signature: function(event: object, newValue: string) => void
event: Change event targeting the text field.
newValue: The new value of the text field.
So i think you should remove setUrl method and change <TextField> like this (no need to use onBlur) :
<TextField id="serverUrl" floatingLabelText={__("Server URL")} value={owner.state.serverUrl} onChange={(evt, value) => this.owner.setState({ serverUrl: value })} />
More comments about the code :
I'm maybe wrong but calling the setState method of a parent component passed in props seems a bad practice to me, you should consider handling the state of the input in the state of Config component.
Also, you're using create-react-class instead of a class component, it seems useless to use it in your case (you're using es6 import while create-react-class is used to build react app without es6) see official docs for more infos.
Edit : I'm able to reproduce a minimal working example :
Config.js :
import React from 'react';
import createReactClass from 'create-react-class';
import TextField from 'material-ui/TextField';
export var Config = createReactClass({
setUrl: function(evt, value) {
this.owner.setState({ serverUrl: value });
},
render: function() {
var { owner } = this.props;
this.owner = owner;
return (
<div>
<TextField
id="serverUrl"
floatingLabelText={'Server URL'}
value={owner.state.serverUrl}
onChange={this.setUrl}
/>
</div>
);
},
});
index.js :
import React, { Component } from 'react';
import createReactClass from 'create-react-class';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import { render } from 'react-dom';
import { Config } from './Config';
var App = createReactClass({
getInitialState: function() {
return { serverUrl: 'test' };
},
render: function() {
console.log(this.state.serverUrl);
return (
<MuiThemeProvider>
<Config owner={this} />
</MuiThemeProvider>
);
},
});
render(<App />, document.querySelector('#root'));
I guess the issue is with Textfield value props and onBlur. The state value that you are passing to value prop is incorrect i.e., value={owner.state.serverUrl} it should be value={this.owner.state.serverUrl}.
The onBlur fuction doesn't exist in your code but you trying to call onBlur={this.onBlur} which should be removed from TextField component. It seems onBlur is not a valid prop to TextField as per material UI docs
<TextField id="serverUrl" floatingLabelText={__("Server URL")} value={this.owner.state.serverUrl} onChange={(evt, value) => this.owner.setState({ serverUrl: value })} />

React bootstrap - Uncaught TypeError: Cannot read property 'toUpperCase' of undefined

My class is as follows:
import React from 'react';
import Input from 'react-bootstrap';
export default class FormWidget1 extends React.Component {
render() {
if (!this.props.fields) {
console.log('no fields passed');
}
else {
console.log(this.props.fields.length);
console.log(this.props.fields);
}
var formFieldList = this.props.fields.map(function(field) {
console.log("iterating");
return (
<Input type="text" placeholder="testing" label="label" />
);
});
return (
<div>
<form action="">
{formFieldList}
</form>
</div>
);
}
}
If I replace <Input /> with <input /> then there's no error.
The stacktrace only shows my app.jsx which is not useful.
What is wrong?
You need to de-structure your import of the Input jsx component.
import {Input} from 'react-bootstrap';
What this does is render to var Input = require('react-bootstrap').Input; Whereas what you previously had would render to var Input = require('react-bootstrap');
It does mention this in the documentation for React Bootstrap here:
https://react-bootstrap.github.io/getting-started.html#es6
Edit: A good hint is that the error you're getting from React is a typical error when you're trying to render as a component, something which is actually not a react component. So basically you were trying to render the object that react bootstrap returns containing all components, rather than the actual input component you wanted.

Resources