web-dev-qa-db-fra.com

Commutateur CSS à 3 états

Je cherchais un commutateur à 3 états mais je n’ai pas eu beaucoup de chance.

Fondamentalement, j'ai besoin d'un commutateur qui a les états suivants: | ON | N/A | OFF | 

Le curseur par défaut commence au milieu et une fois que l'utilisateur a glissé vers la gauche ou la droite, il ne peut plus revenir à l'état N/A (sans réponse).

Quelqu'un a une idée sur la façon de gérer cela?

14
OHope

Essayez quelque chose comme ça:

.switch-toggle {
  width: 10em;
}

.switch-toggle label:not(.disabled) {
  cursor: pointer;
}
<link href="https://cdn.jsdelivr.net/css-toggle-switch/latest/toggle-switch.css" rel="stylesheet" />

<div class="switch-toggle switch-3 switch-candy">
  <input id="on" name="state-d" type="radio" checked="" />
  <label for="on" onclick="">ON</label>

  <input id="na" name="state-d" type="radio" disabled checked="checked" />
  <label for="na" class="disabled" onclick="">&nbsp;</label>

  <input id="off" name="state-d" type="radio" />
  <label for="off" onclick="">OFF</label>

  <a></a>
</div>

Cela commencera avec N/A comme option par défaut (via checked="checked"), mais le rendra non sélectionnable plus tard (en utilisant disabled)

JSFiddle Demo (simplifié)

28
DarkAjax

En plus de la réponse de gat, il est possible de modéliser cela comme un bouton radio groupé via Bootstrap

<div class="btn-group" data-toggle="buttons">
    <label class="btn btn-primary">
        <input type="radio" name="options" id="On" />ON</label>
    <label class="btn btn-primary">
        <input type="radio" name="options" id="NA" />N/A</label>
    <label class="btn btn-primary">
        <input type="radio" name="options" id="Off" />OFF</label>
</div>

JSFiddle: http://jsfiddle.net/p7DGe/1/

5
Ishan Chatterjee

En tant que plugin jQuery

