Chequear todos los checkbox de un gridview con javascript

3 11 2007

NOTA 16/06/2009: He publicado como hacer esta misma tarea con jQuery en este artículo, recomiendo utilizar esa alternativa por los motivos que comento en dicho artículo.

Muchas veces queremos chequear o deschequear todos los checkbox de un gridview de una sola vez, puede ser cuando el usuario realiza determinada acción en otro control, por ejemplo un botón para “seleccionar todo”, o que cuando se activa un CheckBox en la cabecera de la columna, cambie el estado de todos los checks al de la cabecera.

Si bien esto se puede hacer con código de servidor, normalmente no queremos que se realice un postback solo para esto, la solución es javascript.

(Nuevamente, si solo te interesa un código js que solucione el problema que acabo de describir, te recomiendo ir directamente a copiar los dos fragmentos de javascript al final del post.)

En su momento utilicé el código que Scott Mitchell publicó en este artículo, pero esta solución, si bien funciona y no genera un postback, requiere código de servidor, ya que en la creación de la página se registra mediante el método RegisterArrayDeclaration un array con los ids que tendrá cada checkbox en el cliente, lo que nos obliga a hacerlo en cada postback o a recargar el estado, ya sea ViewState o Session.

Buscando otra alternativa encontré este otro artículo de Mohammad Azam, el autor de GridViewGuy. Este si es un ejemplo totalmente sobre javascript, pero tiene un gran defecto: opera sobre todos los checkbox de la página, sin importar si están dentro de la grilla o no, ni hablar si tenemos dos grillas.

En este punto decidí escribir mi propia solución, o sea una totalmente en el cliente y que permita operar sobre los checkbox de una grilla en particular y, por que no, sobre una columna en particular, de manera que podamos tener más de una columna con checkbox y cambiar el estado de los checks de una de ellas sin afectar la otra.

Un poco de background que pueden saltarse si les parece:

Como incluir CheckBox en una columna de un gridview

Antes que nada hay que generar una columna con los checkbox. Hay dos maneras de hacer esto como cuenta Scott Mitchell en el artículo nombrado, yo utilizo también un TemplateField (no encontré todavía utilidad para los CheckBoxField), de modo que colocando un checkbox en el ItemTemplate genero uno en cada celda del TemplateField:

<asp:TemplateField HeaderText="chk">
   <ItemTemplate>
      <asp:CheckBox ID="chkColumna1" runat="server" />
   </ItemTemplate>
</asp:TemplateField>

Visualmente (en VisualStudio), agregamos un TemplateField al gridview y seleccionamos EditTemplate del menú contextual. Luego arrastramos un CheckBox a la zona ItemTemplate. Para finalizar: End Template Editing, en el menú contextual.

Como chequear todos CheckBox de un GridView

Esta rutina javascript cambia el estado de todos los checkbox de una grilla sin importar su ubicación:

function ChangeAllChecks(gridViewName,newState)
{
   var tabla = document.getElementById(gridViewName);
   celdas = tabla.cells;
   for(i=0;i<celdas.length-1;i++)
   {
   if (celdas[i].firstChild.type=="checkbox"
   && celdas[i].firstChild.checked != newState)
      {
         celdas[i].firstChild.click();
      }
   }
}

Para llamarla utilizamos ChangeAllChecks(‘GridView1’,true); o false si es el caso

Como chequear una columna específica

Puede ocurrir que en un gridview tengamos más de un TemplateField con CheckBox, y que solo queramos chequear o deschequear una sola columna, para ello hice un nuevo método que toma como paramétro el índice de la columna (empezando por 0). (Actualizado 29/09/2008 según respuesta al comentario de Martín)

function ChangeChecksByColumn(gridViewName, newState, columnIndex){
    var tabla = document.getElementById(gridViewName);
    var columnas = tabla.cells.length / tabla.rows.length;
    celdas = tabla.cells;
    for (i = columnas + columnIndex; i < celdas.length; i += columnas){
        if (celdas[i].firstChild.type == "checkbox"
               && celdas[i].firstChild.checked != newState
            /* && agregar aquí otras condiciones */){
            celdas[i].firstChild.click();
        }
    }
}

Como chequear a partir de un CheckBox en la cabecera

