จะทำ Jquery Callback หลังจากส่งแบบฟอร์มได้อย่างไร?


119

ฉันมีรูปแบบง่ายๆด้วย remote = true

แบบฟอร์มนี้อยู่ในกล่องโต้ตอบ HTML ซึ่งจะปิดทันทีที่คลิกปุ่มส่ง

ตอนนี้ฉันต้องทำการเปลี่ยนแปลงบางอย่างในหน้า HTML หลักหลังจากส่งแบบฟอร์มสำเร็จแล้ว

ฉันลองใช้ jQuery แต่สิ่งนี้ไม่มั่นใจว่างานจะสำเร็จหลังจากการตอบสนองบางรูปแบบของการส่งแบบฟอร์ม

$("#myform").submit(function(event) {

// do the task here ..

});

ฉันจะแนบการโทรกลับได้อย่างไรเพื่อให้รหัสของฉันถูกเรียกใช้หลังจากส่งแบบฟอร์มสำเร็จแล้วเท่านั้น มีวิธีใดบ้างในการเพิ่มการเรียกกลับ. สำเร็จหรือการเรียกกลับแบบสมบูรณ์ในแบบฟอร์ม?


ทำไมคุณไม่ใช้ Ajax? ด้วยฟังก์ชัน jQuery Ajax คุณสามารถกำหนดการเรียกกลับดังกล่าวได้
davidbuzatto

12
davidbuzatto มีบางกรณีที่คุณไม่สามารถใช้ ajax ได้ ตัวอย่างเช่นเมื่อคุณต้องการอัปโหลดไฟล์
Pere

3
@Pere ไม่เป็นความจริงที่นี่ในอนาคต
SparK

คำตอบ:


119

ฉันเพิ่งทำสิ่งนี้ -

 $("#myform").bind('ajax:complete', function() {

         // tasks to do 


   });

และสิ่งต่างๆก็ทำงานได้อย่างสมบูรณ์แบบ

ดูเอกสาร api นี้สำหรับรายละเอียดเพิ่มเติม


3
ว้าว ... เพิ่งได้เรียนรู้อะไรใหม่ ๆ ใช่จากรูปลักษณ์ของมันนี่เป็นวิธีที่ง่ายที่สุด บางทีมันอาจจะดีที่สุด ฉันเป็นนักอ่าน Coding Horror ตัวยงและในบล็อกนั้น Jeff Attwood เน้นย้ำว่าเราควรเขียนโค้ดให้น้อยลงและวิธีนี้ก็บรรลุผลสำเร็จ หาดี :)
Sal

7
และถ้า<form>ส่งมักจะ? (ฉันไม่ได้หมายถึง Ajax) ฉันจะใส่อะไรในอาร์กิวเมนต์แรกของ.bind()? แก้ไข: clickดีผมคิดว่า Nvm ขออภัย : p
4wk_

9
ระวัง: นี้เป็นไปที่จะยิงฟังก์ชั่นของคุณหลังจากเสร็จสิ้นการใด ๆเหตุการณ์ที่อาแจ็กซ์ไม่เพียง แต่ส่งแบบฟอร์มของคุณ (ถ้าผมเข้าใจผิดซึ่งในกรณีนี้ผมรักสำหรับคุณที่จะมีการเชื่อมโยงกับสถานที่ที่คุณพบก)
dmac the Destroyer

18
"ตั้งแต่ jQuery 1.8 ควรแนบเมธอด. jaxComplete () ไปกับเอกสารเท่านั้น"
เมเรดิ ธ

6
ไม่ได้ทำงานในรูปแบบฉันโดยใช้ Form ปกติพร้อมปุ่ม แต่ปุ่มเรียก javascript $ ('# formFile') submit ();
Daniel

35

ฉันไม่สามารถรับโซลูชันที่ได้รับการโหวตอันดับหนึ่งให้ทำงานได้อย่างน่าเชื่อถือ แต่พบว่าวิธีนี้ใช้ได้ผล ไม่แน่ใจว่าจำเป็นหรือไม่ แต่ฉันไม่มีแอตทริบิวต์ action หรือ method บนแท็กซึ่งทำให้แน่ใจว่า POST ได้รับการจัดการโดยฟังก์ชัน $ .ajax และให้ตัวเลือกการโทรกลับ

<form id="form">
...
<button type="submit"></button>
</form>

<script>
$(document).ready(function() {
  $("#form_selector").submit(function() {

    $.ajax({
     type: "POST",
      url: "form_handler.php",
      data: $(this).serialize(),
      success: function() {
        // callback code here
       }
    })

  })
})
</script>

1
+1 กุญแจสำคัญสำหรับคำตอบนี้คือ$(this).serialize()บรรทัด ช่วยให้คุณใช้jQuery.ajax()เพื่อส่งแบบฟอร์มที่มีอยู่ในเบื้องหลังจากนั้นรับการตอบกลับจากเซิร์ฟเวอร์และดำเนินการกับมัน
Warren Young

15
javascript ที่ไม่มีเครื่องหมายอัฒภาค ... บางคนแค่อยากดูโลกมอดไหม้ วิธีแก้ปัญหาของคุณใช้งานได้ดีขอบคุณ :)
viggity

2
โปรดทราบว่า.serializeไม่รวมอินพุตไฟล์ในคำขอ POSTed ของคุณ ใช้ HTML5 FormData (ดูคำถามนี้ ) แทนเว้นแต่ว่าคุณจะรองรับเบราว์เซอร์เก่าเช่น IE <9
brichins

อุปกรณ์ประกอบการใช้$(this).serialize()มันแก้ปัญหาของฉันได้!
gnclmorais

'form_selector' ใน html ของคุณที่คุณอ้างอิงใน js คืออะไร
Kevin Meredith

23

คุณจะต้องทำสิ่งต่างๆด้วยตนเองด้วยการเรียก AJAX ไปยังเซิร์ฟเวอร์ ซึ่งจะทำให้คุณต้องแทนที่แบบฟอร์มด้วย

แต่ไม่ต้องกังวลมันเป็นเค้ก นี่คือภาพรวมเกี่ยวกับวิธีการทำงานกับแบบฟอร์มของคุณ:

  • แทนที่การดำเนินการส่งเริ่มต้น (ขอบคุณวัตถุที่ส่งผ่านในเหตุการณ์ที่มีpreventDefaultวิธีการ)
  • คว้าค่าที่จำเป็นทั้งหมดจากแบบฟอร์ม
  • ปิดการร้องขอ HTTP
  • จัดการการตอบสนองต่อคำขอ

ขั้นแรกคุณจะต้องยกเลิกแบบฟอร์มส่งการดำเนินการดังนี้:

$("#myform").submit(function(event) {
    // Cancels the form's submit action.
    event.preventDefault();
});

จากนั้นคว้าค่าของข้อมูล สมมติว่าคุณมีกล่องข้อความเดียว

$("#myform").submit(function(event) {
    event.preventDefault();
    var val = $(this).find('input[type="text"]').val();
});

จากนั้นจึงส่งคำขอ สมมติว่าเป็นคำขอ POST

$("#myform").submit(function(event) {
    event.preventDefault();
    var val = $(this).find('input[type="text"]').val();

    // I like to use defers :)
    deferred = $.post("http://somewhere.com", { val: val });

    deferred.success(function () {
        // Do your stuff.
    });

    deferred.error(function () {
        // Handle any errors here.
    });
});

และสิ่งนี้ควรทำ

หมายเหตุ 2:สำหรับการแยกข้อมูลในแบบฟอร์มของมันเป็นที่นิยมที่คุณใช้ปลั๊กอิน มันจะทำให้ชีวิตของคุณง่ายขึ้นจริง ๆ รวมทั้งให้ความหมายที่ดีซึ่งเลียนแบบการดำเนินการส่งแบบฟอร์มจริง

หมายเหตุ 2:คุณไม่จำเป็นต้องใช้ defers เป็นเพียงความชอบส่วนบุคคล คุณสามารถทำสิ่งต่อไปนี้ได้อย่างเท่าเทียมกันและควรได้ผลเช่นกัน

$.post("http://somewhere.com", { val: val }, function () {
    // Start partying here.
}, function () {
    // Handle the bad news here.
});

2
ตัวอย่างที่ดี จะทำสิ่งเดียวกันกับการอัพโหลดไฟล์ (หลายส่วน / แบบฟอร์มข้อมูล) ???
Adam W

11

สำหรับ MVC นี่เป็นวิธีที่ง่ายกว่า คุณต้องใช้แบบฟอร์ม Ajax และตั้งค่า AjaxOptions

@using (Ajax.BeginForm("UploadTrainingMedia", "CreateTest", new AjaxOptions() { HttpMethod = "POST", OnComplete = "displayUploadMediaMsg" }, new { enctype = "multipart/form-data", id = "frmUploadTrainingMedia" }))
{ 
  ... html for form
}

นี่คือรหัสการส่งซึ่งอยู่ในส่วนพร้อมเอกสารและเชื่อมโยงเหตุการณ์ onclick ของปุ่มเพื่อส่งแบบฟอร์ม

$("#btnSubmitFileUpload").click(function(e){
        e.preventDefault();
        $("#frmUploadTrainingMedia").submit();
});

นี่คือการโทรกลับที่อ้างถึงใน AjaxOptions

function displayUploadMediaMsg(d){
    var rslt = $.parseJSON(d.responseText);
    if (rslt.statusCode == 200){
        $().toastmessage("showSuccessToast", rslt.status);
    }
    else{
        $().toastmessage("showErrorToast", rslt.status);
    }
}

ในวิธีการควบคุมสำหรับ MVC จะมีลักษณะเช่นนี้

[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult UploadTrainingMedia(IEnumerable<HttpPostedFileBase> files)
{
    if (files != null)
    {
        foreach (var file in files)
        {
            // there is only one file  ... do something with it
        }
        return Json(new
        {
            statusCode = 200,
            status = "File uploaded",
            file = "",
        }, "text/html");
    }
    else
    {
        return Json(new
        {
            statusCode = 400,
            status = "Unable to upload file",
            file = "",
        }, "text/html");
    }
}

2
รหัสเหล่านั้นคือรหัส. Net และในคำถามไม่เคยระบุไว้
MrMins

13
นั่นไม่ใช่เหตุผลที่ดีในการลงคะแนนนี้ คำตอบได้ผลและอาจช่วยนักพัฒนา. NET ที่ประสบปัญหาเดียวกัน
edepperson

ฉันชอบแนวคิดนี้ แต่ด้วยเหตุผลบางประการการติดต่อกลับไม่เริ่มทำงาน เมธอดคอนโทรลเลอร์ต้องส่งคืน JsonResult หรือไม่ วิธีการควบคุมของฉันส่งคืน ActionResult
mattpm

7

ฉันไม่เชื่อว่ามีฟังก์ชันเรียกกลับเหมือนที่คุณอธิบาย

สิ่งปกติที่นี่คือการเปลี่ยนแปลงโดยใช้ภาษาฝั่งเซิร์ฟเวอร์เช่น PHP

ตัวอย่างเช่นใน PHP คุณสามารถดึงฟิลด์ที่ซ่อนจากแบบฟอร์มของคุณและทำการเปลี่ยนแปลงบางอย่างได้หากมีอยู่

PHP:

  $someHiddenVar = $_POST["hidden_field"];
    if (!empty($someHiddenVar)) {
        // do something 
    }

วิธีหนึ่งที่จะใช้ใน Jquery คือการใช้ Ajax คุณสามารถฟังเพื่อส่งกลับเท็จเพื่อยกเลิกพฤติกรรมเริ่มต้นและใช้ jQuery.post () แทน jQuery.post มีการโทรกลับที่สำเร็จ

$.post("test.php", $("#testform").serialize(), function(data) {
  $('.result').html(data);
});

http://api.jquery.com/jQuery.post/


0

ระบบจะเรียกตัวจัดการ "เมื่อส่ง" ของแบบฟอร์มก่อนส่งแบบฟอร์ม ฉันไม่รู้ว่ามีตัวจัดการที่จะถูกเรียกหลังจากส่งแบบฟอร์มหรือไม่ ในความหมายที่ไม่ใช่ Javascript แบบดั้งเดิมการส่งแบบฟอร์มจะโหลดหน้านี้ซ้ำ


เว้นแต่การส่งแบบฟอร์มจะเปลี่ยนเส้นทางไปยังการดาวน์โหลดไฟล์ซึ่งในกรณีนี้หน้าเว็บจะไม่เสียหาย ฉันไม่สามารถใช้การส่ง JavaScript ได้เนื่องจากคำขอ Ajax ไม่สามารถเริ่มการดาวน์โหลดไฟล์ (หากไม่มีเกมแท็กจุดยึด) แต่ฉันก็ไม่สามารถบอกให้ผู้ใช้รอหรือล้างข้อมูลเมื่อมีไฟล์ ...
kitsu .eb

-1
$("#formid").ajaxForm({ success: function(){ //to do after submit } });

3
เป็นajaxForm()ส่วนประกอบของบุคคลที่สามคุณได้ติดตั้ง? ไม่ใช่ส่วนมาตรฐานของ jQuery
Warren Young
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.