Tag Archive bootstrap

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 เพียงอย่าเดียว

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 เพิ่มเติม

slick: responsive และ ความกว้าง

เจอปัญหาว่า slick เวลาวางต่อไปอีก block ต่อจากตัวอื่น มันจะตกลงมา หรือแสดงไม่ครบแล้วแต่กรณี เพราะว่า block มันจะยาวเท่าหน้า windows เลย ไม่ใช่ container หรือ div ที่ห่อมันเอาไว้เหมือน slideshow ตัวอื่นๆ

ลองหลายวิธีจนพบว่าวิธีของคุณ kirana Slick Carousel Center Padding Demo นั้นดีที่สุด

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <title>kenwheeler.slick: responsive</title>
    <link href="../vendor/components/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css" />
    <link href="../vendor/kenwheeler/slick/slick/slick.css" rel="stylesheet" type="text/css" />
    <link href="../vendor/kenwheeler/slick/slick/slick-theme.css" rel="stylesheet" type="text/css" />
    <link href="../vendor/twbs/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" type="text/css">
    <link href="theme.css" rel="stylesheet" type="text/css" />
    <style>
        .slickContainer {
            background: #1f6d38;
            color: #333;
            margin: 0 auto;
            padding: 40px;
            width: 80%;
        }
    </style>
</head>

<body>

    <div class="container">
        <div class="row">
            <div class="col-1 col-sm-2 col-md-3 col-lg-4 col-xl-5">
                <h1>sidebar</h1>
            </div>
            <div class="col-11 col-sm-10 col-md-9 col-lg-8 col-xl-7">
                <div class="slickContainer">
                    <div id="slideshowA">
                        <div><b>Acrobat</b><img alt="Acrobat" src="http://www.avatarsdb.com/avatars/acrobat.gif">
                            <p>แสดง acrobat.gifจาก http://www.avatarsdb.com</p>
                        </div>
                        <div><b>Cat Rain</b><img alt="Cat Rain" src="http://www.avatarsdb.com/avatars/cat_rain.gif">
                            <p>แสดง cat_rain.gifจาก http://www.avatarsdb.com</p>
                        </div>
                        <div><b>Dota Windranger</b><img alt="Dota Windranger" src="http://www.avatarsdb.com/avatars/dota_windranger.jpg">
                            <p>แสดง dota_windranger.jpgจาก http://www.avatarsdb.com</p>
                        </div>
                        <div><b>Fighting Funny</b><img alt="Fighting Funny" src="http://www.avatarsdb.com/avatars/fighting_funny.gif">
                            <p>แสดง fighting_funny.gifจาก http://www.avatarsdb.com</p>
                        </div>
                        <div><b>Fire 01</b><img alt="Fire 01" src="http://www.avatarsdb.com/avatars/fire_01.gif">
                            <p>แสดง fire_01.gifจาก http://www.avatarsdb.com</p>
                        </div>
                        <div><b>German Shepherd Puppy</b><img alt="German Shepherd Puppy" src="http://www.avatarsdb.com/avatars/german_shepherd_puppy.jpg">
                            <p>แสดง german_shepherd_puppy.jpgจาก http://www.avatarsdb.com</p>
                        </div>
                        <div><b>Girl With Cigarette</b><img alt="Girl With Cigarette" src="http://www.avatarsdb.com/avatars/girl_with_cigarette.jpg">
                            <p>แสดง girl_with_cigarette.jpgจาก http://www.avatarsdb.com</p>
                        </div>
                        <div><b>Hidden Cat</b><img alt="Hidden Cat" src="http://www.avatarsdb.com/avatars/hidden_cat.jpg">
                            <p>แสดง hidden_cat.jpgจาก http://www.avatarsdb.com</p>
                        </div>
                        <div><b>Im Fabulous</b><img alt="Im Fabulous" src="http://www.avatarsdb.com/avatars/im_fabulous.jpg">
                            <p>แสดง im_fabulous.jpgจาก http://www.avatarsdb.com</p>
                        </div>
                        <div><b>One Direction</b><img alt="One Direction" src="http://www.avatarsdb.com/avatars/One_Direction.jpg">
                            <p>แสดง One_Direction.jpgจาก http://www.avatarsdb.com</p>
                        </div>
                        <div><b>Panda Kiss</b><img alt="Panda Kiss" src="http://www.avatarsdb.com/avatars/panda_kiss.gif">
                            <p>แสดง panda_kiss.gifจาก http://www.avatarsdb.com</p>
                        </div>
                        <div><b>PC User</b><img alt="PC User" src="http://www.avatarsdb.com/avatars/pc_user.gif">
                            <p>แสดง pc_user.gifจาก http://www.avatarsdb.com</p>
                        </div>
                        <div><b>Riri Queen</b><img alt="Riri Queen" src="http://www.avatarsdb.com/avatars/riri_queen.gif">
                            <p>แสดง riri_queen.gifจาก http://www.avatarsdb.com</p>
                        </div>
                        <div><b>Tennessee</b><img alt="Tennessee" src="http://www.avatarsdb.com/avatars/tennessee.jpg">
                            <p>แสดง tennessee.jpgจาก http://www.avatarsdb.com</p>
                        </div>
                        <div><b>Tuxedo M</b><img alt="Tuxedo M" src="http://www.avatarsdb.com/avatars/Tuxedo_m.jpg">
                            <p>แสดง Tuxedo_m.jpgจาก http://www.avatarsdb.com</p>
                        </div>
                        <div><b>Tuxedo Mask</b><img alt="Tuxedo Mask" src="http://www.avatarsdb.com/avatars/tuxedo_mask.jpg">
                            <p>แสดง tuxedo_mask.jpgจาก http://www.avatarsdb.com</p>
                        </div>
                        <div><b>Ugly Face</b><img alt="Ugly Face" src="http://www.avatarsdb.com/avatars/ugly_face.gif">
                            <p>แสดง ugly_face.gifจาก http://www.avatarsdb.com</p>
                        </div>
                        <div><b>Waifu</b><img alt="Waifu" src="http://www.avatarsdb.com/avatars/waifu.jpg">
                            <p>แสดง waifu.jpgจาก http://www.avatarsdb.com</p>
                        </div>
                        <div><b>Wolf In The Snow</b><img alt="Wolf In The Snow" src="http://www.avatarsdb.com/avatars/wolf_in_the_snow.jpg">
                            <p>แสดง wolf_in_the_snow.jpgจาก http://www.avatarsdb.com</p>
                        </div>
                        <div><b>Xerxes Break Kevin</b><img alt="Xerxes Break Kevin" src="http://www.avatarsdb.com/avatars/xerxes_break_kevin.jpg">
                            <p>แสดง xerxes_break_kevin.jpgจาก http://www.avatarsdb.com</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <script src="../vendor/components/jquery/jquery.min.js"></script>
    <script src="../vendor/kenwheeler/slick/slick/slick.min.js"></script>
    <script>
        $(function() {
            $('#slideshowA').slick({
    "autoplay": true,
    "autoplaySpeed": 3000,
    "centerMode": true,
    "infinite": true,
    "responsive": [{
            "breakpoint": 1140,
            "settings": {
                "dots": true,
                "infinite": true,
                "slidesToScroll": 4,
                "slidesToShow": 4
            }
        }, {
            "breakpoint": 960,
            "settings": {

                "dots": true,
                "infinite": true,
                "slidesToScroll": 3,
                "slidesToShow": 3
            }
        }, {
            "breakpoint": 720,
            "settings": {
                "dots": false,
                "infinite": false,
                "slidesToScroll": 2,
                "slidesToShow": 2
            }
        },
        {
            "breakpoint": 540,
            "settings": "unslick"
        }
    ],
    "speed": 300,
    "variableWidth": true,
    "zIndex": 2
});

});
    </script>
