JSFiddle - React, Tailwind, and code Playground
by corinnekm
HTML
<body>
<h1>Contacts</h1>
<table id="contacts-table">
<tr id="contacts-head">
<th>ID</th>
<th>First name</th>
<th>Last name</th>
<th>Email</th>
<th>Actions</th>
</tr>
</table>
<form id="contacts-form">
<div class="item text">
<label>First name:</label>
<div class="field">
<input type="text" name="first_name" />
</div>
</div>
<div class="item text">
<label>Last name:</label>
<div class="field">
<input type="text" name="last_name" />
</div>
</div>
<div class="item text">
<label>Email:</label>
<div class="field">
<input type="text" name="email" />
</div>
</div>
<div class="button-wrapper">
<div class="item button">
<div class="field">
<input type="button" id="contacts-op-discard" value="Discard" />
</div>
</div>
<div class="item button button-default">
<div class="field">
<input type="submit" id="contacts-op-save" value="Save" />
</div>
</div>
</div>
<input type="hidden" name="id_entry" value="0" />
</form>
</body>
CSS
a {
color: #0068D2;
cursor: pointer;
}
a:link, a:visited {
text-decoration: none;
color: #0068D2;
}
a:hover, a:active {
text-decoration: underline;
color: #0068D2;
}
body {
font: 12px/18px"Lucida Grande", "Lucida Sans Unicode", sans-serif;
}
#contacts-table {
border-collapse: collapse;
}
#contacts-table, #contacts-table th, #contacts-table td {
padding: 8px 16px;
text-align: left;
border: 0px solid #B9BABE;
}
#contacts-table th {
font-weight: bold;
font-size: 14px;
color: #29344B;
}
#contacts-table td {
color: #000;
}
#contacts-table tr:nth-child(2n) {
background: #E8EDFF;
}
#contacts-form {
padding: 10px;
}
.text input, .button input {
padding: 5px;
margin: 0;
border: 1px solid #ccc;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
border-radius: 2px;
}
#contacts-form .item {
margin: 3px 0;
}
#contacts-form label, #contacts-form .field {
display: inline-block;
color: #0C0B07;
}
#contacts-form label {
width: 110px;
font-weight: bold;
text-align: right;
color: #666;
}
#contacts-form .text input {
width: 176px;
padding: 3px;
}
#contacts-form .button {
display: inline-block;
}
#contacts-form .button-wrapper {
padding-left: 113px;
}
.button input {
padding: 4px 8px;
color: #343434;
background-color: #fdfdfd;
background: -moz-linear-gradient(#fdfdfd, #e1e1e1);
background: -webkit-gradient(linear, 0 0, 0 100%, from(#fdfdfd), to(#e1e1e1));
}
.button-default input {
font-weight: bold;
color: #fff;
background-color: #7ca0c7;
background: -moz-linear-gradient(#acc6e1, #7ca0c7);
background: -webkit-gradient(linear, 0 0, 0 100%, from(#acc6e1), to(#7ca0c7));
border-color: #5b80b2;
}
JavaScript
var Contacts = {
index: window.localStorage.getItem("Contacts:index"),
$table: document.getElementById("contacts-table"),
$form: document.getElementById("contacts-form"),
$button_save: document.getElementById("contacts-op-save"),
$button_discard: document.getElementById("contacts-op-discard"),
init: function () {
// initialize storage index
if (!Contacts.index) {
window.localStorage.setItem("Contacts:index", Contacts.index = 1);
}
// initialize form
Contacts.$form.reset();
Contacts.$button_discard.addEventListener("click", function (event) {
Contacts.$form.reset();
Contacts.$form.id_entry.value = 0;
}, true);
Contacts.$form.addEventListener("submit", function (event) {
var entry = {
id: parseInt(this.id_entry.value),
first_name: this.first_name.value,
last_name: this.last_name.value,
email: this.email.value
};
if (entry.id == 0) { // add
Contacts.storeAdd(entry);
Contacts.tableAdd(entry);
} else { // edit
Contacts.storeEdit(entry);
Contacts.tableEdit(entry);
}
this.reset();
this.id_entry.value = 0;
event.preventDefault();
}, true);
// initialize table
if (window.localStorage.length - 1) {
var contacts_list = [],
i, key;
for (i = 0; i < window.localStorage.length; i++) {
key = window.localStorage.key(i);
if (/Contacts:\d+/.test(key)) {
contacts_list.push(JSON.parse(window.localStorage.getItem(key)));
}
}
if (contacts_list.length) {
contacts_list.sort(function (a, b) {
return a.id < b.id ? -1 : (a.id > b.id ? 1 : 0);
...