Jump to content
Mark
 Share


4.0 - Forms

Forms are an ubiquitous aspect of any web application. In the IPS Social Suite, particularly in the Admin CP, I often find myself copying and pasting code in various places to create a form. We've had the ipsRegistry::getClass('output')->formInput() and similar methods since 3.0, but you still have to copy all the HTML to display the rows, and write all the code to validate it yourself.

Copying and pasting code is something all developers hate. It's a red flag that you're probably doing something wrong. In IPS 4.0, we've written a central form building helper class to alleviate this.

Just as a reminder: Everything in this blog is a work in progress - naturally someone with a much keener design sense than I will be going over the interface - I'm just demonstrating the functionality, not a finished product :smile:


The Basics

Let's say I want to create a form with a single text input field. I simply initiate the form, add an object representing the input, and then display the form (it has a __toString method) - like so:

$form = new IPSHelpersForm();
$form->add( new IPSHelpersFormText( 'name', 'default value' ) );
IPSOutput::i()->output .= $form;




The helper will automatically look for language strings with the same name as the form element and use them. If there is a language string with the same name and then "_desc" - it'll use that as the description.

So the above code, in the ACP, produces something like this:



Required

Let's say I want the field to be required - I just pass a third argument indicating so. When the form is submitted, if no value has been provided, it will automatically display an inline error:

new IPSHelpersFormText( 'name', '', TRUE )








Options

The fourth argument I can pass is an array with options dependent on the type of input field I'm adding. These options may change the way a field is displayed or add additional validation.

So for a text field, I can specify the minimum and maximum length (which, naturally takes multibyte languages into consideration):

new IPSHelpersFormText( 'name', '', TRUE, array( 'minLength' => 5 ) )






For a number field, I might specify the number of decimal points to round to, which it will do on the fly:

new IPSHelpersFormNumber( 'name', 0, TRUE, array( 'decimals' => 2 ) )



Watch Video


Or I could add an "Unlimited" checkbox, which is quite common for Admin CP settings:

new IPSHelpersFormNumber( 'name', 0, TRUE, array( 'unlimited' => TRUE ) )






Custom Validation

If the built-in options don't provide enough validation for a given need, you can pass a lambda function as a 5th argument:

new IPSHelpersFormText( 'name', '', TRUE, array(), function( $val )
{
	if ( $val === 'Bad Value' )
	{
		throw new IPSHelpersFormException( 'That value is not allowed.' );
	}
} )






Uploads

Of course - simple input fields aren't all that can be done. How does drag and drop uploading sound?

new IPSHelpersFormUpload( 'name', NULL, FALSE, array( 'multiple' => TRUE ) )



Watch Video

(By the way, you'll notice a stripy bar flashes up briefly - this is a real progress bar, but because I'm uploading to localhost it's filling faster than it displays - in practice, you'll see a nice smooth-filling progress bar)


Getting the values

The form helper will by default (you can override it of course) submit to the same page it's on. You can check if it has been submitted (and passed validation) and obtain the values if so simply by calling the values() method - here's an example:

$form = new IPSHelpersForm();

$form->add( ... );

if ( $values = $form->values() )
{
	// $values contains the values from the form
}
else
{
	IPSOutput::i()->output .= $form;
}




