Angularjs dynamic ng-pattern การตรวจสอบ


84

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

ปัญหาคือฉันยังมี regex สำหรับการตรวจสอบความถูกต้องที่ระบุไว้ในอินพุตด้วยเช่นกันโดยใช้คำสั่งเชิงมุมรูปแบบ ng ปัญหาที่ฉันพบคือหากผู้ใช้กรอกหมายเลขโทรศัพท์ที่ไม่ถูกต้องให้ทำเครื่องหมายที่ช่องเพื่อปิดการใช้งานข้อมูลนั้น (และไม่จำเป็นต้องตรวจสอบความถูกต้องเพิ่มเติม) แบบฟอร์มจะไม่อนุญาตให้ส่งเนื่องจากไม่ถูกต้องตามรูปแบบ ng

ฉันพยายามแก้ไขปัญหานี้โดยเพิ่มฟังก์ชัน ng-change เพื่อตั้งค่ารูปแบบการป้อนข้อมูลเป็น null อย่างไรก็ตามรูปแบบ ng จึงยังคงตั้งค่าฟิลด์ไม่ถูกต้องในชุดเริ่มต้นของช่องทำเครื่องหมายเป็นเท็จ อย่างไรก็ตามหากฉันยกเลิกการเลือกช่องตั้งค่าทุกอย่างกลับไปที่การโหลดแบบฟอร์มเริ่มต้นจากนั้นทำเครื่องหมายที่ช่องอีกครั้งแบบฟอร์มนั้นถูกต้องและสามารถส่งได้ ฉันไม่แน่ใจว่าฉันขาดอะไรไป นี่คือรหัส ng-change ที่ฉันมีจนถึงตอนนี้:

    var phoneNumberRegex = /^\(?(\d{3})\)?[ .-]?(\d{3})[ .-]?(\d{4})$/;
    $scope.phoneNumberPattern = phoneNumberRegex;
    $scope.removeValidation = function() {
        if ($scope.cell._newUser === false) {
            $scope.request._number = '';
            $scope.phoneNumberPattern = /[0-9a-zA-Z]?/;
        } else {
            $scope.phoneNumberPattern = phoneNumberRegex;
        }
    };

คำตอบ:


175

นี่เป็นปัญหาที่น่าสนใจการตรวจสอบเชิงมุมที่ซับซ้อน ซอต่อไปนี้ใช้สิ่งที่คุณต้องการ:

http://jsfiddle.net/2G8gA/1/

รายละเอียด

ฉันสร้างคำสั่งใหม่rpatternที่เป็นส่วนผสมของเชิงมุมของng-requiredและโค้ดจากng-pattern input[type=text]สิ่งที่ไม่สามารถดูrequiredแอตทริบิวต์ของสนามและใช้เวลาที่เข้าบัญชีเมื่อตรวจสอบกับ regexp valid-patternเช่นถ้าไม่จำเป็นต้องใช้เครื่องหมายฟิลด์เป็น

หมายเหตุ

  • โค้ดส่วนใหญ่มาจาก Angular ซึ่งปรับให้เหมาะกับความต้องการนี้
  • เมื่อเลือกช่องทำเครื่องหมายจำเป็นต้องกรอกฟิลด์
  • ฟิลด์จะไม่ถูกซ่อนเมื่อช่องทำเครื่องหมายที่ต้องการเป็นเท็จ
  • นิพจน์ทั่วไปถูกทำให้ง่ายขึ้นสำหรับการสาธิต (ถูกต้องคือ 3 หลัก)

สกปรก ( แต่เล็กกว่า) วิธีการแก้ปัญหาหากคุณไม่ต้องการให้สั่งใหม่จะเป็นสิ่งที่ชอบ

$scope.phoneNumberPattern = (function() {
    var regexp = /^\(?(\d{3})\)?[ .-]?(\d{3})[ .-]?(\d{4})$/;
    return {
        test: function(value) {
            if( $scope.requireTel === false ) {
                return true;
            }
            return regexp.test(value);
        }
    };
})();

และใน HTML ไม่จำเป็นต้องมีการเปลี่ยนแปลง:

<input type="text" ng-model="..." ng-required="requireTel"
    ng-pattern="phoneNumberPattern" />

