Cách ngăn nút gửi biểu mẫu


917

Trong trang tiếp theo, với Firefox, nút remove sẽ gửi biểu mẫu, nhưng nút add thì không. Làm cách nào để ngăn nút xóa gửi biểu mẫu?

<html>

<head>
    <script type="text/javascript" src="jquery-1.3.2.min.js"></script>
    <script type="text/javascript">
        function addItem() {
            var v = $('form :hidden:last').attr('name');
            var n = /(.*)input/.exec(v);

            var newPrefix;
            if (n[1].length == 0) {
                newPrefix = '1';
            } else {
                newPrefix = parseInt(n[1]) + 1;
            }

            var oldElem = $('form tr:last');
            var newElem = oldElem.clone(true);
            var lastHidden = $('form :hidden:last');

            lastHidden.val(newPrefix);

            var pat = '=\"' + n[1] + 'input';

            newElem.html(newElem.html().replace(new RegExp(pat, 'g'), '=\"' + newPrefix + 'input'));
            newElem.appendTo('table');
            $('form :hidden:last').val('');
        }

        function removeItem() {
            var rows = $('form tr');
            if (rows.length > 2) {
                rows[rows.length - 1].html('');
                $('form :hidden:last').val('');
            } else {
                alert('Cannot remove any more rows');
            }
        }
    </script>
</head>

<body>
    <form autocomplete="off" method="post" action="">
        <p>Title:<input type="text" /></p>
        <button onclick="addItem(); return false;">Add Item</button>
        <button onclick="removeItem(); return false;">Remove Last Item</button>
        <table>
            <th>Name</th>

            <tr>
                <td><input type="text" id="input1" name="input1" /></td>
                <td><input type="hidden" id="input2" name="input2" /></td>
            </tr>
        </table>
        <input id="submit" type="submit" name="submit" value="Submit">
    </form>
</body>

</html>

câu trả lời nào bạn muốn giới thiệu?
sanepete

Câu trả lời:


1798

Bạn đang sử dụng phần tử nút HTML5. Hãy nhớ lý do là nút này có hành vi gửi mặc định, như đã nêu trong đặc tả W3 như được thấy ở đây: Nút HTML5 của W3C

Vì vậy, bạn cần xác định rõ ràng loại của nó:

<button type="button">Button</button>

để ghi đè loại trình mặc định. Tôi chỉ muốn chỉ ra lý do tại sao điều này xảy ra =)

=)


17
Tôi cũng muốn chỉ ra rằng một phần tử HTML có thuộc tính loại, một trong số các loại đó là nút , không nên f # $ 'n có kiểu gửi mặc định . Nó chỉ đơn giản là ngu ngốc, và một sai lầm lớn trong thông số kỹ thuật. Tôi luôn sử dụng các nút trong các biểu mẫu và ngay cả khi đó là trường hợp cạnh (không phải vậy), vẫn có nghĩa là phải gửi loại mặc định.
dudewad

3
Tôi đã dành hầu hết tuần này bực mình vì ứng dụng Electron của tôi "được làm mới" khi tôi mở một chế độ bằng một nút trong một biểu mẫu. Nó đã xảy ra một lần và sau đó ứng dụng hoạt động như tôi mong đợi. Tôi hoàn toàn không biết chuyện gì đang xảy ra. Đây chính là nó! Tôi không có vấn đề với loại mặc định được gửi. Có vẻ như một chút của một gotcha mặc dù đã cho tôi phải mất năm năm để tìm hiểu về nó.
freethebees

4
Nhờ tham chiếu của bạn, tôi mới biết rằng có một loại = đặt lại cho biểu mẫu. Tuyệt vời!
Dương Nguyên

602

Đặt loại trên các nút của bạn:

<button type="button" onclick="addItem(); return false;">Add Item</button>
<button type="button" onclick="removeItem(); return false;">Remove Last Item</button>

