Tag Archive AJAX

jQuery: Ajax Cache

ต้องการเก็บข้อมูลส่วนที่ใช้บ่อยๆ ไว้ในฝั่ง user (browser) นั่นละ จะได้ลดการ query แต่ข้อมูลมันมีการเปลี่ยนแปลงด้วย ที่เก็บข้อมูลระยะยาวได้ในฝั่ง browser กลับออกแบบให้ localStorage เก็บข้อมูลถาวรโดยไม่มีการ expires เหมือน cookie ทำให้ต้องเขียน code จัดการเพิ่ม

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <title>Ajax: localStorage</title>
</head>

<body>
    <h1>localStorage</h1>
    <div class="col-sm-12" id="datasA"></div>
    <div class="col-sm-12" id="resultA"></div>
    <script src="../vendor/components/jquery/jquery.min.js"></script>
    <script>
        $(function() {

            function getDatas() {
                let cacheKey = 'memories';

                if (cacheKey in localStorage) {
                    let datas = JSON.parse(localStorage.getItem(cacheKey));

                    // if expired
                    if (datas['expires'] < Date.now()) {
                        localStorage.removeItem(cacheKey);

                        getDatas()
                    } else {
                        setDatas(datas);
                    }
                } else {
                    $.ajax({
                        "dataType": "json",
                        "success": function(datas, textStatus, jqXHR) {
                            let today = new Date();

                            datas['expires'] = today.setDate(today.getDate() + 7) // expires in next 7 days

                            setDatas(datas);

                            localStorage.setItem(cacheKey, JSON.stringify(datas));
                        },
                        "url": "http://localhost/phunsanit/snippets/PHP/json.json_encode.php",
                    });
                }
            }

            function setDatas(datas) {
                // display json as text
                $('#datasA').text(JSON.stringify(datas));

                // your code here
                let html = '';
                $.each(datas.datas, function(index, value) {
                    html += '<br>' + index + ' = ' + value;
                });
                $('#resultA').html(html);

            }

            // call
            getDatas();

        });
    </script>
</body>

</html>

ข้อมูลที่ call ผ่าน ajax จะโดนเก็บใน localStorage แต่เวลาใช้ก็จะเอามาเทียบ expires ก่อน ถ้ายังไม่หมดอายุก็เอามาใช้ ถ้าหมดอายุไปแล้วก็ call ใหม่ ลองดัดแปลงดูให้เหมาะกับงานดูครับ

Fetch API: Download

ที่นี้มาถึงการที่ใช้ fetch download file จาก server ซึ่งวิธีนี้ง่ายกว่าการใช้ jQuery ดึงไฟล์มามาก จากที่เคยเขียน jQuery ajax download file เอาไว้จะเห็นว่าวิธีนี้ง่ายกว่ามาก

เริ่มจากการที่โหลด download.js มาก่อน โดยใช้คำสั่ง npm i downloadjs
ไฟล์กลางที่ไว้ใช้ร่วมกัน

scripts.js

/*
pitt phunsanit
default fetch api options
version 1
*/
let fetchOptions = {
    "headers": {
        'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
    },
    "method": "post"
};

