2011-01-11 7 views
12

Ho una funzione jQuery che commuta la visibilità del contenuto di un fieldset quando il suo legenda viene cliccato, lasciando solo il confine fieldset (se presente) e la legenda mostrando:collasso fieldset quando l'elemento legenda cliccata

$('legend.togvis').click(function() { 
    $(this).siblings().toggle(); 
    return false; 
}); 

Funziona benissimo a meno che il fieldset contenga nodi di testo.

<fieldset><legend class='togvis'>Click Me</legend> 
    <p>I toggle when the legend is clicked.</p> 
    But I'm a recalcitrant text node and refuse to toggle. 
</fieldset> 

Nel tentativo di alternare il testo nodi troppo Ho provato questo:

$('legend.togvis').click(function() { 
    $(this).parent().contents().not('legend').toggle(); 
    return false; 
}); 

che funziona come la prima funzione. E questo:

$('legend.togvis').click(function() { 
    $(this).parent().contents(":not(legend)").toggle(); 
    return false; 
}); 

che genera l'errore

Message: 'style.display' is null or not an object 
Line: 5557 
Char: 3 
Code: 0 
URI: http://code.jquery.com/jquery-1.4.4.js 

Ogni pensiero su come ottenere i intero contenuto di un fieldset (meno la leggenda) per attivare o disattivare quando la leggenda si fa clic?

ETA Solution, con molti ringraziamenti per Eibx

$('legend.togvis').click(function() { 
    $(this).parent().contents().filter(
     function() { return this.nodeType == 3; }).wrap('<span></span>');//wrap any stray text nodes 
    $(this).siblings().toggle(); 
}); 
+0

sembra che il problema sia che i nodi di testo non hanno/non possono avere uno stile. Poiché '.toggle()' funziona influenzando il css del nodo, non può influenzare i nodi del testo. Forse ho bisogno di memorizzare il contenuto del fieldset in '.data()' e quindi rimuovere i bambini? – dnagirl

risposta

14

Semplicemente non è possibile far scomparire il testo in HTML, JavaScript o CSS. Deve essere contenuto in un elemento HTML con display:none; applicato o qualcosa di simile.

Il seguente codice racchiude tutto in un div e sposta la legenda allo stesso livello del div e crea il div show/hide quando si fa clic sulla legenda.

$("fieldset legend").click(function() { 
    if ($(this).parent().children().length == 2) 
    $(this).parent().find("div").toggle(); 
    else 
    { 
    $(this).parent().wrapInner("<div>"); 
    $(this).appendTo($(this).parent().parent()); 
    $(this).parent().find("div").toggle(); 
    } 
}); 
+0

questa è davvero una bella soluzione perché il markup viene aggiunto dalla funzione che ne ha bisogno. – dnagirl

+0

Grazie - ma ti consiglio di spostare parte del codice in $ (document) .ready() poiché questo controllerà l'elemento ad ogni clic. Sarebbe intelligente per assicurarsi che tutte le leggende abbiano i bambini giusti. Qualcosa di simile: http://jsbin.com/eleva3/2/edit –

+0

Sfortunatamente, sta causando alcuni problemi di layout. Mi stai mandando davvero in una buona direzione. – dnagirl

5

Utilizzare un tag div per separare il contenuto, qualcosa di simile:

<fieldset> 
    <legend class='togvis'>Click Me</legend> 
    <div class="contents"> 
    <p>I toggle when the legend is clicked.</p> 
    But I'm a recalcitrant text node and refuse to toggle. 
    </div> 
</fieldset> 

Poi solo bisogno di attivare o disattivare la div.

$('legend.togvis').click(function() { 
    $(this).closest("contents").toggle(); 
    return false; 
}); 

Aggiornamento solo nel caso in cui non è possibile modificare il codice HTML è possibile effettuare le seguenti operazioni ma funzionerà solo se tutti i testi sono a almeno un tag:

$('legend.togvis').click(function() { 
    $(this).parents("fieldset").find("*:not('legend')").toggle(); 
    return false; 
}); 

online demo qui:http://jsfiddle.net/yv6zB/1/

+0

potrebbe non essere in grado di farlo – hunter

+0

grazie, l'ho preso in considerazione ora – amosrivera

+0

non funziona ancora – hunter

0

Potrebbe essere semplicemente racchiudere il testo nel tag sibilig:

<fieldset><legend class='togvis'>Click Me</legend> 
    <div><p>I toggle when the legend is clicked.</p> 
    But I'm a recalcitrant text node and refuse to toggle.</div> 
</fieldset> 
+0

potrebbe non essere in grado di fare quello – hunter

10

Poiché i nodi di testo non sono elementi, non è possibile spostarli.

Come ultima risorsa, se non li può avvolgere con un elemento, è possibile rimuovere tutto tranne la leggenda e aggiungere gli elementi e il testo nodi più tardi:

$(document).ready(function() { 
    $('legend.togvis').click(function() { 
     var $this = $(this); 
     var parent = $this.parent(); 
     var contents = parent.contents().not(this); 
     if (contents.length > 0) { 
      $this.data("contents", contents.remove()); 
     } else { 
      $this.data("contents").appendTo(parent); 
     } 
     return false; 
    }); 
}); 

È possibile verificare questa soluzione here.

+0

+1 ben fatto, signore – hunter

+0

+1 per il caching degli oggetti jquery – JCM

+0

Questo dovrebbe funzionare per me. Volevo essere in grado di attivare un fieldset con i controlli di filtro dei report, così ho avuto un paio di drop down e un paio di caselle di testo e le relative etichette. –

0

Ho apprezzato la risposta accettata, ma non lo abbiamo trovato abbastanza robusto per i miei scopi. Solo il controllo della lunghezza del numero di elementi figlio non supporta molti scenari. Come tale, prenderei in considerazione l'utilizzo di un'implementazione simile a:

$("fieldset legend").click(function() { 
    var fieldset = $(this).parent(); 
    var isWrappedInDiv = $(fieldset.children()[0]).is('div'); 

    if (isWrappedInDiv) { 
     fieldset.find("div").slideToggle(); 
    } else { 
     fieldset.wrapInner("<div>"); 
     $(this).appendTo($(this).parent().parent()); 
     fieldset.find("div").slideToggle(); 
    } 
}); 
Problemi correlati