Page 1 of 1

A new take on forms...

Posted: Tue Mar 14, 2006 7:36 pm
by RobertPaul
The somewhat-recent Advanced Form Validation thread got me thinking a bit about form validation and all that, and the net result was what I'm about to present. 'm a bit uncertain about the quality of the idea, so I figure better to toss it out here now than to spend ages on it only to have it shot down for some reason I hadn't noticed from the beginning. Not to mention that I feel like someone would have done something like this already if it were such a good idea. ;)

Basically my idea is to have forms defined in XML (no, not quite like XForms) which is parsed on the server-side and translated into XHTML. The key feature is that there is a rule (or set of rules) and options defined alongside each form element in the XML. As opposed to setting all your rules/options/error messages in code, where it's separated from the form elements. It's also a bit easier to read. Plus the rules can be used to validate not only on the server-side, but on the client-side as well by dynamically generating JavaScript.

I've put my "sketch" of what it'd like like in a pastebin for the sake of syntax highlighting. Check it out. Obviously it's far from complete (look at that TODO list 8O).

What do you think (of the idea moreso than the sample ... the format can change easily enough)? Am I onto something big, or am I wasting my time?

Posted: Tue Mar 14, 2006 7:41 pm
by feyd
we have syntax highlighting here if you didn't know..

Code: Select all

tags.

Posted: Tue Mar 14, 2006 8:02 pm
by RobertPaul
Doesn't seem to want to highlight the XML, though ...

Posted: Wed Mar 15, 2006 12:58 am
by Christopher
I think it looks like a fine idea. I would want a layered solution that allows the form description to be in PHP arrays, INI files, XML files, database records, etc. All of those would feed some common format (probably an associative array) to the Form Controller. I usually create an object for each parameter/field, so building those from the XML you presented would be pretty easy. Then just like the Form Controller do its stuff.

Posted: Wed Mar 15, 2006 2:48 am
by onion2k
Do this. Seriously. It's a fantastic time saver. I've written exactly this sort of library for my company. But .. be aware that forms can be pretty complicated.

An example of one of my admin forms:

Code: Select all