El código anterior no es muy útil porque nos solicita el estado (true=checked/false=unchequed) en el que queremos dejar los checkbox, la solución es agregar un checkbox en la cabecera de la TemplateColumn:

y agregamos una rutina que permita identificar el estado del mismo y la columna en que se encuentra, luego llamamos al método anterior: ChangeChecksByColumn:

function CopyCheckStateByColumn(HeaderCheckBox, gridViewName)
{
    var columnIndex = HeaderCheckBox.parentElement.cellIndex;
    var newState = HeaderCheckBox.checked;
    ChangeChecksByColumn(gridViewName, newState, columnIndex);
}

Para terminar, completamos el evento onclick del checkbox con una llamada a CopyCheckStateByColumn pasando como parámetro el propio checkbox y el nombre del gridview:
(lo que sigue cambiado el 08/11 según la respuesta al comentario de Roger)

<asp:TemplateField HeaderText="chk">
<HeaderTemplate>
    <asp:CheckBox ID="chkHeader" runat="server" onclick="javascript:CopyCheckStateByColumn(this,this.offsetParent.offsetParent.id);"/>
</HeaderTemplate>
<ItemTemplate>
    <asp:CheckBox ID="chkTest" runat="server" />
</ItemTemplate>
</asp:TemplateField>

Una precaución: Tener en cuenta que el código javascript consulta si el contenido es un CheckBox mediante la propiedad firstChild para cada objeto de la colección cells del objeto table, o sea: el contenido de cada TD. Si ponemos otro objeto en el ItemTemplate junto con el CheckBox, podemos tener problemas si nos descuidamos.

Un tip: Para llamar métodos javascript en el evento click de un control Button, se debe utilizar el evento OnClientClick en vez de onclick.

Una desventaja: No funciona en Firefox.

Saludos

Anuncios

Acciones

Information

36 responses

8 11 2007
Roger Martinez

El codigo no me funciona debido a que tengo utilizando una master page, a la funcion le estoy mandando el uniqueid del gridview pero tampoco realiza nada, me podrias ayudar?

9 11 2007
Alejandro Hernández

Roger:

Si necesitás solucionarlo ya, el artículo está corregido en la declaración del CheckBox en el header. Para saber que era lo que pasaba:

Master Page, buen punto. Veamos, el problema es que con una master page nuestro GridView va dentro de un ContenPlaceHolder, y de estos muchachos puede haber más de uno, Entonces ASP.NET “renombra” el control, ¿que quiere decir esto? que a partir de un WebControl de tipo GridView con Name = GridView1, crea un elemento HTML de tipo table con ID = (por ejemplo) “ctl00_ContentPlaceHolder1_GridView1”.

Mas allá de la master page nuestro problema es que por x motivo el id no se corresponde con el nombre, por lo que:

<asp:CheckBox ID="chkHeader" runat="server" onclick="javascript:CopyCheckStateByColumn(this,'GridView1');"/>

no referencia un corno.

Soluciones:

Podríamos poner :
<asp:CheckBox ID="CheckBox1" runat="server" onclick="javascript:CopyCheckStateByColumn(this,'ctl00_ContentPlaceHolder1_GridView1');"/>
Si eso es lo que hiciste, a mi por lo menos me funcionó.

Lo segundo que pensé es en inyectar el javascript desde el page_load (Attributes.Add) concatenando la ClientID del gridview. Pero ¿porque no hacerlo (tercer pensamiento) al viejo estilo ASP, poniendo codigo VB/C# entre <% %>?,

<asp:CheckBox ID="CheckBox1" runat="server" onclick='<%# "CopyCheckStateByColumn(this," + ((GridViewRow)Container).NamingContainer.ClientID + ".id)"%>' />

Bien, funciona y no hace falta hardcodear el nombre del GridView.

Ahora, (y conste que gasté las cuatro ideas del día en esto), ¿porque no hacerlo con JavaScript? y de paso no sobrecargar el binding, no escribir el nombre del GridView, etc.

Bien, mirando un poco el DOM, llegué a esto, con lo cual te debería funcionar en donde sea sin importar que tipo de página utilices:

<asp:CheckBox ID="chkHeader" runat="server" onclick="javascript:CopyCheckStateByColumn(this,this.offsetParent.offsetParent.id);"/>

Observese que offsetParent va del CheckBox al TD y del TD al TABLE, o sea el GridView al fin y al cabo; sin pasar por el TH, lo que no ocurre por ejemplo con parentElement que pasa por el TH y después al BODY sin pasar por la tabla.

Cosas de JavaScript, lenguaje que no es de mi agrado pero que últimamente parece que no nos queda otra que aprender, ahora con VS2008 que trae intelisense para javascript nos será de más agrado espero.

Espero que te sirva.

9 11 2007
Roger Martinez

Muchas gracias por la contestacion a mi problema del grid view, ahora tengo el siguiente problema. Tengo un templatefield de tipo checkbox en cada fila y en el encabezado de un grid. Si presiono el encabezado se seleccionan todos los checkbox del grid o si selecciono el checbox de una fila se selecciona el checkbox de la fila. Tengo un boton img que en su evento clic tengo el siguiente codigo:

Dim Ensambles(50) As String
Dim I As Integer
Dim row As GridViewRow
Dim ch As HtmlControls.HtmlInputCheckBox
For I = 0 To gvEnvia.Rows.Count – 1
row = gvEnvia.Rows(I)
If row.RowType = DataControlRowType.DataRow Then
ch = row.FindControl(“checkbox1”)
If ch.Checked = True Then
Ensambles(0) = row.Cells(1).Text
End If
End If
Next

A la hora de querer obtener el valor actual del checkbost no me su valor actual sino el valor que trae cuando se carga la pagina.

Me podrian ayudar(agradezco de antemano la atencion a mi ignorancia)

Gracias.

9 11 2007
Alejandro Hernández

Roger, Estás usando un checkbox HTML, esto quiere decir entre otras cosas que no guarda estado, o sea, una vez que se envío el control al navegador, ya nunca más sabremos (si no hacemos nada más) que pasó en el cliente con ese control.
A priori deberías usar un WebControl de tipo CheckBox, como los que uso en el ejemplo (paradójicamente en el caso del artículo sería hasta un poquito mejor utilizar controles HTML para alivianar el binding).
De esta manera el valor del control al momento del postback queda en el ViewState y desde el código servidor que utilizás en el ejemplo te retornará el valor seleccionado (no olvides de dejar el EnableViewState en true, si no estás en la misma).
Comentario aparte si lo que querés es poner X texto de las filas seleccionadas en el array, la orden Ensambles(0) = row.Cells(1).Text está asignando siempre la misma posición, deberías utilizar Ensambles(i). Te recomendaría usar un List(Of String) en vez de un array si lo permite el caso.

Saludos

9 11 2007
Roger Martinez

Muchas gracias Alejandro pero cuando llamo al contro mediante findcontrol no lo encuentra porque estoy usando master pages, que tendira que modificarle al codigo para que lo encuentre. Le pongo el uniqueid y el clientid y tampoco lo busca. Me puedes ayduar

9 11 2007
roger Martinez

Alejadnro ya cambie los controles a checbox, pero aun me sigue apareciendo en la funcion los valores que trae por default la pagina, no se como hacerle, agradezco tu pronta respuesta.

Agradezco de antemano tu respuesta

10 11 2007
Alejandro Hernández

Roger, respecto de que no te conserva los valores, asegurate que la propiedad EnableViewState sea verdadera, (me equivoqué y te dije autopostback, cuando la propiedad que mantiene el estado es EnableViewState, perdón)

En cuanto a encontrar el control, tenés que ver un poco el tema de ClientSide y ServerSide. UniqueID, es una propiedad que diferencia cada control de la página del lado servidor, en cambio ClientID te da el nombre con el que se generará el control en el HTML que se enviará al navegador o sea del lado cliente, también es único y tal vez parecido, pero son dos cosas distintas.

De todos modos FindControl te pide el ID del control, que también es del lado servidor. Para clarificar corré un código como este:

foreach (GridViewRow gvr in GridView1.Rows)
{
if (gvr.RowType==DataControlRowType.DataRow)
{
CheckBox oChk = (CheckBox)gvr.FindControl("CheckBox1");
Response.Write("¡Eureka! encontré un control con las siguientes propiedades:");
Response.Write("ID: " + oChk.ID);
Response.Write("ClientID: " + oChk.ClientID);
Response.Write("UniqueID: " + oChk.UniqueID);
Response.Write("--------------------------");
}
}
Si no consigues hacerlo funcionar, te recomiendo enviar tu código y una explicación de tu problema en el foro de asp.net (podés entrar desde los grupos de google), donde seguro te darán solución. Pero con esto deberías poder hacer que funcione.

