0
votes

I'm using this plugin to make a simple star rating system -> http://antenna.io/demo/jquery-bar-rating/examples/

Works pretty good up to a point where I get stuck.. I followed the documentation and I made a div with some select items.

$('#skills').barrating({
    theme: 'fontawesome-stars',
    initialRating: null,
    onSelect: function(value, text, event) {
      if (typeof(event) !== 'undefined') {
        // rating was selected by a user
        val = $(event.target).data("rating-value");
        console.log(val);
      }
    }
  });
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/font-awesome/latest/css/font-awesome.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-bar-rating/1.2.2/jquery.barrating.min.js"></script>
<select id="skills">
     <option value="1">1</option>
     <option value="2">2</option>
     <option value="3">3</option>
     <option value="4">4</option>
     <option value="5">5</option>
    </select>

<select id="communication">
     <option value="1">1</option>
     <option value="2">2</option>
     <option value="3">3</option>
     <option value="4">4</option>
     <option value="5">5</option>
    </select>

<select id="quality">
     <option value="1">1</option>
     <option value="2">2</option>
     <option value="3">3</option>
     <option value="4">4</option>
     <option value="5">5</option>
    </select>

And I'm using the script like so:

  $('#skills').barrating({
    theme: 'fontawesome-stars',
    initialRating: null,
    onSelect: function(value, text, event) {
      if (typeof(event) !== 'undefined') {
        // rating was selected by a user
        val = $(event.target).data("rating-value");
        console.log(val);
      }
    }
  });

As you can see on the OnSelect function I'm able to get the star rating value that the user selected. The problem is, I want to store this value in a variable outside of the onSelect function and outside of the barrating function.

I want this because I have multiple star ratings and I need to make an average of those ratings. Any suggestions?

4
Isn't that exactly what you're doing with that val variable?David
Yes but I can't access that variable outside of the barrrating function.. As I was saying I need to access that value outside so I can make an average with it.Ovidiu G
Why can't you? The code shown implies that the val variable is in a higher scope than that function, possibly on the window object itself.David
@OvidiuG, What David is saying is that since your did not declare val with var (or something similar like const or let), val is attached to the window object. Using strict mode, this would through an error.Raphael Rafatpanah

4 Answers

2
votes

For anyone wondering, I was able to fix this by adding a hidden input. Basically, when the OnSelect function happens I set the value of that hidden input to 'val'. This way I will always have the correct value.

<select id="skills">
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
  <option value="4">4</option>
  <option value="5">5</option>
</select>
<input type="hidden" class="skills-rating" name="skills-rating" value="">


  $('#skills').barrating({
    theme: 'fontawesome-stars',
    initialRating: null,
    onSelect: function(value, text, event) {
      if (typeof(event) !== 'undefined') {
        // rating was selected by a user
        val = $(event.target).data("rating-value");
        $(".skills-rating").val(val);
      }
    }
  });
1
votes

You can declare a variable outside the scope of barrating() and use $.extend() to merge new data into the original state.

var state = {};

$('#skills').barrating({
  theme: 'fontawesome-stars',
  initialRating: null,
  onSelect: function(value, text, event) {
    if (typeof(event) !== 'undefined') {
      // rating was selected by a user
      var val = $(event.target).data("rating-value");
      $.extend(state, {skills: val});
      console.log(state);
    }
  }
});

$('#communication').barrating({
  theme: 'fontawesome-stars',
  initialRating: null,
  onSelect: function(value, text, event) {
    if (typeof(event) !== 'undefined') {
      // rating was selected by a user
      var val = $(event.target).data("rating-value");
      $.extend(state, {communication: val});
      console.log(state);
    }
  }
});
1
votes

You can either create a map; globally to store the ratings or you can create a jQuery plugin to scrape the values from the widgets.

var formState = {};

(function($) {
  $.fn.starRating = function() {
    return this.next().find('.br-current').data('rating-text');
  };
  $.fn.starRatings = function() {
    var map = {};
    this.each(function(index, widget) {
      map[$(widget).attr('name')] = $(widget).starRating();
    });
    return map;
  };
})(jQuery);

$('.star-rating').barrating({
  theme : 'fontawesome-stars',
  initialRating : null,
  onSelect : function(value, text, event) {
    var $starWidget = $(event.target),
        $select = $starWidget.parent().prev(),
        val = $starWidget.data('rating-value');

    // Global form state
    formState[$select.attr('name')] = val;
    console.log(JSON.stringify(formState));
    
    // jQuery plugin to get all the ratings.
    console.log(JSON.stringify($('.star-rating').starRatings()));
    
    // Get individual rating.
    console.log($('select[name="skills"]').starRating());
  }
});
.as-console-wrapper { max-height: 4em !important; }
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/font-awesome/latest/css/font-awesome.min.css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/jquery-bar-rating/1.2.2/themes/fontawesome-stars.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jquery-bar-rating/1.2.2/themes/css-stars.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-bar-rating/1.2.2/jquery.barrating.min.js"></script>

<form>
  <label>Skills</label>
  <select name="skills" class="star-rating">
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
  </select>

  <label>Communication</label>
  <select name="communication" class="star-rating">
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
  </select>

  <label>Quality</label>
  <select name="quality" class="star-rating">
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
  </select>
</form>
0
votes

Just take an array to store the all ratings. Push new value each time OnSelect is performed.

 var ratings = [];

 $('#skills').barrating({
   theme: 'fontawesome-stars',
   initialRating: null,
   onSelect: function(value, text, event) {
     if (typeof(event) !== 'undefined') {
      // rating was selected by a user
      val = $(event.target).data("rating-value");
      console.log(val);
      ratings.push(val); 
    }
  }
});