-1

I've a stars rating sistem, and I want to capture the value selected by user and afterwards send it via AJAX to Server for further processing.

I cant alert the value of the star selected with this code:

$("fieldset input").click(function () {
                var radios = document.getElementsByName('rating');

                for (var i = 0, length = radios.length; i < length; i++) {
                    if (radios[i].checked) {
                        // do whatever you want with the checked radio
                        var review_stars = radios[i].value;

                        alert(review_stars);

                        // only one radio can be logically checked, don't check the rest
                        break;
                    }
                }
            });

But as mentioned, I need to save the value to a variable and afterwards send it via AJAX to the Backend. Therefore, I'm inserting the code above into another function that will execute the AJAX part, like this:

$("#send_review").click(function (e) {

            $("fieldset input").click(function () {
                var radios = document.getElementsByName('rating');

                for (var i = 0, length = radios.length; i < length; i++) {
                    if (radios[i].checked) {
                        // do whatever you want with the checked radio
                        var review_stars = radios[i].value;


                        // only one radio can be logically checked, don't check the rest
                        break;
                    }
                }
            });

            alert(review_stars);
 });

But now, I cannot access the review_stars variable. I cannot alert it's value. Why?

UPDATE 1

Updated with answer from Trincot, but value is not alerted:

https://codepen.io/anon/pen/qvmwJb

Omar Gonzales
  • 3,806
  • 10
  • 56
  • 120
  • 3
    Possible duplicate of [What is the scope of variables in JavaScript?](https://stackoverflow.com/questions/500431/what-is-the-scope-of-variables-in-javascript) – Taplar Mar 08 '19 at 18:12
  • 1
    Two issues. #1) It's scoped to low. #2) It's in an event handler which will not have fired when the send review is clicked. #3 issue) You're creating a click binding inside another click binding. **don't do that**™ – Taplar Mar 08 '19 at 18:13

4 Answers4

1

Having a click handler within another click handler is often an indication that something is wrong in the design.

Think of this: why would you need to know which checkbox is checked before you get the user's click on the "send" button? Maybe you have a reason, but the code you provided shows no such reason.

In short, you just need to do the task when preparing the Ajax call, not when a checkbox is clicked. Remove this line and the corresponding closing brackets:

$("fieldset input").click(function () {

... Now you will have the variable where you need it: a var declaration gives the variable a scope within the function it appears in:

$("#send_review").click(function (e) {
    var radios = document.getElementsByName('rating');
    for (var i = 0, length = radios.length; i < length; i++) {
        if (radios[i].checked) {
            // do whatever you want with the checked radio
            var review_stars = radios[i].value;
            // only one radio can be logically checked, don't check the rest
            break;
        }
    }
    alert(review_stars);
});

Of course, you could also solve it with a global variable, but that is not really best practice, at least not in this case.

You could make things easier, by creating a separate function for retrieving the checked checkbox:

function getReviewStars() {
    var radios = document.getElementsByName('rating');
    for (var i = 0, length = radios.length; i < length; i++) {
        if (radios[i].checked) {
            // do whatever you want with the checked radio
            var review_stars = radios[i].value;
            // only one radio can be logically checked, don't check the rest
            break;
        }
    }
    return review_stars; // <---- return it!
}

// And now you can call it whenever you want it:

$("#send_review").click(function () {
    alert(getReviewStars());
});
$("fieldset input").click(function () {
    alert(getReviewStars());
});
trincot
  • 317,000
  • 35
  • 244
  • 286
  • please, see my update 1. It doesn't alert the value, unless instead of returning the value in `getReviewStars()` I do alert it from here. – Omar Gonzales Mar 08 '19 at 20:06
  • There was a missing `)` in my answer. When you open the console you can see the error saying there is a missing `)` at the very end. Just add it, and it works fine. – trincot Mar 08 '19 at 20:15
0

Because variables declared with var have function scope.You should declare review_stars in global scope

var review_stars;
$("#send_review").click(function (e) {

            $("fieldset input").click(function () {
                var radios = document.getElementsByName('rating');
                for (var i = 0, length = radios.length; i < length; i++) {
                    if (radios[i].checked) {
                        // do whatever you want with the checked radio
                        review_stars = radios[i].value;
                        // only one radio can be logically checked, don't check the rest
                        break;
                    }
                }
            });
Maheer Ali
  • 35,834
  • 5
  • 42
  • 73
0

Var variable in JavaScript have function scope.

review_stars scope is set to inside the functions "fieldset input" click handler

Your are referencing to review_stars outside of its scope

Dave Keane
  • 729
  • 8
  • 19
0

As mentioned by others you have a scope issue. You just need to define the variable outside of these functions.

var review_stars;
$("#send_review").click(function (e) {

            $("fieldset input").click(function () {
                var radios = document.getElementsByName('rating');

                for (var i = 0, length = radios.length; i < length; i++) {
                    if (radios[i].checked) {
                        // do whatever you want with the checked radio
                        review_stars = radios[i].value;


                        // only one radio can be logically checked, don't check the rest
                        break;
                    }
                }
            });

            alert(review_stars);
});
dave
  • 2,762
  • 1
  • 16
  • 32