web-dev-qa-db-fra.com

Comment styliser l'étiquette parent d'une entrée radio cochée

Je dois styliser certaines entrées radio. J'ai essayé des solutions d'ici mais aucune n'a fonctionné pour moi. Quelqu'un peut-il s'il vous plaît jeter un oeil à ce code et me dire que puis-je faire?

C'est le HTML:

<div class="controls">
  <table>
    <tbody>
      <tr>
        <td>
          <label class="radio">
            <input type="radio" name="ad_caroserie" value="0">Berlina
          </label>
        </td>
        <td>
          <label class="radio">
            <input type="radio" name="ad_caroserie" value="1">Break
          </label>
        </td>
        <td>
          <label class="radio">
            <input type="radio" name="ad_caroserie" value="2">Cabrio
          </label>
        </td>
      </tr>
    </tbody>
  </table>
</div>

Et le CSS:

label.radio {
  background: #fcb608;
}
.radio input {
  display: none;
}
label.radio input[type="radio"]:checked + label {
  background: #000 !important;
  border: 1px solid green;
  padding: 2px 10px;
}

Le CSS n'a pas l'effet désiré. Pouvez-vous m'aider s'il vous plaît?

Voici quelques extraits connexes de JS: 

//If checkboxes or radio buttons, special treatment

  else if (jQ('input[name="'+parentname+'"]').is(':radio')  || jQ('input[name="'+parentname+'[]"]').is(':checkbox')) {
    var find = false;
    var allVals = [];
    jQ("input:checked").each(function() {
      for(var i = 0; i < parentvalues.length; i++) {
        if (jQ(this).val() == parentvalues[i] && find == false) {  
          jQ('#adminForm #f'+child).show();
          jQ('#adminForm #row_'+child).show();
          find = true;
        }
      }
    });
    if (find == false) {
      jQ('#adminForm #f'+child).hide();
      jQ('#adminForm #row_'+child).hide();
      //cleanup child field 
      if (jQ('#adminForm #f'+child).is(':checkbox') || jQ('#adminForm #f'+child).is(':radio')) {
        jQ('#adminForm #f'+child).attr('checked', false);
      }
      else {
        if (cleanValue == true) {
          jQ('#adminForm #f'+child).val('');
        }
      }
    }
  }
  else {
    var find = false;
    for(var i = 0; i < parentvalues.length; i++) {
      if (jQ('#adminForm #f'+parentname).val() == parentvalues[i] && find == false) {  
        jQ('#adminForm #f'+child).show();
        jQ('#adminForm #row_'+child).show();
        find = true;
      }
    }
    if(find == false) {
      jQ('#adminForm #f'+child).hide();
      jQ('#adminForm #row_'+child).hide();
      //cleanup child field 
      if (jQ('#adminForm #f'+child).is(':checkbox') || jQ('#adminForm #f'+child).is(':radio')) {
        jQ('#adminForm #f'+child).attr('checked', false);
      }
      else {
        if (cleanValue == true) {
          jQ('#adminForm #f'+child).val('');
        }
      }
    }
  }
}

function dependency(child,parentname,parentvalue) {
  var parentvalues = parentvalue.split(",");
  //if checkboxes
  jQ('input[name="'+parentname+'[]"]').change(function() {
    checkdependency(child,parentname,parentvalues,true);
    //if checkboxes
    jQ('input[name="'+child+'[]"]').change();
    jQ('input[name="'+child+'"]').change();
    jQ('#'+child).change();
  });
  //if buttons radio
  jQ('input[name="'+parentname+'"]').change(function() {
    checkdependency(child,parentname,parentvalues,true);
    //if checkboxes
    jQ('input[name="'+child+'[]"]').change();
    jQ('input[name="'+child+'"]').change();
    jQ('#'+child).change();
  });
  jQ('#f'+parentname).click(function() {
    checkdependency(child,parentname,parentvalues,true);
    //if checkboxes
    jQ('input[name="'+child+'[]"]').change();
    jQ('input[name="'+child+'"]').change();
    jQ('#f'+child).change();
  });
  checkdependency(child,parentname,parentvalues,false);
}
3
Dinu Raph Alexandru

Une possibilité

Au moment de la publication de mon message, je ne suis pas tout à fait sûr de ce que devrait être la mise en page souhaitée, mais il existe un problème spécifique dans la tentative de CSS qui doit être résolu.

Le sélecteur de frères et sœurs adjacents :

... sépare deux sélecteurs et ne fait correspondre le deuxième élément que s'il suit immédiatement le premier élément.

Si le <input> est un enfant du <label>, il n'est pas adjacent, alors:

label.radio input[type="radio"]:checked + label

est à la recherche d'une label suivant immédiatement un :checkedinput dans une label avec la classe .radio, et rien de tel n'existe.

Pour modifier le style de label dans ce cas, il faudrait un sélecteur qui affecte le parent, qui n'est actuellement pas possible .

