Código javascript para agregar líneas a formulario_ml en toba 3.4

Lo solucioné con ajax y javascript, pero queda muy improlijo porque el evento atender_respuesta() está vacío, lo único que hago es pasar el parámetro del id_empresa seleccionado y no envío ninguna respuesta el método javascript.
Este es el código del método ajax:

function ajax__cargar_empresa($parametros, toba_ajax_respuesta $respuesta)
{
	$this->s__id_empresa = $parametros['id_empresa'];
}

Y este es el código de la extensión del formulario:

<?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 parametro = {'id_empresa': id_empresa};
				this.controlador.ajax('cargar_empresa', parametro, this, this.atender_respuesta);
			}
		}
		{$this->objeto_js}.atender_respuesta = function()
		{
		}
		";
	}

}
?>

Matias,

trate de explicarte que no es necesario en ppio que recurras a un evento de paso de tab, que el mismo viaje al servidor te propaga los datos del combo.

A esta altura ya estoy perdido sobre lo que queres lograr, pasteame como te quedo el codigo del CI (completo) asi te digo que podes reacomodar y que secuencia seria la que te convendria usar en lugar de recurrir al pedido ajax… de paso entiendo mejor que queres lograr.

Saludos

Este es el código del ci con los dos formularios en forma de tab horizontal:

<?php
class ci_edicion extends sindicato_ci
{
	protected $s__id_empresa;
	protected $s__datos_recibo;
	protected $s__total;
	protected $s__datos_aportes;

	function get_relacion()
	{
		return $this->controlador->get_relacion();
	}

	//-----------------------------------------------------------------------------------
	//---- formulario -------------------------------------------------------------------
	//-----------------------------------------------------------------------------------

	function ajax__cargar_empresa($parametros, toba_ajax_respuesta $respuesta)
	{
		$this->s__id_empresa = $parametros['id_empresa'];
	}

	function conf__formulario(sindicato_ei_formulario $form)
	{
		if(!empty($this->s__datos_recibo)) $form->set_datos($this->s__datos_recibo);
		elseif($this->get_relacion()->tabla("recibos")->esta_cargada())
			$form->set_datos($this->get_relacion()->tabla("recibos")->get());
		elseif(!empty($this->s__total)) $form->ef('total')->set_estado($this->s__total);
	}

	function evt__formulario__modificacion($datos)
	{
		$this->get_relacion()->tabla("recibos")->set($datos);
	}

	//-----------------------------------------------------------------------------------
	//---- Configuraciones --------------------------------------------------------------
	//-----------------------------------------------------------------------------------

	function evt__recibo__salida()
	{
		$this->s__datos_recibo = $this->dep('formulario')->get_datos();
	}

	function evt__aportes__entrada()
	{
		if(!$this->get_relacion()->esta_cargada() && !empty($this->s__id_empresa)) {
			$id_empresa = quote($this->s__id_empresa);
			$sql = "select t_ap.id_aporte, t_ap.id_concepto, t_ap.importe from pendientes t_p "
				."inner join aportes_pendientes t_ap on t_p.id_pendiente=t_ap.id_pendiente where "
				."id_empresa=$id_empresa order by t_ap.id_aporte, t_ap.id_concepto";
			$datos = consultar_fuente($sql);
			$this->dep('formulario_ml')->set_datos($datos);
		}
	}

	function evt__aportes__salida()
	{
		$this->s__datos_aportes = $this->dep('formulario_ml')->get_datos();
	}

	//-----------------------------------------------------------------------------------
	//---- formulario_ml ----------------------------------------------------------------
	//-----------------------------------------------------------------------------------

	function ajax__get_importe($parametros, toba_ajax_respuesta $respuesta)
	{
		$id_aporte = quote($parametros['id_aporte']);
		$id_concepto = quote($parametros['id_concepto']);
		$sql = "select importe from aportes_pendientes where id_aporte=$id_aporte and "
			."id_concepto=$id_concepto";
		$aporte_pendiente = consultar_fuente($sql);
		$respuesta->set($aporte_pendiente);
	}

