SCSS
@import url('https://fonts.googleapis.com/css?family=Montserrat:200,300,400,500,600');
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body{
background: white;
font-family: 'Montserrat', Helvetica, sans-serif;
}
input[type='checkbox']{ height: 0; width: 0; }
input[type='checkbox'] + label{
position: relative;
display: inline-flex;
margin: 0 0;
color: #9e9e9e;
transition: color 250ms cubic-bezier(.4,.0,.23,1);
}
input[type='checkbox'] + label > span{
display: flex;
justify-content: center;
align-items: center;
width: 15px;
height: 15px;
background: transparent;
border: 2px solid #9E9E9E;
border-radius: 2px;
cursor: pointer;
transition: all 250ms cubic-bezier(.4,.0,.23,1);
}
input[type='checkbox'] + label:hover, input[type='checkbox']:focus + label{
color: #fff;
}
input[type='checkbox'] + label:hover > span, input[type='checkbox']:focus + label > span{
background: rgba(255,255,255,.1);
}
input[type='checkbox']:checked + label > span{
border: .5em solid #f9e01f;
animation: shrink-bounce 200ms cubic-bezier(.4,.0,.23,1);
}
input[type='checkbox']:checked + label > span:before{
content: "";
position: absolute;
top: 5px;
left: 2px;
margin: auto;
border-right: 3px solid transparent;
border-bottom: 3px solid transparent;
transform: rotate(45deg);
transform-origin: 0% 100%;
animation: checkbox-check 125ms 250ms cubic-bezier(.4,.0,.23,1) forwards;
}
@keyframes shrink-bounce{
0%{
transform: scale(1);
}
33%{
transform: scale(.85);
}
100%{
transform: scale(1);
}
}
@keyframes checkbox-check{
0%{
width: 0;
height: 0;
border-color: #212121;
transform: translate3d(0,0,0) rotate(45deg);
}
33%{
width: .2em;
height: 0;
transform: translate3d(0,0,0) rotate(45deg);
}
100%{
width: .2em;
height: .5em;
border-color: #212121;
transform: translate3d(0,-.5em,0) rotate(45deg);
}
}
.container{
width: 1170px;
overflow: auto;
background: white;
border: 1px solid rgba(0,0,0,0.2);
padding: 20px;
margin: 30px;
h1{
position: relative;
font-size: 20px;
font-weight: 600;
color: #404040;
text-transform: uppercase;
&:after{
content: '';
display: block;
position: absolute;
bottom: -7px;
width: 100px;
height: 2px;
background: #e96656;
}
}
table{
margin-top: 40px;
border-collapse: collapse;
border: 3px solid #404040;
width: 100%;
.totalTR{
text-align: left;
font-size: 20px;
padding: 7px 10px;
}
.totalTr{
background: #404040 !important;
font-size: 19px;
color: #f9e01f;
.totalText{
padding-left: 10px;
}
}
.checkTh{
width: 38px;
}
.checkTd{
padding-left: 10px;
}
th{
font-weight: 400;
font-size: 18px;
background-color: #f9e01f;
color: #404040;
padding: 15px;
}
th, td{
text-align:left;
}
.flexcenter{
display: flex;
align-items: center;
justify-content: center;
}
tr:nth-child(even) {background-color: #f2f2f2}
/*tr:last-child{
background-color: rgba(204, 235, 255,0.5);
}*/
.numberi{
width: 100px !important;
}
td{
padding: 5px;
input{
border: none;
width: 85%;
max-width: 250px;
background: rgba(0,0,0,0.04);
font-size: 15px;
padding: 8px 8px;
margin: 3px 5px;
border-left: 3px solid transparent;
&:focus{
outline: none;
border-left: 3px solid #333;
//background: rgba(249, 224, 31, 0.6);
}
}
}
.total{
text-align: right;
font-weight: 500;
padding: 0 14px;
}
}
button{
margin-top: 20px;
width: 35px;
height: 35px;
border: none;
color: #333;
font-size: 21px;
font-weight: 400;
text-align: center;
cursor: pointer;
background: #f9e01f;
line-height: 35px;
transition: all 0.3s;
margin-right: 20px;
border-radius: 3px;
&:hover{
box-shadow: 0 10px 25px -7px rgba(0,0,0,0.4);
transform: translatey(-3px);
transition: all 0.3s;
}
&:focus{
outline: none;
}
}
}
ES6
"use strict";
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var totalVec = [];
var Header = React.createClass({
displayName: "Header",
render: function render() {
return React.createElement(
"h1",
null,
"Dynamic Table with Checkbox - React"
);
}
});
var ListItem = React.createClass({
displayName: "ListItem",
getInitialState: function getInitialState() {
return { name: this.props.value.name, costo: this.props.value.costo, serviceCheck: this.props.value.checked };
},
render: function render() {
return React.createElement(
"tr",
null,
React.createElement(
"td",
{ className: "checkTd" },
React.createElement(
"div",
{ className: "flexcenter" },
React.createElement("input", { type: "checkbox", name: "serviceCheck", id: "c" + this.props.value.id, checked: this.state.serviceCheck, onChange: this.handleChange }),
React.createElement(
"label",
{ htmlFor: "c" + this.props.value.id },
React.createElement("span", null)
)
)
),
React.createElement(
"td",
null,
React.createElement("input", { type: "text", name: "name", value: this.state.name, onChange: this.handleChange, placeholder: "Service name..." })
),
React.createElement(
"td",
null,
React.createElement("input", { type: "text", name: "costo", value: this.state.costo, onChange: this.handleChange, placeholder: "Service price..." })
)
);
},
handleChange: function handleChange(event) {
var target = event.target;
var name = target.name;
var value = target.type === 'checkbox' ? target.checked : target.value;
this.setState(_defineProperty({}, name, value), this.calcoloTotale);
},
componentDidMount: function componentDidMount() {
var finalValue = 0;
if (this.state.serviceCheck) {
finalValue = this.state.costo * 1.0;
} else {
finalValue = 0;
}
totalVec[this.props.value.id] = finalValue;
this.props.updateGlobalTotal();
},
calcoloTotale: function calcoloTotale() {
var finalValue = 0;
if (this.state.serviceCheck) {
finalValue = this.state.costo * 1.0;
} else {
finalValue = 0;
}
totalVec[this.props.value.id] = finalValue;
this.props.updateGlobalTotal();
}
});
var Table = React.createClass({
displayName: "Table",
getInitialState: function getInitialState() {
return { totale: 0, checked: false };
},
render: function render() {
var _this = this;
return React.createElement(
"div",
null,
React.createElement(
"table",
null,
React.createElement(
"tr",
null,
React.createElement("th", { className: "checkTh" }),
React.createElement(
"th",
null,
"Good / Service"
),
React.createElement(
"th",
null,
"Price \u20AC"
)
),
this.props.items.map(function (prodotto) {
return React.createElement(ListItem, { key: prodotto.id, value: prodotto, updateGlobalTotal: _this.updateGlobalTotal });
}),
React.createElement(
"tr",
{ className: "totalTr" },
React.createElement("td", null),
React.createElement(
"td",
{ className: "totalText" },
"Total (ex VAT):"
),
React.createElement(
"td",
{ className: "totalTR" },
this.state.totale,
" \u20AC"
)
)
)
);
},
/*selectAll: function(source){
this.setState({checked: !this.state.checked}, function(){
var checkboxes = document.getElementsByName('serviceCheck');
for(var i=0, n=checkboxes.length;i<n;i++) {
checkboxes[i].checked = this.state.checked;
}
});
},*/
updateGlobalTotal: function updateGlobalTotal() {
var total = 0;
for (var i = 0; i < this.props.ids; i++) {
total += totalVec[i];
}
this.setState({ totale: total });
}
});
var AddNewRow = React.createClass({
displayName: "AddNewRow",
render: function render() {
return React.createElement(
"div",
null,
React.createElement(
"button",
{ onClick: this.props.onClick },
"+"
),
"Add Service"
);
}
});
var Calculator = React.createClass({
displayName: "Calculator",
getInitialState: function getInitialState() {
return {
counter: this.props.len, lists: this.props.servizi
};
},
render: function render() {
return React.createElement(
"div",
{ className: "container" },
React.createElement(Header, null),
React.createElement(Table, { items: this.state.lists, ids: this.state.counter }),
React.createElement(AddNewRow, { onClick: this.addRow })
);
},
addRow: function addRow() {
this.setState({ counter: this.state.counter + 1 });
var listItem = { id: this.state.counter, product: { name: "", costo: "0" } };
var allItem = this.state.lists.concat([listItem]);
this.setState({ lists: allItem });
}
});
var servizi = [{ "id": "0", "name": "Example 1", "costo": "49", "checked": "true" }, { "id": "1", "name": "Example 2", "costo": "20", "checked": "true" }, { "id": "2", "name": "Example 3", "costo": "100" }, { "id": "3", "name": "Example 4", "costo": "40", "checked": "true" }, { "id": "4", "name": "Example 5", "costo": "1130" }];
ReactDOM.render(React.createElement(Calculator, { servizi: servizi, len: servizi.length }), document.getElementById("render"));