Salute!

12 11 2007
Roger Martinez

Alejandro , me sigue sin dar el valor actual del chckbox, sera que si te mando la pagina completa me puedas ayudar?

2 04 2008
Gabriel Euan

Mira tengo un problema parecido no enuentro el checkbox que ando seleccionado dentro del gridview..ya busque de todas las maneras y no lo encuentra…ya que esta dentro de un masterpage y Contents…si te agradeceria que mandaras un ejmplo o una posible solucion……te lo agredeceria mucho

9 04 2008
Leonardo Rosales

Gracias Alejandro por compartir este codigo, me resolviste una gran duda.

16 05 2008
Gastón

Consulta…
Tengo un gridview que tengo 3 columnas
una precio
otra cantidad (textbox) donde agrego la cantidad que lleva el cliente
y una tercera donde quiero que aparezcan el resultado.

Como puedo hacer ?? para pasar el gridview a javascript y que haga la cuenta sin tener que ir contra el servidor…NO ENCUENTRO UN EJEMPLO REAL DE ALGO SIMIL…
Muchas gracias.

10 09 2008
roger

Hola Gaston yo stoy haciedo algo muy parecido. la que expuso alejandro es muy viable.. la aplicaré y si logro llegar a la solucion.. la compartiré por este mismo canal. Exito

16 09 2008
Martin

Ayuda:
Le agregue:

como puedo obtener el dato que esta en ese hidden, ya que el chelbox lo obtengo asi
bool = celdas[i].firstChild.checked;
pero no se como obtener el del hidden

21 09 2008
vpg

Estoy trabajando en asp.net, c# y tengo un gridview con un checkbox en la columna itemtemplate. El problema es que cuando quiero recorrer el gridview, los checkbox no cambian su estado, siempre se quedan en false aun cuando el usuario los haya marcado.
como puedo hacer para que los checkbox cambien su estado????
gracias!

24 09 2008
Martin

Me anda bien hasta que tengo muchos registros y por lo tanto muchas paginas el
cuando recorro por filas.lenght me da undefinido.

29 09 2008
Alejandro Hernández

Martín: No entiendo bien como afecta el hecho de que tengas muchas páginas y no realizo un .length de las filas en el código.

Si el problema es la velocidad se puede mejorar el código omitiendo las iteraciones en las celdas de otras columnas. (edito el post en función de esto)

También se puede omitir el chequeo de la existencia del checkbox en la celda (lo que hace la función menos generíca pero un poco…bastante poco, más performante). Ojo con esto si se incluye algo más dentro del template column donde están los checkboxs.

Con estas modificaciónes a mi (con un X2 1900mhz) me funciona bien hasta 500 filas.

Personalmente no veo mucho la utilidad de paginar de a más de 20-50 registros, no creo que un usario mire más datos que esos, pero este comentario tal vez no aplique la especificación de tu aplicación.

En fin, quedaría así:
function ChangeChecksByColumn(gridViewName, newState, columnIndex){
var tabla = document.getElementById(gridViewName);
var columnas = tabla.cells.length / tabla.rows.length;
celdas = tabla.cells;
for (i = columnas + columnIndex; i < celdas.length; i += columnas){
if (celdas[i].firstChild.checked != newState
/* && agregar aquí otras condiciones */){
celdas[i].firstChild.click();
}
}
}

vpn: Atención con la propiedad EnableViewState de la grilla y los checkbox: debe estar en true. Recordemos que el ViewState es un campo hidden en la página en el cliente, que contiene el estado de todos los controles (que tengan EnableViewstate en true) y que se envía al server en cada postback de la página.

Saludos: Alejandro

12 12 2008
Don Pepe

A continuación dejaré el ejemplo agregando un pequeño gran cambio: que puedas deschequear todos los registros a la vez.

