Arsip Penulis: Hendra,MT

Tentang Hendra,MT

Hendra,S.Kom.,MT. lahir di Tangerang tahun 1975. Menamatkan gelar sarjana komputer di Universitas Bina Nusantara tahun 1998 dan Magister Teknik Elektro di Universitas Trisakti Jakarta tahun 2001. Disamping sebagai praktisi IT di perusahaan IT Services, juga aktif mengajar di Binus University sejak 1999.

Membuat Spiner svg dengan CSS

Spinner svg

Untuk menampilkan animasi lingkaran berputar saat menunggu proses di web sebaiknya kita gunakan html tag karena lebih ringan dari pada menggunakan file gif. Elemen HTML SVG (Scalable Vector Graphics) dapat menampilkan bentuk gambar lingkaran , persegi , poligon atau lainnya.
Kita akan memanfaatkannya untuk membuat animasi lingkaran berputar dengan rule CSS @keyframes animation.

Berikut coding selengkapnya.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <title>Spinner</title>
  <style>
  @keyframes spin {to {stroke-dashoffset:-260;}}/* minus = searah jarum jam */
  .spinner circle {
    fill: #ffff00; /* warna lingkaran */
    stroke: #ff0000; /* warna garis */
    stroke-width: 15; /* tebal garis */
    stroke-linecap: round; /* bentuk ujung garis */
    stroke-dasharray: 0, 0, 80, 50;  /* garis putus */
    stroke-dashoffset: 0; /* tempat mulai putus */
    animation: spin 1s infinite linear; /* kecepatan putar 1 detik */
  }
  </style>
</head>
<body>
  <h3>Membuat Spiner svg dengan CSS</h3>  
  <svg class="spinner" viewBox="0 0 100 100" width="25" height="25">
    <circle cx="50" cy="50" r="40" transform="rotate(-90,50,50)" />
  </svg>
</body>
</html>

Selamat mencoba. Semoga bermanfaat.

Membuat Tabel Responsive

Untuk menampilkan tabel yang panjang diperangkat mobile dengan layar kecil tentu akan menyulitkan kita untuk melihatnya. Kita akan membuat tampilan tabel dengan banyak kolom menjadi baris secara responsive mengikuti ukuran layar smartphone seperti pada gambar di atas.