The values will be returned in a way that is appropriate to the input type. For example, a text input field will return a string, number input will return either an integer or float, an upload field will return an IPSFile object (or array of them, if you're accepting multiple files), etc.

 Share

Comments

Recommended Comments



naturally someone with a much keener design sense than I will be going over the interface

*coughRIKKIcough*
 
 

The helper will automatically look for language strings with the same name as the form element and use them. If there is a language string with the same name and then "_desc" - it'll use that as the description.

Don't suppose 'description' or 'desc' could be added to the array as either an override or an optional method of providing the description, in case someone doesn't want to go through the effort of making a description for that field in the language files?

Link to comment
Share on other sites

Don't suppose 'description' or 'desc' could be added to the array as either an override or an optional method of providing the description, in case someone doesn't want to go through the effort of making a description for that field in the language files?

 

*slap* All language strings should be in the language files. I agree there could be some value in that, though for a different reason. Pulling it in automatically means you can't insert any dynamic text (say a date, or the value of some dependent setting).

Link to comment
Share on other sites

*slap* All language strings should be in the language files. I agree there could be some value in that, though for a different reason. Pulling it in automatically means you can't insert any dynamic text (say a date, or the value of some dependent setting).

I was thinking more on the lines of using it in IP.Content or other custom work that isn't part of a product.  Example, form that is custom to a site and you don't expect it to be translated.

 

Of course, for hooks/apps/etc, those should all be in language bits, period.  I'm just thinking of custom/single site only situations.

Link to comment
Share on other sites

This should have a builder tool to do all this.. something like the forms builder in Visual Studio.  

 

Create a "blank" form and drag controls onto the form.  The programmer edits the control attributes in a properties window and the tool generates all the code for you.   The form gets stored as XML so it can be later edited.

Link to comment
Share on other sites

Its gonna take me awhile to get used to all the everywhere, I'm used to the underscore like new IPS_Helper_Forms.

computernamesharenamefolderfilename.txt

 

Oh wait, that's something different.

 

 

O well, It'll grow on me.

Like a fungus?

 

 

Create a "blank" form and drag controls onto the form.  The programmer edits the control attributes in a properties window and the tool generates all the code for you.   The form gets stored as XML so it can be later edited.

What about something like in IPC when adding a database field?  Click to add, fill in the form there, submit and then see a list of fields you've added.  A form to build a form. :D

Link to comment
Share on other sites

So bottom line is that your makeing it so that we can make our own forums that is built in to the system itself and won't have to use addons if we wish?

forms, not forums.

 

Think of an application where you fill in certain data so that it works correctly on the front end.  Member groups for example.

 

Form is something you fill out.  Forums hold discussions.

Link to comment
Share on other sites

So bottom line is that your makeing it so that we can make our own forums that is built in to the system itself and won't have to use addons if we wish?

 

No. The purpose of this blog entry is for those interested in our underlying code, or for that mod authors might want to utilise our helper classes.

Link to comment
Share on other sites

This should have a builder tool to do all this.. something like the forms builder in Visual Studio.  

 

Create a "blank" form and drag controls onto the form.  The programmer edits the control attributes in a properties window and the tool generates all the code for you.   The form gets stored as XML so it can be later edited.

>.>... uhh.... No, just no? That's not programming by any means, and to call the user using such a tool a programmer is a stretch generally.

Very nice Mark. :D I especially appreciate the validation callback... going to use that a LOT I can tell ;)

Link to comment
Share on other sites

No. The purpose of this blog entry is for those interested in our underlying code, or for that mod authors might want to utilise our helper classes.

I know what the point of this blog is about. xD  I just stated a question. Thus I take your answer as a no.

 

 

 

forms, not forums.

 

Think of an application where you fill in certain data so that it works correctly on the front end.  Member groups for example.

 

Form is something you fill out.  Forums hold discussions.

 

Yes, thank you Wolfie, my figures are moving slower then my mind can keep up. I know the different between them. But yes I meant to say forms.

Link to comment
Share on other sites

Yes, thank you Wolfie, my figures are moving slower then my mind can keep up. I know the different between them. But yes I meant to say forms.

Since there is a language barrier, I thought perhaps you misread it, thus my clarifying it.  Wasn't mean to come off in any bad way. :)

Link to comment
Share on other sites

Cool! 

A question, will you add methods to create HTML5 new inputs (date, range, email)? I think I already know the answer, and it should be no, since very few browser support all of them.

 

I see you created a sort of range input, are you going to do a date one? I mean, when user clicks on the input, a small popup with a calendar appears. There's jquery calendar picker that does this. I know it's not vital, but it could be a very user-friendly way to select a date, and could prevent miswritten dates. :)

Link to comment
Share on other sites

>.>... uhh.... No, just no? That's not programming by any means, and to call the user using such a tool a programmer is a stretch generally.

 

That's funny.. because that's exactly how application developers on Windows have developed applications for the past 20+ years.  It's how XCode does it to build OSX apps.  It's how ASP.Net developers have done it since Microsoft figured out that perhaps doing it by hand with classic ASP was a bad idea and lead to error prone code.  It's how GUI builder tools for Android/IOS currently do it.  Doing it "the hard way" isn't smart nor is it clever.. no offense.   It is only necessary if the developer tools suck.

 

In fact, because the IPS code includes validation methods a tool like this could easily be made to create event stubs for handling the input that the user could program directly through the tool and later "compile" the output for including into their app.  Perhaps on the form builder you click on something near the control and it opens up the code view for processing the form input for that control.   Microsoft Visual Studio compilers hide this from you with the idea of "partial classes", where half of the class exists for the purpose of initializing a form and the other half contains the code for handling form interactions.  This was done to separate tool-generated code from user-generated code.

 

Clearly IPS is looking at streamlining development here.. and hand-coding forms is stuff of the 90's.  Any tool that makes application development quicker means more accessibility to developers.

 

In fact, I would probably just fork CodeCanvas to do it and match it to the IPS style guide and add in that callback capability.  I'm sure IP.Content users would absolutely prefer that route.

 

http://www.codecanvas.org/

Link to comment
Share on other sites

complex forms do not stand a chance of creation with such a tool, a dynamic form, or even a multi-step form, would immediately outgrow the bounds of such a tool.

and seriously, HOW is that programming? You just showed me a video of a dude pressing auto-add buttons in a Content-like manner.

Regardless, such could not be a part of the core of a web application, and is an over-glorified form WYSIWYG.

WYSIWYG editors only open up accessibility for the laymen, but bind the hands of the more advanced developers.

Such a tool could be created easily, but should not be forced down the dev's throat or bloating the core framework.

Link to comment
Share on other sites

That's funny.. because that's exactly how application developers on Windows have developed applications for the past 20+ years.  It's how XCode does it to build OSX apps.  It's how ASP.Net developers have done it since Microsoft figured out that perhaps doing it by hand with classic ASP was a bad idea and lead to error prone code.  It's how GUI builder tools for Android/IOS currently do it.  Doing it "the hard way" isn't smart nor is it clever.. no offense.   It is only necessary if the developer tools suck.

 

 

Not to butt into what seems to be a heated argument but as a mobile developer I can tell you the Interface builders aren't used as much as you think they are. 

 

The Android interface builder is useless. You usually just write your own XML for layouts. 

 

 

IB on iOS really only saves you time setting the frames of an item, yes it gives you access to some popular properties but not all. Most companies don't even allow the use of nib files because of how difficult they are to resolve merge conflicts in. (OSX is the same way).

 

RDEs are designed to just make it quick to layout where you want your items to be. A web form is more of a linar layout. You typically don't have forms thrown all over in random places on a page. A drag and drop UI isn't really necessary. 

Link to comment
Share on other sites

WYSIWYG editors only open up accessibility for the laymen, but bind the hands of the more advanced developers. Such a tool could be created easily, but should not be forced down the dev's throat or bloating the core framework.

 

Just to clear the air, this isn't a heated argument.. just a discussion really as to how to accelerate the productivity of developers.   Having this API at all helps establish a more consistent way of handling forms.

 

I didn't post a video of what I'm talking about in action, but a form builder in jQuery.   If you want howto videos based around web development, look up ASP.NET on Youtube.   Microsoft developed a way to package controls and drop them onto a visual form builder, and then do all the advanced coding you need for form manipulation.

 

In this case what I'm talking about is for time-saving..    Something that would make it quick to put together forms in a manner consistent with the IPS style guides.

 

The Android interface builder is useless. You usually just write your own XML for layouts. 

..

 

RDEs are designed to just make it quick to layout where you want your items to be. A web form is more of a linar layout. You typically don't have forms thrown all over in random places on a page. A drag and drop UI isn't really necessary. 

 

Android was actually the one platform I was thinking of when I said that you need to do it by hand if the developer tools suck.  But yes, the linear nature of forms makes the actual design of them pretty easy.   It would be more like dragging and dropping controls into a sortable list really and then configuring their properties.

 

