今からお前んちこいよ

多摩川沿いにて細々とお勉強。

Laravel5.5 + React 超入門チュートリアル その4 - ToDo編集/削除

f:id:hakopako03:20180117210816p:plain

ToDo編集ページをつくる

resources/assets/js/components/Edit.js を作る

// Edit.js

import React, {Component} from 'react';
import axios from 'axios';
import { Link } from 'react-router';

class Edit extends Component {
  constructor(props) {
    super(props);
    this.state = {title: '', description: ''};
  }

  componentDidMount(){
    axios.get("http://localhost:8000/api/todos/" + this.props.params.id)
    .then(response => {
      this.setState({ 
        title: response.data.title, 
        description: response.data.description 
      });
    })
    .catch(function (error) {
      console.log(error);
    })
  }
  handleChangeTitle(e){
    this.setState({
      title: e.target.value
    })
  }
  handleChangeDesc(e){
    this.setState({
      description: e.target.value
    })
  }

  handleSubmit(event) {
    event.preventDefault();
    const products = {
      title: this.state.title,
      description: this.state.description
    }
    let uri = 'http://localhost:8000/api/todos/' + this.props.params.id
    axios.patch(uri, products).then((response) => {
          this.props.history.push('/list');
    });
  }
  render(){
    return (
    <div>
      <h1>Edit ToDo</h1>
      <div className="row">
        <div className="col-md-10"></div>
        <div className="col-md-2">
          <Link to="/list">&lt;&lt; Back to List</Link>
        </div>
      </div>
      <form onSubmit={this.handleSubmit.bind(this)}>
        <div className="form-group">
          <label>Title</label>
          <input type="text"
            className="form-control"
            value={this.state.title}
            onChange={this.handleChangeTitle.bind(this)} />
        </div>

        <div className="form-group">
          <label name="product_price">Item Price</label>
          <input type="text" className="form-control"
            value={this.state.description}
            onChange={this.handleChangeDesc.bind(this)} />
        </div>

        <div className="form-group">
          <button className="btn btn-primary">Update</button>
        </div>
      </form>
    </div>
    )
  }
}
export default Edit;

resources/assets/js/app.js にルートを追加

// app.js

  import List from './components/List';
+ import Edit from './components/Edit';

~~~

          <Route path="/list" component={List} />
+         <Route path="/:id/edit" component={Edit} />

resources/assets/js/components/TableRow.js

// TableRow.js

  import React, { Component } from 'react';
+ import { Link } from 'react-router';

~~~~

- <button className="btn btn-primary">Edit</button>
+ <Link to={"/todos/"+this.props.obj.id + "/edit"} className="btn btn-primary">Edit</Link>

ToDoを削除する

resources/assets/js/components/TableRow.js のDeleteボタンに処理を追加する

// TableRow.js

import React, { Component } from 'react';
import { Link, browserHistory } from 'react-router';

class TableRow extends Component {
  constructor(props) {
      super(props);
  }
  handleSubmitDeletion(event) {
    event.preventDefault();
    let uri = "http://localhost:8000/api/todos/" + this.props.obj.id
    axios.delete(uri);
    browserHistory.push('/');
  }
  render() {
    return (
      <tr>
        <td>
          {this.props.obj.id}
        </td>
        <td>
          {this.props.obj.title}
        </td>
        <td>
          {this.props.obj.description}
        </td>
        <td>
          <Link to={"/todos/"+this.props.obj.id + "/edit"} className="btn btn-primary">Edit</Link>
        </td>
        <td>
          <form onSubmit={this.handleSubmitDeletion.bind(this)}>
           <input type="submit" value="Delete" className="btn btn-danger"/>
          </form>
        </td>
      </tr>
    )
  }
}

export default TableRow;

これで削除ボタン押下でToDoの削除処理が行われる。

f:id:hakopako03:20180117214531g:plain

 


React編:
(その1)http://www.hakopako.net/entry/2018/01/17/220538
(その2)http://www.hakopako.net/entry/2018/01/17/220620
(その3)http://www.hakopako.net/entry/2018/01/17/220707
(その4)http://www.hakopako.net/entry/2018/01/17/220730

API編:
Laravel5.5 で REST API 入門チュートリアル - 今からお前んちこいよ

Laravel5.5 + React 超入門チュートリアル その3 - ToDo一覧

f:id:hakopako03:20180117204825p:plain

一覧ページを作る

resources/assets/js/components/List.js を作る

// List.js

import React, {Component} from 'react';
import axios from 'axios';
import { Link } from 'react-router';
import TableRow from './TableRow';

class List extends Component {
  constructor(props) {
    super(props);
    this.state = {data: ''}
  }
  componentDidMount(){
    axios.get('http://localhost:8000/api/todos')
    .then(response => {
      this.setState({ data: response.data })
    })
    .catch(function (error) {
      console.log(error)
    })
  }
  tabRow(){
    if(this.state.data instanceof Array){
      return this.state.data.map(function(object, i){
        return <TableRow obj={object} key={i} />
      })
    }
  }

  render(){
    return (
      <div>
        <h1>ToDo List</h1>

        <div className="row">
          <div className="col-md-10"></div>
          <div className="col-md-2">
            <Link to="/create">+ New ToDo</Link>
          </div>
        </div><br />

        <table className="table table-hover">
            <thead>
            <tr>
                <td>ID</td>
                <td>Title</td>
                <td>Description</td>
                <td>Actions</td>
            </tr>
            </thead>
            <tbody>
              {this.tabRow()}
            </tbody>
        </table>
    </div>
    )
  }
}
export default List;