/*
pitt phunsanit
get file name from fetch api
version 1
*/
function fetchGetFilename(response) {
    let filename = '';
    let disposition = response.headers.get('Content-Disposition');
    if (disposition && disposition.indexOf('attachment') !== -1) {
        let filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
        let matches = filenameRegex.exec(disposition);
        if (matches != null && matches[1]) {
            filename = matches[1].replace(/['"]/g, '');
        }
    }
    return filename;
}

/*
pitt phunsanit
get status from fetch api
version 1
*/
function fetchStatus(Response) {
    if (Response.status >= 200 && Response.status < 300) {
        return Promise.resolve(Response);
    } else {
        return Promise.reject(new Error(Response.status + ' : ' + Response.statusText));
    }
}

ตัวอย่างการใช้ fetch download file โดยใช้ downloadjs ช่วยให้ทำงานได้ทุกบราวเซอร์ (ยกเว้น IE ถ้าจะใช้กลับไปอ่าน Fetch API)

JavaScript/fetch.download.html
<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

      <meta name="author" content="Pitt Phunsanit">
      <title>fetch: download</title>
   </head>
   <body>
      <script src="../node_modules/downloadjs/download.min.js"></script>
      <script src="../scripts.js"></script>
      <script>
fetchOptions.body = 'file=ISO 3166-1 two aplha COUNTRY codes (01102009).xls&token=HH89VOiirgXlCdEqDrFs';

fetch('http://localhost/snippets/PHP/download.php', fetchOptions)
    .then(fetchStatus)
    .then(
        function(response) {
            if (response.ok) {
                let fileName = fetchGetFilename(response);
                let mimeType = response.headers.get('Content-Type');

                response.blob().then(function(blob) {
                    download(blob, fileName, mimeType);
                });
            }
        }
    )
    .catch(function(error) {
        alert(error);
    });
      </script>

</body></html>

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

Fetch API

Fetch API เป็นวิธีที่ใช้ทำ ajax แทน XMLHttpRequest (XHR) สามารถใช้ได้กับทุกบราวเซอร์ยกเว้น อ้ายอี (IE) แม้แต่ microsoft edge ก็ยังใช้ได้ แต่จริงๆ แล้วสามารถบังคับให้อ้ายอีใช้ได้โดยการเรียกใช้ github/fetch ช่วย

ไฟล์กลางที่ไว้ใช้ร่วมกัน

scripts.js

/*
pitt phunsanit
default fetch api options
version 1
*/
let fetchOptions = {
    "headers": {
        'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
    },
    "method": "post"
};

/*
pitt phunsanit
get status from fetch api
version 1
*/
function fetchStatus(Response) {
    if (Response.status >= 200 && Response.status < 300) {
        return Promise.resolve(Response);
    } else {
        return Promise.reject(new Error(Response.status + ' : ' + Response.statusText));
    }
}

ตัวอย่างการใช้ fetch แบบ GET

JavaScript/fetch.get.html
<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

      <meta name="author" content="Pitt Phunsanit">
      <title>fetch: get</title>
   </head>
   <body>
      <script src="../scripts.js"></script>
      <script>
fetch('http://localhost/snippets/PHP/json.json_encode.php?name=pitt&surname=phunsanit')
    .then(fetchStatus)
    .then(
        function(response) {

            response.json()
                .then(function(data) {
                    alert(JSON.stringify(data));
                });

        }
    )
    .catch(function(error) {
        alert(error);
    });
      </script>

</body></html>

เมื่อต้องการส่งข้อมูลแบบ POST ก็เพิ่ม option ไปเล็กน้อย
ตัวอย่างการ fetch แบบ POST

JavaScript/fetch.post.html
<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

      <meta name="author" content="Pitt Phunsanit">
      <title>fetch: post</title>
   </head>
   <body>
      <script src="../scripts.js"></script>
      <script>
fetchOptions.body = '[email protected]&name=pitt&surname=phunsanit';

fetch('http://localhost/snippets/PHP/json.json_encode.php', fetchOptions)
    .then(fetchStatus)
    .then(
        function(response) {

            response.json()
                .then(function(data) {
                    alert(JSON.stringify(data));
                });

        }
    )
    .catch(function(error) {
        alert(error);
    });
      </script>

</body></html>

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

slick: carousel / slideshow จาก ajax

ตัวอย่างการแก้ไข carousel หรือ slideshow โดย update slide จาก ajax

[code language=”html” title=”kenwheeler.slick/ajax.html”]<!doctype html>
<html>

<head>
<meta charset="utf-8">
<title>kenwheeler.slick: ajax update</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="theme.css" rel="stylesheet" type="text/css" />
</head>

<body>
<div id="slideshowA"></div><br>
<select id="order_by">
<option value="asc">น้อยไปมาก</option>
<option value="desc">มากไปน้อย</option>
<option value="random">สุ่ม</option>
</select>
<script src="../vendor/components/jquery/jquery.min.js"></script>
<script src="../vendor/kenwheeler/slick/slick/slick.min.js"></script>
<script>
$(function() {

var order_by = $(‘#order_by’);
var slideshowA = $(‘#slideshowA’);

function getSliderSettings() {
return {
"autoplay": false,
"autoplaySpeed": 3000,
"centerMode": true,
"infinite": false,
"slidesToScroll": 4,
"slidesToShow": 4,
"speed": 300,
"variableWidth": true,
"zIndex": 2
}
}

function getSlideShow() {

$.ajax({
"data": {
"order_by": order_by.val(),
},
"success": function(data, textStatus, jqXHR) {

/* add items */
$.each(data.datas, function(index, value) {
slideshowA.append(‘<div><b>’ + index + ‘</b><img alt="’ + index + ‘" src="’ + value + ‘"><p>แสดง ‘ + index + ‘ จาก http://www.avatarsdb.com</p></div>’);
});

slideshowA.slick(‘unslick’); /* ONLY remove the classes and handlers added on initialize */
$(‘.my-slide’).remove(); /* Remove current slides elements, in case that you want to show new slides. */
slideshowA.slick(getSliderSettings()); /* Initialize the slick again */

alert(‘ทดลองดูครับ’);

},
"url": "ajax.php",
});

}

order_by.change(function() {
getSlideShow();
});

getSlideShow();
slideshowA.slick(getSliderSettings());
});
</script>
</body>

</html>[/code]

ไฟล์ที่ส่งข้อมูลกลับมาให้[code language=”php” title=”kenwheeler.slick/ajax.php”]<?php
$datas = [];

if (isset($_GET[‘order_by’])) {
$order_by = $_GET[‘order_by’];
} else {
$order_by = ‘asc’;
}

$datas[‘Acrobat’] = ‘http://www.avatarsdb.com/avatars/acrobat.gif’;
$datas[‘Cat Rain’] = ‘http://www.avatarsdb.com/avatars/cat_rain.gif’;
$datas[‘Dota Windranger’] = ‘http://www.avatarsdb.com/avatars/dota_windranger.jpg’;
$datas[‘Fighting Funny’] = ‘http://www.avatarsdb.com/avatars/fighting_funny.gif’;
$datas[‘Fire 01’] = ‘http://www.avatarsdb.com/avatars/fire_01.gif’;
$datas[‘German Shepherd Puppy’] = ‘http://www.avatarsdb.com/avatars/german_shepherd_puppy.jpg’;
$datas[‘Girl With Cigarette’] = ‘http://www.avatarsdb.com/avatars/girl_with_cigarette.jpg’;
$datas[‘Hidden Cat’] = ‘http://www.avatarsdb.com/avatars/hidden_cat.jpg’;
$datas[‘Im Fabulous’] = ‘http://www.avatarsdb.com/avatars/im_fabulous.jpg’;
$datas[‘One Direction’] = ‘http://www.avatarsdb.com/avatars/One_Direction.jpg’;
$datas[‘Panda Kiss’] = ‘http://www.avatarsdb.com/avatars/panda_kiss.gif’;
$datas[‘PC User’] = ‘http://www.avatarsdb.com/avatars/pc_user.gif’;
$datas[‘Riri Queen’] = ‘http://www.avatarsdb.com/avatars/riri_queen.gif’;
$datas[‘Tennessee’] = ‘http://www.avatarsdb.com/avatars/tennessee.jpg’;
$datas[‘Tuxedo M’] = ‘http://www.avatarsdb.com/avatars/Tuxedo_m.jpg’;
$datas[‘Tuxedo Mask’] = ‘http://www.avatarsdb.com/avatars/tuxedo_mask.jpg’;
$datas[‘Ugly Face’] = ‘http://www.avatarsdb.com/avatars/ugly_face.gif’;
$datas[‘Waifu’] = ‘http://www.avatarsdb.com/avatars/waifu.jpg’;
$datas[‘Wolf In The Snow’] = ‘http://www.avatarsdb.com/avatars/wolf_in_the_snow.jpg’;
$datas[‘Xerxes Break Kevin’] = ‘http://www.avatarsdb.com/avatars/xerxes_break_kevin.jpg’;

switch ($order_by) {
case ‘desc’:{krsort($datas);}
break;

case ‘random’:{
$keys = array_keys($datas);
shuffle($keys);
$random = [];
foreach ($keys as $key) {
$random[$key] = $datas[$key];
}
$datas = $random;
}break;

case ‘asc’:
default:
{ksort($datas);}
break;
}

header(‘Content-type: application/json; charset=utf-8’);
echo json_encode([
‘datas’ => $datas,
‘order_by’ => $order_by,
]);[/code]

code บางส่วนจะอยู่ในบทความ slick: สร้าง carousel / slideshow

Credit: Reinitialize Slick js after successful ajax call

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

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

[code language=”html” title=”jQuery.DataTables/data.json.transferDataToAnotherTable.html”]<!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>[/code]

ส่วนที่เขียนเป็นฟังก์ชั่นกลางไว้ให้ไฟล์อื่นเรียกใช้[code language=”javascript” title=”jQuery.DataTables/DataTables.js”]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’,
});
}[/code]

ไฟล์ที่ทำหน้าที่ควบคุมการคัดลอกข้อมูล[code language=”javascript” title=”jQuery.DataTables/data.json.transferDataToAnotherTable.js”]$(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’);

});[/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

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

DataTable: การค้นหาชั้นสูง

เราสามารถเพิ่มเงื่อนไขให้ DataTables ใช้ในการค้นหาได้ โดยส่วนที่เปลี่ยนไปจากเดิมคือใช้ “beforeSend” ในการรวมข้อมูลจาก form (formA) และเขียน validation ง่ายๆ โดยบังคับว่าถ้า advanceSearch ถูกติ๊กอยู่จะต้องเลือก geo_id ด้วย (จริงๆคือ ถึงไม่ติ๊ก advanceSearch ก็ใช้ geo_id search ได้เหมือนกัน)

[code language=”html” title=”jQuery.DataTables/data.json.external.search.html”]<!doctype html>
<html>

<head>
<meta charset="utf-8">
<meta name="author" content="Pitt Phunsanit">
<title>DataTables: external.search</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">
</head>

<body>
<form action="DataTables.json.php" class="form-inline" id="formA" method="post">
<div class="form-group">
<input name="advanceSearch" type="checkbox">
<label for="advanceSearch">advance Search</label>
</div>
<div class="form-group">
<label for="geo_id">ภูมิภาค:</label>
<select class="form-control" name="geo_id">
<option selected="selected" value="">— Select —</option>
<option value="1">ภาคเหนือ</option>
<option value="2">ภาคกลาง</option>
<option value="3">ภาคตะวันออกเฉียงเหนือ</option>
<option value="4">ภาคตะวันตก</option>
<option value="5">ภาคตะวันออก</option>
<option value="6">ภาคใต้</option>
</select>
</div>
<button type="submit" class="btn btn-default">Search</button>
</form>
<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="data.json.external.search.js"></script>
</body>

</html>[/code][code language=”javascript” title=”jQuery.DataTables/data.json.external.search.js”]$(function() {

formA = $(‘#formA’);
tableA = $(‘#tableA’);

datatable = tableA.DataTable({
"ajax": {
"beforeSend": function(jqXHR, settings) {
/* add value form from to DataTable params */
settings.data = formA.serialize() + ‘&’ + settings.data;

/* validation */
var params = new URLSearchParams(settings.data);

/* user must selected region if enable advance search */
if (params.get(‘advanceSearch’) == ‘on’ && params.get(‘geo_id’) == ”) {
jqXHR.abort();
alert(‘กรุณาเลือกภูมิภาค’);
return false;
}

return true;
},
"dataSrc": function(json) {
alert(‘data back ‘ + json.data.length + ‘ items’);

return json.data;
},
"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) {
return ‘<input 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",
}
],
/* default sort */
"order": [
[3, "asc"],
[4, "asc"],
],
"processing": true,
"serverSide": true,
"stateSave": true,
});

$(‘.checkAll’, tableA).click(function() {
$(‘input:checkbox’, tableA).not(this).prop(‘checked’, this.checked);
});

formA.submit(function(event) {
event.preventDefault();

datatable.ajax.reload();
});

});[/code]

  • ข้อมูลจากฟอร์ม [code language=”html”]id="formA"[/code] จะถูกรวมกับ data ที่ DataTable สร้างขึ้นมาเองโดย[code language=”javascript” title=”beforeSend”]"beforeSend": function(jqXHR, settings) {
    settings.data = formA.serialize() + ‘&’ + settings.data;
    },[/code]
  • สามารถทำ validation data ก่อนส่งข้อมูลออกไป ถ้าต้องการหยุดการทำงาน ก็ให้ใช้[code language=”javascript” title=”beforeSend”]"beforeSend": function(jqXHR, settings) {
    jqXHR.abort();
    },[/code]ไม่ให้ส่งข้อมูลกลับไป server อาจจะดัดแปลงให้ datatable ไม่ขอข้อมูลจาก server กรณีที่ไม่มีการเลือกตัว filter ก็ได้เช่นกัน
  • หลังได้ข้อมูลกลับมายังสามารถใช้[code language=”javascript” title=”dataSrc / success”]"dataSrc": function(json) {
    alert(‘data back ‘ + json.data.length + ‘ items’);

    return json.data;
    },[/code]แก้ไขข้อมูลก่อนแสดงผลได้ แต่ไม่ใช่ “success” เหมือนใน jQuery ajax ตามปกตินะครับ เพราะจะทำให้ DataTable มันทำงานผิดปกติได้เลย

  • ถ้าต้องการให้ DataTable ดึงข้อมูลใหม่ให้ใช้รูปแบบ[code language=”javascript” title=”refresh datatable”]datatable.ajax.reload();[/code]

[code language=”php” title=”jQuery.DataTables/data.json.php”]<?php
/* https://datatables.net/manual/server-side */

$output = [
‘data’ => [],
‘debug’ => [
‘length’ => $_REQUEST[‘length’],
‘post’ => $_REQUEST,
‘sqlCount’ => ”,
‘sqlResult’ => ”,
‘start’ => $_REQUEST[‘start’],
],
‘draw’ => $_REQUEST[‘draw’],
‘recordsFiltered’ => $_REQUEST[‘length’],
‘recordsTotal’ => 0,
];

$dns = new PDO(‘mysql:host=localhost;dbname=snippets’, ‘root’, ”, [
//PDO::ATTR_EMULATE_PREPARES => false,
PDO::MYSQL_ATTR_INIT_COMMAND => ‘SET NAMES utf8’,
]);

$condition = [];
$from = ‘ FROM district AS d LEFT JOIN province AS p ON d.PROVINCE_ID = p.PROVINCE_ID’;
$parameters = [];
$where = ”;

if (isset($_REQUEST[‘filters’]) || isset($_REQUEST[‘search’][‘value’])) {

if (isset($_REQUEST[‘search’][‘value’])) {
if ($_REQUEST[‘search’][‘value’] != ”) {

$parameter = ‘:d_DISTRICT_NAME’;

$parameters[$parameter] = ‘%’ . $_REQUEST[‘search’][‘value’] . ‘%’;
array_push($condition, ‘d.DISTRICT_NAME LIKE ‘ . $parameter);
}
}

if (isset($_REQUEST[‘filters’])) {
foreach ($_REQUEST[‘filters’] as $tableAlias => $filter) {
foreach ($filter as $field => $value) {
if ($value != ”) {
$parameter = ‘:’ . $tableAlias . ‘_’ . $field;

$parameters[$parameter] = ‘%’ . $value . ‘%’;
array_push($condition, $tableAlias . ‘.’ . $field . ‘ LIKE ‘ . $parameter);
}
}
}
}

}

if (isset($_REQUEST[‘geo_id’]) && $_REQUEST[‘geo_id’] != ”) {
$parameter = ‘:d_geo_id’;

$parameters[$parameter] = $_REQUEST[‘geo_id’];
array_push($condition, ‘d.GEO_ID = ‘ . $parameter);
}

if (count($parameters)) {
$where = ‘ WHERE ‘ . implode("\n\t AND ", $condition);
}

if (isset($_REQUEST[‘order’]) && isset($_REQUEST[‘order’][0])) {
$columns = [
0 => ‘DISTRICT_NAME’,
3 => ‘DISTRICT_CODE’,
4 => ‘DISTRICT_NAME’,
5 => ‘PROVINCE_NAME’,
];

$order = ‘ ORDER BY ‘ . $columns[$_REQUEST[‘order’][0][‘column’]] . ‘ ‘ . strtoupper($_REQUEST[‘order’][0][‘dir’]);
} else {
$order = ‘ ORDER BY DISTRICT_NAME ASC’;
}

$output[‘debug’][‘parameters’] = $parameters;

/* Total records, before filtering */
$sql = ‘SELECT COUNT(d.DISTRICT_ID)’ . $from;
try {
$output[‘debug’][‘sqlCount’] = $sql;
$stmt = $dns->prepare($sql);
$stmt->execute($parameters);
$output[‘recordsTotal’] = (int) $stmt->fetchColumn(0);
} catch (PDOException $e) {
exit($e->getMessage());
}

/* Total records, after filtering */
$sql = ‘SELECT COUNT(d.DISTRICT_ID)’ . $from . $where;
try {
$output[‘debug’][‘sqlCount’] = $sql;
$stmt = $dns->prepare($sql);
$stmt->execute($parameters);
$output[‘recordsFiltered’] = (int) $stmt->fetchColumn(0);
} catch (PDOException $e) {
exit($e->getMessage());
}

/* data */
if ($output[‘recordsTotal’] > 0) {
$sql = ‘SELECT d.enable, d.DISTRICT_ID, d.DISTRICT_CODE, d.DISTRICT_NAME, p.PROVINCE_NAME’ . $from . $where . $order . " LIMIT " . $_REQUEST[‘start’] . ", " . $_REQUEST[‘length’] . ";";

try {
$output[‘debug’][‘sqlResult’] = $sql;
$stmt = $dns->prepare($sql);
$stmt->execute($parameters);
$output[‘data’] = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
exit($e->getMessage());
}
}

/* unset debug for security */
unset($output[‘debug’]);

header(‘Content-type: application/json; charset=utf-8’);
echo json_encode($output);[/code]

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

jQuery: Ajax รับข้อมูลแบบ stream

บางงานต้องใช้เวลาในการทำงาน ถ้าปล่อยให้ user รออย่างเดียวก็จะกังวลว่ามันจะทำงานสำเร็จหรือมี error รึเปล่า เคยเขียนวิธี jQuery Ajax แบบอนุกรมตามลำดับ ไว้ แต่อาจจะไม่เหมาะถ้า task บางอย่างมันยาวนานกว่านั้น ถึงลองเขียนแบบ flush stream / streaming ดู

ตัวจำลองเวลาโหลดโดยสุ่มถ่วงเวลาให้เหมือนจริง[code language=”php” title=”stream.php”]<?php

set_time_limit(0);

header(‘Cache-Control: no-cache’);
header(‘Content-Type: text/event-stream’);

function task($ad, $message, $progress = ”)
{
$data = [
‘id’ => $ad,
‘message’ => $message,
‘progress’ => $progress,
];

echo json_encode($data);

ob_flush();
flush();
}

/* loop processing */
for ($a = 1; $a <= 10; $a++) {
task($a, ‘on iteration ‘ . $a . ‘ of 10’, $a * 10);

sleep(rand(1, 10));
}

task(‘CLOSE’, ‘Process complete’);[/code]

ตัวอย่างการใช้ jQuery.ajax()[code language=”html” title=”stream_jquery.html”]<!DOCTYPE>
<html>

<head>
<title>Flushed ajax test</title>
<meta charset="UTF-8" />
<style>
#results {
background: #eee;
border: 1px solid #c00000;
height: 250px;
overflow: auto;
padding: 10px;
width: 98%;
}
</style>
</head>

<body>
<div id="results" style=""></div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script>
var last_response_len = false;
$.ajax(‘stream.php’, {
xhrFields: {
onprogress: function(e) {
var this_response, response = e.currentTarget.response;
if (last_response_len === false) {
this_response = response;
last_response_len = response.length;
} else {
this_response = response.substring(last_response_len);
last_response_len = response.length;
}
console.log(this_response);
data = $.parseJSON(this_response);
console.log(data);
$(‘#results’).append(‘<br>’ + data.message);
}
}
})
.done(function(data) {
console.log(‘Complete response = ‘ + data);
$(‘#results’).append(‘<br><br>Complete response = ‘ + data);
})
.fail(function(data) {
console.log(‘Error: ‘, data);
});
console.log(‘Request Sent’);
</script>
</body>

</html>[/code]

ถ้าดูใน console.log จะเห็นว่าตัวแปร data มันจะโดนเพิ่มขึ้นมาเรื่องๆ ดังนั้นถ้ามี response มาจาก server เยอะๆ ก็ต้องแก้ไข code ด้วย

update วิธีเขียนให้ง่ายขึ้นและทำงานบน nginx ได้ ตามที่เขียนใน NGINX: แสดงผลลัพธ์ทันที[code language=”php” title=”stream.php”]<?php

set_time_limit(0);

header(‘Cache-Control: no-cache’);
header(‘Content-Type: text/event-stream’);
header(‘X-Accel-Buffering: no’);

set_time_limit(0);

ob_implicit_flush(true);
ob_end_flush();

function task($ad, $message, $progress = ”)
{
$data = [
‘id’ => $ad,
‘message’ => $message,
‘progress’ => $progress,
];

echo json_encode($data);
}

/* loop processing */
for ($a = 1; $a <= 10; $a++) {
task($a, ‘on iteration ‘ . $a . ‘ of 10’, $a * 10);

sleep(rand(1, 10));
}

task(‘CLOSE’, ‘Process complete’);
[/code]

DataTable: ทำ ajax data grid table

DataTables เป็น grid ที่สามารถให้ฟรีได้โดยไม่มีเงื่อนไขจริงๆ การใช้ก็ไม่ยุ่งยากจนเกินไป

[code language=”html” title=”jQuery.DataTables/data.json.html”]<!doctype html>
<html>

<head>
<meta charset="utf-8">
<meta name="author" content="Pitt Phunsanit">
<title>DataTables: datas from ajax</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">
</head>

<body>
<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="data.json.js"></script>
</body>

</html>[/code][code language=”javascript” title=”jQuery.DataTables/data.json.js”]$(function() {

tableA = $(‘#tableA’);

datatable = tableA.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) {
return ‘<input 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",
}
],
/* default sort */
"order": [
[3, "asc"],
[4, "asc"],
],
"processing": true,
"serverSide": true,
"stateSave": true,
});

$(‘.checkAll’, tableA).click(function() {
$(‘input:checkbox’, tableA).not(this).prop(‘checked’, this.checked);
});

});[/code][code language=”php” title=”jQuery.DataTables/data.json.php”]<?php
/* https://datatables.net/manual/server-side */