Berikut coding selengkapnya.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Responsive Table</title>
  <style>
  	table,th,td {border-collapse:collapse;font:12px verdana;border:1px #c0c0c0 solid;color:#808080;}
	table tr:hover td {background:#BBDEFB;}
	table th {background-color:#BBDEFB;color:#1a73eb;padding:8px;}
	table tr:nth-child(odd) {background-color:#E3F2FD;}
	@media only screen and (max-width:500px)  {
		table,thead,tbody,th,td,tr{display:block;}
		thead tr {
			position: absolute;
			top: -9999px;
			left: -9999px;
		}
		tr {margin:0 0 1rem 0;}
		td {
			position: relative;
			padding-left: 160px;
		}
		td:before {
			position: absolute;
			top: 0;
			left: 6px;
			width: 25%;
			padding-right: 10px;
			white-space: nowrap;
			color:#1a73eb;
		}
		td:nth-of-type(1):before { content: "No."; }
		td:nth-of-type(2):before { content: "Nama"; }
		td:nth-of-type(3):before { content: "Versi"; }
		td:nth-of-type(4):before { content: "Tanggal Rilis"; }
		td:nth-of-type(5):before { content: "Versi Kernel Linux"; }
		td:nth-of-type(6):before { content: "Level API"; }
		td:nth-of-type(7):before { content: "Fitur"; }
	}
	</style>
</head>
<body>
<h1>Table Responsive</h1>
<table>
  <thead>
    <tr>
    <th>No.</th>
    <th>Nama</th>
    <th>Versi Android</th>
    <th>Tanggal Rilis</th>
	<th>Versi Kernel Linux</th>
	<th>Level API</th>
	<th>Fitur</th>
	</tr>
  </thead>
  <tbody>
    <tr>
    <td>1</td>
    <td>Froyo</td>
    <td>2.2</td>
    <td>10 Mei 2010</td>
	<td>?</td>
	<td>8</td>
	<td>USB tethering and Wi-Fi hotspot functionality</td>
  </tr>
  <tr>
    <td>2</td>
    <td>Gingerbread</td>
    <td>2.3</td>
    <td>6 Desember 2010</td>
	<td>2.6.35</td>
	<td>9-10</td>
	<td>Support for Near Field Communication (NFC)</td>
  </tr>
  <tr>
    <td>3</td>
    <td>Honeycomb</td>
    <td>3.0</td>
    <td>22 Februari 2011</td>
	<td>2.6.36</td>
	<td>11-13</td>
	<td>Increased ability of applications to access files on the SD card</td>
  </tr>
  <tr>
    <td>4</td>
    <td>Ice Cream Sandwich</td>
    <td>4.0</td>
    <td>19 Oktober 2011</td>
	<td>3.0.1</td>
	<td>14-15</td>
	<td>Improvements to graphics, databases, spell-checking and Bluetooth functionality</td>
  </tr>
  <tr>
    <td>5</td>
    <td>Jelly Bean</td>
    <td>4.1</td>
    <td>9 Juli 2012</td>
	<td>3.0.31-39</td>
	<td>16-18</td>
	<td>Bluetooth Audio/Video Remote Control Profile (AVRCP) 1.3 support</td>
  </tr>
  <tr>
    <td>6</td>
    <td>Kitkat</td>
    <td>4.4</td>
    <td>31 Oktober 2013</td>
	<td>3.10</td>
	<td>19-20</td>
	<td>UI updates for Google Maps navigation and alarmsv</td>
  </tr>
  <tr>
    <td>7</td>
    <td>Lollipop</td>
    <td>5.0</td>
    <td>12 November 2014</td>
	<td>3.16</td>
	<td>21-22</td>
	<td>Ability to join Wi-Fi networks and control paired Bluetooth devices from quick settings</td>
  </tr>
  <tr>
    <td>8</td>
    <td>Marshmallow</td>
    <td>6.0</td>
    <td>28 Mei 2015</td>
	<td>3.18</td>
	<td>23</td>
	<td>Doze mode, which reduces CPU speed while the screen is off in order to save battery life</td>
  </tr>
  <tr>
    <td>9</td>
    <td>Nougat</td>
    <td>7.0</td>
    <td>22 Agustus 2016</td>
	<td>4.4</td>
	<td>24-25</td>
	<td>Touch/display performance improvements</td>
  </tr>
  <tr>
    <td>10</td>
    <td>Oreo</td>
    <td>8.0</td>
    <td>21 Agustus 2017</td>
	<td>4.10</td>
	<td>26-27</td>
	<td>Bluetooth battery level for connected devices, accessible in Quick Settings</td>
  </tr>
</table>

</body>
</html>

Selamat mencoba. Semoga bermanfaat.

Tombol Switch dengan CSS

Kali ini kita akan mencoba membuat tombol geser kiri kanan (switch button) dengan menggunakan CSS lalu mengambil statusnya dengan javascript.
Kita manfaatkan properti CSS: ‘appearance’ pada elemen input checkbox untuk manipulasi tampilan field checkbox biasa menjadi tombol geser.
Kita juga menfaatkan pseudo-element ‘:before’ untuk manipulasi tampilan content di dalam tombol switch.

Berikut coding selengkapnya.

<!doctype html>
<html lang="en">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>CSS Switch Botton</title>
	<style>
	.toggle {
	  -webkit-appearance: none;
	  -moz-appearance: none;
	  appearance: none;
	  width: 98px;
	  height: 30px;
	  position: relative;
	  border-radius: 20px;
	  display: inline-block;
	  overflow: hidden;
	  outline: none;
	  border: none;
	  cursor: pointer;
	  background-color: #707070;
	  transition: background-color ease 0.3s;
	}
	.toggle:before {
	  content: "Depan Belakang";
	  display: block;
	  position: absolute;
	  z-index: 2;
	  width: 25px;
	  height: 25px;
	  background: #fff;
	  left: 2px;
	  top: 2px;
	  border-radius: 50%;
	  font:bold 12px/28px Helvetica;
	  text-indent: -40px;
	  word-spacing: 30px;
	  color: #fff;
	  text-shadow: -1px -1px rgba(0,0,0,0.15);
	  white-space: nowrap;
	  box-shadow: 0 1px 2px rgba(0,0,0,0.2);
	  transition: all cubic-bezier(0.3, 1.5, 0.7, 1) 0.3s;
	}
	.toggle:checked {background: #4CD964;}
	.toggle:checked:before {left:70px;}
	</style>
</head>
<body>
<h2 id="status">Belakang</h2>
<input id="swbtn" class="toggle" type="checkbox" />
<script>
	let swbtn = document.getElementById("swbtn");
	let status = document.getElementById("status");
	swbtn.addEventListener("click", function(){
		if (swbtn.checked) {
			status.innerHTML = "Depan";
		} else if (!swbtn.checked)	{
			status.innerHTML = "Belakang";
		}
	});
</script>
</body>
</html>

Selamat mencoba. Semoga bermanfaat.

Sumber: https://danklammer.com/articles/simple-css-toggle-switch/

Sort dan Search Data Tabel

JSSortSearchData

Fitur pengurutan (sort) data dan pencarian (search) data merupakan fitur yang umum diperlukan dalam aplikasi web. Kita bisa membuatnya dengan bantuan library seperti jquery dan datatables.
Kali ini saya akan memberikan cara membuat fitur sort dan search data dalam table menggunakan fungsi javascript tanpa library.

Ada 2 fungsi yang kita buat:

  • fungsi searchTable()
  • fungsi sortTable(), yang dapat melakukan sort data huruf (alphabet), angka (numeric) dan tanggal (date)

Fungsi resetHeader() digunakan untuk mengembalikan kolom header tabel supaya ketika kolom header di click, tanda panah ke atas ↑ (sort ascending) atau ke bawah ↓ (sort descending)  hanya tampil di kolom yang di click. Header kolom disimpan dalam variable array headerCol.

Berikut coding selengkapnya.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Sort Search Data in Table</title>
<style>
html,body{font:12px Arial,Helvetica,sans-serif;}
.cari {padding:5px;border:1px solid #ddd;}
#table1 {border-collapse:collapse;}
#table1 th {padding:12px;text-align:center;background-color:#f0f0f0;cursor:pointer;}
#table1 th, #table1 td {border:1px solid #ddd;padding:6px;}
#table1 tr:nth-child(odd){background-color: #f1f1f1;}
#table1 tr:hover {background-color:#f8f8f8;}
</style>
</head>
<body>
<h2>Tabel Versi Android</h2>
<p><input type="text" id="1" class="cari" onkeyup="searchTable(1)" size="10" placeholder="Cari Nama...">
<input type="text" id="3" class="cari" onkeyup="searchTable(3)" size="10" placeholder="Cari Rilis..."></p>
<table id="table1">
  <tr>
    <th onclick="sortTable('num',0)">No.</th>
	<th onclick="sortTable('alfa',1)">Nama</th>
    <th onclick="sortTable('num',2)">Versi</th>
    <th onclick="sortTable('date',3)">Rilis</th>
  </tr>
  <tr>
    <td>1</td>
	<td>Froyo</td>
    <td>2.2</td>
    <td>10 May 2010</td>
  </tr>
  <tr>
    <td>2</td>
	<td>Gingerbread</td>
    <td>2.3</td>
    <td>6 Dec 2010</td>
  </tr>
  <tr>
    <td>3</td>
	<td>Honeycomb</td>
    <td>3.0</td>
    <td>22 Feb 2011</td>
  </tr>
  <tr>
    <td>4</td>
	<td>Ice Cream Sandwich</td>
    <td>4.0</td>
    <td>19 Oct 2011</td>
  </tr>
  <tr>
    <td>5</td>
	<td>Jelly Bean</td>
    <td>4.1</td>
    <td>9 Jul 2012</td>
  </tr>
  <tr>
    <td>6</td>
	<td>Kitkat</td>
    <td>4.4</td>
    <td>31 Oct 2013</td>
  </tr>
  <tr>
    <td>7</td>
	<td>Lollipop</td>
    <td>5.0</td>
    <td>12 Nov 2014</td>
  </tr>
  <tr>
    <td>8</td>
	<td>Marshmallow</td>
    <td>6.0</td>
    <td>28 May 2015</td>
  </tr>
  <tr>
    <td>9</td>
	<td>Nougat</td>
    <td>7.0</td>
    <td>22 Aug 2016</td>
  </tr>
  <tr>
    <td>10</td>
	<td>Oreo</td>
    <td>8.0</td>
    <td>21 Aug 2017</td>
  </tr>
</table>
<script>
var cols = document.getElementById('table1').rows[0].cells;
var headerCol = new Array();
for (var i = 0; i < (cols.length); i++) {
	headerCol[i]=cols[i].textContent;
}
	
function searchTable(col) {
  var input, filter, table, tr, td, i;
  input = document.getElementById(col);
  filter = input.value.toUpperCase();
  table = document.getElementById("table1");
  tr = table.getElementsByTagName("tr");
  for (i = 0; i < tr.length; i++) {
    if(col=='1') td = tr[i].getElementsByTagName("td")[1];
	else if(col=='3') td = tr[i].getElementsByTagName("td")[3];
    if (td) {
      if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
        tr[i].style.display = "";
      } else {
        tr[i].style.display = "none";
      }
    }     
  }
}
function resetHeader(){
	var c = document.getElementById('table1').rows[0].cells;
	for (var i = 0; i < (c.length); i++) {
		c[i].textContent=headerCol[i];
	}
}
function sortTable(d,n) {
  var table, rows, col_header, switching, i, x, y, a,b,shouldSwitch, dir = "asc", switchcount = 0;
  table = document.getElementById("table1");
  rows = table.getElementsByTagName("tr");
  col_header  = rows[0].getElementsByTagName("th")[n];
  switching = true;
  while (switching) {
	switching = false;    
    for (i = 1; i < (rows.length - 1); i++) {
		shouldSwitch = false;
		x = rows[i].getElementsByTagName("td")[n];
		y = rows[i + 1].getElementsByTagName("td")[n];
		if (d=="num")
		{	a = Number(x.innerHTML);
			b = Number(y.innerHTML);
		} else if (d=="alfa")
		{	a = x.innerHTML.toLowerCase();
			b = y.innerHTML.toLowerCase();
		} else if (d=="date")
		{	a = Date.parse(x.innerHTML);
			b = Date.parse(y.innerHTML);
		}
		if (dir == "asc") {
			if (a > b) {
			  shouldSwitch = true;
			  break;
			}
		} else if (dir == "desc") {
			if (a < b) {
			  shouldSwitch = true;
			  break;
			}
		}
    }
    if (shouldSwitch) {
      rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
      switching = true;
      switchcount ++;
    } else {
      if (switchcount == 0 && dir == "asc") {
        dir = "desc";
        switching = true;
      }
    }	
  }
  resetHeader();
  if (dir == "asc") {col_header.textContent =  headerCol[n] + " \u2191";}
  if (dir == "desc") {col_header.textContent = headerCol[n] + " \u2193";}
}
</script>
</body>
</html>

 Selamat mencoba dan semoga bermanfaat.

CSS Hide Show Field

css_showhide

css_showhide

Halo Semua, kali ini saya akan memberikan cara bagaimana menampilkan dan menyembunyikan (Show Hide Toggle) elemen html hanya dengan menggunakan CSS saja.
Mengapa dengan CSS bukan JavaScript? Ya, JavaScript memang bisa melakukan apa saja yang bisa dilakukan dengan CSS, tapi lebih simpel dengan CSS, Keep It Simple Smart! 🙂
CSS menyediakan pseudo-class “:checked” yang bisa kita gunakan pada selector CSS, dalam hal ini id=trigger.
Tanda tilde (~) pada selector .trigger:checked ~ .toggle1 digunakan untuk memilih element toggle1 yang ditempatkan secara langsung setelah memilih (:checked) element .trigger.

Berikut coding selengkapnya.

<!doctype html>
<html>
<head>
<title>CSS Toggle</title>
<style>
   .toggle1 {display:none;}
   .trigger:checked ~ .toggle1 {display:inline;}
</style>
</head>
<body>
<div> Warna Favorit: </div>
<input type="radio" name="warna" id="Merah"/><label for="Merah">Merah</label>
<input type="radio" name="warna" id="Hijau"/><label for="Hijau">Hijau</label>
<input type="radio" name="warna" id="Biru"/><label for="Biru">Biru</label>
<input type="radio" name="warna" class="trigger" id="Lainnya"/><label for="Lainnya">Lainnya : </label>
<input type="text" name="warna" class="toggle1" autofocus/>
</body>
</html>

Anda tertarik, selamat mencoba.

Sumber: http://css-workshop.com/css-show-hide-div-without-javascript/

Send HTML Email dengan Attachment

Pada posting saya terdahulu tentang cara mengirim email dengan form di PHP, kali ini saya akan sharing tentang cara mengirim email dengan attachment yang diambil langsung dari local.
Berikut ini coding lengkapnya.

<?php
$from = "Amir <amir@gmail.com>";
$to = "budi@yahoo.com , cica@hotmail.com";
$subject = "Ini File Excelnya";
$message = "<b>Terlampir file excel</b><br/>Thanks.";
$filename = "Dummy File1.xls";
	
$uid = md5(uniqid(time()));
$header = "From: ".$from."\r\n";
$header .= "Reply-To: ".$from."\r\n";
$header .= "MIME-Version: 1.0\r\n";

if (file_exists($filename))
{ $header .= "Content-Type:multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";
  $nmessage = "--".$uid."\r\n";
  $nmessage .= "Content-type:text/html; charset=\"UTF-8\"\r\n";
  $nmessage .= "Content-Transfer-Encoding:quoted-printable\r\n\r\n";
  $nmessage .= $message."\r\n\r\n";
  $nmessage .= "--".$uid."\r\n";
  $content = chunk_split(base64_encode(file_get_contents($filename)));
  $nmessage .= "Content-Type:application/octet-stream; name=\"".$filename."\"\r\n";
  $nmessage .= "Content-Transfer-Encoding:base64\r\n";
  $nmessage .= "Content-Disposition:attachment; filename=\"".$filename."\"\r\n\r\n";
  $nmessage .= $content."\r\n\r\n";
  $nmessage .= "--".$uid."--";
  $message = $nmessage;
} else {
  $header .= "Content-Type:text/html; boundary=\"".$uid."\"\r\n\r\n";
}
	
if (mail($to, $subject, $message, $header)) {
  echo '<p>Mail has been sent! <br />Please check both inbox and spam folder! </p>'; 
} else {
  echo '<p>Mail can not be sent! Please try again later! </p>';
}  

Anda bisa mengirimkan pesan email dengan format HTML pada variable $message.
Panjang pesan bisa lebih dari 1000 karakter, termasuk tag HTML-nya.

Jika tidak ingin mengirimkan file attachment Anda cukup kosongkan variable $filename=”;

Silakan Anda pakai coding ini di aplikasi php Anda. Selamat mencoba dan semoga sukses.

Membuat Tooltip yang Mengikuti Pointer Mouse

tooltips

Sekarang kita coba membuat tooltip seperti gambar di atas. Yang membuat saya tertarik adalah tooltip ini bisa bergerak mengikuti gerakan pointer mouse di sepanjang text link.

Tampilan kotak tooltip kita buat dengan menggunakan CSS lalu untuk menggerakan kotak tersebut kita pakai javascript

<script>
var tooltip = document.querySelectorAll('.tooltip');
document.addEventListener('mousemove', fn, false);
function fn(e) {
  for (var i = tooltip.length; i--;) {
    tooltip[i].style.left = e.pageX + 'px';
    tooltip[i].style.top = e.pageY + 'px';
  }
}
</script>

Untuk coding lengkapnya silakan coba di bawah ini.

<!DOCTYPE html>
<html>
<head>
  <title>CSS Tooltip</title>
  <style>
	a:hover .tooltip 
	{ display: block; }
	.tooltip {
	  display: none;
	  position: absolute;
	  z-index: 1000;
	  margin: 15px;
	  border:2px solid #0094ff;
	  border-radius: 8px 8px 0 0;
	  width:400px;
	  font: 12px Arial;
	}
	.tooltip h3 {
	  background:#0094ff;
	  color:#ffffff;
	  margin:0;
	  padding:8px;
	}
	.tooltip p {
	  background:#f0f0f0;
	  color:#000000;
	  margin:0;padding:8px; 
	}
	</style>
</head>
<body>
<a href="#" >Ini adalah link dengan tooltip mengikuti pointer mouse
<div class="tooltip">
    <h3>Contoh Teks Lorem Ipsum yang Lazim Digunakan</h3>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,
	sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
	Ut enim ad minim veniam, quis nostrud exercitation ullamco
	laboris nisi ut aliquip ex ea commodo consequat. 
	Duis aute irure dolor in reprehenderit in voluptate 
	velit esse cillum dolore eu fugiat nulla pariatur. 
	Excepteur sint occaecat cupidatat non proident, 
	sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</a> 

<script>
var tooltip = document.querySelectorAll('.tooltip');
document.addEventListener('mousemove', fn, false);
function fn(e) {
  for (var i = tooltip.length; i--;) {
    tooltip[i].style.left = e.pageX + 'px';
    tooltip[i].style.top = e.pageY + 'px';
  }
}
</script>
</body>
</html>

Selamat mencoba, semoga sukses.

Membuat Slideshow dengan CSS3

Hampir di setiap website kita temui slideshow. Kali ini saya berikan contoh membuat slideshow yang sangat simple hanya dengan menggunakan CSS, tanpa javascript.

CSS3 memiliki property “animation” yang akan kita gunakan untuk mengganti 1 gambar dengan gambar lainnya.

Pertama kita berikan nama animation : slideshow
dengan durasi: 9 detik (3 gambar masing masing tampil 3 detik)
dan kecepatan tiap slide berjalan sama atau linear.
Supaya slideshow ini jalan terus maka kita berikan animation-iteration-count: infinite.

img {
 animation-name: slideshow;
 animation-duration: 9s;
 animation-timing-function: linear;
 animation-iteration-count: infinite;
}

4 baris property “animation” poada css tersebut bisa kita singkat penulisannya (shorthand CSS) menjadi:
animation: slideshow 9s linear 0s infinite;

Kemudian kita buat @Keyframes untuk animation-name: slideshow untuk memberikan efek transisi antar gambar tersebut.

@keyframes slideshow {
   25% { opacity: 1;}
   33.33% { opacity: 0;}
   91.66% { opacity: 0;}
   100% { opacity: 1;}
}

Berikut coding selengkapnya.

<!DOCTYPE HTML>
<html>
<head>
<title>Slideshow CSS3</title>
<style>
div {margin: 100px 200px; }
img {
  position: absolute;
  z-index: 3;
  animation: slideshow 9s linear 0s infinite;
}
img:nth-child(2) {
  z-index: 2;
  animation: slideshow 9s linear 3s infinite;
}
img:nth-child(3) {
   z-index: 1;
  animation: slideshow 9s linear 6s infinite;
}
@keyframes slideshow {
   25% { opacity: 1;}
   33.33% { opacity: 0;}
   91.66% { opacity: 0;}
   100% { opacity: 1;}
}
</style>
</head>
<body>
<div>
	<img src="images/img_1.jpg" alt="Gambar 1"/>
	<img src="images/img_2.jpg" alt="Gambar 2"/>
	<img src="images/img_3.jpg" alt="Gambar 3"/></div>
</body>
</html>

Membuat Popup Window dengan CSS

modal-box-dengan-css

Bagaimana cara membuat popup window tanpa javascript?
Kita bisa membuat modal dialog box atau yang dikenal popup window hanya dengan menggunakan CSS3 dan HTML5
Berikut ini codingnya :

<!DOCTYPE html>
<head>
	<title>Modal box dengan CSS3</title>
	<style>
	.modalDialog {
		position: fixed;
		font-family: Arial, Helvetica, sans-serif;
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
		background: rgba(0,0,0,0.8);
		z-index: 99999;
		opacity:0;
		transition: opacity 200ms ease-in;
		pointer-events: none;
	}
	.modalDialog:target {opacity:1;	pointer-events: auto;}
	.modalDialog > div {
		width: 400px;
		position: relative;
		margin: 10% auto;
		padding: 5px 20px 13px 20px;
		border-radius: 10px;
		background: #fff;
		background: linear-gradient(#fff, #aaa);
	}
	.close:hover { background:#00d9ff; }
	.close {
		background: #606061;
		color: #FFFFFF;
		line-height: 25px;
		position: absolute;
		text-align: center;
		top: -10px;
		right: -12px;
		width: 24px;
		text-decoration: none;
		font-weight: bold;
		border-radius: 12px;
		box-shadow: 1px 1px 3px #000;
	}
	
input[type=text], input[type=password] {
    width: 100%;
    padding: 12px 20px;
    margin: 8px 0;
    display: inline-block;
    border: 1px solid #ccc;
    box-sizing: border-box;
}
button {
    background-color: #4CAF50;
    color: white;
    padding: 14px 20px;
    margin: 8px 0;
    border: none;
    cursor: pointer;
    width: 100%;
}
span.psw {
    float: right;
}

	</style>
</head>
<body>
<p><a href="#openModal">Open Modal</a></p>
<p><a href="#iklan">IKLAN</a></p>
<p><a href="#login">Login</a></p>


<div id="openModal" class="modalDialog">
	<div>
		<a href="#" title="Close" class="close">X</a>
		<h2>Perhatian!</h2>
		<p>Ini adalah contoh kotak dialog modal yang dibuat hanya dengan menggunakan CSS3 saja, tanpa javascript.</p>
		<p>Silakan diubah sesuai kebutuhan, seperti membuat iklan pop-up yang tampil saat website terbuka,
		atau membuat form login/register user.</p>
	</div>
</div>

<div id="iklan" class="modalDialog">
	<div>
		<a href="#" title="Close" class="close">X</a>
		<h3>Dapatkan Buku Proyek PHP & MySQL :</h3> 
		<h2>"Membuat Helpdesk System Berbasis OOP dan PDO dengan PHP"</h2>
		<p>di toko buku online Lokomedia<br/>
		Harga: Rp 50.000,-</p>
	</div>
</div>

<div id="login" class="modalDialog">
	<div>
		<a href="#" title="Close" class="close">X</a>
		<h3>Please Log in</h3> 
		<form  action="action_page.php">
		<label><b>Username</b></label>
		<input type="text" placeholder="Enter Username" name="uname" required>
		<label><b>Password</b></label>
		<input type="password" placeholder="Enter Password" name="psw" required>
		<button type="submit">Log in</button>
		<input type="checkbox" id="Remember" checked="checked"> <label for="Remember">Remember me</label>
		<span class="psw"><a href="#login">Forgot password?</a></span>
	</form>
	</div>
</div>

</body>
</html>

Selamat mencoba, semoga sukses.

Membuat Script Login yang Aman dengan PHP dan MySQL

Sebuah aplikasi berbasis web umumnya membutuhkan halaman login bagi user/member untuk mengakses halaman tertentu. Halaman itu tentunya harus aman dari resiko pembobolan dan pencurian data.

Kali ini saya akan mencoba memberikan sedikit tips cara membuat script login yang aman dengan PHP dan MySQL.
Script ini hanya memberikan gambaran tentang bagaimana cara mengamankan halaman login dari ancaman dan resiko pembobolan dan pencurian data user/member. Script ini juga menggunakan teknik enkripsi password dengan fungsi hash(sha512) dan salt.
Saya tidak meng-klaim script ini benar-benar dapat membuat halaman login yang aman karena masalah keamanan system web tentu lebih luas dan kompleks.
Semoga tips berikut ini bisa menambah pengetahuan Anda dalam mengamankan aplikasi web Anda.

Script Login berikut ini diharapkan dapat menahan halaman web Anda dari serangan:
SQL Injections
Session Hijacking
Network Sniffing
Cross Site Scripting
Brute Force Attacks

Script ini jalan di PHP minimal versi 5.4 dan MySQL versi 5.0

Pertama kita siapkan databasenya.

1. Create Database login:

CREATE DATABASE `login`;

2. Create user untuk akses database tersebut. Hindari menggunakan user default root MySql.

CREATE USER 'admin_db'@'localhost' IDENTIFIED BY 'eKcGZr59zAa2BEWU';
GRANT SELECT, INSERT, UPDATE ON `login`.* TO 'sec_user'@'localhost';

3. Create tabel login_attempts untuk menyimpan data percobaan login oleh user. Dengan demikian kita bisa menahan serangan brute force attack

CREATE TABLE `login_attempts` (
    `user_id` INT(11) NOT NULL,
    `time` VARCHAR(30) NOT NULL
) ENGINE=InnoDB

4. Create tabel members dengan 5 field: id, username, email, password dan salt.
Khusus pada field password kita gunakan tipe CHAR(128) untuk menyimpan data password yang di encrypt dengan fungsi hash(sha512) dan salt .

CREATE TABLE `secure_login`.`members` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `username` VARCHAR(30) NOT NULL,
    `email` VARCHAR(50) NOT NULL,
    `password` CHAR(128) NOT NULL,
    `salt` CHAR(128) NOT NULL 
) ENGINE = InnoDB;

5. Insert 1 row data user admin ke tabel members untuk test login.

INSERT INTO `login`.`members` VALUES(1, 'admin_user', 'admin@kampushendra.com',
'00807432eae173f652f2064bdca1b61b290b52d40e429a7d295d76a71084aa96c0233b82f1feac45529e0726559645acaed6f3ae58a286b9f075916ebf66cacc',
'f9aab579fc1b41ed0c44fe4ecdbfcdb4cb99b9023abb241a6db833288f4eea3c02f76e0d35204a8695077dcf81932aa59006423976224be0390395bae152d4ef');

Berikutnya kita siapkan script PHP-nya.

1. Create folder “includes” di luar folder root aplikasi web Anda (misal: xampp/apps/includes/)

2. Create file psl-config.php berikut ini lalu simpan di folder includes:

<?php
/** These are the database login details */  
define("HOST", "localhost");    // The host you want to connect to.
define("USER", "admin_db");    // The database username. 
define("PASSWORD", "eKcGZr59zAa2BEWU");  // The database password. 
define("DATABASE", "login");     // The database name.
define("CAN_REGISTER", "any");
define("DEFAULT_ROLE", "member");
define("SECURE", FALSE);    // FALSE for Dev, TRUE for Prod using https
?>

3. Create file db_connect.php berikut ini lalu simpan di folder includes:

<?php
include_once 'psl-config.php';   // As functions.php is not included
$mysqli = new mysqli(HOST, USER, PASSWORD, DATABASE);

4. Create file functions.php berikut ini lalu simpan di folder includes:

<?php
include_once 'psl-config.php';
function sec_session_start() {
    $session_name = 'sec_session_id';   // Set a custom session name
    $secure = SECURE;
    // This stops JavaScript being able to access the session id.
    $httponly = true;
    // Forces sessions to only use cookies.
    if (ini_set('session.use_only_cookies', 1) === FALSE) {
        header("Location: ../error.php?err=Could not initiate a safe session (ini_set)");
        exit();
    }
    // Gets current cookies params.
    $cookieParams = session_get_cookie_params();
    session_set_cookie_params($cookieParams["lifetime"],
        $cookieParams["path"], 
        $cookieParams["domain"], 
        $secure,
        $httponly);
    // Sets the session name to the one set above.
    session_name($session_name);
    session_start();              // Start the PHP session 
    session_regenerate_id(true);  // regenerated the session, delete the old one. 
}

//This login function will check the email and password against the database. 
//It will return true if there is a match.
function login($email, $password, $mysqli) {
    // Using prepared statements means that SQL injection is not possible. 
    if ($stmt = $mysqli->prepare("SELECT id, username, password, salt 
        FROM members  WHERE email = ?  LIMIT 1")) {
        $stmt->bind_param('s', $email);  // Bind "$email" to parameter.
        $stmt->execute();    // Execute the prepared query.
        $stmt->store_result();
        // get variables from result.
        $stmt->bind_result($user_id, $username, $db_password, $salt);
        $stmt->fetch();
 
        // hash the password with the unique salt.
        $password = hash('sha512', $password . $salt);
        if ($stmt->num_rows == 1) {
            // If the user exists we check if the account is locked
            // from too many login attempts 
 
            if (checkbrute($user_id, $mysqli) == true) {
                // Account is locked 
                // Send an email to user saying their account is locked
                return false;
            } else {
                // Check if the password in the database matches
                // the password the user submitted.
                if ($db_password == $password) {
                    // Password is correct!
                    // Get the user-agent string of the user.
                    $user_browser = $_SERVER['HTTP_USER_AGENT'];
                    // XSS protection as we might print this value
                    $user_id = preg_replace("/[^0-9]+/", "", $user_id);
                    $_SESSION['user_id'] = $user_id;
                    // XSS protection as we might print this value
                    $username = preg_replace("/[^a-zA-Z0-9_\-]+/", 
                                                                "", 
                                                                $username);
                    $_SESSION['username'] = $username;
                    $_SESSION['login_string'] = hash('sha512', 
                              $password . $user_browser);
                    // Login successful.
                    return true;
                } else {
                    // Password is not correct
                    // We record this attempt in the database
                    $now = time();
                    $mysqli->query("INSERT INTO login_attempts(user_id, time)
                                    VALUES ('$user_id', '$now')");
                    return false;
                }
            }
        } else {
            // No user exists.
            return false;
        }
    }
}

//This checkbrute function will hold login tries for 2 hour if 5 logins failed.
function checkbrute($user_id, $mysqli) {
    // Get timestamp of current time 
    $now = time();
     // All login attempts are counted from the past 2 hours. 
    $valid_attempts = $now - (2 * 60 * 60);
     if ($stmt = $mysqli->prepare("SELECT time 
                             FROM login_attempts 
                             WHERE user_id = ? 
                            AND time > '$valid_attempts'")) {
        $stmt->bind_param('i', $user_id);
         // Execute the prepared query. 
        $stmt->execute();
        $stmt->store_result();
         // If there have been more than 5 failed logins 
        if ($stmt->num_rows > 5) {
            return true;
        } else {
            return false;
        }
    }
}
//This login_check function will Check if all session variables are set
function login_check($mysqli) {
    if (isset($_SESSION['user_id'], $_SESSION['username'], $_SESSION['login_string'])) {
        $user_id = $_SESSION['user_id'];
        $login_string = $_SESSION['login_string'];
        $username = $_SESSION['username'];
         // Get the user-agent string of the user.
        $user_browser = $_SERVER['HTTP_USER_AGENT'];
         if ($stmt = $mysqli->prepare("SELECT password FROM members WHERE id = ? LIMIT 1")) {
            // Bind "$user_id" to parameter. 
            $stmt->bind_param('i', $user_id);
            $stmt->execute();   // Execute the prepared query.
            $stmt->store_result();
             if ($stmt->num_rows == 1) {
                // If the user exists get variables from result.
                $stmt->bind_result($password);
                $stmt->fetch();
                $login_check = hash('sha512', $password . $user_browser);
                if ($login_check == $login_string) {
                    // Logged In!!!! 
                    return true;
                } else {
                    // Not logged in 
                    return false;
                }
            } else {
                // Not logged in 
                return false;
            }
        } else {
            // Not logged in 
            return false;
        }
    } else {
        // Not logged in 
        return false;
    }
}
//This login_check function will sanitizes URL from the PHP_SELF server variable
function esc_url($url) {
     if ('' == $url) {
        return $url;
    }
    $url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\\x80-\\xff]|i', '', $url);
    $strip = array('%0d', '%0a', '%0D', '%0A');
    $url = (string) $url;
     $count = 1;
    while ($count) {
        $url = str_replace($strip, '', $url, $count);
    }
    $url = str_replace(';//', '://', $url);
    $url = htmlentities($url);
    $url = str_replace('&amp;', '&', $url);
    $url = str_replace("'", ''', $url);
    if ($url[0] !== '/') {
        // We're only interested in relative links from $_SERVER['PHP_SELF']
        return '';
    } else {
        return $url;
    }
}

5. Create file process_login.php berikut ini lalu simpan di folder aplikasi web Anda (Misal: //xampp/htdocs/myweb/)

<?php
include_once 'db_connect.php';
include_once 'functions.php';
sec_session_start(); // custom secure way of starting a PHP session.
if (isset($_POST['email'], $_POST['p'])) {
    $email = $_POST['email'];
    $password = $_POST['p']; // The hashed password.
    if (login($email, $password, $mysqli) == true) {
        // Login success 
        header('Location: ../protected_page.php');
    } else {
        // Login failed 
        header('Location: ../index.php?error=1');
    }
} else {
    // The correct POST variables were not sent to this page. 
    echo 'Invalid Request';
}

6. Create file logout.php berikut ini lalu simpan di folder aplikasi web Anda (Misal: //xampp/htdocs/myweb/)

<?php
include_once 'functions.php';
sec_session_start();
// Unset all session values 
$_SESSION = array();
// get session parameters 
$params = session_get_cookie_params();
// Delete the actual cookie. 
setcookie(session_name(),'', time() - 42000,
        $params["path"], 
        $params["domain"], 
        $params["secure"], 
        $params["httponly"]);
// Destroy session 
session_destroy();
header('Location: ../index.php');

7. Create file index.php berikut ini lalu simpan di folder aplikasi web Anda (Misal: //xampp/htdocs/myweb/)
File index.php adalah halaman login Anda.

<?php
include_once 'includes/db_connect.php';
include_once 'includes/functions.php';
sec_session_start();
if (login_check($mysqli) == true) {
    $logged = 'in';
} else {
    $logged = 'out';
}
?>
<!DOCTYPE html>
<html>
<head>
    <title>Secure Login: Log In</title>
    <script type="text/JavaScript" src="js/sha512.js"></script> 
    <script type="text/JavaScript" src="js/forms.js"></script> 
</head>
<body>
        <?php
        if (isset($_GET['error'])) {
            if(@$_SESSION['error']==2)
		echo '<p class="error">Account is locked due to 5 failed logins!</p>';
	    else 
		echo '<p class="error">Error Logging In!</p>';
        }
        ?> 
        <form action="includes/process_login.php" method="post" name="login_form">                      
            Email: <input type="text" name="email" />
            Password: <input type="password" name="password" id="password"/>
            <input type="button" value="Login" 
                   onclick="formhash(this.form, this.form.password);" /> 
        </form>
<?php
        if (login_check($mysqli) == true) {
            echo '<p>Currently logged ' . $logged . ' as ' . htmlentities($_SESSION['username']) . '.</p>';
 
            echo '<p>Do you want to change user? <a href="includes/logout.php">Log out</a>.</p>';
        } else {
            echo '<p>Currently logged ' . $logged . '.</p>';
            echo "<p>If you don't have a login, please <a href='register.php'>register</a></p>";
                }
?>      
</body>
</html>

8. Create file protected_page.php berikut ini lalu simpan di folder aplikasi web Anda
File protected_page.php adalah halaman member yang bisa diakses setelah berhasil login.

<?php
include_once 'includes/db_connect.php';
include_once 'includes/functions.php';
sec_session_start(); 
if(login_check($mysqli) == false) {
    echo 'You are not authorized to access this page, please login.';
    exit();
}

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Secure Login: Protected Page</title>
        <link rel="stylesheet" href="styles/main.css" />
    </head>
    <body>
        <?php if (login_check($mysqli) == true) : ?>
            <p>Welcome <?php echo htmlentities($_SESSION['username']); ?>!</p>
            <p>
                This is an example protected page.  To access this page, users
                must be logged in.  At some stage, we'll also check the role of
                the user, so pages will be able to determine the type of user
                authorised to access the page.
            </p>
            <p>Return to <a href="index.php">login page</a></p>
        <?php else : ?>
            <p>
                <span class="error">You are not authorized to access this page.</span> 
Please <a href="index.php">login</a>.
            </p>
        <?php endif; ?>
    </body>
</html>

9. Create folder js di dalam folder aplikasi web Anda (Misal: //xampp/htdocs/myweb/js/)

10. Download file sha512.js dan forms.js lalu simpan di folder js

Setelah semua file siap, Anda dapat mencoba script login ini di web browser Anda.

Untuk script selengkapnya bisa Anda download dari sumber berikut ini:
https://github.com/peredurabefrog/phpSecureLogin