function ChangeAllChecks(newState)
{
var tabla = document.getElementById('””');
celdas = tabla.cells;
for(i=0;i<celdas.length-1;i++)
{
if (celdas[i].firstChild.type==”checkbox” && celdas[i].firstChild.checked != newState)
{
celdas[i].firstChild.click();
}
else if (celdas[i].firstChild.type==”checkbox” && celdas[i].firstChild.checked == newState)
{
celdas[i].firstChild.click();
}

}
}

Lo único que me queda es averiguar cómo implementar esta función cuando la grilla tiene más de una página.

Saludos a todos.

12 12 2008
Don Pepe

mejor me escirben a mi mail aries25@chile.com y les cuento

12 12 2008
Alejandro Hernández

Don pepe: He intentado emprolijar los comentarios. Cualquier observación los corrijo nuevamente. (la interpretación de las comillas del wordpress es muy fastidiosa! )

En cuanto al código, si se quita el parámetro con el nombre del gridview, el comportamiento se ‘contagia’ a todos los tables de la página, por eso en el script se especifica el nombre.

Por otro lado la función original copia el estado del check de la cabecera al resto, incluso cuando se lo deschequea.

En cuando a las multiples páginas, entiendo que hablamos de que el usuario navegue por las páginas marcando y desmarcando los checks y al final confirma la acción y esta se ejecute para todos los registros, incluyendo los que marco en las páginas que no están visibles….bueno, no veo una solución ‘linda’ para esto.

Mantener el estado de todas las selecciones se debe hacer en el servidor, yo diría en el session o en la base. podría ser en un Dictionary con los ids y los valores de chequeo, o bien un DataSet (tal vez el mismo que sirve de DataSource a la grilla, siempre y cuando tengamos cuidado de no hacerlo con miles de datos o de usuarios), entre otras opciones.

Y si lo que buscamos es la manera de chequear o deschequear todas las páginas a la vez, yo lo haría desde un botón dedicado, ya que un check en la cabecera creo que se presta a la confusión. Este botón puede correr el mismo script que el check de la cabecera (para el efecto visual) pero setearía un hidden (con los valores, digamos ‘todo chequeado’, ‘nada chequeado’ e ‘indefinido’) para poder procesar en el server.

Hay que tener en cuenta que cualquier cambio de estado en un check debería setear el flag en ‘indefinido’, y que hay que conservar el valor (chequeado o no) de los registros que no están en la página, de manera que al paginar, aparezcan con el valor seteado por el usuario.

Muchas gracias por colaborar y cualquier cosa los comentarios son bienvenidos.

7 04 2009
Sebastian

Es post está muy interesante, utilicé la primera opcion y todo funcionó sin problema, hasta que mi jefe pidio que el grid tuviera paginación, y con eso me mató. la maxima paginacion es de 50, y como es un proyecto de constructoras ellos manejan muchos recursos, que exigen que el grid sea asi de extenso, necesito su ayuda por favor, si pueden escribanme a mi correo: scefiro@hotmail.com

15 04 2009
M. Ramirez

Hola estoy empezando en este tema y necesito hacer un gridview con checkbox y rescatar los valores que pueden ser 1 o todos los de la grilla y no se aplicar lo que he encontrado en VBScript, y pasarlos como string ( que se es con un arreglo ) si me pueden ayudar se los agradecere.

12 05 2009
ffffff

No entiendo bien como accesar a tu control si esta en una pagina maestra.
Yo tengo codigo en javascript en la pagina de esta forma:

document.getElementById(”)
y me funciona; pero si uso un archivo externo pára adjuntar las funciones de javascript ya no me funciona, pero si funciona usando la forma:
document.getElementById(‘ctl00_ContentPlaceHolder1_Algo’)
Me imagino que debo buscar el place holder y luego el control, algo asi
document.getElementById(”)
esto no me funciona
espero me puedas ayudar.

12 05 2009
Alejandro Hernández

ffffff, fijate en el comentario del 9/7/2007, a ver si se puede resolver como está en el último snippet.

saludos: Alejandro

12 05 2009
ffffff

He investagado y lo que he visto es que por alguna razon cuando utilizas un archivo externo de javascript no puedes usar la propiedad
para obtener un control.
Si pones la funciones javascript en el mismo aspx no hay problema.
Yo quiero acceder a los controles con un archivo externo pero sin pasarle el ID ’ctl00_ContentPlaceHolder1_Algo’.
Si sabes alguna solucion espero me la puedas proporcionar.
Saludos

