วิธีใช้ Twitter Bootstrap popovers สำหรับการแจ้งเตือนการตรวจสอบความถูกต้อง jQuery


84

ฉันสามารถทำให้ป๊อปโอเวอร์ปรากฏขึ้นโดยใช้bootstrapได้ง่ายพอและฉันยังสามารถทำการตรวจสอบความถูกต้องโดยใช้ปลั๊กอินตรวจสอบความถูกต้อง jQueryมาตรฐานหรือเครื่องมือตรวจสอบความถูกต้อง jQueryแต่ฉันไม่สามารถหาวิธีป้อนข้อมูลลงในอีกรายการหนึ่งได้

ฉันคิดว่าสิ่งที่ฉันต้องการคือ hook ที่ถูกเรียกโดย validator เมื่อต้องการแสดงการแจ้งเตือนให้ปิดการส่งข้อความและองค์ประกอบเป้าหมายไปยัง popover ดูเหมือนว่าเป็นการฉีดยาแบบพึ่งพา

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

ฉันชอบระบบตรวจสอบความถูกต้องที่ใช้คลาสเพื่อกำหนดกฎมากกว่าเนื่องจากพวกเขาเล่นได้ดีกับรูปแบบที่สร้างขึ้นแบบไดนามิก

ใครมีวิธีแก้ปัญหาหรือแนวคิดที่ดีกว่านี้

คำตอบ:


21

ดูตัวเลือกhighlightและshowErrors jQuery Validatorสิ่งเหล่านี้จะช่วยให้คุณสามารถเชื่อมต่อกับไฮไลต์ข้อผิดพลาดที่กำหนดเองของคุณเองซึ่งเรียกใช้ Bootstrap popovers


เยี่ยมมากขอบคุณ ไฮไลต์และไฮไลท์คือสิ่งที่ฉันกำลังมองหา
Synchro

80

นี่คือตัวอย่างภาคปฏิบัติ:

$('form').validate({
    errorClass:'error',
    validClass:'success',
    errorElement:'span',
    highlight: function (element, errorClass, validClass) { 
        $(element).parents("div[class='clearfix']").addClass(errorClass).removeClass(validClass); 
    }, 
    unhighlight: function (element, errorClass, validClass) { 
        $(element).parents(".error").removeClass(errorClass).addClass(validClass); 
    }
});

ใส่คำอธิบายภาพที่นี่

มันไม่ได้ใช้ bootstrap popovers แต่มันดูดีมากและทำได้ง่าย

อัปเดต

ดังนั้นในการตรวจสอบความถูกต้องคุณสามารถใช้รหัสนี้:

$("form").validate({
  rules : {
    test : {
      minlength: 3 ,
      required: true
    }
  },
  showErrors: function(errorMap, errorList) {
    $.each(this.successList, function(index, value) {
      return $(value).popover("hide");
    });
    return $.each(errorList, function(index, value) {
      var _popover;
      _popover = $(value.element).popover({
        trigger: "manual",
        placement: "top",
        content: value.message,
        template: "<div class=\"popover\"><div class=\"arrow\"></div><div class=\"popover-inner\"><div class=\"popover-content\"><p></p></div></div></div>"
      });
      // Bootstrap 3.x :      
      //_popover.data("bs.popover").options.content = value.message;
      // Bootstrap 2.x :
      _popover.data("popover").options.content = value.message;
      return $(value.element).popover("show");
    });
  }
});

คุณจะได้รับสิ่งนี้:

ใส่คำอธิบายภาพที่นี่

ตรวจสอบjsFiddle


3
โหวตเพิ่มขึ้นเพราะนี่คือทิศทางของสิ่งที่ฉันกำลังมองหา :-) ดูคำตอบของฉันสำหรับตัวแปร
namin

จะทำอย่างไรถ้าเป็นรูปแบบหลายขั้นตอน
Tachyons