... Điều đó sẽ ngăn họ kích hoạt hành động gửi khi có ngoại lệ xảy ra trong trình xử lý sự kiện. Sau đó, sửa removeItem()chức năng của bạn để nó không kích hoạt ngoại lệ:

function removeItem() {
  var rows = $('form tr');
  if ( rows.length > 2 ) {
    // change: work on filtered jQuery object
    rows.filter(":last").html('');
    $('form :hidden:last').val('');
  } else {
    alert('Cannot remove any more rows');
  }
}

Lưu ý thay đổi: mã gốc của bạn đã trích xuất một phần tử HTML từ bộ jQuery và sau đó thử gọi một phương thức jQuery trên nó - điều này đã tạo ra một ngoại lệ, dẫn đến hành vi mặc định cho nút.

FWIW, có một cách khác mà bạn có thể thực hiện với điều này ... Kết nối trình xử lý sự kiện của bạn bằng jQuery và sử dụng phương thức ngăn chặn DefDefault () trên đối tượng sự kiện của jQuery để hủy bỏ hành vi mặc định trước:

$(function() // execute once the DOM has loaded
{

  // wire up Add Item button click event
  $("#AddItem").click(function(event)
  {
    event.preventDefault(); // cancel default behavior

    //... rest of add logic
  });

  // wire up Remove Last Item button click event
  $("RemoveLastItem").click(function(event)
  {
    event.preventDefault(); // cancel default behavior

    //... rest of remove last logic
  });

});

...

<button type="button" id="AddItem" name="AddItem">Add Item</button>
<button type="button" id="RemoveLastItem" name="RemoveLastItem">Remove Last Item</button>

Kỹ thuật này giữ tất cả logic của bạn ở một nơi, giúp gỡ lỗi dễ dàng hơn ... nó cũng cho phép bạn thực hiện dự phòng bằng cách thay đổi typecác nút quay lại submitvà xử lý phía máy chủ sự kiện - điều này được gọi là không phô trương JavaScript .


4
type = "button" không phải lúc nào cũng hoạt động trong Firefox đối với tôi. Nếu js đủ phức tạp và có lỗi thì Firefox sẽ gửi biểu mẫu. Chứng điên cuồng!
Khóa Matthew

1
@MatthewLock: Khó - một lỗi trong tập lệnh chỉ tắt khối mã đó và hành động tiếp tục như bình thường. Hãy thử gọi các phương thức sự kiện jQuery e.preventDefault () và / hoặc e.stopPropgation () làm các dòng đầu tiên của phương thức. Xem stackoverflow.com/questions/2017755/ trên để tìm hiểu thêm
brichins

8
loại = nút không bao giờ nên gửi biểu mẫu mặc dù, bất kể điều gì
Matthew Lock

1
return falserất quan trọng đôi khi thậm chí sử dụng nó cho nút gửi ( onclick)
Jamie

7
Tôi nghĩ rằng html là lạ ở đây. Nó phải là kiểu = "nút" theo mặc định, không gửi. Tôi luôn luôn bất ngờ khi thấy rằng gửi theo mặc định. Đó là ngoại lệ.
httpete

31

Cách đây không lâu, tôi cần một cái gì đó rất giống ... và tôi đã nhận được nó.

Vì vậy, những gì tôi đặt ở đây là cách tôi thực hiện các thủ thuật để có thể gửi biểu mẫu bằng JavaScript mà không cần xác thực và chỉ thực hiện xác thực khi người dùng nhấn nút (thường là nút gửi).

Ví dụ tôi sẽ sử dụng một hình thức tối thiểu, chỉ với hai trường và nút gửi.

Hãy nhớ những gì đang muốn: Từ JavaScript, nó phải có thể được gửi mà không cần kiểm tra. Tuy nhiên, nếu người dùng nhấn nút như vậy, việc xác thực phải được thực hiện và chỉ gửi mẫu nếu vượt qua xác thực.

