jQuery Semantic-UI

Por defecto, Ubiquity utiliza la librería phpMv-UI para la parte experiencia de usuario.
PhpMv-UI permite crear componentes basados en Semantic-UI o Bootstrap y generar scripts jQuery en PHP.

Esta biblioteca se utiliza para la interfaz de administración de webtools.

Integración

Por defecto, se inyecta una variable $jquery en los controladores en tiempo de ejecución.

Esta operación se realiza mediante inyección de dependencias, en app/config.php:

app/config.php
...
"di"=>array(
             "@exec"=>array(
                             "jquery"=>function ($controller){
                                     return \Ajax\php\ubiquity\JsUtils::diSemantic($controller);
                                     }
                             )
             )
...

Así que no hay nada que hacer,
pero para facilitar su uso y permitir la finalización de código en un controlador, se recomienda añadir la siguiente documentación de código:

app/controllers/FooController.php
 /**
 * Controller FooController
 * @property \Ajax\php\ubiquity\JsUtils $jquery
 **/
class FooController extends ControllerBase{

     public function index(){}
}

jQuery

Referencias (Href) a solicitudes ajax

Cree un nuevo Controlador y su vista asociada, luego defina las siguientes rutas:

app/controllers/FooController.php
 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 vista asociada:

app/views/FooController/index.html
     <a href="{{path('action.a')}}">Action a</a>
     <a href="{{path('action.b')}}">Action b</a>

Inicializar la caché del router:

Ubiquity init:cache -t=controllers

Pruebe esta página en su navegador en http://127.0.0.1:8090/FooController.

Transformación de peticiones en peticiones Ajax

El resultado de cada petición ajax debe mostrarse en un área de la página definida por su selector jQuery (.result span)

app/controllers/FooController.php
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");
     }
     ...
}
app/views/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 }}

Nota

La variable script_foot contiene el script jquery generado por el método renderView. El filtro raw marca el valor como «safe», lo que significa que en un entorno con escape automático activado esta variable no será escapada.

Añadamos un poco de css para hacerlo más profesional:

app/views/FooController/index.html
<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 queremos añadir un nuevo enlace cuyo resultado deba mostrarse en otra zona, es posible especificarlo mediante el atributo data-target.

La nueva acción:

app/controllers/FooController.php
namespace controllers;

class FooController extends ControllerBase {
     ...
     /**
      *@get("c","name"=>"action.c")
      */
     public function cAction() {
             echo \rand(0, 1000);
     }
}

La vista asociada:

app/views/FooController/index.html
<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 }}
../_images/fooController.png

Definición de los atributos de la petición ajax:

En el siguiente ejemplo, los parámetros pasados a la variable attributes del método getHref:

  • eliminar el historial de navegación,

  • hacer que el cargador ajax sea interno al botón pulsado.

app/controllers/FooController.php
 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}

Nota

Es posible utilizar el método postHref para utilizar el método http POST.

Peticiones ajax clásicas

Para este ejemplo, cree la siguiente base de datos:

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;

Conectar la aplicación a la base de datos, y generar la clase User:

Con devtools:

Ubiquity config:set --database.dbName=uguide
Ubiquity all-models

Crear un nuevo controlador UsersJqueryController.

Ubiquity controller UsersJqueryController -v

Crea las siguientes acciones en UsersJqueryController:

../_images/UsersJqueryControllerStructure.png

Acción index

La acción index debe mostrar un botón para obtener la lista de usuarios, cargada mediante una petición ajax:

app/controllers/UsersJqueryController.php
 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 vista por defecto asociada a la acción index:

app/views/UsersJqueryController/index.html
<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 }}

acción displayUsers

Se muestran todos los usuarios, y un clic en un usuario debe mostrar los detalles del usuario a través de una solicitud ajax publicada:

app/controllers/UsersJqueryController.php
 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 vista asociada a la acción displayUsers:

app/views/UsersJqueryController/displayUsers.html
<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 }}

acción displayOneUser

app/controllers/UsersJqueryController.php
 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 vista asociada a la acción displayOneUser:

app/views/UsersJqueryController/displayUsers.html
<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 }}

Componentes semantic

A continuación, vamos a hacer un controlador implementando las mismas funcionalidades que antes, pero utilizando componentes PhpMv-UI (parte semántica).

HtmlButton ejemplo

Crear un nuevo controlador UsersJqueryController.

Ubiquity controller UsersCompoController -v
app/controllers/UsersJqueryController.php
 1namespace controllers;
 2
 3use Ubiquity\controllers\Router;
 4
 5/**
 6 * Controller UsersCompoController
 7 *
 8 * @property \Ajax\php\ubiquity\JsUtils $jquery
 9 * @route("users-compo")
10 */
11class UsersCompoController extends ControllerBase {
12
13     private function semantic() {
14             return $this->jquery->semantic();
15     }
16
17     /**
18      *
19      * @get
20      */
21     public function index() {
22             $bt = $this->semantic()->htmlButton('users-bt', 'Display users');
23             $bt->addIcon('users');
24             $bt->getOnClick(Router::path('display.compo.users'), '#users', [
25                     'hasLoader' => 'internal'
26             ]);
27             $this->jquery->renderDefaultView();
28     }

Nota

Al llamar a renderView o renderDefaultView sobre el objeto JQuery se realiza la compilación del componente, y se genera el HTML y JS correspondientes.

La vista asociada integra el componente de botón con la matriz q disponible en la vista :

app/views/UsersCompoController/index.html
<div class="ui container">
     {{ q['users-bt'] | raw }}
     <p></p>
     <div id="users">
     </div>
</div>
{{ script_foot | raw }}

//todo DataTable sample +++++++++++++++++