Jump to content


Photo

Module want: form builder


  • Please log in to reply
75 replies to this topic

#21 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,530 posts
  • 856

  • LocationVihti, Finland

Posted 01 May 2011 - 03:03 PM

Can't applaud you enough for this Ryan! Thank you.

I had that wrong - rendering form after that second snippet. This wasn't enough tough, since I got some minor issues left. Here is code how I got it working (form rendering & inputfields):

This is before any html output:
<?php
// Get the page you need to edit
$somepage = $pages->get('/some/page/');

// Jquery and UI is needed (though you could probably use these outside pw)
$modules->get('JqueryCore');
$modules->get('JqueryUI');

$form = $modules->get('InputfieldForm');

// Add fields to the form
$fields = $somepage->getInputfields();
$form->append($fields);

// Add save button
$field = $this->modules->get('InputfieldSubmit');
$field->attr('id+name', 'submit_save');
$field->attr('value', 'Save');
$form->append($field);

// Render the form, but don't echo here
$form->out = $form->render();

// Not required, but if you want get styles from normal admin... Widgets (images, AsmSelect) works nicely without default styles, so you might wanna get naked here :)
$config->styles->prepend($config->urls->adminTemplates . "styles/main.css");
$config->styles->append($config->urls->adminTemplates . "styles/ui.css"); 


This code goes between <head>:

// Some of the widgets use this data, so you get js errors without this
<script type="text/javascript">
<?php
$jsConfig = $config->js();
$jsConfig['debug'] = $config->debug;
$jsConfig['urls'] = array(
	'root' => $config->urls->root,
	'admin' => $config->urls->admin,
	'modules' => $config->urls->modules,
	'core' => $config->urls->core,
	'files' => $config->urls->files,
	'templates' => $config->urls->templates,
	'adminTemplates' => $config->urls->adminTemplates,
	);
?>

var config = <?php echo json_encode($jsConfig); ?>;
</script>

// And these outputs the .css and .js files for each module
<?php foreach($config->styles->unique() as $file) echo "\n\t<link type='text/css' href='$file' rel='stylesheet' />"; ?>
<?php foreach($config->scripts->unique() as $file) echo "\n\t<script type='text/javascript' src='$file'></script>"; ?>

And finally you echo the form where you need it (between your body tags, I assume):
<?php echo $form->out; ?>

You also might wanna debug this stuff, so set debug true on config.php and this to your template:
<?php if($config->debug && $this->user->isSuperuser()) include($config->paths->adminTemplates . "debug.inc"); ?>

This just renders the form and all the fancy widgets there is. I didn't get to processing the page, but with Ryan's examples it should be easy and I am looking forward to it.

#22 ryan

ryan

    Hero Member

  • Administrators
  • 5,780 posts
  • 3125

  • LocationAtlanta, GA

Posted 02 May 2011 - 09:33 AM

This is great! Thanks for posting this. This is a great guide for people that want to implement some of PW's form controls outside of the admin template. It looks like you've got all the parts covered. Since this thread is turning into a helpful tutorial and reference, I want to cover the different ways of getting and setting values to Inputfields:

<?php

// setting
$inputfield->attr('name', 'value');
$inputfield->set('name', 'value');
$inputfield->name = value; // same as set() above, but shorter 

// getting
$value = $input->attr('name');
$value = $inputfield->get('value');
$value = $inputfield->value; // same as get() above, but shorter

The attr() method is designed for explicitly setting setting/getting attributes that should go with the form input. For instance, 'name', 'class', 'id', 'value', 'checked', 'type', or whatever other attributes you want to go with the input. It should not be used for anything else because whatever you pass to it will end up as an attribute on the markup that gets output.

Whereas the set(), get() and direct reference methods are designed for setting/getting other properties, like field configuration options. They also work with attributes like the attr() method, but it's better to use the attr() method when setting an attribute just to be clear to PW that you intend that to be an actual attribute with the markup that gets output.

If you look in PW's code, you might also see it using these two functions in some instances:

<?php
$inputfield->setAttribute('name', 'value'); // same as $inputfield->attr('name', 'value'); 
$value = $inputfield->getAttribute('name'); // same as $value = $inputfield->attr('name'); 

These are the same thing as the attr() method, and the preferred syntax is to use the attr() method in your code. Internally, PW translates the attr() method to either setAttribute() or getAttribute(), depending on the number of arguments. The reason setAttribute() and getAttribute() exist is for people creating new Inputfield classes... it's easier to override single purpose methods rather than multi-purpose methods (like attr). But on a public interface, it's easier to use a multi-purpose method like attr(), so I recommend ignoring setAttribute() and getAttribute() unless you are developing new Inputfields.

Variations of attr()
In addition to getting and setting single attributes, the attr() method can also set multiple attributes at the same time. Below are all the possible variations (some repeated from above):

<?php

// set single attribute (same as example above)
$inputfield->attr('name', 'value'); 

// get single attribute (same as example above)
$value = $inputfield->attr('name'); 

// set multiple attributes with same value
$inputfield->attr('id+name', 'value');

// set multiple attributes with different values
$attrs = array(
    'name' => 'value',
    'name' => 'value', 
    // etc.. 
    ); 
$inputfield->attr($attrs);

Inputfields that contain other Inputfields
One type of Inputfield is the InputfieldWrapper, and it's designed solely to contain other Inputfields. Examples of InputfieldWrappers also include InputfieldForm and InputfieldFieldset (all are derived from InputfieldWrapper). On these Inputfields, the get() and direct reference can be used to retrieve any one of the fields by name:

<?php
$inputfield = $form->get('your_field_name'); 
$inputfield = $form->your_field_name; // direct reference works as alternate syntax

Internally, the two calls above translate to this:

<?php
$inputfield = $form->find("name=your_field_name")->first();

What that means is it'll find any field in the form, not just direct children of the field you are checking. So a call to $form->get('your_field_name') will return the associated field, regardless of of many fieldsets it's wrapped under. This is just to keep things simple. After all, the form fields are all living in the same namespace when the form gets output.

By the way, that find() method mentioned above can be used with any selector, just like with pages. It will return all inputfields in the form that match the properties you give it. But in practice, I've not ever needed it in my forms, so not sure how useful it really is.

You can add/remove Inputfields as children using these methods. In the example below, we'll assume that $form is an instance of InputfieldForm:

<?php
$form->append($inputfield); // append an inputfield to the form
$form->prepend($inputfield); // prepend an inputfield to the form
$form->add($inputfield); // same as append()
$form->remove($inputfield); // remove inputfield from the form


Built in properties
All Inputfields have these built-in properties that you can set or get:

<?php

$inputfield->label = "The clickable label that appears above this field. Should only be a few words.";
$inputfield->description = "A longer description that appears below the label. Can be any length.";
$inputfield->notes = "A extra highlighted area that appears under the field. Can be any length.";
$inputfield->head = "Headline that appears below label/above description. "; // PW 2.1 only!

$inputfield->id; // HTML 'id' attribute. Auto-generated if you don't set it. 
$inputfield->name; // HTML 'name' attribute, required
$inputfield->value; // HTML 'value' attribute, if applicable
$inputfield->class; // HTML 'class' attribute, optional

$inputfield->required = 0; // value not required for this inputfield
$inputfield->required = 1; // value IS required for this inputfield

$inputfield->collapsed = Inputfield::collapsedNo; // Field will display open (this is the default)
$inputfield->collapsed = Inputfield::collapsedYes; // Field will display collapsed, requiring a click to open
$inputfield->collapsed = Inputfield::collapsedBlank; // Field will display collapsed only if blank
$inputfield->collapsed = Inputfield::collapsedHidden; // Field will not be rendered in the form






#23 adamkiss

adamkiss

    Master of the universe

  • Moderators
  • 1,078 posts
  • 289

Posted 12 May 2011 - 10:33 AM

Ryan, two notes:

1.,  can this contact from template use any field in PW?
2., wouldn't it be better if you created release: thread for this plugin?

#24 ryan

ryan

    Hero Member

  • Administrators
  • 5,780 posts
  • 3125

  • LocationAtlanta, GA

Posted 12 May 2011 - 10:50 AM

1.,  can this contact from template use any field in PW?


Just for clarification (for other people reading this), the posts above mine and Adam's aren't talking about the plugin module, they are just talking about regular API use of PW's Inputfield classes.

That FormTemplateProcessor module is just a proof-of-concept, and it may work with any field, but I have not tested it with anything other than text-based fields. In addition, the style recommendations included at the bottom of the module file only attempts to style these simple fields.

Even if it does work with any field, I would not recommend adding file/image uploads or things like that to a contact form. Most of PW's Inputfields are designed for administrative tasks, not contact form tasks -- It is overkill and overhead for simple contact forms. But for simple things like text, textarea, integer, email, url fields, the distinction doesn't matter much. For fields that deal with outside assets (file/image for example), those should not be put on a public contact form (nor do I think they would even work).

2., wouldn't it be better if you created release: thread for this plugin?


Probably so -- When I make updates to this next, I'll put it in it's own thread. I think in most cases people are better off creating their own forms for most things you would have on a site (at least that's what I do). But this module can be very handy in the right circumstances, especially as something to build from.


#25 ryanscherler

ryanscherler

    Jr. Member

  • Members
  • PipPip
  • 10 posts
  • 2

Posted 10 August 2011 - 02:29 PM

The form builder is working as expected (awesome!), until I actually submit the form when I get this error message while logged in as superuser (I am running PW 2.0):

Exception: New page '/support/support-ticket/0/' must be saved before files can be accessed from it (in [root]/.../.../wire/core/PagefilesManager.php line 100)

#26 ryan

ryan

    Hero Member

  • Administrators
  • 5,780 posts
  • 3125

  • LocationAtlanta, GA

Posted 10 August 2011 - 04:15 PM

Ryan, I haven't actually tried this FormBuilder module recently, so it's possible it needs an update. But first I wanted to check -- do you have any file fields on that form? Based on the error message, it sounds like that might be the case, but let me know... I was really only thinking of that FormBuilder as being for the more basic fields (like text and textarea), as the other types have more javascript dependencies making them really only appropriate for admin use at present.  And of course, this FormBuilder is not a core module, it's more an example to build from. But a real FormBuilder will be in the works later this year.

#27 Soma

Soma

    Hero Member

  • Moderators
  • 3,217 posts
  • 1762

  • LocationSH, Switzerland

Posted 05 September 2011 - 08:48 AM

I finally tried this module out, and it still works in new 2.1! Thanks for the example Ryan.

But it throws an error if it's saving the form as page:

Exception: Method Page::removeRole does not exist or is not callable in this context (in /wire/core/Wire.php line 231)

#0 [internal function]: Wire->__call('removeRole', Array)
#1 /site/modules/FormTemplateProcessor.module(198): Page->removeRole('guest')
#2 [internal function]: FormTemplateProcessor->___savePage(Object(InputfieldForm))
#3 /wire/core/Wire.php(267): call_user_func_array(Array, Array)
#4 /wire/core/Wire.php(229): Wire->runHooks('savePage', Array)
#5 [internal function]: Wire->__call('savePage', Array)
#6 /site/modules/FormTemplateProcessor.module(237): FormTemplateProcessor->savePage(Object(InputfieldForm))
#7 [internal function]: FormTemplateProcessor->___render()
#8 /wire/core/Wire.php(267): call_user_func_array(Array, Array)
#9 /wire/core/Wire.php(229): Wire

After commenting out the following line in the ___savePage() it works and Page gets saved as child of the form page:
$this->contact->removeRole('guest');

I have only tested with standard text, email, textarea fields.

Would be great to may have this developed further. What are the plans on this? This is intended to be for the admin only? Or would it be possible to have clients build a form in this way?

@somartist | modules created | support me, flattr my work flattr.com


#28 ryan

ryan

    Hero Member

  • Administrators
  • 5,780 posts
  • 3125

  • LocationAtlanta, GA

Posted 05 September 2011 - 01:10 PM

Thanks I have updated for 2.1 and placed on GitHub:
https://github.com/r...mplateProcessor

Would be great to may have this developed further. What are the plans on this?


Somewhere around ProcessWire 2.3 we'll be including a formal form builder. Not yet sure if it's going to use the same approach as this one.

This is intended to be for the admin only? Or would it be possible to have clients build a form in this way?


This can be used for public facing forms. But the person creating the forms should be an administrator in PW (whether the developer or the client).

#29 Soma

Soma

    Hero Member

  • Moderators
  • 3,217 posts
  • 1762

  • LocationSH, Switzerland

Posted 05 September 2011 - 01:56 PM

As always, much appreciated! Already on my watch list. :) I can't wait to see how this evolves.

