Hướng dẫn array in form html - mảng ở dạng html
Bài viết sau hướng dẫn tạo HTML Form truyền dữ liệu có cấu trúc (object và array) lên server. Cách tạo form gửi object/array và xử lý bằng PHPNếu đã từng sử dụng PHP hẳn bạn biết có thể dùng Ví dụ theo cách thông thường khi muốn truyền tham số lên server ta làm như sau: Dùng ngoặc vuông trong thuộc tính // Result of $_POST (PHP): // array( // 'user' => array( // 'username' => 'User Name' // 'password' => 'Password' // ) // )0, ta có thể gửi một Object lên server như sau: // Result of $_POST (PHP): // array( // 'user' => array( // 'username' => 'User Name' // 'password' => 'Password' // ) // )Nếu không chỉ định index trong dấu ngoặc vuông, PHP ngầm hiểu đó là một Array và sẽ tự tăng index (tính từ 0) nếu gặp phần tử trùng lặp. // Result of $_POST (PHP): // array( // 'user' => array( // 0 => 'User Name', // 1 => 'Password' // ) // )Và tất nhiên ta có thể chỉ định index của mảng nếu muốn. // Result of $_POST (PHP): // array( // 'user' => array( // 0 => 'User Name', // 1 => 'Password' // ) // )Tuyệt vời hơn, cách này cũng có thể áp dụng với cấu trúc dữ liệu lồng nhau (nested). Xử lý form có object/array với JavaScriptĐôi khi phía Server lại là của bên thứ 3 và dữ liệu quy ước nhận được lại có Content Type là JSON chẳng hạn thì cách làm như trên hoàn toàn vô hiệu. Cách làm của tôi là thay vì submit trực tiếp, tôi tách dữ liệu của Form thành một JSON object, sau đó sử dụng jQuery AJAX để gửi lên server. Ở đây tôi sử dụng một jQuery plugin là // Result of $_POST (PHP): // array( // 'user' => array( // 'username' => 'User Name' // 'password' => 'Password' // ) // )3 (không phải mặc định của jQuery đâu nhé).Nhiệm vụ của plugin này là chuyển đổi dữ liệu trong các input của một form thành một JSON object giống như những gì một server PHP nhận được như đã nói ở phần trước. Với ví dụ trên, data trả về có cấu trúc như sau: { 'user': { 'auth': { 'username': 'User Name', 'password': 'Password' }, 'info' : { [ { 'address': 'Address 1', 'city': 'City 1' }, { 'address': 'Address 1', 'city': 'City 1' } ] } } } Mã nguồn của plugin // Result of $_POST (PHP): // array( // 'user' => array( // 'username' => 'User Name' // 'password' => 'Password' // ) // )3 như sau:jquery.icreativ.js(function ( $ ) { $.fn.serializeToObject = function() { let data = $(this).serializeArray(), ret = {}; data.forEach( obj => { var matches = obj.name.match(/^[a-zA-Z0-9_]+(\[[a-zA-Z0-9_]*])+$/); if (matches) { // array type input let lastKey = obj.name.match(/^[a-zA-Z0-9_]+/)[0], dimensions = obj.name.match(/\[[a-zA-Z0-9_]*\]/g), ref = ret; dimensions.forEach( function(key, depth) { key = key.replace(/[\[\]]/g, ''); // remove square brackets if (key === '') { // dynamic array if (lastKey == '') { let idx = ref.length - 1; if (idx == -1 || !ref[idx]) { ref[idx + 1] = []; } } else { if (!ref[lastKey]) { ref[lastKey] = []; } } } else if (isInteger(key)) { // indexed array if (lastKey == '') { let idx = ref.length - 1; if (idx == -1 || ref[idx][key] !== undefined) { ref[idx + 1] = []; } } else { if (!ref[lastKey]) { ref[lastKey] = []; } } } else { // object if (lastKey == '') { let idx = ref.length - 1; if (idx < 0 || ref[idx][key] !== undefined) { ref[idx + 1] = {}; } } else { if (!ref[lastKey]) { ref[lastKey] = {}; } } } if (lastKey === '') { let idx = ref.length - 1; ref = ref[idx]; } else { ref = ref[lastKey]; } if (depth === dimensions.length - 1) { if (key === '') { let idx = ref.length; ref[idx] = obj.value; } else { ref[key] = obj.value; } } lastKey = key; }); } else { if (!ret[obj.name]) { ret[obj.name] = obj.value; } else { if (ret[obj.name].constructor === Array) { ret[obj.name].push(obj.value); } else { let temp = ret[obj.name]; ret[obj.name] = [temp, obj.value]; } } } } ); return ret; } } )( jQuery ); Nếu hứng thú với Vanilla JS thì tôi cũng chia sẻ mã nguồn như sau: function serializeArray(form) { var result = []; Array.prototype.slice.call(form.elements).forEach(function (field) { if (!field.name || field.disabled || ['file', 'reset', 'submit', 'button'].indexOf(field.type) > -1) return; if (field.type === 'select-multiple') { Array.prototype.slice.call(field.options).forEach(function (option) { if (!option.selected) return; result.push({ name: field.name, value: option.value }); }); return; } if (['checkbox', 'radio'].indexOf(field.type) > -1 && !field.checked) return; result.push({ name: field.name, value: field.value }); }); return result; } function serializeObject(form) { let data = serializeArray(form); let ret = {}; data.forEach( obj => { var matches = obj.name.match(/^[a-zA-Z0-9_]+(\[[a-zA-Z0-9_]*\])+$/); if (matches) { // array type input let lastKey = obj.name.match(/^[a-zA-Z0-9_]+/)[0], dimensions = obj.name.match(/\[[a-zA-Z0-9_]*\]/g), ref = ret; dimensions.forEach( function(key, depth) { key = key.replace(/[\[\]]/g, ''); // remove square brackets if (key === '') { // dynamic array if (lastKey == '') { let idx = ref.length - 1; if (idx == -1 || !ref[idx]) { ref[idx + 1] = []; } } else { if (!ref[lastKey]) { ref[lastKey] = []; } } } else if (isInteger(key)) { // indexed array if (lastKey == '') { let idx = ref.length - 1; if (idx == -1 || ref[idx][key] !== undefined) { ref[idx + 1] = []; } } else { if (!ref[lastKey]) { ref[lastKey] = []; } } } else { // object if (lastKey == '') { let idx = ref.length - 1; if (idx < 0 || ref[idx][key] !== undefined) { ref[idx + 1] = {}; } } else { if (!ref[lastKey]) { ref[lastKey] = {}; } } } if (lastKey === '') { let idx = ref.length - 1; ref = ref[idx]; } else { ref = ref[lastKey]; } if (depth === dimensions.length - 1) { if (key === '') { let idx = ref.length; ref[idx] = obj.value; } else { if (!ref[key]) { ref[key] = obj.value; } else { if (ref[key].constructor === Array) ref[key].push(obj.value); else { let temp = ref[key]; ref[key] = [temp, obj.value]; } } } } lastKey = key; }); } else { if (!ret[obj.name]) { ret[obj.name] = obj.value; } else { if (ret[obj.name].constructor === Array) { ret[obj.name].push(obj.value); } else { let temp = ret[obj.name]; ret[obj.name] = [temp, obj.value]; } } } } ); return ret; }; |