นี้ที่จริงเทคนิคเชิงมุมเข้าโทรของเรา test()วิธีการแทนการRegExp.test()ที่จะใช้เวลาrequiredเข้าบัญชี


2
ฉันสนใจมากที่จะรู้ว่าวงเล็บกลมรอบ ๆ และหลังฟังก์ชันทำอะไร มันใช้ไม่ได้ถ้าไม่มีพวกเขา
NeedHack

5
พวกเขาเรียกใช้ฟังก์ชันโดยตรงโดยวางค่าตอบแทนให้กับตัวแปรอย่างมีประสิทธิภาพ มันเป็นเรื่องธรรมดามากใน Javascript เพื่อที่จะไม่ก่อให้เกิดมลพิษขอบเขตด้านนอกโดยมีรายละเอียดการดำเนินงานขององค์ประกอบที่เฉพาะเจาะจงให้ดูเช่นในรูปแบบโมดูล
Nikos Paraskevopoulos

6
วิธีแก้ปัญหาที่สกปรกในการเล่นเคล็ดลับบน AngularJS โดยใช้ "Ducktyping" ของ JS เป็นรหัสที่ยอดเยี่ยมที่สุดที่ฉันเห็นในวันนี้ วิธีแก้ที่ฉลาดจริงๆ!
Florian Loch

ขอบคุณสำหรับรหัสที่ยอดเยี่ยม แต่ก็ยังไม่ชัดเจนนัก 1) อ้างอิงจากdocs.angularjs.org/api/ng/directive/input "ถ้านิพจน์ได้รับการประเมินเป็นอ็อบเจ็กต์ RegExp ระบบจะใช้สิ่งนี้โดยตรงหากนิพจน์ประเมิน เป็นสตริงจากนั้นจะถูกแปลงเป็น RegExp "แต่ฉันคิดว่า phoneNumberPattern เป็นวัตถุเมื่อส่งคืน? นี่ควรจะเป็น Regxp Obj หรือไม่? 2) และในฟังก์ชัน (ค่า) {} เก็บในการทดสอบพารามิเตอร์ "value" มาจากไหน? ขอบคุณสำหรับการตอบกลับ!
user2499325

1
1) ประโยค "ถ้านิพจน์ประเมินเป็น RegExp" ถูกนำไปใช้โดย Angular โดยตรวจสอบว่าสิ่งที่ได้รับมีtestวิธีการหรือไม่ นั่นคือเหตุผลที่เราให้มันเป็นวัตถุด้วยประเพณีของเราเองtest()โดยเลียนแบบ JS ดั้งเดิมเป็นRegExpหลัก 2) valueแน่นอนว่าผ่าน Angular เมื่อดำเนินการตรวจสอบความถูกต้องจริง
Nikos Paraskevopoulos

25

ไม่เอาอะไรไปจากคำตอบที่ยอดเยี่ยมของ Nikos บางทีคุณอาจทำได้ง่ายกว่านี้:

<form name="telForm">
  <input name="cb" type='checkbox' data-ng-modal='requireTel'>
  <input name="tel" type="text" ng-model="..." ng-if='requireTel' ng-pattern="phoneNumberPattern" required/>
  <button type="submit" ng-disabled="telForm.$invalid || telForm.$pristine">Submit</button>
</form>

ให้ความสนใจกับอินพุตที่สอง: เราสามารถใช้ng-ifเพื่อควบคุมการแสดงผลและการตรวจสอบความถูกต้องในแบบฟอร์ม หากrequireTelไม่ได้ตั้งค่าตัวแปรอินพุตที่สองจะไม่เพียงถูกซ่อนไว้ แต่จะไม่แสดงผลเลยดังนั้นแบบฟอร์มจะผ่านการตรวจสอบความถูกต้องและปุ่มจะเปิดใช้งานและคุณจะได้รับสิ่งที่คุณต้องการ


1
กลับหัวก็ง่าย ข้อเสียอินพุตใด ๆ ที่ถูกลบออกเมื่อนิพจน์ ng-if เป็นเท็จจะมีข้อความใด ๆ ในนั้นถูกลบออกหาก ng-if ถูกประเมินเป็นจริงในภายหลัง ยังคง +1 เพื่อความเรียบง่าย
Brad