function filterme(value) {
  value = parseInt(value, 10); // Convert to an integer
  if (value === 1) {
    $('#RangeFilter').removeClass('rangeAll', 'rangePassive').addClass('rangeActive');
    $('span').text('Active');
  } else if (value === 2) {
    $('#RangeFilter').removeClass('rangeActive', 'rangePassive').addClass('rangeAll');
    $('span').text('All');
  } else if (value === 3) {
    $('#RangeFilter').removeClass('rangeAll', 'rangeActive').addClass('rangePassive');
    $('span').text('Passive');
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="range-field" style=" width:60px">
  <input type="range" id="RangeFilter" name="points" onchange="filterme(this.value);" min="1" class="rangeAll" max="3" value="2">
</p>
<span>All</span>

 enter image description here

(function($) {
  $.fn.removeClasses = function(classes) {
    return this.removeClass(classes.join(' '));
  };
  $.fn.switchify = function(config) {
    config = config || {};
    var prefix   =           config.prefix   || 'range-';
    var onCls    = prefix + (config.onCls    || 'on'   );
    var offCls   = prefix + (config.offCls   || 'off'  );
    var unsetCls = prefix + (config.unsetCls || 'unset');
    var $self = this;
    return this.on('change', function(e) {
      var value = parseInt(this.value, 10);
      switch (value) {
        case 1  :  return $self.removeClasses([unsetCls, offCls]).addClass(onCls);
        case 2  :  return $self.removeClasses([onCls, offCls]).addClass(unsetCls);
        case 3  :  return $self.removeClasses([onCls, unsetCls]).addClass(offCls);
        default :  return $self;
      }
    });
  };
})(jQuery);

$('#range-filter').switchify({
   onCls    : 'active',
   offCls   : 'passive',
   unsetCls : 'all'
}).on('change', function(e) {
  var $self = $(this);
  if      ($self.hasClass('range-active'))  $('span').text('Active');
  else if ($self.hasClass('range-passive')) $('span').text('Passive');
  else if ($self.hasClass('range-all'))     $('span').text('All');
  else                                      $('span').text('Error!');
});
.range-field { width: 60px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="range-field">
  <input type="range" id="range-filter" name="points" min="1" class="rangeAll" max="3" value="2">
</p>
<span>All</span>

4
tuncergulcann

J'ai créé un JSFiddle qui illustre un commutateur à trois états entièrement fonctionnel. Veuillez noter que la fenêtre javascript dans JSfiddle ne fonctionnait pas correctement et que le script est chargé dans la fenêtre html.

function togglebutton(range) {
  var val = range.value;
  if (val == 1) {
    //change color of slider background
    range.className = "rangeFalse";

    //alter text 
    $('.toggle-false-msg').attr('id', 'textActive');
    $('.toggle-neutral-msg').attr('id', '');
    $('.toggle-true-msg').attr('id', '');
  } else if (val == 2) {
    //change color of slider background
    range.className = "rangeNeutral";

    //alter text 
    $('.toggle-false-msg').attr('id', '');
    $('.toggle-neutral-msg').attr('id', 'textActive');
    $('.toggle-true-msg').attr('id', '');

  } else if (val == 3) {
    //change color of slider background
    range.className = "rangeTrue";

    //alter text 
    $('.toggle-false-msg').attr('id', '');
    $('.toggle-neutral-msg').attr('id', '');
    $('.toggle-true-msg').attr('id', 'textActive');
  }
}
.test_div {
  height: 50px;
  width: 50px;
  background: #204d75 !important;
  top: 100px;
  position: relative;
  display: block;
}

.toggle-container {
  position: relative;
  width: 8em;
  margin: 1em;
  padding: 0.25em;
  border: thin solid lightgrey;
  text-align: center;
}

.range-field {
  display: inline-block;
  width: 100px;
  margin: 0px;
  border-radius: 2px;
}

input[type=range] {
  -webkit-appearance: none;
  margin: 0;
  width: 100%;
  padding: 0px;
  outline: none;
  border: none;
}

.toggle-false-msg {
  display: none;
  opacity: .2;
  transition: .5s opacity;
  display: inline-block;
  position: relative;
  top: -8px;
}

.toggle-true-msg {
  display: none;
  opacity: .2;
  transition: .5s opacity;
  display: inline-block;
  position: relative;
  top: -8px;
}

.toggle-neutral-msg {
  display: none;
  opacity: .2;
  transition: .5s opacity;
  display: none;
  position: relative;
  top: -8px;
}

#rangeActive {
  background-color: blue;
}

#textActive {
  opacity: 1;
  color: black;
}

input[type=range]:focus {
  outline: none;
}

input[type=range]::-webkit-slider-runnable-track {
  width: 100%;
  height: 30px;
  cursor: pointer;
  animate: 0.2s;
  box-shadow: 0px 0px 0px #000000;
  background: #3071A9;
  border-radius: 0px;
  border: 0px solid #000000;
}

input[type=range]::-webkit-slider-thumb {
  box-shadow: 0px 0px 0px #000000;
  border: 0px solid #000000;
  height: 30px;
  width: 19px;
  border-radius: 0px;
  background: #FFFFFF;
  cursor: pointer;
  -webkit-appearance: none;
  margin-top: 0px;
}

input[type=range]:focus::-webkit-slider-runnable-track {
  background: #3071A9;
}

input[type=range]::-moz-range-track {
  width: 100%;
  height: 30px;
  cursor: pointer;
  animate: 0.2s;
  box-shadow: 0px 0px 0px #000000;
  background: #3071A9;
  border-radius: 0px;
  border: 0px solid #000000;
}

input[type=range]::-moz-range-thumb {
  box-shadow: 0px 0px 0px #000000;
  border: 0px solid #000000;
  height: 30px;
  width: 19px;
  border-radius: 0px;
  background: #FFFFFF;
  cursor: pointer;
}

input[type=range]::-ms-track {
  width: 100%;
  height: 30px;
  cursor: pointer;
  animate: 0.2s;
  background: transparent;
  border-color: transparent;
  color: transparent;
}

input[type=range]::-ms-fill-lower {
  background: #3071A9;
  border: 0px solid #000000;
  border-radius: 0px;
  box-shadow: 0px 0px 0px #000000;
}

input[type=range]::-ms-fill-upper {
  background: #3071A9;
  border: 0px solid #000000;
  border-radius: 0px;
  box-shadow: 0px 0px 0px #000000;
}

input[type=range]::-ms-thumb {
  box-shadow: 0px 0px 0px #000000;
  border: 0px solid #000000;
  height: 30px;
  width: 19px;
  border-radius: 0px;
  background: #FFFFFF;
  cursor: pointer;
}

input[type=range]:focus::-ms-fill-lower {
  background: #3071A9;
}

input[type=range]:focus::-ms-fill-upper {
  background: #3071A9;
}

.rangeFalse::-webkit-slider-runnable-track {
  background: #5d0a0a !important;
}

.rangeFalse::-webkit-slider-thumb {
  background: white !important;
}

.rangeNeutral::-webkit-slider-runnable-track {
  background: #204d75 !important;
}

.rangeNeutral::-webkit-slider-thumb {
  background: white !important;
}

.rangeTrue::-webkit-slider-runnable-track {
  background: #0e4e1f !important;
}

.rangeTrue::-webkit-slider-thumb {
  background: white !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="toggle-container">
  <div class="toggle-false-msg">Off</div>
  <div class="range-field" style=" width:60px">
    <input type="range" name="points" min="1" class="" max="3" value="2"
           onchange="togglebutton(this);">
  </div>
  <div class="toggle-neutral-msg">Neutral</div>
  <div class="toggle-true-msg">On</div>
</div>

Au lieu d'utiliser des boutons radio, ce commutateur utilise une plage et transmet la valeur à JavaScript pour déterminer les actions du commutateur. Le principal obstacle à la conception de ce système a été de changer le pseudo-élément de la plage (en particulier la couleur de fond de la piste). Ceci peut être réalisé en définissant différentes classes avec des éléments pseduo et en utilisant Java pour faire pivoter les classes.

Vous trouverez des informations sur la modification de pseudo-éléments dans le lien ci-dessous. J'ai utilisé la méthode 1 décrite dans l'article.

Ressources

1
Mark Crawford

$(function() {
  $("input[name=radgroup]:checked").click(function() {
    var state = $(this).val();
    // do action depending on state
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type='radio' name='radgroup' value='on' id='on' />
<label for='on'>On</label>
<input type='radio' name='radgroup' value='na' id='na' checked='true' />
<label for='na'>NA</label>
<input type='radio' name='radgroup' value='off' id='off' />
<label for='off'>Off</label>

0
nettux