Jump to content

Create simple forms using API


Soma

Recommended Posts

I am using the api as suggested in somas gist´s but I want to have multiple checkboxes that don´t have own div´s but instead are together in one div so I can style them as a button-group. The markup I want is:

<fieldset>
                        <legend>Ich möchte</legend>
                        <div class="button-group">
                            <input id="checkbox1" type="checkbox" name="Neue Kunden gewinnen" value="Ja">
                            <label class="button" for="checkbox1">neue Kunden gewinnen</label>
                            <input id="checkbox2" type="checkbox"  name="Meine Kunden halten" value="Ja">
                            <label class="button" for="checkbox2">Kunden halten</label>
                            <input id="checkbox3" type="checkbox"  name="Kunden zurückgewinnen" value="Ja">
                            <label class="button" for="checkbox3">Kunden zurückgewinnen</label>
                        </div>
                    </fieldset>

I should mention, that these are not the only fields in the form.

Here is a screenshot of what I try to accomplish. How can I do that? InputFieldWrapper to the rescue?! But how?post-1299-0-22235900-1451472480_thumb.pn

Link to comment
Share on other sites

  • 1 month later...

Sorry @felic and @jmartsch for not having some help for your answers :/

Anyone know why when I use Ryan's code from P1 of this thread to add a fieldset to a form:

...extend your example, lets say that you wanted the 'email' and 'password' fields in a fieldset titled "About You". You would create the fieldset...
 
no HTML fieldset tags are rendered?
Link to comment
Share on other sites

@gebeer
Thanks for the tip, yes, sorry, I should have noted, I get

<li class='Inputfield InputfieldFieldset ui-widget' id='InputfieldFieldset2'>

I checked your link and Googled and tried variations around

$form->setMarkup(array(
    'fieldset' => "<fieldset {attrs}>{out}</fieldset>"
));

along with using Ryan's example:

// 
// Fieldset
$fieldset = $modules->get('InputfieldFieldset');
$fieldset->label = 'About You';

but an HTML fieldset tag is never rendered.

Maybe your reply to @LostKobrakai means I can't do this; sadly the Soma code you linked to and using forms via the API is not familiar enough for me to work out how I can use an HTML fieldset tag as it's intended.

Thanks very much all the same and if I find the way to do this I'll be sure to post back here.

Link to comment
Share on other sites

  • 3 weeks later...

Hi Guys

I really like the Form API of Processwire, it is really flexible. You can build from a simple contact form until to a complex registration form in a short time without using HTML. The only "flaw" which I encountered is. The bigger the form is, the bigger the code gets and this can be frustrating when you are building forms with more than 20 Inputfields. The code gets longer and readability gets lost over the time since it is a (almost)self repeating process of "codeblocks" where the structure is almost always the same. So I decided to write up a simple class to "minify" the code when building forms with the form API.

How does the class work?

It is a very simply class where you create a new (didn't know how to name the class ^^)ProcessForm Object and get the InputfieldForm Object with the getFormObject() function. Now you can call the addInputfield() function to create any kind(not are all supported, only the simple ones) of Inputfield. And at the end you can render the ProcessForm object which basically calls the render() function of the InputfieldForm class. 

<?php

$form = new ProcessForm("./contact", "post", "contactform"); //default ("./", "post", "ProcessForm")

$form->addInput(array(
    'type' => "InputfieldText", 
    'label' => "First Name",
    'attributes' => array('id' => "firstname", 'name' => "firstname"),
    'required' => 1
));

$form->addInput(array(
    'type' => "InputfieldRadios", 
    'label' => "To much code for a simple Form?",
    'options' => array('yes' => "Yes, absolutely", 'no' => "No, absolutely not"),
    'attributes' => array('id' => "tomuchcode", 'name' => "tomuchcode"),
    'required' => 1
));

$form->render();

?>

Is this usefull?

Honestly said, I don't know if this is usefull for you. It is usefull for me, since I can "minify" or have a better overview/readability over my code.

PS: I am still learning PHP OOP, so dont hate me when my "oop skills" are too low. I'am very open to better approaches, tipps, suggestions to improve this class or go antoher way to manage the big amount of code when building big forms with API. 

PPS: The class isn't tested very well(or better said it isn't tested at all ^^) since I am to lazy to do tests. So don't use this in commercial projects(but when you want still using it commercial it is at your own risk ^^).

The code is on Github

 
Greetings Orkun aka "Nukro"
Edited by Nukro
Source Code of ProcessForm.php was changed
  • Like 5
Link to comment
Share on other sites

  • 1 month later...

Hi, a beginners question to the $form->action = "./" part:

Couldn't you just leave the action-attribute out, just do not write it?

AFAIK this would have the same effect.

I read that "./" means "same directory" and is only in this context interpreted as "same url/file/script".

Link to comment
Share on other sites

  • 2 months later...
On 3/11/2016 at 5:09 PM, Nukro said:

Hi Guys

I really like the Form API of Processwire, it is really flexible. You can build from a simple contact form until to a complex registration form in a short time without using HTML. The only "flaw" which I encountered is. The bigger the form is, the bigger the code gets and this can be frustrating when you are building forms with more than 20 Inputfields. The code gets longer and readability gets lost over the time since it is a (almost)self repeating process of "codeblocks" where the structure is almost always the same. So I decided to write up a simple class to "minify" the code when building forms with the form API.

How does the class work?

