Created
June 18, 2010 02:28
-
-
Save gestadieu/443124 to your computer and use it in GitHub Desktop.
Symfony Form widget to manage many-to-many relationship
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* sfWidgetFormChoiceAutocomplete represents a multiple select displayed as an autocomplete input and a list of checkboxes. | |
* | |
* | |
* @package symfony | |
* @subpackage widget | |
* @author Gerald Estadieu <[email protected]> | |
* @version | |
*/ | |
class sfWidgetFormChoiceAutocomplete extends sfWidgetForm | |
{ | |
/** | |
* Constructor. | |
* | |
* Available options: | |
* | |
* * choices: An array of possible choices (required) | |
* * source: url, array of data or javascript function (required) | |
* * template: The HTML template to use to render this widget | |
* The available placeholders are: | |
* * class | |
* * autocomplete | |
* * list | |
* | |
* @param array $options An array of options | |
* @param array $attributes An array of default HTML attributes | |
* | |
* @see sfWidgetForm | |
*/ | |
protected function configure($options = array(), $attributes = array()) | |
{ | |
parent::configure($options,$attributes); | |
$this->addRequiredOption('choices'); | |
$this->addRequiredOption('source'); | |
$this->addOption('list_options',array()); | |
$this->addOption('help','Search here...'); | |
$this->addOption('config', '{ }'); | |
$this->addOption('template',<<<EOF | |
<div class="%class% ui-widget"> | |
<div class="%class%_autocomplete"> | |
%autocomplete% | |
</div> | |
<div class="%class%_list" id="%id%_list"> | |
%list% | |
</div> | |
</div> | |
EOF | |
); | |
} | |
/** | |
* Renders the widget. | |
* | |
* @param string $name The element name | |
* @param string $value The value selected in this widget | |
* @param array $attributes An array of HTML attributes to be merged with the default HTML attributes | |
* @param array $errors An array of errors for the field | |
* | |
* @return string An HTML tag string | |
* | |
* @see sfWidgetForm | |
*/ | |
public function render($name, $value = null, $attributes = array(), $errors = array()) | |
{ | |
if (is_null($value)) | |
{ | |
$value = array(); | |
} | |
$choices = $this->getOption('choices'); | |
if ($choices instanceof sfCallable) | |
{ | |
$choices = $choices->call(); | |
} | |
$associated = array(); | |
$unassociated = array(); | |
foreach ($choices as $key => $option) | |
{ | |
if (in_array(strval($key), $value)) | |
{ | |
$associated[$key] = $option; | |
} | |
else | |
{ | |
$unassociated[$key] = $option; | |
} | |
} | |
$associatedWidget = new sfWidgetFormChoice(array_merge($this->getOption('list_options'),array('choices' => $associated, 'multiple' => true, 'expanded' => true))); | |
return strtr($this->getOption('template'),array( | |
'%class%' => 'USJjQueryUIAutocomplete', | |
'%id%' => $this->generateId($name), | |
'%list%' => $associatedWidget->render($name,$value), | |
'%autocomplete%' => $this->renderTag('input', array('type' => 'text', 'name' => 'autocomplete_'.$name)) . | |
sprintf(<<<EOF | |
<script type="text/javascript"> | |
jQuery(document).ready(function() { | |
jQuery('#%s').focus(function(){ $(this).val(''); }).trigger('focus'); | |
jQuery('#%s').blur(function(){ $(this).val('%s'); }).trigger('blur'); | |
if (!$('div#%s_list ul.checkbox_list').length) { | |
$('div#%s_list').append('<ul class="checkbox_list"></ul>'); | |
} | |
jQuery('#%s').autocomplete({ | |
source: %s, | |
select: function(event, ui) { | |
if (!$('#%s_'+ui.item.id).length) { | |
var ul = $('div#%s_list ul.checkbox_list'); | |
$('<li><input type="checkbox" checked="checked" id="%s_'+ui.item.id+'" value="'+ui.item.id+'" name="%s"> <label for="%s_'+ui.item.id+'">'+ui.item.value+'</label></li>').prependTo(ul); | |
} | |
$(this).trigger('blur'); | |
} | |
}); | |
jQuery('div#%s_list').change(function(e){ | |
var elt = $(e.target); | |
if ($(elt).is(':not(:checked)')) { | |
$(elt).parent('li').animate({'backgroundColor':'#fb6c6c'},300); | |
} | |
setTimeout(function(){ | |
if ($(elt).is(':not(:checked)')) { | |
$(elt).parent('li').slideUp(300,function() { $(this).remove() }); | |
} else { | |
$(elt).parent('li').css({'backgroundColor':'#fff'}); | |
} | |
},3000); | |
}); | |
}); | |
</script> | |
EOF | |
, | |
$this->generateId('autocomplete_'.$name), | |
$this->generateId('autocomplete_'.$name), | |
$this->getOption('help'), | |
$this->generateId($name), | |
$this->generateId($name), | |
$this->generateId('autocomplete_'.$name), | |
'"' . $this->getOption('source') . '"', | |
$this->generateId($name), | |
$this->generateId($name), | |
$this->generateId($name), | |
$name, | |
$this->generateId($name), | |
$this->generateId($name) | |
) | |
)); | |
} | |
/** | |
* Gets the JavaScript paths associated with the widget. | |
* | |
* @return array An array of JavaScript paths | |
*/ | |
// public function getJavascripts() | |
// { | |
// return array(); | |
// } | |
/** | |
* Gets the stylesheet paths associated with the widget. | |
* | |
* @return array An array of stylesheet paths | |
*/ | |
// public function getStylesheets() | |
// { | |
// return array('/css/widgets.css' => 'all'); | |
// } | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment