OneSpan Sign How To: Creating Field Validators

Haris Haidary, April 6, 2016
Thumbnail

When creating a form, you may require your user to fill-in mandatory fields and you may also want to ensure that valid entries are entered by your user. For example, as a life insurance broker, you possibly will want to contact your client in case of any changes in policies. For this, you will need your client to enter a valid phone number when filling out your form. By validating form data while the user is filling it out, the user can know immediately if they've made any mistakes or if they’ve left a required field empty. This saves you the time of having to deal with improper or empty form input. With OneSpan Sign, you can achieve this by creating field validators. A field validator enables you to require and restrict the range of acceptable values for an unbounded field. Additionally, each field may only have one validator. In this blog, I will show you how to create field validators with the OneSpan Sign Java SDK, .NET SDK, and REST API.

The Code

With our objective set, you can go ahead and skip to the section which applies to your method. I will cover the exact same content in each segment. Full example code for this blog can be found in the Developer Community Code Share (Java, .NET, REST). Java SDK First, I’ll start with the Java SDK. The sample code below shows you how to add field validation to a field that is bound to a signature. If you need a comparison to the basic signature object creation or if this is your first time creating a package with the Java SDK, see this blog.

.withSignature(SignatureBuilder.captureFor("[email protected]")
			.withName("client_signature")
			.withPositionExtracted()
			.withField(FieldBuilder.signatureDate()
				.withName("client_date")
				.withPositionExtracted())
			.withField(FieldBuilder.textField()
				.withName("first_name")
				.withPositionExtracted()
				.withValidation(FieldValidatorBuilder.alphabetic().required().withErrorMessage("Please enter a valid first name.")))
			.withField(FieldBuilder.textField()
				.withName("last_name")
				.withPositionExtracted()
				.withValidation(FieldValidatorBuilder.alphabetic().required().withErrorMessage("Please enter a valid last name.")))
			.withField(FieldBuilder.textField()
				.withName("address")
				.withPositionExtracted()
				.withValidation(FieldValidatorBuilder.basic().required().withErrorMessage("Please enter a valid address.")))
			.withField(FieldBuilder.textField()
				.withName("city")
				.withPositionExtracted()
				.withValidation(FieldValidatorBuilder.alphabetic().required().withErrorMessage("Please enter a valid city.")))
			.withField(FieldBuilder.textField()
				.withName("state")
				.withPositionExtracted()
				.withValidation(FieldValidatorBuilder.alphabetic().required().maxLength(2).minLength(2).withErrorMessage("Please enter a valid state.")))
			.withField(FieldBuilder.textField()
				.withName("zip")
				.withPositionExtracted()
				.withValidation(FieldValidatorBuilder.numeric().required().maxLength(5).minLength(5).withErrorMessage("Please enter a valid zip.")))
			.withField(FieldBuilder.textField()
				.withName("country")
				.withPositionExtracted()
				.withValidation(FieldValidatorBuilder.alphabetic().required().withErrorMessage("Please enter a valid country.")))
			.withField(FieldBuilder.textField()
				.withName("phone_number")
				.withPositionExtracted()
				.withValidation(FieldValidatorBuilder.regex("^[2-9]\\d{2}-\\d{3}-\\d{4}$").required().withErrorMessage("Please enter a valid phone number (XXX-XXX-XXXX)")))
			.withField(FieldBuilder.textField()
				.withName("email")
				.withPositionExtracted()
				.withValidation(FieldValidatorBuilder.email().required().withErrorMessage("Please enter a valid email.")))
			.withField(FieldBuilder.textField()
				.withName("company")
				.withPositionExtracted()
				.withValidation(FieldValidatorBuilder.alphabetic().required().withErrorMessage("Please enter a valid company.")))
			.withField(FieldBuilder.textField()
				.withName("policy_number")
				.withPositionExtracted()
				.withValidation(FieldValidatorBuilder.numeric().required().withErrorMessage("Please enter a valid policy number."))))

In this example, I chose to extract the form fields from my PDF. To extract each form field in your PDF, you will need to pass the exact name of your PDF form field to the withName() method and use the withPositionExtracted() method to ensure that the exact position and size are retained in OneSpan Sign. Note that currently using position extraction in OneSpan Sign can only be done when uploading your document and only through the API/SDKs. To create a field validator, you will need to pass a field validator type to the FieldValidatorBuilder. You can either use the pre-defined validators that come with the API/SDKs or you can create your own customized validator using regular expression. You can find a complete list of field validator types here. The required() method makes a field mandatory and the withErrorMessage() method customizes the error message that will appear if your user enters invalid format data or if the required field is left empty. You can also restrict the length of an input using the maxLength() and minLength() methods. [promotion id="15582"] .NET SDK Next, I’ll go over the .NET SDK. The sample code below shows you how to edit the signature block for creating field validators. If you need a comparison to the basic document object creation or if this is your first time creating a package with the .NET SDK, see this blog.

.WithSignature(SignatureBuilder.CaptureFor("[email protected]")
		.WithName("client_signature")
		.WithPositionExtracted()
		.WithField(FieldBuilder.SignatureDate()
			.WithName("client_date")
			.WithPositionExtracted())
		.WithField(FieldBuilder.TextField()
			.WithName("first_name")
			.WithPositionExtracted()
			.WithValidation(FieldValidatorBuilder.Alphabetic().Required().WithErrorMessage("Please enter a valid first name.")))
		.WithField(FieldBuilder.TextField()
			.WithName("last_name")
			.WithPositionExtracted()
			.WithValidation(FieldValidatorBuilder.Alphabetic().Required().WithErrorMessage("Please enter a valid last name.")))
		.WithField(FieldBuilder.TextField()
			.WithName("address")
			.WithPositionExtracted()
			.WithValidation(FieldValidatorBuilder.Basic().Required().WithErrorMessage("Please enter a valid address.")))
		.WithField(FieldBuilder.TextField()
			.WithName("city")
			.WithPositionExtracted()
			.WithValidation(FieldValidatorBuilder.Alphabetic().Required().WithErrorMessage("Please enter a valid city.")))
		.WithField(FieldBuilder.TextField()
			.WithName("state")
			.WithPositionExtracted()
			.WithValidation(FieldValidatorBuilder.Alphabetic().Required().MaxLength(2).MinLength(2).WithErrorMessage("Please enter a valid state.")))
		.WithField(FieldBuilder.TextField()
			.WithName("zip")
			.WithPositionExtracted()
			.WithValidation(FieldValidatorBuilder.Numeric().Required().MaxLength(5).MinLength(5).WithErrorMessage("Please enter a valid zip.")))
		.WithField(FieldBuilder.TextField()
			.WithName("country")
			.WithPositionExtracted()
			.WithValidation(FieldValidatorBuilder.Alphabetic().Required().WithErrorMessage("Please enter a valid country.")))
		.WithField(FieldBuilder.TextField()
			.WithName("phone_number")
			.WithPositionExtracted()
			.WithValidation(FieldValidatorBuilder.Regex("^[2-9]\\d{2}-\\d{3}-\\d{4}$").Required().WithErrorMessage("Please enter a valid phone number (XXX-XXX-XXXX)")))
		.WithField(FieldBuilder.TextField()
			.WithName("email")
			.WithPositionExtracted()
			.WithValidation(FieldValidatorBuilder.Email().Required().WithErrorMessage("Please enter a valid email.")))
		.WithField(FieldBuilder.TextField()
			.WithName("company")
			.WithPositionExtracted()
			.WithValidation(FieldValidatorBuilder.Alphabetic().Required().WithErrorMessage("Please enter a valid company.")))
		.WithField(FieldBuilder.TextField()
			.WithName("policy_number")
			.WithPositionExtracted()
			.WithValidation(FieldValidatorBuilder.Numeric().Required().WithErrorMessage("Please enter a valid policy number."))))