I think having a way to build simple or even more advanced forms, is a very welcome addition to further speed up the process. "Everybody" hates building forms manually.

EDIT: Oh and new version tested, still works! ;)

@somartist | modules created | support me, flattr my work flattr.com


#30 diogo

diogo

    Hero Member

  • Moderators
  • 2,011 posts
  • 1089

  • LocationPorto, Portugal

Posted 05 September 2011 - 07:24 PM

I came across this thread only now. This module would certainly be very useful and i though i could throw something in the discussion.

I would like something like that too, though don't know how it could be done without being something that generates markup.

that one is from January already :)

Symphony as a nice way of dealing with this problem. The System generates the markup, but instead of using it automatically, it just gives it as an example to paste on the template file. Here is the form builder on the admin: http://symphony-cms....-1264826920.png; and here is a usage example: http://symphony-cms....ony/6/#pagehead.
I think this is quite a simple way of giving control over the markup.

#31 ryan

ryan

    Hero Member

  • Administrators
  • 5,780 posts
  • 3125

  • LocationAtlanta, GA

Posted 06 September 2011 - 08:24 AM

Great example, thanks for posting it. There are definitely some things I like about that approach. The only problem is that it's static. You can't go back and make changes directly to the form (without copying and pasting the whole thing, or parts of it again)? And if you've customized the markup further, then copying and pasting may then be out of the picture. Still, seems like a worthwhile compromise and it really may be the best way to go. But I see this approach as being one more aimed at people that already know how to build their own forms and are just using this as a convenience. So this is one area where I'm still leaning towards more automation and less markup control, just to keep things dynamic, and within reach of clients. But providing the copy/paste markup like this seems like a good option to provide regardless.

#32 alchime.net

alchime.net

    Jr. Member

  • Members
  • PipPip
  • 31 posts
  • 0

  • LocationReunion - Island ile de la Reunion

Posted 17 October 2011 - 08:41 AM



Since the module can save entries as pages, would it be usable to create
"web directories" of persons/users/links with description and pictures ?

saving to pages is not different than saving to sbdg, right ?
So the missing parts are
- security options for images
- users creation and setting up their pages.

Ryan (and someone else) do you think that will be possible with the
way you intend to make the formBuilder updated ?

I'm pretty sure there is enought resources on php to get something like that done
(i mean even by me) but i was wondering how hard would that be and how
PW would help do it..

I should read again this topic and the ones about images galery...

Regards,



#33 ryan

ryan

    Hero Member

  • Administrators
  • 5,780 posts
  • 3125

  • LocationAtlanta, GA

Posted 17 October 2011 - 09:04 AM

Ryan (and someone else) do you think that will be possible with the
way you intend to make the formBuilder updated ?


