Foros del Web » Programando para Internet » Jquery »

Funcion toggle ¿2 clicks para funcionar? Mi intención es en un click

Estas en el tema de Funcion toggle ¿2 clicks para funcionar? Mi intención es en un click en el foro de Jquery en Foros del Web. Buenas tardes compañero! Como siempre agradecer las posibles respuestas! Estoy creando un sistema de comentarios, y para responder a cada comentario he colocado un botón ...
  #1 (permalink)  
Antiguo 04/12/2015, 12:04
sidneyendis
Invitado
 
Mensajes: n/a
Puntos:
Pregunta Funcion toggle ¿2 clicks para funcionar? Mi intención es en un click

Buenas tardes compañero!
Como siempre agradecer las posibles respuestas!
Estoy creando un sistema de comentarios, y para responder a cada comentario he colocado un botón de "responder". Cuando clican dicho botón aparece el formulario de respuesta.
Para ello utilizo la función toggle de Jquery. El problema que tengo es que para abrir dicho formulario tienen que hacer doble click en el botón "responder" cuando yo quiero que únicamente hagan un click.
Os dejo el ejemplo en codepen: http://codepen.io/anon/pen/qbBXWy
Como podeis comprobar para abrir el contenido del botón hay que hacer doble click la primera vez que lo intentas, despues para ocultarlo o mostrarlo de nuevo solo necesitas un click.

¿Solución? La única que he encontrado es no ocultar el div desde la hoja de estilos css externa sino desde la misma etiqueta del div:
Código HTML:
<div style="display:none;"></div> 
Pero tengo entendido que los estilos no deben ir en el documento html ya que Google los penaliza, imaginaros despues de 50 comentarios, estariamos hablando de 50 divs con etiquetas de estilo en el documento html.

Espero haberme explicado bien y que podáis ayudarme.
Un saludo muy grande!!! :)
  #2 (permalink)  
Antiguo 04/12/2015, 14:02
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 13 años
Puntos: 977
Respuesta: Funcion toggle ¿2 clicks para funcionar? Mi intención es en un click

Lo que sucede es que la propiedad style, además de establecer valores para las distintas propiedades CSS, devuelve los estilos del elemento pero establecidos inline, es decir, mediante el atributo style="propiedad:valor". La primera vez que pulsas al elemento, lo que se obtiene es una cadena vacía para dom.style.display puesto que no estableciste ningún valor inline para dicha propiedad, entonces, por la condición que pones, se asignar el valor "none". La segunda vez que pulsas al elemento, ya se estableció el valor inline, por lo tanto, se cumple la condición y se asigna el valor "block".

Para obtener el valor definido en la hoja de estilos, puedes utilizar el método .getComputedStyle(). Y para obtener compatibilidad con navegadores antiguos, puedes utilizar esta función.

Un saludo
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand
  #3 (permalink)  
Antiguo 04/12/2015, 14:08
 
Fecha de Ingreso: noviembre-2015
Mensajes: 59
Antigüedad: 9 años
Puntos: 0
Respuesta: Funcion toggle ¿2 clicks para funcionar? Mi intención es en un click

la funcion toogle de jquery no esta disponible a partir de la version 1.9 para ese efecto que deseas hacer. aca te pongo un codigo que te debe funcionar . la funcion toogle permite tambien alternar entre dos funciones y este seria el caso. si no quieres el efecto slide puedes usar FadeIn - FadeOut o cambiar directamente la propiedad css.


