How to customize the form display with embedded i18n?

Discussion relating to version 1.3.x and 1.4.x

How to customize the form display with embedded i18n?

Postby zaktrak » Fri Sep 07, 2012 10:20 pm

I am using symfony 1.4.18 with doctrine. I am familiar with symfony 1.0 and propel, but now I am working on a new project in 1.4.

The forms "sub-framework" has been my greatest hurdle with using sf 1.4. I am attempting to embed the i18n form in the main form and customize the display of the form on the page. If I just use <?php echo $form ?>, then I have no problems... it saves to the database fine, but if I try to customized the display it seems it is no longer treated as one object. I'm sure this is rather simple and straightforward, as it seems like a common requirement, but for the life of me I cannot figure it out. Any help would be greatly appreciated.

I have an internationalized model:
Code: Select all
Table1:
  actAs:
    Timestampable: ~
    I18n:
      fields:           [name, description]
  columns:
    name:               { type: string(255), notnull: true }
    description:        { type: string(1000) }
    is_public:          { type: boolean, default: 1 }


Below is my Table1Form.class.php
Code: Select all
class Table1Form extends BaseTable1Form
{
  public function configure()
  {
     $this->embedI18n($this->getCurrentCulture());
  }
 
  public function getCurrentCulture()
  {
    return isset($this->options['culture']) ? explode(',',str_replace(' ', '', $this->options['culture'])) : array('en');
  }
}


in my Action:
Code: Select all
$this->form = new Table1Form(null, array('culture'=> 'en,es'));
  if($request->isMethod('post')){
      $this->form->bind($request->getParameter('table1'));
      if($this->form->isValid()){
         $table1 = $this->form->save();
         $this->redirect($url.'?id='.$table1->getId());
      }
  }


If I use the following piece of code, it all works fine:
Code: Select all
<table><?php echo $form?>
   <tr>
      <td><input type="submit" /></td>
   </tr>
</table>


But this is not very flexible, so I tried this:
Code: Select all
<?php echo $form->renderFormTag('/table1/create')?>
   <?php echo $form->renderHiddenFields()?>
   <?php foreach ($form->getEmbeddedForms() as $i18n){?>
      <div class="form_row">
         <?php echo $i18n['name']->renderLabel()?><?php echo $i18n['name']->renderError()?>
         <div><?php echo $i18n['name']->render()?></div>
      </div>
      <div class="form_row">
         <?php echo $i18n['description']->renderLabel()?><?php echo $i18n['description']->renderError()?>
         <div><?php echo $i18n['description']->render()?></div>
      </div>
   <?php }?>
   <div class="form_row">
      <?php echo $form['is_public']->renderLabel()?><?php echo $form['is_public']->renderError()?>
      <div><?php echo $form['is_public']->render()?></div>
   </div>
   <button type="submit" class="button"><?php echo __('Next')?></button>
</form>


The form looks great now and I can apply my css, but now it no longer binds correctly. Perhaps there is another way to loop through the embeded forms. When I customize the form this way, the name of the "name" input field is - name="table1_translation[name]", instead of - name="table1[en][name]" as it should be (and is if I just use <?php echo $form ?>). What am I doing wrong? How can I preserve this nested structure of the request parameters so I can retrieve them and bind them properly with $this->form->bind($request->getParameter('table1'));

Thanks for your help!!
zaktrak
Member
 
Posts: 32
Joined: Thu Jun 26, 2008 12:21 am

Re: How to customize the form display with embedded i18n?

Postby smugford » Sat Sep 08, 2012 8:59 am

The forms sub frame work is crazy to learn at first. The simplest things seem to be so complicated. Until you try to do the same things from scratch then they don't seem so bad in comparison.

Go over the Advanced Forms section in the More with Symfony Book.

It explains with a working example exactly what you are trying to do.

http://www.symfony-project.org/more-with-symfony/1_4/en/06-Advanced-Forms

I'm sorry I can't give you an exact answer but your solution lies somewhere in that chapter of the book.
User avatar
smugford
Faithful Member
 
Posts: 205
Joined: Sun Nov 29, 2009 8:32 pm

Re: How to customize the form display with embedded i18n?

Postby smugford » Sat Sep 08, 2012 10:00 am

i just went through my version of the photo code.

it may be the browser cache and the crsf token. I viewed my source because mine wasn't working and the csrf token had no value until it CTRL+f5'd

this little snippet will help you track down form errors when customizing forms.
Code: Select all
            <?php if( $form->hasErrors() || $form->hasGlobalErrors() ) : ?>
                <?php $errors = $form->getErrorSchema()->getErrors() ?>
                <?php if ( count($errors) > 0 ) : ?>
                    <?php foreach( $errors as $name => $error ) : ?>
                       <?php echo $name; echo $error; ?>
                                       
                        <?php endif; ?>
                    <?php endforeach ?>
                    <?php endif ?>
               
            <?php endif ?>


User avatar
smugford
Faithful Member
 
Posts: 205
Joined: Sun Nov 29, 2009 8:32 pm

Re: How to customize the form display with embedded i18n?

Postby zaktrak » Mon Sep 10, 2012 8:55 pm

Thanks for the reply, I was afraid these forums had been abandoned for symfony 2.

I read and re-read the advanced form chapter of the book before posting here, because it seemed so similar to what I want to do. The main difference is my form is automatically embedded with $this->embedI18n($this->getCurrentCulture()); so I cannot (or do not know how to) loop through the embedded form as the example shows:
Code: Select all
<?php foreach ($form['newPhotos'] as $photo): ?>
  <?php echo $photo['caption']->renderRow() ?>
  <?php echo $photo['filename']->renderRow() ?>
<?php endforeach; ?>

I have tried to do the same thing with: foreach ($form->getEmbeddedForms() as $i18n)
which displays everything correctly but as I mentioned before, it changes the names of the fields and does not bind correctly.

I have checked the crsf token as you suggested, but it is working. I added your snipped to display the errors and I get: enname [Required.] which is expected since my name field was changed from name="table1[en][name]" to name="table1_translation[name]".

If I manually add fields like this: $form['en']['name']->render() it will work, but I will have to know which language(s) will be embedded. I, of course, could pass the languages in an array and loop through the array rendering each field, but it just seems that there is probably a better way that I am missing. Something like $form->getTranslations() or something... I haven't been able to find any examples like the one in the Advanced Forms section for I18N.

Any ideas? Thanks!
zaktrak
Member
 
Posts: 32
Joined: Thu Jun 26, 2008 12:21 am

Re: How to customize the form display with embedded i18n?

Postby smugford » Thu Sep 13, 2012 5:27 am

I like 1.4 in some ways more than 2.x i guess mostly because I understand it and have a library of code that actually works. I know they aren't going to do anything to it so all of a sudden something that worked yesterday won't work today.

I think your Array idea is the way to go. I looked around and couldn't find anything that is even close to what you're trying to do.

Symfony is awesome but it doesn't do EVERYTHING. And all the dev focus has moved on to 2.x.

You have to come up with solutions on your own if you can't find what you're looking for and I think you found one of those cases.

http://www.symfony-project.org/forms/1_4/en/08-Internationalisation-and-Localisation

You could limit the size of the array by limiting the language options.

Code: Select all
$languages = array('fr', 'en', 'es', 'de', 'nl');
$this->widgetSchema['language'] = new sfWidgetFormI18nChoiceLanguage(array('culture'   => 'fr',
                                                                           'languages' => $languages));
User avatar
smugford
Faithful Member
 
Posts: 205
Joined: Sun Nov 29, 2009 8:32 pm

Re: How to customize the form display with embedded i18n?

Postby zaktrak » Mon Sep 17, 2012 5:39 pm

Hey Thanks again for you help!

I just figured I was missing something really simple. I will implement it by passing the array of cultures that is embedded into the form and rendering the form fields from the array.
I really appreciate you taking the time to look around for a solution.
zaktrak
Member
 
Posts: 32
Joined: Thu Jun 26, 2008 12:21 am


Return to symfony 1.3 and 1.4

Who is online

Users browsing this forum: No registered users and 5 guests