2009-12-26 9 views
0

J'ai essayé de faire fonctionner cela pendant les 7 dernières heures alors s'il vous plaît excuser le léger ton de la frustration.JQuery UI Tabs callbacks ne fonctionne pas

J'ai implémenté avec succès un joli jeu d'onglets jquery ui qui charge leur contenu via ajax.

Le contenu chargé via ajax comporte un formulaire. Je voulais que le premier champ du formulaire (qui a un ID de # titre) soit automatiquement focalisé lorsque l'onglet est chargé. Cela n'a pas fonctionné quand j'ai essayé de mettre le script dans le document externe donc j'ai pensé qu'un rappel serait une bonne idée. J'ai reçu cette idée de here. Le retard est dû au fait que je rencontrais des problèmes avec le champ ne se focalisant pas correctement en cliquant sur chaque onglet. Au début, je pensais que cela avait résolu une partie du problème, mais après encore plus de tests j'ai trouvé que ce champ de focus ne fonctionne que sur l'onglet qui a été initialement chargé.

j'ai décidé de me vider la tête et mettre en œuvre un nouveau test nice jquery autocomplete text field.

Ce script a semblé fonctionner quand directement chargé dans le contenu externe, mais à ma grande consternation a montré que ce ne pas être le cas. Le champ de saisie semi-automatique fonctionne uniquement sur l'onglet chargé lors du chargement de la page.

C'est à ce moment que j'ai remarqué le motif que mes deux scripts ne fonctionnent que sur l'onglet chargé initial.

J'ai essayé d'utiliser les événements select, load et show, mais tous ne fonctionnent pas.

Je sais que le rappel fonctionne parce que l'alerte apparaît lorsque chaque onglet est cliqué.

De toute évidence, je fais quelque chose de très mal. S'il vous plaît choisir mon code en morceaux et dites-moi ce que je fais mal.

<script type="text/javascript"> 
    $(function() { 
     $("#tabs").tabs({ 
     load: function(event, ui) { setTimeout(function() { $("#title").focus(); }, 500); 
       $("#role").autocomplete(
        "/profile/autocomplete", 
        { 
         delay:10, 
         minChars:1, 
         matchSubset:1, 
         matchContains:1, 
         cacheLength:10, 
         onItemSelect:selectItem, 
         onFindValue:findValue, 
         formatItem:formatItem, 
         autoFill:true 
        } 
       ); 

      alert('callback'); 
       } 
      }); 

     }); 
    </script> 
+0

'# title' et '# role' sont-ils dans les onglets? – Mottie

+0

Bonjour, Oui # titre et #role sont chargés via le contenu ajax. Je ne comprends pas vraiment le rôle des rappels, mais j'ai entendu dire qu'ils sont une bonne chose à faire, et les scripts ne fonctionnent pas quand j'essaie d'y accéder à partir d'un onglet ... – Tim

+1

Les rappels sont la bonne façon de planifier un l'action a lieu une fois qu'un autre événement s'est produit. C'est très utile avec le code ajax où une erreur courante est de dire load_foo_via_ajax(); use_foo(); car les deux appels se produiront simultanément et le deuxième morceau de code risque d'échouer car foo n'a pas encore été chargé. –

Répondre

2

Je crois que le problème est que vous n'avez pas d'ID uniques. Si votre code HTML est semblable à ceci:

<div class="tabs"> 
<ul> 
    <li><a href="tab1.htm">Tab1</a></li> 
    <li><a href="tab2.htm">Tab2</a></li> 
</ul> 
</div> 

Le plugin Tab chargera les deux pages (tab1.htm et tab2.htm) dans la page en cours. Et puisque le premier onglet a à la fois #title et #role jQuery arrête de chercher un doublon (à juste titre). Ainsi, la solution facile serait de faire des classes, puis de faire en sorte que la fonction show cible l'onglet sélectionné et appelle le focus et le plugin autocomplete.

$(function(){ 
$(".tabs").tabs({ 
    show: function(e, ui) { 
    $(ui.panel) // target the current tab contents 
    .find('.title').focus().end() 
    .find('.role').autocomplete(
     "/profile/autocomplete", 
     { 
     delay:10, 
     minChars:1, 
     matchSubset:1, 
     matchContains:1, 
     cacheLength:10, 
     onItemSelect:selectItem, 
     onFindValue:findValue, 
     formatItem:formatItem, 
     autoFill:true 
     } 
    ); 
    } 
}); 
}); 

Et pour répondre à une question que vous aviez dans un commentaire, un rappel est essentiellement ce que vous voulez arriver après tout ce que vous faisiez est terminé. Par exemple, la fonction ci-dessous permet de masquer l'élément avec la classe hideme puis une fois l'effet de fadeOut est terminée, la fonction de rappel supprime l'élément de la page (et DOM)

$('.hideme').fadeOut('slow', function(){ 
$(this).remove(); 
}) 

En outre, dans le cas où vous n'êtes pas familier avec .end() il vous permet de chaîner des objets. Plus précisément, il ramène le sélecteur à l'objet le plus récent qui est dans ce cas ui.panel. En savoir plus à ce sujet here et également être sûr de vérifier .andSelf()here.

+0

Merci fudgey pour ça. Cela a résolu mon problème. Wow un rappel précieux de la différence entre les classes et les ID. J'apprécie vraiment les informations supplémentaires que vous avez placées au bas de votre réponse. Je vais certainement lire et apprendre plus sur les DOM et les rappels! – Tim

+0

Donc, cette solution fonctionne, mais j'ai une situation où je ne peux pas sélectionner mon champ par le nom de la classe.J'ai une forme réutilisable, qui vit parfois dans l'onglet et parfois dehors. Parce que je génère automatiquement mes champs de saisie semi-automatique, j'ai besoin d'utiliser le même code tout au long, et l'utilisation d'ID a plus de sens dans le cas général. Existe-t-il un moyen de supprimer l'onglet précédent du DOM, comme solution alternative? – pocketfullofcheese

+0

@pocketfullofcheese: Avez-vous essayé d'utiliser la méthode [tab remove] (http://jqueryui.com/demos/tabs/#method-remove)? Si cela ne vous aide pas, du code aiderait :) – Mottie

-2

pas 100% sûr, mais il peut être parce que vous enveloppez votre code de manipulation dans $(document).ready(function() { ... });.

+0

J'ai supprimé le code ci-dessus, supprimé les cookies et effacé le cache. Malheureusement, le problème demeure. – Tim

2

Votre problème n'est pas entièrement clair à la question. Je dirais que la partie $ (document) .ready n'est définitivement pas nécessaire mais qu'elle ne posera probablement aucun problème puisque je pense qu'elle fonctionnera immédiatement. Ce dont je ne suis pas sûr, c'est comment vous créez vos onglets et en particulier ce que vous entendez par "seulement sur le premier chargement de l'onglet, le chargement d'un autre onglet ne focalise pas le champ". Que voulez-vous dire par charge? Les onglets sont-ils chargés via un appel Ajax ou voulez-vous simplement dire que la page est rendue? Voulez-vous qu'un élément spécifique soit focalisé sur la balise PER ou juste à chaque chargement d'une balise? (Votre code indique un champ spécifique mais votre texte n'est pas clair). Ok, sur la base de vos clarifications, je me rends compte maintenant que le problème est que vous avez plusieurs instances de 'title' et 'role' mais vous utilisez des ID pour les nommer et les référencer. Dans le html, vous avez quelque chose comme ça

