I have just started to work on React and have been trying to come up with a To-Do App using raw React, without JSX. I have been trying to implement 'Delete' functionality for each of the To-Do item, but it doesn't work. Can someone please help me to understand and implement this 'delete button'
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width">
<script src="https://cdn.rawgit.com/zloirock/core-js/master/client/shim.min.js"></script>
<meta charset="utf-8">
<title>To-Do app</title>
</head>
<body>
<div id="ToDo-app"></div>
<script src="https://cdn.jsdelivr.net/react/0.14.0-rc1/react.js"></script>
<script src="https://cdn.jsdelivr.net/react/0.14.0-rc1/react-dom.js"></script>
<script>
var ItemForm = React.createClass({
PropTypes: {
value: React.PropTypes.object.isRequired,
onChange: React.PropTypes.func.isRequired,
onSubmit: React.PropTypes.func.isRequired,
},
onItemInput : function(e) {
this.props.onChange(Object.assign({},this.props.value, {item: e.target.value}));
},
onSubmit: function(e) {
e.preventDefault();
this.props.onSubmit();
},
render: function() {
var errors = this.props.value.errors || {};
return (
React.createElement('form', {onSubmit: this.onSubmit, className: 'ItemForm', noValidate: true},
React.createElement('input', {
type: 'text',
className: errors.item && 'ItemForm-error',
placeholder: 'To-Do item',
onInput: this.onItemInput,
value: this.props.value.item,
}),
React.createElement('button', {type: 'submit'}, "Add Item")
)
);
},
});
var ToDoItem = React.createClass({
PropTypes: {
item: React.PropTypes.string.isRequired,
id: React.PropTypes.string.isRequired,
onSubmit: React.PropTypes.func.isRequired,
},
onSubmit: function(e) {
e.preventDefault();
this.props.onSubmit(this.props.id);
},
render: function() {
return (
React.createElement('li', {className: 'ToDoItem'},
React.createElement('h2', {className: 'ToDoItem-item', onSubmit: this.onSubmit}, this.props.item),
React.createElement('button', {type: 'submit'}, "Delete")
)
);
},
});
var ItemsView = React.createClass({
PropTypes: {
id: React.PropTypes.string.isRequired,
items: React.PropTypes.array.isRequired,
newItem: React.PropTypes.object.isRequired,
onNewItemChange: React.PropTypes.func.isRequired,
onNewItemSubmit: React.PropTypes.func.isRequired,
onDSubmit: React.PropTypes.func.isRequired,
},
render: function() {
var ItemElements = this.props.items
.map(function(item) {
return React.createElement(ToDoItem, item);
});
//alert(ItemElements);
return(
React.createElement('div', {className: 'ItemView'},
React.createElement('h1', {className: 'ItemView-title'}, "To-Do Items"),
React.createElement('ul', {className: 'ItemView-list', onSubmit: this.props.onDSubmit}, ItemElements),
React.createElement(ItemForm, {value: this.props.newItem, onChange: this.props.onNewItemChange,
onSubmit: this.props.onNewItemSubmit,
})
)
);
},
});
var ITEM_TEMPLATE = {item: "", errors: null};
function updateNewItem(item) {
setState({ newItem: item});
};
function submitNewItem() {
var item = Object.assign({}, state.newItem, {key: state.items.length + 1, errors: {}});
if (!item.item) {
item.errors.item = ["Please enter your To-Do item"];
}
setState(
Object.keys(item.errors).length === 0
? {
newItem: Object.assign({}, ITEM_TEMPLATE),
items: state.items.slice(0).concat(item),
}
: { newItem: item }
);
};
function deleteItem(e,item) {
alert("Inside delete func");
var index = state.item.id;
var elements = state.items.splice(index, 1);
setState({items: elements});
};
function navigated() {
setState({
location: window.location.hash});
}
var state = {
items: [
{key: 1, item: "Pay the internet bill"},
{key: 2, item: "Call the team for conference"},
],
newItem: Object.assign({}, ITEM_TEMPLATE),
location: window.location.hash
};
function setState(changes) {
var component;
Object.assign(state, changes);
switch (state.location) {
case '#/items':
//alert("Inside items")
component = React.createElement(ItemsView, Object.assign({}, state, {
onDSubmit: deleteItem,
onNewItemChange: updateNewItem,
onNewItemSubmit: submitNewItem,
}));
break;
default:
component = React.createElement('div', {},
React.createElement('h1', {}, "Let's get this Done!"),
React.createElement('a', {href: '#/items'}, "To Do Items")
);
}
ReactDOM.render(component, document.getElementById('ToDo-app'));
};
// Handle browser navigation events
window.addEventListener('hashchange', navigated, false);
// Start the app
navigated();
</script>
</body>
</html>
Use frontend-boilerplate. It is a fully To-Do app using React, Redux, Webpack and other commonly tools.
Related
I have someone who is responsible for opening / closing the window, I am trying to have one of the three gifts displayed randomly when opened. While there is no progress, how can I do this.
I understand that I need to do this through state.random, but now I don’t understand how. Apparently I'm completely blond ))))
// start open box
var TOGGLE_BOX = '[GiftBox] Toggle';
var toggleBox = function () {
return { type: TOGGLE_BOX };
};
//REDUCERS (Update)
var DEFAULT = { open: false, wasOpen: false };
var reducer = function (state, action) {
if (state === void 0) {state = DEFAULT;}
switch (action.type) {
case TOGGLE_BOX:{
return {
open: state.open ? false : true,
wasOpen: state.open };
}
default:return state;}
};
var store = Redux.createStore(reducer, DEFAULT);
var mapStateToProps = function (state) {
return { open: state.open, wasOpen: state.wasOpen };
};
var mapDispatchToProps = function (dispatch) {
return { dispatch: dispatch };
};
var cGiftBox = function (_a) {
var wasOpen = _a.wasOpen,open = _a.open,dispatch = _a.dispatch;
return React.createElement("div", { className: "floor" },
React.createElement("div", { className: "box" },
open ?
React.createElement("button", { className: "heart-gift", }, "gift1") :
React.createElement(React.Fragment, null),
React.createElement("div", { className: open ?
'lid open' :
wasOpen ?
'lid close' :
'lid', onClick: function (e) {return dispatch(toggleBox());} },
React.createElement("div", { className: "qcube" }, open ? '!' : '?'),
React.createElement("div", { className: "face ltop" }),
React.createElement("div", { className: "face lleft" }),
React.createElement("div", { className: "face lright" })),
React.createElement("div", { className: "face top" }),
React.createElement("div", { className: "face left" }),
React.createElement("div", { className: "face right" }),
));
};
// connect and render
var Provider = ReactRedux.Provider,connect = ReactRedux.connect;
var GiftBox = connect(mapStateToProps, mapDispatchToProps)(cGiftBox);
ReactDOM.render(React.createElement(Provider, { store: store },
React.createElement(GiftBox, null)), document.getElementById('root'));
Main app:
class App extends Component {
constructor(props) {
super(props);
this.state = {
totalCheckBoxes: 0,
checkboxesClicked: 0,
percentage: 0,
};
this.checkboxClick = this.checkboxClick.bind(this);
}
checkboxClick(type) {
(type) ? this.setState({ checkboxesClicked: checkboxesClicked++ }) :
(type > 0) ? this.setState({ checkboxesClicked: checkboxesClicked-- }) : this.setState({ checkboxesClicked: 0 });
}
render() {
// grab steps
const { steps } = this.props;
const { totalCheckBoxes } = this.state;
const { checkboxClick } = this;
// add rendered steps to .allTheSteps
return (
ce('div', { className:'allTheSteps' },
ce(pagination, { steps }),
Object.values(steps).map((step, i) =>
ce(Steps, { step, key: v4(), i, checkboxClick }),
)
)
);
};
};
Child component:
const Steps = ({ step, i, checkboxClick }) =>
ce( "div", {
className: `mainBoxes clearfix playbook_step_${i}`,
key: v4(),
},
ce('span', {
className: 'steps'
}, step.id + 1 + ' - '),
ce("strong", {
className: "titleText",
key: v4(),
}, step.name),
( step.summary.length ) ? ce('div', { className: 'step__summary' }, step.summary) : null,
ce( "div", {
className: "stepArticle__content",
key: v4(),
},
step.articles.map(({ name, url }, j) => ce(Articles, { name, url, key: v4(), j, checkboxClick }))
)
);
Grandchild component:
class Articles extends Component {
constructor(props) {
super(props);
this.state = {
notes: false,
questions: false,
};
this.addNotes = this.addNotes.bind(this);
this.askQuestions = this.askQuestions.bind(this);
}
addNotes() {
this.setState({ notes: !this.state.notes });
}
askQuestions() {
this.setState({ questions: !this.state.questions });
}
render(){
const { name, url, checkboxClick } = this.props;
const { notes, questions } = this.state;
const { addNotes, askQuestions } = this;
return ce('div', null, Article( { name, url, notes, questions, addNotes, askQuestions, checkboxClick } ));
}
}
const Article = ({ name, url, notes, questions, addNotes, askQuestions, checkboxClick }) => (
ce('div', { className: 'stepArticle step__'},
ce('div', {className: 'clearfix'},
ce('div', {className: 'articleTitle'},
ce('input', {
type: 'checkbox',
name: 'done',
onClick: checkboxClick.bind(null, this),
className: 'checkBoxes'}
),
ce('a', {
className: 'checkLink',
target: '_blank',
href: url
}, name),
),
ce('div', {className: 'articleActions'},
ce('input', {
type: 'button',
value: 'Make Notes',
className: 'addNotes',
onClick: addNotes,
}),
ce('input', {
type: 'button',
value: 'Ask Clausehound',
className: 'askQuestions',
onClick: askQuestions,
}),
)
),
(notes) ? ce('textarea', {
className: 'text_areas notes notes__',
placeholder: 'My Notes: '
}) : null,
(questions) ? ce('textarea', {
className: 'text_areas questions questions__',
placeholder: 'Questions for Clausehound Research Team: ',
}) : null,
)
);
The app is a step by step instruction/tutorial and when a user is done with a step, they tick the checkbox and a percentage for completion is displayed. I want to calculate the percentage of checkboxes that have been clicked.
Currently I am trying to do this in checkboxClick function in the parent component. Is this the correct approach? The type needs to be a boolean so that we know whether a checkbox was checked or unchecked.
Codesandbox link.
I am using react with my meteor app and I need to integrate this with a list of items.
There is a ItemList.jsx and a ItemRow.jsx since the item itself has text, links, images, ect.
ItemRow.jsx
ItemRow = ReactMeteor.createClass({
templateName: "ItemRow",
propTypes: {
item: React.PropTypes.object.isRequired,
showPoolTitle: React.PropTypes.bool,
},
getInitialState: function() {
return {
editing: false,
drop: this.props.item,
pool: {},
}
},
startMeteorSubscriptions: function() {
Meteor.subscribe("ItemRow", this.props.item._id);
},
getMeteorState: function() {
return {
item: Items.findOne(this.props.item._id),
pool: Pools.findOne(this.props.drop.poolId),
};
},
toggleEditing: function() {
this.setState({ editing: !this.state.editing });
},
render: function() {
var content;
if (this.state.editing) {
content = <ItemRowEdit drop={this.state.item} done={this.toggleEditing}/>
} else {
content = <ItemRowShow pool={this.state.pool} item={this.state.item} edit={this.toggleEditing} showPoolTitle={this.props.showPoolTitle}/>
}
return (
<div key={this.props.item._id} className="item">
{content}
</div>
)
},
});
and ItemList.jsx
ItemList = ReactMeteor.createClass({
templateName: "ItemList",
propTypes: {
items: React.PropTypes.object.isRequired
},
getInitialState: function() {
return {
items: this.props.items.fetch()
}
},
render: function() {
var items = this.state.items;
return (
<div className="ui very relaxed huge list">
{items.map(function(item) {
return ( <ItemRow item={item}/> );
})}
</div>
);
}
});
I am not using Meteor react for ItemList just yet but I want to be able to drag and drop reorder first so any help to get me on the right track is much appreciated!
Im new to React, I have built a dropdown in ES6 react which shows one image and a text line. It works fine and fetches the data from a data array and shows it. Now I have to do one thing: when the user clicks on an option in the dropdown, the dropdown closes and shows the selected option instead the original one [0]. I tried with javascript sentences taking the innerHTHML, but that is not the way to do it.
Here is the code:
import React from "react";
class StatusBarCompaniesView extends React.Component {
mixins: [ClickAwayable]
constructor(props) {
super(props)
this.state = {dropdown: false}
this.handleClick = this.handleClick.bind(this)
}
handleClick() {
this.setState({ dropdown: !this.state.dropdown });
}
clickSelectOption(e){
console.log(e.target);
e.stopPropagation();
var valueNode = this.refs.dropDownValue.getDOMNode();
valueNode.innerHTML = e.target.innerHTML;
valueNode.setAttribute('data-value',e.target.getAttribute('data-value'))
}
render() {
var me = this;
var company_items = [
{ payload: '1', imageurl: 'images/avatar.png', text: 'Burger Apps, SL' },
{ payload: '2', imageurl: 'images/avatar-apple.png', text: 'Apple Computer Inc' },
{ payload: '3', imageurl: 'images/avatar-hp.png', text: 'Hewlett Packard' },
{ payload: '4', imageurl: 'images/avatar-apple.png', text: 'Eyects Systems' }
];
var cx = require('classnames');
var dropdown = cx ({
'aui-profit-statusbar-companies-dropdown-container' : true,
'dropdown' : this.state.dropdown
});
var cx = require('classnames');
var selected = cx ({
'aui-profit-statusbar-companies-container' : true,
'selected' : this.state.dropdown
});
return (
<div className={selected} onClick={this.handleClick}>
<div ref="dropDownValue">
<div className="aui-profit-statusbar-selected-company-logo"><img src={company_items[0].imageurl}/></div>
<div className="aui-profit-statusbar-selected-company-name">{company_items[0].text}</div>
</div>
<div className={dropdown}>
{company_items.map(function(option, index){
return (
<div key={index} className="option" data-value={option.payload} onClick={me.clickSelectOption.bind(me)}>
<div className="aui-profit-statusbar-companies-logo"><img src={option.imageurl}/></div>
<div className="aui-profit-statusbar-companies-name">{option.text}</div>
</div>
);
})}
</div>
</div>
);
}
};
module.exports = StatusBarCompaniesView;
Any kind of help is welcome! thanks!
When you create the dropdown option you already know its value, so just bind with that, so the callback is called with the correct parameter, saving you from inspecting the DOM, eg:
in render()
{company_items.map(function(option, index){
return (
<div key={index} className="option" onClick={me.clickSelectOption.bind(me, option.payload)}>
<div className="aui-profit-statusbar-companies-logo"><img src={option.imageurl}/></div>
<div className="aui-profit-statusbar-companies-name">{option.text}</div>
</div>
);
})}
Then in the handler:
clickSelectOption(payload){
console.log(payload);
this.setState({ selected: payload });
}
This is the final componet, thanks guys:
import React from "react";
class StatusBarCompaniesView extends React.Component {
mixins: [ClickAwayable]
constructor(props) {
super(props)
this.state = {dropdown: false, selectedOption: 0}
this.handleClick = this.handleClick.bind(this)
}
handleClick() {
this.setState({ dropdown: !this.state.dropdown });
}
componentWillMount() {
this._closeMenuIfClickedOutside = function(event) {
if (!this.state.dropdown) {
return;
}
var menuElem = this.refs.selectMenuContainer.getDOMNode();
var eventOccuredOutsideMenu = this.clickedOutsideElement(menuElem, event);
// Hide dropdown menu if click occurred outside of menu
if (eventOccuredOutsideMenu) {
this.setState({
dropdown: false
}, this._unbindCloseMenuIfClickedOutside);
}
}.bind(this);
this._bindCloseMenuIfClickedOutside = function() {
document.addEventListener('click', this._closeMenuIfClickedOutside);
};
this._unbindCloseMenuIfClickedOutside = function() {
document.removeEventListener('click', this._closeMenuIfClickedOutside);
};
}
clickedOutsideElement(element, event) {
var eventTarget = (event.target) ? event.target : event.srcElement;
while (eventTarget != null) {
if (eventTarget === element) return false;
eventTarget = eventTarget.offsetParent;
}
return true;
}
clickSelectOption(playload){
console.log(playload);
this.state.selectedOption = playload
console.log(this.state.selectedOption)
}
render() {
var me = this;
var company_items = [
{ payload: '0', imageurl: 'images/avatar.png', text: 'Burger Apps, SL' },
{ payload: '1', imageurl: 'images/avatar-apple.png', text: 'Apple Computer Inc' },
{ payload: '2', imageurl: 'images/avatar-hp.png', text: 'Hewlett Packard' },
{ payload: '3', imageurl: 'images/avatar-apple.png', text: 'Eyects Systems' }
];
var cx = require('classnames');
var dropdown = cx ({
'aui-profit-statusbar-companies-dropdown-container' : true,
'dropdown' : this.state.dropdown
});
var cx = require('classnames');
var selected = cx ({
'aui-profit-statusbar-companies-container' : true,
'selected' : this.state.dropdown
});
return (
<div className={selected} onClick={this.handleClick}>
<div ref="dropDownValue">
<div className="aui-profit-statusbar-selected-company-logo"><img src={company_items[this.state.selectedOption].imageurl}/></div>
<div className="aui-profit-statusbar-selected-company-name">{company_items[this.state.selectedOption].text}</div>
</div>
<div className={dropdown} ref="selectMenuContainer">
{company_items.map(function(option, index){
return (
<div key={index} className="option" onClick={me.clickSelectOption.bind(me, option.payload)}>
<div className="aui-profit-statusbar-companies-logo"><img src={option.imageurl}/></div>
<div className="aui-profit-statusbar-companies-name">{option.text}</div>
</div>
);
})}
</div>
</div>
);
}
};
module.exports = StatusBarCompaniesView;
If you go here: http://facebook.github.io/react/index.html you will find tutorials in jsx but how do I use only js?
/** #jsx React.DOM */
var TodoList = React.createClass({
render: function() {
var createItem = function(itemText) {
return <li>{itemText}</li>;
};
return <ul>{this.props.items.map(createItem)}</ul>;
}
});
var TodoApp = React.createClass({
getInitialState: function() {
return {items: [], text: ''};
},
onChange: function(e) {
this.setState({text: e.target.value});
},
handleSubmit: function(e) {
e.preventDefault();
var nextItems = this.state.items.concat([this.state.text]);
var nextText = '';
this.setState({items: nextItems, text: nextText});
},
render: function() {
return (
<div>
<h3>TODO</h3>
<TodoList items={this.state.items} />
<form onSubmit={this.handleSubmit}>
<input onChange={this.onChange} value={this.state.text} />
<button>{'Add #' + (this.state.items.length + 1)}</button>
</form>
</div>
);
}
});
React.renderComponent(<TodoApp />, mountNode);
For example the above code is using a listener, how do I do that in plain javascript?
thanks
Just found this: http://facebook.github.io/react/jsx-compiler.html
/** #jsx React.DOM */
var TodoList = React.createClass({displayName: 'TodoList',
render: function() {
var createItem = function(itemText) {
return React.DOM.li(null, itemText);
};
return React.DOM.ul(null, this.props.items.map(createItem));
}
});
var TodoApp = React.createClass({displayName: 'TodoApp',
getInitialState: function() {
return {items: [], text: ''};
},
onChange: function(e) {
this.setState({text: e.target.value});
},
handleSubmit: function(e) {
e.preventDefault();
var nextItems = this.state.items.concat([this.state.text]);
var nextText = '';
this.setState({items: nextItems, text: nextText});
},
render: function() {
return (
React.DOM.div(null,
React.DOM.h3(null, "TODO"),
TodoList( {items:this.state.items} ),
React.DOM.form( {onSubmit:this.handleSubmit},
React.DOM.input( {onChange:this.onChange, value:this.state.text} ),
React.DOM.button(null, 'Add #' + (this.state.items.length + 1))
)
)
);
}
});
React.renderComponent(TodoApp(null ), mountNode);