Cómo implementar un diálogo modal de jQuery UI en un plugin de WordPress
Tengo un plugin de WordPress que crea un menú principal personalizado y submenús correctamente. El submenú llama a este formulario PHP de BranchMaintenance (ver código abajo), que muestra sucursales en una tabla desde la base de datos (usando $wpdb
).
El problema es hacer que aparezca el formulario modal de jQuery UI. Probablemente mi código sea el responsable... no tengo claro cosas como funciones de nivel superior sin nombre como aparece en el código, por ejemplo $(function() {
Estoy intentando activar los scripts necesarios para: a) Ocultar inicialmente el formulario del diálogo (aparece encima de mi tabla de datos de sucursales)... probablemente lo hice mal b) Mostrarlo cuando sea llamado (esto sigue como en el código demo original)
<div class="wrap" id="main">
<form name="Mantenimiento de Sucursales Sandwich Baron" method="post" action="<?php echo str_replace( '%7E', '~', $_SERVER['REQUEST_URI']); ?>">
<script>
$(function() {
// una solución para un fallo en el sistema demo (http://dev.jqueryui.com/ticket/4375), ¡ignorar!
//$( "#dialog:ui-dialog" ).dialog( "destroy" );
$( "#dialog-form" ).dialog({
autoOpen: false,
height: 300,
width: 350,
modal: true,
buttons: {
"Crear una cuenta": function() {
var bValid = true;
allFields.removeClass( "ui-state-error" );
if ( bValid ) {
//Añade los datos capturados a la tabla en la página principal
//$( "#users tbody" ).append( "<tr>" +
// "<td>" + txtBrname.val() + "</td>" +
// "<td>" + txtStrAddress.val() + "</td>" +
// "<td>" + txtManager.val() + "</td>" +
//"</tr>" );
$( this ).dialog( "close" );
}
},
Cancelar: function() {
$( this ).dialog( "close" );
}
},
close: function() {
allFields.val( "" ).removeClass( "ui-state-error" );
}
});
$( "#create-branch" )
.button()
.click(function() {
$( "#dialog-form" ).dialog( "open" );
});
});
</script>
<?php
function fn_DeleteBranch(Id)
{
//$wpdb-> etc etc ; //elimina esta sucursal (por Id) de la base de datos
}
?>
<style>
body { font-size: 62.5%; }
label, input { display:block; }
input.text { margin-bottom:12px; width:95%; padding: .4em; }
fieldset { padding:0; border:0; margin-top:25px; }
h1 { font-size: 1.2em; margin: .6em 0; }
div#users-contain { width: 350px; margin: 20px 0; }
div#users-contain table
{ margin: 1em 0; border-collapse: collapse; width: 100%; }
div#users-contain table td, div#users-contain table th
{ border: 1px solid #eee; padding: .6em 10px; text-align: left; }
.ui-dialog .ui-state-error { padding: .3em; }
.validateTips { border: 1px solid transparent; padding: 0.3em; }
</style>
<?php
// Hook para añadir el formulario de diálogo (ESPERO)
add_action('admin_init', "#dialog-form" );
add_action( 'admin_init', 'my_Deregister_scripts' );
add_action( 'admin_enqueue_scripts-options_page-{page}', 'myplugin_admin_scripts' );
function my_Deregister_scripts() {
wp_deregister_script( 'jquery-ui' ); //Desregistrar la versión de WP
}
function myplugin_admin_scripts(){
// sintaxis wp_enqueue_script( $handle,$src,$deps,$ver,$in_footer );
// $src = la URL donde se almacenan los scripts
// $in_footer Normalmente los scripts se colocan en la sección <head>, por defecto es false
wp_enqueue_script('jquery');
wp_enqueue_script('jquery-ui-core');
wp_enqueue_script('jquery-ui-dialog');
wp_enqueue_script('jquery-ui-1.8.17.custom.min' );
wp_enqueue_script('jquery-bgiframe-2.1.2' );
wp_enqueue_script('jquery-ui-mouse' );
wp_enqueue_script('jquery-ui-button' );
wp_enqueue_script('jquery-ui-draggable' );
wp_enqueue_script('jquery-ui-position' );
wp_enqueue_script('jquery-ui-resizable' );
wp_enqueue_script('jquery-effects-core' );
wp_enqueue_script('jquery-ui-widget' );
wp_enqueue_style('jquery-style', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/smoothness/jquery-ui.css');
}
?>
<div id="dialog-form" title="Edición de Sucursal">
<p class="validateTips">Todos los campos del formulario son requeridos.</p>
<form>
<fieldset>
<label for="BrName">Nombre de Sucursal</label>
<input type="text" name="txtBrname" id="txtBrName" class="text ui-widget-content ui-corner-all" />
<label for="Tel">Teléfono</label>
<input type="text" name="txtTel" id="txtTel" value="" class="text ui-widget-content ui-corner-all" />
</fieldset>
</form>
</div>
<div id="users-contain" class="ui-widget">
<?php
echo "<table border='1' cellpadding='0' width='100%'>";
echo "<tr>
<th>ID</th>
<th>Nombre Sucursal</th>
<th>¿Express?</th>
<th>Dirección</th>
<th>Área</th>
<th>Gerente</th>
<th>Propietario</th>
<th>Teléfono</th>
<th>Celular</th>
<th>Email</th>
<th>Editar</th>
<th>Eliminar</th>
</tr>";
global $wpdb;
$myrows = $wpdb->get_results("SELECT * FROM wp_sbbranches");
// recorrer resultados de la consulta a la base de datos, mostrándolos en la tabla
foreach ($myrows as $row) {
echo "<tr>";
echo '<td style="border:none;">' .$row->BrId. '</td>';
echo '<td style="border:none;">' .$row->BrName. '</td>';
echo '<td style="border:none;">' .$row->BrTel. '</td>';
echo '<td style="border:none;"><button onclick="create-branch(' . $row->Id. ')"></td>';
echo '<td style="border:none;"><button onclick="fn_DeleteBranch(' . $row->Id. ')"></td>';
echo "</tr>";
}
// cerrar tabla
echo "</table>";
?>
<button id="create-branch(' 0 ')" >Crear nueva sucursal</button>
</div>

Aunque no tengo claro exactamente lo que necesitas, tal vez podría ofrecer algunos consejos.
En primer lugar, la documentación en los diversos sitios tiene todo lo que necesitas, así que deberías visitar el WordPress Codex y los ejemplos de jQuery UI.
Hooks
admin_init: Aquí puedes desregistrar/registrar scripts. Si planeas usar un script personalizado de jQuery UI, por ejemplo:
function my_register_scripts()
{
wp_deregister_script( 'jquery-ui' ); //Desregistra la versión de WP
wp_register_script( 'jquery-ui', plugins_url( 'js/jquery-ui.js', __FILE__ ), array( 'jquery' ) ); //Registra la tuya
}
add_action( 'admin_init', 'my_register_scripts' );
admin_menu: añade la página de tu plugin, enlaza una página específica para tus scripts también
function my_menu()
{
$admin_page = add_menu_page(/*Consulta el codex para los argumentos, enlace abajo*/); //Añade tu página
//usa la variable $admin_page para cargar scripts de forma específica
add_action( 'admin_print_styles-' . $admin_page, 'function_that_enqueues_css_here' );
add_action( 'admin_print_scripts-' . $admin_page, 'function_that_enqueues_js_here' );
}
add_action( 'admin_menu', 'my_menu' );
EDIT: Ejemplo de Diálogo
Aquí tienes un ejemplo simple de un diálogo modal que abre un formulario:
$(document).ready(function(){
$('#form-wrap').dialog({
autoOpen: true, //FALSE si abres el diálogo con, por ejemplo, un clic en un botón
title: 'Mi Formulario',
modal: true
});
});
El código anterior asume que tienes un <div> u otra etiqueta con el ID 'form-wrap'. Dentro colocas tu formulario.
Estructura de Carpetas
Podría estar equivocado, pero no creo que esto importe mucho, simplemente coloco mis archivos .js en una carpeta /js, css en /css, etc...
Usa plugins_url() cuando encoles archivos desde el directorio de tu plugin.
La página de jQuery UI Dialog debería tener todos los ejemplos que necesitas.
Cuando uso esos diálogos, generalmente genero HTML en la página (con display:none) y lo uso para el popup del diálogo.
Espero que algo de esto haya ayudado.
EDIT
Además, creo que personalizar tu propio script de jQuery UI en el sitio web de jQuery UI te dará menos archivos para encolar.
EDIT 2
Tienes errores en tus add_actions si el código anterior es lo que estás usando.
add_action('admin_init', "#dialog-form" );
El segundo argumento debería ser una función PHP, eso parece el ID de tu div HTML.
add_action( 'admin_enqueue_scripts-options_page-{page}', 'myplugin_admin_scripts' );
Estoy bastante seguro de que {page} debe ser reemplazado por la página específica en la que quieres llamar los scripts.
Si jQuery es tu principal problema, sugiero que intentes que funcione en una página HTML simple sin relación con tu sitio hasta que lo tengas funcionando, y luego configures los hooks correctamente.

Gracias, ahora he hecho básicamente eso... me tomó un tiempo juntar todas las partes. Tengo mi plugin Admin TopLevel funcionando con sus submenús, uno de los cuales maneja el formulario BranchMaint mencionado... que debe tener el popup/dialog que debería manejar las Ediciones y/o Insertar NewBranch, y usar $wpdb para insertar o actualizar según corresponda. Sin embargo, la funcionalidad del popup todavía no funciona. He actualizado mi código anterior, con action hooks a my-functions, por si eso ayuda.

Estoy investigando tu sugerencia (Shane), buscando información sobre tags etc. 2 semanas de php y WordPress. (11 años de c# Asp.net). También investigando cómo actualizar automáticamente el formulario principal.

Mira mi segunda edición - También, asegúrate de revisar el código fuente en la página renderizada para ver si se llaman los scripts, y cualquier plugin como Firebug para Firefox puede ayudar con errores de javascript.

¿Tu archivo de plugin se ve exactamente como el código de arriba? Podría ser útil si me muestras tu archivo de plugin.

y {page} también sí. Lo reemplacé con add_action( 'admin_init', 'myplugin_admin_scripts' ); Luego funcionó bien en una página html estándar (solo una copia de su demo con mis propias carpetas y et voilà, ningún problema) JQuery es... revisé mis temas 2011 y 2012 y edité el archivo Header.php agregué el Enque a jquery en él antes de la función wp_head. Es una instalación nueva de WP 3.3.1 en mi WAMPserver WinPC. PERO en mi página las inicializaciones de jquery están siendo ignoradas, es decir, no se invocan. ASÍ QUE mi 'formulario' con los campos que se supone que debe aparecer está visible con el resto de la tabla y campos inmediatamente.

y el botón emergente 'AddBranch' no hace absolutamente nada... Creo que debo seguir con tu sugerencia / formulario modal emergente por ahora (se me acaba el tiempo) y seguir probando/investigando esto de JQuery más adelante

Si usara mi 'fieldset' dentro de sus etiquetas de formulario y tu ejemplo de diálogo... ¿imagino que estaría bien encaminado?

Una pregunta sobre tu popup, ¿cómo lo llamas desde un clic de botón? No veo ningún evento asociado a él para un botón, o un ID de función al que el on-click del botón pueda hacer referencia.

Acabo de rehacer el formulario sin elementos de JQueryUI, solo la tabla y el fieldset junto con tu código de diálogo emergente (referencié el div #form-wrap en mi clic de botón), pero el div + fieldset aún se muestran en la página y no aparecen como emergente.

Coloqué una alerta en la función document.ready, pero tampoco se muestra. Imagino que mi plugin de WP no está respondiendo a JQuery...De vuelta a la mesa de investigación. Gracias de todos modos por tu ayuda, la aprecio.

Para abrir un diálogo al hacer clic en un botón, configuras el diálogo con el parámetro "autoOpen: false", luego al hacer clic en el botón, ejecutas $('#el_dialogo_que_configuraste').dialog( 'open' );

Debes hacer esto:
add_action( 'admin_enqueue_scripts', 'admin_scripts' );
function admin_scripts(){
wp_enqueue_script( 'jquery-ui-dialog' );
wp_enqueue_style( 'wp-jquery-ui-dialog' );
}
luego deberías usar:
jQuery('<div> ¡Hola! <div>').dialog({ modal:true, width:600 });
