Maneja datos de Mysql con Ajax

Consultar una base de datos con Ajax sin necesidad de librería, con soporte desde Internet explorer 7 , Firefox,Chrome, Safari.

Haciendo consultas a una mysql db con Ajax

puedes ver el demo de como quedo, cliqueando llamadas de Ajax a una base de datos.

Con Ajax y Javascript se pueden hacer cosas maravillosas, puedes hacer a los usuario interactuar con la pagina y deslumbrarlos con los cambios.. Pero no solo que se vea bonito sino también la usabilidad de la pagina se mejora en todos los aspectos para el usuario..
Lo difícil esque existen muchos exploradores por lo cual la compatibilidad es muy importante y es donde vienen los problemas porque algunos exploradores no respetan estándares, por esto se nos hace difícil tener una correcta compatibilidad , algunos ejemplos: Microsoft Explorer, Firefox, Chrome, Safari i otros..
Ademas que debemos nombrar los mas horribles que no les importa los estándares en la web, si me entendieron bien.. –>> Microsoft Explorer.
En la ayuda vienen librerías Javascript como Mootools, Jquery, Prototype y otros… Lo malo de esto es que si quieres hacer algo
simple como obtener los valores de una FORMA y hacer una llamada Ajax a un documento en tu servido que chequee tu base de datos.. es que es demasiada librería para hacer algo tan simple como eso. Entonces pensé voy hacer un script que envie los valores de los campos de la FORMA a un documento en mi servidor y este chequee si los valores están en la base de datos, parecido a un login, o un script buscador..
Consultar una base de datos con Ajax sin necesidad de librería, con soporte desde Internet explorer 7 , Firefox, Chrome, Safari.
El javascript que les voy a dar puede ser usado en FORMAS con cualquier cantidad de input tags de FORMAS, tan solo necesitas poner algunos parámetros para que este empiece a funcionar..
La Class tiene como nombre consulta(recipienteid, formaid, ajaxurl , metodo , sincronico); esta se instancia de esta manera:

var consultame         = new consulta('resAjax', 'iniciador', 'mysql.php');

ahora consultame sera el objeto conque trabajaremos, podes cambiarle el nombre que tiene pero para el tutorial este es el nombre a la variable que le daremos.

Teniendo nuestro objecto instanciado con argumentos predeterminados, la class recibe 3 argumentos mandatorios que son :

  • recipienteid ->Este es el id , de el tag en tu html, puede ser p, span, div, h, o cualquier html tag que acepte la propiedad de id.
  • formaid -> El id de la forma en tu HTML, la clase se ara cargo de obtener los valores de los input tags
  • ajaxurl -> el documento donde aras la consulta a tu servidor de mysql, recuerda que tiene que ser la dirección relativa a tu servidor, i que tienes que ser el mismo dominio donde tienes este script de javascript, o el Ajax no te permitirá que funcione…

Hay dos parámetros mas que no son mandatarios, estos son :

  • metodo-> Por defecto, dejándolo sin argumento, es POST. acepta POST Y GET.
  • sincronico-> TRUE Por defecto que es asincronico.. y FALSE sincronico.

Ahora la manera de iniciar nuestra clase y ponerla a trabajar es la siguiente.:

<script type="text/javaScript">
window.onload = function(){
        // inicia el objecto
        var consultame         = new consulta('resAjax', 'iniciador', 'mysql.php');
	    //  escucha el evento de submit
	    consultame.loadform();
}
</script>

Donde el metodo loadform(); ara que el script espere valores de la id de la FORMA pasada en el argumento formaid con el evento de onclick. y window.onload la iniciara cuando el arbol DOM en todo el html este completamente inicializado..

Ahora el script completo, llamado ajax_mysql.js, copia y pegalo.. a sido probado en Microsoft IE 7 mayor o igual , Chrome, Safari, Firefox

        /*
	 * @author  Neumann Valle Aka UTAN
	 * @email   vcomputadoras@yahoo.com, website vcomputadoras.com
	 * Parametros mandatorios son: recipienteid , formaid, ajaxurl
	 * donde recipienteid, es donde reciviremos el resultado de la consulta ajax.
	 * formaid, el id de la forma especificado en el html.
	 * ajaxurl , el documento donde hases el envio ajax o consulta.
	 * metodo , no es mandatorio, sera POST for defecto sin parametro
	 * sincronico, no es mandatorio si lo dejas en blanco se ara la llamada
	 * ajax asincronica.
	 */

	function consulta(recipienteid, formaid, ajaxurl , metodo , sincronico){

            this.recepienterid   = recipienteid;
	        this.formid          = formaid;
	        this.ajaxurl         = ajaxurl;
			this.method          = metodo     == undefined ? 'post': metodo     ;
			this.asynchronous    = sincronico == undefined ? true  : sincronico ;

		/*
		 * colocamos un evento en la forma o elemento con el id especificado
		 * browser independiente, trabaja con  >= ie7 y los otros exploradores
		 * estandares.. firefox, chrome, safari y otros.
		 */
	    consulta.prototype.loadform = function() {
	        var form = document.getElementById(this.formid);
	        if(form){
			    // para todos los browsers execto IE =< 7
		        if(form.addEventListener){
				    // agregamos un evento de submit a nuestra forma
			        form.addEventListener('submit' , function(){

					// declaramos nuestra variable que tendra nuestro datos de la forma
					var data = [];
					    /*
						 *  si tenemos mas imputs, en nuestra forma este loop se ara cargo
						 *  de crear un array con todos los datos de la forma
						 */
					    if(form.elements.length >= 1){
						    for(var i= 0; i < form.elements.length; i++){
					            data[form.elements[i].name] = form.elements[i].value;
					        }
						}else{
						    return false;
						}
					    //dejemonos de jugar mandemos el request a nuestro servidor
						this.sendRequest(data);
					}.bind(this));

				}else if(form.attachEvent){
				    // como ie,  <= ie8 no soporta el keyboard bind() esta es una buena solucion
				    consulta.prototype.binding();
					// agregamos el evento a nuestra forma
				    form.attachEvent('onsubmit' , function(){

					// declaramos nuestra variable que tendra nuestro datos de la forma
					var data = [];
					    /*
						 *  si tenemos mas imputs, en nuestra forma este loop se ara cargo
						 *  de crear un array con todos los datos de la forma
						 */
					    if(form.elements.length >= 1){
						    for(var i= 0; i < form.elements.length; i++){
					            data[form.elements[i].name] = form.elements[i].value;
					        }
						}else{
						    return false;
						}
						//dejemonos de jugar mandemos el request a nuestro servidor
						this.sendRequest(data);

				    }.bind(this));

				}
		    }
	    };
		// una function para serialize objetos
		consulta.prototype.serialize = function(obj)
		{
			var str = [];
			for(var p in obj)
			str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
			return str.join("&");


		};

		consulta.prototype.sendRequest = function(data){
		    // instanciamos nuestro ajax objeto
		    var request    =  new ajaxob();
			var recipiente = document.getElementById(this.recepienterid);
			var url        = this.ajaxurl;
		    // una timestamp que cambiara en cada enviada ajax, por el cache de IE.
		    var timestamp  = parseInt(new Date().getTime().toString().substring(0, 10));
		            // serialize el objeto que octuvimos de los input de la forma
					data = consulta.prototype.serialize(data);

					//caso especial para el get, este es enviado en el url
					if(this.method.toLowerCase() == 'get'){
					    url  = url + '?' + data + '&' ;
						data = null;
					}
					// enviemos la consulta de ajax
					request.open(this.method, url + '?t=' + timestamp , this.asynchronous);
					    // si usamos post, entonces enviemos los headers necesarios
					    if(this.method.toLowerCase() == 'post'){
				            request.setRequestHeader("Content-type","application/x-www-form-urlencoded");
				            request.setRequestHeader("Content-length", data.length);
					        request.setRequestHeader("Connection", "close");
					    }

					request.onreadystatechange = function(){
					    if(request.readyState == 4){
						    if(request.status == 200){
							    if(request.responseText != null && request.responseText != ''){
						            // mostremos el resultado en nuestro html
						            if(recipiente) recipiente.innerHTML = request.responseText;
								}else{
								    alert('hubo un error:  estas seguro que, '+ this.ajaxurl +' esta printeando resultados?');
								}
							}else{
							    alert('hubo un error al enviar la consulta : ' + request.statusText);
							}
						}
					}.bind(this)
					request.send(data);
		};
		/*
		 * el bind keyboard no esta disponible en versiones de IE <= 8
		 * con esta funcion la tenemos disponible..
		 * https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind
		 */
		consulta.prototype.binding = function(){
		    if (!Function.prototype.bind) {
				Function.prototype.bind = function (oThis) {
					if (typeof this !== "function") {
						// closest thing possible to the ECMAScript 5 internal IsCallable function
						throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
					}

					var aArgs = Array.prototype.slice.call(arguments, 1),
					fToBind = this,
					fNOP = function () {},
					fBound = function () {
						return fToBind.apply(this instanceof fNOP && oThis
						? this
						: oThis,
						aArgs.concat(Array.prototype.slice.call(arguments)));
					};

					fNOP.prototype = this.prototype;
					fBound.prototype = new fNOP();

					return fBound;
				};
			}
		}
	}
		/*
		 * * checkeamos soporte para el ajax
		 * * browser independiente, trabaja con  >= ie7 y los otros exploradores
		 * * estandares.. firefox, chrome, safari y otros.
		 * */
		function ajaxob(){
			try{
				return new XMLHttpRequest(); // Firefox, Opera 8.0+, Safari
			}
			catch (e){
				try{
					return new ActiveXObject("Msxml2.XMLHTTP"); // Internet Explorer
				}
				catch (e){
					try{
						return new ActiveXObject("Microsoft.XMLHTTP");
					}
					catch (e){
						alert("Sorry AJAX is not supported by your browser.");
						return false;
					}
				}
			}
		};

