Buenas tardes-noches,
Tal como prometí. Vuelvo a exponer un poco de luz al asunto.
Como dije antes, para lo que buscas se necesita realizar las cosas en 2 partes: la parte 1 consiste en tener llenado el combo con las opciones. Luego le sigue el paso que consiste en la llamada AJAX para que al seleccionar un item del combo, se obtenga cierta data.
Hagamos de cuenta que tienes una página "clientes.php" que es la página en donde se consultará y mostrará la info. Por un lado necesitamos un select que tendrá el listado, y unos cuantos span para mostrar la info*. En su concepción más simple y básica, y que nos interesa, en clientes.php tendremos algo como esto:
<select name="selcliente" id="selcliente">
*Podrían emplearse otros elementos html, aunque por comodidad y simplicidad si lo deja así.
Como puedes ver, el select así como está declarado sin ningún item. Hay en forma resumida, 2 alternativas a seguir.
Alternativa 1: completar el select al mismo momento de invocar y cargar la página del script clientes.php
Para ello basta con tener algo como esto:
<select name="selcliente" id="selcliente">
<?
$sql = "select id_clte, nombre from clientes WHERE ...";
$query = $conn->query($sql) or
die('Error al crear el query'); if ($query->num_rows > 0){
while ($cli = $query->fetch_assoc()){
?>
<option value="<?echo $cli['id_clte'];?>"><?echo $cli['nombre'];?><option>
<?
}
}
?>
</select>
Como puedes ver, en el mismo script php, al momento de declarar el select, allí mismo se embebe el codigo php para armar la consulta, ejecutar, e iterar sobre el conjunto de datos devuelto y meter todo en options.
El ejemplo está hecho con msyli OO, creería que no te sería problemas en cambiarlo por el enfoque estructurado empleando las funciones mysqli_* correspondientes. $conn es la variable donde se tiene la conexión, $sql contiene el string de la consulta SQL. $query por su parte almacena el objeto query creado, y con $cli accedemos a los registros.
Alternativa 2: completar el combo por llamada AJAX. Esta alternativa es un poco más indirecta, pero tiene la particularidad de que ofrece más dinamismo y la posibilidad de que se pueda invocar y obtener los nuevos clientes sin necesidad de recargar la página. Si disponemos de algún control que dispare la llamada a un hipotético CargarClientes().
Por un lado necesitamos un script php que será invocado vía AJAX que nos traiga el listado. Aquí hay variedad de formas de hacerlo, hay quienes prefieren ya traernos el contenido html con todos los options a meter dentro del select, y otros que prefieren un JSON con el objeto lista para luego iterar y meter item a item.
Las necesidades, cuestiones técnicoss-operativas pueden inclinarte la balanza para una u otra opción.
Yo voy a exponerte la 2da forma: JSON y meter item a item. Dejaré unos tips de como hacerlo por la alternativa "html".
Digamos que tenemos un 2do script llamado cargarclientes.php. Este script deberá tener algo como esto:
<?
// aquí los require() y algunas operaciones de control y evaluación de parámatros pasados
// ...
// aquí el código que nos interesa:
$sql = "SELECT id_clte, nombre FROM clientes WHERE... ";
$query = $conn->query($sql) or
die('error');
$i = -1;
if ($query->num_rows > 0){
while ($cli = $query->fetch_assoc()){
$i += 1;
'id' => $cli['id_clte'],
'value' => $cli['nombre']
);
$lista[$i] = $item;
}
} else {
'id' => 0,
'value' => 'Seleccione uno'
);
$lista[0] = $item;
}
// aquí devolvemos la lista
?>
Habrás notado que con esto consigo una estructura JSON que contenga algo como esto:
vector = { {id, value}, {id, value}, {id, value}, .... {id, value} }
Una lista donde cada posición contiene una dupla (id, value). ¿Porqué? Porque necesitaremos el id del cliente, para poder referenciar y consultar la info según el ID y obviamente el nombre. El id lo terminaremos metiendo en el atributo value del option, y el nombre será el texto del mismo. Necesitaremos conseguir algo como:
Ya tenemos el script que nos devuelva la lista, ahora necesitamos hacer el codigo JQuery y la llamada AJAX. Dentro de tu $(document).ready(function(){} tendrás algo como esto:
function CargarClientes(){
$.ajax({
type: 'GET',
url: 'admin/cargarclientes.php',
data: 'aqui la lista de paramatros que necesites pasarle al script php',
async: false,
//datatype: "html",
cache: false,
beforeSend: function(){},
complete: function(){},
success: function(data){
//alert(data);
var newOptions=jQuery.parseJSON(data);
//alert(newOptions);
$('#selcliente').empty();
var i = -1;
$.each(newOptions, function(key, value){
i += 1;
//alert(newOptions[i].key + '|' + newOptions[i].value);
$('#selcliente').append('<option value="'+ newOptions[i].id +'"'>' + newOptions[i].value + '</option>');
});
}
});
}
Luego, simplemente es cosa de invocar o llamar a esta función CargarClientes(), una buena alternativa es justo al ejecutarse el ready(), por lo que allí mismo basta con un CargarClientes();
Como he dicho, hay otras formas de devolver esta info. La alternativa quizá más poderosa es que el servidor ya nos traiga el html a meter dentro del select en lugar de delegar en el navegador cliente que haga el trabajo.
En este caso el script php en lugar de armar un vector nos bastaría con una simple variable $opciones en la que vamos concatenando el string con el html del option a medida que iteramos por los registros. Entonces en vez de hacer un $("nuestroselect").append() dentro de un for(), podemos hacer una única llamada append(). En este escenario en lugar de devolver el vector, podemos devolver algo como esto:
$salida['cantitems'] = $cantidad;
$salida['items] = $opciones;
echo json_encode($salida);
La estructura JSON se lee en nuestro js de la siguiente forma:
var newOptions = $.parse_JSON(data);
if (newOptions.cantidad > 0){
$('#selcliente').append(newOptions.items); // asumimos que items tendra todo el html
}
Notarás que no es mucho cambio. Cada forma tiene sus pros y contras. Y hasta es válido mezclar ambas cosas... en ocasiones tendrás que tener ya las cosas másticadas en forma HTML, y en otras más "sueltas" o estructuradas de otra forma.
Para no extender mucho el tema, corto el mensaje acá y continúo con la 2da parte en el siguiente mensaje.