Zend Form Registration with - forms

I am new in Zend.
I have tried to create registration form in Zend.
I have get an array of form but it return false.
It returns me every time bye .
I don't know why???

It's Simple:
First, create your registration form under application/forms or use zend tool
zf enable form
zf create form registration
this will create a file under application/forms entitled Registration.php
class Application_Form_Registration extends Zend_Form
{
public function init()
{
$firstname = $this->createElement('text','firstname');
$firstname->setLabel('First Name:')
->setRequired(false);
$lastname = $this->createElement('text','lastname');
$lastname->setLabel('Last Name:')
->setRequired(false);
$email = $this->createElement('text','email');
$email->setLabel('Email: *')
->setRequired(false);
$username = $this->createElement('text','username');
$username->setLabel('Username: *')
->setRequired(true);
$password = $this->createElement('password','password');
$password->setLabel('Password: *')
->setRequired(true);
$confirmPassword = $this->createElement('password','confirmPassword');
$confirmPassword->setLabel('Confirm Password: *')
->setRequired(true);
$register = $this->createElement('submit','register');
$register->setLabel('Sign up')
->setIgnore(true);
$this->addElements(array(
$firstname,
$lastname,
$email,
$username,
$password,
$confirmPassword,
$register
));
}
}
This is a simple form with limited validation (only validation for fields that are required!)
Then you have to render the form in a view using the corresponding action:
as example in your UserController add action called
public function registerAction() {
//send the form to the view (register)
$userForm = new Application_Form_Registration();
$this->view->form = $userForm;
//check if the user entered data and submitted it
if ($this->getRequest()->isPost()) {
//check the form validation if not valid error message will appear under every required field
if ($userForm->isValid($this->getRequest()->getParams())) {
//send data to the model to store it
$userModel = new Application_Model_User();
$userId = $userModel->addUser($userForm->getValues());
}
}
}
The last two, is to render the form in the view called register
using
<?= $this->form ?>
and add method in your model called addUser() to handle the insertion of data into the database

Related

Compare two fields to see if they match

