Category Archive CSS

Byphunsanit

Bootstrap: dynamic tabs hash

เพราะว่า dynamic tabs ของ Bootstrap มันจะไม่เลือก tabs จาก hash หรือเครื่องหมาย # ใน url ถ้าต้องการให้แสดงแท็บที่ต้องการจาก links ต้องเขียน code เพิ่มเติมอีกเล็กน้อย

<!doctype html>
<html>

<head>
<meta charset="utf-8">
<title>Bootstrap: Dynamic Tabs With Hash</title>
<link href="../vendor/twbs/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" type="text/css">
</head>

<body>
<div class="container">
<h2>Dynamic Tabs With Hash</h2>

<input id="tabindex" name="tabindex" type="text">

<ul class="nav nav-tabs">

<li class="nav-item">
<a class="active nav-link show" data-toggle="tab" href="#menu1">Menu 1</a>
</li>

<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#menu2">Menu 2</a>
</li>

<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#menu3">Menu 3</a>
</li>
</ul>

<div class="tab-content">

<div id="menu1" class="active fade in show tab-pane">
<h3>Menu 1</h3>
<p>นาย</p>
</div>

<div id="menu2" class="fade tab-pane">
<h3>Menu 2</h3>
<p>พิชญ์</p>
</div>

<div id="menu3" class="fade tab-pane">
<h3>Menu 3</h3>
<p>พันธุ์สนิท</p>
</div>

</div>

</div>

<script src="../vendor/components/jquery/jquery.min.js"></script>
<script src="../vendor/twbs/bootstrap/dist/js/bootstrap.min.js"></script>
<script>
$(document).ready(function () {

let hash = window.location.hash.substr(1);
let tabindex = $('#tabindex');
if (hash != tabindex.val()) {
$('a[href="#' + hash).click();
tabindex.val(hash);
}

});
</script>

</body>

</html>

เมื่อเปิดหน้าเว็บมาจาก url ที่ใส่ # ของแท็บที่ต้องการมา เช่น http://localhost/snippets/Bootstrap/tabs.dynamic.hash.html#menu2 แท็บก็จะเปิดหน้าที่ถูกต้องตามที่ต้องการ แทนที่จะดูจาก class active เพียงอย่าเดียว

Byphunsanit

Bootstrap: Dynamic Tabs

สามารถสร้างเนื้อหาที่เป็นรูปแบบ tabs หรือที่เรียกว่า dynamic tabs ได้โดยใช้แค่ jQuery และ Bootstrap

ตัวอย่าง

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <title>Bootstrap: Dynamic Tabs</title>
    <link href="../vendor/twbs/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" type="text/css">
</head>

<body>
    <div class="container">
        <h2>Bootstrap: Dynamic Tabs</h2>

        <ul class="nav nav-tabs">

            <li class="nav-item">
                <a class="active nav-link show" data-toggle="tab" href="#menu1">Menu 1</a>
            </li>

            <li class="nav-item">
                <a class="nav-link" data-toggle="tab" href="#menu2">Menu 2</a>
            </li>

            <li class="nav-item">
                <a class="nav-link" data-toggle="tab" href="#menu3">Menu 3</a>
            </li>
        </ul>

        <div class="tab-content">

            <div id="menu1" class="active fade in show tab-pane">
                <h3>Menu 1</h3>
                <p>นาย</p>
            </div>

            <div id="menu2" class="fade tab-pane">
                <h3>Menu 2</h3>
                <p>พิชญ์</p>
            </div>

            <div id="menu3" class="fade tab-pane">
                <h3>Menu 3</h3>
                <p>พันธุ์สนิท</p>
            </div>

        </div>

    </div>

    <script src="../vendor/components/jquery/jquery.min.js"></script>
    <script src="../vendor/twbs/bootstrap/dist/js/bootstrap.min.js"></script>

</body>

</html>

