Tag Archive filter

DataTable: ดัดแปลง / คัดลอก ข้อมูล

แนวคิดคือ คัดลอกข้อมูลที่เลือกเอาไว้จาก DataTables ตัวหนึ่งไปยังอีกตัวหนึง

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="author" content="Pitt Phunsanit">
    <title>DataTables: Transfer Data To Another Table</title>
    <link href="../vendor/twbs/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" type="text/css">
    <link href="../vendor/twbs/bootstrap/dist/css/bootstrap-theme.min.css" rel="stylesheet" type="text/css">
    <link href="../vendor/datatables/datatables/media/css/dataTables.bootstrap.min.css" rel="stylesheet" type="text/css">
    <link href="../assets/fronteed/icheck/skins/minimal/red.css" rel="stylesheet" type="text/css">
</head>

<body>
    <table class="table table-bordered table-hover table-striped" id="filtersTableA" width="100%"></table>
    <button class="btn btn-success" id="copyBtn" type="button">Copy Data To Table</button>
    <table class="table table-bordered table-hover table-striped" id="tableA" width="100%"></table>
    <script src="../vendor/components/jquery/jquery.min.js"></script>
    <script src="../vendor/datatables/datatables/media/js/jquery.dataTables.min.js"></script>
    <script src="../vendor/datatables/datatables/media/js/dataTables.bootstrap.min.js"></script>
    <script src="../assets/fronteed/icheck/icheck.min.js"></script>

    <script src="DataTables.js"></script>

    <script src="data.json.transferDataToAnotherTable.js"></script>
</body>

</html>

ส่วนที่เขียนเป็นฟังก์ชั่นกลางไว้ให้ไฟล์อื่นเรียกใช้

function iCheckBulk(dataTableArea, dataTableObject) {
    dataTableArea.on('ifChanged', '.checkAll', function(event) {

        var datas = dataTableObject.data();
        var inputs = $('input:checkbox, input:radio', dataTableArea);

        if (event.target.checked) {
            var enable = '1';
            var state = 'check';
        } else {
            var enable = '0';
            var state = 'uncheck';
        }

        $.each(datas, function(index, value) {
            value.enable = enable;

            dataTableObject.row(index).data(value);
        });

        iCheckInit($('input:checkbox, input:radio', dataTableArea));
    });

}

/* change filtersTable data value on input name enables is change */
function iCheckChange(filtersTableArea, filtersTableObject, dataTableObject) {
    $('tbody', filtersTableArea).on('ifChanged', 'input[name="enables[]"]', function(event) {

        event.stopPropagation();

        var row = $(this).closest('tr');

        var data = filtersTableObject.row(row).data();

        if ($(this).is(':checked')) {
            $(this).attr('checked', 1);
            data.enable = true;
        } else {
            $(this).attr('checked', 0);
            data.enable = false;
        }
        filtersTableObject.row(row).data(data);

        iCheckInit(row);
    });
}

function iCheckCopy(dataTableObject, filtersTableObject, pkField) {
    $('#copyBtn').click(function() {

        /* loop current data (pkField) in current dataTableObject */
        var datas = dataTableObject.data();
        var hasKeys = new Array();
        $.each(datas, function(index, value) {
            hasKeys.push(value[pkField]);
        });

        var datasChoose = filtersTableObject.data();

        $.each(datasChoose, function(index, value) {
            /* add row to filtersTableObject if input name enables[] is checked */
            if (value.enable == true && hasKeys.indexOf(value[pkField]) == -1) {
                dataTableObject
                    .row.add(value)
                    .draw()
                    .node();
            }
        });

    });

}

function iCheckInit(selector) {
    selector.iCheck({
        checkboxClass: 'icheckbox_minimal-red',
        radioClass: 'iradio_minimal-red',
    });
}

ไฟล์ที่ทำหน้าที่ควบคุมการคัดลอกข้อมูล