I'm trying to think of the best way to approach validating two emails fields for a form: I have an email field and a retype email field, and I want to compare them to see if they match. If not then display an error message saying so until the user enters in their email correctly for both fields.
I know there can be custom fields classes made to allow for custom validation but I'm using 2 separate fields, not one, and I'm not sure a custom class will work in this case since I'm not validating just one field.
I followed the example found here which involves adding custom validation to the form's submit function: https://docs.silverstripe.org/en/3/developer_guides/forms/validation/
However, I don't want to redirect anywhere -- I want to stay on the form.
I'd like to make this as simple as possible if I can help it.
Here is what I have so far. Other than the issue I mentioned, everything else works fine:
public function DemoForm() {
$fieldsArr = array();
$firstName = new TextField('first_name', 'First Name');
$firstName->setAttribute('placeholder', 'First Name');
array_push($fieldsArr, $firstName);
$lastName = new TextField('last_name', 'Last Name');
$lastName->setAttribute('placeholder', 'Last Name');
array_push($fieldsArr,$lastName);
$companytName = new TextField('company_name', 'Company Name');
$companytName->setAttribute('placeholder', 'Company Name');
array_push($fieldsArr,$companytName);
$email = new EmailField('email', 'Email');
$email->setAttribute('placeholder', 'Email');
array_push($fieldsArr, $email);
$retypeemail = new EmailField('retype_email', 'Retype Email');
$retypeemail->setAttribute('placeholder', 'Retype Email');
array_push($fieldsArr, $retypeemail);
$fields = new FieldList($fieldsArr);
$actions = new FieldList(
new FormAction('submit', 'Submit')
);
$validator = new RequiredFields('first_name', 'last_name', 'email', "retype_email");
return new Form($this, 'DemoForm', $fields, $actions, $validator);
}
public function submit($data, $form) {
if($data['email'] != $data['retype_email']){
$form->addErrorMessage('Email', 'The emails do not match.', 'bad');
return $this->redirectBack();
}
else{
$demoRequest = new DemoFormSubmission();
$demoRequest->FirstName = $data['first_name'];
$demoRequest->LastName = $data['last_name'];
$demoRequest->EmailAddress =$data['email'];
$demoRequest->CompanyName = $data['company_name'];
$demoRequest->write();
$email = new Email();
$email->setTo('sara.dejaneiro#innismaggiore.com');
$email->setFrom($data['email']);
$email->setSubject("Demo request submission");
$messageBody = "
<p><strong>First Name:</strong> {$data['first_name']}</p>
<p><strong>Last Name:</strong> {$data['last_name']}</p>
<p><strong>Email: </strong> {$data['email']}</p>
<p><strong>Company Name:</strong> {$data['company_name']}</p>
";
$email->setBody($messageBody);
$email->send();
return $this->redirect("demo-request-submission-thank-you-page");
}
}
Given your reply to my comment, I think you would probably be best to either:
Create your own form field that extends CompositeField and then add a custom validate function (as per https://docs.silverstripe.org/en/3/developer_guides/forms/validation/#form-validation)
Creating a custom validator, by extending RequiredFields (https://github.com/silverstripe/silverstripe-framework/blob/3.6.2/forms/RequiredFields.php) and then overloading the PHP method (https://github.com/silverstripe/silverstripe-framework/blob/3.6.2/forms/RequiredFields.php#L82).
Number 2 might be the less fiddly approach. You can write your own custom logic and then if the validation fails simply return "false" and then SilverStripe will cancel form submission and return the user to the form with their data still in the form fields.

Zend_Form_Element requires each element to have a name

I'm trying to create a form in ZF 1.Here's my form class
class Application_Form_Album extends Zend_Form
{
public function init()
{
$this->setName('album');
#artist
$artist = new Zend_Form_Element_Text('artist');
$artist->setLabel('Artist')->setRequired(true)->addValidator('NotEmpty');
#title
$title = new Zend_Form_Element_Text('title');
$title->setLabel('Title')->setRequired(true)->addValidator('NotEmpty');
#submit
$submit = new Zend_Form_Element_Submit();
$submit->setAttribute('id','submitbutton');
$this->addElements(array($artist,$title,$submit));
}
}
and my controller action
public function addAction()
{
$form = new Application_Form_Album();
$form->submit->setLabel('Add');
$this->view->form = $form;
}
and my add.phtml
<?php echo $this->form;?>
But I'm getting this error.
Message: Zend_Form_Element requires each element to have a name
Not sure what I missed.Could anyone help me?
You should give a name for each form element. Missing name of submit. Zend Form generate id and name html tags from given name
For example:
$submit = new Zend_Form_Element_Submit('submitbutton');
And remove
$submit->setAttribute('id','submitbutton');
line.

How to implement data model with this code

I am new to zend frame work . I am trying to learn zf create db-table tblename,zf create model tblname,zf create model tblnameMapper.
add user.php (form)
<?php
class Application_Form_Adduser extends Zend_Form
{
public function init()
{
$this->setMethod('post');
$username = $this->createElement('text','username');
$username->setLabel('Username:')
->setAttrib('size',10);
$password=$this->createElement('text','password');
$password->setLabel('Password')
->setAttrib('size',10);
$reg=$this->createElement('submit','submit');
$reg->setLabel('save');
$this->addElements(array(
$username,
$password,
$reg
));
return $this;
}
add user view:
<?php
echo 'Add user';
echo "<br />" .$this->a;
echo $this->form;
?>
admin controller:
<?php
class AdminController extends Zend_Controller_Action
{
public function adduserAction(){
$form = new Application_Form_Auth();
$this->view->form = $form;
$this->view->assign('a','Entere new user:');
if($this->getRequest()->isPost()){
$formData = $this->_request->getPost();
$uname=$formData['username'];
$pass=$formData['password'];
$msg=$uname." added to database successfully";
$this->view->assign('a',$msg);
$db= Zend_Db_Table_Abstract::getDefaultAdapter();
$query="INSERT INTO `user` ( `id` , `uname` , `password` )
VALUES ('', '{$uname}', '{$pass}');";
$db->query($query);
}}
i want to implement db-table with the above code .i am new to zend frame work i spend some time on reading programmers guide but in vain .It is very hard to get things from manual.So please some one explain step by step procedure for implementing the same .Thanks in advanced.
Ok here is a quick example:
Create DbTable Model (Basically an adapter for each table in your database):
at the command line: zf create db-table User user add -m moduleName if you want this in a module. This command will create a file name User.php at /application/models/DbTable that looks like:
class Application_Model_DbTable_User extends Zend_Db_Table_Abstract {
protected $_name = 'user'; //this is the database tablename (Optional, automatically created by Zend_Tool)
protected $_primary = 'id'; //this is the primary key of the table (Optional, but a good idea)
}
now to create a method in your DbTable model that executes the query from your controller, add a method similar to:
public function insertUser(array $data) {
$Idata = array(
'name' => $data['name'] ,
'password' => $data['passowrd']
);
$this->insert($Idata); //returns the primary key of the new row.
}
To use in your controller:
public function adduserAction(){
$form = new Application_Form_Auth(); //prepare form
try{
if($this->getRequest()->isPost()){//if is post
if ($form->isValid($this->getRequest()_>getPost()){ //if form is valid
$data = $form->getValues(); //get filtered and validated form values
$db= new Application_Model_DbTable_User(); //instantiate model
$db->insertUser($data); //save data, fix the data in the model not the controller
//do more stuff if required
}
}
$this->view->form = $form; //if not post view form
$this->view->assign('a','Entere new user:');
} catch(Zend_Exception $e) { //catach and handle exception
$this->_helper->flashMessenger->addMessage($e->getMessage());//send exception to flash messenger
$this->_redirect($this->getRequest()->getRequestUri()); //redirect to same page
}
}
This is about as simple as it gets. I have barely scratched the surface of what can be accomplished in simple applications with Zend_Db and a DbTable model. However you will likely find as I have, that at some point you will need more. That would be the time to explore the domain model and mappers.
For a really good basic tutrial that includes all of this and more please check out Rob Allen's ZF 1.x tutorial
I hope this helps.

Validate a set of fields / group of fields in Zend Form

Is there any good solution for the following requirements:
A form with one field for zip code and default validators like number, length, etc.
After submission, the form is checked against a database.
If the zip code is not unique we have to ask for an city.
Examples:
Case 1: Submited zip code is unique in database. Everything is okay. Process form
Case 2: Submited zip code is not unique. Add a second field for city to the form. Go back to form.
We want to handle this in an generic way (not inside an controller). We need this logic for
a lot of forms. First thought was to add it to isValid() to every form or write a
validator with logic to add fields to the form. Subforms are not possible for us, because we need this for different fields (e.g. name and street).
Currently I'm using isValid method inside my forms for an User Form to verify the password and confirm password field. Also, when the form is displayed in a New Action, there are no modifications, but when displayed in an Edit Action, a new field is added to the form.
I think that is a good option work on the isValid method and add the field when the validation return false, and if you want something more maintainable, you should write your own validatator for that purpose.
Take a look at my code:
class Admin_Form_User extends Zf_Form
{
public function __construct($options = NULL)
{
parent::__construct($options);
$this->setName('user');
$id = new Zend_Form_Element_Hidden('id');
$user = new Zend_Form_Element_Text('user');
$user->setLabel('User:')
->addFilter('stripTags')
->addFilter('StringTrim')
->setAllowEmpty(false)
->setRequired(true);
$passwordChange = new Zend_Form_Element_Radio('changePassword');
$passwordChange->setLabel('Would you like to change the password?')
->addMultiOptions(array(1 => 'Sim', 2 => 'Não'))
->setValue(2)
->setSeparator('');
$password = new Zend_Form_Element_Password('password');
$password->setLabel('Password:')
->addFilter('stripTags')
->addFilter('StringTrim')
->setRequired(true);
$confirm_password = new Zend_Form_Element_Password('confirm_password');
$confirm_password->setLabel('Confirm the password:')
->addFilter('stripTags')
->addFilter('StringTrim')
->addValidator('Identical')
->setRequired(true);
$submit = new Zend_Form_Element_Submit('submit');
$submit->setLabel('Save');
$this->addElements(array($id,$name,$lastname,$group,$user,$passwordChange,$password,$confirm_password,$submit));
$this->addDisplayGroup(array('password','confirm_password'),'passwordGroup');
$this->submit->setOrder(8);
$this->setDisplayGroupDecorators(array(
'FormElements',
array('HtmlTag', array('tag' => 'div','id' => 'div-password'))
)
);
$passwordChange->clearDecorators();
}
public function addPasswordOption()
{
$this->changePassword->loadDefaultDecorators();
$this->getDisplayGroup('passwordGroup')
->addDecorators(array(
array('HtmlTag', array('tag' => 'div','id' => 'div-password'))
)
);
$this->password->setRequired(false);
$this->confirm_password->setRequired(false);
}
public function setPasswordRequired($flag = true)
{
$this->password->setRequired($flag);
$this->confirm_password->setRequired($flag);
}
public function isValid($data)
{
$confirm = $this->getElement('confirm_password');
$confirm->getValidator('Identical')->setToken($data['password']);
return parent::isValid($data);
}
}
So, in my controller:
public function newAction()
{
$this->view->title = "New user";
$this->view->headTitle($this->view->title, 'PREPEND');
$form = $this->getForm();
if($this->getRequest()->isPost())
{
$formData = $this->_request->getPost();
if($form->isValid($formData))
{
$Model = $this->getModel();
$id = $Model->insert($formData);
$this->_helper->flashMessenger('The user data has beed updated.');
$this->_helper->redirector('list');
}
}
$this->view->form = $form;
}
public function editAction()
{
$this->view->title = "Edit user";
$this->view->headTitle($this->view->title, 'PREPEND');
$id = $this->getRequest()->getParam('id');
$form = $this->getForm();
// Add yes or no password change option
$form->addPasswordOption();
$Model = $this->getModel();
if($this->getRequest()->isPost())
{
$formData = $this->getRequest()->getPost();
// Change password?
if($formData['changePassword'] == 2) $form->setPasswordRequired(false);
if($form->isValid($formData))
{
$Model->update($formData);
$this->_helper->flashMessenger('The user data has beed updated.');
$this->_helper->redirector('list');
}
}
$data = $Model->getById($id)->toArray();
$form->populate($data);
$this->view->form = $form;
}
You will probably need a Javascript form validator for that. In the submit function perform an AJAX call to check if the zipcode is unique. If not, show an extra city field.
But you still have to perform the validation server side: never trust user input, even if it's validated on the client side.

Extending Zend_View_Helper_FormElement

I have created this file at My/View/Helper/FormElement.php
<?php
abstract class My_View_Helper_FormElement extends Zend_View_Helper_FormElement
{
protected function _getInfo($name, $value = null, $attribs = null,
$options = null, $listsep = null
) {
$info = parent::_getInfo($name, $value, $attribs, $options, $listsep);
$info['id'] = 'My new ID';
return $info;
}
}
How can i get the normal form elements to use this instead?
Why i want this?
Say that i use the same form multiple times on a page, the 'id='-tag of the formelements will apear multiple times, this is not w3c-valid. So initially i want to prefix the id with the id of the form.
Any better ideas or ways to do this is much apreciated.
Update: Just realized it's the same problem with the decorators :( Don't think this is the right path i've taken.
Create new form class extending Zend_Form and in the init() method use variable $ns to add prefix/suffix to all elements. You can set $ns variable through form constructor.
class Form_Test extends Zend_Form
{
protected $ns;
public function init()
{
$this->setAttrib('id', $this->ns . 'testForm');
$name = new Zend_Form_Element_Text('name');
$name->setAttrib('id', $this->ns . 'name');
$name->setLabel('Name: *')->setRequired(true);
$submit = new Zend_Form_Element_Submit('submit');
$submit->setAttrib('id', $this->ns . 'submitbutton');
$submit->setLabel('Add')->setIgnore(true);
$this->addElements(array($name, $submit));
}
public function setNs($data)
{
$this->ns = $data;
}
}
In the controller or wherever you are calling this forms specify each form instance:
$form1 = new Form_Test(array('ns' => 'prefix1'));
$this->view->form1 = $form1;
$form2 = new Form_Test(array('ns' => 'prefix2'));
$this->view->form2 = $form2;
// Validation if calling from the controller
if ($form1->isValid()) ...
Using multiple instances of same forms on a page can be validated if used as subform.
SubForms prefix all id's with the name/identifier of the subform.