![]() |
|
Code snippets for symfony 1.x |
|
One stumbler for me was that I didn't realize that the form created by the input_in_place_editor_tag() helper only submits one key/value pair (value=xxx), so to tell the action which PK to use or which object field to update, you have to pass that information on the form URL (field and id).
One way to solve it would be to write a different action for each field you want to update, but I wanted something I could reuse without writing additional actions, so I added two GET parameters:
So, in my showSuccess.php template:
<h1 id="eipTitle"><?php echo $comment->getTitle() ? $comment->getTitle() : "click to edit" ?></h1> <?php echo input_in_place_editor_tag( 'eipTitle', 'comment/ajaxUpdate?field=title&commentid='.$comment->getCommentid(), array( 'cols' => 40, 'rows' => 1, )) ?>
BTW, you can read about the valid options you can pass in the third argument to input_in_place_editor_tag() at the script.aculo.us Wiki
And for the action, I made it as generic as possible (actually it would be nice if Propel generated an action like this next to the regular executeUpdate action):
private function raiseEipError ($message) { $this->logMessage($message, 'err'); return $this->renderText( "ERROR: $message" ); } public function executeAjaxUpdate() { $id = $this->getRequestParameter('commentid'); $field = $this->getRequestParameter('field'); $this->logMessage("commentid:$id and field='$field'", 'debug'); // Check for required params. // Return a nice message to the user and in the log if there's a problem. if (! $field) return $this->raiseEipError( "No field parameter passed in form action" ); $valid_fields = CommentPeer::getFieldNames(BasePeer::TYPE_FIELDNAME); if (! in_array($field, $valid_fields)) return $this->raiseEipError( "Invalid field parameter '$field' passed in form action.\n". " Valid fields: (" . implode(", ", $valid_fields) . ")" ); if (! $id) return $this->raiseEipError( "No ID parameter passed in form action" ); $comment = CommentPeer::retrieveByPk($id); if (! $comment) return $this->raiseEipError( "Object with ID $id not found" ); $comment->setByName($field, $this->getRequestParameter('value'), BasePeer::TYPE_FIELDNAME); $comment->save(); return $this->renderText( $comment->getByName($field, BasePeer::TYPE_FIELDNAME) ); }
One stumbler for me was that I didn't realize that the form created by the input_in_place_editor_tag() helper only submits one key/value pair (value=xxx), so to tell the action which PK to use or which object field to update, you have to pass that information on the form URL (field and id).
One way to solve it would be to write a different action for each field you want to update, but I wanted something I could reuse without writing additional actions, so I added two GET parameters:
So, in my showSuccess.php template:
<h1 id="eipTitle"><?php echo $comment->getTitle() ? $comment->getTitle() : "click to edit" ?></h1> <?php echo input_in_place_editor_tag( 'eipTitle', 'comment/ajaxUpdate?field=title&commentid='.$comment->getCommentid(), array( 'cols' => 40, 'rows' => 1, )) ?>
BTW, you can read about the valid options you can pass in the third argument to input_in_place_editor_tag() at the script.aculo.us Wiki
And for the action, I made it as generic as possible (actually it would be nice if Propel generated an action like this next to the regular executeUpdate action):
private function raiseEipError ($message) { $this->logMessage($message, 'err'); return $this->renderText( "ERROR: $message" ); } public function executeAjaxUpdate() { $id = $this->getRequestParameter('commentid'); $field = $this->getRequestParameter('field'); $this->logMessage("commentid:$id and field='$field'", 'debug'); // Check for required params. // Return a nice message to the user and in the log if there's a problem. if (! $field) return $this->raiseEipError( "No field parameter passed in form action" ); $valid_fields = CommentPeer::getFieldNames(BasePeer::TYPE_FIELDNAME); if (! in_array($field, $valid_fields)) return $this->raiseEipError( "Invalid field parameter '$field' passed in form action.\n". " Valid fields: (" . implode(", ", $valid_fields) . ")" ); if (! $id) return $this->raiseEipError( "No ID parameter passed in form action" ); $comment = CommentPeer::retrieveByPk($id); if (! $comment) return $this->raiseEipError( "Object with ID $id not found" ); $comment->setByName($field, $this->getRequestParameter('value'), BasePeer::TYPE_FIELDNAME); $comment->save(); return $this->renderText( $comment->getByName($field, BasePeer::TYPE_FIELDNAME) ); }
The idea here is to show different ways of using ajax to update different section of the document.
The first input box updates two different DIV tags, on key up, using two different/separate actions. It is worth noting in the first example the concatenation of the "remote_function" function. You can update as many DIV tags using the concatenation of "remote_function".. cool stuff!
The second input box updates two different DIV tags, on key up, using a single action... with two different values. Note in this example, we have to use a place holder for our ajax response. The response will contain javascript to update several sections of the page.. since the response contains scripts, we enable the script in the call ('script'=>true)
One last thing worth noting is the use of "$F" prototype function. You can use the "$F" function to get the value of any object with ID on the page. let that be an input, select or a radio group.
<br /><div id="input_tag_section_1" >input_tag_section_1</div> <br /><div id="input_tag_section_2" >input_tag_section_2</div> <br /><div id="update_me_1">update_me_1</div> <br /><div id="update_me_2">update_me_2</div> <br /><div id="js_holder_for_multi_update"></div> <?php echo form_tag('test/index'); /** * The following input tag updates two different sections using two different actions. */ echo '<br />'.input_tag('test_input_tag1', '', array('onkeyup'=> remote_function(array( 'update'=>'input_tag_section_1' , 'url'=> 'test/updateInputTagSectionOne' , 'with'=>"'value=' + \$F('test_input_tag1')" )) .remote_function(array( 'update'=>'input_tag_section_2' , 'url'=> 'test/updateInputTagSectionTwo' , 'with'=>"'value=' + \$F('test_input_tag1')" )) )); /** * The following input tag updates two different sections (DIV tags) using a single action * This is done using a javasctipt that gets created in the called action, and updates several sections */ echo '<br />'.input_tag('test_input_tag2', '', array('onkeyup'=> remote_function(array( 'update'=>'js_holder_for_multi_update' , 'url'=> 'test/updateJsHolderForMultiUpdate' , 'with'=>"'value=' + \$F('test_input_tag2')" , 'script'=>true)) )); echo '</form>'; ?>
Here we have the different actions that are used by the ajax callers above.
<?php class testActions extends sfActions { public function executeIndex() { //nothing to do here } public function executeUpdateInputTagSectionOne(){ $this->valueFromAction = 'This is from section ONE action.'; } public function executeUpdateInputTagSectionTwo(){ $this->valueFromAction = 'This is from section TWO action.'; } public function executeUpdateJsHolderForMultiUpdate(){ $this->valueFromAction = 'This is from Multi update action.'; $this->update_me_1_value = 'Value for first '; $this->update_me_2_value = 'Value for second '; } } ?>
This is called by the first input example, updates two DIVs with different content from different actions.
<?php echo $valueFromAction .' Value = '.$sf_params->get('value'); ?>
This is called by the first input example, updates two DIVs with different content from different actions.
This contains the same code as the previous one template, however the action is giving it a different value.
<?php echo $valueFromAction .' Value = '.$sf_params->get('value'); ?>
This is called by the second input example, updates two DIVs with different content from a single action.
This template will only contain javascript to update our DIV tags with required data.
Note how the "update_element_function" is concatenated below.
<?php echo javascript_tag( update_element_function('update_me_1', array('content' => $update_me_1_value.' '.$sf_params->get('value'))) .update_element_function('update_me_2', array('content' => $update_me_2_value.' '.$sf_params->get('value'))) ); ?>
Finally .. Enjoy, and I really hope this helps someone out there.