Using embedFormForEach in Symfony, Part II

January 1st, 2009 by Carlos Barros

In my last post I talked about embedFormForEach method, that will embed a form inside another N times, and in the end of that article, I promised a new post on this subject to show how to use it to dynamically add/remove/sort cars, and here it is. As usual, I put live an example here (I integrated this new form on the old city picker form). In this example, when you create (or edit) an user, you will see a new control called Cars, and a green plus icon. If you click that icon, it will add a new “car form” into the user form. You can add as many cars as you want. Each new form has a set of controls that can be used to sort and remove cars from the form. Let’s take a look on how it all works.

Read the rest of this entry »

Using embedFormForEach in Symfony

December 1st, 2008 by Carlos Barros

The new Form sub-framework, introduced in Symfony 1.1, is really great, and the more I work with it, the more I like it. One of the nicest feature of form sub-framework is the ability to embed a form inside another one, using the embedForm method. Also, symfony provides another method, called embedFormForEach that will embed a form inside another one N times. At first glance this method doesn’t seem to be very useful, but I found it really useful in a project I worked a few weeks ago. Consider the following scenario: you want a form to ask users to input information about all cars they have (make and model). In this form you have a select box (this can be an input box too, but I’m using a select box in this example) where users specify how many cars they have and then it will show X fields where users can input cars model and make (X = number of cars user selected), using ajax to load fields. You can see an example here.

Read the rest of this entry »

Overlabel with Prototype

July 30th, 2008 by Carlos Barros

Some time ago I was searching for some overlabel script to use in a project and found a great script, created by Mike Brittain (here), and since then I’ve used this script in all my projects. But last week I was working in a project that uses Prototype library and I wondered if there was an overlabel plugin for prototype. After some time googling about the subject, I only came up with a JQuery plugin (here), that is a port of Mike Brittain script to JQuery library. So, as I didn’t find what I was looking for, I decided to make my own port and created a prototype plugin. This took me less than 15 minutes to get a working version of it.

This is the resulting code:

var overLabelPlugin = {
 overlabel: function (obj)
 {
  var  field;
 
  obj = $(obj);
 
  // check for attribute
  if(!obj.readAttribute('for') ||
   !(field = $(obj.readAttribute('for'))))
    return false;
 
  // apply overlabel style
  obj.className = 'overlabel-apply';
  if(field.value != '')
   $$('label[for='+$(field).readAttribute('id')+']').invoke('hide');
 
  // setup event handlers
  field.onfocus = function ()
  {
   $$('label[for='+$(this).readAttribute('id')+']').invoke('hide');
  }
 
  field.onblur = function ()
  {
   if($(this).value === '')
    $$('label[for='+$(this).readAttribute('id')+']').invoke('show');
  }
 
  obj.onclick = function ()
  {
   $($(this).readAttribute('for')).focus();
  }
 }
}
 
Event.observe(window,'load',function ()
{
 Element.addMethods(overLabelPlugin);
});

The only change I made to the original technique was the usage of hide() and show() instead of text-ident:-1000px; to hide/show overlabels.

To activate overlabel, you can do something like:

<html>
 <head>
  <title>Overlabel with Prototype</title>
  <style rel="stylesheet" type="text/css">
  label.overlabel-apply {
    position:absolute;
    top:3px;
    left:5px;
    z-index:1;
    color:#999;
    font-family:verdana serif sans-serif;
    font-size:10pt;
  }
  div.overlabel_container {
    position:relative;
  }
  </stype>
  <script src="prototype.js" type="text/javascript"></script>
  <script src="overlabel.js" type="text/javascript"></script>
  <script type="text/javascript">
  Event.observe(window,'load',function ()
  {
   $$('.overlabel').invoke('overlabel');
  });>
 
  </script>
 </head>
 <body>
  <div class="overlabel_container">
   <label class="overlabel" for="uname">Username</label>
   <input id="uname" name="uname" type="text" />
  </div>
 </body>
</html>

I’m by no means a Prototype expert, so if there’s some better way to do this, please let me know.