Thông thường tất cả sẽ bắt đầu từ một cái gì đó gần này (tôi đã loại bỏ tất cả những thứ không quan trọng):

<form method="post" id="theFormID" name="theFormID" action="">
   <input type="text" id="Field1" name="Field1" />
   <input type="text" id="Field2" name="Field2" />
   <input type="submit" value="Send" onclick="JavaScript:return Validator();" />
</form>

Xem làm thế nào thẻ biểu mẫu không có onsubmit="..."(hãy nhớ rằng đó là một điều kiện không có nó).

Vấn đề là biểu mẫu luôn được gửi, bất kể onclicktrả về truehay false.

Nếu tôi thay đổi type="submit"cho type="button", có vẻ như để làm việc nhưng không. Nó không bao giờ gửi biểu mẫu, nhưng điều đó có thể được thực hiện dễ dàng.

Vì vậy, cuối cùng tôi đã sử dụng điều này:

<form method="post" id="theFormID" name="theFormID" action="">
   <input type="text" id="Field1" name="Field1" />
   <input type="text" id="Field2" name="Field2" />
   <input type="button" value="Send" onclick="JavaScript:return Validator();" />
</form>

Và trên function Validator, ở đâu return True;, tôi cũng thêm một câu gửi JavaScript, một cái gì đó tương tự như thế này:

function Validator(){
   //  ...bla bla bla... the checks
   if(                              ){
      document.getElementById('theFormID').submit();
      return(true);
   }else{
      return(false);
   }
}

Cái id=""này chỉ dành cho JavaScript getElementById, cái name=""này chỉ để nó xuất hiện trên dữ liệu POST.

Trên đường như vậy nó hoạt động như tôi cần.

Tôi đặt cái này chỉ cho những người không cần onsubmitchức năng trên biểu mẫu, nhưng thực hiện một số xác nhận khi người dùng nhấn nút.

Tại sao tôi không cần onsubmit trên thẻ mẫu? Thật dễ dàng, trên các phần JavaScript khác tôi cần thực hiện gửi nhưng tôi không muốn có bất kỳ xác nhận nào.

Lý do: Nếu người dùng là người thực hiện việc gửi tôi muốn và cần thực hiện xác thực, nhưng nếu đó là JavaScript đôi khi tôi cần thực hiện việc gửi trong khi xác thực như vậy sẽ tránh được.

Nghe có vẻ lạ, nhưng không phải khi suy nghĩ chẳng hạn: trên Đăng nhập ... với một số hạn chế ... như không cho phép sử dụng các phiên PHP và không cho phép cookie!

Vì vậy, bất kỳ liên kết phải được chuyển đổi để gửi mẫu như vậy, vì vậy dữ liệu đăng nhập không bị mất. Khi chưa đăng nhập xong, nó cũng phải hoạt động. Vì vậy, không có xác nhận phải được thực hiện trên các liên kết. Nhưng tôi muốn trình bày một thông báo cho người dùng nếu người dùng chưa nhập cả hai trường, người dùng và vượt qua. Vì vậy, nếu một trong những mất tích, hình thức không được gửi! có vấn đề

Xem vấn đề: không được gửi biểu mẫu khi một trường trống chỉ khi người dùng nhấn nút, nếu đó là mã JavaScript thì phải gửi được.

Nếu tôi thực hiện công việc trên onsubmitthẻ biểu mẫu, tôi sẽ cần biết đó là người dùng hay JavaScript khác. Vì không có thông số nào có thể được thông qua, nên không thể trực tiếp, vì vậy một số người thêm một biến để cho biết có phải xác thực hay không. Điều đầu tiên về chức năng xác nhận là kiểm tra giá trị biến đó, v.v ... Quá phức tạp và mã không cho biết điều gì thực sự muốn.

Vì vậy, giải pháp là không có onsubmit trên thẻ biểu mẫu. Insead đặt nó ở nơi thực sự cần thiết, trên nút.

