jQuery에서 양식 변경을 어떻게 처리합니까?


81

jQuery에서 양식의 요소가 변경되었는지 테스트하는 간단한 방법이 있습니까?

편집 :click() 이벤트 만 확인하면된다고 추가해야합니다 .

편집 : 정말 더 구체적이어야 미안합니다! 양식이 있고 다음과 같은 버튼이 있다고 가정합니다.

$('#mybutton').click(function() {
  // Here is where is need to test
  if(/* FORM has changed */) {
     // Do something
  }
});

양식이로드 된 후 변경되었는지 어떻게 테스트합니까?


페이지에 포함 된 다른 스크립트의 동작을 의미합니까, 아니면 사용자가 텍스트를 입력하거나 라디오 / 체크 박스를 클릭하자마자 의미합니까?
— FelipeAls 2010-06-11

click () 이벤트 만 확인하면된다고 추가 했어야합니다
— mike

답변:


140

다음과 같이 할 수 있습니다.

$("form :input").change(function() {
  $(this).closest('form').data('changed', true);
});
$('#mybutton').click(function() {
  if($(this).closest('form').data('changed')) {
     //do something
  }
});

이것은 릭 change그 중 하나가 사용 변경하면, 형태의 입력에 이벤트 핸들러를 .data()세트에 changed가치를 true우리는 단지 클릭에 그 값을 확인,이 그 가정 #mybutton(바로 교체하지 않을 경우 형태로 내부 $(this).closest('form')에 $('#myForm')) 그러나 다음과 같이 더 일반적으로 만들 수 있습니다.

$('.checkChangedbutton').click(function() {
  if($(this).closest('form').data('changed')) {
     //do something
  }
});

참조 : 업데이트 됨

jQuery에 따르면 이것은 모든 양식 컨트롤을 선택하는 필터입니다.

http://api.jquery.com/input-selector/

: input 선택기는 기본적으로 모든 양식 컨트롤을 선택합니다.


6
합니까 $('form :input')선택, 텍스트 영역 및 기타 입력 유형의 계정을? 아니면 입력 태그에만 해당됩니까?
— Val

6
내가 틀렸다면 정정 해주세요.이 방법은 누군가가 변경 한 다음 변경을 "취소"하여 양식의 원래 값으로 수동으로 되돌려도 양식이 변경되었다고 말합니다. 이 경우 형식은 데이터와 관련하여 실제로 변경되지 않았지만이 방법은 변경되었다고 말할 수 있습니다.
— paul

1
고마워, 그래도 시도했지만 (다른 답변에 나열되어 있음) 저에게 효과가 없었습니다. 그 방법을 넘어서는 특별한 경우가있는 것 같습니다. 현재 플러그인 작업 - github.com/codedance/jquery.AreYouSure
— 폴

1
이 경우에 좋은 솔루션입니다! 그러나 여기에있는 누군가가 양식의 콘텐츠 상태 (예 : "IsDirty")를 얻으려면 다음 솔루션을 따르십시오. stackoverflow.com/a/26796840/665783
— Jacob

1
@Nick Craver : 양식 요소가 양식의 ID로 양식 속성이있는 양식 태그 외부에 있으면 어떻게 될까요? 나는 케이스를 테스트했지만 운이 좋지 않습니다.
— Mahantesh

49

서버로 보낼 양식 데이터가 변경되었는지 확인하려면 페이지로드시 양식 데이터를 직렬화하고 현재 양식 데이터와 비교할 수 있습니다.

$(function() {

    var form_original_data = $("#myform").serialize(); 

    $("#mybutton").click(function() {
        if ($("#myform").serialize() != form_original_data) {
            // Something changed
        }
    });

});

5
훌륭합니다. 이것이 최고의 솔루션입니다. 감사.
— Anonymous

3
이 방법을 한 번 사용했는데 형태가 커지면 매우 느려졌습니다. 이것은 작은 양식에는 좋은 방법이지만 큰 양식에는 적합하지 않습니다.
— mkdevoogd 2013

파일이있는 양식을 의미합니까?
— Udi

1
이것은 좋지만 컨트롤이 변경 될 때마다 확인하는 대신 양식이 제출 될시기를 직접 확인하는 것이 더 좋을 것입니다
— Ruby Racer

2
이 방법이 훨씬 낫기 때문에 "삭제"와 같이 버튼을 비활성화 상태로 되돌릴 수 있습니다.
— EliuX

29

실시간 및 간단한 솔루션 :

$('form').on('keyup change paste', 'input, select, textarea', function(){
    console.log('Form changed!');
});

1
아주 좋은 솔루션입니다. 양식 유효성 검사를 입력 할 때 적합합니다.
— Bijan 2014