$output = [
‘data’ => [],
‘debug’ => [
‘length’ => $_REQUEST[‘length’],
‘post’ => $_REQUEST,
‘sqlCount’ => ”,
‘sqlResult’ => ”,
‘start’ => $_REQUEST[‘start’],
],
‘draw’ => $_REQUEST[‘draw’],
‘recordsFiltered’ => $_REQUEST[‘length’],
‘recordsTotal’ => 0,
];

$dns = new PDO(‘mysql:host=localhost;dbname=snippets’, ‘root’, ”, [
//PDO::ATTR_EMULATE_PREPARES => false,
PDO::MYSQL_ATTR_INIT_COMMAND => ‘SET NAMES utf8’,
]);

$condition = [];
$from = ‘ FROM district AS d LEFT JOIN province AS p ON d.PROVINCE_ID = p.PROVINCE_ID’;
$parameters = [];
$where = ”;

if (isset($_REQUEST[‘filters’]) || isset($_REQUEST[‘search’][‘value’])) {

if (isset($_REQUEST[‘search’][‘value’])) {
if ($_REQUEST[‘search’][‘value’] != ”) {

$parameter = ‘:d_DISTRICT_NAME’;

$parameters[$parameter] = ‘%’ . $_REQUEST[‘search’][‘value’] . ‘%’;
array_push($condition, ‘d.DISTRICT_NAME LIKE ‘ . $parameter);
}
}

if (isset($_REQUEST[‘filters’])) {
foreach ($_REQUEST[‘filters’] as $tableAlias => $filter) {
foreach ($filter as $field => $value) {
if ($value != ”) {
$parameter = ‘:’ . $tableAlias . ‘_’ . $field;

$parameters[$parameter] = ‘%’ . $value . ‘%’;
array_push($condition, $tableAlias . ‘.’ . $field . ‘ LIKE ‘ . $parameter);
}
}
}
}

}