Ahora el index.html copia y pegalo. basicamente este incluye los ids de la FORMA y el contenedor que tendrá la respuesta de Ajax que se hiso a el servidor.
Ademas de el los scripts que llamaran el archivo ajax_mysql.js y el window.onload que estan colocadas entre la “head” tags.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" dir="ltr" lang="en">
<head>
<title>llamadas de ajax a una base de datos</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javaScript" src="./js/ajax_mysql.js"></script>
<script type="text/javaScript">
window.onload = function(){
        // inicia el objecto
        var consultame         = new consulta('resAjax', 'iniciador', 'mysql.php');
	    //  escucha el evento de submit
	    consultame.loadform();
}
</script>

<style type="text/css">
html , body{
   margin:0;padding:0;
   background-color: black;
   color           : #EEEEEE;

}
div#contenido{
   padding    : 1em;
   margin-left: 21em;
   width      : 600px;
   height     : 400px;
   border     : 1px solid #C3D9FF;
}
div#resAjax{
	padding    : 1em;
	margin-left: 11em;
	width      : 200px;
	height     : 100px;
	border     : 1px solid #6BBA70;
}
p.error{
   color:#FF1A00;
}
p.bien{
   color:#356AA0;
}
</style>
</head>
<body>
<div id="contenido">
<p>Presiona el boton para hacer la llamada ajax a la base de datos.<br />
   Prueba usando los nombres , "metallica" y "megadeth"</p>
<!-- este es nuestro iniciador en el html -->
<form id="iniciador" action="javascript:void(0);" method="post">
	<p><label>*Nombre</label>
		<input type="text" name="username" value="" size="30" />
	</p>
	<input type="submit" name="submit" value="enviar" />
</form>

<!-- nuestro div que recivira el resultado de nuestra llamada ajax -->
<div id="resAjax"></div>
</div>
</body>
</html>

Ahora mysql.php, este solamente tendrá algo simple, para darte una idea como usar el script para tus elaboraciones mas complejas.

<?php
            if(isset($_POST['submit'])){
			    /*
				* iniciamos coneccion a menos que submit procesada.
				* colocamos las credenciales de el mysql servidor.
				*/
				$servidor            =  "localhost";    // direccion del host de mysql
				$msql_usuario        =  "root";         // nombre del usuario de mysql
				$clave_mysql         =  "";             // clave del usuario de mysql
				$base_dedatos        =  "consulta";     // base de datos.
				$tabla_datos         =  "basede_datos"; // la tabla de datos.

				$conectado           =  @mysql_connect($servidor , $msql_usuario , $clave_mysql);
				// si hay error al conectarnos al servidor, terminemos el script y informemos de esto.
				if(!$conectado) exit('<p class="error">hubo un error en la coneccion : '.mysql_error().'</p>');
				// esta todo bien, entonces conectemonos a la base de datos.

				$db                  =  @mysql_select_db($base_dedatos , $conectado);
				// si hay error al conectar a la base de datos, terminemos y informemos.
				if(!$db)       exit('<p class="error">no se pudo conectar a la base de datos : '.mysql_error().'</p>');

				// todo bien en coneccion y en elegir nuestra base de datos , juguemos un poco.

				if(isset($_POST['username']) && $_POST['username'] != ''){
				    // Limpiemos nuestra username , es lo mas importante cuando recivimos valores de los usuarios
					$nombre = mysql_real_escape_string(htmlentities(strip_tags($_POST['username'])));
					// agamos nuestra consulta a mysql
					$consulta         =  @mysql_query("SELECT * FROM ".$tabla_datos." WHERE username='".$nombre."'");
					    // si ubo error en la consulta reportala.
					    if($consulta === false)exit('<p class="error">ubo un error el cual es: '.mysql_error().'</p>');
						// si lo retornado no nos da a 1 entonces el nombre no existe..
						if(@mysql_num_rows($consulta) < 1)exit('<p class="error">Lo lamento no se encontro este usuario.!</p>');
					// si al contrario se encontro satisfactoriamente, reportalo bien.
					echo '<p class="bien">El usuario <strong>'.$nombre.'</strong> fue encontrado..</p>';
				}else{
				    // el campo de nombre esta vacio, reportemoslo
				    echo '<p class="error">No escribistes nada en el nombre de la forma..</p>';
				}
				// serramos la coneccion a mysql
				mysql_close($conectado);

			}
