From 3d48cfbf469708b0738138117a411d6b00eda456 Mon Sep 17 00:00:00 2001 From: Marat Nepomnyashy Date: Thu, 26 Jul 2018 22:19:07 -0700 Subject: [PATCH] Moved the logic for into a new separate file 'webpack_in/list_widget.jsx'. --- webpack_in/entry.jsx | 158 +--------------------------------- webpack_in/list_widget.jsx | 169 +++++++++++++++++++++++++++++++++++++ 2 files changed, 170 insertions(+), 157 deletions(-) create mode 100644 webpack_in/list_widget.jsx diff --git a/webpack_in/entry.jsx b/webpack_in/entry.jsx index af341bf..198cd0b 100644 --- a/webpack_in/entry.jsx +++ b/webpack_in/entry.jsx @@ -10,168 +10,12 @@ import PropTypes from 'prop-types'; import React from 'react'; import ReactDOM from 'react-dom'; -import ButtonWidget from './button_widget.jsx'; import HelloWidget from './hello_widget.jsx'; +import ListWidget from './list_widget.jsx'; import Styles from './styles.es'; import TextWidget from './text_widget.jsx'; -class ListItem extends React.Component { - render() { - return (
  • { this.props.caption }
  • ); - } -} - -ListItem.propTypes = { - caption: PropTypes.string.isRequired, - isChecked: PropTypes.bool.isRequired, - onChangeChecked: PropTypes.func.isRequired - }; - -class ListWidget extends React.Component { - constructor(props) { - super(props); - - this._mutateStateToAddItem = (state, strItemCaption) => ({ - ...state, - items: [ - ...state.items, - { - id: state.total_added, - caption: strItemCaption, - is_checked: false - } - ], - total_added: state.total_added + 1 - }); - - this._mutateStateToUpdateItemCaption = (state, id, strCaptionNew) => ({ - ...state, - items: state.items.map(objItem => ( - objItem.id === id ? { - ...objItem, - caption: strCaptionNew - } - : objItem - )) - }); - - this._mutateStateToUpdateItemChecked = (state, id, isChecked) => ({ - ...state, - items: state.items.map(objItem => ( - objItem.id === id ? { - ...objItem, - is_checked: isChecked - } - : objItem - )) - }); - - this._mutateStateToRemoveItemsChecked = state => ({ - ...state, - items: state.items.filter(objItem => !objItem.is_checked) - }); - - const objStateEmpty = { - items: [], - total_added: 0 - }; - - this.state = this._mutateStateToAddItem( - this._mutateStateToAddItem( - this._mutateStateToAddItem( - objStateEmpty, - "Item 1"), - "Item 2"), - "Item 3"); - } - - render() { - const arrItemsSelected = this.state.items.filter(objItem => objItem.is_checked); - - const formatListOfNames = (arrNames) => arrNames.reduce( - (strOutput, strName, index) => ( - `${strOutput}${index > 0 // Will render either ' and' or ',' before 2nd item. - // Will render ', and' before the 3rd+ last item. - ? (`${arrNames.length > 2 ? ',' : "" - }${index === arrNames.length - 1 ? ' and' : ""}` - ) - : ""} "${strName}"` - ), - ""); - - return ( -
    -
    -
      - { this.state.items.map((objItem, index) => ( - { - this.setState( - this._mutateStateToUpdateItemChecked( - this.state, - objItem.id, - !objItem.is_checked)); - }} - /> - )) } -
    -
    -
    - { - const strItemNew = prompt("Please enter new item to add:", - "Item " - + (this.state.items.length + 1)); - if (strItemNew === null) { - return; - } - - this.setState(this._mutateStateToAddItem(this.state, - strItemNew)); - }}/> - { - const objItemEdit = arrItemsSelected[0]; - const strItemEdited = prompt("Please edit item:", - objItemEdit.caption); - if (strItemEdited === null) { - return; - } - - this.setState(this._mutateStateToUpdateItemCaption( - this.state, - objItemEdit.id, - strItemEdited)); - }}/> - 1 ? "Remove items..." - : "Remove item..." } - isDisabled={ arrItemsSelected.length === 0 } - onClick={() => { - const arrCaptions = arrItemsSelected - .map(objItem => objItem.caption); - const isConfirmed = confirm( - `Are you sure you want to remove item${ - arrCaptions.length > 1 ? "s" : ""} ${ - formatListOfNames(arrCaptions) - }?`); - if (isConfirmed === false) { - return; - } - - this.setState(this._mutateStateToRemoveItemsChecked(this.state)); - }}/> -
    -
    - ); - } -} - class ButtonForCounter extends React.Component { constructor(props) { super(props); diff --git a/webpack_in/list_widget.jsx b/webpack_in/list_widget.jsx new file mode 100644 index 0000000..67ef56e --- /dev/null +++ b/webpack_in/list_widget.jsx @@ -0,0 +1,169 @@ +// This file 'list_widget.jsx' is part of an example for building a multi-widget React front-end +// app step by step as outlined in the tutorial blog at +// http://maratbn.com/blogs/2018/07/02/react-multi-widget/ + + +import PropTypes from 'prop-types'; +import React from 'react'; + +import ButtonWidget from './button_widget.jsx'; +import Styles from './styles.es'; + + +class ListItem extends React.Component { + render() { + return (
  • { this.props.caption }
  • ); + } +} + +ListItem.propTypes = { + caption: PropTypes.string.isRequired, + isChecked: PropTypes.bool.isRequired, + onChangeChecked: PropTypes.func.isRequired + }; + +class ListWidget extends React.Component { + constructor(props) { + super(props); + + this._mutateStateToAddItem = (state, strItemCaption) => ({ + ...state, + items: [ + ...state.items, + { + id: state.total_added, + caption: strItemCaption, + is_checked: false + } + ], + total_added: state.total_added + 1 + }); + + this._mutateStateToUpdateItemCaption = (state, id, strCaptionNew) => ({ + ...state, + items: state.items.map(objItem => ( + objItem.id === id ? { + ...objItem, + caption: strCaptionNew + } + : objItem + )) + }); + + this._mutateStateToUpdateItemChecked = (state, id, isChecked) => ({ + ...state, + items: state.items.map(objItem => ( + objItem.id === id ? { + ...objItem, + is_checked: isChecked + } + : objItem + )) + }); + + this._mutateStateToRemoveItemsChecked = state => ({ + ...state, + items: state.items.filter(objItem => !objItem.is_checked) + }); + + const objStateEmpty = { + items: [], + total_added: 0 + }; + + this.state = this._mutateStateToAddItem( + this._mutateStateToAddItem( + this._mutateStateToAddItem( + objStateEmpty, + "Item 1"), + "Item 2"), + "Item 3"); + } + + render() { + const arrItemsSelected = this.state.items.filter(objItem => objItem.is_checked); + + const formatListOfNames = (arrNames) => arrNames.reduce( + (strOutput, strName, index) => ( + `${strOutput}${index > 0 // Will render either ' and' or ',' before 2nd item. + // Will render ', and' before the 3rd+ last item. + ? (`${arrNames.length > 2 ? ',' : "" + }${index === arrNames.length - 1 ? ' and' : ""}` + ) + : ""} "${strName}"` + ), + ""); + + return ( +
    +
    +
      + { this.state.items.map((objItem, index) => ( + { + this.setState( + this._mutateStateToUpdateItemChecked( + this.state, + objItem.id, + !objItem.is_checked)); + }} + /> + )) } +
    +
    +
    + { + const strItemNew = prompt("Please enter new item to add:", + "Item " + + (this.state.items.length + 1)); + if (strItemNew === null) { + return; + } + + this.setState(this._mutateStateToAddItem(this.state, + strItemNew)); + }}/> + { + const objItemEdit = arrItemsSelected[0]; + const strItemEdited = prompt("Please edit item:", + objItemEdit.caption); + if (strItemEdited === null) { + return; + } + + this.setState(this._mutateStateToUpdateItemCaption( + this.state, + objItemEdit.id, + strItemEdited)); + }}/> + 1 ? "Remove items..." + : "Remove item..." } + isDisabled={ arrItemsSelected.length === 0 } + onClick={() => { + const arrCaptions = arrItemsSelected + .map(objItem => objItem.caption); + const isConfirmed = confirm( + `Are you sure you want to remove item${ + arrCaptions.length > 1 ? "s" : ""} ${ + formatListOfNames(arrCaptions) + }?`); + if (isConfirmed === false) { + return; + } + + this.setState(this._mutateStateToRemoveItemsChecked(this.state)); + }}/> +
    +
    + ); + } +} + +export default ListWidget;