</body>

</html>

เมื่อสร้าง container ครอบตัว slide show และร่วมกับคำสั่ง responsive จะเห็นได้ว่าสามารถควบคุมการแสดงผลได้ดียิ่งขึ้น

แก้ validation error ใน YII 2

ฟอร์มของ yii จะมีการแจ้งเตือนถ้าหากพบว่าข้อมูล input ที่เรากรอกใน form ไม่ถูกต้อง โดยจะทำกรอบอินพุต ป้าย label เป็นสีแดงและมีข้อความแสดงใน help-block เพิ่มขึ้นมา บางครั้งก็ทำให้ฟอร์มที่จัดไว้แน่นๆ ไม่ใช่แบบบรรทัดละกล่องข้อความตามแบบเว็บสมัยใหม่ เวลาเจอความผิดพลาด มันก็จะถีบตัวอื่นออกไป หรือดูอัดแน่นเกินไปจนดูไม่สวย

ก็สามารถเอาออกได้โดยใช้ form template เหมือนเดิม โดยยังสามารถทำ validation ได้ตามปกติ

วิธีการคือ

  1. เปิดไฟล์ _form.php ใน view เป้าหมาย
  2. เปลี่ยน
    <?php $form = ActiveForm::begin(['id' => 'login-form']); ?>
    

    เป็น

    <?php $form = ActiveForm::begin([
        'fieldConfig' => [
            'template' => "{label}\n{input}\n{hint}"
        ],
        'id' => 'login-form'
    ]); ?>
    

อย่าลืมเปลี่ยน id นะครับ

ถ้าใช้

use yii\bootstrap\ActiveForm;

ให้เปลี่ยน template เป็น

'template' => "{label}\n{beginWrapper}\n{input}\n{hint}\n{endWrapper}"

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>';