?>

Ahora el Mysql script, que use en el tutorial.

-- phpMyAdmin SQL Dump
-- version 3.2.4
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Aug 09, 2012 at 09:56 PM
-- Server version: 5.1.41
-- PHP Version: 5.3.1

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";

--
-- Database: `consulta`
--

-- --------------------------------------------------------

--
-- Table structure for table `basede_datos`
--

CREATE TABLE IF NOT EXISTS `basede_datos` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(20) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `username` (`username`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=493 ;

--
-- Dumping data for table `basede_datos`
--

INSERT INTO `basede_datos` (`id`, `username`) VALUES
(1, 'metallica'),
(2, 'megadeth');

Conclucion

Bueno algo pequeño que quería hacer se convirtió en algo mas amplio, algunas notas importantes..
La validación de la forma la ise totalmente del lado del servidor, pues es lo mas recomendable.

Algunos developers tambien les gusta verificar en Javascript, no lo hago porque el
código se alarga un poco, y la verdad del lado del servidor es lo mismo.

En el codigo PHP como resultados utilice el tag p y le di class de error o bien a mi parecer se ve bien y funciona a la perfección.

puedes ver el demo de como quedo, cliqueando llamadas de Ajax a una base de datos.

El Javascript puede ser usado para formas que chequean credenciales, registraciones, para perfiles,
para formas de búsqueda.. para muchas cosas que te de la imaginación.

18 thoughts on “Maneja datos de Mysql con Ajax”

  1. Hola!

    Pues me ayudo mucho tu post, esta muy bien la explicación y me funciono a la primera, de entrada gracias por compartirlo.

    Nada mas una pregunta, las consultas que hago se tardan mucho porque es una bd bastante grande, sería posible agregar un loader?? Si es esto posible como podría hacerlo??

    De antemano gracias y saludos !!

  2. Hola,

    Puedes probar cuando request.readyState sea 2 y pasar una imagen a un container o elemento en tu html..

    seria bien facil hacerlo de esta manera.

    gracias por comentar.
    un ejemplo:

    request.onreadystatechange = function(){
    					if(request.readyState == 2){
    					// El request se hiso y esta siendo procesado
    					
    					/*aqui tu codigo que mostrara una imagen que esta loading or esperando respuesta
    					* lo pasas a recipiente o otro elemento en tu HTML.
    					*/
    					
    					}else if(request.readyState == 4){
    					    if(request.status == 200){
    						    if(request.responseText != null && request.responseText != ''){
    					            // mostremos el resultado en nuestro html
    					            if(recipiente) recipiente.innerHTML = request.responseText;
    							}else{
    							    alert('hubo un error:  estas seguro que, '+ this.ajaxurl +' esta printeando resultados?');
    							}
    						}else{
    						    alert('hubo un error al enviar la consulta : ' + request.statusText);
    						}
    					}
    				}.bind(this)
    				request.send(data);
    
  3. Gracias por tu pronta respuesta!

    Ya intente lo que me dices, de hecho soy nuevo usando ajax. Trate de cargar el preloader de la siguiente manera:

    request.onreadystatechange = function(){
    if(request.readyState == 2){
    // El request se hiso y esta siendo procesado

    /*aqui tu codigo que mostrara una imagen que esta loading or esperando respuesta
    * lo pasas a recipiente o otro elemento en tu HTML.
    */
    preloader.innerHTML = “Buscando…”;
    preloader.style.background = “url(‘preload.gif’) no-repeat”;

    }else if(request.readyState == 4){
    if(request.status == 200){
    if(request.responseText != null && request.responseText != ”){
    // mostremos el resultado en nuestro html
    if(recipiente) recipiente.innerHTML = request.responseText;
    }else{
    alert(‘hubo un error: estas seguro que, ‘+ this.ajaxurl +’ esta printeando resultados?’);
    }
    }else{
    alert(‘hubo un error al enviar la consulta : ‘ + request.statusText);
    }
    }
    }.bind(this)
    request.send(data);

    Pero nada mas no funciono, seguro que me estoy equivocando en algo pero no tengo idea en que.

    De antemano gracias por tu apoyo.

  4. Hola,

    preloader no esta definido en la clase, definelo primero:

    var preloader =document.getElementById('preloader');
    
    if(preloader){
    	preloader.innerHTML = "Buscando…";
    	preloader.style.background = "url('preload.gif') no-repeat"; 
    }
    

    revisa si no tienes errores de javascript..

  5. Hola Utan, excelente tutorial. Tengo lo siguiente, a ver si me puedes ayudar que hace 2 meses no puedo solucionalo y en un mes tengo que entregar un trabajo.
    Tengo un tab que tiene en la primera pesatania una tabla que traigo desde mysql la llena y luego tengo que hacer un click en alguno de los registros de esta primera pesatnia para que se llenen las otras 3 pestanias. El tema es que cada vez que lo hago se me refresca toda la pagina y pierdo los datos. Hay alguna manera de que no se refresque toda la pagina y unicamente se llenen las pestanias que corresponden? Cada pestania es una div.
    Estoy trabajando con jquery, la pagina es una jsp y la bbdd es mysql.
    Y otra pregunta hay alguna manera de que cuando se llena la tabla de la primera pestania aparezca recién cuando ya se llenó y no por partes y toda desacomodada y luego de un rato se acomoda?
    Muchisimas gracias por todo

  6. Bueno,

    Primero que nada, tendrías que mostrar tu código para entender tu situación , algo entendí pero no todo, porque se te refresca toda la pagina?

    Lo que debes hacer en un request con algun hyperlink a la base the datos, llenar el div con el resultado de el request de tu script de mysql y formar el html con esta infomacion en el div..

    pasa un ejemplo para entender bien..

  7. Hola Utan, muchas gracias por tu rápida contestación.
    Cómo hago para pasarte el código?
    Ojo que todavía no usé ajax. Esto lo hago con una simple llamada al servlet y de ahí a la base y retorna el resultado y cuando vuelve me refresca toda la pagina y no sólamente las otras pestanias.
    Ej.
    Al comienzo la pagina se llena con una llamada a una bbdd que llena la tabla (datatable) de la primera pestania de la tab (tarda un monton de tiempo en dibujarlo). Las otras pestanias se llenan una vez que selecciono una fila de la tabla de la primera pestania. Cuando selecciono y hace el submit, llenas las otgras pestanias pero como el submit es de la misma pagina se refresca tgoda la pagina.
    Verlo en funcionamiento es mas facil, explicarlo es medio dificil para entender.
    Saludos y muchas gracias
    Carlos

  8. Utan,

    a ver si entendío lo último que me escribiste.
    Se me complica un poco entender porque de php no se nada 🙁 estoy trabajando en JAVA con jsp.
    Donde se coloca la pagina de php yo deberia poner la pagina jsp que es la que por medio del servlet va a buscar la informacion a la base y luego llenar el Div? pero esa pagina jsp ya tengo estructurado como quiero que reciba la info en inputbox…
    No me doy cuenta !!!! soy medio bestia, no hay nada que hacerle.

    Abrazo,

    Carlos

  9. hola, disculpa por responder tan tarde, el servlet documento responde con los datos de tu sql oh mysql, esto es pasado en el response del ajax pasándolo en el div.. si quieres pasarlo estructurado entonce hasle el markup en servlet y como es hml este lo pasara al div y este sera extructurado.. ahora si haces esto serciorate que se los usuarios no manipulen el resultado si no que lo pases directamente de tu base de datos.. hay que cuidarnos del XSS.

  10. Hola, gracias por tu aportación, perdon pero yo tengo un problema cuando le doy enviar me dice: hubo un error al enviar la consulta: no found. Supongo que es porque no localiza el mysql.php. por favor dime en donde coloco y el archivo. y si no es mucha molestia como se podria hacer la busqueda del nombre pero entre un tiempo determinado.

  11. cambie la consulta a una tabla que tengo, pero me dice hubo un error: estas seguro que, mysql.php esta printeando resultados. llenando la caja de texto o sin llenarlas. tengo otros php que hacen la conexión a la bd, pero no se que debo revisar.

  12. Hola,
    Bueno lo que aria es ir a la dirección de tu documento que accesa la base de datos y ver que te printea,

    si el callback del request es nulo o no tiene nada entonces tu documento no te esta dando resultado alguno.. revisa tus webserver log por errores de mysql,

    pues puede que los tengas silenciado en los documentos en si.. pero se muestran en el logo del servidor.

Leave a Reply

Your email address will not be published. Required fields are marked *