โดยพื้นฐานคือใส่ data-toggle=”tab” ใน tag a ที่ลิงค์ไปยัง hash ที่เป็น id ของ div ที่มี class tab-pane ที่อยู่ใน div class tab-content ก็จะทำงานได้แล้วโดยไม่ต้องกำหนดสคริปเพิ่มเติมอีก แต่ถ้าหากต้องการเลือกแท็บจากลิงค์ให้อ่าน Bootstrap: dynamic tabs hash เพิ่มเติม

Byphunsanit

ทำ checkbox / radio สวยๆ

สิ่งที่ css framework อย่าง bootstrapt ไม่ยอมทำซักทีคือ ทำให้ checkbox หรือ radio ออกมาเหมือนๆกันทุก browser ทำให้การออกแบบฟอร์มทำได้ไม่สวยงามเท่าที่ควร

แก้ได้โดยใช้ fronteed/icheck มาวางภาพทับ checkbox หรือ radio ไว้ และทำการจับ event แทนตัว input จริงๆ

ตัวอย่าง

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery iCheck</title>
<link href="vendor/twbs/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href="vendor/fronteed/icheck/skins/square/green.css" rel="stylesheet" type="text/css">
</head>
<body>
<?php
if(count($_POST)) {
   echo '<pre>', print_r($_POST, true), '</pre>';
}
?>
<div class="container">
  <form action="jQuery.icheck.php" id="formA" method="post">
    <fieldset class="form-group row">
      <legend class="col-form-legend col-sm-2">Checkbox</legend>
      <div class="col-sm-10">
        <div class="form-check">
          <label class="form-check-label">
            <input class="form-check-input" checked id="chk1" name="checkbox1" type="checkbox" value="checkbox1">
            Check me out </label>
        </div>
        <div class="form-check">
          <label class="form-check-label">
            <input class="form-check-input" id="chk2" name="checkbox2" type="checkbox" value="checkbox2">
            Check me </label>
        </div>
        <div class="form-check">
          <label class="form-check-label">
            <input class="form-check-input" id="chk3" name="checkbox3" type="checkbox" value="checkbox3" disabled>
            Check is disabled </label>
        </div>
      </div>
    </fieldset>
    <fieldset class="form-group row">
      <legend class="col-form-legend col-sm-2">Radios</legend>
      <div class="col-sm-10">
        <div class="form-check">
          <label class="form-check-label">
            <input class="form-check-input" checked id="gridRadios1" name="radio" type="radio" value="option1">
            Check me out </label>
        </div>
        <div class="form-check">
          <label class="form-check-label">
            <input class="form-check-input" id="gridRadios2" name="radio" type="radio" value="option2">
            Check me </label>
        </div>
        <div class="form-check disabled">
          <label class="form-check-label">
            <input class="form-check-input" disabled id="gridRadios3" name="radio" type="radio" value="option3">
            Check is disabled </label>
        </div>
      </div>
    </fieldset>
    <div class="form-group row">
      <label class="col-sm-2"></label>
      <div class="col-sm-10 text-right">
        <button class="btn btn-lg btn-primary" type="submit">Save</button>
      </div>
    </div>
  </form>
  <hr>
  <button class="btn btn-lg btn-info" id="ajaxBtn" type="button">AJAX Value</button>
</div>
<script src="vendor/components/jquery/jquery.min.js"></script>
<script src="vendor/fronteed/icheck/icheck.min.js"></script>
<script>
$(function () {

  /* style */
  $('input').iCheck({
     "checkboxClass": "icheckbox_square-green",
     "radioClass": "iradio_square-green",
  });

  /* event */
  $('input').on('ifChanged', function(event) {
    console.log(event);

    alert('checked = ' + event.target.checked);
    alert('id = ' + event.target.id);
    alert('name = ' + event.target.name);
    alert('type = ' + event.target.type);
    alert('value = ' + event.target.value);
  });

  /* value */
  $('#ajaxBtn').click(function() {
     var formData = $('#formA').serializeArray();
     var message = '';

     $.each(formData, function (index, item) {
  	  message +='\n' +  index + ' ' +  item.name + ' = '+item.value;
     });

     alert(message);

  });

});
</script>
</body>
</html>

