Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1356
  • Last Modified:

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

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
Eric Bourland
Asked:
Eric Bourland
  • 3
  • 2
1 Solution
 
Gurpreet Singh RandhawaWeb DeveloperCommented:
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
 
Eric BourlandAuthor Commented:
randhawa -- thank you. I will try this out tonight and get back to you here.

All best,

Eric
0
 
Eric BourlandAuthor Commented:
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
 
Gurpreet Singh RandhawaWeb DeveloperCommented:
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
 
Eric BourlandAuthor Commented:
randhawa, my thanks as always. I will take a look!

Eric
0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now