Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 11 of 11
  1. #1
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,762
    Thanks
    55
    Thanked 517 Times in 514 Posts

    return false from nested $.each loop

    hello,

    I am trying to write an easily-customisable greasemonkey script that validates phone numbers. There can be any number of numbers for checking and any number of accepted formats (and I want it to be easy for non-coders to add formats). So I figured put the regexes in an object and loop through the input values, testing each regex against them.

    The rules are:
    if there is nothing in any of the inputs, no alert
    if the number matches any of the formats, no alert

    The script is working fine as is, but I don't know much about jQuery and I'm not sure if this is the correct/best way to break out of the loop (if valid) and alert that the number doesn't meet any of the criteria (if not).

    Don't worry about the crappy poiphone string thing - I'm using that for something else, but it came in handy here as well.

    Any suggestions welcomed. Like I say, it's greasemonkey so I can't do anything about class names and it has to work with jQuery 1.6.2

    Code:
    <head>
    <script src="http://code.jquery.com/jquery-1.6.2.js"></script>	
    </head>
    <body>
    <input class="number" value="5738-6969"/>
    <input class="number" value="23-5738-6969"/>
    <input class="number" value="538-6969"/>
    <input class="number" value="2-5738-6969"/>
    <input type="button" id="vali" value="validate"/>
    <script type="text/javascript">
    $(document).ready(function () {
    
    $("#vali").click(function(){
        var poiphone = "";
        var telformats = {
            ph1: (/^(\d{4})-(\d{4})$/), //checks for format of phone number XXXX-XXXX
            ph2: (/^(\d{2})-(\d{4})-(\d{4})$/) //checks for format of phone number XX-XXXX-XXXX
        };
        $.each($(".number"), function () {
            var tel = $(this).val();
            if (tel != "") {
    		poiphone += tel;
                var isValid = false;
                $.each(telformats, function () {
                    if (this.test(tel)) {
                        isValid = true;
                        return;
                    }
                });
                if (!isValid) {
                    alert("Telephone " + tel + " is not a valid format")
                }
            }
        });
    
    });
    });
    </script>
    </body>
    Last edited by xelawho; 01-05-2013 at 08:59 PM. Reason: added button for easier testing

  • #2
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    Yes, return is used to break out of .each, and yours is the approach I would take. Although, you could consider storing the regex in an array and use array methods. Not sure which one; every()? some() looks good .

    If you were to use a simple for loop to check the $('.number') elements then you would have the option to stop as soon as there is a non-match. I mean, to stop in a more orderly fashion (each is intended to examine each/every item).
    Last edited by AndrewGSW; 01-05-2013 at 10:29 PM.
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • Users who have thanked AndrewGSW for this post:

    xelawho (01-05-2013)

  • #3
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,762
    Thanks
    55
    Thanked 517 Times in 514 Posts
    Interesting. I hadn't seen some() or every() before. That's the nice thing about writing for greasemonkey - no need for IE workarounds

    I'll look into them. Thanks

  • #4
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    Quote Originally Posted by xelawho View Post
    Interesting. I hadn't seen some() or every() before. That's the nice thing about writing for greasemonkey - no need for IE workarounds

    I'll look into them. Thanks
    Some of these methods are quite new and you should include prototypes for them to allow for older browsers. For example,

    Code:
    if (!Array.prototype.some)
    {
      Array.prototype.some = function(fun /*, thisp */)
      {
        "use strict";
     
        if (this == null)
          throw new TypeError();
     
        var t = Object(this);
        var len = t.length >>> 0;
        if (typeof fun != "function")
          throw new TypeError();
     
        var thisp = arguments[1];
        for (var i = 0; i < len; i++)
        {
          if (i in t && fun.call(thisp, t[i], i, t))
            return true;
        }
     
        return false;
      };
    }
    You can copy these from Mozilla and put them at the head of your script. Copy them verbatim - don't change them in any way
    Last edited by AndrewGSW; 01-05-2013 at 11:19 PM.
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • #5
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    Last point: If you are using jQuery already then you might consider filter() to return those elements matching a regular expression:

    Code:
    $("input:text")
        .filter(function() {
            return this.value.match(/[^\d]/);
        })
        .addClass("inputError")
    ;
    There is also a validation plug-in. But there is no reason you can't just use plain JS-regex.
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • #6
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,762
    Thanks
    55
    Thanked 517 Times in 514 Posts
    some() did turn out to be promising, but I had a hard time keeping tel in scope. I ended up doing this (which works), but I wonder if there is a better way...

    Code:
    <!HTML>
    <html>
    <head>
    <script src="http://code.jquery.com/jquery-1.6.2.js"></script>	
    </head>
    <body>
    <input class="number" value="5738-6969"/>
    <input class="number" value="23-5738-6969"/>
    <input class="number" value="538-6969"/>
    <input class="number" value="2-5738-6969"/>
    <input type="button" id="vali" value="validate"/>
    <script type="text/javascript">
    $(document).ready(function () {
        var tel;
    
        function correctFormat(reg) {
            return reg.test(tel)
        }
        $("#vali").click(function () {
            var poiphone = "";
            var telformats = [
            (/^(\d{4})-(\d{4})$/), //checks for format of phone number XXXX-XXXX
            (/^(\d{2})-(\d{4})-(\d{4})$/) //checks for format of phone number XX-XXXX-XXXX
            ]
            $.each($(".number"), function () {
                tel = $(this).val();
                if (tel != "") {
                    poiphone += tel;
                    var isValid = false;
                    isValid = telformats.some(correctFormat)
                    if (!isValid) {
                     alert("Telephone " + tel + " is not a valid format")
                    }
                }
            });
        });
    });
    </script>
    </body>
    </html>

  • #7
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    You seem to have a problem with DOCTYPEs

    <!HTML>

    <!DOCTYPE html>

    as I recall from previously
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • #8
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,762
    Thanks
    55
    Thanked 517 Times in 514 Posts
    Quote Originally Posted by AndrewGSW View Post
    as I recall from previously
    no, as I recall your only previous lecture was on code indentation

    no ideas on keeping tel in scope, then?

  • #9
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    no ideas on keeping tel in scope, then?
    Probably.. but it's late. Tomorrow.
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • #10
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    Sorry, I got carried away

    Code:
    var regexes = [ /^(\d{4})-(\d{4})$/, /^(\d{2})-(\d{4})-(\d{4})$/ ];
    // the user can push() new regex into this array.
    
    function testPhones(elems) {
        // Returns an array, possibly of just one element.
        // The array will have the same size as elems.length and will contain:
        // -1 if that element fails all tests, -2 if there is nothing to test,
        // or the index (0, 1, 2, etc.) of the regex that it met.
        
        var phoneResults = [], regLen = regexes.length, elLen = elems.length;
        phoneResults.passed = true;
        for (var i = 0; i < elLen; i++) {
            phoneResults[i] = -1;
            for (var j = 0; j < regLen; j++) {
                var theVal = elems.eq(i).val() || elems.eq(i).text();
                if (!theVal) {      // no phone number/blank
                    phoneResults[i] = -2;
                    phoneResults.passed = false;    // at least one blank
                    break;
                } else if ( regexes[j].test(theVal) === true ) {
                    phoneResults[i] = j;
                    break;
                }
            }
            if (phoneResults[i] == -1) {
                phoneResults.passed = false;    // at least one fail
            }
        }
        return phoneResults;
    }
    
    var testThese = testPhones($('.number'));
    if (testThese.passed) {
        alert('They all passed!');
    }
    var lElems = $('.number').length;
    
    for (var i=0; i < lElems; i++) {
        if (testThese[i] >= 0) {
            alert('Element ' + i + ' passed regex: ' + regexes[testThese[i]]);
        } else if (testThese[i] == -1) {
            alert('Element ' + i + ' failed all tests.');
            // display an error message next to the input?
        } else { // -2
            alert('Element ' + i + ':nothing to test!');
        }
    }
    but I haven't tested yet. Please feel free to ignore any of this - I won't be upset.

    Andy.
    Last edited by AndrewGSW; 01-06-2013 at 11:50 PM. Reason: Changed failed to passed
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • Users who have thanked AndrewGSW for this post:

    xelawho (01-07-2013)

  • #11
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,762
    Thanks
    55
    Thanked 517 Times in 514 Posts
    Quote Originally Posted by AndrewGSW View Post
    Sorry, I got carried away
    I think you did. I appreciate the effort, but I may err on the side of simplicity on this one.

    cheers


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •