jQuery Semantic-UI
Par défaut, Ubiquity utilise la bibliothèque phpMv-UI pour la partie UI.
PhpMv-UI permet de créer des composants basés sur Semantic-UI ou Bootstrap et de générer des scripts jQuery en PHP.
Cette bibliothèque est utilisée pour l’interface d’administration webtools.
Intégration
Par défaut, une variable $jquery est injectée dans les contrôleurs au moment de l’exécution.
Cette opération se fait par injection de dépendance, dans app/config.php
:
...
"di"=>array(
"@exec"=>array(
"jquery"=>function ($controller){
return \Ajax\php\ubiquity\JsUtils::diSemantic($controller);
}
)
)
...
Il n’y a donc rien à faire,
mais pour faciliter son utilisation et permettre la complétion de code dans un contrôleur, il est recommandé d’ajouter la documentation de code suivante :
/**
* Controller FooController
* @property \Ajax\php\ubiquity\JsUtils $jquery
**/
class FooController extends ControllerBase{
public function index(){}
}
jQuery
Href en requêtes ajax
Créez un nouveau contrôleur et sa vue associée, puis définissez les routes suivantes :
1namespace controllers;
2
3class FooController extends ControllerBase {
4
5 public function index() {
6 $this->loadview("FooController/index.html");
7 }
8
9 /**
10 *
11 *@get("a","name"=>"action.a")
12 */
13 public function aAction() {
14 echo "a";
15 }
16
17 /**
18 *
19 *@get("b","name"=>"action.b")
20 */
21 public function bAction() {
22 echo "b";
23 }
24}
La vue associée :
<a href="{{path('action.a')}}">Action a</a>
<a href="{{path('action.b')}}">Action b</a>
Initialiser le cache du routeur :
Ubiquity init:cache -t=controllers
Testez cette page dans votre navigateur à l’adresse http://127.0.0.1:8090/FooController
.
Transformation des requêtes en requêtes Ajax
Le résultat de chaque requête ajax doit être affiché dans une zone de la page définie par son sélecteur jQuery (.result span
).
namespace controllers;
/**
* @property \Ajax\php\ubiquity\JsUtils $jquery
*/
class FooController extends ControllerBase {
public function index() {
$this->jquery->getHref('a','.result span');
$this->jquery->renderView("FooController/index.html");
}
...
}
<a href="{{path('action.a')}}">Action a</a>
<a href="{{path('action.b')}}">Action b</a>
<div class='result'>
Selected action:
<span>No One</span>
</div>
{{ script_foot | raw }}
Note
La variable script_foot
contient le script jquery généré par la méthode renderView. Le filtre raw marque la valeur comme étant « sûre », ce qui signifie que dans un environnement où l’échappement automatique est activé, cette variable ne sera pas échappée.
Ajoutons un peu de css pour le rendre plus professionnel :
<div class="ui buttons">
<a class="ui button" href="{{path('action.a')}}">Action a</a>
<a class="ui button" href="{{path('action.b')}}">Action b</a>
</div>
<div class='ui segment result'>
Selected action:
<span class="ui label">No One</span>
</div>
{{ script_foot | raw }}
Si nous voulons ajouter un nouveau lien dont le résultat doit être affiché dans une autre zone, il est possible de le spécifier via l’attribut data-target.
La nouvelle action
namespace controllers;
class FooController extends ControllerBase {
...
/**
*@get("c","name"=>"action.c")
*/
public function cAction() {
echo \rand(0, 1000);
}
}
La vue associée :
<div class="ui buttons">
<a class="ui button" href="{{path('action.a')}}">Action a</a>
<a class="ui button" href="{{path('action.b')}}">Action b</a>
<a class="ui button" href="{{path('action.c')}}" data-target=".result p">Action c</a>
</div>
<div class='ui segment result'>
Selected action:
<span class="ui label">No One</span>
<p></p>
</div>
{{ script_foot | raw }}
Définition des attributs de la requête ajax :
Dans l’exemple suivant, les paramètres passés à la variable attributs de la méthode getHref
:
supprimer l’historique de la navigation,
rendre le loader ajax interne au bouton cliqué.
1namespace controllers;
2
3/**
4 * @property \Ajax\php\ubiquity\JsUtils $jquery
5 */
6class FooController extends ControllerBase {
7
8 public function index() {
9 $this->jquery->getHref('a','.result span', [
10 'hasLoader' => 'internal',
11 'historize' => false
12 ]);
13 $this->jquery->renderView("FooController/index.html");
14 }
15 ...
16}
Note
Il est possible d’utiliser la méthode postHref
pour utiliser le POST http.
Requêtes ajax classiques
Pour cet exemple, créez la base de données suivante :
CREATE DATABASE `uguide` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
USE `uguide`;
CREATE TABLE `user` (
`id` int(11) NOT NULL,
`firstname` varchar(30) NOT NULL,
`lastname` varchar(30) NOT NULL,
`password` varchar(30) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `user` (`id`, `firstname`, `lastname`) VALUES
(1, 'You', 'Evan'),
(2, 'Potencier', 'Fabien'),
(3, 'Otwell', 'Taylor');
ALTER TABLE `user` ADD PRIMARY KEY (`id`);
ALTER TABLE `user`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1;
Connectez l’application à la base de données, et générez la classe User :
Avec les devtools :
Ubiquity config:set --database.dbName=uguide
Ubiquity all-models
Créer un nouveau contrôleur UsersJqueryController.
Ubiquity controller UsersJqueryController -v
Créez les actions suivantes dans UsersJqueryController :
Action index
L’action index doit afficher un bouton pour obtenir la liste des utilisateurs, chargée via une requête ajax :
1namespace controllers;
2
3/**
4 * Controller UsersJqueryController
5 *
6 * @property \Ajax\php\ubiquity\JsUtils $jquery
7 * @route("users")
8 */
9class UsersJqueryController extends ControllerBase {
10
11 /**
12 *
13 * {@inheritdoc}
14 * @see \Ubiquity\controllers\Controller::index()
15 * @get
16 */
17 public function index() {
18 $this->jquery->getOnClick('#users-bt', Router::path('display.users'), '#users', [
19 'hasLoader' => 'internal'
20 ]);
21 $this->jquery->renderDefaultView();
22 }
23}
La vue par défaut associée à l’action index :
<div class="ui container">
<div id="users-bt" class="ui button">
<i class="ui users icon"></i>
Display <b>users</b>
</div>
<p></p>
<div id="users">
</div>
</div>
{{ script_foot | raw }}
Action displayUsers
Tous les utilisateurs sont affichés, et un clic sur un utilisateur doit afficher les détails de l’utilisateur via une requête ajax postée :
1namespace controllers;
2
3/**
4 * Controller UsersJqueryController
5 *
6 * @property \Ajax\php\ubiquity\JsUtils $jquery
7 * @route("users")
8 */
9class UsersJqueryController extends ControllerBase {
10...
11 /**
12 *
13 * @get("all","name"=>"display.users","cache"=>true)
14 */
15 public function displayUsers() {
16 $users = DAO::getAll(User::class);
17 $this->jquery->click('#close-bt', '$("#users").html("");');
18 $this->jquery->postOnClick('li[data-ajax]', Router::path('display.one.user', [
19 ""
20 ]), '{}', '#user-detail', [
21 'attr' => 'data-ajax',
22 'hasLoader' => false
23 ]);
24 $this->jquery->renderDefaultView([
25 'users' => $users
26 ]);
27 }
La vue associée à l’action displayUsers :
<div class="ui top attached header">
<i class="users circular icon"></i>
<div class="content">Users</div>
</div>
<div class="ui attached segment">
<ul id='users-content'>
{% for user in users %}
<li data-ajax="{{user.id}}">{{user.firstname }} {{user.lastname}}</li>
{% endfor %}
</ul>
<div id='user-detail'></div>
</div>
<div class="ui bottom attached inverted segment">
<div id="close-bt" class="ui inverted button">Close</div>
</div>
{{ script_foot | raw }}
Action displayOneUser
1namespace controllers;
2
3/**
4 * Controller UsersJqueryController
5 *
6 * @property \Ajax\php\ubiquity\JsUtils $jquery
7 * @route("users")
8 */
9class UsersJqueryController extends ControllerBase {
10...
11 /**
12 *
13 * @post("{userId}","name"=>"display.one.user","cache"=>true,"duration"=>3600)
14 */
15 public function displayOneUser($userId) {
16 $user = DAO::getById(User::class, $userId);
17 $this->jquery->hide('#users-content', '', '', true);
18 $this->jquery->click('#close-user-bt', '$("#user-detail").html("");$("#users-content").show();');
19 $this->jquery->renderDefaultView([
20 'user' => $user
21 ]);
22 }
La vue associée à l’action displayOneUser :
<div class="ui label">
<i class="ui user icon"></i>
Id
<div class="detail">{{user.id}}</div>
</div>
<div class="ui label">
Firstname
<div class="detail">{{user.firstname}}</div>
</div>
<div class="ui label">
Lastname
<div class="detail">{{user.lastname}}</div>
</div>
<p></p>
<div id="close-user-bt" class="ui black button">
<i class="ui users icon"></i>
Return to users
</div>
{{ script_foot | raw }}
Composants Semantic
Nous allons ensuite réaliser un contrôleur implémentant les mêmes fonctionnalités que précédemment, mais en utilisant des composants PhpMv-UI (partie sémantique).