$(document).ready(function(){

$('elementod disparador').toggle( // este seria tu boton

// Primer click
function(e){
$('elemento a mostrar-ocultar').slideDown();
$(this).text('Ocultar');///si quieres aqui cambias el texto del boton a ocultar o mostrar
e.preventDefault();
}, // Separas las dos funciones con una coma

// Segundo click
function(e){
$('#elemento a mostrar-ocultar').slideUp();
$(this).text(Mostrar');
e.preventDefault();
}

);

});
  #4 (permalink)  
Antiguo 04/12/2015, 17:49
sidneyendis
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Funcion toggle ¿2 clicks para funcionar? Mi intención es en un click

Muchas gracias por las respuestas!
Edel, me parece muy interesante el código adjunto, pero el elemento a ocultar/mostrar tendrá diferentes id.... es decir, cada elemento a mostrar será independiente en cada comentario:
Código HTML:
<!-- Primer comentario -->
<a class="responder" onclick="javascript:ocultar('div_respuesta_1')">Mostrar</a>
<div id="div_respuesta_1">Aquí contenido oculto</div>
<!-- Segundo comentario -->
<a class="responder" onclick="javascript:ocultar('div_respuesta_2')">Mostrar</a>
<div id="div_respuesta_2">Aquí contenido oculto</div> 
Por lo tanto, ¿como cambio eso el el código jquery que me has adjuntado? Digamos, ¿como lo dinamizo?
Gracias!! :)
  #5 (permalink)  
Antiguo 04/12/2015, 18:23
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 13 años
Puntos: 977
Respuesta: Funcion toggle ¿2 clicks para funcionar? Mi intención es en un click

Utiliza una función que reciba al identificador, así tomas al elemento por dicho dato, o mejor aún, utiliza una clase. A diferencia de los id, las clases pueden repetirse.

De cualquier modo, con cambiar lo que te comenté, también lo puedes hacer, evitando cargar a toda una librería para algo que puedes hacer en una sola línea.

Un saludos
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand
  #6 (permalink)  
Antiguo 04/12/2015, 18:39
sidneyendis
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Funcion toggle ¿2 clicks para funcionar? Mi intención es en un click

Hola Alexis!
Gracias por todas las molestias tomadas!

El problema es que no se introducir ese método para que realice la función... Parece la mejor opción pero por más que busco información no acabo de encontrar un ejemplo que me haga entender como aplicar dicho método... ¿Podrias ayudarme con un ejemplo?

Siento tantas molestias!
  #7 (permalink)  
Antiguo 04/12/2015, 18:58
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 13 años
Puntos: 977
Respuesta: Funcion toggle ¿2 clicks para funcionar? Mi intención es en un click

En los enlaces que te dejé, hay ejemplos.

Código Javascript:
Ver original
  1. var elemento = document.getElementById("ejemplo"),
  2.     height = getComputedStyle(elemento).height,
  3.     width = getComputedStyle(elemento).width,
  4.     display = getComputedStyle(elemento).display;
  5.  
  6. console.log("Height: " + height);
  7. console.log("Width: " + width);
  8. console.log("Display: " + display);

DEMO

NOTAS:
  • Los prefijos de las unidades, como "px" de píxeles, vienen adjuntas. Si quieres tomar solo sus valores numéricos, te aconsejo utilizar algún método de conversión, como .parseInt(), entre otros.
  • Dependiendo del ámbito en el que se ejecute la operación, será o no necesario anteponer el window. al nombre del método.

Un saludo
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand

Última edición por Alexis88; 04/12/2015 a las 19:16 Razón: Notas
  #8 (permalink)  
Antiguo 04/12/2015, 20:58
sidneyendis
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Funcion toggle ¿2 clicks para funcionar? Mi intención es en un click

Hola Alexis!
Muchas gracias por todo el esfuerzo!! Que paciencia tienes que tener!
Mira, lo máximo que consigo es lo siguiente:
Código HTML:
function toggle(id){
    var dom=document.getElementById(id),
	display = getComputedStyle(dom).display;
	dom.innerHTML = "display: " + display;
    dom.style.display=dom.style.display=='none'?'block':'none';
}
Y claro, parece ser que le estoy diciendo a la función que modifique el texto que está entre las etiquetas Div... Estoy más perdido....

Al final tiraré por el código que me decía edel, pero tampoco con su codigo tampcoo se pasar un parámetro desde onclick hasta la función toggle... JS es demasiado para mi... nose cuantas horas llevo detrás de un simple error y sin encontrar una solución....
  #9 (permalink)  
Antiguo 04/12/2015, 22:34
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 13 años
Puntos: 977
Respuesta: Funcion toggle ¿2 clicks para funcionar? Mi intención es en un click

Según lo que veo que has hecho, debería función.

DEMO
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand
  #10 (permalink)  
Antiguo 05/12/2015, 11:17
 
Fecha de Ingreso: noviembre-2015
Mensajes: 59
Antigüedad: 9 años
Puntos: 0
Respuesta: Funcion toggle ¿2 clicks para funcionar? Mi intención es en un click

perfectamente se puede adaptar ese codigo para cada comentario y no precisamente hace falta el id. solo haria falta ver la estructura html de esa parte de la pagina. por ejemplo en codigo que publicas, suponiendo que despues de

<a href="#" class="responder" onclick="toggle('responder_usuario');return false;"><i class="fa fa-reply"></i> Responder</a>

declares el codigo

<div id="responder_usuario" class="ocultar">La prueba funciona</div>

en la estructura del DOM, <div> es el hermano siguiente del <a> por tanto para acceder a el en el codigo que publique seria asi $(this).next(). en ves de
$('elemento a mostrar-ocultar').
recuerda que esto puede variar dependiendo de la estructura del DOM.
PUEDES PUBLICAR EL CODIGO REAL DE LA PAGINA PARA ADAPTARLO EN CASO QUE SEA DISTINTO.

AHORA TE PREGUNTO ,TIENES PENSADO DECLARAR PARA CADA COMENTARIO Y RESPUESTA UN FORMULARIO RESPONDER.???? NO CREO QUE SEA NECESARIO ,IMAGINA SI TIENES 100 REPUESTAS.
  #11 (permalink)  
Antiguo 05/12/2015, 14:22
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 13 años
Puntos: 977
Respuesta: Funcion toggle ¿2 clicks para funcionar? Mi intención es en un click

Buen punto el tocado por edel. Si habrá varios comentarios, no te conviene trabajar con un id puesto que no puede repetirse. Como bien te comentan, dependerá de la estructura de tu DOM para poder determinar la mejor manera de implementar lo que necesitas.

Una estructura que se me ocurre consiste en lo siguiente:
Código HTML:
Ver original
  1. <section class="comentario">
  2.     <article>
  3.         El comentario
  4.     </article>
  5.     <div class="respuestas"></div>
  6.     <div class="respuesta">
  7.         <span class="toggle">Responder</span>
  8.         <form>
  9.             <textarea></textarea>
  10.             <input type="submit" />
  11.         </form>
  12.     </div>

Básicamente, se trata de una sección (también puede ser un <div>) que contiene un artículo en el cual irá el comentario principal, una división para las respuestas que pueda tener y otra con un botón y un formulario para escribir la respuesta. La idea es que el formulario esté oculto y cuando se pulse el botón, se muestre y el botón se oculte. Una vez que se envíe la respuesta, se oculta el formulario y se muestra el botón.

Como algunos de los elementos son dinámicos y puede haber muchas respuestas, lo conveniente es delegar los eventos al documento. Esto sería más o menos así (puede variar según la estructura que tengas):
Código Javascript:
Ver original
  1. document.addEventListener("click", function(event){
  2.     if (event.target.className == "toggle"){
  3.         var form = event.target.parentNode.querySelector("form"),
  4.             toggle = event.target;
  5.        
  6.         if (!form.offsetHeight){
  7.             toggle.innerHTML = "Cancelar";                     
  8.             form.style.display = "block";
  9.             form.style.opacity = 1;    
  10.             form.querySelector(".mensaje").focus();
  11.         }
  12.         else{
  13.             toggle.innerHTML = "Responder";
  14.             form.style.opacity = 0;
  15.             setTimeout(function(){     
  16.                 form.style.display = "none";
  17.             }, 150);
  18.             form.reset();
  19.         }
  20.     }
  21. }, false);
  22.  
  23. document.addEventListener("submit", function(event){
  24.     event.preventDefault();
  25.     var self = event.target,
  26.         toggle = self.parentNode.querySelector(".toggle"),     
  27.         respuestas = self.parentNode.parentNode.querySelector(".respuestas"),
  28.         respuesta = self.querySelector(".mensaje").value,
  29.         parrafo = document.createElement("p");
  30.        
  31.     if (respuesta.length){
  32.         parrafo.innerHTML = respuesta;
  33.         respuestas.appendChild(parrafo);   
  34.         toggle.innerHTML = "Responder";
  35.         self.style.opacity = 0;
  36.         setTimeout(function(){     
  37.             self.style.display = "none";
  38.         }, 150);       
  39.         self.reset();
  40.     }
  41.     else{
  42.         self.querySelector(".mensaje").focus();
  43.     }
  44. }, false);

