mirror of
https://github.com/aspnet/JavaScriptServices.git
synced 2025-12-22 17:47:53 +00:00
Add example of server and client validation for React
This commit is contained in:
30
samples/react/ReactGrid/Controllers/PeopleApiController.cs
Normal file
30
samples/react/ReactGrid/Controllers/PeopleApiController.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Mvc;
|
||||||
|
|
||||||
|
namespace ReactExample.Controllers
|
||||||
|
{
|
||||||
|
public class PeopleApiController : Controller
|
||||||
|
{
|
||||||
|
[HttpPut("api/people/{personId:int}")]
|
||||||
|
public async Task<ActionResult> UpdatePerson([FromBody] PersonDto person)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid) {
|
||||||
|
return HttpBadRequest(ModelState);
|
||||||
|
} else {
|
||||||
|
return new HttpOkResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PersonDto {
|
||||||
|
public string name { get; set; }
|
||||||
|
public string city { get; set; }
|
||||||
|
public string state { get; set; }
|
||||||
|
public string country { get; set; }
|
||||||
|
public string company { get; set; }
|
||||||
|
|
||||||
|
[Range(1, 10)]
|
||||||
|
public int favoriteNumber { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import Griddle from 'griddle-react';
|
import Griddle from 'griddle-react';
|
||||||
import { CustomPager } from './CustomPager.jsx';
|
import { CustomPager } from './CustomPager.jsx';
|
||||||
import { fakeData } from '../data/fakeData.js';
|
import { fakeData } from '../data/fakeData.js';
|
||||||
import { columnMeta } from '../data/columnMeta.js';
|
import { columnMeta } from '../data/columnMeta.jsx';
|
||||||
const resultsPerPage = 10;
|
const resultsPerPage = 10;
|
||||||
|
|
||||||
export class PeopleGrid extends React.Component {
|
export class PeopleGrid extends React.Component {
|
||||||
@@ -13,6 +13,7 @@ export class PeopleGrid extends React.Component {
|
|||||||
<h1>People</h1>
|
<h1>People</h1>
|
||||||
<div id="table-area">
|
<div id="table-area">
|
||||||
<Griddle results={fakeData}
|
<Griddle results={fakeData}
|
||||||
|
columns={columnMeta.map(x => x.columnName)}
|
||||||
columnMetadata={columnMeta}
|
columnMetadata={columnMeta}
|
||||||
resultsPerPage={resultsPerPage}
|
resultsPerPage={resultsPerPage}
|
||||||
tableClassName="table"
|
tableClassName="table"
|
||||||
|
|||||||
57
samples/react/ReactGrid/ReactApp/components/PersonEditor.jsx
Normal file
57
samples/react/ReactGrid/ReactApp/components/PersonEditor.jsx
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Formsy from 'formsy-react';
|
||||||
|
import { Input } from 'formsy-react-components';
|
||||||
|
import { fakeData } from '../data/fakeData.js';
|
||||||
|
|
||||||
|
export class PersonEditor extends React.Component {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.state = { savedChanges: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange() {
|
||||||
|
this.setState({ savedChanges: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
submit(model, reset, setErrors) {
|
||||||
|
PersonEditor.sendJson('put', `/api/people/${ this.props.params.personId }`, model).then(response => {
|
||||||
|
if (response.ok) {
|
||||||
|
this.setState({ savedChanges: true });
|
||||||
|
} else {
|
||||||
|
// Parse server-side validation errors from the response and display them
|
||||||
|
response.json().then(setErrors);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
var personId = parseInt(this.props.params.personId);
|
||||||
|
var person = fakeData.filter(p => p.id === personId)[0];
|
||||||
|
var notificationBox = this.state.savedChanges
|
||||||
|
&& <div className="alert alert-success"><b>Done!</b> Your changes were saved.</div>;
|
||||||
|
|
||||||
|
return <div className='row'>
|
||||||
|
<div className='page-header'>
|
||||||
|
<h1>Edit { person.name }</h1>
|
||||||
|
</div>
|
||||||
|
<Formsy.Form ref='form' className='form-horizontal' onChange={ this.onChange.bind(this) } onValidSubmit={ this.submit.bind(this) }>
|
||||||
|
<Input name='name' label='Name' value={ person.name } required />
|
||||||
|
<Input name='city' label='City' value={ person.city } required />
|
||||||
|
<Input name='state' label='State' value={ person.state } required />
|
||||||
|
<Input name='country' label='Country' value={ person.country } required />
|
||||||
|
<Input name='company' label='Company' value={ person.company } required />
|
||||||
|
<Input name='favoriteNumber' label='Favorite Number' value={ person.favoriteNumber } required validations="isInt" validationError="Must be a number" />
|
||||||
|
{ notificationBox }
|
||||||
|
<button type='submit' className='btn btn-primary'>Save</button>
|
||||||
|
</Formsy.Form>
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
static sendJson(method, url, object) {
|
||||||
|
return fetch(url, {
|
||||||
|
method: method,
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(object)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Router, Route } from 'react-router';
|
import { Router, Route } from 'react-router';
|
||||||
import { PeopleGrid } from './PeopleGrid.jsx';
|
import { PeopleGrid } from './PeopleGrid.jsx';
|
||||||
|
import { PersonEditor } from './PersonEditor.jsx';
|
||||||
|
|
||||||
export default class ReactApp extends React.Component {
|
export default class ReactApp extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
@@ -8,6 +9,7 @@ export default class ReactApp extends React.Component {
|
|||||||
<Router history={this.props.history}>
|
<Router history={this.props.history}>
|
||||||
<Route path="/" component={PeopleGrid} />
|
<Route path="/" component={PeopleGrid} />
|
||||||
<Route path="/:pageIndex" component={PeopleGrid} />
|
<Route path="/:pageIndex" component={PeopleGrid} />
|
||||||
|
<Route path="/edit/:personId" component={PersonEditor} />
|
||||||
</Router>
|
</Router>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,12 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Link } from 'react-router';
|
||||||
|
|
||||||
|
class RowActionsComponent extends React.Component {
|
||||||
|
render() {
|
||||||
|
return <Link to={'/edit/' + this.props.rowData.id}>Edit</Link>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var columnMeta = [
|
var columnMeta = [
|
||||||
{
|
{
|
||||||
"columnName": "id",
|
"columnName": "id",
|
||||||
@@ -40,6 +49,13 @@ var columnMeta = [
|
|||||||
"order": 7,
|
"order": 7,
|
||||||
"locked": false,
|
"locked": false,
|
||||||
"visible": true
|
"visible": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"columnName": "actions",
|
||||||
|
"order": 8,
|
||||||
|
"locked": true,
|
||||||
|
"visible": true,
|
||||||
|
"customComponent": RowActionsComponent
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<div id="react-app" asp-react-prerender-module="ReactApp/components/ReactApp.jsx"></div>
|
<div id="react-app" asp-react-prerender-module="ReactApp/components/ReactApp.jsx"></div>
|
||||||
|
|
||||||
@section scripts {
|
@section scripts {
|
||||||
<script src="bundle.js"></script>
|
<script src="/bundle.js"></script>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,9 @@
|
|||||||
<link rel="stylesheet" href="/main.css" />
|
<link rel="stylesheet" href="/main.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@RenderBody()
|
<div class="container">
|
||||||
|
@RenderBody()
|
||||||
|
</div>
|
||||||
@RenderSection("scripts", required: false)
|
@RenderSection("scripts", required: false)
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"babel-core": "^5.8.29",
|
"babel-core": "^5.8.29",
|
||||||
"bootstrap": "^3.3.5",
|
"bootstrap": "^3.3.5",
|
||||||
|
"formsy-react": "^0.17.0",
|
||||||
|
"formsy-react-components": "^0.6.3",
|
||||||
"griddle-react": "^0.2.14",
|
"griddle-react": "^0.2.14",
|
||||||
"history": "^1.12.6",
|
"history": "^1.12.6",
|
||||||
"react": "^0.14.0",
|
"react": "^0.14.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user