	function conf__formulario_ml(sindicato_ei_formulario_ml $form_ml)
	{
		if($this->get_relacion()->esta_cargada()) 
			return $this->get_relacion()->tabla("aportes_recibos")->get_filas(null, true);
		elseif(!empty($this->s__datos_aportes))
			return $this->s__datos_aportes;
	}

	function evt__formulario_ml__modificacion($datos)
	{
		$this->get_relacion()->tabla("aportes_recibos")->procesar_filas($datos);
		$this->get_relacion()->sincronizar();
		$aportes_recibos = $this->get_relacion()->tabla("aportes_recibos")->get_filas(null, true);
		foreach($aportes_recibos as $value)
		{
			$id_aporte = quote($value['id_aporte']);
			$id_concepto = quote($value['id_concepto']);
			$importe = $value['importe'];
			$sql = "select * from aportes_pendientes where id_aporte = $id_aporte and id_concepto = $id_concepto";
			$aporte_pendiente = consultar_fuente($sql);
			if(!empty($aporte_pendiente))
			{
				$id_aporte_pendiente = quote($aporte_pendiente[0]['id_aporte_pendiente']);
				$importe_pendiente = $aporte_pendiente[0]['importe'] - $importe;
				$sql = !empty($importe_pendiente) ? "update aportes_pendientes set importe = $importe_pendiente "
					."where id_aporte_pendiente = $id_aporte_pendiente" : "delete from aportes_pendientes "
					."where id_aporte_pendiente = $id_aporte_pendiente";
				$cant_ap = ejecutar_fuente($sql);
			}
		}
		$id_empresa = quote($this->s__id_empresa);
		$sql = "select p.id_pendiente, p.total, sum(ap.importe) as aporte from pendientes p left join "
			."aportes_pendientes ap on p.id_pendiente = ap.id_pendiente where p.id_empresa = $id_empresa "
			."group by p.id_pendiente, p.total";
		$pendientes = consultar_fuente($sql);
		foreach($pendientes as $value)
		{
			$id_pendiente = quote($value["id_pendiente"]);
			$total = $value["total"];
			$aporte = $value["aporte"];
			$pendiente = $total - $aporte;
			$sql_du = !empty($aporte) ? "update pendientes set total = $pendiente where "
				."id_pendiente = $id_pendiente" : "delete from pendientes where id_pendiente = $id_pendiente";
			$cant_p = ejecutar_fuente($sql_du);
		}
	}

	function evt__formulario_ml__procesar($datos)
	{
		$this->s__total = 0;
		foreach($datos as $value) $this->s__total += $value["importe"];
	}

}
?>

Y este es el código de la extensión del formulario para ejecutar el pedido ajax:

<?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 parametro = {'id_empresa': id_empresa};
				this.controlador.ajax('cargar_empresa', parametro, this, this.atender_respuesta);
			}
		}
		{$this->objeto_js}.atender_respuesta = function()
		{
		}
		";
	}

}
?>

Hola Matias,

mirando el codigo me queda la sensacion que estas haciendo las cosas en mas de una ocasion y eso te esta generando inconvenientes, si me lo permitis te ofrezco una version alternativa de tu codigo

<?php
class ci_edicion extends sindicato_ci
{
	protected $s__id_empresa;
	protected $s__datos_recibo;
	protected $s__total;
	protected $s__datos_aportes;

	function get_relacion()
	{
		return $this->controlador->get_relacion();
	}

	//-----------------------------------------------------------------------------------
	//---- formulario -------------------------------------------------------------------
	//-----------------------------------------------------------------------------------

	function ajax__cargar_empresa($parametros, toba_ajax_respuesta $respuesta)
	{
		$this->s__id_empresa = $parametros['id_empresa'];
	}

	function conf__formulario(sindicato_ei_formulario $form)
	{
		if(!empty($this->s__datos_recibo)) 
			$form->set_datos($this->s__datos_recibo);
		elseif($this->get_relacion()->tabla("recibos")->esta_cargada())
			$form->set_datos($this->get_relacion()->tabla("recibos")->get());
		elseif(!empty($this->s__total)) 
			$form->ef('total')->set_estado($this->s__total);
	}

	function evt__formulario__modificacion($datos)
	{
		$this->s__datos_recibo = $datos;
		$this->get_relacion()->tabla("recibos")->set($datos);
	}

	//-----------------------------------------------------------------------------------
	//---- Configuraciones --------------------------------------------------------------
	//-----------------------------------------------------------------------------------

	/*function evt__recibo__salida()
	{
		$this->s__datos_recibo = $this->dep('formulario')->get_datos();
	}*/

	/*function evt__aportes__entrada()
	{
		if(! $this->get_relacion()->esta_cargada() && !empty($this->s__id_empresa)) {
			$this->dep('formulario_ml')->set_datos($this->get_datos_empresa($this->s__id_empresa));
		}
	}*/

	/*function evt__aportes__salida()
	{
		$this->s__datos_aportes = $this->dep('formulario_ml')->get_datos();
	}*/

	//-----------------------------------------------------------------------------------
	//---- formulario_ml ----------------------------------------------------------------
	//-----------------------------------------------------------------------------------

	function ajax__get_importe($parametros, toba_ajax_respuesta $respuesta)
	{
		$id_aporte = quote($parametros['id_aporte']);
		$id_concepto = quote($parametros['id_concepto']);
		$sql = "select importe from aportes_pendientes where id_aporte=$id_aporte and "
			."id_concepto=$id_concepto";
		$aporte_pendiente = consultar_fuente($sql);
		$respuesta->set($aporte_pendiente);
	}

	function conf__formulario_ml(sindicato_ei_formulario_ml $form_ml)
	{

		if($this->get_relacion()->esta_cargada()) 
			$form_ml->set_datos($this->get_relacion()->tabla("aportes_recibos")->get_filas(null, true));
		elseif(!empty($this->s__datos_aportes))
			$form_ml->set_datos($this->s__datos_aportes);
		elseif (!empty($this->s__id_empresa))
			$form_ml->set_datos($this->get_datos_empresa($this->s__id_empresa));
	}

	function evt__formulario_ml__modificacion($datos)
	{

		$this->s__datos_aportes = $datos;		//Asegurate que el evt de modificacion en toba_editor este marcado como implicito

		$this->get_relacion()->tabla("aportes_recibos")->procesar_filas($datos);
		$this->get_relacion()->sincronizar();				//OJO aca ya estas impactando las tablas (independientemente de los updates inferiores)

		$aportes_recibos = $this->get_relacion()->tabla("aportes_recibos")->get_filas(null, true);

		##
		# todo esto incluido el SINCRONIZAR previo deberia estar en una unica TRANSACCION MIRA EL AP!
		# de paso sumale un try/catch
		##
		foreach($aportes_recibos as $value)
		{			
			$aporte_pendiente = $this->get_pendientes($value['id_aporte'], $value['id_concepto']);
			if(!empty($aporte_pendiente))
			{
				$id_aporte_pendiente = quote($aporte_pendiente[0]['id_aporte_pendiente']);
				$importe_pendiente = $aporte_pendiente[0]['importe'] - $value['importe'];

				$sql = !empty($importe_pendiente) ? "update aportes_pendientes set importe = $importe_pendiente "
					."where id_aporte_pendiente = $id_aporte_pendiente" : "delete from aportes_pendientes "
					."where id_aporte_pendiente = $id_aporte_pendiente";
				$cant_ap = ejecutar_fuente($sql);
			}
		}

		$pendientes = $this->get_pendientes_x_empresa($this->s__id_empresa);
		foreach($pendientes as $value)
		{
			$id_pendiente = quote($value["id_pendiente"]);
			$pendiente = quote($value["total"] - $value["aporte"]);			
			$sql_du = !empty($value["aporte"]) ? "update pendientes set total = $pendiente where "
				."id_pendiente = $id_pendiente" : "delete from pendientes where id_pendiente = $id_pendiente";
			$cant_p = ejecutar_fuente($sql_du);
		}

		##
		# FIN DE LA TRANSACCION
		##


	}

