You are browsing the unmaintained documentation for old Nette 2.0. See documentation for current Nette.

AJAX & Snippets

Modern web applications nowadays run half on a server and half in a browser. AJAX is the vital uniting factor. What support does Nette Framework offer?

  • sending template fragments (so called snippets)
  • passing variables between PHP and JavaScript
  • AJAX applications debugging

An AJAX request can be detected using a method of a service encapsulating a HTTP request $httpRequest->isAjax() (detects based on the X-Requested-With HTTP header). There is also a shorthand method in presenter: $this->isAjax().

An AJAX request is no different from a normal one – a presenter is called with a certain view and parameters. It is, too, up to the presenter how will it react: it can use its routines to either return a fragment of HTML code (a snippet), an XML document, a JSON object or a piece of Javascript code.

Caution: Nette doesn't implement client-side AJAX requests. We recommend nette.ajax.js library by Vojtěch Dobeš.

There is a pre-processed object called payload dedicated to sending data to the browser in JSON.

	public function actionDelete($id)
		if ($this->isAjax()) {
			$this->payload->message = 'Success';

For a full control over your JSON output use JsonResponse in your presenter. It terminates presenter immediately and you'll do without a template:

	$this->sendResponse(new JsonResponse(array('key' => 'value', ...)));

If we want to send HTML, we can either set a special template for AJAX requests:

	public function handleClick($param)
		if ($this->isAjax()) {

However, there is a far more powerful tool of built-in AJAX support – snippets. Using them makes it possible to turn a regular application into an AJAX one using only a few lines of code. How it all works is demonstrated in the Fifteen example whose code is also accessible in the build or on GitHub. The way snippets work is that the whole page is transferred during the initial (i.e. non-AJAX) request and then with every other AJAX subrequest (request of the same view of the same presenter) only the code of the changed parts is transferred in the earlier mentioned repository called payload. There are two mechanisms designated for this: invalidation and snippets rendering.


Each descendant of class Control (which a Presenter is too) is able to remember whether there were any changes during a subrequest that require it to re-render. There is a triplet of methods to handle this: invalidateControl(), validateControl() and isControlInvalid(). An example:

	public function handleLogin($user)
		// The object has to re-render after the user has logged in

Nette, however, offers an even slighter distinction than on the level of components. The listed methods can accept a name of a snippet as a parameter. Hence, it is possible to invalidate (that is to force to re-render) on the level of snippets (every object can keep any number of snippets). If the entire component is invalidated, then every snippet re-renders. A component is “invalid” even if any of its subcomponents is invalid as well.

echo $this->isControlInvalid(); // -> FALSE

$this->invalidateControl('header'); // invalidates the snippet named 'header'
echo $this->isControlInvalid('header'); // -> TRUE
echo $this->isControlInvalid('footer'); // -> FALSE
echo $this->isControlInvalid(); // -> TRUE, at least one snippet is invalid

$this->invalidateControl(); // invalidates the whole component, every snippet
echo $this->isControlInvalid('footer'); // -> TRUE

A component that receives a signal, is automatically invalidated.

Thanks to invalidation of snippets we know exactly which parts of which elements will it be necessary to re-render.

Macro {snippet} … {/snippet}

Nette is based on the idea of logical, not graphical elements, i.e. a descendant of Control does not represent a rectangular area on a page, but a logical component that that can render even into various forms. (for instance a hypothetical component DataGrid can have a method for rendering the grid and another one for rendering the “paginator”, and so on). Each element can also be rendered multiple times on a single page; or conditionally, or every time with a different template, etc. Therefore it is not possible to call some render method of every invalid object. The approach to the render must be the same as when the whole page is being rendered.

Rendering of the page proceeds very similarly as in case of a regular request: the same templates are loaded, etc. The vital part is, however, to leave out the parts that are not supposed to reach the output and those that are shall be associated with an identifier and be sent to the user in a comprehensible format for a JavaScript handler.

If there is a control or a snippet in the template, we have to wrap it using the {snippet} ... {/snippet} pair tag – it will make sure that the rendered snippet will be “cut out” and sent to the browser. It will also enclose it in a helper <div> tag (it is possible to use a different one). In the following example a snippet is named header and may as well represent a template of a control:

{snippet header}
<h1>Hello .... </h1>

Debugging of AJAX applications