<form>

	<table>product</table>
	<primary_key>product_id</primary_key>
	<content_directory>content</content_directory>
	<return_path>products_list.php</return_path>
	<write_to_db>1</write_to_db>

	<element>
		<type>label</type>
		<label>Product</label>
	</element>

	<element>
		<type>text</type>
		<label>Title</label>
		<form_name>title</form_name>
		<db_name>title</db_name>
		<class>uniform240</class>
		<validation>
			<required>1</required>
		</validation>
	</element>

	<element>
		<type>text</type>
		<label>Stockcode</label>
		<form_name>stockcode</form_name>
		<db_name>stockcode</db_name>
		<class>uniform160</class>
	</element>

	<element>
		<type>dropdown</type>
		<label>Site</label>
		<form_name>site</form_name>
		<db_name>site_id</db_name>
		<options>
			<table>site</table>
			<value>site_id</value>
			<label>title</label>
			<order>title</order>
			<direction>asc</direction>
		</options>
	</element>

	<element>
		<type>textarea</type>
		<label>Summary</label>
		<form_name>original_summary</form_name>
		<db_name>original_summary</db_name>
		<class>uniform240</class>
	</element>
	
	<element>
		<type>label</type>
		<label>Description</label>
		<class>text</class>
	</element>
	
	<element>
		<type>fckeditor</type>
		<label>Description</label>
		<form_name>original_description</form_name>
		<db_name>original_description</db_name>
		<class>uniform_textarea_page</class>
		<fckeditor_width>650</fckeditor_width>
		<fckeditor_height>500</fckeditor_height>
		<fckeditor_pagebuilder>1</fckeditor_pagebuilder>
		<validation>
			<required>0</required>
		</validation>
	</element>

	<element>
		<type>imageupload</type>
		<label>Product Thumbnail</label>
		<form_name>image_filename_thumbnail</form_name>
		<db_name>image_filename_thumbnail</db_name>
		<class>uniform240</class>
		<show_current>1</show_current>
		<subdirectory>products</subdirectory>
		<sharpen>1</sharpen>
		<resize>
			<thumb_x>120</thumb_x>
			<thumb_y>120</thumb_y>
			<thumb_prefix>thumb_</thumb_prefix>
			<mid_x>180</mid_x>
			<mid_y>180</mid_y>
			<mid_prefix>mid_</mid_prefix>
		</resize>
		<validation>
			<min_x>60</min_x>
			<min_y>60</min_y>
			<max_x>1280</max_x>
			<max_y>960</max_y>
			<min_size>0</min_size>
			<max_size>1000000</max_size>
			<required>1</required>
		</validation>
	</element>

	<element>
		<type>imageupload</type>
		<label>Product Main</label>
		<form_name>image_filename_1</form_name>
		<db_name>image_filename_1</db_name>
		<class>uniform240</class>
		<show_current>1</show_current>
		<subdirectory>products</subdirectory>
		<resize>
			<thumb_x>120</thumb_x>
			<thumb_y>120</thumb_y>
			<thumb_prefix>thumb_</thumb_prefix>
			<mid_x>180</mid_x>
			<mid_y>180</mid_y>
			<mid_prefix>mid_</mid_prefix>
		</resize>
		<validation>
			<min_x>60</min_x>
			<min_y>60</min_y>
			<max_x>1280</max_x>
			<max_y>960</max_y>
			<min_size>0</min_size>
			<max_size>1000000</max_size>
			<required>1</required>
		</validation>
	</element>

	<element>
		<type>imageupload</type>
		<label>Product Mood</label>
		<form_name>image_filename_2</form_name>
		<db_name>image_filename_2</db_name>
		<class>uniform240</class>
		<show_current>1</show_current>
		<subdirectory>products</subdirectory>
		<resize>
			<thumb_x>60</thumb_x>
			<thumb_y>60</thumb_y>
			<thumb_prefix>thumb_</thumb_prefix>
			<mid_x>180</mid_x>
			<mid_y>180</mid_y>
			<mid_prefix>mid_</mid_prefix>
		</resize>
		<validation>
			<min_x>120</min_x>
			<min_y>120</min_y>
			<max_x>1280</max_x>
			<max_y>960</max_y>
			<min_size>0</min_size>
			<max_size>1000000</max_size>
			<required>1</required>
		</validation>
	</element>

	<element>
		<type>imageupload</type>
		<label>Product Color/Small 1</label>
		<form_name>image_filename_3</form_name>
		<db_name>image_filename_3</db_name>
		<class>uniform240</class>
		<show_current>1</show_current>
		<subdirectory>products</subdirectory>
		<resize>
			<thumb_x>120</thumb_x>
			<thumb_y>120</thumb_y>
			<thumb_prefix>thumb_</thumb_prefix>
			<mid_x>180</mid_x>
			<mid_y>180</mid_y>
			<mid_prefix>mid_</mid_prefix>
		</resize>
		<validation>
			<min_x>60</min_x>
			<min_y>60</min_y>
			<max_x>1280</max_x>
			<max_y>960</max_y>
			<min_size>0</min_size>
			<max_size>1000000</max_size>
			<required>1</required>
		</validation>
	</element>

	<element>
		<type>imageupload</type>
		<label>Product Small 2</label>
		<form_name>image_filename_4</form_name>
		<db_name>image_filename_4</db_name>
		<class>uniform240</class>
		<show_current>1</show_current>
		<subdirectory>products</subdirectory>
		<resize>
			<thumb_x>120</thumb_x>
			<thumb_y>120</thumb_y>
			<thumb_prefix>thumb_</thumb_prefix>
			<mid_x>180</mid_x>
			<mid_y>180</mid_y>
			<mid_prefix>mid_</mid_prefix>
		</resize>
		<validation>
			<min_x>60</min_x>
			<min_y>60</min_y>
			<max_x>1280</max_x>
			<max_y>960</max_y>
			<min_size>0</min_size>
			<max_size>1000000</max_size>
			<required>1</required>
		</validation>
	</element>


	<element>
		<type>checkbox</type>
		<label>Completed</label>
		<form_name>completed</form_name>
		<db_name>completed</db_name>
		<class>uniform240</class>
		<columns>1</columns>
		<options>
			<option>
				<value>1</value>
				<label>Completed</label>
			</option>
		</options>
	</element>

	<element>
		<type>ndf</type>
		<subtype>timestamp</subtype>
		<insert_only>1</insert_only>
		<db_name>created</db_name>
	</element>

	<element>
		<type>ndf</type>
		<subtype>timestamp</subtype>
		<db_name>last_updated</db_name>
	</element>
	
	<element>
		<type>submit</type>
		<form_name>submit</form_name>
		<label>* = Required</label>
		<value>Save</value>
	</element>