In my example, I chose to extract the form fields from my PDF. To extract each form field in your PDF, you will need to pass the exact name of your PDF form field to the withName() method and use the withPositionExtracted() method to ensure that the exact position and size are retained in OneSpan Sign. Note that currently using position extraction in OneSpan Sign can only be done when uploading your document and only through the API/SDKs. To create a field validator, you will need to pass a field validator type to the FieldValidatorBuilder. You can either use the pre-defined validators that come with the API/SDKs or you can create your own customized validator using regular expression. You can find a complete list of field validator types here. The required() method makes a field mandatory and the withErrorMessage() method customizes the error message that will appear if your user enters invalid format data or if the required field is left empty. You can also restrict the length of an input using the maxLength() and minLength() methods. REST API Finally, I will cover the REST API. I included the JSON that will create a document package with field validators for convenience. If you need a comparison to the basic document object creation or if this is your first time creating a package with the REST API, see this blog. [code language="javascript"]{ "autocomplete": true, "documents": [ { "approvals": [ { "role": "manager", "fields": [ { "subtype": "LABEL", "binding": "{approval.signed}", "extract": true, "type": "INPUT", "name": "manager_date" }, { "subtype": "CAPTURE", "extract": true, "type": "SIGNATURE", "name": "manager_signature" } ], "name": "" }, { "role": "client", "fields": [ { "subtype": "LABEL", "binding": "{approval.signed}", "extract": true, "type": "INPUT", "name": "client_date" }, { "validation": { "required": true, "errorMessage": "Please enter a valid first name.", "pattern": "^[\\sa-zA-Z]+$" }, "subtype": "TEXTFIELD", "extract": true, "type": "INPUT", "name": "first_name" }, { "validation": { "required": true, "errorMessage": "Please enter a valid last name.", "pattern": "^[\\sa-zA-Z]+$" }, "subtype": "TEXTFIELD", "extract": true, "type": "INPUT", "name": "last_name" }, { "validation": { "required": true, "errorMessage": "Please enter a valid address.", "pattern": "" }, "subtype": "TEXTFIELD", "extract": true, "type": "INPUT", "name": "address" }, { "validation": { "required": true, "errorMessage": "Please enter a valid city.", "pattern": "^[\\sa-zA-Z]+$" }, "subtype": "TEXTFIELD", "extract": true, "type": "INPUT", "name": "city" }, { "validation": { "maxLength": 2, "required": true, "minLength": 2, "errorMessage": "Please enter a valid state.", "pattern": "^[\\sa-zA-Z]+$" }, "subtype": "TEXTFIELD", "extract": true, "type": "INPUT", "name": "state" }, { "validation": { "maxLength": 5, "required": true, "minLength": 5, "errorMessage": "Please enter a valid zip.", "pattern": "^[-+]?[0-9]*\\.?[0-9]*$" }, "subtype": "TEXTFIELD", "extract": true, "type": "INPUT", "name": "zip" }, { "validation": { "required": true, "errorMessage": "Please enter a valid country.", "pattern": "^[\\sa-zA-Z]+$" }, "subtype": "TEXTFIELD", "extract": true, "type": "INPUT", "name": "country" }, { "validation": { "required": true, "errorMessage": "Please enter a valid phone number (XXX-XXX-XXXX)", "pattern": "^[2-9]\\d{2}-\\d{3}-\\d{4}$" }, "subtype": "TEXTFIELD", "extract": true, "type": "INPUT", "name": "phone_number" }, { "validation": { "required": true, "errorMessage": "Please enter a valid email.", "pattern": "^([a-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$" }, "subtype": "TEXTFIELD", "extract": true, "type": "INPUT", "name": "email" }, { "validation": { "required": true, "errorMessage": "Please enter a valid company.", "pattern": "^[\\sa-zA-Z]+$" }, "subtype": "TEXTFIELD", "extract": true, "type": "INPUT", "name": "company" }, { "validation": { "required": true, "errorMessage": "Please enter a valid policy number.", "pattern": "^[-+]?[0-9]*\\.?[0-9]*$" }, "subtype": "TEXTFIELD", "extract": true, "type": "INPUT", "name": "policy_number" }, { "subtype": "CAPTURE", "extract": true, "type": "SIGNATURE", "name": "client_signature" } ], "name": "" } ], "extract": true, "name": "Contract" } ], "status": "SENT", "type": "PACKAGE", "roles": [ { "id": "client", "index": 0, "type": "SIGNER", "signers": [ { "lastName": "Smith", "email": "[email protected]", "firstName": "John", "id": "client" } ], "name": "client" }, { "id": "manager", "index": 1, "type": "SENDER", "signers": [ { "lastName": "Haidary", "email": "[email protected] ", "firstName": "Haris", "id": "manager" } ], "name": "manager" } ], "name": "Sample Contract" } In my example, I chose to extract the form fields from my PDF. To extract each form field in your PDF, you will need to pass the exact name of your PDF form field to the "name" object and set "extract" to true to ensure that the exact position and size are retained in OneSpan Sign. Note that currently using position extraction in OneSpan Sign can only be done when uploading your document and only through the API/SDKs. To create a field validator, you will need to create a "validation" object and pass the regular expression to the "pattern" object. To make a field mandatory, you will need to set "required" object to true. The "errorMessage" object is the error message that will appear if your user enters invalid data or if the required field is left empty. You can also restrict the length of an input by creating "maxLength" and "minLength" objects.

Running Your Code

The PDF I used to run the examples is included in the Code Share Links above. You can now go ahead and run your code. Once you’ve send your document package for signing, this is what your signer will see:
Sample contract with fields

As you can see, the required fields are highlighted for the user to fill out. The "Signing Date" field will be filled in automatically by OneSpan Sign when the signing is complete. If you have questions regarding this blog or anything else concerning integrating OneSpan Sign into your application, visit the developer community forums: https://developer.onespan.com. That's it from me. Thank you for reading! If you found this post helpful, please share it on Facebook, Twitter, or LinkedIn.

Haris Haidary Junior Technical Evangelist LinkedIn | Twitter