$(function() {

    dataTableA = $('#dataTableA');
    filtersTableA = $('#filtersTableA');
    tableA = $('#tableA');

    filtersTable = filtersTableA
        .DataTable({
            "ajax": {
                "data": function(parameters) {},
                "method": "POST",
                "url": "data.json.php",
            },
            "columns": [{
                    "orderable": false,
                    "render": function(data, type, row, meta) {
                        return parseInt(meta.row) + parseInt(meta.settings._iDisplayStart) + 1;
                    },
                    "title": 'No.',
                    "width": "10px",
                },
                {
                    "orderable": false,
                    "render": function(data, type, row, meta) {
                        if (row.enable == '1') {
                            var checked = ' checked';
                        } else {
                            var checked = '';
                        }

                        return '<input' + checked + ' name="enables[]" type="checkbox" value="' + row.DISTRICT_CODE + '">';
                    },
                    "title": '<input class="checkAll" type="checkbox">',
                    "width": "10px",
                },
                {
                    "orderable": false,
                    "render": function(data, type, row, meta) {
                        if (row.enable == '1') {
                            return '<span class="glyphicon glyphicon-ok"></span>';
                        } else {
                            return '<span class="glyphicon glyphicon-remove"></span>';
                        }
                    },
                    "title": "Enable",
                    "width": "10px",
                }, {
                    "data": "DISTRICT_CODE",
                    "title": "District Code",
                    "width": "90px",
                }, {
                    "data": "DISTRICT_NAME",
                    "title": "District Name",
                }, {
                    "data": "PROVINCE_NAME",
                    "title": "Province Name",
                }
            ],
            "processing": true,
            "serverSide": true,
            "stateSave": true
        })
        .on('draw', function(event, settings, json, xhr) {
            /* add style to checkbox, radio */
            iCheckInit($('input:checkbox, input:radio', settings.nTable));
        });

    iCheckBulk(filtersTableA, filtersTable);

    dataTable = tableA
        .DataTable({
            "columns": [{
                    "orderable": false,
                    "render": function(data, type, row, meta) {
                        return parseInt(meta.row) + parseInt(meta.settings._iDisplayStart) + 1;
                    },
                    "title": 'No.',
                    "width": "10px",
                },
                {
                    "orderable": false,
                    "render": function(data, type, row, meta) {
                        if (row.enable == 1) {
                            var checked = ' checked';
                        } else {
                            var checked = '';
                        }

                        return '<input' + checked + ' name="enables[]" type="checkbox" value="' + row.DISTRICT_CODE + '">';
                    },
                    "title": '<input class="checkAll" type="checkbox">',
                    "width": "10px",
                },
                {
                    "orderable": false,
                    "render": function(data, type, row, meta) {
                        if (row.enable) {
                            return '<span class="glyphicon glyphicon-ok"></span>';
                        } else {
                            return '<span class="glyphicon glyphicon-remove"></span>';
                        }
                    },
                    "title": "Enable",
                    "width": "10px",
                }, {
                    "data": "DISTRICT_CODE",
                    "title": "District Code",
                    "width": "90px",
                }, {
                    "data": "DISTRICT_NAME",
                    "title": "District Name",
                }, {
                    "data": "PROVINCE_NAME",
                    "title": "Province Name",
                }
            ]
        })
        .on('draw', function(event, settings, json, xhr) {
            /* add style to checkbox, radio */
            iCheckInit($('input:checkbox, input:radio', settings.nTable));
        });

    iCheckBulk(tableA, dataTable);

    iCheckChange(filtersTableA, filtersTable, dataTable);

    iCheckCopy(dataTable, filtersTable, 'DISTRICT_CODE');

});

อธิบาย

  • มี 2 ตารางคือ id=”filtersTableA” เป็นต้นฉบับ และ id=”tableA” เป็นตารางที่จะรับค่าที่จะคัดลอก
  • เพราะว่าอาจจะแบ่งข้อมูลไว้หลายหน้าและ DataTable จะ render ที่ละหน้าเท่านั้น ถ้า user เลือกรายการโดยใช้ input enables[] แล้วเปลี่ยนไปหน้าอื่น input นั้นจะหายไป ทำให้ต้องใช้วิธี update กลับไปที่ Data ของตัว DataTable filtersTableA โดยเปลี่ยนค่าใน object data เช่น data.enable = true; หรือ data.enable = false;
  • เมือคลิก ปุ่ม id=”copyBtn” ให้คัดลอกข้อมูล เพื่อป้องกันการเก็บข้อมูลซ้ำจึงต้อง ดึงรายการที่เก็บข้อมูลเอาไว้แล้ว มาเทียบว่าที่จะเข้ามาใหม่มีรึยังโดยใช้ primary key คือ DISTRICT_CODE

อ่านเพิ่มเติม

สร้าง grid ใน laravel แบบ advance

