Ajax responses will sometimes need to update existing DOM elements, for example refresh a set of search results. Returning plain HTML is generally a good default behaviour, as it allows you to keep template rendering in one place (in SilverStripe PHP code), and is easy to deal with in JavaScript.
If you need to process or inspect returned data, consider extracting it from the loaded HTML instead (through id/class attributes, or the jQuery.metadata plugin). For returning status messages, please use the HTTP status-codes.Only return evaluated JavaScript snippets if unavoidable. Most of the time you can just pass data around, and let the clientside react to changes appropriately without telling it directly through JavaScript in AJAX responses. Don't use the Form SilverStripe class, which is built solely around this inflexible concept.
Example: Autocomplete input field loading page matches through AJAX
Template:
<ul> <% control Results %> <li id="Result-$ID">$Title</li> <% end_control %> </ul> |
PHP:
class MyController { function autocomplete($request) { $SQL_title = Convert::raw2sql($request->getVar('title')); $results = DataObject::get("Page", "Title = '$SQL_title'"); if(!$results) return new HTTPResponse("Not found", 404); // Use HTTPResponse to pass custom status messages $this->response->setStatusCode(200, "Found " . $results->Count() . " elements"); // render all results with a custom template $vd = new ViewableData(); return $vd->customise(array( "Results" => $results ))->renderWith('AutoComplete'); }} |
HTML
<form action"#"> <div class="autocomplete {url:'MyController/autocomplete'}"> <input type="text" name="title" /> <div class="results" style="display: none;"> </div> <input type="submit" value="action_autocomplete" /></form> |
JavaScript:
$('.autocomplete input').live('change', function() { var resultsEl = $(this).siblings('.results'); resultsEl.load( // get form action, using the jQuery.metadata plugin $(this).parent().metadata().url, // submit all form values $(this.form).serialize(), // callback after data is loaded function(data, status) { resultsEl.show(); // get all record IDs from the new HTML var ids = jQuery('.results').find('li').map(function() { return $(this).attr('id').replace(/Record\-/,''); }); } );}); |
No comments:
Post a Comment