This is just an idea for a code generation tool.  Of course as a programmer you could customize the code.  =)

Link to comment
Share on other sites

Actually the linear nature of most web forms is often detrimental to user experience / UI design IMO/E.  The tendency of most web developers to just loop through an array and spit it all out in a top down format is a crutch.  Yes it's easier, but it's not always the best thing to do from the user's perspective.

 

The human eye is trained to read/scan text from side to side (L-R or R-L depending on your language) not top to bottom.  Often a well designed form can use this to build a much more compact form that makes more sense and takes little to no scrolling.

 

James

Link to comment
Share on other sites

I know what the point of this blog is about. xD  I just stated a question. Thus I take your answer as a no.

 

The information in this blog entry and the code samples are meant to give an idea as to how a developer might look to create common form elements in the 4.0 Suite.  This is not something that is likely going to be "exposed" to the end user (e.g. an administrator).  That said, we may look at expanding IP.Content to make more generic forms that don't require being attached to a database utilizing some of these changes.  We'll have to see where development leads us. :)

 

This should have a builder tool to do all this.. something like the forms builder in Visual Studio.  

 

Create a "blank" form and drag controls onto the form.  The programmer edits the control attributes in a properties window and the tool generates all the code for you.   The form gets stored as XML so it can be later edited.

 

Honestly, I'm not really sure that's necessary?  Say a developer is building an application.  They're going to have to code the application as it is, and the changes described here allow you to easily build uniform and consistent forms without dealing with copying and pasting the same HTML over and over.  I don't see how us spending the development time (not only building, but maintaining) to generate some sort of ACP interface where you can drag n drop form elements in specific orders for every single form throughout the suite is going to be helpful in this instance.

 

I would suggest it is unlikely we're going to build a GUI on top of what is described in this entry in order to create forms.  I don't think the vast majority of developers who write code for our framework will really need it.  We can always evaluate as time goes on, however.  I never (ok, rarely) say never.

 

Cool! 

A question, will you add methods to create HTML5 new inputs (date, range, email)? I think I already know the answer, and it should be no, since very few browser support all of them.

 

I see you created a sort of range input, are you going to do a date one? I mean, when user clicks on the input, a small popup with a calendar appears. There's jquery calendar picker that does this. I know it's not vital, but it could be a very user-friendly way to select a date, and could prevent miswritten dates. :smile:

 

The 4.0 Suite will be utilizing HTML5.  The input types you are referring to have very low support, so while you will likely be able to create a "date" input field (for example), there will very likely have to be some sort of javascript fallback.  If it doesn't work in both IE and Firefox out of the box, it's not sufficient.

 

FWIW, we have date input fields even in IP.Board 3.x using javascript (see the advanced search page for an example).

Link to comment
Share on other sites

Cool! 

A question, will you add methods to create HTML5 new inputs (date, range, email)? I think I already know the answer, and it should be no, since very few browser support all of them.

 

I see you created a sort of range input, are you going to do a date one? I mean, when user clicks on the input, a small popup with a calendar appears. There's jquery calendar picker that does this. I know it's not vital, but it could be a very user-friendly way to select a date, and could prevent miswritten dates. :smile:

 

The number input form in the example is actually specified as type="number" - the browser I used to take that screenshot doesn't do anything special with that. If you're using a browser that does, the experience will be enhanced by whatever features the browser requires, but it will otherwise work perfectly.

 

 

As Brandon says, for things like dates, it will define type="date", but we'll have JS to cover that if your browser doesn't support it.

Link to comment
Share on other sites

I would like to add my two cents. Years ago, I used DotNetNuke. I moved away from it because it was too slow, but the one thing that I miss about it was the form/list builder. I think building forms via code is fine, but most of the forms I've needed to create are simple. Going into the code is a pain for simple tasks. So, please add my vote for the form builder.

Link to comment
Share on other sites

Will it be feasible to easily use this for tabbed and stepped forms like the ACP often has?

 

We will need to build tabbed/stepped forms ourselves, so I'm certain this helper class or another one on top of it will be available to do so.

Link to comment
Share on other sites




Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...