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
:
...
"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:
/**
* 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:
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:
<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
)
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 }}
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:
<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:
namespace controllers;
class FooController extends ControllerBase {
...
/**
*@get("c","name"=>"action.c")
*/
public function cAction() {
echo \rand(0, 1000);
}
}
La vista asociada:
<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 }}
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.
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:
Acción index
La acción index debe mostrar un botón para obtener la lista de usuarios, cargada mediante una petición 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 vista por defecto asociada a la acción 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 }}
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:
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:
<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
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:
<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).