Symfony-Plugin: ein FormWidget mit eigenen Ajax Actions

Wenn man versucht mit Symfony/Doctrine/Generator Bordmitteln “related” Objekte in Formularen darzustellen, wird das schnell schwierig bei etwas mehr Daten.
“Ein Projekt wird mehreren Mitarbeitern zugewiesen. Es gibt aber 500.000 Mitarbeiter.”
Schon rendert sich das generierte multi-select im Projekt-Formular den sprichwörtlichen Wolf.
Hier braucht man eigentlich schon was mit Ajax/Pagination.

Hier ein Entwurf für ein FormWidget, Plugin das seine eigenen Ajax Actions haben soll.
Also erstmal

/plugins/myMightyWidget 

anlegen.

Die Struktur darin sieht dann nachher so aus:

./lib/myMightyWidget.class.php            
./modules/myMightyWidget/actions/actions.class.php
./modules/myMightyWidget/templates/_myMightyWidget.php       
./modules/myMightyWidget/templates/myajaxactionSuccess.php
( ./web/css/myMightyCSSFile.css )
( ./web/js/myMightyExternalJSFile.js )

als erstes:

/plugins/myMightyWidget/lib/myMightyWidget.class.php

Das Template HTML schreiben wir in ein Partial das wir dann nachher in der render-Methode holen.
Dafür müssen wir uns eben den Partial Helper laden, von Haus aus gibt es die Funktion nicht in der Widget Klasse.
Falls unser Widget einen eigenen Stylesheet und auch eine eigene JS Datei haben möchte, könnten wir die beiden auch bequem im entsprechenden myMightyWidget/web Ordner unterbringen. Und auch via den getStylesheet/ getJavascripts Methoden laden lassen.

/plugins/myMightyWidget/lib/myMightyWidget.class.php
class myMightyWidget extends sfWidgetForm
{
	
  public function configure( $options = array(), $attributes = array() )
  {
  	
  	$this->addOption(  "someOption" );
  	
  	$this->addOption(  "someOtherOption", "default" );
  }
  
  public function getStylesheets()
  {
    return array(
    	'/myMightyWidget/css/myMightyWidget.css' => ''
    );
  }
  
  public function getJavascripts()
  {
    return array(
    	'/myMightyWidget/js/myMightyWidget.js'
    );
  }
  
  public function render($name, $value = null, $attributes = array(), $errors = array())
  {
  	
        //load partial Helper as we want to outsource the Template
	sfContext::getInstance()->getConfiguration()->loadHelpers('Partial');
  	
  	
    $options = array(
        'someOption'           => $this->getOption('someOption'),
        'someOtherOption'  => $this->getOption('someOtherOption')
    );
    
  	return  get_partial( 'myMightyWidget/myMightyWidget', $options );
  }
  
}

dann brauchen wir den modules Ordner, hier schonmal für das Partial template
also den Ordner

/plugins/myMightyWidget/modules/myMightyWidget

anlegen.

Darin dann das Partial “_myMightyWidget.php” anlegen:

(ich setze aus Schreibfaulheit einfach mal jQuery voraus …)


<script type="text/javascript">

	$(document).ready(function() {
            $("#myMightyWidget").find(".ajaxResults")load( '<?php echo url_for( "myMightyWidget/myAjaxAction" ); ?>' );
        });
		
</script>

<div id="myMightyWidget">

    Hello ...

    <div class="ajaxResults"></div>

</div>

Für die Ajax Daten dann Action und Template anlegen:

/plugins/myMightyWidget/modules/myMightyWidget/actions/actions.class.php
class myMightyWidgetActions extends sfActions
{
	
	public function executeMyAjaxAction( sfWebRequest $request )
 	{
 		$this->world = "World";
    	}
	
 }

und das Template:

/plugins/myMightyWidget/modules/myMightyWidget/templates/myajaxactionSuccess.php
<strong>
    <?php echo $world; ?>
</strong>

Dann in der app, wo wir das Widget benutzen möchten einfach das Modul “myMightyWidget” aktivieren (settings.yml).
Und das Widget im Template oder direkt in einer Formklasse einbinden.
Und man kann sich mitten im Formular durch irgendwelche Ajax Listen blättern, oder was einem eben einfällt.

Um die Ergebnisse dem generierten Formular “unterzuschmuggeln” muss man nur via JS inputs mit den entsprechenden Namen erzeugen, dann wird das ganz normal mitverarbeitet.
zB.

<input type="hidden" name="project&#91;mitarbeiter_list&#93;&#91;&#93;" value="<?php echo $mitarbeiter_id ?>" />