ฉันอยากจะเพิ่มถ้าคุณไปเส้นทางนี้ตรวจสอบให้แน่ใจว่าคุณเข้าใจว่าทุกอย่างภายใน ng-if (ถ้าคุณใส่ไว้ใน div เป็นต้น) จะมีขอบเขตของมันเอง
Brad

5

รูปแบบที่ใช้:

 ng-pattern="/^\d{0,9}(\.\d{1,9})?$/"

ไฟล์อ้างอิงที่ใช้:

 '<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.js"></script>'

ตัวอย่างสำหรับการป้อนข้อมูล:

 <input type="number" require ng-pattern="/^\d{0,9}(\.\d{1,9})?$/"><input type="submit">


2

ฉันเพิ่งเจอเรื่องนี้เมื่อวันก่อน

สิ่งที่ฉันทำซึ่งดูเหมือนง่ายกว่าข้างต้นคือการตั้งค่ารูปแบบบนตัวแปรในขอบเขตและอ้างถึงในรูปแบบ ng ในมุมมอง

เมื่อ "ไม่ได้ทำเครื่องหมายในช่องทำเครื่องหมาย" ฉันเพียงแค่ตั้งค่า regex เป็น /.*/ ในการเรียกกลับ onChanged (หากจะไม่เลือก) ng-pattern หยิบที่เปลี่ยนไปแล้วพูดว่า "ตกลงค่าของคุณสบายดี" ตอนนี้แบบฟอร์มถูกต้อง ฉันจะลบข้อมูลที่ไม่ดีออกจากสนามเพื่อที่คุณจะได้ไม่มีโทรศัพท์ที่ไม่ดี # นั่งอยู่ที่นั่น

ฉันมีปัญหาเพิ่มเติมเกี่ยวกับ ng-required และทำสิ่งเดียวกัน ทำงานอย่างมีเสน่ห์


0

ตั้งค่าคีย์ข้อผิดพลาดการตรวจสอบความถูกต้องของรูปแบบหาก ngModel $ viewValue ไม่ตรงกับ RegExp ที่พบโดยการประเมินนิพจน์เชิงมุมที่กำหนดในค่าแอ็ตทริบิวต์ หากนิพจน์ประเมินเป็นอ็อบเจ็กต์ RegExp ค่านี้จะถูกใช้โดยตรง หากนิพจน์ได้รับการประเมินเป็นสตริงนิพจน์จะถูกแปลงเป็น RegExp หลังจากตัดด้วยอักขระ ^ และ $

ดูเหมือนว่าคำตอบที่ได้รับการโหวตมากที่สุดในคำถามนี้ควรได้รับการอัปเดตเพราะเมื่อฉันลองใช้มันไม่ได้ใช้testฟังก์ชันและการตรวจสอบความถูกต้องไม่ทำงาน

ตัวอย่างจากเอกสารเชิงมุมเหมาะสำหรับฉัน:

การแก้ไขตัวตรวจสอบความถูกต้องในตัว

html

<form name="form" class="css-form" novalidate>
  <div>
   Overwritten Email:
   <input type="email" ng-model="myEmail" overwrite-email name="overwrittenEmail" />
   <span ng-show="form.overwrittenEmail.$error.email">This email format is invalid!</span><br>
   Model: {{myEmail}}
  </div>
</form>

js

var app = angular.module('form-example-modify-validators', []);

app.directive('overwriteEmail', function() {
    var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@example\.com$/i;

    return {
        require: 'ngModel',
        restrict: '',
        link: function(scope, elm, attrs, ctrl) {
            // only apply the validator if ngModel is present and Angular has added the email validator
            if (ctrl && ctrl.$validators.email) {

                // this will overwrite the default Angular email validator
                ctrl.$validators.email = function(modelValue) {
                    return ctrl.$isEmpty(modelValue) || EMAIL_REGEXP.test(modelValue);
                };
             }
         }
     };
 });

Plunker


-1

คุณสามารถใช้ไซต์https://regex101.com/เพื่อสร้างรูปแบบเฉพาะของคุณเองสำหรับบางประเทศ:

ตัวอย่างเช่นโปแลนด์:

-pattern = xxxxxxxxx OR xxx-xxx-xxx OR xxx xxx xxx 
-regexp ="^\d{9}|^\d{3}-\d{3}-\d{3}|^\d{3}\s\d{3}\s\d{3}"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.