I see the ability to import data provided by form submissions into pages as pretty important. While it may or may not be in the first preview version of the form builder, it's something that is most definitely part of the overall plan.

#34 alchime.net

alchime.net

    Jr. Member

  • Members
  • PipPip
  • 31 posts
  • 0

  • LocationReunion - Island ile de la Reunion

Posted 19 October 2011 - 07:08 AM


  ;D I ll be patient.



#35 Soma

Soma

    Hero Member

  • Moderators
  • 3,217 posts
  • 1762

  • LocationSH, Switzerland

Posted 26 October 2011 - 06:44 AM

I'm currently using this module to render simple contact form and it works great so far.

Now I got a page reference field with a select inputfield for selecting a category. These categories are pages and they are multilang. So there's 3 fields for title_de, title_en, title_fr. How would it be possible to render the select chosing the option text from the current language?

So far I've added a parameter to the ___render($lang) function and give that to the ___buildForm function where the form is built.  How can I make it (if ie inputfield->name is "category_select") using like "title_$lang" for the option text. Or maybe simpler /alternatively, how can I build the select menu using API?

Any help is appreciated.

EDIT: I should first investigate.. then ask :D I found the simplest solution:

<?php
if($inputfield->name == "formfield_category_select"){
	$inputfield->labelFieldName = "title_$lang";	
}

This sets the field chosen from the reference pages for the inputfield select. Amazing, didn't thought it was that simple. :D

EDIT: Only problem now the select has id's as value which get sent by email, how could I set the option value to be the title?

EDIT: Well I think this wouldn't be easy possible, no? Now what I did is a simple check, when preparing the mail content for sending email, for the fieldtype label. If it's the category select, I do a find using the id and return the title_de, title_en ...

@somartist | modules created | support me, flattr my work flattr.com


#36 Soma

Soma

    Hero Member

  • Moderators
  • 3,217 posts
  • 1762

  • LocationSH, Switzerland

Posted 18 November 2011 - 08:39 AM

Sorry for the double post.

Ryan, I'm using this for simple form. I noticed there's a setting "emailSubject" but on the mail send, you don't enter $this->emailSubject its a hard coded "Web Contact" ...

Also I had to modifiy it a little here and there to make it work for my case (multilang). I also added a property to be abel to add a string before the message body.  I know this is still very rough version, but just to mention.

@somartist | modules created | support me, flattr my work flattr.com


#37 ryan

ryan

    Hero Member

  • Administrators
  • 5,780 posts
  • 3125

  • LocationAtlanta, GA

Posted 18 November 2011 - 11:04 AM

Oops, thanks for finding that Soma. I've just fixed it in the live source so that emailSubject is no longer hard coded.

#38 Giovanni

Giovanni

    Newbie

  • Members
  • Pip
  • 9 posts
  • 0

Posted 07 December 2011 - 03:14 PM

I've got the form to work fine using the form template processor on one website, but i cant seem to get it to work on another website  ???

When submitting the form, it does not check the validation fields and just returns to the main page(without errors).
I've tried reinstalling the module but no luck.

Any suggestions? :)

#39 Pete

Pete

    Administrator

  • Administrators
  • 1,756 posts
  • 658

  • LocationChester, England

Posted 07 December 2011 - 03:23 PM

I had something similar a while back - are you sure the fields you've set as required are actually spelled right in both the formbuilder code and the HTML code? If they don't match then they won't get checked - that was my issue anyway.

#40 Giovanni

Giovanni

    Newbie

  • Members
  • Pip
  • 9 posts
  • 0

Posted 07 December 2011 - 04:04 PM

my fields are correct, they match the names. It's as if it does not even validate the fields

$form = $modules->get('FormTemplateProcessor'); 
$form->template = $templates->get('contact'); // required
$form->requiredFields = array('form_name','form_email','form_message');
$form->parent = $page; // optional, saves form as page
$form->email = 'jerez@giovanniorigins.com'; // optional, sends form as email
echo $form->render(); // draw form or process submitted form





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users