Solved

Form validation using HTML 5 / CSS 3 / ColdFusion 9 -- without CFIDE

Posted on 2014-04-14
5
1,185 Views
Last Modified: 2014-04-18
ColdFusion Version 9
MS SQL Server 2012
Windows Server 2008 R2 64-bit / 6GB memory


Hi. I am trying to set up improved form validation -- for the convenience of users, and for (I hope) better security.

Short version: client side validation does not work, even when using the HTML 5 "required" attribute. Also I want to eschew CFIDE scripts.

Details:

I would like to set up form validation without using the scripts in CFIDE. Why? CFIDE seems like a target for manipulation by villains, and I would rather not include a virtual directory /CFIDE/ in every web site I set up in Windows Server IIS. I am open to being convinced otherwise.

It seems like there must be another way to set up server-side and client side form validation.

For now I am focusing on client-side form validation using CSS3 and HTML 5. I thought I would find out how other folks handle this.

I am trying to set up client-side validation following this example:
http://www.the-art-of-web.com/html/html5-form-validation/

But as you can see in my test page, I have failed so far:

http://test2.ebwebwork.com/editnewstest.cfm

Current problems:

* client-side validation does not work and I wonder if I have either a) competing style sheets or b) interference from styles included by ColdFusion or c) user error on my own part.

* form input fields do not display correct style; in the CSS I am trying to do something like:

input:required:invalid, input:focus:invalid { background-image: url(https://lh6.googleusercontent.com/-YUiLQPFuHZo/U0whswRO1PI/AAAAAAAAAnU/xZs_Hu7nliA/s800/invalid.png); background-position: right top; background-repeat: no-repeat; }

input:required:valid { background-image: url(https://lh3.googleusercontent.com/-Lz7UMr66m1U/U0whsyznPYI/AAAAAAAAAnY/TFWdf-kEZRM/s800/valid.png); background-position: right top; background-repeat: no-repeat; }

Open in new window


...but, no luck. My input fields are not styled properly.

I'll go ahead and post this in ColdFusion and CSS forums since I think that's appropriate. Thank you for advice or guidance. Sorry about the discursive nature of this question. =)

Eric

<!-----
Name:        editNews.cfm
Author(s):      Eric Bourland / gdemaria / _agx_
Description: this interface allows a user to create and edit database records that contain news items
Created:     March 2011
Edited: April 2014
ColdFusion Version 9
MS SQL Server 2012
----->


 <!--- Set default value for newsID in scope URL --->
<cfparam name="url.newsID" default="">

<!--- Define newsID in scope FORM, then set form.newsID equal to the newsID passed in the URL: for use later in the application --->
<cfparam name="form.newsID" default="#url.newsID#">

<cfparam name="form.newsTitle" default="">
<cfparam name="form.newsContent" default="">
<cfparam name="form.newsAuthor" default="">
<cfparam name="newsDateCreated" default="">
<cfparam name="form.NewsDate" default="">
<cfparam name="form.newsExcerpt" default="">

<!--- in user-editable fields, set up protection against XSS  --->
    <cfloop collection="#FORM#" item="field">
      <cfset FORM[ field ] = ReReplaceNoCase (FORM[ field ], "<script.*?>.*?</script>", "", "all")>
    </cfloop>

<cfquery datasource="#application.datasource#" name="editNews">
SELECT newsID, newsTitle, NewsDate, newsAuthor, newsContent, newsExcerpt, newsDateCreated
FROM #REQUEST.NewsTable#
WHERE newsID = <cfqueryparam value="#val(url.newsID)#" cfsqltype="cf_sql_integer">
</cfquery>

		   
<!---- begin CFTRY; catch errors ---->
<cftry>  
 
<!---- populate cftry with error message ---->
<cfset variables.error = ""> 
 
<!--- begin form.doSave --->

<cfif IsDefined("form.doSave")>

<!--- when an newsID Exists, the action is UPDATE --->
   
<cfif val(form.newsID)>
                
            <cfquery name="UpdateRecord" datasource="#application.datasource#">
				  UPDATE #REQUEST.NewsTable#
				  SET
           newsTitle = <cfqueryparam cfsqltype="cf_sql_varchar"  value="#Trim(Left(form.newsTitle,255))#">, 
           NewsDate = <cfqueryparam cfsqltype="cf_sql_date"  value="#createODBCdate(Trim(form.NewsDate))#">,
           newsAuthor = <cfqueryparam cfsqltype="cf_sql_varchar"  value="#Trim(Left(form.newsAuthor,128))#">,
           newsContent = <cfqueryparam cfsqltype="cf_sql_varchar"  value="#Trim(form.newsContent)#">,
           newsExcerpt = <cfqueryparam cfsqltype="cf_sql_varchar"  value="#Trim(form.newsExcerpt)#">
           		  WHERE newsID = <cfqueryparam cfsqltype="cf_sql_integer" value="#val(form.newsID)#">
			</cfquery>


<!--- CFELSE: if newsID does not exist, then create new record --->
				<cfelse> 
                
                
<!--- query to insert new user record into #REQUEST.NewsTable# --->
			<cfquery name="InsertRecord" datasource="#application.datasource#" result="newPage">
				 INSERT INTO #REQUEST.NewsTable#
     					(
                        newsTitle,
			            NewsDate,
                        newsAuthor,
                        newsContent,
                        newsExcerpt,
                        newsDateCreated
                        )
			     VALUES(
                    <cfqueryparam cfsqltype="cf_sql_varchar"  value="#Trim(Left(form.newsTitle,255))#">,
                    <cfqueryparam cfsqltype="cf_sql_date"  value="#createODBCdate(Trim(form.NewsDate))#">,
                    <cfqueryparam cfsqltype="cf_sql_varchar"  value="#Trim(Left(form.newsAuthor,128))#">,
                    <cfqueryparam cfsqltype="cf_sql_varchar"  value="#Trim(form.newsContent)#">,
                    <cfqueryparam cfsqltype="cf_sql_varchar"  value="#Trim(form.newsExcerpt)#">,
                    <cfqueryparam cfsqltype="cf_sql_timestamp" value="#now()#">
                         )         
					</cfquery>
                    
                    
<!--- use the result attribute value (newPage) to set form field value --->
      <cfset form.newsID = newPage.IDENTITYCOL>
              
<!--- END queries to update or insert database records ---> 

<!--- END cfif val(form.newsID) -- if a topic needed to be updated or added, then it was done --->
					    </cfif>  


<!--- done? relocate --->


<cfif val(url.NewsID)>
<cflocation url="/admin/editNews.cfm?NewsID=#val(url.newsID)#" addtoken="yes">

<cfelse>                     
<cflocation url="/admin/manageNews.cfm" addtoken="no">
				     
</cfif>
             
<!--- END: Save action --->

<!--- END form.doSave --->
                    </cfif>
       
<!--- END queries to update or insert database records ---> 
        

<!--- this CFCATCH will trap errors --->
            <cfcatch type="Any">
                 <cfset variables.error = cfcatch.message>
            </cfcatch>

<!--- END CFTRY --->  
			</cftry>
       
       
<!--- fetch the data from the database only when there are no errors; let the form variables pass back from the data table into the form to display ---->
 
<cfif len(variables.error) eq 0>
    
<!--- get data from table #REQUEST.NewsTable# and convert the data into form variables --->
			  <cfquery name="getPageDetails" datasource="#application.datasource#">
			    SELECT newsID, newsTitle, NewsDate, newsAuthor, newsContent, newsExcerpt, newsDateCreated
                FROM #REQUEST.NewsTable#
                WHERE newsID = <cfqueryparam cfsqltype="cf_sql_integer" value="#val(form.newsID)#">
 			  </cfquery>

  			<cfloop index="aCol" list="#getPageDetails.columnList#">
			       <cfset "form.#aCol#" = getPageDetails[aCol][getPageDetails.currentRow]>
			  </cfloop>
    
</cfif>



<!----- if record already exists then update record; otherwise, add new record ----->
				<cfif val(url.newsID)>
					  <cfset FormTitle="Update News">
					  <cfset ButtonText="Update">
				<cfelse>
						<cfset FormTitle="Create News Event">
						<cfset ButtonText="Create News Event">

				</cfif>

       
       
       <!--- BEGIN HTML / CSS PAGE HEADER --->
<cfinclude template="/admin/admin_header.cfm">

<!--- if there an error, display error in readable form --->

<cfif len(variables.error)> 
	  <cfoutput>
	    <div class="errorbox">#variables.error#</div>
	    </cfoutput>
   
   <br />

             <div class="center">
               <input type=button value="Go Back" onClick="history.go(-1)">
             </div>
             
             <cfabort>
</cfif>

<cfparam name="url.cftoken" default="">

<cfif len(url.cftoken)> 

<div class="center"><button class="medium green"><span class="icon white medium" data-icon="C"></span> Update Succeeded. Good work.</button></div>

</cfif>

	<!--- Add or Update News Form begins here --->
	<cfform method="post" enctype="multipart/form-data" name="newsForm" onsubmit="return false;">
                
 
 <!--- Embed newsID (PK) to assign a value to it --->
 <cfoutput>
<input type="hidden" name="newsID" value="#form.newsID#" />
 </cfoutput>



<cfoutput>

<h2>#FormTitle#</h2>

</cfoutput>


   
  <label for="newsTitle">News Title:</label>
  	 <cfinput
		placeholder="Title or Headline"
        required
        autofocus
   		type="Text"
		name="newsTitle"
		value="#form.newsTitle#"
		size="100"
		maxlength="255"
        tabindex="1" />
  

 
            
<label for="NewsDate">News Date:</label>

<cfinput
		placeholder="mm/dd/yyyy"
        required
		type="text"
        name="NewsDate"
        value="#DateFormat(NewsDate, "mm/dd/yyyy")#"
        tabindex="2" />
        
<label for="newsAuthor">Author:</label>
  	 <cfinput
		placeholder="Author Name"
        required
   		type="Text"
		name="newsAuthor"
		value="#form.newsAuthor#"
		size="50"
		maxlength="128"
        tabindex="3" />
            
               <p class="center">Use the TinyMCE Editing Interface to edit content:</p>


<label for="newsContent">News Description:</label>

    <span class="smallred">Enter and format content here.</span>
     
      <textarea required
      name="newsContent"
      width="600"  
      height="500"  
            style="width:600px;height:500px;"  
            wrap="virtual"  
            tabindex="4">

           <cfoutput>#form.newsContent#</cfoutput>
   
	  </textarea>


     <p class="width600px"><strong>Event Excerpt:</strong> <span class="smallred">Display an excerpt to tempt readers. Just text, no images. There is no need to format this excerpt text. Your web site style sheet formats it for you.</span></p>
     
      <textarea name="newsExcerpt"
            width="600"  
            height="200"  
            style="width:600px;height:200px;"  
            wrap="virtual"  
            tabindex="5">

           <cfoutput>#form.newsExcerpt#</cfoutput>
   
	  </textarea>

     

   <!--- submit form to ColdFusion for processing; this is the DoSave function, which will add or edit a record --->
<br />

   <div class="center">
   <cfoutput>
  
   <button name="doSave" type="submit" class="green">#ButtonText#</button>
  
   </cfoutput>
   </div>

</cfform>



<!--- Page footer --->
<cfinclude template="/admin/admin_footer.cfm">

Open in new window

0
Comment
Question by:Eric Bourland
  • 3
  • 2
5 Comments
 
LVL 15

Accepted Solution

by:
myselfrandhawa earned 500 total points
Comment Utility
Using html5 and css3 validation is a Good Point, But you have to keep following points to use it:

1. Not all browsers support completely HTML5 elements. Example: IE
2. You have to include some external library like Modernizr or HTML5shiv to make it backward compatible.
3. Not all HTML 5 validation types have been approved by W3c Yet.
4. Use Jquery Validate Plugin Which Works very Good for the kind of work you want to do:

Here is the Example:

<script src="http://code.jquery.com/jquery-git.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>

<script>
$().ready(function() {
// validate signup form on keyup and submit
	$("#signupForm").validate({
		rules: {
			firstname: "required",
			lastname: "required",
			username: {
				required: true,
				minlength: 2
			},
			password: {
				required: true,
				minlength: 5
			},
			confirm_password: {
				required: true,
				minlength: 5,
				equalTo: "#password"
			},
			email: {
				required: true,
				email: true
			},
			topic: {
				required: "#newsletter:checked",
				minlength: 2
			},
			agree: "required"
		},
		messages: {
			firstname: "Please enter your firstname",
			lastname: "Please enter your lastname",
			username: {
				required: "Please enter a username",
				minlength: "Your username must consist of at least 2 characters"
			},
			password: {
				required: "Please provide a password",
				minlength: "Your password must be at least 5 characters long"
			},
			confirm_password: {
				required: "Please provide a password",
				minlength: "Your password must be at least 5 characters long",
				equalTo: "Please enter the same password as above"
			},
			email: "Please enter a valid email address",
			agree: "Please accept our policy"
		},
		errorPlacement: function(error, element) { 
			element.attr('title', error.addClass('error').text()); 
			element.attr('placeholder', error.addClass('error').text()); 
		}
	});
});
</script>

<form class="cmxform" id="signupForm" method="get" action="">
	<fieldset>
		<legend>Validating a complete form</legend>
		<p>
			<label for="firstname">Firstname</label>
			<input id="firstname" name="firstname" type="text" />
		</p>
		<p>
			<label for="lastname">Lastname</label>
			<input id="lastname" name="lastname" type="text" />
		</p>
		<p>
			<label for="username">Username</label>
			<input id="username" name="username" type="text" />
		</p>
		<p>
			<label for="password">Password</label>
			<input id="password" name="password" type="password" />
		</p>
		<p>
			<label for="confirm_password">Confirm password</label>
			<input id="confirm_password" name="confirm_password" type="password" />
		</p>
		<p>
			<label for="email">Email</label>
			<input id="email" name="email" type="email" />
		</p>
		<p>
			<label for="agree">Please agree to our policy</label>
			<input type="checkbox" class="checkbox" id="agree" name="agree" />
		</p>
		<p>
			<label for="newsletter">I'd like to receive the newsletter</label>
			<input type="checkbox" class="checkbox" id="newsletter" name="newsletter" />
		</p>
		<p>
			<input class="submit" type="submit" value="Submit"/>
		</p>
	</fieldset>
</form>

Open in new window

http://jsfiddle.net/JLLn6/

you can add class to the display or the title for displaying the error

http://jsfiddle.net/JLLn6/1/


Let me know if you need further guidance

Regards
0
 
LVL 3

Author Comment

by:Eric Bourland
Comment Utility
randhawa -- thank you. I will try this out tonight and get back to you here.

All best,

Eric
0
 
LVL 3

Author Closing Comment

by:Eric Bourland
Comment Utility
Dear randhawa,

I am still working on this. I have tried a few jquery solutions, including the solution that you suggested. I can't quite get a jquery solution to work. I did finally get a CSS3 solution to mostly work; I am still working out a few bugs. I do suspect that ColdFusion 9 adds javascript to a web page that interferes with other scripts. I will keep working on this task; I think I am close to a pure CSS3 client side validation solution. Thank you as always for your help.

Eric
0
 
LVL 15

Expert Comment

by:myselfrandhawa
Comment Utility
Dear Eric,

The form you had posted wil work with the solution i provided to you, another notable thing is:

you can even combine the jquery.form.js to make upload files to it also:

see the working solution here:

http://steadysoft.in/signatures/

Try it and Post if you encounter any issue, we will solve, probably you get to lean new stuff
0
 
LVL 3

Author Comment

by:Eric Bourland
Comment Utility
randhawa, my thanks as always. I will take a look!

Eric
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Suggested Solutions

When writing CSS, there are a few simple rules that will make your life easier.    1. Using ‘* {box-sizing:border-box;}’. Using this will wrap all your elements in a nice little compact box-model that will give you the width you want, like so... …
Recently while working on a project I got a very annoying cfdocument has no body error message. I had never seen this error before. So I checked the code. The code was pretty simple; it was Just showing me the cfdocumnt tag and inside that tag a …
In this Micro Tutorial users will learn how to embed custom fonts into websites using @font-face in CSS Select a font: Ensure the EULA allows you to use @font-face: Download the font: Get the browser-compatible files you need: Edit your CSS       - Name …
In this tutorial viewers will learn how add a full-size background image to a webpage using CSS3. Create a new HTML document with an internal stylesheet.: In CSS, define the html element to have a background image. Use a high resolution image.: In t…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now