React-dnd: рдзреНрдпрд╛рди рдореЗрдВ рди рдЖрдпрд╛ рддреНрд░реБрдЯрд┐: рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рджреЛ HTML5 рдмреИрдХрдПрдВрдб рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреЗред

рдХреЛ рдирд┐рд░реНрдорд┐рдд 20 рдЕрдкреНрд░реИрд▓ 2017  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: react-dnd/react-dnd

рдореИрдВ Rails5, рдПрдХреНрд╢рди рдХреЗрдмрд▓, рд░рд┐рдПрдХреНрдЯ рдФрд░ рд░реЗрд▓ рдФрд░ рд░рд┐рдПрдХреНрдЯ рдбреАрдПрдирдбреА рдХреЗ рд╕рд╛рде рдПрдХ рдкреАрдУрд╕реА рдмрдирд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред

рдордХрд╕рдж рд╣реИ рдЯреНрд░реЗрд▓реЛ рдЬреИрд╕рд╛ рдРрдк рдмрдирд╛рдирд╛ рд▓реЗрдХрд┐рди рднрд░реНрддреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдПред

рдореЗрд░рд╛ рдореЛрд░реНрдЪрд╛ ReactJS рдореЗрдВ рд╣реИред

рдореЗрд░реЗ рдкрд╛рд╕ 3 рдШрдЯрдХ рд╣реИрдВ, рдкрд╣рд▓рд╛, рдХрдВрдЯреЗрдирд░ рдХреЙрд▓ "рдЙрдореНрдореАрджрд╡рд╛рд░", рдпрд╣ рдШрдЯрдХ 2 "рдХрд╛рд░реНрдбрдмреЛрд░реНрдб" рдШрдЯрдХреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ рдЬреЛ "рдХрд╛рд░реНрдб" рдШрдЯрдХ рдХрд╣рддреЗ рд╣реИрдВред

рдореИрдВ рдбреНрд░реИрдЧ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдХрд╛рд░реНрдб рдФрд░ рдбреНрд░реЙрдк рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдХрд╛рд░реНрдбрдмреЛрд░реНрдб рдХреЗ рд▓рд┐рдП рдбреАрдПрдирдбреА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд░рддрд╛ рд╣реВрдВред рдЬрдм рдореИрдВ рдХрд╛рд░реНрдбрдмреЛрд░реНрдб рдкрд░ рдХрд╛рд░реНрдб рдЫреЛрдбрд╝рддрд╛ рд╣реВрдВ, рддреЛ рдореИрдВ рдЕрдкрдиреЗ рд░рд╛рдЬреНрдп рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреЛрд╕реНрдЯ рдХреЙрд▓ рдФрд░ рдПрдХ рд╡реЗрдмрд╕реЛрдХреЗрдЯ (рд░реЗрд▓ 5 рд╕реЗ рдПрдХреНрд╢рди рдХреЗрдмрд▓) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВред рдореБрдЭреЗ рд╕рдордЭ рдореЗрдВ рдирд╣реАрдВ рдЖрддрд╛ рдХрд┐ рдкреЛрд╕реНрдЯ рдХреЙрд▓ рдХреЗ рдмрд╛рдж рдореЗрд░реЗ рдкрд╛рд╕ рдпрд╣ рд╕рдВрджреЗрд╢ рдХреНрдпреЛрдВ рд╣реИ:

Uncaught Error: Cannot have two HTML5 backends at the same time.
    at HTML5Backend.setup (eval at <anonymous> (webpack-bundle.self-7b1a342тАж.js?body=1:4175), <anonymous>:87:15)
    at DragDropManager.handleRefCountChange (eval at <anonymous> (webpack-bundle.self-7b1a342тАж.js?body=1:3566), <anonymous>:52:22)
    at Object.dispatch (eval at <anonymous> (webpack-bundle.self-7b1a342тАж.js?body=1:4931), <anonymous>:186:19)
    at HandlerRegistry.addSource (eval at <anonymous> (webpack-bundle.self-7b1a342тАж.js?body=1:3594), <anonymous>:104:18)
    at registerSource (eval at <anonymous> (webpack-bundle.self-7b1a342тАж.js?body=1:4294), <anonymous>:9:27)
    at DragDropContainer.receiveType (eval at <anonymous> (webpack-bundle.self-7b1a342тАж.js?body=1:1793), <anonymous>:146:32)
    at DragDropContainer.receiveProps (eval at <anonymous> (webpack-bundle.self-7b1a342тАж.js?body=1:1793), <anonymous>:135:14)
    at new DragDropContainer (eval at <anonymous> (webpack-bundle.self-7b1a342тАж.js?body=1:1793), <anonymous>:102:13)
    at eval (eval at <anonymous> (webpack-bundle.self-7b1a342тАж.js?body=1:4399), <anonymous>:295:18)
    at measureLifeCyclePerf (eval at <anonymous> (webpack-bundle.self-7b1a342тАж.js?body=1:4399), <anonymous>:75:12)

рдЙрдореНрдореАрджрд╡рд╛рд░.рдЬреЗрдПрд╕рдПрдХреНрд╕ =

import React, { PropTypes } from 'react';
import { DragDropContextProvider } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import CardBoard from './CardBoard.jsx';

export default class Candidates extends React.Component {

  constructor(props, _railsContext) {
    super(props);

    this.state = {
      candidates: this.props.candidates
    }

    this.filterByStatus = this.filterByStatus.bind(this)
  }

  componentDidMount() {
    this.setupSubscription();
  }

  setupSubscription() {
    App.candidate = App.cable.subscriptions.create("CandidateChannel", {
      connected: () => {
        console.log("User connected !")
      },

      received: (data) => {
        this.setState({ candidates: data.candidates })
      },
    });
   }

  render() {
    return (
      <DragDropContextProvider backend={HTML5Backend}>
        <div className="recruitment">
          {
            ["├А Rencontrer", "Entretien"].map((status, index) => {
              return (
                <CardBoard candidates={(this.filterByStatus({status}))} status={status} key={index} />
              );
            })
          }
        </div>
      </DragDropContextProvider>
    );
  } 
}

рдХрд╛рд░реНрдбрдмреЛрд░реНрдб.рдЬреЗрдПрд╕рдПрдХреНрд╕ =

import React, { PropTypes } from 'react';
import Card from './Card.jsx';
import { DropTarget } from 'react-dnd';
import ItemTypes from './ItemTypes';

const cardTarget = {
  drop(props: Props) {
    var status = ''

    if(props.status == "├А Rencontrer") {
      status = 'to_book'
    } else {
      status = 'interview'
    }

    return { status: status };
  },
};

@DropTarget(ItemTypes.CARD, cardTarget, (connect, monitor) => ({
  connectDropTarget: connect.dropTarget(),
  isOver: monitor.isOver(),
  canDrop: monitor.canDrop(),
}))

export default class CardBoard extends React.Component<Props> {

  constructor(props, _railsContext) {
    super(props);
  }

  render() {
    const { canDrop, isOver, connectDropTarget } = this.props;
    const isActive = canDrop && isOver;


    return connectDropTarget(
      <div className={`${this.props.status} ui cards`}>
        <h2>{`${this.props.status} (${this.props.candidates.length})`}</h2>
        {
          (this.props.candidates).map((candidate, index) => {
            return <Card candidate={candidate} key={index} />
          })
        }
        { isActive?
          'Release to drop' : 'drag a card here'
        }
      </div>
    );
  }
}

рдХрд╛рд░реНрдб.рдЬреЗрдПрд╕рдПрдХреНрд╕=

import React, { PropTypes } from 'react';
import { DragSource } from 'react-dnd';
import ItemTypes from './ItemTypes';


const cardSource = {
  beginDrag(props) {
    return {
      candidate_id: props.candidate.id,
    };
  },

  endDrag(props, monitor) {
    const item = monitor.getItem();
    const dropResult = monitor.getDropResult();

    if (dropResult) {
      console.log(`You dropped ${item.candidate_id} vers ${dropResult.status} !`);
      $.post(`/update_status/${item.candidate_id}/${dropResult.status}`);
    }
  },
};

@DragSource(ItemTypes.CARD, cardSource, (connect, monitor) => ({
  connectDragSource: connect.dragSource(),
  isDragging: monitor.isDragging(),
}))

export default class Card extends React.Component {

  constructor(props, _railsContext) {
    super(props);
  }

  render() {
    const { isDragging, connectDragSource } = this.props;
    const { name } = this.props;
    const opacity = isDragging ? 0 : 1;

    var candidate = this.props.candidate;

    return (
      connectDragSource(
        <div className="card" key={candidate.id} style={{opacity}}>
          <div className="content">
            <div className="header">{`${candidate.first_name} ${candidate.last_name}`}</div>
            <div className="description">
              {candidate.job_title}
            </div>
            <span className="right floated">
              <i className="heart outline like icon"></i>
              {candidate.average_rate}
            </span>
          </div>
        </div>
      )
    );
  }
}

рдмреЗрд╣рддрд░ рд╕рдордЭ рдХреЗ рд▓рд┐рдП, рдпрд╣рд╛рдБ рдореЗрд░реА рд╕реБрд╡рд┐рдзрд╛ рдФрд░ рдЙрд╕рдХреА рдмрдЧ рдХрд╛ рдПрдХ GIF рд╣реИ:
bugcard

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

@antoineBernard рдореИрдВрдиреЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдПрдХ рд╣реА рддреНрд░реБрдЯрд┐ рдХреЛ рджреВрд░ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдореЗрдВ рдкреВрд░рд╛ рджрд┐рди рдмрд┐рддрд╛рдпрд╛ред рдпрд╣ рдЖрдкрдХреА рдЬреИрд╕реА рд╣реА рд╕рдорд╕реНрдпрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИред 2 рдЪреАрдЬреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ:

  1. рдЕрдкрдиреЗ <DragDropContextProvider> рдХреЛ Candidates.jsx рдХреЗ рдореВрд▓ рдШрдЯрдХ рдореЗрдВ рд▓реЗ рдЬрд╛рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред
  2. рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд┐рдВрдЧрд▓рдЯрди рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдХрд┐ рдЖрдкрдХреЗ рдкреВрд░реЗ рдРрдк рдореЗрдВ DragDropContext рдХрд╛ рдХреЗрд╡рд▓ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдЖрд░рдВрдн рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдореИрдВрдиреЗ рд╕рдлрд▓рддрд╛ рдХреЗ рд╕рд╛рде @gcorne рдХреЗ рд╕реБрдЭрд╛рд╡ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ред

рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рдЖрдкрдХреЗ рд▓рд┐рдП рднреА рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛!

рд╕рднреА 3 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

@antoineBernard рдореИрдВрдиреЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдПрдХ рд╣реА рддреНрд░реБрдЯрд┐ рдХреЛ рджреВрд░ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдореЗрдВ рдкреВрд░рд╛ рджрд┐рди рдмрд┐рддрд╛рдпрд╛ред рдпрд╣ рдЖрдкрдХреА рдЬреИрд╕реА рд╣реА рд╕рдорд╕реНрдпрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИред 2 рдЪреАрдЬреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ:

  1. рдЕрдкрдиреЗ <DragDropContextProvider> рдХреЛ Candidates.jsx рдХреЗ рдореВрд▓ рдШрдЯрдХ рдореЗрдВ рд▓реЗ рдЬрд╛рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред
  2. рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд┐рдВрдЧрд▓рдЯрди рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдХрд┐ рдЖрдкрдХреЗ рдкреВрд░реЗ рдРрдк рдореЗрдВ DragDropContext рдХрд╛ рдХреЗрд╡рд▓ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдЖрд░рдВрдн рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдореИрдВрдиреЗ рд╕рдлрд▓рддрд╛ рдХреЗ рд╕рд╛рде @gcorne рдХреЗ рд╕реБрдЭрд╛рд╡ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ред

рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рдЖрдкрдХреЗ рд▓рд┐рдП рднреА рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛!

рдЗрд╕рдиреЗ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд┐рдпрд╛: https://github.com/react-dnd/react-dnd/issues/186#issuecomment -282789420

рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдкреБрд░рд╛рдиреЗ рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдореЗрдВ рд╣рд╛рд▓ рдХреА рдЧрддрд┐рд╡рд┐рдзрд┐ рдирд╣реАрдВ рд╣реИред рдЖрдЧреЗ рдХреЛрдИ рдЧрддрд┐рд╡рд┐рдзрд┐ рдирд╣реАрдВ рд╣реЛрдиреЗ рдкрд░ рдЗрд╕реЗ рдмрдВрдж рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЖрдкрдХреЗ рдпреЛрдЧрджрд╛рдиреЛрдВ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

croraf picture croraf  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

FutureProg picture FutureProg  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

redochka picture redochka  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

user1736 picture user1736  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

bebbi picture bebbi  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