2009-12-10 10 views
0

J'ai un <asp:CheckBoxList> en utilisant RepeatLayout="Flow" dans ma page J'affecte dynamiquement des valeurs à. Si la page est chargée la première fois (!IsPostBack), la version rendue ressemble à ceci;Empêcher le nouveau rendu de CheckBoxList

<span children="Cat"> 
    <input id="ctl00_Menu_Category_0" type="checkbox" name="ctl00$Menu$Category$0"/> 
    <label for="ctl00_Menu_Category_0">Cat</label> 
</span> 
<br/> 
<span class="Cat"> 
    <input id="ctl00_Menu_Category_1" type="checkbox" name="ctl00$Menu$Category$1"/> 
    <label for="ctl00_Menu_Category_1"> - SubCat1</label> 
</span> 

children est un attribut que j'utilise un code jQuery, donc lorsque les contrôles utilisateur Cat, tous les SubCat s sont également vérifiés.

Le code jQuery recherche tous les <span> s ayant la classe égale à l'attribut children, donc j'ai besoin de maintenir cette structure que le jQuery fonctionne.

Mais, après que je recharger la page ou suivre un lien, quelle que soit, la liste semble tout à coup comme ceci:

<input id="ctl00_Menu_Category_0" type="checkbox" name="ctl00$Menu$Category$0"/> 
<label for="ctl00_Menu_Category_0">Cat</label> 
<br/> 
<input id="ctl00_Menu_Category_1" type="checkbox" name="ctl00$Menu$Category$1"/> 
<label for="ctl00_Menu_Category_1"> - SubCat1</label> 

Comment est-ce possible? J'ai assigné les valeurs à la liste une seule fois, alors pourquoi est-il rendu à nouveau après un PostBack et comment puis-je l'empêcher de le faire?

Modifier

Voici le code qui crée la liste;

// Get all available categories that are not a child of another category 
DataTable categoryParents = functions.SelectSql(Resources.Data.GetCategoryParents); 

// Get the child categories 
foreach (DataRow parent in categoryParents.Rows) 
{ 
    // Add the category 
    ListItem parentItem = new ListItem(parent["Name"].ToString(), parent["Name"].ToString()); 
    parentItem.Attributes.Add("children", parent["Name"].ToString().Replace(' ', '_')); 
    Category.Items.Add(parentItem); 

    // For every parent category, get all its child categories 
    DataTable categoryChildren = functions.SelectSql(Resources.Data.GetCategoryChildrenByParent.Replace("##PARENTID##", parent["ID"].ToString())); 

    // Add the child categories after their parents 
    foreach (DataRow child in categoryChildren.Rows) 
    { 
     ListItem item = new ListItem(" - " + child["Name"].ToString(), parent["Name"].ToString() + "\\" + child["Name"].ToString()); 
     item.Attributes.Add("class", parent["Name"].ToString().Replace(' ', '_')); 
     Category.Items.Add(item); 
    } 
} 
Category.DataBind(); 

jQuery lui-même ne fait rien avec le HTML, il ne détient que la fonctionnalité pour vérifier les catégories d'enfants lorsqu'un parent est vérifié;

$("#Category :checkbox").click(function(){ 
    var checked = $(this).attr("checked"); 
    var children = $(this).parent("span").attr("children"); 
    $("#Category ." + children + " :checkbox").attr("checked", checked); 
}); 

Répondre

0

Le code HTML entier sera toujours rendu chaque fois que vous rechargez la page. Ce que vous pouvez empêcher en vérifiant IsPostBack est en changeant comment le HTML est rendu cette fois. Cela signifie que lors de la publication de la page, le serveur ne liera pas la liste de cases à cocher avec de nouvelles valeurs, mais ira directement pour les rendre exactement comme il l'a fait la dernière fois, en utilisant les valeurs stockées dans ViewState.

Si votre code jQuery modifie le HTML après son rendu, le serveur aura aucune idée et il n'y a vraiment aucun moyen possible de changer cela. La question intéressante ici est: comment sont les enveloppes d'emballage et les propriétés children et tout ce code qui est appliqué en premier lieu?

Vos options sont à faire une des opérations suivantes:

  • Faire une demande AJAX plutôt qu'un postback complet, en changeant seulement la partie du DOM que vous souhaitez modifier
  • Réappliquer le code jQuery qui permet d'obtenir cette modification, sur domready après la publication

EDIT

En réponse à TH e modifications dans le message d'origine:

Est Category votre CheckBoxList? Si vous avez ajouté itérativement tous les éléments de la liste, pourquoi est-ce que vous renumérotez la liste après cela? Je pense que la première boucle devrait rendre le databinding obsolète.Ma meilleure estimation ici est que lorsque CheckBoxList est en cours de sérialisation à ViewState, il stocke les propriétés qui lui sont appliquées, avec un dictionnaire id/value pour les listitems (et non les propriétés supplémentaires que vous appliquez itérativement).

Si ce n'est pas enregistré dans le ViewState - et il semble qu'il ne l'est pas - il n'y a pas de solutions vraiment propres à votre problème. Contournement serait d'exécuter le code sur chaque pageload, ou hériter le CheckBoxList dans une sous-classe, qui remplace la méthode Render, pour toujours produire la sortie que vous voulez. En fait, cette dernière option pourrait être assez soignée, si vous l'utilisez beaucoup tout au long du site ...?

+0

jQuery ne fait aucune manipulation, voir mon édition. –

+0

bien, je crains que je n'ai pas une solution simple et génial, mais voir mon édition –

+0

D'accord, une solution de contournement a semblé fonctionner; Je définis 'EnableViewState =" false "' et maintenant il rend correctement chaque fois ... mais supprime les boîtes sélectionnées après rechargement: -/ –