<div id="tabs"> 
    <div class="tab"> 
     <input id="title"> 
     <input id="role"> 
    </div> 
    <div class="tab"> 
     <input id="title"> 
     <input id="role"> 
    </div> 
    ... 
    etc 
</div> 

Le problème est, le champ « id » doit être unique pour tous vos éléments, sinon on ne peut se référer à l'un d'entre eux (et pas seulement unique par onglet) .Donc quand vous dites $ ('# title'), vous ne pouvez vous référer qu'au premier élément avec un identifiant de 'titre'. Beaucoup de gens résolvent ce problème en ajoutant des numéros et en donnant des identifiants aux onglets de 'tab1', 'tab2', etc et 'title1', 'title2', etc. C'est en fait une mauvaise idée avec jquery. Vous devriez plutôt utiliser des classes et la méthode très utile jquery .Find() comme ceci:

<script type="text/javascript"> 
    $(function() { 
     $("#tabs").tabs({ 
      load: function(event, ui) { 
       var tab_content = $(ui.panel); 
       setTimeout(function() { tab_content.find(".title").focus(); }, 500); 
       tab_content.find(".role").autocomplete(
        "/profile/autocomplete", 
        { 
         delay:10, 
         minChars:1, 
         matchSubset:1, 
         matchContains:1, 
         cacheLength:10, 
         onItemSelect:selectItem, 
         onFindValue:findValue, 
         formatItem:formatItem, 
         autoFill:true 
        } 
       ); 
       alert('callback'); 
      } 
     }); 
    }); 
</script> 

Toujours pas sûr si le timout sur la mise au point est nécessaire. Vous devriez supprimer cela si c'était juste une tentative de «faire fonctionner quelque chose».

+0

Rob, Je m'excuse profondément pour la question mal formulée. Je suis retourné à travers et ajouté des détails importants que j'ai complètement oublié. Les onglets sont simplement des onglets d'interface utilisateur JQUERY standard qui chargent leur contenu via ajax. Chaque onglet charge dans un formulaire standard que je voulais que le premier champ (# titre) soit automatiquement focalisé. Cela ne fonctionne que sur l'onglet qui a été chargé avec la page. Cliquer sur les autres onglets charge le formulaire, mais le champ #title n'est pas focalisé. Même problème avec mon autre script. J'ai essayé d'afficher, sélectionner et charger des événements mais tous ne parviennent pas à résoudre ce problème. – Tim

+0

Ah, ça confirme ce que je soupçonnais. J'ai modifié ma question pour refléter votre commentaire. –

+0

Merci pour votre aide Rob. J'aimerais pouvoir partager la générosité – Tim