Making a choice (select) widget read-only in Symfony

I have a form in Symfony that contains a Choice widget (my database field is called created_group) and I need to show its value to the user but make it not editable, so that the user cannot change the value.

Using the HTML disabled attribute won’t work:

   $this -> widgetSchema['created_group']->setAttribute(‘disabled’,'disable’);

as this will show the select field as blurred and thus show the content, but the selected option won’t be sent on a form submit: Symfony will mark that field as missing and will save it as NULL in the database, or generate a database error if the field cannot be NULL. The more complicated solution would be to also make Symfony skip that field in updates / creation.

The simpler solution is to create a custom widget type that just shows the Select’s option text and adds a hidden field with the Select’s option value. This way the users sees the text and Symfony gets the correct value upon update. This solution assumes that you trust that the user won’t tamper the hidden field with things like Firebug, so keep in mind that it’s not a secure option to make that field read-only and to make sure that the user cannot change it. It’s more of a cosmetic option.

You must create a custom widget class. The class’s code is the following:

<?php
class sfReadonlySelect extends sfWidgetFormDoctrineChoice
{
public function render($name, $value = null, $attributes = array(), $errors = array())
{
$choices = $this->getChoices();
$string = $choices[$value];
$string.= ‘<input type=”hidden” name=”‘.escape_once($name).’” value=”‘.escape_once($value).’”/>’;
return $string;
}
}

all you need to do is to save that in a file called sfReadonlySelect.class.php in the /lib/widget/ directory of your installation.

Then in your /lib/form/doctrine/myForm.php class (where myForm is the name of the object to which your Select field belongs) you initialize  the field as following:

$this -> setWidget ( ‘created_group’, new sfReadonlySelect (array(‘model’ => $this->getRelatedModelName(‘GroupCreated’), ‘add_empty’ => true)) );

It’s a simple solution to a fairly simple problem, but I haven’t found a better one on the web so here it is! Please leave your comments/questions below.

 

 

Hiding option groups (optgroups) in Chrome and Internet Explorer with Jquery

If you need to hide a series of optgroups with Jquery, it is easy to do so in Firefox: you just need to call $(this).hide() on the option group, and it and all its children will be hidden and not selectable. If you want to show them back, you just need to call $(this).show() and they will reappear.

However, other browser like Chrome and IE don’t allow this: the style rule (display:none) is applied to the element but does not work, and the elements stay visible. I’ve found out a quick workaround for this problem.

Basically, all you need to do is to

  1. disable all the options within the optgroup (and deselect them if they are selected)
  2. move the optgroup to the end of the select’s optgroups, so that it does not get in the way

If you want to reinstate that optgroup (make it selectable again), you must do the opposite:

  1. enable all the options within the optgroup
  2. move the optgroup to the beginning of the select’soptgroups, so that it is visibile again.

I’ve created a couple of custom jquery functions for the purpose:

$.fn.hideOptionGroup = function() {
 $(this).hide();
 $(this).children().each(function(){
 $(this).attr("disabled", "disabled").removeAttr("selected");
 });
 $(this).appendTo($(this).parent());

}

$.fn.showOptionGroup = function() {
 $(this).show();    
 $(this).children().each(function(){
 $(this).removeAttr("disabled" );
 });
 $(this).prependTo($(this).parent());
 $(this).parent().animate({scrollTop:0},0);
}

You apply the function to the optgroup as follows:

$("#myOptgroupId").showOptionGroup();
$("#myOptgroupId").hideOptionGroup();

What this functions do is:

  1. hide/show the element in Firefox directly.
  2. then, it disables/enables all of the optgroup’s options.
  3. and moves it to the end/beginning of the select’s optgroups.
  4. scrolls the select to the top, so that the first optgroup is shown even if the user had scrolled down and selected something else (only for the show function).

This has been tested with Chrome, will test it with Explorer soon. Hope this helps. Comments and suggestions are welcome.

Converting to Title Case in MySQL – Capitalizing MySQL (a PHP solution)

Ever found some tables in your MySQL database with user-compiled data that is not coherent in terms of case? Some entries are in Title Case, some are all in UPPER CASE, some are all in lower case. If you need to switch everything to upper case or lower case, it’s as easy as typing the following query:
UPDATE `table` SET `field` = UPPER(`field`)
(For lower case, just use LOWER() instead of UPPER() ).

Continue reading

HCE Crowd

A fortnightly web strip about Information Technology

HCE Web Design launches a new website, HCE Crowd. It will be dedicated to the publication of a series of web strips, for now on a fortnightly basis, all set in the office of a fictional Information Technology company in North-Eastern Italy. Any references to historical events, real people, or real locales are used fictitiously. Other names, characters, places, and incidents are the product of the authors’ imagination, and any resemblance to actual events or locales or persons, living or dead, is entirely coincidental. Each strip is the work of all HCE editorial staff: fasten your RSS feeds, ready, steady, go!

Javascript class member access control

Class member access control, that is the possibility of defining private, protected or public class members, is one of the cornerstones of object oriented programming, since it permits hiding and incapsulating implementation details and disciplines access to the resources from the outside granting their consistency is maintained. Unfortunately Javascript does not provide a built-in class member access control: in this article I will describe a pair of techniques which can be applied to implement it.

A first way of disciplining access to a variable or a method of a class could be obtained adopting an appropriate naming convention. For example it is quite common using an underscore as a prefix for the class members that implement the internals of a software component. This obviously doesn’t really deny access to those resources, but helps a careful programmer not to inadvertently breaking application consistency.

Continue reading