if (isset($_REQUEST[‘geo_id’]) && $_REQUEST[‘geo_id’] != ”) {
$parameter = ‘:d_geo_id’;

$parameters[$parameter] = $_REQUEST[‘geo_id’];
array_push($condition, ‘d.GEO_ID = ‘ . $parameter);
}

if (count($parameters)) {
$where = ‘ WHERE ‘ . implode("\n\t AND ", $condition);
}

if (isset($_REQUEST[‘order’]) && isset($_REQUEST[‘order’][0])) {
$columns = [
0 => ‘DISTRICT_NAME’,
3 => ‘DISTRICT_CODE’,
4 => ‘DISTRICT_NAME’,
5 => ‘PROVINCE_NAME’,
];

$order = ‘ ORDER BY ‘ . $columns[$_REQUEST[‘order’][0][‘column’]] . ‘ ‘ . strtoupper($_REQUEST[‘order’][0][‘dir’]);
} else {
$order = ‘ ORDER BY DISTRICT_NAME ASC’;
}

$output[‘debug’][‘parameters’] = $parameters;

/* Total records, before filtering */
$sql = ‘SELECT COUNT(d.DISTRICT_ID)’ . $from;
try {
$output[‘debug’][‘sqlCount’] = $sql;
$stmt = $dns->prepare($sql);
$stmt->execute($parameters);
$output[‘recordsTotal’] = (int) $stmt->fetchColumn(0);
} catch (PDOException $e) {
exit($e->getMessage());
}

