Star vote with input radio, javascript / css

5

I am creating a registration form, in it I will insert a voting system, I wanted to do that when clicking on some star, the previous ones will change color as well. (Here is the code I created)

<div class="vote">
<label>
    <input type="radio" id="cm_star" name="fb" value="1" />
    <i class="fa"></i>
</label>
<label>
    <input type="radio" id="cm_star" name="fb" value="2" />
    <i class="fa"></i>
</label>
<label>
    <input type="radio" id="cm_star" name="fb" value="3" />
    <i class="fa"></i>
</label>
<label>
    <input type="radio" id="cm_star" name="fb" value="4" />
    <i class="fa"></i>
</label>
<label>
    <input type="radio" id="cm_star" name="fb" value="5" />
    <i class="fa"></i>
</label>

The result in image:

    
asked by anonymous 22.06.2015 / 17:41

3 answers

14

You can do this using CSS only, with the ~ sibling selector and some HTML modifications.

.estrelas input[type=radio] {
  display: none;
}
.estrelas label i.fa:before {
  content:'\f005';
  color: #FC0;
}
.estrelas input[type=radio]:checked ~ label i.fa:before {
  color: #CCC;
}
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<div class="estrelas">
  <input type="radio" id="cm_star-empty" name="fb" value="" checked/>
  <label for="cm_star-1"><i class="fa"></i></label>
  <input type="radio" id="cm_star-1" name="fb" value="1"/>
  <label for="cm_star-2"><i class="fa"></i></label>
  <input type="radio" id="cm_star-2" name="fb" value="2"/>
  <label for="cm_star-3"><i class="fa"></i></label>
  <input type="radio" id="cm_star-3" name="fb" value="3"/>
  <label for="cm_star-4"><i class="fa"></i></label>
  <input type="radio" id="cm_star-4" name="fb" value="4"/>
  <label for="cm_star-5"><i class="fa"></i></label>
  <input type="radio" id="cm_star-5" name="fb" value="5"/>
</div>

Note: It was necessary to include a pre-selected empty radius so that stars appear correctly when no value is selected.

    
22.06.2015 / 19:09
5

I did using pure javascript, basically I created a function to go through all img with same name and according to which star was clicked (index) I assign whether it will be highlight or not.

function seleciona(name, indice) {
   var imgs = document.querySelectorAll('img[name=' + name + ']');
  
   for (var i=0; i < imgs.length; i++) {
       if (i <= indice)
           imgs[i].className = "destaque";
       else
           imgs[i].className = "apagada";
   }
}

window.onload = function() {
   var imgs = document.querySelectorAll('img[name=fb]');
  
   for (var i=0; i < imgs.length; i++) {
       (function(name, i) {
          imgs[i].addEventListener('click', function () {
              seleciona(name, i);
          });
       })(imgs[i].name, i);
   }
}
.apagada {
  background-image: url('http://www.biblecast.net.br/resources/estrela-prata.png');
  width: 32px;
  height: 32px;
  cursor: pointer;
}

.destaque {
  background-image: url('http://imobiliariacincoestrelas.com.br/images/estrela.png');
  width: 32px;
  height: 32px;
  cursor: pointer;
}
<label>
    <img name="fb" class="apagada"/>
</label>
<label>
    <img name="fb" class="apagada"/>
</label>
<label>
    <img name="fb" class="apagada"/>
</label>
<label>
    <img name="fb" class="apagada"/>
</label>
<label>
    <img name="fb" class="apagada"/>
</label>
    
22.06.2015 / 18:12
5

Following your HTML structure, here is a suggestion using jQuery.

$('.vote label i.fa').on('click mouseover',function(){
    // remove classe ativa de todas as estrelas
    $('.vote label i.fa').removeClass('active');
    // pegar o valor do input da estrela clicada
    var val = $(this).prev('input').val();
    //percorrer todas as estrelas
    $('.vote label i.fa').each(function(){
        /* checar de o valor clicado é menor ou igual do input atual
        *  se sim, adicionar classe active
        */
        var $input = $(this).prev('input');
        if($input.val() <= val){
            $(this).addClass('active');
        }
    });
    $("#voto").html(val); // somente para teste
});
//Ao sair da div vote
$('.vote').mouseleave(function(){
    //pegar o valor clicado
    var val = $(this).find('input:checked').val();
    //se nenhum foi clicado remover classe de todos
    if(val == undefined ){
        $('.vote label i.fa').removeClass('active');
    } else { 
        //percorrer todas as estrelas
        $('.vote label i.fa').each(function(){
            /* Testar o input atual do laço com o valor clicado
            *  se maior, remover classe, senão adicionar classe
            */
            var $input = $(this).prev('input');
            if($input.val() > val){
                $(this).removeClass('active');
            } else {
                $(this).addClass('active');
            }
        });
    }
    $("#voto").html(val); // somente para teste
});
.vote label {
    cursor:pointer;
}
.vote label input{
    display:none;
}
.vote label i {
    font-family:FontAwesome;
    font-size:18px;
    -webkit-transition-property:color, text;
    -webkit-transition-duration: .2s, .2s;
    -webkit-transition-timing-function: linear, ease-in;
    -moz-transition-property:color, text;
    -moz-transition-duration:.2s;
    -moz-transition-timing-function: linear, ease-in;
    -o-transition-property:color, text;
    -o-transition-duration:.2s;
    -o-transition-timing-function: linear, ease-in;
}
.vote label i:before {
    content:'\f005';
}
.vote label i.active {
    color:gold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><linkrel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<div class="vote">
<label>
    <input type="radio" name="fb" value="1" />
    <i class="fa"></i>
</label>
<label>
    <input type="radio" name="fb" value="2" />
    <i class="fa"></i>
</label>
<label>
    <input type="radio" name="fb" value="3" />
    <i class="fa"></i>
</label>
<label>
    <input type="radio" name="fb" value="4" />
    <i class="fa"></i>
</label>
<label>
    <input type="radio" name="fb" value="5" />
    <i class="fa"></i>
</label>
</div>

<div id="voto">
    
</div>

JSFiddle

    
22.06.2015 / 18:45