Donc, pour sélectionner la label du :checkedinput, il faut que la label soit adjacente, pas le parent.

Nous pouvons utiliser l'attribut for="id" :

Un <label> peut être associé à un contrôle en plaçant l'élément de contrôle à l'intérieur de l'élément <label> ou en utilisant l'attribut for.

Comme je l'ai dit, je ne suis pas tout à fait sûr de la disposition souhaitée, mais voici un exemple utilisant l'attribut for, qui n'a pas l'air trop mal.

div {
  display: inline-block;
  position: relative;
}
label {
  background: #fcb608;
  padding: 2px 10px 2px 1.5em;
  border: 1px solid transparent; /* keeps layout from jumping */
}
input {
  position: absolute;
}
input[type="radio"]:checked + label {
  background: #000;
  border-color: green;
  color: white;
}
<div>
  <input id="id1" type="radio" name="ad_caroserie" value="0"><label for="id1" class="radio">Berlina</label>
</div>
<div>
  <input id="id2" type="radio" name="ad_caroserie" value="1"><label for="id2" class="radio">Break</label>
</div>
<div>
  <input id="id3" type="radio" name="ad_caroserie" value="2"><label for="id3" class="radio">Cabrio</label>
</div>

Avec <input> en tant qu'enfant de <label>

Utilisation d'un petit gestionnaire JavaScript listening pour remplace par le <form>.

  • Si une change est détectée, la fonction déclenchée vérifie si un <input type="radio"> a été modifié et, dans l'affirmative, s'il a un <label> comme étant sa parentElement.
  • Si c'est vrai, il vérifie s'il existe un <input type="radio"> portant le même nom et qui est l'enfant d'un élément <label> avec le class.checked.
  • Si c'est le cas, cela supprime la class du <label> avant d'appliquer la même class au <label> parent de la <input>target qui a déclenché le tout.

let form = document.querySelector( "form" );
form.addEventListener( "change", ( evt ) => {
  let trg = evt.target,
      trg_par = trg.parentElement;
  if ( trg.type === "radio" && trg_par && trg_par.tagName.toLowerCase() === "label" ) {
    let prior = form.querySelector( 'label.checked input[name="' + trg.name + '"]' );
    if ( prior ) {
      prior.parentElement.classList.remove( "checked" );
    }
    trg_par.classList.add( "checked" );
  }
}, false );
label {
  background: #fcb608;
  padding: 2px 10px 2px 0;
  border: 1px solid transparent; /* keeps layout from jumping */
}
label.checked {
  background: #000;
  border-color: green;
  color: white;
}
<form>
  <label class="radio"><input type="radio" name="ad_caroserie" value="0">Berlina</label>
  <label class="radio"><input type="radio" name="ad_caroserie" value="1">Break</label>
  <label class="radio"><input type="radio" name="ad_caroserie" value="2">Cabrio</label>
</form>

Sans JavaScript les choses deviennent difficiles (selon mon explication initiale de la raison pour laquelle il est préférable d'utiliser l'attribut for dans ce cas).

Nous pouvons utiliser la propriété appearance ( avec les préfixes et support raisonnable ) pour masquer efficacement l'interface utilisateur radio de l'agent-agent, puis utiliser l'élément restant faceless pour créer un fakebackground pour le <label>.

C’est très hacky et beaucoup moins dynamique que la valeur par défaut, car il faut du positionnement absolute et des dimensions spécifiques pour le réussir.
Cela fonctionne (dans la plupart des navigateurs), mais il est difficile d’appliquer l’ensemble du site.

Quelque chose à jouer avec cependant :-)

input {
  position: absolute;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  width: 5em;
  height: 1.5em;
  z-index: -1;
  background: #fcb608;
  border: 1px solid transparent;
  margin: -.1em -.8em;
  outline: 0;
}
label {
  display: inline-block;
  width: 5em;
  color: white;
  text-shadow: 1px 1px 0px black;
}
input[type="radio"]:checked {
  background: #000;
  border-color: green;
}
<label class="radio"><input type="radio" name="ad_caroserie" value="0">Berlina</label>
<label class="radio"><input type="radio" name="ad_caroserie" value="1">Break</label>
<label class="radio"><input type="radio" name="ad_caroserie" value="2">Cabrio</label>

7
Fred Gandt

Il suffit d’utiliser jQuery avec une nouvelle classe css "sélectionnée" qui ressemble à ceci:

au début:

$("input[name='ad_caroserie']:checked").parent().addClass("selected");

et onchange:

$('input[type=radio][name=ad_caroserie]').change(function() {
  $("input[name='ad_caroserie']").parent().removeClass("selected");
  $("input[name='ad_caroserie']:checked").parent().addClass("selected");
  // console.log($("input[name='ad_caroserie']:checked").val());
});
0
paddibr