Solved

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

Posted on 2014-04-14
5
1,226 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 16

Accepted Solution

by:
Gurpreet Singh Randhawa earned 500 total points
ID: 40001001
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
ID: 40002389
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
ID: 40007880
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 16

Expert Comment

by:Gurpreet Singh Randhawa
ID: 40008226
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
ID: 40009122
randhawa, my thanks as always. I will take a look!

Eric
0

Featured Post

How our DevOps Teams Maximize Uptime

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us. Read the use case whitepaper.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Styling your websites can become very complex. Here I'll show how SASS can help you better organize, maintain and reuse your CSS code.
This article demonstrates how to create a simple responsive confirmation dialog with Ok and Cancel buttons using HTML, CSS, jQuery and Promises
In this tutorial viewers will learn how to position items using CSS's three positioning types Create a new HTML document with an internal stylesheet.: Create another div in CSS and name it Absolute : Type "position:absolute;" and "top:10px; left:50p…
Learn how to create flexible layouts using relative units in CSS.  New relative units added in CSS3 include vw(viewports width), vh(viewports height), vmin(minimum of viewports height and width), and vmax (maximum of viewports height and width).

825 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