สามารถเปลี่ยนรูปแบบอื่นได้โดยดู style ได้จาก iCheck v1.0.1 @FRONTEED จากนั้นเปลี่ยน css ไฟล์ และ checkboxClass หรือ radioClass ไม่ก็ทำภาพพื้นหลังใหม่และเขียน css ของตัวเองก็ได้

Byphunsanit

YII 2 : Horizontal / inline form

ตามปกติ form ของ yii ที่ใช้ GII generate ออกมาจะเป็นรูปแบบ label บรรทัดหนึ่ง input อีกบรรทัดหนึ่ง อ่านง่าย สวยงามพอสมควร แต่อาจจะไม่ถูกใจบรรดาหัวหน้าอนุรักษ์นิยมทั้งหลาย

yii มีอีกทางเลือกให้ใช้ทำฟอร์ม คือ มี Horizontal form ให้เลือกใช้ yii bootstrap activeform (Horizontal form) อีกตัว

วิธีการคือ

  1. เปิดไฟล์ _form.php ใน view เป้าหมาย
  2. เปลี่ยน use yii\widgets\ActiveForm; เป็น use yii\bootstrap\ActiveForm; ถ้าไม่เปลี่ยนจะเจอ error Setting unknown property: yii\widgets\ActiveForm::layout
  3. เปลี่ยน
    $form = ActiveForm::begin();

    เป็น

    $form = ActiveForm::begin([
        'fieldConfig' => [
            'horizontalCssClasses' => [
                'label' => 'col-sm-2',
                'offset' => 'col-sm-offset-2',
                'wrapper' => 'col-sm-10'
            ]
        ],
        'layout' => 'horizontal'
    ]);
  4. สำเร็จแล้ว ฟอร์มจะเปลี่ยนเป็นรูปแบบเหมือนกับ Bootstrap Horizontal form โดย

    • layout คือ จะวางฟอร์มเป็นแบบไหน มีให้เลือก คือ default, horizontal และ inline
    • label คือ ค่า grid ของ label
    • wrapper คือ ความกว้างของช่อง input
    • offset คือ การเว้นระยะของพวก checkbox ตั้งไว้เท่ากับ label จะได้ตรงกันพอดี

    เสร็จแล้ว หรือจะใช้การจัด code แบบของผมก็ได้ครับ ไม่อยากสลับ php เข้าออก ไปๆ มาๆ

    <?php
    
    use yii\helpers\Html;
    use yii\bootstrap\ActiveForm;
    
    ?>
    
    <div class="user-form">
    <?php
    $form = ActiveForm::begin([
        'fieldConfig' => [
            'horizontalCssClasses' => [
                'label' => 'col-sm-2',
                'offset' => 'col-sm-offset-2',
                'wrapper' => 'col-sm-10'
            ]
        ],
        'layout' => 'horizontal'
    ]);
    
    echo $form->field($model, 'username')->textInput(),
    $form->field($model, 'email')->textInput(),
    $form->field($model, 'status')->checkbox(array('label'=>'enable')),
    '<div class="form-group">',Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']);
    ActiveForm::end();
    echo'</div>';
Byphunsanit

ตรวจฟอร์มด้วย HTML 5 / jQuery Validation Plugin

HTML 5 มี attribute อย่าง required ช่วยตรวจสอบฟอร์ม แต่มันยังไม่สมบูรณ์ เช่น ใช้ required กับกลุ่ม checkbox ไม่ได้ มันตรวจได้แค่เลือก checkbox ตัวนั้นๆเท่านั้น จะบังคับให้เลือก 1 ในตัวเลือกไม่ได้