1
나를위한 최고의 솔루션! 감사합니다.
— 이반

2
이전 브라우저를 지원해야하는 경우가 아니라면 오른쪽 마우스 붙여 넣기를 처리 하는 'input'대신 사용 을 고려하십시오 'keyup change'.
— TrueWill

10

여러 선택기를 사용하여 모든 양식 요소의 변경 이벤트에 콜백을 연결할 수 있습니다.

$("input, select").change(function(){
    // Something changed
});

편집하다

클릭 한 번에만 필요하다고 언급 했으므로 원래 코드를 다음과 같이 수정할 수 있습니다.

$("input, select").click(function(){
    // A form element was clicked
});

# 2 수정

좋아, 다음과 같이 무언가가 변경되면 설정되는 전역을 설정할 수 있습니다.

var FORM_HAS_CHANGED = false;

$('#mybutton').click(function() {
    if (FORM_HAS_CHANGED) {
        // The form has changed
    }
});

$("input, select").change(function(){
    FORM_HAS_CHANGED = true;
});

3

업데이트 된 질문을보고 다음과 같이 시도하십시오.

$('input, textarea, select').each(function(){
    $(this).data("val", $(this).val());
});
$('#button').click(function() {
    $('input, textarea, select').each(function(){
        if($(this).data("val")!==$(this).val()) alert("Things Changed");
    });
});

원래 질문의 경우 다음과 같이 사용하십시오.

$('input').change(function() {
    alert("Things have changed!");
});

이것은 <textarea>또는 <select>요소를 확인하지 않습니다 .
— Nick Craver

편집 후 ... 이것은 많은 추가 작업과 데이터가 이동되는 것처럼 보이며 boolean변경이 발생할 때 필요한 것은 true 로 설정하는 것뿐입니다. 또한 이것은 여전히 ​​양식별로 다르지 않습니다. 페이지에 다른 양식이 있으면 어떻게됩니까?
— Nick Craver

+1은 좋지만 약간의 작업이 필요하고 바인딩하여 형성하고 초기화합니다.
— Anonymous

그 :) 내가 생각 정확히 무엇 (Y) 당신의 누 볐어
— RK 샤르마


2

여기에 우아한 해결책이 있습니다.

값이 변경되었는지 여부를 판별하는 데 사용할 수있는 양식의 각 입력 요소에 대한 숨겨진 특성이 있습니다. 각 입력 유형에는 고유 한 속성 이름이 있습니다. 예를 들면

  • 에 대한 text/textarea그것의 DEFAULTVALUE
  • 에 대한 select그것의 defaultSelect
  • 에 대한 checkbox/radio그것의 defaultChecked

다음은 그 예입니다.

function bindFormChange($form) {

  function touchButtons() {
    var
      changed_objects = [],
      $observable_buttons = $form.find('input[type="submit"], button[type="submit"], button[data-object="reset-form"]');

    changed_objects = $('input:text, input:checkbox, input:radio, textarea, select', $form).map(function () {
      var
        $input = $(this),
        changed = false;

      if ($input.is('input:text') || $input.is('textarea') ) {
        changed = (($input).prop('defaultValue') != $input.val());
      }
      if (!changed && $input.is('select') ) {
        changed = !$('option:selected', $input).prop('defaultSelected');
      }
      if (!changed && $input.is('input:checkbox') || $input.is('input:radio') ) {
        changed = (($input).prop('defaultChecked') != $input.is(':checked'));
      }
      if (changed) {
        return $input.attr('id');
      }

    }).toArray();

    if (changed_objects.length) {
      $observable_buttons.removeAttr('disabled')   
    } else {
      $observable_buttons.attr('disabled', 'disabled');
    }
  };
  touchButtons();

  $('input, textarea, select', $form).each(function () {
    var $input = $(this);

    $input.on('keyup change', function () {
      touchButtons();
    });
  });

};

이제 페이지의 양식을 반복하면 기본적으로 비활성화 된 제출 버튼이 표시되고 실제로 양식의 일부 입력 값을 변경하는 경우에만 활성화됩니다.

$('form').each(function () {
    bindFormChange($(this));
});

jQuery플러그인으로 구현하는 방법 은 여기 https://github.com/kulbida/jmodifiable입니다.


2
var formStr = JSON.stringify($("#form").serializeArray());
...
function Submit(){
   var newformStr = JSON.stringify($("#form").serializeArray());
   if (formStr != newformStr){
      ...
         formChangedfunct();
      ...
   }
   else {
      ...
         formUnchangedfunct();
      ...
   }
}

예, 몇 년 후 저는 더 이상 jQuery를 사용하지 않습니다. 지금까지 관찰자와 바인딩! jQuery를 사용하는 모든 사람에게 좋습니다.
— mike