En el primer bloque, detectamos la ejecución del evento click en el documento, tomando al elemento directamente afectado mediante la propiedad event.target y comprobando que su clase sea "toggle". Si esto se cumple, quiere decir que se le dio un clic a cualquiera de los botones para responder. Dentro del bloque de instrucciones, tomamos al formulario, buscándolo en el elemento padre del botón (propiedad parentNode), además del propio botón. Enseguida, compruebo si la altura del formulario es mayor a cero (recordemos que el cero se evalúa como falso, por lo que una cifra distinta será el caso contrario, es decir, verdadero); de ser así, cambio el texto del botón por el de "Cancelar", hago visible al formulario y le doy el enfoque al área de texto del formulario; caso contrario, es decir, si el usuario cancela la respuesta, cambio el texto del botón por el de "Responder", oculto al formulario y lo limpio mediante el método .reset(). Cuando un elemento es oculto por el valor none asignado a la propiedad display, este no tiene presencia en el formulario, por lo que si posee una altura, quiere decir que es visible.

Cabe señalar que utilizo las propiedades opacity y display para darle un efecto especial al momento de mostrar u ocultar al botón o al formulario. La presencia del temporizador (método setTimeout()), se debe a que utilizo la propiedad transition de CSS3 para dilatar unas milésimas de segundo el cambio de opacidad. Si deseas, puedes trabajar solo con la propiedad display.

En el segundo bloque, detectamos la ejecución del evento submit en el documento, el cual se produce cuando se inicia el procesamiento de datos de un formulario. Acto seguido, cancelamos la ejecución de dicho evento mediante el método .preventDefault() para evitar que se recargue la página y se realice el envío. A continuación, tomamos a distintos elementos, como el formulario (que es el elemento en el cual se produjo el evento), el botón para mostrar el formulario, el bloque de respuestas, la respuesta escrita por el usuario y creamos un párrafo en el cual se insertará la respuesta. Si la longitud de la respuesta es superior a cero (el mismo caso del primer bloque de código, solo que ahora se trata de longitud y no de altura), insertamos la respuesta en el párrafo recién creado y lo adherimos al bloque de respuestas mediante el método .appendChild(). Finalmente, cambiamos el texto del formulario por el de "Responder", ocultamos a este último y lo limpiamos para que cuando se desee realizar una futura respuesta al mismo comentario, el área de texto esté vacío. Si no se ha escrito la respuesta pero se pulsa el botón de envío, solo se le dará el enfoque al área de texto.

DEMO

Y otro DEMO que muestra la fecha y hora de cada respuesta.

Como trabajamos con clases y delegando los eventos, puedes tener uno o más comentarios con una o más respuestas. Y si deseas guardar la información en una base de datos, puedes aprovechar que se cancela el evento submit para realizar una petición asíncrona (AJAX).

P. D.: Disculpa si el diseño no es adaptable; lo hice un poco rápido para efectos del ejemplo.

Un saludo
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand

Última edición por Alexis88; 05/12/2015 a las 16:13 Razón: Mejora

Etiquetas: hidden, toggle
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 17:47.