Mặt khác, tại sao lại đặt mã onsubmit vì về mặt khái niệm tôi không muốn xác thực onsubmit. Tôi thực sự muốn xác nhận nút.

Không chỉ mã rõ ràng hơn, đó là nơi nó phải được. Chỉ cần nhớ điều này: - Tôi không muốn JavaScript xác thực biểu mẫu (phải luôn được PHP thực hiện ở phía máy chủ) - Tôi muốn hiển thị cho người dùng một thông báo cho biết tất cả các trường không được để trống, cần JavaScript (máy khách bên)

Vậy tại sao một số người (nghĩ hoặc nói với tôi) nó phải được thực hiện khi xác nhận onsumbit? Không, về mặt khái niệm tôi không thực hiện xác nhận onsumbit ở phía khách hàng. Tôi chỉ đang làm một cái gì đó trên một nút được nhấn, vậy tại sao không để điều đó được thực hiện?

Vâng, mã và phong cách thực hiện các thủ thuật hoàn hảo. Trên bất kỳ JavaScript nào tôi cần gửi biểu mẫu tôi vừa đặt:

document.getElementById('theFormID').action='./GoToThisPage.php'; // Where to go
document.getElementById('theFormID').submit(); // Send POST data and go there

Và điều đó bỏ qua xác nhận khi tôi không cần nó. Nó chỉ gửi biểu mẫu và tải một trang khác, v.v.

Nhưng nếu người dùng nhấp vào nút gửi (còn gọi là type="button"không type="submit") thì việc xác thực được thực hiện trước khi để biểu mẫu được gửi và nếu không hợp lệ thì không được gửi.

Cũng hy vọng điều này sẽ giúp những người khác không thử mã dài và phức tạp. Chỉ cần không sử dụng onsubmitnếu không cần thiết, và sử dụng onclick. Nhưng chỉ cần nhớ thay đổi type="submit"thành type="button"và xin đừng quên thực hiện submit()bằng JavaScript.


28

Tôi đồng ý với Shog9, mặc dù tôi có thể sử dụng:

<input type = "button" onClick="addItem(); return false;" value="Add Item" />

Theo w3schools , <button>thẻ có hành vi khác nhau trên các trình duyệt khác nhau.


18

Giả sử mẫu HTML của bạn có id="form_id"

<form id="form_id">
<!--your HTML code-->
</form>

Thêm đoạn mã jQuery này vào mã của bạn để xem kết quả,

$("#form_id").submit(function(){
  return false;
});

18

Bạn chỉ có thể lấy tham chiếu các nút của mình bằng jQuery và ngăn sự lan truyền của nó như bên dưới:

 $(document).ready(function () {
    $('#BUTTON_ID').click(function(e) {

            e.preventDefault();
            e.stopPropagation();
            e.stopImmediatePropagation();

            return false;
    });});

2
e.preventDefault(); e.stopPropagation();là đủ cho mọi thứ để làm việc. e.stopImmediatePropagation()điều này đưa ra một lỗi của phương thức không xác định trong Chrome.
Subroto

14

$("form").submit(function () { return false; }); điều đó sẽ ngăn nút gửi hoặc bạn chỉ có thể thay đổi loại nút thành "nút" <input type="button"/>thay vì nút <input type="submit"/> này sẽ chỉ hoạt động nếu nút này không phải là nút duy nhất trong biểu mẫu này.


2
Đây là cho jQuery, một tương đương trong Javascript là: myform.onsubmit = function () {return false} ... đồng thời, ngay cả khi bạn loại bỏ nút gửi, biểu mẫu cũng có thể được gửi bằng cách nhấn enter từ trường biểu mẫu khác.
Synexis

10

Đây là một lỗi html5 như đã nói, bạn vẫn có thể có nút dưới dạng gửi (nếu bạn muốn bao gồm cả người dùng javascript và không javascript) bằng cách sử dụng nó như sau:

     <button type="submit" onclick="return false"> Register </button>

