[{"data":1,"prerenderedAt":1538},["ShallowReactive",2],{"post:forms-1-validation":3},{"id":4,"title":5,"body":6,"date":1524,"description":12,"draft":1525,"extension":1526,"meta":1527,"navigation":1528,"path":1529,"seo":1530,"stem":1531,"tags":1532,"__hash__":1537},"posts\u002Fposts\u002Fforms-1-validation.md","Form Processing in CFScript Part One: Form Validation",{"type":7,"value":8,"toc":1512},"minimark",[9,13,24,29,89,92,95,108,115,118,462,465,468,475,478,481,484,497,500,505,658,661,664,675,679,686,769,787,794,800,842,845,848,968,974,977,984,991,1105,1112,1198,1205,1491,1496,1499,1505,1508],[10,11,12],"p",{},"This series will teach you how to process form submissions using ColdFusion's CFScript syntax. In Part One I'll show you the basics of validating form submissions on the backend!",[10,14,15,19,20,23],{},[16,17,18],"strong",{},"Note:"," This article (and entire series) assumes you are not using a frontend framework like Vue or ReactJS to generate and validate the form. If you are, great, but ",[16,21,22],{},"do not"," rely on client-side validation as it is too easily bypassed. See section on backend vs. frontend validation.",[25,26,28],"h2",{"id":27},"table-of-contents","Table of Contents",[30,31,32,39,45,51,57,77,83],"ul",{},[33,34,35],"li",{},[36,37,28],"a",{"href":38},"#table-of-contents",[33,40,41],{},[36,42,44],{"href":43},"#intro-to-form-validation","Intro to Form Validation",[33,46,47],{},[36,48,50],{"href":49},"#form-validation-backend-vs-frontend","Form Validation: Backend Vs. Frontend",[33,52,53],{},[36,54,56],{"href":55},"#validating-field-length-required-fields","Validating Field Length (Required Fields)",[33,58,59,63],{},[36,60,62],{"href":61},"#validating-field-type","Validating Field Type",[30,64,65,71],{},[33,66,67],{},[36,68,70],{"href":69},"#static-type-checking","Static Type Checking",[33,72,73],{},[36,74,76],{"href":75},"#iterative-type-checking","Iterative Type Checking",[33,78,79],{},[36,80,82],{"href":81},"#dealing-with-validation-errors","Dealing with Validation Errors",[33,84,85],{},[36,86,88],{"href":87},"#conclusion","Conclusion",[25,90,44],{"id":91},"intro-to-form-validation",[10,93,94],{},"When validating form submissions, there are two main things to keep in mind which should guide your overall validation strategy.",[10,96,97,98,102,103,107],{},"First, the main point of form validation is 1) to helpfully notify the user when they mistype a value, and 2) to prevent backend errors. (e.g. ",[99,100,101],"code",{},"cfmail()"," will throw an error for some badly misformed email addresses). Besides that, validation should be used ",[104,105,106],"em",{},"as sparingly as possible",". This is because it's easy to be too strict and unintentionally exclude users with different zip codes, email addresses and phone numbers than we might expect.",[10,109,110,111,114],{},"Secondly, you can never force a user to input their personal information if they do not wish to! Requiring an ",[99,112,113],{},"address"," field, for example, will generate a significant amount of falsified info, like \"1600 Pennsylvania Ave NW\".",[10,116,117],{},"With that out of the way, let's take a look at a basic HTML form we're going to validate. Nothing fancy here, just a small contact form. Donation forms are much larger and require much stricter validation (and if you are processing payments through your server, I pray for you!)",[119,120,125],"pre",{"className":121,"code":122,"language":123,"meta":124,"style":124},"language-html shiki shiki-themes github-light github-dark","\u003Cform action=\"contact.cfm\">\n    \u003Cdiv class=\"field\">\n        \u003Clabel for=\"name\">Your Name\u003C\u002Flabel>\n        \u003Cinput type=\"text\" name=\"name\" id=\"name\" value=\"\" \u002F>\n    \u003C\u002Fdiv>\n    \u003Cdiv class=\"field\">\n        \u003Clabel for=\"email\">Your Email\u003C\u002Flabel>\n        \u003Cinput type=\"text\" name=\"email\" id=\"email\" value=\"\" \u002F>\n    \u003C\u002Fdiv>\n    \u003Cdiv class=\"field\">\n        \u003Clabel for=\"message\">Message\u003C\u002Flabel>\n        \u003Ctextarea name=\"message\" id=\"message\">\u003C\u002Ftextarea>\n    \u003C\u002Fdiv>\n    \u003Cdiv class=\"submit\">\n        \u003Cinput type=\"submit\" class=\"button button-primary\" value=\"Send\">\n    \u003C\u002Fdiv>\n\u003C\u002Fform>\n","html","",[99,126,127,154,173,197,238,248,263,284,317,326,341,362,389,398,414,443,452],{"__ignoreMap":124},[128,129,132,136,140,144,147,151],"span",{"class":130,"line":131},"line",1,[128,133,135],{"class":134},"sVt8B","\u003C",[128,137,139],{"class":138},"s9eBZ","form",[128,141,143],{"class":142},"sScJk"," action",[128,145,146],{"class":134},"=",[128,148,150],{"class":149},"sZZnC","\"contact.cfm\"",[128,152,153],{"class":134},">\n",[128,155,157,160,163,166,168,171],{"class":130,"line":156},2,[128,158,159],{"class":134},"    \u003C",[128,161,162],{"class":138},"div",[128,164,165],{"class":142}," class",[128,167,146],{"class":134},[128,169,170],{"class":149},"\"field\"",[128,172,153],{"class":134},[128,174,176,179,182,185,187,190,193,195],{"class":130,"line":175},3,[128,177,178],{"class":134},"        \u003C",[128,180,181],{"class":138},"label",[128,183,184],{"class":142}," for",[128,186,146],{"class":134},[128,188,189],{"class":149},"\"name\"",[128,191,192],{"class":134},">Your Name\u003C\u002F",[128,194,181],{"class":138},[128,196,153],{"class":134},[128,198,200,202,205,208,210,213,216,218,220,223,225,227,230,232,235],{"class":130,"line":199},4,[128,201,178],{"class":134},[128,203,204],{"class":138},"input",[128,206,207],{"class":142}," type",[128,209,146],{"class":134},[128,211,212],{"class":149},"\"text\"",[128,214,215],{"class":142}," name",[128,217,146],{"class":134},[128,219,189],{"class":149},[128,221,222],{"class":142}," id",[128,224,146],{"class":134},[128,226,189],{"class":149},[128,228,229],{"class":142}," value",[128,231,146],{"class":134},[128,233,234],{"class":149},"\"\"",[128,236,237],{"class":134}," \u002F>\n",[128,239,241,244,246],{"class":130,"line":240},5,[128,242,243],{"class":134},"    \u003C\u002F",[128,245,162],{"class":138},[128,247,153],{"class":134},[128,249,251,253,255,257,259,261],{"class":130,"line":250},6,[128,252,159],{"class":134},[128,254,162],{"class":138},[128,256,165],{"class":142},[128,258,146],{"class":134},[128,260,170],{"class":149},[128,262,153],{"class":134},[128,264,266,268,270,272,274,277,280,282],{"class":130,"line":265},7,[128,267,178],{"class":134},[128,269,181],{"class":138},[128,271,184],{"class":142},[128,273,146],{"class":134},[128,275,276],{"class":149},"\"email\"",[128,278,279],{"class":134},">Your Email\u003C\u002F",[128,281,181],{"class":138},[128,283,153],{"class":134},[128,285,287,289,291,293,295,297,299,301,303,305,307,309,311,313,315],{"class":130,"line":286},8,[128,288,178],{"class":134},[128,290,204],{"class":138},[128,292,207],{"class":142},[128,294,146],{"class":134},[128,296,212],{"class":149},[128,298,215],{"class":142},[128,300,146],{"class":134},[128,302,276],{"class":149},[128,304,222],{"class":142},[128,306,146],{"class":134},[128,308,276],{"class":149},[128,310,229],{"class":142},[128,312,146],{"class":134},[128,314,234],{"class":149},[128,316,237],{"class":134},[128,318,320,322,324],{"class":130,"line":319},9,[128,321,243],{"class":134},[128,323,162],{"class":138},[128,325,153],{"class":134},[128,327,329,331,333,335,337,339],{"class":130,"line":328},10,[128,330,159],{"class":134},[128,332,162],{"class":138},[128,334,165],{"class":142},[128,336,146],{"class":134},[128,338,170],{"class":149},[128,340,153],{"class":134},[128,342,344,346,348,350,352,355,358,360],{"class":130,"line":343},11,[128,345,178],{"class":134},[128,347,181],{"class":138},[128,349,184],{"class":142},[128,351,146],{"class":134},[128,353,354],{"class":149},"\"message\"",[128,356,357],{"class":134},">Message\u003C\u002F",[128,359,181],{"class":138},[128,361,153],{"class":134},[128,363,365,367,370,372,374,376,378,380,382,385,387],{"class":130,"line":364},12,[128,366,178],{"class":134},[128,368,369],{"class":138},"textarea",[128,371,215],{"class":142},[128,373,146],{"class":134},[128,375,354],{"class":149},[128,377,222],{"class":142},[128,379,146],{"class":134},[128,381,354],{"class":149},[128,383,384],{"class":134},">\u003C\u002F",[128,386,369],{"class":138},[128,388,153],{"class":134},[128,390,392,394,396],{"class":130,"line":391},13,[128,393,243],{"class":134},[128,395,162],{"class":138},[128,397,153],{"class":134},[128,399,401,403,405,407,409,412],{"class":130,"line":400},14,[128,402,159],{"class":134},[128,404,162],{"class":138},[128,406,165],{"class":142},[128,408,146],{"class":134},[128,410,411],{"class":149},"\"submit\"",[128,413,153],{"class":134},[128,415,417,419,421,423,425,427,429,431,434,436,438,441],{"class":130,"line":416},15,[128,418,178],{"class":134},[128,420,204],{"class":138},[128,422,207],{"class":142},[128,424,146],{"class":134},[128,426,411],{"class":149},[128,428,165],{"class":142},[128,430,146],{"class":134},[128,432,433],{"class":149},"\"button button-primary\"",[128,435,229],{"class":142},[128,437,146],{"class":134},[128,439,440],{"class":149},"\"Send\"",[128,442,153],{"class":134},[128,444,446,448,450],{"class":130,"line":445},16,[128,447,243],{"class":134},[128,449,162],{"class":138},[128,451,153],{"class":134},[128,453,455,458,460],{"class":130,"line":454},17,[128,456,457],{"class":134},"\u003C\u002F",[128,459,139],{"class":138},[128,461,153],{"class":134},[10,463,464],{},"Later on, we'll tweak this form to support the particular \"flow\" I prefer for backend validation.",[25,466,50],{"id":467},"form-validation-backend-vs-frontend",[10,469,470,471,474],{},"Form validation at the frontend level is ",[16,472,473],{},"far"," superior than equivalent validation at the backend level. Think of the User Experience - with frontend validation, you can get immediate feedback and avoid sending bad data in the first place. Backend validation is only necessary when the frontend is broken, disabled (Noscript mode) or purposely skirted around via some bot or hacker submitting HTTP requests to your backend.",[10,476,477],{},"For this reason, you could probably dispense with the pleasantries and ignore the need for decent UX when validating via the backend. I say \"probably\" - I still like to provide a nice UX for those legitimate users browsing with javascript disabled.",[25,479,56],{"id":480},"validating-field-length-required-fields",[10,482,483],{},"Validating a form field is not exactly nuclear science. For many fields(not all, but many), it is enough to ensure that the field value is not empty. When validating required fields, I use a variable to store a simple list of field names deemed \"required\", and if any of those fields are indeed empty we halt the processing and display an error to the user.",[10,485,486,488,489,492,493,496],{},[16,487,18],{}," I use member functions throughout this blog post. Member functions can be great as long as they are relatively short and importantly, ",[104,490,491],{},"achieve only a single purpose",". Larger blocks of code, in my opinion, probably belong in a ",[99,494,495],{},"for"," loop - not a member function.",[10,498,499],{},"Here's what I'd use to validate required fields using some clever* member functions.",[10,501,502],{},[104,503,504],{},"*Cleverness is useful but dangerous; please use carefully. (And see note on member functions above.)",[119,506,510],{"className":507,"code":508,"language":509,"meta":124,"style":124},"language-js shiki shiki-themes github-light github-dark","var requiredFields = \"email,phone,message\";\nvar invalidFields = \"\";\nform.fieldnames.each((fieldname) => {\n    if ( requiredFields.find(fieldname) && isEmpty(form[fieldname]) ) {\n        writeOutput('\u003Cp class=\"alert alert-danger\">Please fill out #fieldname#\u003C\u002Fp>');\n        invalidFields.listAppend(fieldname);\n    }\n});\nif ( invalidFields.len() ) {\n    \u002F\u002F halt processing and re-render the form.\n    cfabort();\n}\n","js",[99,511,512,529,543,567,590,604,615,620,625,639,645,653],{"__ignoreMap":124},[128,513,514,518,521,523,526],{"class":130,"line":131},[128,515,517],{"class":516},"szBVR","var",[128,519,520],{"class":134}," requiredFields ",[128,522,146],{"class":516},[128,524,525],{"class":149}," \"email,phone,message\"",[128,527,528],{"class":134},";\n",[128,530,531,533,536,538,541],{"class":130,"line":156},[128,532,517],{"class":516},[128,534,535],{"class":134}," invalidFields ",[128,537,146],{"class":516},[128,539,540],{"class":149}," \"\"",[128,542,528],{"class":134},[128,544,545,548,551,554,558,561,564],{"class":130,"line":175},[128,546,547],{"class":134},"form.fieldnames.",[128,549,550],{"class":142},"each",[128,552,553],{"class":134},"((",[128,555,557],{"class":556},"s4XuR","fieldname",[128,559,560],{"class":134},") ",[128,562,563],{"class":516},"=>",[128,565,566],{"class":134}," {\n",[128,568,569,572,575,578,581,584,587],{"class":130,"line":199},[128,570,571],{"class":516},"    if",[128,573,574],{"class":134}," ( requiredFields.",[128,576,577],{"class":142},"find",[128,579,580],{"class":134},"(fieldname) ",[128,582,583],{"class":516},"&&",[128,585,586],{"class":142}," isEmpty",[128,588,589],{"class":134},"(form[fieldname]) ) {\n",[128,591,592,595,598,601],{"class":130,"line":240},[128,593,594],{"class":142},"        writeOutput",[128,596,597],{"class":134},"(",[128,599,600],{"class":149},"'\u003Cp class=\"alert alert-danger\">Please fill out #fieldname#\u003C\u002Fp>'",[128,602,603],{"class":134},");\n",[128,605,606,609,612],{"class":130,"line":250},[128,607,608],{"class":134},"        invalidFields.",[128,610,611],{"class":142},"listAppend",[128,613,614],{"class":134},"(fieldname);\n",[128,616,617],{"class":130,"line":265},[128,618,619],{"class":134},"    }\n",[128,621,622],{"class":130,"line":286},[128,623,624],{"class":134},"});\n",[128,626,627,630,633,636],{"class":130,"line":319},[128,628,629],{"class":516},"if",[128,631,632],{"class":134}," ( invalidFields.",[128,634,635],{"class":142},"len",[128,637,638],{"class":134},"() ) {\n",[128,640,641],{"class":130,"line":328},[128,642,644],{"class":643},"sJ8bj","    \u002F\u002F halt processing and re-render the form.\n",[128,646,647,650],{"class":130,"line":343},[128,648,649],{"class":142},"    cfabort",[128,651,652],{"class":134},"();\n",[128,654,655],{"class":130,"line":364},[128,656,657],{"class":134},"}\n",[10,659,660],{},"Fairly straightforward CFML here - iterate through all form fields, see if it is required, and if it is not provided spit out an error and halt processing. This is rather simplistic, but perfectly workable - skip down to \"Dealing with Validation Errors\" for an improved way to handle error messages.",[25,662,62],{"id":663},"validating-field-type",[10,665,666,667,670,671,674],{},"Validating the ",[104,668,669],{},"type"," of data is much more difficult than validating the ",[104,672,673],{},"presence"," of data.",[676,677,70],"h3",{"id":678},"static-type-checking",[10,680,681,682,685],{},"The simple way to do this is to use ",[99,683,684],{},"isValid()"," to check email, phone, zip or other standard inputs.",[119,687,689],{"className":507,"code":688,"language":509,"meta":124,"style":124},"if ( !isValid(\"email\", form[\"email\"]) ) {\n    writeOutput('\u003Cp class=\"alert alert-danger\">Please enter a valid email\u003C\u002Fp>');\n}\nif ( !isValid(\"telephone\", form[\"phone\"]) ) {\n    writeOutput('\u003Cp class=\"alert alert-danger\">Please enter a valid phone number\u003C\u002Fp>');\n}\n",[99,690,691,716,728,732,754,765],{"__ignoreMap":124},[128,692,693,695,698,701,704,706,708,711,713],{"class":130,"line":131},[128,694,629],{"class":516},[128,696,697],{"class":134}," ( ",[128,699,700],{"class":516},"!",[128,702,703],{"class":142},"isValid",[128,705,597],{"class":134},[128,707,276],{"class":149},[128,709,710],{"class":134},", form[",[128,712,276],{"class":149},[128,714,715],{"class":134},"]) ) {\n",[128,717,718,721,723,726],{"class":130,"line":156},[128,719,720],{"class":142},"    writeOutput",[128,722,597],{"class":134},[128,724,725],{"class":149},"'\u003Cp class=\"alert alert-danger\">Please enter a valid email\u003C\u002Fp>'",[128,727,603],{"class":134},[128,729,730],{"class":130,"line":175},[128,731,657],{"class":134},[128,733,734,736,738,740,742,744,747,749,752],{"class":130,"line":199},[128,735,629],{"class":516},[128,737,697],{"class":134},[128,739,700],{"class":516},[128,741,703],{"class":142},[128,743,597],{"class":134},[128,745,746],{"class":149},"\"telephone\"",[128,748,710],{"class":134},[128,750,751],{"class":149},"\"phone\"",[128,753,715],{"class":134},[128,755,756,758,760,763],{"class":130,"line":240},[128,757,720],{"class":142},[128,759,597],{"class":134},[128,761,762],{"class":149},"'\u003Cp class=\"alert alert-danger\">Please enter a valid phone number\u003C\u002Fp>'",[128,764,603],{"class":134},[128,766,767],{"class":130,"line":250},[128,768,657],{"class":134},[10,770,771,772,775,776,779,780,786],{},"I say the ",[16,773,774],{},"simple way"," for a reason: ",[104,777,778],{},"I personally do not recommend this option",". Why? Because ",[36,781,785],{"href":782,"rel":783},"https:\u002F\u002Fwww.raymondcamden.com\u002F2014\u002F07\u002F21\u002FColdFusion-isValid-Email-and-new-TLDs\u002F",[784],"nofollow","IsValid is not accurate for email validation",", and the only way to guarantee that an email address is truly valid is to send the user an email. This is common practice in signup forms, for example.",[10,788,789,790,793],{},"I would avoid stringent validation for any localization-specific formats such as postal codes or phone numbers - there are simply too many variants. For any validation regex, there will almost certainly be issues with certain \"valid\" formats. That is my ",[104,791,792],{},"opinion"," - you are free to use or reject it!",[10,795,796,797,799],{},"For simpler values like numerics, floats or strings, ",[99,798,684],{}," is fine. For example, we could validate a donation form's \"amount\" field to make sure it is a dollar value.",[119,801,803],{"className":507,"code":802,"language":509,"meta":124,"style":124},"if ( !isValid(\"float\", form[\"amount\"]) ) {\n    writeOutput('\u003Cp class=\"alert alert-danger\">Please enter a valid donation amount\u003C\u002Fp>');\n}\n",[99,804,805,827,838],{"__ignoreMap":124},[128,806,807,809,811,813,815,817,820,822,825],{"class":130,"line":131},[128,808,629],{"class":516},[128,810,697],{"class":134},[128,812,700],{"class":516},[128,814,703],{"class":142},[128,816,597],{"class":134},[128,818,819],{"class":149},"\"float\"",[128,821,710],{"class":134},[128,823,824],{"class":149},"\"amount\"",[128,826,715],{"class":134},[128,828,829,831,833,836],{"class":130,"line":156},[128,830,720],{"class":142},[128,832,597],{"class":134},[128,834,835],{"class":149},"'\u003Cp class=\"alert alert-danger\">Please enter a valid donation amount\u003C\u002Fp>'",[128,837,603],{"class":134},[128,839,840],{"class":130,"line":175},[128,841,657],{"class":134},[676,843,76],{"id":844},"iterative-type-checking",[10,846,847],{},"Now, instead of hard-coded field type checking, we could loop over an array of field names with type info:",[119,849,851],{"className":507,"code":850,"language":509,"meta":124,"style":124},"var formFields = [{\n    name: \"amount\",\n    type: \"float\"\n},{\n    name: \"name\",\n    type: \"string\"\n}];\nformFields.each((field) => {\n    if ( form[field.name] != \"\" && !isValid(field.type, form[field.name]) ) {\n        writeOutput('\u003Cp class=\"alert alert-error\">#field.name# must be a valid #field.type#\u003C\u002Fp>');\n    }\n});\n",[99,852,853,865,875,883,888,896,903,908,926,949,960,964],{"__ignoreMap":124},[128,854,855,857,860,862],{"class":130,"line":131},[128,856,517],{"class":516},[128,858,859],{"class":134}," formFields ",[128,861,146],{"class":516},[128,863,864],{"class":134}," [{\n",[128,866,867,870,872],{"class":130,"line":156},[128,868,869],{"class":134},"    name: ",[128,871,824],{"class":149},[128,873,874],{"class":134},",\n",[128,876,877,880],{"class":130,"line":175},[128,878,879],{"class":134},"    type: ",[128,881,882],{"class":149},"\"float\"\n",[128,884,885],{"class":130,"line":199},[128,886,887],{"class":134},"},{\n",[128,889,890,892,894],{"class":130,"line":240},[128,891,869],{"class":134},[128,893,189],{"class":149},[128,895,874],{"class":134},[128,897,898,900],{"class":130,"line":250},[128,899,879],{"class":134},[128,901,902],{"class":149},"\"string\"\n",[128,904,905],{"class":130,"line":265},[128,906,907],{"class":134},"}];\n",[128,909,910,913,915,917,920,922,924],{"class":130,"line":286},[128,911,912],{"class":134},"formFields.",[128,914,550],{"class":142},[128,916,553],{"class":134},[128,918,919],{"class":556},"field",[128,921,560],{"class":134},[128,923,563],{"class":516},[128,925,566],{"class":134},[128,927,928,930,933,936,938,941,944,946],{"class":130,"line":319},[128,929,571],{"class":516},[128,931,932],{"class":134}," ( form[field.name] ",[128,934,935],{"class":516},"!=",[128,937,540],{"class":149},[128,939,940],{"class":516}," &&",[128,942,943],{"class":516}," !",[128,945,703],{"class":142},[128,947,948],{"class":134},"(field.type, form[field.name]) ) {\n",[128,950,951,953,955,958],{"class":130,"line":328},[128,952,594],{"class":142},[128,954,597],{"class":134},[128,956,957],{"class":149},"'\u003Cp class=\"alert alert-error\">#field.name# must be a valid #field.type#\u003C\u002Fp>'",[128,959,603],{"class":134},[128,961,962],{"class":130,"line":343},[128,963,619],{"class":134},[128,965,966],{"class":130,"line":364},[128,967,624],{"class":134},[10,969,970,971,973],{},"I prefer this approach ",[104,972,629],{}," I'm going to generate the form dynamically via CFML, because I'll probably already have metadata about each field. For most smaller\u002Fnon-generated HTML forms, who really cares if my code is a little repetitive?",[25,975,82],{"id":976},"dealing-with-validation-errors",[10,978,979,980,983],{},"Most of the examples shown above display a Bootstrap alert immediately and abort or exit the form processing to show the message to the user. That is more than adequate ",[104,981,982],{},"as long as we trust our frontend validation",". Validating on the frontend will filter out most real users from submitting invalid data in the first place.",[10,985,986,987,990],{},"However, we can improve on this model if we have the ability to generate the HTML form. Halting the request, displaying an error, and asking the user to click the back button is inconvenient and may clear the form, causing the user to lose all progress made. For a better flow, I usually stuff an ",[99,988,989],{},"errors"," array with error messages, then render the form with errors at the top (if the submission is invalid):",[119,992,994],{"className":507,"code":993,"language":509,"meta":124,"style":124},"var requiredFields = \"email,phone,message\";\nvar errors = [];\nform.fieldnames.each((fieldname) => {\n    if ( requiredFields.find(fieldname) && isEmpty(form[fieldname]) ) {\n        errors.append(\"#fieldname# is required.\");\n    }\n});\nif ( errors.len() ) {\n    \u002F\u002F don't process the form; display it instead.\n    include \"form.cfm\";\n}\n",[99,995,996,1008,1020,1036,1052,1067,1071,1075,1086,1091,1101],{"__ignoreMap":124},[128,997,998,1000,1002,1004,1006],{"class":130,"line":131},[128,999,517],{"class":516},[128,1001,520],{"class":134},[128,1003,146],{"class":516},[128,1005,525],{"class":149},[128,1007,528],{"class":134},[128,1009,1010,1012,1015,1017],{"class":130,"line":156},[128,1011,517],{"class":516},[128,1013,1014],{"class":134}," errors ",[128,1016,146],{"class":516},[128,1018,1019],{"class":134}," [];\n",[128,1021,1022,1024,1026,1028,1030,1032,1034],{"class":130,"line":175},[128,1023,547],{"class":134},[128,1025,550],{"class":142},[128,1027,553],{"class":134},[128,1029,557],{"class":556},[128,1031,560],{"class":134},[128,1033,563],{"class":516},[128,1035,566],{"class":134},[128,1037,1038,1040,1042,1044,1046,1048,1050],{"class":130,"line":199},[128,1039,571],{"class":516},[128,1041,574],{"class":134},[128,1043,577],{"class":142},[128,1045,580],{"class":134},[128,1047,583],{"class":516},[128,1049,586],{"class":142},[128,1051,589],{"class":134},[128,1053,1054,1057,1060,1062,1065],{"class":130,"line":240},[128,1055,1056],{"class":134},"        errors.",[128,1058,1059],{"class":142},"append",[128,1061,597],{"class":134},[128,1063,1064],{"class":149},"\"#fieldname# is required.\"",[128,1066,603],{"class":134},[128,1068,1069],{"class":130,"line":250},[128,1070,619],{"class":134},[128,1072,1073],{"class":130,"line":265},[128,1074,624],{"class":134},[128,1076,1077,1079,1082,1084],{"class":130,"line":286},[128,1078,629],{"class":516},[128,1080,1081],{"class":134}," ( errors.",[128,1083,635],{"class":142},[128,1085,638],{"class":134},[128,1087,1088],{"class":130,"line":319},[128,1089,1090],{"class":643},"    \u002F\u002F don't process the form; display it instead.\n",[128,1092,1093,1096,1099],{"class":130,"line":328},[128,1094,1095],{"class":134},"    include ",[128,1097,1098],{"class":149},"\"form.cfm\"",[128,1100,528],{"class":134},[128,1102,1103],{"class":130,"line":343},[128,1104,657],{"class":134},[10,1106,1107,1108,1111],{},"Once we have that array of error messages, we can easily display a Bootstrap alert for each error at the top of ",[99,1109,1110],{},"form.cfm"," like so:",[119,1113,1115],{"className":121,"code":1114,"language":123,"meta":124,"style":124},"\u003Ccfif errors.len() >\n    \u003Ccfloop list=\"#error#\" index=\"error\">\n       \u003Cp class=\"alert alert-error\">#error#\u003C\u002Fp>\n    \u003C\u002Fcfloop>\n\u003C\u002Fcfif>\n\u003C!--- render form --->\n",[99,1116,1117,1131,1156,1177,1185,1193],{"__ignoreMap":124},[128,1118,1119,1121,1125,1128],{"class":130,"line":131},[128,1120,135],{"class":134},[128,1122,1124],{"class":1123},"s7hpK","cfif",[128,1126,1127],{"class":142}," errors.len()",[128,1129,1130],{"class":134}," >\n",[128,1132,1133,1135,1138,1141,1143,1146,1149,1151,1154],{"class":130,"line":156},[128,1134,159],{"class":134},[128,1136,1137],{"class":1123},"cfloop",[128,1139,1140],{"class":142}," list",[128,1142,146],{"class":134},[128,1144,1145],{"class":149},"\"#error#\"",[128,1147,1148],{"class":142}," index",[128,1150,146],{"class":134},[128,1152,1153],{"class":149},"\"error\"",[128,1155,153],{"class":134},[128,1157,1158,1161,1163,1165,1167,1170,1173,1175],{"class":130,"line":175},[128,1159,1160],{"class":134},"       \u003C",[128,1162,10],{"class":138},[128,1164,165],{"class":142},[128,1166,146],{"class":134},[128,1168,1169],{"class":149},"\"alert alert-error\"",[128,1171,1172],{"class":134},">#error#\u003C\u002F",[128,1174,10],{"class":138},[128,1176,153],{"class":134},[128,1178,1179,1181,1183],{"class":130,"line":199},[128,1180,243],{"class":134},[128,1182,1137],{"class":1123},[128,1184,153],{"class":134},[128,1186,1187,1189,1191],{"class":130,"line":240},[128,1188,457],{"class":134},[128,1190,1124],{"class":1123},[128,1192,153],{"class":134},[128,1194,1195],{"class":130,"line":250},[128,1196,1197],{"class":643},"\u003C!--- render form --->\n",[10,1199,1200,1201,1204],{},"And finally, make sure to tweak the form by filling each input with the submitted ",[99,1202,1203],{},"form.field"," value. This allows the user to seamlessly  pick up after an invalid submission, letting them easily fill out a required field or correct an email typo.",[119,1206,1208],{"className":121,"code":1207,"language":123,"meta":124,"style":124},"\u003Cform action=\"contact.cfm\">\n    \u003Cdiv class=\"field\">\n        \u003Clabel for=\"name\">Your Name\u003C\u002Flabel>\n        \u003Cinput type=\"text\" name=\"name\" id=\"name\" value=\"#encodeForHTMLAttribute(form.name)#\" \u002F>\n    \u003C\u002Fdiv>\n    \u003Cdiv class=\"field\">\n        \u003Clabel for=\"email\">Your Email\u003C\u002Flabel>\n        \u003Cinput type=\"text\" name=\"email\" id=\"email\" value=\"#encodeForHTMLAttribute(form.email)#\" \u002F>\n    \u003C\u002Fdiv>\n    \u003Cdiv class=\"field\">\n        \u003Clabel for=\"message\">Message\u003C\u002Flabel>\n        \u003Ctextarea name=\"message\" id=\"message\">#encodeForHTMLAttribute(form.message)#\u003C\u002Ftextarea>\n    \u003C\u002Fdiv>\n    \u003Cdiv class=\"submit\">\n        \u003Cinput type=\"submit\" class=\"button button-primary\" value=\"Send\">\n    \u003C\u002Fdiv>\n\u003C\u002Fform>\n",[99,1209,1210,1224,1238,1256,1289,1297,1311,1329,1362,1370,1384,1402,1427,1435,1449,1475,1483],{"__ignoreMap":124},[128,1211,1212,1214,1216,1218,1220,1222],{"class":130,"line":131},[128,1213,135],{"class":134},[128,1215,139],{"class":138},[128,1217,143],{"class":142},[128,1219,146],{"class":134},[128,1221,150],{"class":149},[128,1223,153],{"class":134},[128,1225,1226,1228,1230,1232,1234,1236],{"class":130,"line":156},[128,1227,159],{"class":134},[128,1229,162],{"class":138},[128,1231,165],{"class":142},[128,1233,146],{"class":134},[128,1235,170],{"class":149},[128,1237,153],{"class":134},[128,1239,1240,1242,1244,1246,1248,1250,1252,1254],{"class":130,"line":175},[128,1241,178],{"class":134},[128,1243,181],{"class":138},[128,1245,184],{"class":142},[128,1247,146],{"class":134},[128,1249,189],{"class":149},[128,1251,192],{"class":134},[128,1253,181],{"class":138},[128,1255,153],{"class":134},[128,1257,1258,1260,1262,1264,1266,1268,1270,1272,1274,1276,1278,1280,1282,1284,1287],{"class":130,"line":199},[128,1259,178],{"class":134},[128,1261,204],{"class":138},[128,1263,207],{"class":142},[128,1265,146],{"class":134},[128,1267,212],{"class":149},[128,1269,215],{"class":142},[128,1271,146],{"class":134},[128,1273,189],{"class":149},[128,1275,222],{"class":142},[128,1277,146],{"class":134},[128,1279,189],{"class":149},[128,1281,229],{"class":142},[128,1283,146],{"class":134},[128,1285,1286],{"class":149},"\"#encodeForHTMLAttribute(form.name)#\"",[128,1288,237],{"class":134},[128,1290,1291,1293,1295],{"class":130,"line":240},[128,1292,243],{"class":134},[128,1294,162],{"class":138},[128,1296,153],{"class":134},[128,1298,1299,1301,1303,1305,1307,1309],{"class":130,"line":250},[128,1300,159],{"class":134},[128,1302,162],{"class":138},[128,1304,165],{"class":142},[128,1306,146],{"class":134},[128,1308,170],{"class":149},[128,1310,153],{"class":134},[128,1312,1313,1315,1317,1319,1321,1323,1325,1327],{"class":130,"line":265},[128,1314,178],{"class":134},[128,1316,181],{"class":138},[128,1318,184],{"class":142},[128,1320,146],{"class":134},[128,1322,276],{"class":149},[128,1324,279],{"class":134},[128,1326,181],{"class":138},[128,1328,153],{"class":134},[128,1330,1331,1333,1335,1337,1339,1341,1343,1345,1347,1349,1351,1353,1355,1357,1360],{"class":130,"line":286},[128,1332,178],{"class":134},[128,1334,204],{"class":138},[128,1336,207],{"class":142},[128,1338,146],{"class":134},[128,1340,212],{"class":149},[128,1342,215],{"class":142},[128,1344,146],{"class":134},[128,1346,276],{"class":149},[128,1348,222],{"class":142},[128,1350,146],{"class":134},[128,1352,276],{"class":149},[128,1354,229],{"class":142},[128,1356,146],{"class":134},[128,1358,1359],{"class":149},"\"#encodeForHTMLAttribute(form.email)#\"",[128,1361,237],{"class":134},[128,1363,1364,1366,1368],{"class":130,"line":319},[128,1365,243],{"class":134},[128,1367,162],{"class":138},[128,1369,153],{"class":134},[128,1371,1372,1374,1376,1378,1380,1382],{"class":130,"line":328},[128,1373,159],{"class":134},[128,1375,162],{"class":138},[128,1377,165],{"class":142},[128,1379,146],{"class":134},[128,1381,170],{"class":149},[128,1383,153],{"class":134},[128,1385,1386,1388,1390,1392,1394,1396,1398,1400],{"class":130,"line":343},[128,1387,178],{"class":134},[128,1389,181],{"class":138},[128,1391,184],{"class":142},[128,1393,146],{"class":134},[128,1395,354],{"class":149},[128,1397,357],{"class":134},[128,1399,181],{"class":138},[128,1401,153],{"class":134},[128,1403,1404,1406,1408,1410,1412,1414,1416,1418,1420,1423,1425],{"class":130,"line":364},[128,1405,178],{"class":134},[128,1407,369],{"class":138},[128,1409,215],{"class":142},[128,1411,146],{"class":134},[128,1413,354],{"class":149},[128,1415,222],{"class":142},[128,1417,146],{"class":134},[128,1419,354],{"class":149},[128,1421,1422],{"class":134},">#encodeForHTMLAttribute(form.message)#\u003C\u002F",[128,1424,369],{"class":138},[128,1426,153],{"class":134},[128,1428,1429,1431,1433],{"class":130,"line":391},[128,1430,243],{"class":134},[128,1432,162],{"class":138},[128,1434,153],{"class":134},[128,1436,1437,1439,1441,1443,1445,1447],{"class":130,"line":400},[128,1438,159],{"class":134},[128,1440,162],{"class":138},[128,1442,165],{"class":142},[128,1444,146],{"class":134},[128,1446,411],{"class":149},[128,1448,153],{"class":134},[128,1450,1451,1453,1455,1457,1459,1461,1463,1465,1467,1469,1471,1473],{"class":130,"line":416},[128,1452,178],{"class":134},[128,1454,204],{"class":138},[128,1456,207],{"class":142},[128,1458,146],{"class":134},[128,1460,411],{"class":149},[128,1462,165],{"class":142},[128,1464,146],{"class":134},[128,1466,433],{"class":149},[128,1468,229],{"class":142},[128,1470,146],{"class":134},[128,1472,440],{"class":149},[128,1474,153],{"class":134},[128,1476,1477,1479,1481],{"class":130,"line":445},[128,1478,243],{"class":134},[128,1480,162],{"class":138},[128,1482,153],{"class":134},[128,1484,1485,1487,1489],{"class":130,"line":454},[128,1486,457],{"class":134},[128,1488,139],{"class":138},[128,1490,153],{"class":134},[10,1492,1493],{},[104,1494,1495],{},"PS. Make sure to encode all user-submitted data to prevent Cross-Site Scripting (XSS)!",[25,1497,88],{"id":1498},"conclusion",[10,1500,1501,1502,700],{},"Form validation is not hard, just tedious. Hopefully this helps you understand the basics of validation. When in doubt, be more permissive than you need to be, but ",[104,1503,1504],{},"never trust user input",[10,1506,1507],{},"That wraps up Part One of Form Processing in CFScript. If you liked this or hated this, please comment below. :)",[1509,1510,1511],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .s7hpK, html code.shiki .s7hpK{--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic}",{"title":124,"searchDepth":156,"depth":156,"links":1513},[1514,1515,1516,1517,1518,1522,1523],{"id":27,"depth":156,"text":28},{"id":91,"depth":156,"text":44},{"id":467,"depth":156,"text":50},{"id":480,"depth":156,"text":56},{"id":663,"depth":156,"text":62,"children":1519},[1520,1521],{"id":678,"depth":175,"text":70},{"id":844,"depth":175,"text":76},{"id":976,"depth":156,"text":82},{"id":1498,"depth":156,"text":88},"2019-07-23T16:13:57-04:00",false,"md",{},true,"\u002Fposts\u002Fforms-1-validation",{"title":5,"description":12},"posts\u002Fforms-1-validation",[1533,1534,1535,1536],"coldfusion","cfscript","cfml","validation","9RVZEw6I8d4d71BTrr40Dj21cgqXMwqSHjM-VLATA8k",1790471527785]