4
โปรดทราบโดยย่อว่า Bootstrap เวอร์ชันล่าสุดจะไม่มีคีย์. data ("popover") อีกต่อไป บางทีเพื่อหลีกเลี่ยงการปะทะกันพวกเขาได้เปลี่ยนคีย์เป็น "bs.popover" ฉันใช้เวลาสักพักเพื่อหาสาเหตุว่าทำไมฉันถึงได้รับข้อผิดพลาดที่ไม่ได้กำหนด ตอนนี้คุณจะต้องใช้_popover.data ("bs.popover") options.content = value.message; ในโค้ดด้านบน
davidethell

ฉันจะแสดงป๊อปอัปในประเภทข้อผิดพลาดอื่นนอกเหนือจากฟิลด์บังคับได้อย่างไร ฉันหมายถึงจะบอกว่าฉันจะปรับแต่งให้แสดงข้อผิดพลาดเฉพาะในกฎเฉพาะได้อย่างไร
arjun

มีปัญหาเล็กน้อยที่คุณสามารถตรวจสอบได้อย่างง่ายดายใน jsFiddle เช่นกัน หากไม่ต้องการฟิลด์และกฎบางข้อเสียป๊อปโอเวอร์จะปรากฏขึ้น แต่ถ้าฉันว่างฟิลด์และโฟกัสไปที่ฟิลด์อื่นป๊อปโอเวอร์ยังคงอยู่ที่นั่น ลูปแรกในรายการ successList จะไม่ถูกเรียกดังนั้นป๊อปโอเวอร์จะไม่อยู่ในสถานะ "ซ่อน" หลังจากอยู่ในสถานะ "แสดง" มีอะไรที่เราสามารถทำได้หรือไม่?
G4bri3l

9

Chris Fulstow พูดถูก แต่ก็ยังต้องใช้เวลาสักพักดังนั้นนี่คือรหัสทั้งหมด:

สิ่งนี้แสดงป๊อปโอเวอร์บนข้อผิดพลาดและซ่อนป้ายกำกับข้อผิดพลาดเริ่มต้น:

$('#login').validate({
  highlight: function(element, errClass) {
    $(element).popover('show');
  },
  unhighlight: function(element, errClass) {
    $(element).popover('hide');
  },
  errorPlacement: function(err, element) {
    err.hide();
  }
}).form();

สิ่งนี้ตั้งค่าป๊อปโอเวอร์ สิ่งเดียวที่คุณต้องการจากสิ่งนี้คือทริกเกอร์: 'คู่มือ'

$('#password').popover({
  placement: 'below',
  offset: 20,
  trigger: 'manual'
});

แอตทริบิวต์หัวเรื่องและเนื้อหาที่ส่งไปยังป๊อปโอเวอร์ใช้งานไม่ได้ดังนั้นฉันจึงระบุไว้ในบรรทัดในการป้อนรหัสผ่านด้วย data-content = 'ขั้นต่ำ 5 ตัวอักษร' และ data-original-title = 'รหัสผ่านไม่ถูกต้อง' คุณต้องมี rel = 'popover' ในแบบฟอร์มของคุณด้วย

วิธีนี้ใช้งานได้ แต่ป๊อปโอเวอร์จะกะพริบเมื่อยกเลิกการเลือก มีความคิดอย่างไรที่จะแก้ไข?


6

ต่อไปนี้เป็นข้อเสนอแนะที่ยอดเยี่ยมจาก Varun Singh ซึ่งป้องกันปัญหา "การสั่นไหว" ของการตรวจสอบความถูกต้องพยายาม "แสดง" อยู่ตลอดเวลาแม้ว่าจะมีป๊อปอัปอยู่แล้วก็ตาม ฉันเพิ่งเพิ่มอาร์เรย์สถานะข้อผิดพลาดเพื่อจับภาพว่าองค์ประกอบใดแสดงข้อผิดพลาดและไม่ได้ ใช้งานได้เหมือนมีเสน่ห์!

var errorStates = [];