1

Udi의 답변을 확장하면 모든 입력 변경이 아닌 양식 제출 만 확인합니다.

$(document).ready( function () {
  var form_data = $('#myform').serialize();
  $('#myform').submit(function () {
      if ( form_data == $(this).serialize() ) {
        alert('no change');
      } else {
        alert('change');
      }
   });
});

0

먼저 양식의 상태를 추적하기 위해 양식에 숨겨진 입력을 추가합니다. 그런 다음이 jQuery 스 니펫을 사용하여 양식의 내용이 변경 될 때 숨겨진 입력의 값을 설정합니다.

    $("form")
    .find("input")
    .change(function(){
        if ($("#hdnFormChanged").val() == "no")
        {
            $("#hdnFormChanged").val("yes");
        }
    });

버튼을 클릭하면 숨겨진 입력 상태를 확인할 수 있습니다.

$("#Button").click(function(){
    if($("#hdnFormChanged").val() == "yes")
    {
        // handler code here...
    }
});

0

$('form[name="your_form_name"] input, form[name="your_form_name"] select').click(function() {
  $("#result").html($(this).val());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>Form "your_form_name"</h2>
<form name="your_form_name">
  <input type="text" name="one_a" id="one_a" value="AAAAAAAA" />
  <input type="text" name="one_b" id="one_b" value="BBBBBBBB" />
  <input type="text" name="one_c" id="one_c" value="CCCCCCCC" />
  <select name="one_d">
    <option value="111111">111111</option>
    <option value="222222">222222</option>
    <option value="333333">333333</option>
  </select>
</form>
<hr/>
<h2>Form "your_other_form_name"</h2>
<form name="your_other_form_name">
  <input type="text" name="two_a" id="two_a" value="DDDDDDDD" />
  <input type="text" name="two_b" id="two_b" value="EEEEEEEE" />
  <input type="text" name="two_c" id="two_c" value="FFFFFFFF" />
  <input type="text" name="two_d" id="two_d" value="GGGGGGGG" />
  <input type="text" name="two_e" id="two_f" value="HHHHHHHH" />
  <input type="text" name="two_f" id="two_e" value="IIIIIIII" />
  <select name="two_g">
    <option value="444444">444444</option>
    <option value="555555">555555</option>
    <option value="666666">666666</option>
  </select>
</form>
<h2>Result</h2>
<div id="result">
  <h2>Click on a field..</h2>
</div>

위의 @JoeD의 답변 외에도.

필드뿐 아니라 특정 양식의 필드를 대상으로 지정하려는 경우 (두 개 이상의 양식이 있다고 가정) 다음 코드를 사용할 수 있습니다.

$('form[name="your_form_name"] input, form[name="your_form_name"] select').click(function() {
    // A form element was clicked
});

참고로, 이것은 아마도 원하는 작업을 수행하지 않을 것입니다. "your_form_name"양식의 입력 요소를 대상으로하고 문서에서 모두 선택합니다. 또한 성능상의 이유로 하위 선택자를 대상으로하는 것보다 항상 $ .fn.find를 사용하는 것이 좋습니다. 예 :$('form').find('input,select')
— dgo

@ user1167442 양식이 두 개 이상이면 어떻습니까? 내 예는 단일 페이지에 둘 이상의 양식이있는 상황입니다.
— Anjana Silva

1
그러나 여전히-귀하의 예제는 "your_form_name"양식의 자식 인 모든 입력 요소를 찾은 다음 "your_form_name"의 자식인지 아니면 어떤 형태인지 모두 선택합니다. 해당 양식의 선택만을 대상으로하지 않는 한 여러 양식에 대해 예제가 작동하지 않습니다. 당신은 성능 부분을 참조하는 경우 또한, 항상 더 나은 사용하는 것입니다 $.fn.find빨리도 이상 - $.fn.filter- 참조 아이들에게 오히려 하위 선택기를 사용하는 것보다. vaughnroyko.com/the-real-scoop-on-jquery-find-performance
— dgo

1
@ user1167442, 당신은 절대적으로 옳습니다. 나는 당신이 어떤 형태에 있든 상관없이 select가 표적이된다는 사실을 놓쳤다. 나는 그것을 수정했다. 지적 해 주셔서 대단히 감사합니다. 건배!
— Anjana Silva

0

이 시도:

<script>
var form_original_data = $("form").serialize(); 
var form_submit=false;
$('[type="submit"]').click(function() {
    form_submit=true;
});
window.onbeforeunload = function() {
    //console.log($("form").submit());
    if ($("form").serialize() != form_original_data && form_submit==false) {
        return "Do you really want to leave without saving?";
    }
};
</script>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.