16 06 2009
Alejandro Hernández

ffffff, tarde pero seguro, este artículo que publiqué resuelve tu problema.

16 06 2009
Como checkear todos los CheckBox de una columna con jQuery « VarioNet

[…] checkear todos los CheckBox de una columna con jQuery 19 05 2009 Uno de los artículos más consultados de este blog explica como configurar una tabla para que al clickear en un Checkbox […]

20 10 2009
Ariel

muy bueno el post… lo hice igual pero usando jquery para la seleccion.

21 10 2009
Alejandro Hernández

Ariel, en la nota al principio del post está el link al artículo donde lo hice con jQuery. Son bienvenidos los comentarios sobre como lo hiciste. ¡Gracias!

3 02 2010
mcone

disculpa queria saber si es posible ,como se puede enviar como parametro a la funcion javascript el valor de otra columna de un gridview , es decir

si es posible ya que quiero evitar el postback ya que necesito marcar la fila de un gridview cuando de chekea y cuando esta ya esta chekeada de otro color.

3 02 2010
mcone

:CheckBox ID=”chkHeader” runat=”server” onclick=”javascript:CopyCheckStateByColumn(this,this.offsetParent.offsetParent.el valor del otra columna de gridview );”/>
/HeaderTemplate>

perdon aqui va como quiero hacerlo

22 03 2010
Tatiana

Buenas. Tengo el mismo problema con los checkbox en el gridview. El asunto es que aparentemente todo en mi grid esta perfecto. El enableViewState esta en true, el grid no se carga en el load por lo que tampoco se esta volviendo a generar con el postback. Este es mi grid:

<asp:Label runat="server" ID="glblRequisito" Text='’ />

<asp:Label runat="server" ID="glblEstado" Text='’ />

y el codigo es este:

For indice = 0 To gvReq.Rows.Count – 1
chk = gvReq.Rows(indice).FindControl(“gchkExonerar”)
If chk.Checked Then
cSolNegReq = gvReq.DataKeys(indice)(“ide_solnegreq”).ToString()
oDatos.Actualizar(cSolNegReq, “4”) ‘El estado 4 es Exonerado
End If
Next
chk.Checked siempre viene en false. He buscado en otros lugares con gente con el mismo error y siempre la solucion es el viewstate o sacarlo del postback pero en mi caso no sucede ninguna de las dos situaciones. ayuda por favor. grax

22 03 2010
Tatiana

el grid se copio mal

.
.
.

9 03 2011
willy

Buenas ya pude resolver el pequeño dilema gracias a los ejemplos anteriores. Mi problema era el siguiente, necesitaba marcar todos los checks del grid para ejecutar un proceso, entonces esto fue lo que hice:
en el diseño compie este codigo

function chequear(gridViewName,newState)
{
var tabla = document.getElementById(gridViewName);
celdas = tabla.cells;
for(i=0;i<celdas.length-1;i++)
{
if (celdas[i].firstChild.type=="checkbox"
&& celdas[i].firstChild.checked != newState)
{
celdas[i].firstChild.click();
}
}
}

despues en la pagina.cs
protected void Page_Load(object sender, EventArgs e)
{
nombre_del_boton.Attributes.Add(“OnClick”, “chequear(‘GridView1’,true);”);
GridView1 es el nombre del grid
true lo utilizo para chequear todos los campos

si necesitaramos el proceso inverso solamente cambiamos el nombre del boton y cambiamos true por false.

Espero les sirva

6 06 2011
Juan Moreno Silva

Mi pana si el gridview esta paginado como se puede hacer alli..me podrias ayudar?

11 10 2011
elias avellaneda

Buenas, me ocurre lo mismo al tener paginada la grilla. Ademas tengo dos columnas check box. Si alguien puede darme una ayuda se lo agredecere.
Mi correo: avellaneda.elias@gmail.com
Muchas gracias.

10 08 2012
maty

Perdón que moleste con esto, y espero que sea una pavada…pero no me tilda ni destilda nada. Estoy trabajando con una master page. El código se ejecuta genial. Pero celdas[i].firstChild.type siempre es undefined. Alguna idea de por qué puede pasar? Gracias!

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s




A %d blogueros les gusta esto: