PHPackages                             zaxcms/ui - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. zaxcms/ui

ActiveLibrary[Framework](/categories/framework)

zaxcms/ui
=========

Extra components behavior for Nette Framework

v1.1.0(11y ago)229PHPPHP &gt;=5.4.0

Since Jan 8Pushed 11y ago1 watchersCompare

[ Source](https://github.com/ZaxCMS/UI)[ Packagist](https://packagist.org/packages/zaxcms/ui)[ RSS](/packages/zaxcms-ui/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (2)Dependencies (3)Versions (3)Used By (0)

This library contains some useful UI extensions for Nette framework.

Zax\\Application\\UI\\IAjaxAware
================================

[](#zaxapplicationuiiajaxaware)

Defines one method `enableAjax()` and is - quite obviously - intended to enable AJAX features.

Zax\\Application\\UI\\Control
=============================

[](#zaxapplicationuicontrol)

This class extends standard Nette Control and adds some interesting features, including `IAjaxAware` implementation and views. Its main purpose is to save us from typing repetitive boiler-plate code when doing some common tasks and makes AJAXification of a finished component much easier, with consistent results.

Example
-------

[](#example)

A very simple component might look like this:

```
class SomeControl extends Zax\Application\UI\Control {

	public function beforeRender() {
		// gets called before a component gets rendered
	}

	public function viewDefault() {
		// gets called only if view is "Default"
	}

}
```

A component also needs a template. So let's add a 'Default.latte' into 'templates' directory, relative to where the component is located. The structure will look like this:

- SomeControl.php
- /templates
    - Default.latte

That's it!

Using views
-----------

[](#using-views)

Views are defined by view&lt;View&gt; methods. If you try to access an undefined view, an exception will be thrown. Also each view has a corresponding template with same name.

Views are internally nothing but a persistent param `$view`, so creating links to views couldn't be any easier:

```
$this->link('this', ['view' => 'Foo']);
```

Using renders
-------------

[](#using-renders)

In Nette, we sometimes might want to use something like this: `{control someControl:foo}`. Normally, we'd make a `renderFoo` method, but this component is based on `__call` magic method, so this wouldn't work properly. Instead, let's call our method `beforeRenderFoo`. And again, it needs a separate template, which would be (assuming we are still in "Default" view) 'Default.Foo.latte'.

*The pattern for naming templates is '&lt;View&gt;.latte' or '&lt;View&gt;.&lt;Render&gt;.latte'.*

We can pass parameters to renders as well, so `{control someControl:foo, bar => val}` will call`beforeRenderFoo`method and pass "val" to parameter called "bar".

Working with AJAX
-----------------

[](#working-with-ajax)

I'm not gonna beat around the bush. AJAX is magic and it's made to suit my needs, so you might find some WTF factors here. But since I took the time to implement it, I might as well document it too.

First thing we need to do is call `enableAjax` on our freshly created component (in `createComponent*` method) and wrap our component in a `{snippet}` (without name) in our component's template. From now on, when we send an AJAX request, the component should automatically redraw it's snippet. Note that this will enable AJAX on all subcomponents as well (well, on all subcomponents, that implement `IAjaxAware`).

**Known limitation:** Nette creates components on-demand. That means, if a component doesn't receive any parameters during a request, it will get created after it is demanded in a template, which is too late for AJAX redrawing. A simple workaround is to create the component manually in action, like this:

```
public function actionDefault() {
	$this->createComponent('someControl');
	// or shorter
	$this['someControl'];
}
```

Okay, now we have a component that knows about AJAX and knows whether AJAX is enabled or not. Now is time to create some links that respect this settings. There are two ways to do it, one which respects default nette.ajax.js settings, but requires a little bit more boiler-plate code, and another, which uses `n:ajax` macro.

To use the first method, just check `$control->isAjaxEnabled()` (or `$control->ajaxEnabled` thanks to Nette\\Object magic) before adding class "ajax" to your link, like this:

```
link

```

The other method looks a little bit more elegant in templates:

```
link

```

This n:macro does the very same check on your component, but instead of adding a class, it adds `data-zax-ajax`attribute. To make it work, we need to register an extension in config

```
extensions:
	ajax: Zax\DI\AjaxExtension

```

and we need to add this piece of code to our js before calling `$.nette.init()`:

```
$.nette.ext('init').linkSelector = 'a[data-zax-ajax]';
```

Simple, right? Now, there's one last thing to cover. If you ever tried to AJAXify your app, you've probably went down the path where you kept writing `if is ajax, redraw, else redirect` like a mofo all the time and usually you were able to only use AJAX in signals, because you cannot call `redrawControl` when eg. setting a persistent param or something like that.

I've been down that path as well and it plain sucked. We already have automatic snippet invalidation, which solves the persistent params part, but what about the `if is ajax blahblahblah`? Well, I've added a method called `go`, which does this check for us AND ensures we end up on the same destination, no matter whether it's AJAX request or not.

So calling `$this->go('signal!', ['view' => 'Foo']);` will check whether it's AJAX request or not and will either perform regular redirect to signal and Foo view, or it will just forward us to the same destination, without making an additional request. It couldn't be any easier!

Zax\\Application\\UI\\Multiplier
================================

[](#zaxapplicationuimultiplier)

Multiplier is a cool little class that allows us to have multiple instances of the same component on one page. Default Nette Multiplier will however prevent sub-components from receiving the ajaxEnabled state, because it's not `IAjaxAware`. So I made it `IAjaxAware`.

Customization
=============

[](#customization)

Control behavior is divided into several traits:

TControlForward
---------------

[](#tcontrolforward)

`forward()` and `presenterForward()` methods.

TControlAjax
------------

[](#tcontrolajax)

`IAjaxAware` implementation + `TControlForward`

TControlLifeCycle
-----------------

[](#tcontrollifecycle)

Life cycle using `__call`, calls `view*()` and `beforeRender*()` and adds a persistent parameter `$view`. Also, if a control implements `IHasControlLifeCycle`, then it automatically calls `run()` method, which we can use to render a template or do whatever we want.

TControlMergeLinkParams
-----------------------

[](#tcontrolmergelinkparams)

Allows us to specify `$defaultLinkParams` in specific components to keep URLs as clean as possible when using multiple (sub)components with persistent params.

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity10

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity59

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~7 days

Total

2

Last Release

4141d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/e355c4a95369341c4d21dcda1279dcd227f73ea58e88171e91affd56c2fadacb?d=identicon)[Zax](/maintainers/Zax)

---

Top Contributors

[![zaxxx](https://avatars.githubusercontent.com/u/7381443?v=4)](https://github.com/zaxxx "zaxxx (7 commits)")

### Embed Badge

![Health badge](/badges/zaxcms-ui/health.svg)

```
[![Health](https://phpackages.com/badges/zaxcms-ui/health.svg)](https://phpackages.com/packages/zaxcms-ui)
```

###  Alternatives

[nette/nette

👪 Nette Framework - innovative framework for fast and easy development of secured web applications in PHP (metapackage)

1.6k2.8M335](/packages/nette-nette)[contributte/application

Extra contrib to nette/application

352.8M7](/packages/contributte-application)[o5/grido

Grido - DataGrid for Nette Framework

87290.5k4](/packages/o5-grido)[nette/web-project

Nette: Standard Web Project

10991.8k](/packages/nette-web-project)[nasext/dependent-select-box

Dependent Select Box for Nette Framework.

21262.8k2](/packages/nasext-dependent-select-box)[kdyby/autowired

Syntax sugar for working with services in Nette Framework

30885.7k9](/packages/kdyby-autowired)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