/* Total records, after filtering */
$sql = ‘SELECT COUNT(d.DISTRICT_ID)’ . $from . $where;
try {
$output[‘debug’][‘sqlCount’] = $sql;
$stmt = $dns->prepare($sql);
$stmt->execute($parameters);
$output[‘recordsFiltered’] = (int) $stmt->fetchColumn(0);
} catch (PDOException $e) {
exit($e->getMessage());
}

/* data */
if ($output[‘recordsTotal’] > 0) {
$sql = ‘SELECT d.enable, d.DISTRICT_ID, d.DISTRICT_CODE, d.DISTRICT_NAME, p.PROVINCE_NAME’ . $from . $where . $order . " LIMIT " . $_REQUEST[‘start’] . ", " . $_REQUEST[‘length’] . ";";

try {
$output[‘debug’][‘sqlResult’] = $sql;
$stmt = $dns->prepare($sql);
$stmt->execute($parameters);
$output[‘data’] = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
exit($e->getMessage());
}
}

/* unset debug for security */
unset($output[‘debug’]);

header(‘Content-type: application/json; charset=utf-8’);
echo json_encode($output);[/code]json ที่ส่งกลับมาที่สำคัญคือ

data

เป็นข้อมูลที่นำมาสร้างเป้นตัว body ใน table หรือคือ data ที่ต้องการนำมาแสดง
draw
เป็นรหัสอ้างอิงให้ DataTable รู้ว่า json ที่ส่งมาอันไหนใหม่กว่า จะเรียกว่าเป็นเลข version ของข้อมูลก็ได้
recordsFiltered
เป็นจำนวนชุดข้อมูลทั้งหมดที่ query ได้ (ไม่ใช่จำนวนจริงๆ ที่ return กลับมา เช่น query ได้ข้อมูลทั้งหมด 8,880 รายการ แต่ทำ paging ดึงข้อมูล data มาแค่ครั้งละ 10, 20, 50 และ 100 รายการ)
recordsTotal
เป็นจำนวนข้อมูลทั้งหมดที่มีใน table โดยที่ยังไม่ใส่เงื่อนไข query ซึ่งจริงๆแล้วคัดลอกค่ามากจาก recordsTotal ไปเลยก็ได้ จะได้ไม่เสียเวลา query

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

