Jump to content

Create simple forms using API


Soma

Recommended Posts

Double/triple checked. Images do not resize based on max width / max height of field.

However, it does work to resize image after it is added to the field and the page is saved.

$user_image = $user->images->first();
$newSize = new ImageSizer($user_image->filename);

if ($user_image->width >= $user_image->height){
    $newSize->setUpscaling(false)->resize(1200,0);
}else if ($user_image->height >= $user_image->width){
    $newSize->setUpscaling(false)->resize(0,1200);} 

This will conditionally resize the image (based on orientation) and turns upscaling off.

Link to comment
Share on other sites

Yeah this should work. 

I figured out how you could add a image and get resized with the InputfieldImage you have.

Having this as setting 

$field->maxWidth = 100;
$field->maxHeight = 100;
 
Then when adding the image to page field:
// create new page image first
$img = new PageImage($uploadpage->images, $upload_path . $file); 

// add it to page as usual
$uploadpage->images->add($img); 

// trigger the image max size sizing
$form->get("images")->fileAdded($img); 
  • Like 4
Link to comment
Share on other sites

This has been extremely helpful for both learning the framework and php in general. I was hoping someone could help explain a few things in further detail as I am really new to Processwire and somewhat new to php other the working with WordPress. I have used Soma's code example which is extremely useful and altered it to my needs. I am attempting to create a simple contact form, but was unsure of a few things. 

Below, she provides a validation check for any hotmail addresses. Are there any other validations required or suggested if you are planning on having the submissions emailed to you? IE, check if is a valid email address with FILTER_VALIDATE_EMAIL or is this done for you

$email = $form->get("email");
    if($email && (strpos($email->value,'@hotmail') !== FALSE)){
        // attach an error to the field
        // and it will get displayed along the field
        $email->error("Sorry we don't accept hotmail addresses for now.");
    }
 

Secondly, any tips on how I would send the values submitted by email to the admin user or any user/email?

$email = $form->get("email")->value;
$name = $form->get("name")->value;
$name = $form->get("text")->value;
 

Thanks in advance for the community support and I am looking forward to working more with Processwire. The form builder is on my to get list and will same me hours of time, but I thought understanding the inside of it will benefit me more. 

Although I would still like to understand the above, I went with a similar solution others may find usefull here

Edited by RJay
Link to comment
Share on other sites

Below, she provides a validation check for any hotmail addresses. Are there any other validations required or suggested if you are planning on having the submissions emailed to you? IE, check if is a valid email address with FILTER_VALIDATE_EMAIL or is this done for you

InputfieldEmail does this validation for you. 

Secondly, any tips on how I would send the values submitted by email to the admin user or any user/email?

PHP's built-in mail() function makes this pretty simple:

$body = "This is the message body";
$subject = "Web Contact";
$emailFrom = $form->get('email')->value; 
$emailTo = 'you@domain.com';

mail($emailTo, $subject, $body, "From: $emailFrom"); 
  • Like 2
Link to comment
Share on other sites

  • 2 weeks later...

Hmm — I figured as much.

What do you do for forms that need to create (and edit) repeaters?

I have a half baked idea:

foreach($pages->get("/config/expense-types/")->children() as $cat) {
   	$fieldset = $modules->get("InputfieldFieldset");
	$fieldset->label = "Expense Type";

	$field = $modules->get("InputfieldText");
	$field->label = $cat->title;
	$field->value = $cat->title;
	$field->attr("name+id",$cat->title);
	$fieldset->add($field);
	
	$field = $modules->get("InputfieldText");
	$field->label = "amount";
	$field->attr("name+id",$cat."-amount");
   	$fieldset->add($field);
	
	$form->add($fieldset);
}

That would create required inputs for all the possible expense types.

I think I can sort out how to foreach() the $input->post(s) and save them to repeaters.

Not sure how I would pull up the page and edit the repeaters, especially if they need to add new ones?

Am I making any sense?

Link to comment
Share on other sites

I think I can sort out how to foreach() the $input->post(s) and save them to repeaters.

