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).