ส่งค่าตัวแปรในเช็กบ็อกซ์โดย jQuery

เขียนระบบ update ข้อมูลโดยใช้ ajax แต่ปัญหาคือ ใน form นี้มันมี input อยู่หลายตัว และเพราะว่าต้องการแค่ input ที่ชื่อ items[] ตัวเดียวเท่านั้น ถ้าส่ง data ไปโดยใช้ jQuery โดยปกติจะส่งค่าไปโดยใช้ .serialize() หรือ .serializeArray() ก็จะส่งตัวแปรอื่นๆ ที่ไม่จำเป็นติดไปด้วย จนทำให้ url ยาวจนเกิน limit ทำให้ต้องหาวิธีส่งไปเฉพาะตัวที่ใช้จริงๆ เท่านั้น

ตัวอย่างการส่งค่าไปในแบบ array[code language=”html” title=”checkbox_to_array.html”]
<!doctype html>
<html>

<head>
<meta charset="utf-8">
<title>checkbox to array</title>
</head>

<body>
<ul>
<li>
<input name="items[]" type="checkbox" value="c1">
</li>
<li>
<input name="items[]" type="checkbox" value="c2">
</li>
<li>
<input name="items[]" type="checkbox" value="c3">
</li>
<li>
<input name="items[]" type="checkbox" value="c4">
</li>
<li>
<input name="items[]" type="checkbox" value="c5">
</li>
<li>
<input name="items[]" type="checkbox" value="c6">
</li>
<li>
<input name="items[]" type="checkbox" value="c7">
</li>
<li>
<input name="items[]" type="checkbox" value="c8">
</li>
<li>
<input name="items[]" type="checkbox" value="c9">
</li>
<li>
<input name="items[]" type="checkbox" value="c10">
</li>
</ul>
<div id="result"></div>
<button id="sendBtn" type="submit">Send</button>
<script src="jquery-3.1.1.min.js"></script>
<script>
$(function() {

$(‘#sendBtn’).click(function() {
var checkboxs = $(‘input[name="items\\[\\]"]:checked’);

alert(‘checked ‘ + checkboxs.length + ‘ items’);

var values = checkboxs.map(function() {
return $(this).val();
})
.get();

var params = {
"id": 24,
"items": values,
};
$.ajax({
"data": params,
"success": function(data) {
$(‘#result’).html(data);
},
"type": "GET",
"url": "processing.php",
});

});

});
</script>
</body>

