Archive

Posts Tagged ‘form’

Symfony Form: unsetAllFieldsExcept()

April 27th, 2009 Van de Voorde Toni 5 comments

When creating forms in symfony which extends from a Base (ORM) class, you sometimes do not need all fields that Propel/Doctrine generates for you. If you want to remove them you have several ways to do so.

1. Unset the fiels you don’t need.

public function configure() {
  unset($this['field1'], $this['field2'], ... );
}

Simple way to remove the fields you don’t want, but if you change something in your database, which has an impact on that form (new column, foreignkey, etc ), it will be added in the (generated) super class. And if you don’t update the unset function with that extra field, it will be expected in the form. Unless you have unit tests for all your forms this could brake it without knowing it.

2. Override the setup function.

/**
 * @override
 */
public function setup()
  {
    parent::setup();

    $this->setWidgets(...);

    $this->setValidators(...);
  }

Another way is to override the setup function and do your own widgets and validators initialization. This is a good way to only intialize the fields you really need, but you’ll have to do what your ORM generated for you.

3. Use a function which unsets all fields except the one you need (like the enableAllPluginsExcept function).

$this->unsetAllFieldsExcept(array(
      'field1',
      'field2',
      'field3',
      ...));

This would be usefull, because it will remove all fields you do not want to use, and even if new fields are added it will not use them. The drawback is that if you have 20 fields and only need to unset one of them, you’ll have more type work ;) .
Since it does not exist in symfony, I quickly created our own function. This function should be added in the class BaseFormPropel.class:

abstract class BaseFormPropel extends sfFormPropel
{
  public function setup() {
  }

  protected function unsetAllFieldsExcept($fields = array()) {

    $unsetFields = array_diff(array_keys($this->getWidgetSchema()->getFields()), $fields);

    foreach($unsetFields as $value) {
      unset($this[$value]);
    }
  }
}

Which one to use ?
None of them are better. But if you need to reset a majority of the fields the ORM has generated then I would go for the method 2. If you only need to unset the fields you do not want to use then I would use the function unsetAllFieldsExcept().

Which method do/would you use ?

Categories: General, Symfony, php Tags: , ,

sfWidgetFormInputCheckbox unchecked bug

April 23rd, 2009 Van de Voorde Toni 9 comments

Ever tried to create a Symfony form with a check box input field, which by default should be unchecked ? No ? Well read on because it’s not that easy :) .

This would be the code to print a check box input field in a Symfony form:

class CheckboxForm extends BaseCheckboxForm {
 public function configure() {
 $this->widgetSchema['field'] = new sfWidgetFormInputCheckbox();
 }
}

When you use the form to create something then by default the check box should be unchecked. And when you use this form for editing, then the check box should be checked if the object you try to edit has already been checked in the past.

If you try this code, you’ll see that the check box will always be checked. Even if you display this form to create a new object. Strange no ?

Read more…

Symfony Forms Framework: Merge 2 forms

March 19th, 2009 Van de Voorde Toni 22 comments

Recently I had to create a form to create/update users in our system. Some time ago we decided to save are users in 2 tables. The first table would contain all login information and the second his personal information. This is a simple example of the DB design:

User db design

User db design

I would not recommend doing this for so little fields. But in our system we have a lot more fields, and it helps us to optimize our queries.

Wouldn’t it be better if we could merge the 2 forms? The answer is yes. And it’s pretty easy to do so in Symfony … too bad that it’s not documented on the Symfony website.

Read more…

Symfony Forms Framework: Change validators at runtime.

February 15th, 2009 Van de Voorde Toni 1 comment

Let’s say you have to make a user form with password fields. When you create the user you want the password fields to be required, but on an update the password fields should be optional because you don’t want the user the fill in his password on each update.

This is tricky because in the symfony forms Framework you have to predefine your validators. Your form would look like this:

class UserForm extends BaseUserForm {

  public function configure() {
    // Widgets
    $this->widgetSchema['password'] = new sfWidgetFormInputPassword();
    $this->widgetSchema['password_again'] = new sfWidgetFormInputPassword();

    // Validators
    $this->validatorSchema['password']->setOption('required', false);
    $this->validatorSchema['password_again'] = clone $this->validatorSchema['password'];

    $this->widgetSchema->moveField('password_again', 'after', 'password');

    $this->mergePostValidator(new sfValidatorSchemaCompare('password', sfValidatorSchemaCompare::EQUAL, 'password_again', array(), array('invalid' => 'The two passwords must be the same.')));
  }

}

In this signature of the form I defined the password and password_again field as optional, which is correct for an update of the user, but incorrect for the creation of the user. How the hell can I change the validator of the password field when I create a user ?

Well thanks to the good and well designed framework of symfony it is very simple :) .

class UserForm extends BaseUserForm {

  public function configure() {
    // Widgets
    $this->widgetSchema['password'] = new sfWidgetFormInputPassword();
    $this->widgetSchema['password_again'] = new sfWidgetFormInputPassword();

    // Validators
    $this->validatorSchema['password']->setOption('required', false);
    $this->validatorSchema['password_again'] = clone $this->validatorSchema['password'];

    $this->widgetSchema->moveField('password_again', 'after', 'password');

    $this->mergePostValidator(new sfValidatorSchemaCompare('password', sfValidatorSchemaCompare::EQUAL, 'password_again', array(), array('invalid' => 'The two passwords must be the same.')));
  }

  public function bind(array $taintedValues = null, array $taintedFiles = null) {

    if ( $this->object->isNew() ) {
      $this->validatorSchema['password']->setOption('required', true);
    }

    parent::bind($taintedValues, $taintedFiles);
  }

}

What I did is override the function bind and before calling the bind method of the parent, I checked if the user object is new (means that we create a user) and if this is the case set the required option of the password field to true.

Categories: Framework, Symfony, php Tags: , ,

basic tips and tricks: 3.Forgotten form attributes

January 16th, 2009 van Rumste Kenneth No comments

A lot of people create easy forms but don’t think it trough before designing the page. I listed 5 useful attributes/elements a lot of people intend to forget or simply don’t know why they are using it.

Use get or post to send a form

Get will append the form data to the URL that is set in the action attribute of the form and is used when the form is idempotent. For example on search forms.
Post will not append it to the URL but sent it in the body of the form. It should be used when we are modifying a database or doing a subscription.

What is enctype?

This attribute is used to submit the form to the server; it is only needed when using post. Whenever you use a file field in your form you should set the enctype value to multipart/form-data, otherwise it uses the default value application/x-www-form-urlencoded.

Use tabindex

This creates an order when going from one field to the next using your tab button. When creating complex forms, this might come in quite handy. It creates the opportunity for the developer to indicate the order the form needs to be completed. Every field in the form gets a ‘tabindex’ value starting from 0 with a maximum of 32767.

Connect a label to a field

It’s always handy to have a label for each input field, so you can click on the label and the cursor automatically gets positioned in the input field. The only thing to do is put a ‘for’ attribute in the label and give it the id of the corresponding field as value. Easy and Handy for users

Fieldset and legend

This allows you to thematically group your form elements. The ‘legend’ element gives you the opportunity to create a title on each fieldset and has to be put in between the fieldset tags. Use css styling to create a nice design for the fieldset.

Greetings K.

3 tips when using jQuery

September 29th, 2008 van Rumste Kenneth No comments

AjaxForm or ajaxSubmit

This plug-in provides numerous options you can call to manage your form before and after submission and all this in AJAX. More info on http://malsup.com/jquery/form/

Live Query

When an element is loaded into a page, you will not be able to use the events on this element. But when the Live Query is used, this magically appears to work… This is because the Live Query binds events of elements together every few milliseconds and does a DOM (Document Object Model) update. A really cool plug-in that creates the possibility for web developers to execute events without reloading the page every time an element is clicked. The only disadvantage of live query is the fact that it appears to slow down the execution time a bit, but when you don’t have to reload your page each time, I guess it’s worth the usage. More info on http://brandonaaron.net/docs/livequery/

JSON (JavaScript Object Notation)

In our case we are using JSON as response-type from an AJAX request. This is a sort of XML but a lot easier to read, especially when you work with a lot of data. For more information on JSON visit http://json.org/ or http://borkweb.com/story/the-case-for-json-what-is-it-and-why-use-it

Categories: Javascript, Jquery Tags: , , , , , ,