Permalink
Browse files

feature(ajax): Allows fetching form views wrapped by elgg_view_form()

This alters the ajax/view/ page handler to also accept ajax/form/<action>
and this renders the view wrapped with the form element and CSRF tokens.
  • Loading branch information...
mrclay committed May 6, 2015
1 parent 4867727 commit ee7641c4cbff8896d4e9618c206a10a314a37281
Showing with 66 additions and 19 deletions.
  1. +33 −1 docs/guides/ajax.rst
  2. +33 −18 engine/lib/elgglib.php
View
@@ -125,7 +125,7 @@ link to an object given by its GUID:
}
});
The Ajax view system work significantly differently than the action system.
The Ajax view system works significantly differently than the action system.
* There are no access controls based on session status.
* Non-XHR requests are automatically rejected.
@@ -136,6 +136,10 @@ The Ajax view system work significantly differently than the action system.
* System messages/errors shouldn't be used, as they don't display until the user loads another page.
* If the view name begins with ``js/`` or ``css/``, a corresponding Content-Type header is added.
.. warning::
Unlike views rendered server-side, Ajax views must treat ``$vars`` as completely untrusted user data.
Returning JSON from a view
--------------------------
@@ -152,6 +156,34 @@ Here's an example of fetching a view that returns a JSON-encoded array of times:
}
});
Fetching Forms
==============
If you register a form view (name starting with ``forms/``), you can fetch it pre-rendered with ``elgg_view_form()``.
Simply use ``ajax/form/<action>`` (instead of ``ajax/view/<view_name>``):
.. code:: php
// in myplugin_init()
elgg_register_ajax_view('forms/myplugin/add');
.. code:: js
elgg.get('ajax/form/myplugin/add, {
success: function (output) {
$('.myplugin-form-container').html(output);
}
});
* The GET params will be passed as ``$vars`` to *your* view, **not** the ``input/form`` view.
* If you need to set ``$vars`` in the ``input/form`` view, you'll need to use the ``("view_vars", "input/form")``
plugin hook (this can't be done client-side).
.. warning::
Unlike views rendered server-side, Ajax views must treat ``$vars`` as completely untrusted user data. Review
the use of ``$vars`` in an existing form before registering it for Ajax fetching.
Ajax helper functions
---------------------
View
@@ -1452,26 +1452,35 @@ function _elgg_js_page_handler($page) {
/**
* Serve individual views for Ajax.
*
* /ajax/view/<name of view>?<key/value params>
* /ajax/view/<view_name>?<key/value params>
* /ajax/form/<action_name>?<key/value params>
*
* @param array $page Array of URL segements
* @param string[] $segments URL segments (not including "ajax")
* @return bool
*
* @see elgg_register_ajax_view()
* @elgg_pagehandler ajax
* @access private
*/
function _elgg_ajax_page_handler($page) {
function _elgg_ajax_page_handler($segments) {
// the ajax page handler should only be called from an xhr
if (!elgg_is_xhr()) {
register_error(_elgg_services()->translator->translate('ajax:not_is_xhr'));
forward(null, '400');
}
if (is_array($page) && sizeof($page)) {
// throw away 'view' and form the view name
unset($page[0]);
$view = implode('/', $page);
if (count($segments) < 2) {
return false;
}
if ($segments[0] === 'view' || $segments[0] === 'form') {
if ($segments[0] === 'view') {
// ignore 'view/'
$view = implode('/', array_slice($segments, 1));
} else {
// form views start with "forms", not "form"
$view = 'forms/' . implode('/', array_slice($segments, 1));
}
$allowed_views = elgg_get_config('allowed_ajax_views');
if (!array_key_exists($view, $allowed_views)) {
@@ -1489,19 +1498,25 @@ function _elgg_ajax_page_handler($page) {
$vars['entity'] = get_entity($vars['guid']);
}
// Try to guess the mime-type
switch ($page[1]) {
case "js":
header("Content-Type: text/javascript");
break;
case "css":
header("Content-Type: text/css");
break;
}
if ($segments[0] === 'view') {
// Try to guess the mime-type
switch ($segments[1]) {
case "js":
header("Content-Type: text/javascript");
break;
case "css":
header("Content-Type: text/css");
break;
}
echo elgg_view($view, $vars);
echo elgg_view($view, $vars);
} else {
$action = implode('/', array_slice($segments, 1));
echo elgg_view_form($action, array(), $vars);
}
return true;
}
return false;
}

0 comments on commit ee7641c

Please sign in to comment.