$('#LoginForm').validate({
    errorClass:'error',
    validClass:'success',
    errorElement:'span',
    highlight: function (element, errorClass) {
        if($.inArray(element, errorStates) == -1){
            errorStates[errorStates.length] = element;
            $(element).popover('show');
        }
    }, 
    unhighlight: function (element, errorClass, validClass) {
        if($.inArray(element, errorStates) != -1){
            this.errorStates = $.grep(errorStates, function(value) {
              return value != errorStates;
            });
            $(element).popover('hide');
        }
    },
    errorPlacement: function(err, element) {
        err.hide();
    }
});

$('#Login_unique_identifier').popover({
    placement: 'right',
    offset: 20,
    trigger: 'manual'
});

$('#Login_password').popover({
    placement: 'right',
    offset: 20,
    trigger: 'manual'
});

นี่เป็นคำตอบเดียวในหน้านี้ที่เหมาะกับฉัน น่าเสียดายที่ไม่ได้รับการโหวตมากขึ้น
alastairs

1
นี่ไม่ได้หมายความว่าคุณต้องกำหนด Explicit popoverสำหรับทุกๆช่องที่คุณต้องการตรวจสอบความถูกต้องใช่หรือไม่? ถ้าเป็นเช่นนั้นนั่นคือถั่ว
g33kz0r

สำหรับกรณีการใช้งานส่วนใหญ่ฉันคาดหวังว่านี่จะเป็นที่ยอมรับอย่างสมบูรณ์ หากคุณมีทางออกที่ดีที่สุดอย่าลังเลที่จะเพิ่ม :)
เจฟฟรีย์กิลเบิร์ต

5

ส่วนขยาย jQuery สำหรับ jQuery Validation Plugin (ทดสอบด้วยเวอร์ชัน 1.9.0) จะทำเคล็ดลับ

https://github.com/tonycoco/rails_template/blob/master/files/assets/javascripts/jquery.validate.bootstrap.js

นอกจากนี้ยังเพิ่มในข้อความแสดงข้อผิดพลาด Rails-esk บางรายการ


นี่มันเยี่ยมมาก มีประโยชน์มาก ตอนนี้ที่จะคิดออกว่าจะได้รับข้อความที่เหมาะสมสำหรับช่องทำเครื่องหมาย TOS ...
TIG

3

ฉันชอบเปลี่ยน CSS ของ bootstrap เพิ่งเพิ่มคลาสของ jQuery validate ในตำแหน่งที่ถูกต้อง field-validation-error และ input-validation-error

    form .clearfix.error > label, form .clearfix.error .help-block, form .clearfix.error .help-inline, .field-validation-error {
  color: #b94a48;
}
form .clearfix.error input, form .clearfix.error textarea, .input-validation-error {
  color: #b94a48;
  border-color: #ee5f5b;
}
form .clearfix.error input:focus, form .clearfix.error textarea:focus, .input-validation-error:focus {
  border-color: #e9322d;
  -webkit-box-shadow: 0 0 6px #f8b9b7;
  -moz-box-shadow: 0 0 6px #f8b9b7;
  box-shadow: 0 0 6px #f8b9b7;
}

แนวทางนี้ดูดีที่สุดสำหรับฉัน :) นี่คือสิ่งที่ฉันคิดเช่นกัน
Freshblood

3

นี่คือวิธีที่ฉันทำกับ Bootstrap 2.x และ jQuery Validate 1.9

$('#form-register').validate({ errorElement: 'span', errorClass:'help-inline', highlight:    function (element, errorClass) {
        $(element).parent().parent().addClass('error');
    }, unhighlight: function (element, errorClass) {
        $(element).parent().parent().removeClass('error');
    }});

3

โปรดดูสิ่งต่อไปนี้:
- https://gist.github.com/3030983
ฉันคิดว่ามันง่ายที่สุด

แก้ไข

รหัสจากลิงค์:

$('form').validate({
    rules: {
        numero: {
            required: true
        },
        descricao: {
            minlength: 3,
            email: true,
            required: true
        }
    },

    showErrors: function (errorMap, errorList) {

        $.each(this.successList, function (index, value) {
            $(value).popover('hide');
        });


        $.each(errorList, function (index, value) {

            console.log(value.message);

            var _popover = $(value.element).popover({
                trigger: 'manual',
                placement: 'top',
                content: value.message,
                template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><div class="popover-content"><p></p></div></div></div>'
            });

            _popover.data('popover').options.content = value.message;

            $(value.element).popover('show');

        });

    }

});

ขอบคุณมากสำหรับการแจ้งให้ทราบ! ดูเวอร์ชันของฉันสำหรับ Bootstrap แต่มีคำแนะนำเครื่องมือ ในความคิดของฉันมันหรูหรากว่าป๊อปโอเวอร์
Adrian P.

3

ขอบคุณมากสำหรับการแจ้งให้ทราบ! นี่คือเวอร์ชันของฉันสำหรับ Bootstrap แต่มี Tooltips ในความคิดของฉันมันหรูหรากว่าป๊อปโอเวอร์ ฉันรู้ว่าคำถามนี้เป็นของ popovers ดังนั้นโปรดอย่าโหวตด้วยเหตุผลนี้ อาจจะมีคนชอบวิธีนี้ ฉันชอบเวลาที่ค้นหาบางสิ่งและพบแนวคิดใหม่ ๆ ใน Stackoverflow หมายเหตุ: ไม่จำเป็นต้องมาร์กอัปบนแบบฟอร์ม

    $('#LoginForm').validate({
        rules: {
            password: {
                required: true,
                minlength: 6
            },

            email_address: {
                required: true,
                email: true
            }
        },
        messages: {
            password: {
                required: "Password is required",
                minlength: "Minimum length is 6 characters"
            },
            email_address: {
                required: "Email address is required",
                email: "Email address is not valid"
            }
        },  
        submitHandler: function(form) {
            form.submit();
        },

        showErrors: function (errorMap, errorList) {

            $.each(this.successList, function (index, value) {
                $('#'+value.id+'').tooltip('destroy');
            });


            $.each(errorList, function (index, value) {

                $('#'+value.element.id+'').attr('title',value.message).tooltip({
                    placement: 'bottom',
                    trigger: 'manual',
                    delay: { show: 500, hide: 5000 }
                }).tooltip('show');

            });

        }

    }); 

1
ฉันพยายามใช้แนวทางของคุณ แต่ฉันเริ่มได้รับและข้อผิดพลาด มดเขามีปัญหาถ้าคุณใช้ Jquery UI คุณจะได้รับความขัดแย้งเพราะทั้งคู่ใช้คำแนะนำเครื่องมือ ฉันรู้ว่ามีวิธีแก้ปัญหานี้ แต่แค่อยากให้ผู้ใช้คนอื่นรู้
Richard Pérez

+1 สำหรับ jQuery UI โปรดทราบ! คุณจะต้องกำหนดค่าการดาวน์โหลดแบบกำหนดเอง (jQueryUI หรือ Bootstrap) เพื่อไม่รวมฟังก์ชัน Tooltip JS มันจะมีข้อขัดแย้งสำหรับคำแนะนำเครื่องมือใด ๆ หากคุณทำไม่สำเร็จ
Adrian P.

มีเฮ้ผมพยายามที่จะใช้รหัสของคุณกับ regex และเกิดขึ้นจะมีข้อผิดพลาดที่stackoverflow.com/questions/16087351/... คุณคิดว่าคุณสามารถช่วย? :)
psharma

@psharma ไม่เกี่ยวอะไรกับ bootstrap หรือ tooltip ข้อผิดพลาดของคุณคือการประกาศกฎเมื่อคุณได้รับคำตอบสำหรับคำถามของคุณ ข้อความแสดงข้อผิดพลาดกล่าวว่าเงื่อนไขไม่ได้กำหนด!
Adrian P.

ด้วยเหตุผลบางประการนี่เป็นทางออกเดียวที่เหมาะกับฉัน ขอบคุณ!
suchanoob

2

นี่คือวิธีที่ฉันทำให้มันเกิดขึ้น แต่มันเกี่ยวข้องกับการเปลี่ยนแปลง 2 ครั้งในสคริปต์ตรวจสอบความถูกต้อง (ฉันได้รับรหัสสำหรับ bootstrap 1.4 ที่นี่แล้วแก้ไข - http://mihirchitnis.net/2012/01/customizing-error-messages-using-jquery-validate-plugin- สำหรับ twitter bootstrap / )

การโทรของฉันเพื่อตรวจสอบความถูกต้อง:

    $("#loginForm").validate({
  errorClass: "control-group error",
  validClass: "control-group success",
  errorElement: "span", // class='help-inline'
  highlight: function(element, errorClass, validClass) {
    if (element.type === 'radio') {
        this.findByName(element.name).parent("div").parent("div").removeClass(validClass).addClass(errorClass);
    } else {
        $(element).parent("div").parent("div").removeClass(validClass).addClass(errorClass);
    }
  },
  unhighlight: function(element, errorClass, validClass) {
    if (element.type === 'radio') {
        this.findByName(element.name).parent("div").parent("div").removeClass(errorClass).addClass(validClass);
    } else {
        $(element).parent("div").parent("div").removeClass(errorClass).addClass(validClass);
    }
  }
});

จากนั้นคุณต้องเปลี่ยน 2 สิ่งใน jquery.validate.js
1. ใช้การแก้ไขนี้ - https://github.com/bsrykt/jquery-validation/commit/6c3f53ee00d8862bd4ee89bb627de5a53a7ed20a
2. หลังจากบรรทัด 647 (ในฟังก์ชัน showLabel สร้างส่วนฉลาก ) หลังจาก.addClass(this.settings.errorClass)เพิ่มบรรทัด: .addClass("help-inline")
อาจมีคนหาวิธีใช้การแก้ไขที่สองในฟังก์ชันตรวจสอบความถูกต้อง แต่ฉันไม่พบวิธีใดเนื่องจาก showLabel ถูกเรียกหลังจากไฮไลต์


2

นี่คือสิ่งที่ฉันใส่ไว้ในการตรวจสอบความถูกต้องของฉันเพื่อให้เป็นไปตามแนวทาง Twitter Bootstrap ข้อความการตรวจสอบข้อผิดพลาดถูกใส่ไว้ใน a <span class=help-inline>และเราต้องการเน้นที่คอนเทนเนอร์ด้านนอกเป็นerrorหรือsuccess:

errorClass:'help-inline',
errorElement:'span',
highlight: function (element, errorClass, validClass) {
$(element).parents("div.clearfix").addClass('error').removeClass('success');
},
unhighlight: function (element, errorClass, validClass) {
$(element).parents(".error").removeClass('error').addClass('success');
}

2

นี่คือการปรับปรุงเพื่อคำตอบที่ดีเคนนีเมเยอร์เหนือ มีปัญหาสองสามประการที่ทำให้ไม่สามารถใช้งานได้สำหรับฉันซึ่งฉันได้กล่าวถึงในตัวอย่างนี้:

showErrors: function (errorMap, errorList) {
        $.each(this.successList, function (index, element) {
            return $(element).popover("destroy");
        });

        $.each(errorList, function (index, error) {
            var ele = $(error.element); //Instead of referencing the popover directly, I use the element that is the target for the popover

            ele.popover({
                    trigger: "manual",
                    placement: "top",
                    content: function(){ //use a function to assign the error message to content
                        return error.message
                    },
                    template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><div class="popover-content"><p></p></div></div></div>'
            });

            //bs.popover must be used, not just popover
            ele.data("bs.popover").options.content = error.message;

            return $(error.element).popover("show");
        });
    }

ขอบคุณสำหรับความคิดริเริ่ม รหัสมีการเปลี่ยนแปลงมากอย่างที่เห็น :-)
Kenny Meyer

1

ไม่แน่ใจว่าสิ่งนี้เกี่ยวข้องกับการสนทนาหรือไม่เนื่องจากผู้โพสต์ต้นฉบับขอ hooks เพื่อแสดง / ซ่อนรายการ bootstrap popovers

ฉันกำลังมองหาการตรวจสอบความถูกต้องอย่างง่ายและป๊อปโอเวอร์ก็ไม่สำคัญ โพสต์ที่เกี่ยวข้องและเป็นครั้งแรกในผลการค้นหาของ Google ได้มีการทำเครื่องหมายที่ซ้ำกันของคำถามนี้ ดังนั้นจึงควรพูดถึง jqValidation JS ที่ยอดเยี่ยมของ @ ReactiveRaven ซึ่งเรียกว่า jqBootstrapValidation ซึ่งเข้ากันได้ดีกับ Twitter Bootstrap การตั้งค่าใช้เวลาไม่กี่นาทีเท่านั้น ดาวน์โหลดที่นี่

หวังว่านี่จะเป็นการเพิ่มมูลค่า


1

tl; drหลีกเลี่ยงความจำเป็นในการแจกแจง popovers ที่ชัดเจนโดยใช้แผนที่แฮชเพื่อจัดเก็บรหัสขององค์ประกอบและสร้างป๊อปโอเวอร์ได้ทันที (วิธีการผสมของเจฟฟรีย์กิลเบิร์ตและเคนนีเมเยอร์)

ที่นี่ใช้เวลาของฉันซึ่งการแก้ไขปัญหาดังกล่าวริบหรี่โดยคนอื่น ๆ แต่ไม่เหมือนคำตอบ @Jeffrey กิลเบิร์ไม่ได้ใช้รายการ ( errorStates) แต่ใช้ข้อผิดพลาดแผนที่ แฮชแมพ FTW ฉันคิดว่าฉันจำได้ว่าอ่านที่ไหนสักแห่งที่ทุกปัญหาใน CS สามารถแก้ไขได้ด้วยแผนที่แฮช :)

var err_map = new Object();     // <--- n.b.
$("form#set_draws").validate({
  rules: {
    myinput: { required: true, number: true },
  },
  showErrors: function(errorMap, errorList) {
    $.each(this.successList, function(index, value) {
      if (value.id in err_map)
      {
        var k = err_map[value.id];
        delete err_map[value.id]; // so validation can transition between valid/invalid states
        k.popover("hide");
      }
    });
    return $.each(errorList, function(index, value) {
      var element = $(value.element);
      if( ! (value.element.id in err_map) ) {
        var _popover = element.popover({
          trigger: "manual",
                 placement: "top",
                 content: value.message,
                 template: "<div class=\"popover\"><div class=\"arrow\"></div><div class=\"popover-inner\"><div class=\"popover-content\"><p></p></div></div></div>"
        });
        _popover.data("popover").options.content = value.message;
          err_map[value.element.id] = _popover;
        return err_map[value.element.id].popover("show");
      }
    });
  }
});

ขอบคุณคนอื่น ๆ ทุกคนที่โพสต์แนวคิดเกี่ยวกับเรื่องนี้



0

หากใช้โค้ด Kenny Meyer ด้านบนสำหรับป๊อปอัปโปรดระวังว่ากฎที่ตรวจสอบเนื้อหาของฟิลด์ แต่ไม่จำเป็นเช่น URL ที่ถูกต้องจะทำให้ป๊อปอัปไม่หายไปเมื่อล้างฟิลด์ ดูวิธีแก้ปัญหาด้านล่างบนคีย์อัพ ถ้าใครมีวิธีแก้ไขที่ดีกว่านี้ช่วยโพสต์

onkeyup: function(element, event) {
            if($(element).valid())  {
                return $(element).popover("hide");
            }
        }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.