It is a very simply class where you create a new (didn't know how to name the class ^^)ProcessForm Object and get the InputfieldForm Object with the getFormObject() function. Now you can call the addInputfield() function to create any kind(not are all supported, only the simple ones) of Inputfield. And at the end you can render the ProcessForm object which basically calls the render() function of the InputfieldForm class. 


<?php

$example = new ProcessForm();
$formObject = $example->getFormObject();

$attributes = array('id' => "firstname", 'name' => "firstname");
$example->addInputfield("InputfieldText", $formObject, "First Name", $attributes, 1);

$out .= $example->render();

?>

Is this usefull?

Honestly said, I don't know if this is usefull for you. It is usefull for me, since I can "minify" or have a better overview/readability over my code.

PS: I am still learning PHP OOP, so dont hate me when my "oop skills" are too low. I'am very open to better approaches, tipps, suggestions to improve this class or go antoher way to manage the big amount of code when building big forms with API. 

PPS: The class isn't tested very well(or better said it isn't tested at all ^^) since I am to lazy to do tests. So don't use this in commercial projects(but when you want still using it commercial it is at your own risk ^^).

The code is on Github

 
Greetings Orkun aka "Nukro"

Hi Nukro,

  I tried working with your ProcessForm class and I ran into a few problems. I am using the code from ProcessForm.php . I would like to know if maybe the example code you listed is out of sync with the actual class's code ? One reason I ask this is that the class's code references what I believe is an associative array, that is supposed to be passed to the addInput method.  For example, the method definition contains ' function addInput ( $opts = array() , $fieldset ) ... and within addInput, there is code such as if ($opts['columnWidth'] != "") { $field->columnWidth = $opts['columnWidth'] ; } . Also, the example code calls addInputfield but in the class the method name is addInput.

I could probably use the class definition itself and get something working but I just wanted to run these questions past you and maybe save myself and anyone else  some time. So if i am missing something, please let me know if you have a chance , and thanks for sharing this class.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

Later that evening....  lol

 Hey again Nukro, yeah I think I just should have worked with the class file and figured it out for myself, which is what I did after my first post. I was able to create two fields and a submit button , for example, with the following code.... (see attachment below)

$example = new ProcessForm($wire);  // had to pass the $wire variable to the class

$example->addInput( array('type'=>"InputfieldText",'label'=>"Name") );
$example->addInput( array('type'=>"InputfieldText",'label'=>"Address") );
$example->addInput( array('type'=>"InputfieldSubmit",'value'=>"Submit") );

$out .= $example->render();
echo($out);

------------------------------------------------------------------------

As mentioned in the comment I needed to make a change to give the class access to $wire. I tested this code out in a single php file. I included index.php in it to get access to $wire and then I passed $wire to the constructor for the ProcessForm class. I made $wire a private variable in the class and then I only had to change lines like $field = wire('modules')->get($type);  to $field = $this->wire('modules')->get($type);

So anyway, thank you again for the code Nukro. It was a good learning experience. The class offers more options than I used in my simple example, and I intend to play around with them and learn more. And thanks @Soma too for his original post... And lastly, sorry for the HUGE post guys, I tried to trim down the original post by Nukro in my post but didn't have much luck.

Bill

formTest.GIF

  • Like 1
Link to comment
Share on other sites

There's also something similar in the core. If you look here https://processwire.com/blog/posts/new-module-configuration-options/#using-an-array-to-define-module-configuration you'll see that module configuration inputfields can be defined by an array. This is also possible for custom created forms, as it's mentioned to the end of the text.

  • Like 8
Link to comment
Share on other sites

  • 1 month later...

anything on spam filtering at all in this thread? Love the simple form but was wondering if there was a good rule of thumb for preventing bots.

Currently I use a javascript solution that adds a small bit of missing information to the form after 1 second on the front end which it checks for when posted.

Link to comment
Share on other sites

  • 2 months later...

Hello @ all,

til now I have written the codes for my forms manually, but now I will use the API-method from PW. On my inputfields I always have the following code for collapsing inside my labels:

<i title="Toggle open/close" class="toggle-icon fa fa-fw fa-angle-down" data-to="fa-angle-down fa-angle-right" aria-hidden="true"></i>

Is there a way to get rid of this part via the API like this:

$field->collapsed(....);

Best regards

Link to comment
Share on other sites

Above post is not a big problem, because I can make in invisible via CSS. Another question: Is it possible to add a fe "isvalid" class after form submission to valid fields, so I can style them with CSS (fe a green border around the input field).

Link to comment
Share on other sites

Thanks for the hint. I didnt know that there are CSS properties for valid and invalid. Anyway! I have solved it by adding a class after submission with this piece of code:

    foreach ($form as $field){
      $field->attr('class' , $field->attr('class') . ' submitted'); //add class submitted after form submission
    } 

So every field will get the additional class "submitted". The code must be placed after $input->post->submit. Now I can style the inputs depending on their state.

Thanks

 

  • Like 1
Link to comment
Share on other sites

Hello @bernhard

of course: adding a submission class to the form itself will be the easier way instead of adding it to every field :). Maybe to less coffee this morning. Beside this topic: Thanks for pointing me to UIKit (you have mentioned in one of your emails that you use this framework). I have tested it and I find it much better than Bootstrap. Its also better to integrate with the form API of PW.

  • Like 1
Link to comment
Share on other sites

glad you like it. i think ryan likes it too, as the new demo page is also powered by uikit and the roadmap for 2016 (how fast did this year pass?!??) states, that the admin may get powered by uikit as well. really looking forward to that. https://processwire.com/blog/posts/happy-new-year-heres-a-roadmap-for-processwire-in-2016/

  • Like 2
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...