</html>[/code]

ตัวอย่างการส่งค่าไปในแบบ string[code language=”html” title=”checkbox_to_string.html”]
<!doctype html>
<html>

<head>
<meta charset="utf-8">
<title>checkbox to string</title>
</head>

<body>
<ul>
<li>
<input name="items[]" type="checkbox" value="c1">
</li>
<li>
<input name="items[]" type="checkbox" value="c2">
</li>
<li>
<input name="items[]" type="checkbox" value="c3">
</li>
<li>
<input name="items[]" type="checkbox" value="c4">
</li>
<li>
<input name="items[]" type="checkbox" value="c5">
</li>
<li>
<input name="items[]" type="checkbox" value="c6">
</li>
<li>
<input name="items[]" type="checkbox" value="c7">
</li>
<li>
<input name="items[]" type="checkbox" value="c8">
</li>
<li>
<input name="items[]" type="checkbox" value="c9">
</li>
<li>
<input name="items[]" type="checkbox" value="c10">
</li>
</ul>
<div id="result"></div>
<button id="sendBtn" type="submit">Send</button>
<script src="jquery-3.1.1.min.js"></script>
<script>
$(function() {

$(‘#sendBtn’).click(function() {
var checkboxs = $(‘input[name="items\\[\\]"]:checked’);

alert(‘checked ‘ + checkboxs.length + ‘ items’);

var values = checkboxs.map(function() {
return $(this).val();
})
.get()
.join();

alert(‘values = ‘ + values);

var encoded = encodeURIComponent(values);

alert(‘URL encoded = ‘ + encoded);

var decoded = decodeURIComponent(encoded);

alert(‘URL decoded = ‘ + decoded);

$.ajax({
"data": ‘id=24&items=’ + encoded,
"success": function(data) {
$(‘#result’).html(data);
},
"type": "GET",
"url": "processing.php",
});

});

});
</script>
</body>

</html>[/code]

ตัวอย่างการนำค่าไปเขียนเป็น sql query[code language=”php” title=”processing.php”]
<dl>
<dt>method="GET"</dt>
<dd><?=print_r($_GET, true);?></dd>
<dt>method="POST"</dt>
<dd><?=print_r($_POST, true);?></dd>
</dl>
<?php
if (is_array($_REQUEST[‘items’])) {
echo ‘<br>send items by array’;
$where = "WHERE id IN(‘" . implode("’, ‘", $_REQUEST[‘items’]) . "’)";
} else {
echo ‘<br>send items by string’;
$where = "WHERE id IN(‘" . str_replace(‘,’, "’, ‘", $_REQUEST[‘items’]) . "’)";
}

$query = "SELECT *
FROM table_name
$where;";

echo ‘<br>example query = ‘ . $query;[/code]

เลือกใช้การส่งแบบสตริงหรืออาร์เรย์ ก็แล้วแต่ความสดวก ที่ต้องนำไป loop อีกหรือแค่ใช้ในการสร้างเอสคิวแอลคิวรีอย่างเดียว

laravel ajax method delete

เขียน ui laravel 5.1 อยู่ แบบใช้ ajax update ข้อมูล โดยเดิมมันใช้ form ธรรมดาแต่ใช้ method เป็น DELETE ทดลองส่งคำสั่งผ่าน ajax อยู่นานก็ไม่ได้ผล แถมมันวิ่งไปที่อื่นอีกตะหาก ทดลองเขียน php ธรรมดามาลองดูก็ไม่เจออะไร

นั่งงงอยู่นาน ก็ pass ค่าไปถูก เขียน php ธรรมดาไป ก็ได้ค่าไปถูก จน search ไปเจอ Delete request Jquery Ajax doesn’t work ที่แท้ laravel ถ้าจะใช้ method delete ต้องใช้ “method”: “POST” กับตัวแปร “_method”: “delete”[code language=”javascript”]
$(‘.glyphicon-trash’).click(function(e) {
e.preventDefault();

var r = confirm(‘Are you sure?’);
if(r == true) {
$.ajax({
"data": {
"_method":"DELETE",
"_token": "{{ csrf_token() }}",
},
"success": function(result) {
location.reload();
alert(‘success’);
},
"type": "POST",
"url": "/admin/index",
});
}
});
[/code]ใช้ได้แล้ว แต่น่าจะเขียนเป็นคู่มือเอาไว้นะ