</form>
That's a pretty basic form .. just some text editting (using FCKEditor), a dropdown (populated by a SQL query), and a few image uploads .. once you get many-to-one and many-to-many cross reference tables and stuff going on it gets really tricky.

Posted: Wed Mar 15, 2006 3:05 pm
by timvw
I always wonder why people write it in yet-another-xml format if your end-goal is to generate xhtml?
If you really want a different rendering you could as easily write an xsl file that does xhml->output instead of anotherformat->output

Posted: Thu Mar 16, 2006 2:47 am
by onion2k
timvw wrote:I always wonder why people write it in yet-another-xml format if your end-goal is to generate xhtml?
That isn't my goal. My goal was simply to define what form elements are required and what populates them. The generation of the form, be it in HTML, XHTML, PDF, Flash, GTK, Swing, etc is a different part of the process. Having an application where the offline GTK based version is defined in the exactly the same way as the online HTML version is my ultimate aim.

Posted: Thu Mar 16, 2006 4:51 am
by patrikG
timvw wrote:I always wonder why people write it in yet-another-xml format if your end-goal is to generate xhtml?
It's not necessarily about rendering. You can include all kinds of meta-information into the XML-file, e.g. what can of values are allowed (e.g. only alphanumeric, numeric), what kind of validation (e.g. credit-card, date etc.) and directly link the field to a column (or columns) in a db-table, etc., etc.

In short: you can write "intelligent forms" - layout would only one aspect of it.

Posted: Thu Mar 16, 2006 7:35 am
by fastfingertips
Everything looks fine in my opinion.

My question is: how you are planning to use it in a multilanguage website if you are attaching the error message there? I'm asking this because i consider it an excellent idea and i'll use it in my current project :).

OFC i will post here source files when i willl be ready.

Posted: Thu Mar 16, 2006 3:29 pm
by RobertPaul
fastfingertips wrote:My question is: how you are planning to use it in a multilanguage website if you are attaching the error message there?
Good point! One could easily substitute "message" for "code" and do it that way, I suppose. Hadn't really thought about that.

Posted: Wed Mar 22, 2006 6:35 pm
by gavinandresen
Personally, I don't like mixing the validation information in with the form display. In my work the look of the form is generally done by a HTML/CSS expert who knows how to make it all look fancy.

And the whole XML -> XSLT -> XHTML thing seems way too complicated and hard to debug (XSLT... shudder...).

So I code validation separate from the form's HTML (actually, the HTML for the forms is generally in a Smarty template, and if we needed multilingual pages we'd just point Smarty to language-specific templates).

The real problem with validation is there's ALWAYS Yet Another Thing to Validate. You can write a few simple validation conditions that cover 90% of what you need to do, but pretty quick you'll need to write PHP code that checks "if they chose this and didn't choose this, then make sure they didn't do THAT last week"... or "if they're adding stuff into a content area less then 190 pixels wide, throw a validation error if they try to upload images wider than that" or something similarly obscure (but critical).

My form auto-filling code and Smarty gets rid of the grunt work on the display end; the Zend Framework's validating filters look like a pretty nice solution for the validation side...