Tengo una pantalla que tiene un componente ci con dos pantallas en forma de tab horizontal, en un tab tengo un formulario y en el otro tengo un formulario_ml, en el formulario tengo un ef_combo_editable, quiero que cuando hago clic en un elemento del combo editable me haga una consulta a una tabla hija de muchos a muchos y me cree las líneas del formulario_ml desde la consulta a esa tabla, ¿cuál es y dónde pongo el código javascript para hacer eso?
Ahí conseguí un código en chatgpt, pero me da el error SyntaxError: Unexpected token ‘<’, "<!DOCTYPE "… is not valid JSON, este es el código de extensión del formulario donde selecciono el elemento del combo editable:
<?php
class ei_formulario extends sindicato_ei_formulario
{
//-----------------------------------------------------------------------------------
//---- JAVASCRIPT -------------------------------------------------------------------
//-----------------------------------------------------------------------------------
function extender_objeto_js()
{
echo "
//---- Procesamiento de EFs --------------------------------
{$this->objeto_js}.evt__id_empresa__procesar = function(es_inicial)
{
var id_empresa = this.ef('id_empresa').get_estado();
if (id_empresa != apex_ef_no_seteado) {
var parametros = {'id_empresa': id_empresa};
this.ajax('cargar_pendientes_aportes', parametros, this.atender_respuesta);
}
}
{$this->objeto_js}.ajax = function(operacion, parametros, callback) {
var url = 'aplicacion.php?menu=' + operacion;
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(parametros)
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok ' + response.statusText);
}
return response.json();
})
.then(data => callback.call(this, data))
.catch(error => console.error('Error:', error));
}
{$this->objeto_js}.atender_respuesta = function(datos) {
if (datos) {
alert(datos);
this.cargar_datos_formulario_ml(datos);
}
}
{$this->objeto_js}.cargar_datos_formulario_ml = function(datos) {
var filas = [];
for (var i = 0; i < datos.length; i++) {
filas.push({
'id_aporte': datos[i].id_aporte,
'id_concepto': datos[i].id_concepto,
'importe': datos[i].importe
});
}
this.dep('formulario_ml').cargar_datos(filas);
}
";
}
}
?>
Este es el código de ajax__cargar_pendientes_aportes:
function ajax__cargar_pendientes_aportes($parametros, toba_ajax_respuesta $respuesta)
{
$id_empresa = $parametros['id_empresa'];
$this->id_empresa = array("id_empresa" => quote($id_empresa));
$pendientes = $this->get_relacion()->tabla("pendientes")->get_filas($this->id_empresa, true);
$this->get_relacion()->tabla("aportes_pendientes")->set_cursor($pendientes);
$datos = $this->get_relacion()->tabla("aportes_pendientes")->get_filas(null, true);
echo json_encode($datos);
}
Podrían decirme dode está el error por favor?
Ahí encontré como hacer el código de ajax, tengo que hacer this.controlador.ajax, pero me da otro error en el método que escucha del lado del servidor, ese método tiene dos parámetros como bien saben: $parámetros y toba_ajax_respuesta $respuesta, este es el código del javascript en la extensión del ei_formulario:
{$this->objeto_js}.evt__id_empresa__procesar = function(es_inicial)
{
var id_empresa = this.ef('id_empresa').get_estado();
if (id_empresa != apex_ef_no_seteado) {
var parametros = {'id_empresa': id_empresa};
this.controlador.ajax_cadenas('cargar_periodo', parametros, this, this.atender_respuesta);
}
}
Y este es el método php:
function ajax__cargar_periodo($parametros, toba_ajax_respuesta $respuesta)
{
$id_empresa = quote($parametros['id_empresa']);
$sql = "select max(periodo) as periodo from aportes where id_empresa = $id_empresa";
$aporte = consultar_fuente($sql);
$periodo = "";
if(!empty($aporte))
{
$ahora = new DateTime("now");
list($anio, $mes) = explode("-", $aporte[0]["periodo"]);
$anio = intval($anio);
$mes = intval($mes);
$fechaAporte = $ahora->setDate($anio, $mes, 1);
$intervalo = new DateInterval('P1M');
$fechaAporte = $fechaAporte->add($intervalo);
$periodo = $fechaAporte->format("Y-m");
}
$respuesta->agregar_cadena('periodo', $periodo);
}
¿Qué devuelve la función serializar del archivo basico.js y cómo lo transformo a un array de php?
Ahí cambié este código por este otro:
<?php
class form_recibo extends sindicato_ei_formulario
{
//-----------------------------------------------------------------------------------
//---- JAVASCRIPT -------------------------------------------------------------------
//-----------------------------------------------------------------------------------
function extender_objeto_js()
{
echo "
//---- Procesamiento de EFs --------------------------------
{$this->objeto_js}.evt__id_empresa__procesar = function(es_inicial)
{
var id_empresa = this.ef('id_empresa').get_estado();
if (id_empresa != apex_ef_no_seteado) {
var parametros = {'id_empresa': id_empresa};
this.controlador.ajax('cargar_pendientes_aportes', parametros, this, this.atender_respuesta);
}
}
{$this->objeto_js}.atender_respuesta = function(data) {
if (data) {
datos = JSON.parse(data);
this.cargar_datos_formulario_ml(datos);
}
}
{$this->objeto_js}.cargar_datos_formulario_ml = function(datos) {
var filas = [];
for (var i = 0; i < datos.length; i++) {
filas.push({
'id_aporte': datos[i].id_aporte,
'id_concepto': datos[i].id_concepto,
'importe': datos[i].importe
});
}
this.controlador.dep('formulario_ml').set_datos(filas);
}
";
}
}
?>
Pero me da error que no existe el método set_datos, ¿cómo puedo hacer con javascript para agregar varias filas en un ei_formulario_ml?
¿Cómo identifico el formulario_ml dentro del javascript de form_recibo?
Me está dando error que no existe el método crear_fila y vi en ei_formulario_ml.js que si existe.
Si tenes 2 tabs si o si debes interactuar con el servidor para pasar de uno a otro, lo que significa que podes usar PHP para realizar la carga del otro formulario sin tener que hacer un pedido ajax.
Recorda que en la temporalidad de procesamiento del pedido… primeramente se atienden los eventos (la modificacion del formulario que tiene el combo), luego se configuran los elementos que vas a enviar al cliente (el formulario del segundo tab) y finalmente se envia el marcado completo al cliente.
No necesitas JS para hacer esa transicion, lo resolves todo en PHP.
El ML te va a agregar tantas filas como datos le pases.
Y cómo hago para pasarle el id_empresa elegido en el combo_editable del formulario que está en el tab izquierdo al formulario_ml que está en el tab derecho de la pantalla?
Matias,
esta todo dentro de la misma operacion, que deberias pasarle?.. no entiendo me perdi.
Sí, está todo dentro de la misma operación, tengo una pantalla con el cuadro (pant_seleccion), con los eventos crud, y otra pantalla (pant_edicion) donde tengo un ci (ci_edicion.php) donde tengo dos pantallas (recibo y aportes) que las tengo en tipo de navegación tab horizontal, en recibo tengo un ef_combo_editable (id_empresa) que cuando selecciono una empresa de la lista necesito que me agregue las líneas al formulario_ml de la pantalla aportes desde la consulta a dos tablas (pendientes y aportes_pendientes) que están relacionadas entre sí y la primera (pendientes) está relacionada con empresas mediante el campo id_empresa
¿Cómo hago para disparar un evento en el servidor desde un ef_combo_editable sin usar js y que los datos que tiene ese evento pasarlo al conf__formulario_ml?
En vez de esto:
function ajax__cargar_pendientes_aportes($parametros, toba_ajax_respuesta $respuesta)
{
$id_empresa = $parametros['id_empresa'];
$this->id_empresa = array("id_empresa" => quote($id_empresa));
$pendientes = $this->get_relacion()->tabla("pendientes")->get_filas($this->id_empresa, true);
$this->get_relacion()->tabla("aportes_pendientes")->set_cursor($pendientes);
$datos = $this->get_relacion()->tabla("aportes_pendientes")->get_filas(null, true);
$respuesta->set($datos);
}
Poner esto:
function evt__id_empresa()
{
$id_empresa = $parametros['id_empresa'];
$this->id_empresa = array("id_empresa" => quote($id_empresa));
$pendientes = $this->get_relacion()->tabla("pendientes")->get_filas($this->id_empresa, true);
$this->get_relacion()->tabla("aportes_pendientes")->set_cursor($pendientes);
$datos = $this->get_relacion()->tabla("aportes_pendientes")->get_filas(null, true);
}
Por favor, necesito resolver este tema con urgencia, mi cliente me está presionando para que le entregue el sitio.
la navegacion misma desde el Tab (recibos) hacia (aportes) te dispara el evento en el servidor y envia el valor del combo hacia el mismo, una vez tenes ese dato en el servidor podes cargar las filas en el ML en el metodo conf de dicho formulario. Es lo que te venia diciendo aca.
No entiendo para que queres disparar un evento desde el primer Tab para un formulario en un tab que no es visible en ese momento en lugar de usar el viaje al servidor (para mostrar el Tab aportes) para enviar los mismos. Hay algun requerimiento funcional que no estes mencionando y fuerce esto que queres hacer?
Si necesitas cargar varias empresas en el primer Tab, usa un ML ahi tambien y envia varios combos de un solo saque en lugar de complicarte inventando la polvora verde.
Saludos
Ahhh ya entiendo, no entendía como lo tenía que hacer, pensé que tenía que hacerlo al hacer clic en el combo_editable, muchas gracias.
¿Qué métodos tengo que agregar en el código del ci para atrapar el evento de cambio de tab y en cuál pongo la consulta a las tablas para agregar las líneas al formulario_ml?
El tab del formulario_ml se llama aportes.
Disculpen la insistencia, pero necesito solucionar esto con urgencia, mi cliente me está presionando o contrata a otro, no quiero perder este negocio, por favor.
Muchas gracias por su ayuda, ya lo descubrí, es con el método evt__pantalla__entrada.
Yo lo solucioné con código ajax y php, tengo la extensión del formulario donde uso evt__id_empresa__procesar y llamo un método ajax para asignar el valor del id_empresa seleccionado ($this->s__id_empresa = $parametros['id_empresa'];
) y después hago la consulta en el método evt__aportes__entrada, por favor decime si hay una manera de hacerlo sin ajax y por favor poneme el código porque no tengo ni idea de como hacerlo.
Por favor, necesito que me respondan este pregunta, tengo que solucionarlo con urgencia.
Hola Matias,
esto se esta volviendo monotono, no termino de entender que queres hacer y te lo pregunte al menos 2 veces, no lo explicaste completamente nunca. Si solo tenes preguntas y nunca respondes las mias, te encerras solito en un rincon del que nadie te puede sacar mas que vos mismo.
Tampoco entiendo en que estado esta lo que hiciste, tu propio msg previo dice que lo solucionaste.
Muchas gracias por la respuesta, lo que yo necesito saber es si hay un evento de paso de un tab a otro que reciba por parámetro los datos del tab que estaba activo antes del paso, en este caso sería el tab donde está el formulario con el ef id_empresa, sería algo así:
function evt__paso_tab($datos)
{
$id_empresa = quote($datos['id_empresa']);
// código para llenar el formulario_ml
}