	function evt__formulario_ml__procesar($datos)
	{
		/*
		 * Este evento se dispara por botonera?.. tene en cuenta que se va a disparar evt__formulario_ml__modificacion
         * si esta configurado como `implicito`, capaz te conviene hacer la cuenta directamente en el otro metodo
         */
		$this->s__total = 0;
		foreach($datos as $value) 
			$this->s__total += $value["importe"];
	}

	protected function get_datos_empresa($empresa)
	{
		$id_empresa = quote($empresa);
		$sql = "select t_ap.id_aporte, t_ap.id_concepto, t_ap.importe 
				  from pendientes t_p "
				."inner join aportes_pendientes t_ap on t_p.id_pendiente=t_ap.id_pendiente 
					where "
				."id_empresa=$id_empresa order by t_ap.id_aporte, t_ap.id_concepto";
		$datos = consultar_fuente($sql);
		return $datos;
	}

	protected function get_pendientes($aporte, $concepto)
	{
		$id_aporte = quote($aporte);
		$id_concepto = quote($concepto);
		$sql = "select * from aportes_pendientes where id_aporte = $id_aporte and id_concepto = $id_concepto";
		return consultar_fuente($sql);
	}

	protected function get_pendientes_x_empresa($empresa)
	{
		$id_empresa = quote($empresa);
		$sql = "select p.id_pendiente, p.total, sum(ap.importe) as aporte 
				from pendientes p left join "
			."aportes_pendientes ap on p.id_pendiente = ap.id_pendiente 
				where p.id_empresa = $id_empresa "
			."group by p.id_pendiente, p.total";
		return consultar_fuente($sql);
	}


}
?>

me faltan algunos datos sobre como estan configurados los eventos de los formularios en toba_editor.. pero creo que eso reflejaria el ciclo mas o menos.

Presta atencion particular a lo que menciono sobre la transaccion, si se te cae el pedido de pagina te va a quedar inconsistente la bd.

Saludos

Hola @richard, gracias por la respuesta, te paso el código del ci_edicion como lo tengo ahora:

<?php
class ci_edicion extends sindicato_ci
{
    protected $s__id_empresa;
    protected $s__datos_recibo;
    protected $s__datos_aportes;

    function get_relacion()
    {
        return $this->controlador->get_relacion();
    }

    //-----------------------------------------------------------------------------------
    //---- formulario -------------------------------------------------------------------
    //-----------------------------------------------------------------------------------

    function ajax__cargar_empresa($parametros, toba_ajax_respuesta $respuesta)
    {
        $this->s__id_empresa = $parametros['id_empresa'];
    }

    function conf__formulario(sindicato_ei_formulario $form)
    {
        if(!empty($this->s__datos_recibo))
            $form->set_datos($this->s__datos_recibo);
        elseif($this->get_relacion()->tabla("recibos")->esta_cargada())
            $form->set_datos($this->get_relacion()->tabla("recibos")->get());
    }

    function evt__formulario__modificacion($datos)
    {
        $this->s__datos_recibo = $datos;
        $this->get_relacion()->tabla("recibos")->set($datos);
    }

    //-----------------------------------------------------------------------------------
    //---- formulario_ml ----------------------------------------------------------------
    //-----------------------------------------------------------------------------------

    function ajax__get_importe($parametros, toba_ajax_respuesta $respuesta)
    {
        $aporte_pendiente = $this->get_pendientes($parametros['id_aporte'], $parametros['id_concepto']);
        $respuesta->set($aporte_pendiente);
    }

    function conf__formulario_ml(sindicato_ei_formulario_ml $form_ml)
    {
        if($this->get_relacion()->esta_cargada())
            $form_ml->set_datos($this->get_relacion()->tabla("aportes_recibos")->get_filas(null, true));
        elseif(!empty($this->s__datos_aportes))
            $form_ml->set_datos($this->s__datos_aportes);
        elseif (!empty($this->s__id_empresa))
            $form_ml->set_datos_defecto($this->get_datos_empresa($this->s__id_empresa));
    }

    function evt__formulario_ml__modificacion($datos)
    {
        $this->s__datos_aportes = $datos;
        $this->get_relacion()->tabla("aportes_recibos")->procesar_filas($datos);
        $this->get_relacion()->sincronizar();
        $aportes_recibos = $this->get_relacion()->tabla("aportes_recibos")->get_filas(null, true);
        $aportes_pendientes = toba::tabla("aportes_pendientes");
        $total = 0;
        foreach($aportes_recibos as $value)
        {
            $importe = $value['importe'];
            $aporte_pendiente = $this->get_pendientes($value['id_aporte'], $value['id_concepto']);
            if(!empty($aporte_pendiente))
            {
                $id_aporte_pendiente = array('id_aporte_pendiente'=>$aporte_pendiente['id_aporte_pendiente']);
                $aportes_pendientes->cargar($id_aporte_pendiente);
                $aporte_pendiente['importe'] -= $importe;
                if(!empty($aporte_pendiente["importe"])) $aportes_pendientes->set($aporte_pendiente);
                else $aportes_pendientes->eliminar_todo();
                $aportes_pendientes->sincronizar();
            }
            $total += $importe;
        }
        $recibo = $this->get_relacion()->tabla('recibos')->get();
        $recibo["total"] = $total;
        $this->get_relacion()->tabla('recibos')->set($recibo);
        $pendiente = $this->get_pendientes_x_empresa($this->s__id_empresa);
        $pendientes = toba::tabla("pendientes");
        foreach($pendiente as $value)
        {
            $array_pendiente = array("id_pendiente" => $value["id_pendiente"]);
            $pendientes->cargar($array_pendiente);
            $datos = $pendientes->get();
            $datos["total"] = $value["aporte"];
            $pendientes->set($datos);
        }
        $pendiente = $this->get_pendientes_baja($this->s__id_empresa);
        foreach($pendiente as $value) {
            $array_pendiente = array("id_pendiente" => $value["id_pendiente"]);
            $pendientes->cargar($array_pendiente);
            $pendientes->eliminar_todo();
        }
        $aportes_pendientes->resetear();
        $pendientes->resetear();
    }

    protected function get_datos_empresa($empresa)
    {
        $id_empresa = quote($empresa);
        $sql = "select t_a.periodo, t_ap.id_aporte, t_ap.id_concepto, t_ap.importe from pendientes t_p inner join "
            ."aportes_pendientes t_ap on t_p.id_pendiente=t_ap.id_pendiente inner join aportes t_a on "
            ."t_a.id_aporte=t_ap.id_aporte where t_p.id_empresa=$id_empresa and t_ap.anula=false and "
            ."t_p.anula=false order by t_ap.id_aporte, t_ap.id_concepto";
        $datos = consultar_fuente($sql);
        foreach($datos as $key => $value) {
            $datos[$key]["referencia"] = "COBRANZA PERIODO ".$value["periodo"];
        }
        return $datos;
    }

    protected function get_pendientes($aporte, $concepto)
    {
        $array_aportes_pendientes = array("id_aporte"=>$aporte,"id_concepto"=>$concepto);
        $aportes_pendientes = toba::tabla("aportes_pendientes");
        $aportes_pendientes->cargar($array_aportes_pendientes);
        return $aportes_pendientes->get();
    }

    protected function get_pendientes_x_empresa($empresa)
    {
        $id_empresa = quote($empresa);
        $sql = "select p.id_pendiente, p.total, sum(ap.importe) as aporte from pendientes p left join "
            ."aportes_pendientes ap on p.id_pendiente = ap.id_pendiente where p.id_empresa = $id_empresa "
            ."group by p.id_pendiente, p.total";
        return consultar_fuente($sql);
    }

    protected function get_pendientes_baja($empresa)
    {
        $id_empresa = quote($empresa);
        $sql = "select * from pendientes p where not exists (select '' from aportes_pendientes ap "
            ."where p.id_pendiente = ap.id_pendiente and ap.anula=false) and p.id_empresa = $id_empresa";
        return consultar_fuente($sql);
    }

}
?>

Te comento que hice los cambios que pusiste vos, pero me sigue dando el error porque el atributo apex_ei_analisis_fila del array $datos del evento evt__formulario_ml__modificacion sigue siendo igual a M.