nakome
5/5/2014 - 6:10 PM

A Pen by Moncho Varela.

A Pen by Moncho Varela.

body {
  position: relative;
  height: 100%;
  background:url(http://tinyurl.com/pgmbblo) repeat-y center center fixed transparent;
  -webkit-background-size:cover;
  background-size:cover;
  -moz-background-size:cover;
  font-size: 13px;
  font-family: sans-serif;
  font-weight: 400;
}
a {
  color: #54A0E5;
}
a:hover {
  text-decoration: none;
}
.addNewContact, .moreInfo {
  position:fixed;
  top:0;
  display:inline-block;
  cursor:pointer;
  margin:0;
  z-index:100;
  text-decoration:none;
  padding: 10px 25px 10px 25px;
  color: #ecf0f1;
  opacity:1;
  -webkit-transition:all 0.5s ease;
  transition:all 0.5s ease;
}
.addNewContact:hover, .moreInfo:hover {
  opacity:0.8;
  -webkit-transition:all 0.5s ease;
  transition:all 0.5s ease;
}
.addNewContact {
  left:0;
  background: #3498db;
  border: 1px solid #2980b9;
}
.moreInfo {
  right: 0;
  background: #FF7A00;
  border: 1px solid #995A16;
}
.contactBook {
  display:block;
  margin: 60px auto;
  font-size:13px;
  font-family:monospace;
  font-weight:400;
}
/* List */
.contactBook ul {
  position:relative;
  list-style: none;
  margin: 5px auto;
  padding: 10px;
  width: 450px;
  display: block;
  background: #FCFCFC;
  color: #777;
  border: 1px solid #ECECEC;
  -webkit-box-shadow: 0 5px 5px -5px black;
  box-shadow: 0 5px 5px -5px black;
}
.contactBook ul li b {
  color: #3498db;
}
.contactBook ul li {
  color: #777;
}
.delUser {
  position:absolute;
  top:0;
  right:0;
  display:inline-block;
  cursor:pointer;
  margin:0;
  z-index:100;
  text-decoration:none;
  background: #ecf0f1;
  border: 1px solid #ECECEC;
  border-top:none;
  border-right:none;
  padding: 10px 25px 10px 25px;
  color:#3498db;
  font-family: sans-serif;
  -webkit-transition:all 0.5s ease;
  transition:all 0.5s ease;
}
.delUser:hover {
  color: #fff;
  background-color: #f55;
  border-color: #f44;
  -webkit-transition:all 0.5s ease;
  transition:all 0.5s ease;
}
/* Overlay */
.overlay, .info {
  display:none;
  position:fixed;
  top:0;
  left:0;
  width:100%;
  height:100%;
  margin:0;
  padding:0;
  background: #FF7A00;
  background: rgba(255, 102, 0, 0.86);
  z-index:99999999;
}
.overlay-inner {
  width: 460px;
  height: 460px;
  margin: auto;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  padding:0;
  overflow:auto;
}
.info-inner {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  height: 450px;
  width: 450px;
  padding: 10px;
  background: white;
  border: 1px solid #eee;
  border-radius: 4px;
  -webkit-box-shadow: 0 5px 5px -5px #533F31;
  box-shadow: 0 5px 5px -5px #533F31;
  color: #858585;
}
.logo img {
  display: block;
  width: 100%;
}
div.logo {
  width: 100px;
  height: 100px;
  border: 5px solid #FFFFFF;
  -webkit-box-shadow: 0 0 5px 1px #D8D5D5;
  box-shadow: 0 0 5px 1px #D8D5D5;
  margin: 0 auto;
  padding: 0;
  border-radius: 100%;
  overflow: hidden;
  position: relative;
}
.logo:before {
  content:"";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: -webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0.56)), to(rgba(36, 36, 36, 0.54)));
  background: -webkit-linear-gradient(rgba(255, 255, 255, 0.56), rgba(36, 36, 36, 0.54));
  background: linear-gradient(rgba(255, 255, 255, 0.56), rgba(36, 36, 36, 0.54));
}
.info-inner h1 {
  text-align: center;
  color: #E07818;
  text-transform: uppercase;
  font-size: 20px;
}
.info-inner .deleteDb {
  text-align: center;
  display: block;
  text-decoration: none;
  margin: 5px auto;
  padding: 5px 10px;
  width: 130px;
  background: #F3F3F3;
  border: 1px solid #CFCFCF;
  color: #BBBBBB;
  font-size: 15px;
  font-family: sans-serif;
  -webkit-transition: all 0.5s ease;
  transition: all 0.5s ease;
}
.info-inner .deleteDb:hover {
  background: #FF7000;
  color: white;
  border-color: #C27B11;
  -webkit-transition: all 0.5s ease;
  transition: all 0.5s ease;
}
.closeInfo {
  position: absolute;
  top: 0;
  right: 0;
  margin: 0;
  background: #F3F3F3;
  border: 1px solid #E9E9E9;
  padding: 10px 25px 10px 25px;
  color: #2ABD88;
  display: inline-block;
  text-decoration: none;
  cursor: pointer;
  -webkit-transition: all 0.5s ease;
  transition: all 0.5s ease;
}
.closeInfo:hover {
  background: #F16969;
  color: #FFFFFF;
  -webkit-transition: all 0.5s ease;
  transition: all 0.5s ease;
}
/* show overlay*/
.show {
  display:block;
}
/* forms */
.form {
  margin-right: auto;
  margin-left: auto;
  background: #F8F8F8;
  padding: 20px 30px 20px 30px;
  font: 12px"Helvetica Neue", Helvetica, Arial, sans-serif;
  color: #888;
  text-shadow: 1px 1px 1px #ADADAD;
  border: 1px solid #A5A5A5;
  border-radius: 4px;
  -webkit-border-radius: 4px;
  -webkit-box-shadow: 0 5px 5px -5px #533F31;
  box-shadow: 0 5px 5px -5px #533F31;
}
.form h1 {
  font: 25px"Helvetica Neue", Helvetica, Arial, sans-serif;
  padding: 0px 0px 10px 40px;
  display: block;
  border-bottom: 1px solid #DADADA;
  margin: -10px -30px 30px -30px;
  color: #888;
}
.form h1>span {
  display: block;
  font-size: 11px;
}
.form label {
  display: block;
  margin: 0px 0px 5px;
}
.form label>span {
  float: left;
  width: 80px;
  text-align: right;
  padding-right: 10px;
  margin-top: 10px;
  color: #333;
  font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;
  font-weight: bold;
}
.form input[type="text"], .form input[type="email"], .form input[type="phone"], .form textarea, .form select {
  border: 1px solid #CCC;
  color: #888;
  height: 20px;
  margin-bottom: 16px;
  margin-right: 6px;
  margin-top: 2px;
  outline: 0 none;
  padding: 6px 12px;
  width: 65%;
  border-radius: 4px;
  -webkit-border-radius: 4px;
  -moz-border-radius: 4px;
  font: normal 14px/14px"Helvetica Neue", Helvetica, Arial, sans-serif;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.form select {
  background: #FFF url('down-arrow.png') no-repeat right;
  background: #FFF url('down-arrow.png') no-repeat right);
  appearance:none;
  -webkit-appearance:none;
  -moz-appearance: none;
  text-indent: 0.01px;
  text-overflow:'';
  width: 72%;
  height: 30px;
}
.form textarea {
  height:100px;
}
.form .btn {
  background: #FFF;
  border: 1px solid #CCC;
  padding: 10px 25px 10px 25px;
  color: #333;
  border-radius: 4px;
  display:inline-block;
  cursor:pointer;
  margin:0;
  margin-right:5px;
}
.form .btn:hover {
  color: #333;
  background-color: #EBEBEB;
  border-color: #ADADAD;
}
@media screen and (max-width: 480px) {
  .info-inner {
    height:90%;
    width:90%;
  }
  .contactBook ul {
    width:92%;
  }
  .overlay-inner {
    height:90%;
    width:90%;
  }
  .form {
    padding: 20px 33px 20px 10px;
  }
  .form label>span {
    width:auto;
  }
  .form input[type="text"], .form input[type="email"], .form input[type="phone"], .form textarea, .form select {
    width:100%;
  }
}
var Contact_book = (function() {

  'use strict';

  // JSLint global
  /*global DocumentTouch,document,window,alert,Notification,setInterval,setTimeout,clearTimeout*/

  // click or touch
  var clickEvent = (('ontouchstart' in window) || (window.DocumentTouch && document instanceof DocumentTouch)) ? 'touchstart' : 'click',
      db;

  return {
    // Call events here
    run: function() {
      this.openDb(); // init database
      this.fns(); // init database
    },
    // this.qS('single class');
    qS: function(el) {
      return document.querySelector(el);
    },
    fns: function() {

      var self = this;

      // Show form
      this.qS('.addNewContact').addEventListener(clickEvent, function() {
        self.qS('.overlay').classList.toggle('show');
        document.body.style.overflow = 'hidden';
      }, false);



      // Show info
      this.qS('.moreInfo').addEventListener(clickEvent, function() {
        self.qS('.info').classList.add('show');
        document.body.style.overflow = 'hidden';
      }, false);
      // Hide info
      this.qS('.closeInfo').addEventListener(clickEvent, function() {
        self.qS('.info').classList.remove('show');
        document.body.style.overflow = 'auto';
      }, false);



      // Delete database
      this.qS('.deleteDb').addEventListener(clickEvent, function() {
        var r = indexedDB.deleteDatabase('contactBook');
        self.notifyMe('Success', 'The database has been deleted', 'http://tinyurl.com/pnfdwtp');
        self.qS('.info').classList.remove('show');
        document.body.style.overflow = 'auto';
        return r;
      }, false);
      // on close demo delete database
      /*
                window.onunload = function() {
                    var r = indexedDB.deleteDatabase('contactBook');
                    return r;
                };
                */

      window.addEventListener('resize', function(e) {
        var w = document.documentElement.clientWidth;
        if (w < 500) {
          console.log(e);
          self.notifyMe('Resize', 'You are in mobile version', 'http://tinyurl.com/pnfdwtp');
        }
        return false;
      }, false);




      // Save contact
      this.qS('#saveContact').addEventListener(clickEvent, function(ev) {

        ev.preventDefault();

        var n = self.qS('#contact_name'),
            p = self.qS('#contact_phone'),
            e = self.qS('#contact_email'),
            d = self.qS('#contact_desc');

        // basic if blank add no provide
        if (p.value === '') n.value = 'No provide';
        if (d.value === '') d.value = 'No provide';

        // basic if blank alert
        if (n.value === '' || e.value === '') {
          self.notifyMe('Ups', 'Please give me something', 'http://tinyurl.com/pnfdwtp');
          // clear values
          n.value = ''; p.value = ''; e.value = ''; d.value = '';
          return false;
        }
        var rq = db.transaction(["users"], "readwrite").objectStore("users").add({
          name: n.value,
          phone: p.value,
          email: e.value,
          desc: d.value
        });
        // success
        rq.onsuccess = function(evt) {
          // clear values
          n.value = ''; p.value = ''; e.value = ''; d.value = '';
          // show users
          self.showUsers();
          // toggle class
          self.qS('.overlay').classList.toggle('show');
          document.body.style.overflow = 'auto';
          // Show nofify
          self.notifyMe('Sucess', 'operation performed successfully', 'http://tinyurl.com/pnfdwtp');
        };

        return false;
      });

      // cancel action
      this.qS('#cancel').addEventListener(clickEvent, function(e) {
        e.preventDefault();
        // toggle class
        self.qS('.overlay').classList.toggle('show');
        document.body.style.overflow = 'auto';
        // Show nofify
        self.notifyMe('Cancel', 'Operation canceled', 'http://tinyurl.com/pnfdwtp');
        return false;
      }, false);

    },
    // self.notifyMe('title', 'desc', 'http://tinyurl.com/pnfdwtp');
    notifyMe: function(a, b, c) {
      var Notification = window.Notification || window.mozNotification || window.webkitNotification;

      if (!Notification) {
        return alert(b);
      }

      Notification.requestPermission(function(permission) {
        // console.log(permission);
      });

      return this.show(a, b, c);


    },
    show: function(d, e, f) {
      var self = this,
          instance = new Notification(
            d, {
              body: e,
              icon: f
            }
          );
      instance.onshow = function() {
        // wait 3 seconds and hide
        var t = setTimeout(function() {
          instance.close();
          clearTimeout(t);
        }, 3000);
      };
      instance.onclose = function() {
        // on close window add function
      };
      return false;
    },
    openDb: function() {
      var self = this;

      // https://developer.mozilla.org/en/IndexedDB/Using_IndexedDB
      var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB;
      var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction;
      if (!indexedDB) {
        alert('Sorry this not have support');
      }
      // Make db
      var request = indexedDB.open('contactBook', 1);
      //handle setup
      request.onupgradeneeded = function(e) {

        var thisDb = e.target.result;

        //Create Note
        if (!thisDb.objectStoreNames.contains('users')) {

          var objectStore = thisDb.createObjectStore('users', {
            keyPath: "id",
            autoIncrement: true
          });
        }
      }; // end onupgradeneeded

      // success function
      request.onsuccess = function(e) {
        db = e.target.result;
        // if error
        db.onerror = function(event) {
          console.dir('Database error: ' + event.target.errorCode);
        };
        self.showUsers();
      };

    },
    showUsers: function() {
      var self = this;
      var transaction = db.transaction(['users'], "readwrite");
      var content = '';

      transaction.oncomplete = function(e) {
        self.qS("#contactBook").innerHTML = content;
        self.DeleteUsers();
      };

      transaction.onerror = function(e) {
        console.dir(e);
      };

      var store = transaction.objectStore('users');

      store.openCursor().onsuccess = function(e) {
        var user = e.target.result;

        if (user) {
          content += "<ul>" +
            "<li><b>Name: </b>" + user.value.name + "</li>" +
            "<li><b>Email: </b>" + user.value.email + "</li>" +
            "<li><b>Phone: </b>" + user.value.phone + "</li>" +
            "<li><b>Description: </b>" + user.value.desc + "</li>" +
            "<a href=\"#\" class=\"delUser\"  data-key=\"" + user.key + "\">X</a></ul>";
          user.
          continue ();
        } else {
          content += "<ul>" +
            "<li><b>Name: </b> Nakome </li>" +
            "<li><b>Email: </b> nakome@demo.com </li>" +
            "<li><b>Phone: </b> 0024325232323</li>" +
            "<li><b>Description: </b> This is a demo you can't remove</li>";
        }

      };

    },
    DeleteUsers: function() {
      var self = this,
          delUser = document.querySelectorAll('.delUser');
      Array.prototype.forEach.call(delUser, function(el, i) {
        el.addEventListener(clickEvent, function(e) {
          // confirm first
          var result = confirm("Are you sure you want to delete?");
          if (result === true) {
            e.preventDefault();
            var id = parseInt(this.getAttribute('data-key')),
                tr = db.transaction("users", "readwrite").objectStore("users").delete(id).onsuccess = function(e) {
                  // show users
                  self.showUsers();
                  // Show nofify
                  self.notifyMe('Sucess', 'Delete the id number - ' + id, 'http://tinyurl.com/pnfdwtp');
                };
          }
          return false;
        }, false);
      });
    }
  };
})();

Contact_book.run();
<a href="#" class="addNewContact">Add New</a>
<a href="#" class="moreInfo">More Info</a>
<!-- Book -->
<div class="contactBook" id="contactBook"></div>
<!-- info -->
<div class="info">
  <div class="info-inner">
    <a href="#" class="closeInfo">X</a>

    <div class="logo">
      <img src="http://tinyurl.com/pnfdwtp" alt="">
        </div>

      <h1>Contact list with IndexedDB</h1>
      <p>This is an example database with <a href="http://tinyurl.com/mdfud5w">indexeDb</a>. You can delete the database by pressing the button, the database is automatically erased at the end of the session.</p>
      <p>
        <em>Regards.</em>
      </p>
      <a href="#" class="btn deleteDb">Delete Database</a>
    </div>
  </div>
  <!--- form -->
  <div class="overlay">
    <div class="overlay-inner">
      <form action="#" id="contacts" class="form">
        <label>
          <h1>Add User to Contact list</h1>
        </label>
        <label>
          <span class="label">Name</span>
          <input type="text" name="contact_name" id="contact_name" class="input" />
        </label>
        <label>
          <span class="label">Phone</span>
          <input type="phone" name="contact_phone" id="contact_phone" class="input" />
        </label>
        <label>
          <span class="label">Email</span>
          <input type="email" name="contact_email" id="contact_email" class="input" />
        </label>
        <label>
          <span class="label">Description</span>
          <textarea name="contact_desc" id="contact_desc" cols="30" rows="10"></textarea>
        </label>
        <input type="submit" id="saveContact" class="btn" value="Save Data" />
        <button id="cancel" class="btn">Cancel</button>
      </form>
    </div>
  </div>

IndexedDB demo

This is an example database with indexeDb. You can delete the database by pressing the button, the database is automatically erased at the end of the session.

Regards.

A Pen by Moncho Varela on CodePen.

License.