Bằng cách này, bạn sẽ hủy gửi nhưng vẫn làm bất cứ điều gì bạn đang làm trong hàm jquery hoặc javascript và thực hiện gửi cho người dùng không có javascript.


8

Tôi chắc chắn rằng trên FF

removeItem 

Hàm gặp lỗi JavaScript, điều này không xảy ra trên IE

Khi lỗi javascript xuất hiện mã "return false" sẽ không chạy, làm cho trang phải gửi lại


8

Trả về false ngăn chặn hành vi mặc định. nhưng sai trả về phá vỡ bong bóng của các sự kiện nhấp bổ sung. Điều này có nghĩa là nếu có bất kỳ ràng buộc nhấp chuột nào khác sau khi chức năng này được gọi, những người khác không xem xét.

 <button id="btnSubmit" type="button">PostData</button>
 <Script> $("#btnSubmit").click(function(){
   // do stuff
   return false;
}); </Script>

Hoặc đơn giản là bạn có thể đặt như thế này

 <button type="submit" onclick="return false"> PostData</button>

7

Chỉ cần thêm e.preventDefault();vào phương thức của bạn sẽ ngăn trang của bạn gửi biểu mẫu.

function myFunc(e){
       e.preventDefault();
}

Theo Tài liệu web MDN

Phương thức notifyDefault () của giao diện Sự kiện cho tác nhân người dùng biết rằng nếu sự kiện không được xử lý rõ ràng, thì hành động mặc định của nó sẽ không được tính đến như bình thường. Sự kiện này tiếp tục lan truyền như bình thường, trừ khi một trong những người nghe của nó gọi stopPropagation ()hoặc stopImmediatePropagation (), một trong hai kết thúc việc truyền bá.


6

Đặt nút của bạn theo cách thông thường và sử dụng event.preventDefault như ..

   <button onclick="myFunc(e)"> Remove </button>  
   ...
   ...

   In function...

   function myFunc(e){
       e.preventDefault();
   }

4
return false;

Bạn có thể trả về false ở cuối hàm hoặc sau khi gọi hàm.

Miễn là điều cuối cùng xảy ra, biểu mẫu sẽ không được gửi.


2

Đây là một cách tiếp cận đơn giản:

$('.mybutton').click(function(){

    /* Perform some button action ... */
    alert("I don't like it when you press my button!");

    /* Then, the most important part ... */
    return false;

});

1

Mã mẫu sau đây cho bạn thấy làm thế nào để ngăn chặn nhấp vào nút gửi biểu mẫu.

Bạn có thể thử mã mẫu của tôi:

 <form autocomplete="off" method="post" action="">
   <p>Title:
     <input type="text" />
   </p>
   <input type="button" onclick="addItem()" value="Add Item">
   <input type="button" onclick="removeItem()" value="Remove Last Item">
   <table>
     <th>Name</th>

     <tr>
       <td>
         <input type="text" id="input1" name="input1" />
       </td>
       <td>
         <input type="hidden" id="input2" name="input2" />
       </td>
     </tr>
   </table>
   <input id="submit" type="submit" name="submit" value="Submit">
 </form>
<script language="javascript">
function addItem() {
return false;
}

function removeItem() {
return false;
}
</script>

0

Tôi không thể kiểm tra điều này ngay bây giờ, nhưng tôi nghĩ bạn có thể sử dụng phương thức ngăn chặn của jQuery .


0

Hàm removeItem thực sự có lỗi, làm cho nút biểu mẫu thực hiện hành vi mặc định của nó (gửi biểu mẫu). Bảng điều khiển lỗi javascript thường sẽ đưa ra một con trỏ trong trường hợp này.

Kiểm tra chức năng removeItem trong phần javascript:

Dòng:

rows[rows.length-1].html('');

không hoạt động. Hãy thử điều này thay thế:

rows.eq(rows.length-1).html('');
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.