HTML 양식이 편집되었는지 감지하는 일반적인 방법
탭으로 구분 된 html 양식이 있습니다. 한 탭에서 다른 탭으로 이동하면 데이터에 변경 사항이 없더라도 현재 탭의 데이터가 DB에 유지됩니다.
양식이 편집 된 경우에만 지속성 호출을 만들고 싶습니다. 양식에는 모든 종류의 컨트롤이 포함될 수 있습니다. 일부 텍스트를 입력하여 양식을 더럽히는 것은 아니지만 달력 컨트롤에서 날짜를 선택하는 것도 적합합니다.
이를 달성하는 한 가지 방법은 기본적으로 양식을 읽기 전용 모드로 표시하고 '편집'버튼이 있으며 사용자가 편집 버튼을 클릭하면 DB에 대한 호출이 이루어집니다 (데이터 수정 여부에 관계없이 다시 한 번) . 이것은 현재 존재하는 것보다 더 나은 개선입니다).
컨트롤 값이 수정되었는지 확인하는 일반 자바 스크립트 함수를 작성하는 방법을 알고 싶습니다.
순수한 자바 스크립트에서 이것은 쉬운 작업이 아니지만 jQuery를 사용하면 매우 쉽게 할 수 있습니다.
$("#myform :input").change(function() {
$("#myform").data("changed",true);
});
그런 다음 저장하기 전에 변경되었는지 확인할 수 있습니다.
if ($("#myform").data("changed")) {
// submit the form
}
위의 예에서 양식에는 "myform"과 동일한 ID가 있습니다.
여러 형태로 필요한 경우 쉽게 플러그인으로 전환 할 수 있습니다.
$.fn.extend({
trackChanges: function() {
$(":input",this).change(function() {
$(this.form).data("changed", true);
});
}
,
isChanged: function() {
return this.data("changed");
}
});
그런 다음 간단히 말할 수 있습니다.
$("#myform").trackChanges();
양식이 변경되었는지 확인하십시오.
if ($("#myform").isChanged()) {
// ...
}
JQuery가 문제가 아닌 경우. Google의 빠른 검색에서 MD5 및 SHA1 해시 알고리즘의 Javascript 구현을 찾았습니다. 원하는 경우 모든 양식 입력을 연결하고 해시 한 다음 해당 값을 메모리에 저장할 수 있습니다. 사용자가 완료되면. 모든 값을 연결하고 다시 해시하십시오. 2 개의 해시를 비교하십시오. 동일하면 사용자가 양식 필드를 변경하지 않은 것입니다. 서로 다르면 무언가가 편집 된 것이므로 지속성 코드를 호출해야합니다.
질문이 올바른지 확실하지 않지만 addEventListener는 어떻습니까? IE8 지원에 대해 너무 신경 쓰지 않는다면 괜찮을 것입니다. 다음 코드가 저에게 효과적입니다.
var form = document.getElementById("myForm");
form.addEventListener("input", function () {
console.log("Form has changed!");
});
이를 달성하는 또 다른 방법은 양식을 직렬화하는 것입니다.
$(function() {
var $form = $('form');
var initialState = $form.serialize();
$form.submit(function (e) {
if (initialState === $form.serialize()) {
console.log('Form is unchanged!');
} else {
console.log('Form has changed!');
}
e.preventDefault();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
Field 1: <input type="text" name="field_1" value="My value 1"> <br>
Field 2: <input type="text" name="field_2" value="My value 2"> <br>
Check: <input type="checkbox" name="field_3" value="1"><br>
<input type="submit">
</form>
다음은 내가 한 방법입니다 (jQuery를 사용하지 않고).
제 경우에는 확인을 트리거 한 요소이므로 항상 변경 될 것이기 때문에 하나의 특정 양식 요소가 계산되지 않기를 원했습니다. 예외적 인 요소의 이름은 'reporting_period'이며 'hasFormChanged ()'함수에 하드 코딩되어 있습니다.
테스트하려면 요소가 "changeReportingPeriod ()"함수를 호출하도록 만드십시오. 아마도 다른 이름을 지정하고 싶을 것입니다.
중요 : 값이 원래 값으로 설정되면 setInitialValues ()를 호출해야합니다 (일반적으로 페이지로드시, 제 경우에는 아님).
참고 : 나는 이것이 우아한 해결책이라고 주장하지 않습니다. 사실 나는 우아한 JavaScript 솔루션을 믿지 않습니다. JavaScript에서 개인적으로 강조하는 부분은 구조적 우아함이 아니라 가독성입니다 (JavaScript에서 가능했던 것처럼). 자바 스크립트를 작성할 때 파일 크기는 전혀 신경 쓰지 않습니다. 그 이유는 gzip이 그 목적이기 때문이며, 더 간결한 자바 스크립트 코드를 작성하려고하면 항상 유지 관리에 참을 수없는 문제가 발생합니다. 나는 사과하지 않으며, 후회하지도 않으며, 토론을 거부합니다. JavaScript입니다. 죄송합니다. 게시를 귀찮게해야한다고 스스로 확신하기 위해이 사실을 분명히해야했습니다. 행복하세요! :)
var initial_values = new Array();
// Gets all form elements from the entire document.
function getAllFormElements() {
// Return variable.
var all_form_elements = Array();
// The form.
var form_activity_report = document.getElementById('form_activity_report');
// Different types of form elements.
var inputs = form_activity_report.getElementsByTagName('input');
var textareas = form_activity_report.getElementsByTagName('textarea');
var selects = form_activity_report.getElementsByTagName('select');
// We do it this way because we want to return an Array, not a NodeList.
var i;
for (i = 0; i < inputs.length; i++) {
all_form_elements.push(inputs[i]);
}
for (i = 0; i < textareas.length; i++) {
all_form_elements.push(textareas[i]);
}
for (i = 0; i < selects.length; i++) {
all_form_elements.push(selects[i]);
}
return all_form_elements;
}
// Sets the initial values of every form element.
function setInitialFormValues() {
var inputs = getAllFormElements();
for (var i = 0; i < inputs.length; i++) {
initial_values.push(inputs[i].value);
}
}
function hasFormChanged() {
var has_changed = false;
var elements = getAllFormElements();
for (var i = 0; i < elements.length; i++) {
if (elements[i].id != 'reporting_period' && elements[i].value != initial_values[i]) {
has_changed = true;
break;
}
}
return has_changed;
}
function changeReportingPeriod() {
alert(hasFormChanged());
}
jQuery없이 네이티브 JavaScript에서 양식 변경 사항을 쉽게 감지 할 수 있습니다.
function initChangeDetection(form) {
Array.from(form).forEach(el => el.dataset.origValue = el.value);
}
function formHasChanges(form) {
return Array.from(form).some(el => 'origValue' in el.dataset && el.dataset.origValue !== el.value);
}
initChangeDetection()
페이지 수명주기 동안 여러 번 안전하게 호출 할 수 있습니다 . JSBin에서 테스트를 참조하세요.
최신 화살표 / 배열 기능을 지원하지 않는 이전 브라우저의 경우 :
function initChangeDetection(form) {
for (var i=0; i<form.length; i++) {
var el = form[i];
el.dataset.origValue = el.value;
}
}
function formHasChanges(form) {
for (var i=0; i<form.length; i++) {
var el = form[i];
if ('origValue' in el.dataset && el.dataset.origValue !== el.value) {
return true;
}
}
return false;
}
다음은 FormData()
API를 사용하여 생성, 업데이트 및 삭제 된 양식 항목을 감지 하는 네이티브 JavaScript의 polyfill 메서드 데모입니다 . 다음을 사용하여 변경된 것이 있는지 확인하고 다음을 사용하여 HTMLFormElement#isChanged
재설정 양식의 차이점을 포함하는 객체를 가져올 수 있습니다 HTMLFormElement#changes
(입력 이름으로 마스크되지 않는다고 가정).
Object.defineProperties(HTMLFormElement.prototype, {
isChanged: {
configurable: true,
get: function isChanged () {
'use strict'
var thisData = new FormData(this)
var that = this.cloneNode(true)
// avoid masking: https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/reset
HTMLFormElement.prototype.reset.call(that)
var thatData = new FormData(that)
const theseKeys = Array.from(thisData.keys())
const thoseKeys = Array.from(thatData.keys())
if (theseKeys.length !== thoseKeys.length) {
return true
}
const allKeys = new Set(theseKeys.concat(thoseKeys))
function unequal (value, index) {
return value !== this[index]
}
for (const key of theseKeys) {
const theseValues = thisData.getAll(key)
const thoseValues = thatData.getAll(key)
if (theseValues.length !== thoseValues.length) {
return true
}
if (theseValues.some(unequal, thoseValues)) {
return true
}
}
return false
}
},
changes: {
configurable: true,
get: function changes () {
'use strict'
var thisData = new FormData(this)
var that = this.cloneNode(true)
// avoid masking: https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/reset
HTMLFormElement.prototype.reset.call(that)
var thatData = new FormData(that)
const theseKeys = Array.from(thisData.keys())
const thoseKeys = Array.from(thatData.keys())
const created = new FormData()
const deleted = new FormData()
const updated = new FormData()
const allKeys = new Set(theseKeys.concat(thoseKeys))
function unequal (value, index) {
return value !== this[index]
}
for (const key of allKeys) {
const theseValues = thisData.getAll(key)
const thoseValues = thatData.getAll(key)
const createdValues = theseValues.slice(thoseValues.length)
const deletedValues = thoseValues.slice(theseValues.length)
const minLength = Math.min(theseValues.length, thoseValues.length)
const updatedValues = theseValues.slice(0, minLength).filter(unequal, thoseValues)
function append (value) {
this.append(key, value)
}
createdValues.forEach(append, created)
deletedValues.forEach(append, deleted)
updatedValues.forEach(append, updated)
}
return {
created: Array.from(created),
deleted: Array.from(deleted),
updated: Array.from(updated)
}
}
}
})
document.querySelector('[value="Check"]').addEventListener('click', function () {
if (this.form.isChanged) {
console.log(this.form.changes)
} else {
console.log('unchanged')
}
})
<form>
<div>
<label for="name">Text Input:</label>
<input type="text" name="name" id="name" value="" tabindex="1" />
</div>
<div>
<h4>Radio Button Choice</h4>
<label for="radio-choice-1">Choice 1</label>
<input type="radio" name="radio-choice-1" id="radio-choice-1" tabindex="2" value="choice-1" />
<label for="radio-choice-2">Choice 2</label>
<input type="radio" name="radio-choice-2" id="radio-choice-2" tabindex="3" value="choice-2" />
</div>
<div>
<label for="select-choice">Select Dropdown Choice:</label>
<select name="select-choice" id="select-choice">
<option value="Choice 1">Choice 1</option>
<option value="Choice 2">Choice 2</option>
<option value="Choice 3">Choice 3</option>
</select>
</div>
<div>
<label for="textarea">Textarea:</label>
<textarea cols="40" rows="8" name="textarea" id="textarea"></textarea>
</div>
<div>
<label for="checkbox">Checkbox:</label>
<input type="checkbox" name="checkbox" id="checkbox" />
</div>
<div>
<input type="button" value="Check" />
</div>
</form>
참고 URL : https://stackoverflow.com/questions/959670/generic-way-to-detect-if-html-form-is-edited
'Programing' 카테고리의 다른 글
Git은 로컬 브랜치가 원격 브랜치 뒤에 있다고 말하지만 그렇지 않습니다. (0) | 2020.10.07 |
---|---|
Linq에서 SQL로-상위 n 개 행 반환 (0) | 2020.10.07 |
Twitter Bootstrap 탭이 작동하지 않음 : 클릭해도 아무 일도 일어나지 않습니다. (0) | 2020.10.07 |
일관성없는 접근성 : 속성 유형에 대한 접근성이 떨어짐 (0) | 2020.10.07 |
Nginx를 업스트림 프록시로 사용하도록 Docker 포트 매핑을 구성하는 방법은 무엇입니까? (0) | 2020.10.06 |