การใช้ Nayjest Grids แบบ advance เพื่อที่จะสามารถค้นหา filter ข้อมูล, export ไฟล์ ออกมาในรูปแบบ .csv และ excel ได้

ติดตั้งโดย

  1. เปิดไฟล์ composer.json เพิ่ม
    ...
            "laravelcollective/html": "^5",
            "maatwebsite/excel": "~2.1.0",
            "nayjest/grids": "^1.3.1"
    ...
    
  2. Command
    composer update
  3. เปิดไฟล์ \config\app.php เพิ่ม
        'providers' => [
    ...
            'Collective&#92;Html&#92;HtmlServiceProvider',
            'Maatwebsite&#92;Excel&#92;ExcelServiceProvider',
            'Nayjest&#92;Grids&#92;ServiceProvider',
    ...
    
        'aliases' => [
    ...
            'Excel' => 'Maatwebsite&#92;Excel&#92;Facades&#92;Excel',
            'Form' => 'Collective&#92;Html&#92;FormFacade',
            'Grids' => 'Nayjest&#92;Grids&#92;Grids',
            'HTML' => 'Collective&#92;Html&#92;HtmlFacade',
            'Input' => 'Illuminate&#92;Support&#92;Facades&#92;Input',
    ...
    ]

สร้าง grid โดย

  1. <?php
    
    namespace App\Http\Controllers;
    
    use App\user;
    use HTML;
    use Nayjest\Grids\Components\Base\RenderableRegistry;
    use Nayjest\Grids\Components\ColumnHeadersRow;
    use Nayjest\Grids\Components\ColumnsHider;
    use Nayjest\Grids\Components\CsvExport;
    use Nayjest\Grids\Components\ExcelExport;
    use Nayjest\Grids\Components\FiltersRow;
    use Nayjest\Grids\Components\Filters\DateRangePicker;
    use Nayjest\Grids\Components\HtmlTag;
    use Nayjest\Grids\Components\Laravel5\Pager;
    use Nayjest\Grids\Components\OneCellRow;
    use Nayjest\Grids\Components\RecordsPerPage;
    use Nayjest\Grids\Components\RenderFunc;
    use Nayjest\Grids\Components\ShowingRecords;
    use Nayjest\Grids\Components\TFoot;
    use Nayjest\Grids\Components\THead;
    use Nayjest\Grids\EloquentDataProvider;
    use Nayjest\Grids\FieldConfig;
    use Nayjest\Grids\FilterConfig;
    use Nayjest\Grids\Grid;
    use Nayjest\Grids\GridConfig;
    
    class UsersController extends Controller
    {
    
        public function Index()
        {
    
            $query = (new User)
                ->query();
    
            $grid = new Grid(
                (new GridConfig)
                    ->setDataProvider(
                        new EloquentDataProvider($query)
                    )
                    ->setName('UserIndex') /* grid unque id */
                    ->setPageSize(20)
                    ->setColumns([
                        (new FieldConfig)
                            ->addFilter(
                                (new FilterConfig)
                                    ->setOperator(FilterConfig::OPERATOR_LIKE)
                            )
                            ->setLabel('ID')
                            ->setName('id') /* field */
                            ->setSortable(true)
                            ->setSorting(Grid::SORT_DESC)
                        ,
                        (new FieldConfig)
                            ->addFilter(
                                (new FilterConfig)
                                    ->setOperator(FilterConfig::OPERATOR_LIKE)
                            )
                            ->setLabel('Name')
                            ->setName('name')
                            ->setSortable(true)
                        ,
                        (new FieldConfig)
                            ->addFilter(
                                (new FilterConfig)
                                    ->setOperator(FilterConfig::OPERATOR_LIKE)
                            )
                            ->setLabel('Email')
                            ->setName('email')
                            ->setSortable(true)
                        ,
                        (new FieldConfig)
                            ->addFilter(
                                (new FilterConfig)
                                    ->setOperator(FilterConfig::OPERATOR_LIKE)
                            )
                            ->setLabel('Update Information')
                            ->setName('count_update')
                            ->setSortable(true)
                        ,
                        (new FieldConfig)
                            ->setLabel('Created')
                            ->setName('created_at')
                            ->setSortable(true)
                        ,
                        (new FieldConfig)
                            ->setLabel('Last Update')
                            ->setName('updated_at')
                            ->setSortable(true),
                    ])
                    ->setComponents([
                        (new THead)
                            ->setComponents([
                                (new ColumnHeadersRow),
                                (new FiltersRow)
                                    ->addComponents([
                                        (new RenderFunc(function () {
                                            return HTML::style('js/daterangepicker/daterangepicker-bs3.css')
                                            . HTML::script('js/moment/moment-with-locales.js')
                                            . HTML::script('js/daterangepicker/daterangepicker.js')
                                                . "<style>
                                                    .daterangepicker td.available.active,
                                                    .daterangepicker li.active,
                                                    .daterangepicker li:hover {
                                                        color:black !important;
                                                        font-weight: bold;
                                                    }
                                               </style>";
                                        }))
                                            ->setRenderSection('filters_row_column_created_at'),
                                        (new DateRangePicker)
                                            ->setName('created_at')
                                            ->setRenderSection('filters_row_column_created_at')
                                            ->setDefaultValue(['1990-01-01', date('Y-m-d H:i:s')]),
                                        (new DateRangePicker)
                                            ->setName('created_at')
                                            ->setRenderSection('filters_row_column_updated_at')
                                            ->setDefaultValue(['1990-01-01', date('Y-m-d H:i:s')]),
                                    ])
                                ,
                                (new OneCellRow)
                                    ->setRenderSection(RenderableRegistry::SECTION_END)
                                    ->setComponents([
                                        new RecordsPerPage,
                                        new ColumnsHider,
                                        (new CsvExport)
                                            ->setFileName('usersExport_' . date('Y-m-d'))
                                        ,
                                        (new ExcelExport())
                                            ->setFileName('usersExport_' . date('Y-m-d'))
                                        ,
                                        (new HtmlTag)
                                            ->setContent('<span class="glyphicon glyphicon-refresh"></span> Filter')
                                            ->setTagName('button')
                                            ->setRenderSection(RenderableRegistry::SECTION_END)
                                            ->setAttributes([
                                                'class' => 'btn btn-success btn-sm',
                                            ]),
                                    ]),
                            ])
                        ,
                        (new TFoot)
                            ->setComponents([
                                (new OneCellRow)
                                    ->setComponents([
                                        new Pager,
                                        (new HtmlTag)
                                            ->setAttributes(['class' => 'pull-right'])
                                            ->addComponent(new ShowingRecords)
                                        ,
                                    ]),
                            ])
                        ,
                    ])
            );
            $grid = $grid->render();
    
            return view('users.index', [
                'grid' => $grid,
            ]);
        }
    
    }
    
  2. สร้าง view \resources\views\users\index.blade.php
    @extends('layouts.app')
    
    @section('title', 'Users')
    
    @section('main-content') <a href="{{ url('/excels/form') }}">
    <button class="btn btn-success btn-sm"><span class="glyphicon glyphicon-upload"></span> Import Datas</button>
    </a> @if(!empty($text))
    <div class="container">{!! $text !!}</div>
    @endif
    <?=$grid;?>
    @stop
  3. สร้าง route โดยไปที่ \app\Http\routes.php
    ...
    Route::get('/users/index', 'UsersController@index');
    ...

ทดลองโดยเรียก /users/index ในเครื่องผมคือ http://localhost/laravel52/public/users/index grid แสดงข้อมูลออกมาแล้วแต่ จะส่งออกเป็นไฟล์ csv หรือ excel ยังไงละ ใจเย็นๆครับ อ่าน สร้าง grid ใน laravel แบบ advance ครับ

ใส่ฟิลเตอร์ให้ select box

select box (drop down/ dropdown / ดรอปดาวน์ / list / ลิสต์ หลายชื่อเหลือกเกิน) นิยมใช้เวลาต้องการให้ user เลือกจากตัวเลือกที่กำหนดให้เท่านั้น แต่ถ้ามันมีเยอะมาก อย่าง 77 จังหวัด ถ้าต้องเลือกบ่อยๆ ก็ไม่สดวกที่จะต้องไล่หา แก้ได้โดยใช้ jQuery ใส่ filter ให้

ดูตัวอย่างการทำงานได้ที่

ตัวอย่าง Demo -> =>

  1. download jQuery.chosen มาจาก harvesthq Chosen แตกไฟล์
  2. ใส่ code ง่ายๆ ตามตัวอย่าง
    <!doctype html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>jQuery Chosen Demo By Pitt Phunsanit</title>
    <link href="chosen/chosen.min.css" rel="stylesheet" type="text/css">
    </head>
    <body>
    <select id="province" style="width:200px;">
    	<option value="64">กระบี่</option>
    	<option value="1">กรุงเทพมหานคร</option>
    	<option value="56">กาญจนบุรี</option>
    	<option value="34">กาฬสินธุ์</option>
    	<option value="49">กำแพงเพชร</option>
    	<option value="28">ขอนแก่น</option>
    	<option value="13">จันทบุรี</option>
    	<option value="15">ฉะเชิงเทรา</option>
    	<option value="11">ชลบุรี</option>
    	<option value="9">ชัยนาท</option>
    	<option value="25">ชัยภูมิ</option>
    	<option value="69">ชุมพร</option>
    	<option value="45">เชียงราย</option>
    	<option value="38">เชียงใหม่</option>
    	<option value="72">ตรัง</option>
    	<option value="14">ตราด</option>
    	<option value="50">ตาก</option>
    	<option value="17">นครนายก</option>
    	<option value="58">นครปฐม</option>
    	<option value="36">นครพนม</option>
    	<option value="19">นครราชสีมา</option>
    	<option value="63">นครศรีธรรมราช</option>
    	<option value="47">นครสวรรค์</option>
    	<option value="3">นนทบุรี</option>
    	<option value="76">นราธิวาส</option>
    	<option value="43">น่าน</option>
    	<option value="77">บึงกาฬ</option>
    	<option value="20">บุรีรัมย์</option>
    	<option value="4">ปทุมธานี</option>
    	<option value="62">ประจวบคีรีขันธ์</option>
    	<option value="16">ปราจีนบุรี</option>
    	<option value="74">ปัตตานี</option>
    	<option value="5">พระนครศรีอยุธยา</option>
    	<option value="44">พะเยา</option>
    	<option value="65">พังงา</option>
    	<option value="73">พัทลุง</option>
    	<option value="53">พิจิตร</option>
    	<option value="52">พิษณุโลก</option>
    	<option value="61">เพชรบุรี</option>
    	<option value="54">เพชรบูรณ์</option>
    	<option value="42">แพร่</option>
    	<option value="66">ภูเก็ต</option>
    	<option value="32">มหาสารคาม</option>
    	<option value="37">มุกดาหาร</option>
    	<option value="46">แม่ฮ่องสอน</option>
    	<option value="24">ยโสธร</option>
    	<option value="75">ยะลา</option>
    	<option value="33">ร้อยเอ็ด</option>
    	<option value="68">ระนอง</option>
    	<option value="12">ระยอง</option>
    	<option value="55">ราชบุรี</option>
    	<option value="7">ลพบุรี</option>
    	<option value="40">ลำปาง</option>
    	<option value="39">ลำพูน</option>
    	<option value="30">เลย</option>
    	<option value="22">ศรีสะเกษ</option>
    	<option value="35">สกลนคร</option>
    	<option value="70">สงขลา</option>
    	<option value="71">สตูล</option>
    	<option value="2">สมุทรปราการ</option>
    	<option value="60">สมุทรสงคราม</option>
    	<option value="59">สมุทรสาคร</option>
    	<option value="18">สระแก้ว</option>
    	<option value="10">สระบุรี</option>
    	<option value="8">สิงห์บุรี</option>
    	<option value="51">สุโขทัย</option>
    	<option value="57">สุพรรณบุรี</option>
    	<option value="67">สุราษฎร์ธานี</option>
    	<option value="21">สุรินทร์</option>
    	<option value="31">หนองคาย</option>
    	<option value="27">หนองบัวลำภู</option>
    	<option value="6">อ่างทอง</option>
    	<option value="26">อำนาจเจริญ</option>
    	<option value="29">อุดรธานี</option>
    	<option value="41">อุตรดิตถ์</option>
    	<option value="48">อุทัยธานี</option>
    	<option value="23">อุบลราชธานี</option>
    </select>
    <script src="../jQuery/jquery-2.1.3.min.js"></script><!-- เรียกใช้ jQuery -->
    <script src="chosen/chosen.jquery.min.js"></script><!-- เรียกใช้ jQuery plugin -->
    <script>
    $(function(){
    
    	$('#province').chosen(); <!-- เรียกใช้ jQuery plugin chosen กับ id province-->
    
    })
    </script>
    </body>
    </html>
    
  3. ใช้ได้แล้ว