ทำให้ต้องใช้เจคิวรี่อย่าง jQuery Validation Plugin ช่วย

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery Validation : html5 / inline</title>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet" type="text/css">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
      <script src="http://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="http://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<form action="validation.php" enctype="multipart/form-data" id="formA" method="post">
	<div class="form-group">
		<p>เครื่องปรุง</p>
		<!-- ใส่ required ใน input ตัวแรกก็พอ -->
		<label>
			<input type="checkbox" name="flavoring[]" value="1" required>
			เกลือ</label>
		<label>
			<input type="checkbox" name="flavoring[]" value="2">
			น้ำตาล</label>
		<label>
			<input type="checkbox" name="flavoring[]" value="3">
			น้ำปลา</label>
		<label>
			<input type="checkbox" name="flavoring[]" value="4">
			พริกป่น</label>
		<!-- แสดง error ตรงนี้ อย่าลืม  class="error" -->
		<label for="flavoring[]" class="error"></label>
	</div>
	<div class="form-inline">
		<div class="form-group"><!-- input text ธรรมดา -->
			<label>สั่งวันที่
				<input type="text" name="dateOrder" required data-rule-date="true">
			</label>
		</div>
		<div class="form-group"><!-- input date -->
			<label>ส่งวันที่
				<input type="date" name="dateDelivery" required>
			</label>
		</div>
	</div>
	<div class="form-inline">
		<div class="form-group"><!-- min and max length -->
			<label>
				<input type="text" id="sendto" name="sendto" required minlength="10" maxlength="50" data-rule-email="true">
				Email</label>
		</div>
		<div class="form-group"> <!-- data-rule-equalTo id sendto -->
			<label>
				<input type="email" id="sendtoSame" name="sendtoSame" required data-rule-equalTo="#sendto">
				Email Confirm</label>
		</div>
	</div>
	<div class="form-inline">
		<div class="form-group">
			<label>รับเฉพาะภาพ
				<input type="file" name="image" accept="image/*">
			</label>
		</div>
		<div class="form-group"><!-- style input -->
			<label class="btn btn-primary">รับแต่ .jpeg
				<input type="file" name="jpeg" accept="image/jpeg" style="display:none;">
			</label>
		</div>
	</div>
	<div class="form-inline">
		<div class="form-group">
			<label>ข้าวเปล่า
				<input type="text" name="rice" data-rule-number="true">
			</label>
		</div>
		<div class="form-group">
			<label>แคปหมู (ปลีก สั่งเป็นขีดได้ เช่น 0.5)
				<input type="number" name="friedPorkSkin" step="0.1">
			</label>
		</div>
		<div class="form-group"><!-- custom message -->
			<label>แคปหมู (ส่ง kg.)
				<input type="number" name="friedPorkSkin" data-rule-digits="true" data-message-digits="ขายแต่เป็น KG ครับ">
			</label>
		</div>
	</div>
	<div class="form-group">
		<p>เส้น</p>
		<!-- ใส่ required ใน input ตัวแรกก็พอ -->
		<label>
			<input type="radio" name="noodle" value="1" required>
			เส้นหมี่</label>
		<label>
			<input type="radio" name="noodle" value="2">
			เส้นเล็ก</label>
		<label>
			<input type="radio" name="noodle" value="3">
			เส้นใหญ่</label>
		<label>
			<input type="radio" name="noodle" value="4">
			เส้นหมี่</label>
		<!-- แสดง error ตรงนี้ อย่าลืม  class="error" -->
		<label for="noodle" class="error"></label>
	</div>
	<div class="form-group">
		<label>ลวกนานมั๋ย
			<input type="range" min="2" max="8" step="1">
		</label>
	</div>
	<div class="form-inline">
		<div class="form-group">
			<label>เว็บบริษัท
				<input type="text" name="officeUrl" data-rule-url="true">
			</label>
		</div>
		<div class="form-group">
			<label>เว็บส่วนตัว
				<input type="url" name="blogUrl">
			</label>
		</div>
	</div>
	<input type="submit" value="Submit">
</form>
<script src="assets/jQuery/jquery.min.js"></script>
<script src="plus/jQuery/jquery-validation/jquery.validate.min.js"></script>
<script>
$(function()
{
	$('#formA').validate();
});
</script>
</body>
</html>