|
Strict or Transitional DTD type validation, worth hacking just to pass? |
An area of web development that I previously had little exposure to was WCAG validation. This is the industry standard for Accessibility coding for web platforms. For version two (V2) of the WCAG there are three standards, A, AA and triple A (AAA). Each represents different levels of Accessible compatibility.
What this also does is validate against the W3C doctype standards. This is where my problems arose. The main aim of the doctype standard is to clearly define a separation layer between content and behaviour. In practical terms this equates to best practices such as having an external .CSS files rather than inline styling, and declaring the language types for scripting, such as JavaScript etc.
Using a free online tool, http://www.totalvalidator.com/ you can check if your site is W3C and WCAG complaint. It will base the validation on the doctype declared in your html. There are three types of DTD declaration for html 4.01.
2
3<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
4
5<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/frameset.dtd">
You can read more about Doctypes here: http://www.w3schools.com/tags/tag_DOCTYPE.asp
The main difference between these is that the frameset DTD will accept frameset as valid html, whereas the others will not. Also the Strict DTD imposes a very tight restriction of what is accepted as valid in comparison to the Transitional DTD. One is a Strict adherance to the standard, whereas the other shows that you are Transitioning from old code into the new.
The site http://24ways.org/2005/transitional-vs-strict-markup goes into more detail about what the exact differences are, what I am going to discuss is the option of creating functional hacks, merely to pass validation.
One of the deprecated attributes in Strict validation is the target attribute.
We are all familiar with this attribute, but when you examine it you find that it is actually a declaration of behaviour. We are forcing the user into a specific action. IE open a new window. As a best practice guideline whenever we have a link on a site that exits that site, we open a new window. The only work around for this is creating a specific JavaScript function to open a new window, as this will not be marked as invalid. This seems overkill, just to pass validation.
So I am left with the dilemma that if I want my sites to pass Strict DTD validation I must create a JavaScript hack, or compromise the functionality. I'd like to pass the validation, but I view the functionality as key to a site, so it's an easy decision for me.
|
Using Coldfusion to generate JQuery validation scripts |
In this article I am exploring the idea of automatically creating JQuery validation from a simple Coldfusion input. In this case a list of required fields. I'll say up front Ray Camden's blog entry on Jquery Validation (http://www.coldfusionjedi.com/index.cfm/2009/2/10/An-Introduction-to-jQuery-and-Form-Validation-2) has been an invaluable help.
The principle behind this is that you can create a generic validation object routine, and simple provide it with a set data object (list or struct, haven't decided yet) and have it match against a form and validate it. So with that in mind we will create a simple form.
2
3<label for="name">Name</label><br/>
4<input type="text" name="name" id="name" class="form-field"><p/>
5
6<label for="telephone">Telephone</label><br/>
7<input type="text" name="telephone" id="telephone" class="form-field"><p/>
8
9<label for="email">Email</label><br/>
10<input type="text" name="email" id="email" class="form-field"><p/>
11
12<label for="favouriteSandwhich">Favourite Sandwhich</label><br/>
13<input type="text" name="favouriteSandwhich" id="favouriteSandwhich" class="form-field"><p/>
14
15<input type="submit" name="action" value="Submit">
16
17</form>
2<scr/ipt type="text/javascript" src="jquery.validate.pack.js"></script>
2 $(document).ready(function(){
3 $("#form").validate({
4
5 errorContainer: "#error",
6 errorLabelContainer: "#error ul",
7 wrapper: "li",
8
9 rules: {
10 <cfoutput>
11 <cfloop list="#variables.requiredList#" index="variables.index">
12 #variables.index#: {required: true <cfif findNoCase('email', variables.index, '1')>, email: true</cfif>, minlength: 5},
13 </cfloop>
14 </cfoutput>
15 },
16
17 messages: {
18
19 <cfoutput>
20 <cfloop list="#variables.requiredList#" index="variables.index">
21 #variables.index#: {required: "The #variables.index# field is required",
22 <cfif findNoCase('email', variables.index, '1')> email: "Email addresses are of the form user@host. Please enter a valid email address.",</cfif>
23 minlength: jQuery.format("You need to use at least {0} characters for your name.")
24 },
25
26 </cfloop>
27 </cfoutput>
28
29 }
30 }
31 );
32 });
33 </script>
2/* Error handling styles */
3#error {-moz-background-clip:border;
4 -moz-background-inline-policy:continuous;
5 -moz-background-origin:padding;
6 background:#FFE7DF;
7 background-position: 5px 8px;
8 border: #FF3F00 solid 1px;
9 color:#440000;
10 margin:10px 0 1em;
11 padding:0px 7px 7px 7px;
12 display:none;
13 width: 90%;}
14
15/* padding for the list */
16#error ul {list-style-type:none; padding: 0px 0px 0px 0px;}
17
18/* padding for the list items */
19#error ul li {padding: 4px 0 2px 16px;}
20
21.error {color: red; list-style-type:none; padding: 0px 0px 0px 0px; width: 198px; color:#440000; background:#FFE7DF;}
22li {list-style-type:none;}
23.form-field {width: 200px; padding: 0px 0px 0px 0px;}
24</style>
This creates a totally dynamic validation routine - all fed from a list. I think it forms a good basis to build a more dynamic rules driven model, where you can set field lengths as well.
There is an example of the complete code here, along with a variation on the inline or external placing of the validation messages.
|
Embedding Flash content using the SWF Object javascript method - the short answer |
There are several sites available detailing how to embed SWF Object's into your sites. By far the most reliable, and cross browser compatible without writing any form of Internet Explorer / Firefox hack is the SWF Object javascript plugin.
Adobe have a Developer Connection article detailing how the SWF Object javascript plugin works, http://www.adobe.com/devnet/flashplayer/articles/swfobject.html but it is six pages long, and seems to avoid any direct example of the most straight forward method of implementation. I am sure that it is all encompassing, but I was looking for a quick bullet point style guide.
So here it is:
1. Include the call to the Swobject Javascript library, don't host this yourself, just link directly to Google's code base.
2. Setup the flash variable scopes, this ensures that they exist, and it is a handly place to set global variables for your flash. I normally include this in the header of my frameworks.
2 var flashvars = {};
3 var attributes = {};
4 var params = {wmode: "transparent", allowFullScreen: "true"};
5</s cript>
3. Setup a div for your flashcontent. This is what will be displayed if you are not flash enabled. Ensure that your "No Flash content" either closely represents the actual flash content, or signifies a link to getting Adobe flash in some way.
2 <a href="http://get.adobe.com/flashplayer/" target="new_window" title="Follow this link to get Adobe Flash player"><img src="flash_no_content.jpg" alt="Follow this link to get Adobe Flash player" /></a>
3</div>
At thsi point the "No Flash" content will be displayed on screen.
4. Lastly include the script to switch out the "No Flash content" with the actual flash.
This Javascript will over right the div (by id) and insert the flash object into it. Supply the path, the div ID to replace the content for, followed by the height and width values. Next is the Flash player version (set it to a higher number than the Flash player version for Non flash content testing). Next you include the variables scopes you created in stage 2, passing in any other values your flash content is expecting.
2 swfobject.embedSWF("#path#/flashVideo.swf", "flashcontent", "150", "200", "9", "", flashvars, params, attributes);
3</s cript>
If everything is running correctly you can now see your flash content. Simply change the flashplayer value, 9 above, to something higher, for example 20 to see the non flash content.
|
Uploading an image and previewing the thumbnail in one hit |
A recent piece of functionality required a user to be able to upload an image, and view a thumbnail of that image alongside all the other related details that they were entering (item specific data etc).
After having a look through several forums it seemed that people's opinions were split on whether this could be accomplished using Ajax at all. So I decided to go old school and use an iFrame. I'm not a big fan of frames in any incarnation, but in this case I was willing to make an exception.
So firstly there is an upload form. It is a pretty standard ColdFusion form. Just remember when uploading a file to set the enctype="multipart/form-data". Also the submit button does not submit the form, it fires a JavaScript function 'changeFrame()'. The JavaScript function sets the target of the form submission to the iFrame, and then submits it.
2 <iframe id="uploadFrame" name="uploadFrame" src="action.cfm" height="110" width="90" scrolling="no" frameborder="0"></iframe>
3
4<form name="uploader" action="action.cfm" method="post" enctype="multipart/form-data">
5 <input type="file" name="image" size="5">
6 <input type="button" name="action" value="Upload" onclick="changeFrame()"/>
7 </form>
8</div>
9
10<s/cript>
11function changeFrame()
12 {
13 document.getElementById('uploader').target = 'uploadFrame';
14 document.getElementById('uploader').submit();
15 }
16</s/cript>
The form submits to the 'action.cfm' template. This template displays a placeholder image thumbnail initially, but when the form is submitted it performs the file upload using cffile, then displays the newly uploaded file instead of the placeholder. Ideally at this point I would like to resize the image with cfimage, but my hosting company is still using ColdFusion 7, so I may have to use a third party tag to do the same.
2<cfset dest = "webroot/root/tmp/">
3
4<cfif isdefined('form.image')>
5 <cffile action="upload" filefield="form.image" destination="#dest#" nameconflict="makeunique">
6 <cfset variables.img = cffile.clientFile>
7<cfelse>
8 <cfset variables.img = "holder.gif">
9
10</cfif>
11
12<cfoutput><img src="tmp\#variables.img#" height="100" width="75" border="1"></cfoutput>
13</body>
It is a shame I had to use an iFrame, and it would be really interesting to see if this is possible in a more web 2.0 scripted way.