resources/assets/js/components/TableRow.js を作る

// TableRow.js

import React, { Component } from 'react';

class TableRow extends Component {
  render() {
    return (
      <tr>
        <td>
          {this.props.obj.id}
        </td>
        <td>
          {this.props.obj.title}
        </td>
        <td>
          {this.props.obj.description}
        </td>
        <td>
          <button className="btn btn-primary">Edit</button>
        </td>
        <td>
          <button className="btn btn-danger">Delete</button>
        </td>
      </tr>
    )
  }
}

export default TableRow;

resources/assets/js/app.js

  import Create from './components/Create';
+ import List from './components/List';

~~~
          <Route path="/create" component={Create} />
+         <Route path="/list" component={List} />
        </Route>

resources/assets/js/components/Main.js

- <li><a href="#">List</a></li>
+ <li><Link to="list">List</Link></li>

resources/assets/js/components/Create.js での新規TODO作成後の遷移を作る

-       // browserHistory.push('/list')
+       browserHistory.push('/list')

http://localhost:8000/list で表示される

f:id:hakopako03:20180117204710g:plain

 


React編:
(その1)http://www.hakopako.net/entry/2018/01/17/220538
(その2)http://www.hakopako.net/entry/2018/01/17/220620
(その3)http://www.hakopako.net/entry/2018/01/17/220707
(その4)http://www.hakopako.net/entry/2018/01/17/220730

API編:
Laravel5.5 で REST API 入門チュートリアル - 今からお前んちこいよ

Laravel5.5 + React 超入門チュートリアル その2 - ToDo作成

f:id:hakopako03:20180117144949p:plain

Create ページを作る

resources/assets/js/components/Create.js

// Create.js

import React, {Component} from 'react';

class Create extends Component {
    render() {
      return (
      <div>
        <h1>Create a ToDo</h1>
        <form>
          <div className="row">
            <div className="col-md-6">
              <div className="form-group">
                <label>Title:</label>
                <input type="text" className="form-control" />
              </div>
            </div>
            </div>
            <div className="row">
              <div className="col-md-6">
                <div className="form-group">
                  <label>Description:</label>
                  <input type="text" className="form-control col-md-6" />
                </div>
              </div>
            </div><br />
            <div className="form-group">
              <button className="btn btn-primary">Create</button>
            </div>
        </form>
  </div>
      )
    }
}
export default Create;

resources/assets/js/app.js にルーティング情報を追記

// app.js

require('./bootstrap');
import React from 'react';
import { render } from 'react-dom';
import { Router, Route, browserHistory } from 'react-router';
import Main from './components/Main';
import Create from './components/Create';

render(
  <Router history={browserHistory}>
      <Route path="/" component={Main} >
        <Route path="/create" component={Create} />
      </Route>
    </Router>,
        document.getElementById('example'));

resources/assets/js/components/Main.js のヘッダー部分のリンク先を修正

-  <li><a href="#">Create</a></li>
+  <li><Link to="create">Create</Link></li>

サーバを起動して確認
メニューからの遷移はできるが、リロードなどするとNotFound となる状態。
f:id:hakopako03:20180117141045g:plain

URLからでもアクセス可能にする

Laravel側の設定が必要になる。
routes/web.php

// web.php

Route::get('/{any?}', function () {
    return view('welcome');
})->where('any', ".*");

/ 以外のURLにアクセスがあった場合にもwelcome.blade.php を表示するようにする。 これで、リロードなどでも動作する。他のAPIなどのルーティングの下に書く。でないとAPIのURLもwelcomeへのページと判断されてしまう。

f:id:hakopako03:20180117144842g:plain

Ajax で Post する

axios をつかって通信する。

resources/assets/js/components/Create.js

// Create.js

import React, {Component} from 'react';
import { browserHistory } from 'react-router';

class Create extends Component {
  constructor(props){
    super(props)
    this.state = {title: '', description: ''}
  }
  handleChangeTitle(e){
    this.setState({title: e.target.value})
  }
  handleChangeDesc(e){
    this.setState({description: e.target.value})
  }
  handleSubmit(e){
    e.preventDefault()
    const todo = {
      title: this.state.title,
      description: this.state.description
    }
    let uri = 'http://localhost:8000/api/todos'
    axios.post(uri, todo).then((response) => {
      // browserHistory.push('/list')
      console.log("success")
    })
  }
  render() {
    return (
    <div>
      <h1>Create a ToDo</h1>
      <form onSubmit={this.handleSubmit.bind(this)}>
        <div className="row">
          <div className="col-md-6">
            <div className="form-group">
              <label>Title:</label>
              <input type="text" className="form-control" onChange={this.handleChangeTitle.bind(this)}/>
            </div>
          </div>
          </div>
          <div className="row">
            <div className="col-md-6">
              <div className="form-group">
                <label>Description:</label>
                <input type="text" className="form-control col-md-6" onChange={this.handleChangeDesc.bind(this)}/>
              </div>
            </div>
          </div><br />
          <div className="form-group">
            <button className="btn btn-primary">Create</button>
          </div>
      </form>
    </div>
    )
  }
}
export default Create;

 


React編:
(その1)http://www.hakopako.net/entry/2018/01/17/220538
(その2)http://www.hakopako.net/entry/2018/01/17/220620
(その3)http://www.hakopako.net/entry/2018/01/17/220707
(その4)http://www.hakopako.net/entry/2018/01/17/220730

API編:
Laravel5.5 で REST API 入門チュートリアル - 今からお前んちこいよ