Looks like you are on the right track there. As for the field name and/or id, I'm guessing you don't want to use the title though. In order to make sure you've got something unique, you might want to use "myfield{$cat->id}" or something like that. 

Not sure how I would pull up the page and edit the repeaters, especially if they need to add new ones?

If you don't need to support images/files in repeaters, then it won't be too difficult. You would add one or more repeater items at the end, but make them hidden or collapsed. You could have a little javascript link that says "add item" and when clicked, it unhides the next one. Make the fields in each follow a different name format, like "myfield_new1" for the first one, "myfield_new2" for the second one, etc. Basically, some name format that your processor would know is referring to a new item it should add. Then it could process them like this:

$n = 1; 
$name = "myfield_new$n";
while($input->post->$name) {
  $item = $mypage->myrepeater->getNewItem()
  // populate any fields in the repeater you want 
  $item->title = $input->post->$name; 
  $item->save();
  $mypage->myrepeater->add($item); 
  $n++; 
  $name = "myfield_new$n";
}
if($n > 1) $mypage->save('myrepeater');  
  • Like 2
Link to comment
Share on other sites

Just hitting my head to a wall with this:

I have defined a field like this:

$field = $modules->get("InputfieldRadios");
$field->label = "Gender";
$field->addOption('girl', 'Girl');
$field->addOption('boy', 'Boy');
$field->attr("name+id",'gender');
$form->append($field); 

and try to save the field after submit with this:

$form->processInput($input->post);
$uploadpage = new Page();

$uploadpage->gender = $form->gender->value;
//OR 
$uploadpage->set($form->gender->name, $form->gender->value);

But it doesn't save the field value. With Ryans FormTemplateProcessor module this template works, but trying to do the "dirty work" manually, I just can't get radiobuttons or checkboxes to save. 

What is it that I don't understand here?

EDIT:

OK, Soma helped me on IRC:

Change 

$field->addOption('girl','Girl');

to this:

$gender = $pages->get("/options/gender/")->children();
foreach ($gender as $p) {
    $field->addOption($p->id,$p->title);
}

This is because I am using pages as options. Then save the field like this:

$uploadpage->set($form->gender->name, $form->gender->value);

Thanks to Soma!

  • Like 3
Link to comment
Share on other sites

Is it possible to add additional markup?

I need to have a group of fields display in a tabular format.

You can use the InputfieldMarkup to add custom markup.

$field = $modules->get("InputfieldMarkup");
$field->markupText = "<p>your html string here</p>";
  • Like 5
Link to comment
Share on other sites

  • 4 weeks later...
Hi everyone, is it possible to show inputfieldSelect with custom values, 

p.e. i want to search events by current date and get only evetns that they have not closed.

event 1 date: 13/5/2013 time: 9:00

event 2 date: 13/5/2013 time: 9:30

event 3 date: 13/5/2013 time: 10:30

so i want a select input filed with values like

8:00

8:30  // 9:00 until 10:00 is existing events from above

10:00 // 10:30 is existing event from above so go to 11

11:00

11:30

etc

is difficult for me to explained, i hope you have understand.

this is what i have until now, but i cant implemented inside form..


$today = strtotime( date('Y-m-d'));
$day_end = strtotime( "23:59:59" );

$searchDate = wire('pages')->get('/orders/')->children("date>=$today, date<=$day_end");

foreach ($searchDate as $s) {
$currentTime = substr($s->date,11,5) ;
$closedTimes[] = $currentTime;

}
echo "<select>";
$orders= $closedTimes;
$start = "08:00";
$end = "15:00";

$tStart = strtotime($start);
$tEnd = strtotime($end);
$tNow = $tStart;

while ($tNow <= $tEnd) {
$newdate = date("H:i", $tNow);
if (in_array($newdate, $orders)) {
echo "something";
}

else {
echo "<option value='time'>" .date("H:i", $tNow). "</option>";
}
$tNow = strtotime('+30 minutes', $tNow);
}
echo "</select>";

}
Link to comment
Share on other sites

This is as simple as:

$field = $modules->get("InputfieldSelect");
$field->attr("name", "myselect");
$field->addOption("myoption1", "My Option 1");
$field->addOption("myoption2", "My Option 2");
  • Like 5
Link to comment
Share on other sites

hi,  can i have some help please;
every time I save the form as page, with random date selected,  page saves the current day,
 
this is my code
$out = '';
$form = $modules->get("InputfieldForm");
$form->action = "./";
$form->method = "post";
$form->attr("id+name",'subscribe-form');
 
$field = $modules->get("InputfieldText");
$field->label = "Ονοματεπώνυμο";
$field->attr('id+name','name');
$field->required = 1;
$form->append($field); // append the field to the form
 
$field = $modules->get("InputfieldEmail");
$field->label = "E-Mail";
$field->attr('id+name','email');
$field->required = 1;
$form->append($field); // append the field

$field = $modules->get("InputfieldDatetime");
$field->label = "Ημ/νια";
// $field->value = $input->post->date;
$field->attr("id+name","datetime");
// $field->attr("readonly", "readonly");
$field->required = 1;
$form->append($field);

$field = $modules->get("InputfieldSelect");
$field->label = "Ώρα";
$field->attr("id+name","time");

$ttoday = strtotime(date('Y/m/d'));
$tday_end = strtotime( "23:59:59" );    
$searchDate = wire('pages')->get('/orders/')->children("date>=$ttoday, date<=$tday_end");
foreach ($searchDate as $s) {
    $currentTime = substr($s->date,11,5);
    $closedTimes[] = $currentTime;
}
$random = $closedTimes;
$start = "08:00";
$end = "15:00";
$tStart = strtotime($start);
$tEnd = strtotime($end);
$tNow = $tStart;
while ($tNow <= $tEnd) {
    $newdate = date("H:i", $tNow);
    if (in_array($newdate, $random)) {  
    }
    else {
    $dateTnow = date("H:i", $tNow);
     $dates[] =  $dateTnow;
}
    $tNow = strtotime('+30 minutes', $tNow);
}
foreach ($dates as $d) {
   $field->addOption($d,$d);
}
$field->required = 1;
$form->append($field);

$field = $modules->get("InputfieldText");
$field->label = "Τηλέφωνο";
$field->attr('id+name','phone');
$field->required = 1;
$form->append($field); // append the field to the form

$submit = $modules->get("InputfieldSubmit");
$submit->attr("value","ΟΚ");
$submit->attr("id+name","submit");
$form->append($submit);
if($input->post->submit) {
    $form->processInput($input->post);
 
    $email = $form->get("email");
    if($email && (strpos($email->value,'@hotmail') !== FALSE)){
        // attach an error to the field
        // and it will get displayed along the field
        $email->error("Sorry we don't accept hotmail addresses for now.");
    }
 
    if($form->getErrors()) {
        // the form is processed and populated
        // but contains errors
        $out .= $form->render();
    } else {
 

         $sName = $form->get("name")->value;
         $sEmail = $form->get("E-Mail")->value;
         $sDate = $form->get("datetime")->value;
         $sTime = $form->get("time")->value;
         $tr = new Page();
         $tr->template = $templates->get("order");
        $tr->parent = $pages->get("/orders/");

  $sEmail = $sanitizer->email($form->get("email")->value);
  // $sDate  = $sanitizer->datetime($form->get("datetime")->value);

        $tr->of(false);
        $tr->name = $sName;
        $tr->title = $sName;
        $tr->body = $sEmail;
        $tr->date =  strtotime('d/m/Y',$sDate).' '.$sTime;
        $tr->time =  $sTime;
        $tr->save();

        $out .= " $name> ";

    }
 
} else {
    // render out form without processing
    $out .= $form->render();
    }

Link to comment
Share on other sites

  • 3 weeks later...

Hi Soma,

I think I'm moving beyond the "simple forms" portion of this topic. 

I'm trying to figure out how to delete files using this method.

I can get a list of the current files to show using $field->value

But can't seem to get my head around how to process the delete()

$field = $modules->get("InputfieldFile");
$field->label = "Attached Files";
$field->required = 0;
$field->value = $p->files;
$field->attr("name+id",'pagefiles');
$field->destinationPath = $upload_path;
$field->extensions = "doc docx pdf xls xlsx png";
$form->add($field);

I see that each file has a checkbox associated, but not sure how to use that to delete the correct file.

<input type="checkbox" name="delete_pagefiles_f86ba9c52a4f9cf4f81c3b8cf22fb6dd" value="1">

Can you nudge me in the right direction?

:)

Link to comment
Share on other sites

hi,  can i have some help please;
every time I save the form as page, with random date selected,  page saves the current day,
 
this is my code
...

Sorry, I think I missed this or ignored it because it's very hard to decifer your code and with very little initiative from you trying to find out. :)

You may already have solved it but after taking a short look at the code I think I found something

$field->addOption($d,$d);

I think the problem is that the $d is a formated date string? Maybe the value (first argument) should be a timestamp... or at least converted to timestamp before assigning to the $page->time. 

Hi Soma,

I think I'm moving beyond the "simple forms" portion of this topic. 

Can you nudge me in the right direction?

:)

You know that's lots of beer there?

  • Like 1
Link to comment
Share on other sites

Hi all,

i have some trouble trying to do a form on front-end that insert a page of a specific template. In fact the fields are created automagically :) but when i submit the form, PW throws me an error like: "New page '//' must be saved before files can be accessed from it [...]".

It seems that the files cannot be saved before the page is created. I'm right ? There is a workaround for this ?

This is my code:

$form = $this->modules->get("InputfieldForm");
                        $curriculum = new Page();
                        $curriculum->template = "curriculum";

                        // get all the fields of template "curriculum"
                        $fields = $templates->get('curriculum')->fields;

                        // we add also the submit
                        $submit = $modules->get("InputfieldSubmit");
                        $submit->attr("value","Invia");
                        $submit->attr("id+name","submit");

                        foreach ($fields as $key => $field) {
                            // We must have the Inputfield instance, not the Field.
                            $form->append($field->getInputField($curriculum));
                        }

                        $form->append($submit);

                        if( $input->post->submit ):

                            // validate the form
                            $form->processInput($input->post);

                            // Check if there are some errors
                            if( $form->getErrors() ):

                                echo $form->render();

                            else:

                                $curriculum->title = $form->get('nome')->value;
                                $curriculum->parent = $pages->get('/curriculum/')->id;
                                $curriculum->save();
                                foreach( $fields as $field ):
                                    // now we save all the fields.
                                    $curriculum->set( $field->name, $form->get($field->name)->value );

                                endforeach;
                                $curriculum->save();

                            endif;

                        else:

                          echo $form->render();

                        endif;
Link to comment
Share on other sites

Soma,

Haha. So it's complicated then eh?

How much beer are we talking? 

No it's only as complicated as you make it :P

A ship full of.

This might work....

Its name is "delete_fieldname_hash" and this is how PW does process it

$id = $this->name . '_' . $pagefile->hash;
...
if(isset($input['delete_' . $id])) {
     $this->processInputDeleteFile($pagefile); 
     $changed = true; 
}

So I think you can simply loop the pagefiles you have on page and create the id as above and check for if any checkbox is set and delete the file.

foreach($page->pagefiles as $file) {
    $id = "pagefiles" . "_" . $file->hash;
    if(isset($input["delete_" . $id)) { 
        $page->pagefiles->delete($file);
    }
}
Link to comment
Share on other sites

Hi all,

i have some trouble trying to do a form on front-end that insert a page of a specific template. In fact the fields are created automagically :) but when i submit the form, PW throws me an error like: "New page '//' must be saved before files can be accessed from it [...]".

It seems that the files cannot be saved before the page is created. I'm right ? There is a workaround for this ?

The error says exactly what you have to do: Save the page before files can be accessed...

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...