|
jQuery วิธี Save State Form เมื่อกด Refresh หรือ Back แล้วข้อมูลบน Form ไม่หาย |
jQuery วิธี Save State Form เมื่อกด Refresh หรือ Back แล้วข้อมูลบน Form ไม่หาย เห็นถามกันบ่อยๆ เกี่ยวกับเทคนิคการทำ State ของ Form โดยเมื่อเราทำการ Submit หรือกด Refresh หรือกด Back จากหน้าที่ผ่านการ Submit ให้ย้อนกลับไปแล้วค่าไม่หาย ค่าที่ยังกรอกยังอยู่ ซึ่งก่อนหน้านี้ในไทยครีเอทก็มีเทคนิคนี้อยู่บ้างแล้ว แล้วค่อนข้างจะเก่ามาก และ ตกรุ่นไปเยอะพอสมควร วันนี้มีโอกาสเลยเอาเทคนิคดีๆ แบบนี้มาแจกกัน และเชื่อว่าจะมีประโยชน์แน่นอน
jQuery Save State Form
ในบทความนี้ใช้เทคนิคที่ค่อนข้างจะทันสมัยคือ ใช้ jQuery จัดเก็บข้อมูลลงใน localStorage โดยจะเก็บข้อมูลเกือบจะ Real time เพราะทุกครั้งที่มีการ พิมพ์ข้อมูล หรือ เลือกรายการต่างๆ บน Form โปรแกรมจะจัดเก็บข้อมูลลงใน localStorage และเมื่อกด Submit แล้ว Back กลับมา หรือ Refresh หน้าเดิม โปรแกรมก็จะนำข้อมูลที่เคสจัดเก็บลงใน localStorage มาใส่ใน element ต่างๆ
function ที่ใช้จัดเก็บ State ลงใน localStorage
//*** function
(function ($) {
function formsaver(method, container) {
function getStorageId(container) {
return 'formdata__$url__$extra'.replace('$url', location.pathname)
.replace('$extra', container.attr('id') || '');
}
var storageId = getStorageId(container),
controller = {
save: function () {
this._save(storageId, this.extractValues());
},
restore: function () {
this.fillFields(this._load(storageId));
},
clear: function () {
this._remove(storageId);
},
extractValues: function () {
var formData = container.find(":input[name]").serializeArray(),
preparedData = {};
$.each(formData, function (index, element) {
var name = element.name,
value = encodeURIComponent(element.value);
if (preparedData[name]) {
preparedData[name] = preparedData[name] instanceof Array ?
preparedData[name].concat(value) :
[preparedData[name], value];
} else {
preparedData[name] = value;
}
});
return preparedData;
},
fillFields: function (formData) {
$.each(formData, function (name, value) {
var field = container.find("[name=" + name + "]"),
inputType = field.prop('type');
value = value instanceof Array ? value.map(decodeURIComponent) :
decodeURIComponent(value);
if (inputType === 'checkbox') {
field.attr('checked', 'checked');
} else if (inputType === 'radio') {
field.filter("[value=" + value + "]").prop('checked', true);
} else {
field.val(value);
}
});
},
_save: function (storageId, data) {
localStorage[storageId] = JSON.stringify(data);
},
_load: function (storageId) {
return localStorage[storageId] ? JSON.parse(localStorage[storageId]) : {};
},
_remove: function (storageId) {
localStorage.removeItem(storageId);
}
},
methodsQueue = method instanceof Array ? method : [method];
$.each(methodsQueue, function (index, method) {
controller[method]();
});
}
$.fn.saveForm = function () {
formsaver('save', $(this));
};
$.fn.restoreForm = function () {
formsaver(['restore'], $(this));
};
$.fn.clearForm = function () {
formsaver(['clear'], $(this));
};
})(jQuery);
เมื่อมีการคีย์ข้อมูลลงใน Form จะมีการ Save State
$("#frmMain").on("change click", function(e) {
$("#frmMain").saveForm();
});
เมื่อมีการกด Back หรือ Refresh จะมีการ Restore State
$(document).ready(function() {
$("#frmMain").restoreForm();
});
เมื่อกต้องการ Clear ค่าให้เรียก function นี้
$("#frmMain").clearForm();
Code เต็มๆ
<html>
<head>
<title>ThaiCreate.Com</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
</head>
<body>
<form action="" method="post" name="frmMain" id="frmMain">
<table width="480" border="0">
<tr>
<td width="157">Name</td>
<td width="307"><input type="text" id="txtName" name="txtName"></td>
</tr>
<tr>
<td>Email</td>
<td><input type="text" id="txtEmail" name="txtEmail"></td>
</tr>
<tr>
<td>Gender</td>
<td><input type="radio" name="rdoGender"id="rdoGender1" value="M">
Mail
<input type="radio" name="rdoGender" id="rdoGender2" value="F">
Female</td>
</tr>
<tr>
<td>Working</td>
<td><input type="checkbox" name="chkWorking" id="chkWorking" value="Y"></td>
</tr>
<tr>
<td>Address</td>
<td><textarea name="txtAddress" id="txtAddress" cols="40" rows="5"></textarea></td>
</tr>
<tr>
<td>Country</td>
<td><select name="ddlCountry" id="ddlCountry">
<option value="-">-- Country --</option>
<option value="TH">Thailand</option>
<option value="US">United States</option>
</select></td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
</table>
<input type="submit" name="Submit" value="Submit">
<input type="button" name="btnClear" id="btnClear" value="Clear">
</form>
<script type="text/javascript">
//*** function
(function ($) {
function formsaver(method, container) {
function getStorageId(container) {
return 'formdata__$url__$extra'.replace('$url', location.pathname)
.replace('$extra', container.attr('id') || '');
}
var storageId = getStorageId(container),
controller = {
save: function () {
this._save(storageId, this.extractValues());
},
restore: function () {
this.fillFields(this._load(storageId));
},
clear: function () {
this._remove(storageId);
},
extractValues: function () {
var formData = container.find(":input[name]").serializeArray(),
preparedData = {};
$.each(formData, function (index, element) {
var name = element.name,
value = encodeURIComponent(element.value);
if (preparedData[name]) {
preparedData[name] = preparedData[name] instanceof Array ?
preparedData[name].concat(value) :
[preparedData[name], value];
} else {
preparedData[name] = value;
}
});
return preparedData;
},
fillFields: function (formData) {
$.each(formData, function (name, value) {
var field = container.find("[name=" + name + "]"),
inputType = field.prop('type');
value = value instanceof Array ? value.map(decodeURIComponent) :
decodeURIComponent(value);
if (inputType === 'checkbox') {
field.attr('checked', 'checked');
} else if (inputType === 'radio') {
field.filter("[value=" + value + "]").prop('checked', true);
} else {
field.val(value);
}
});
},
_save: function (storageId, data) {
localStorage[storageId] = JSON.stringify(data);
},
_load: function (storageId) {
return localStorage[storageId] ? JSON.parse(localStorage[storageId]) : {};
},
_remove: function (storageId) {
localStorage.removeItem(storageId);
}
},
methodsQueue = method instanceof Array ? method : [method];
$.each(methodsQueue, function (index, method) {
controller[method]();
});
}
$.fn.saveForm = function () {
formsaver('save', $(this));
};
$.fn.restoreForm = function () {
formsaver(['restore'], $(this));
};
$.fn.clearForm = function () {
formsaver(['clear'], $(this));
};
})(jQuery);
//*** restore after refresh
$(document).ready(function() {
$("#frmMain").restoreForm();
});
//*** save form
$("#frmMain").on("change click", function(e) {
$("#frmMain").saveForm();
});
//*** clear form
//$("#frmMain").clearForm();
</script>
</body>
</html>
ทดสอบการทำงาน
ทดสอบคีย์ข้อมูล แล้วให้กด Refresh
จะเห็นว่าข้อมูลยังอยู่เหมือนเดิม
เพิ่มเติม สามารถแยกเป็นไฟล์ js เพราะจะสามารถเรียกได้ในทุกๆ หน้าได้ง่ายและสะดวกขึ้น
savestate.js
//*** function
(function ($) {
function formsaver(method, container) {
function getStorageId(container) {
return 'formdata__$url__$extra'.replace('$url', location.pathname)
.replace('$extra', container.attr('id') || '');
}
var storageId = getStorageId(container),
controller = {
save: function () {
this._save(storageId, this.extractValues());
},
restore: function () {
this.fillFields(this._load(storageId));
},
clear: function () {
this._remove(storageId);
},
extractValues: function () {
var formData = container.find(":input[name]").serializeArray(),
preparedData = {};
$.each(formData, function (index, element) {
var name = element.name,
value = encodeURIComponent(element.value);
if (preparedData[name]) {
preparedData[name] = preparedData[name] instanceof Array ?
preparedData[name].concat(value) :
[preparedData[name], value];
} else {
preparedData[name] = value;
}
});
return preparedData;
},
fillFields: function (formData) {
$.each(formData, function (name, value) {
var field = container.find("[name=" + name + "]"),
inputType = field.prop('type');
value = value instanceof Array ? value.map(decodeURIComponent) :
decodeURIComponent(value);
if (inputType === 'checkbox') {
field.attr('checked', 'checked');
} else if (inputType === 'radio') {
field.filter("[value=" + value + "]").prop('checked', true);
} else {
field.val(value);
}
});
},
_save: function (storageId, data) {
localStorage[storageId] = JSON.stringify(data);
},
_load: function (storageId) {
return localStorage[storageId] ? JSON.parse(localStorage[storageId]) : {};
},
_remove: function (storageId) {
localStorage.removeItem(storageId);
}
},
methodsQueue = method instanceof Array ? method : [method];
$.each(methodsQueue, function (index, method) {
controller[method]();
});
}
$.fn.saveForm = function () {
formsaver('save', $(this));
};
$.fn.restoreForm = function () {
formsaver(['restore'], $(this));
};
$.fn.clearForm = function () {
formsaver(['clear'], $(this));
};
})(jQuery);
ตอนที่เรียกใช้งานจะเหลือแค่
<html>
<head>
<title>ThaiCreate.Com</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" src="savestate.js"></script>
</head>
<body>
<script type="text/javascript">
//*** restore after refresh
$(document).ready(function() {
$("#frmMain").restoreForm();
});
//*** save form
$("#frmMain").on("change click", function(e) {
$("#frmMain").saveForm();
});
//*** clear form
//$("#frmMain").clearForm();
</script>
|