简体   繁体   中英

Combine two javascript functions?

How can I combine these two functions so that they both work? Right now, I can only get one to validate and not the other.

SAMPLE OF THE JAVASCRIPT:

function validateForm() {

var x=document.forms["giftCert"]["gift_name"].value;

if (x==null || x=="") {

errMsg = "The recpient's name is required.";              
    $("div#emptyName").show();
    $("div#emptyName").html(errMsg);

return false;
  }
}

function validateForm() {

var x=document.forms["giftCert"]["gift_email"].value;

if (x==null || x=="") {

errMsg2 = "The recpient's email address is required.";              
    $("div#emptyEmail").show();
    $("div#emptyEmail").html(errMsg2);

return false;
  }
}

SHORT VERSION OF THE FORM HTML:

<form action="http://ww6.aitsafe.com/cf/voucher.cfm" method="post" name="giftCert" onsubmit="return validateForm()"  />
    *Name:<input type="text" name="gift_name">
    <div id="emptyName" class="error"></div>

    *Email: <input type="text" name="gift_email">
    <div id="emptyEmail" class="error"></div>

    <input class="button" type="submit" value="Add to Cart" />

</form>

You can put the code in the same function.

function validateForm() {
    return ["Name", "Email"].every(function(type) {
        var lower_type = type.toLowerCase(),
            x=document.forms["giftCert"]["gift_" + lower_type].value;

        if (x==null || x=="")
            $("div#empty" + type).show().html("The recpient's " + lower_type + " is required.");
        else
            return true;
    });
}

Since much of the code is nearly identical, you can put the "Name" and "Email" values in an Array, and loop the Array, invoking the identical code, dropping in the appropriate value where needed.

This uses the Array.prototype.every to indicate if each value in the Array passed validation.

If either item fails validation, it returns undefined , the loop halts and validateForm returns false .

Every item that passes validation returns true . If all items pass validation, .every will return true , and the form proceeds.


If you want to make sure all the validations run, you can use .filter() , and return true on a failure, so that it will add an item to the resulting Array. If there were no failures, the Array will be empty.

Then test the .length of the Array, and return a comparison to 0 .

function validateForm() {
    return ["Name", "Email"].filter(function(type) {
        var lower_type = type.toLowerCase(),
            x=document.forms["giftCert"]["gift_" + lower_type].value;

        if (x==null || x=="") {
            $("div#empty" + type).show().html("The recpient's " + lower_type + " is required.");
            return true;
        }
    }).length === 0; // will be true if no validation failures
}

Have it call the second one when done.

Or have a 3rd function that calls both of them and have that in your onsubmit. That function will see the return values of both functions and return true only if both of them return true.

Or just put the code of the second one inside the first, since it's similar anyway. You can get rid of some of duplicate code too.

When you reuse the same function name, each succeeding function declaration will overwrite any preceding entries. It might be easiest to keep your validations in separate functions, so you should name them appropriately and create a driver function to call them all. Example:

function validateForm() {
  return validateName && validateEmail();
}

function validateName() {

  var x=document.forms["giftCert"]["gift_name"].value;

  if (x==null || x=="") {

    errMsg = "The recpient's name is required.";              
    $("div#emptyName").show();
    $("div#emptyName").html(errMsg);

    return false;
  }

  return true;
}

function validateEmail() {

  var x=document.forms["giftCert"]["gift_email"].value;

  if (x==null || x=="") {

    errMsg2 = "The recpient's email address is required.";              
    $("div#emptyEmail").show();
    $("div#emptyEmail").html(errMsg2);

    return false;
  }

  return true;
}

Additionally, you can just combine the two, but this isn't nearly as flexible:

function validateForm() {

  var name =document.forms["giftCert"]["gift_name"].value;

  if (name == null || name == "") {

    errMsg = "The recpient's name is required.";              
    $("div#emptyName").show();
    $("div#emptyName").html(errMsg);

    return false;
  }

  var email = document.forms["giftCert"]["gift_email"].value;

  if (email == null || email == "") {

    errMsg2 = "The recpient's email address is required.";              
    $("div#emptyEmail").show();
    $("div#emptyEmail").html(errMsg2);

    return false;
  }

  return true;
}

The short answer is just do this

function validateForm() {

var x=document.forms["giftCert"]["gift_name"].value;

if (x==null || x=="") {

    errMsg = "The recpient's name is required.";              
    $("div#emptyName").show();
    $("div#emptyName").html(errMsg);

    return false;
}
x=document.forms["giftCert"]["gift_email"].value;

if (x==null || x=="") {

    errMsg2 = "The recpient's email address is required.";              
    $("div#emptyEmail").show();
    $("div#emptyEmail").html(errMsg2);

   return false;
  }
}

The longer answer is your functions have to have unique names. Also, you use jquery in part of your code why not use it to access your forms? Also, it usually considered bad practice to call your functions from the HTML.

One possible solution:

function validateForm() {

    var x=document.forms["giftCert"]["gift_name"].value,
        y = document.forms["giftCert"]["gift_email"].value,
        error = false;

    if ( !x ) {
        errMsg = "The recpient's name is required.";              
        $("div#emptyName").html(errMsg).show();
        error = true;
    }

    if ( !y ) {
        errMsg2 = "The recpient's email address is required.";              
        $("div#emptyEmail").html(errMsg2).show();
        error = true;
    }

    if (error === true) return false;

}​

For anyone wondering how to combine two functions into one, here's a function I created for doing this:

function combineFunctions() {
    var args = Array.prototype.slice.call(arguments, 0);
    return function() {
            for (var i = 0, len = args.length; i < len; i++) {
                if (typeof args[i] === "function") {
                    args[i].apply(this, arguments);
                }
            }
    };
}

Then to combine to functions:

var myFunc = function() { console.log('1'); };
var myOtherFunc = function() { console.log('2'); };

var myCombinedFunc = combineFunctions(myFunc, myOtherFunc);
myCombinedFunc(); // outputs 1, then 2 to the console

Note: This only works for functions with the same arguments -- works great for adding a function to an event handler

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM