Steps to store radio button selections in local storage

I have a quiz that includes radio buttons, and I need to save the answers on my local storage. However, I am currently stuck and unsure of what else to do. I am learning, so please don't be too hard on me. Thank you!

Here is the code I have written so far:

<form id="quiz"> </form>
    <script>

        let object;
        let httpRequest = new XMLHttpRequest(); 
        httpRequest.open("GET", "quiz.json", true);
        httpRequest.send();
        httpRequest.addEventListener("readystatechange", function () {
        if (this.readyState === this.DONE) {
                object = JSON.parse(this.response);
                console.log(object)
            }
            let json = object

            let quiz = document.getElementById("quiz");
            let keyList = Object.keys(json.quiz);

            for (let i = 0; i < keyList.length; i++) {
                let key = keyList[i];
                let questionItem = json.quiz[key];
                let html = "<div>";
                html += "<div><h2>Question " + (i + 1) + ": " + questionItem.question + "</h2></div>";
                html += "<div>";
                for (let i = 0; i < questionItem.options.length; i++) {
                    html += "<div >";
                    html += "<input type=\"radio\" id=\"q\" checked=\"checked\" name=\"qzz" + key + "_option\"  value=\"" + questionItem.options[i] + "\">" + questionItem.options[i] ;
                    html += "</div>";
                }

                quiz.innerHTML += html;
            }
            quiz.innerHTML += "<input type=\"submit\" value=\"submit\">";       
 
function save() {
  
  var g1 = document.querySelector('input[type="radio]');
  g1 = (g1) ? g1.value : '';
  localStorage.setItem("g1", g1);
}
        });

Answer №1

To simplify your AJAX dialog, try using fetch() instead of new XMLHttpRequest();. I have made some adjustments to your code (also refer to the comments in @brianagulo's answer) and created a sample set of data to showcase the quiz functionality. Note that the jsonplaceholder.typicode.com URL is just a placeholder for a working json-server endpoint and the received data is not utilized here.

In your "production version," remember to uncomment the line:

localStorage.setItem("quiz", JSON.stringify(ans))

The selected answers are stored in an object using:

[...document.querySelectorAll('input[type=radio]:checked')].reduce((a,{name,value}) => (a[name]=value,a), {});

This code snippet:

  • Gathers all checked radio button inputs (
    document.querySelectorAll('input[type=radio]:checked')
    ),
  • Converts the DOM element collection into an array (using [... ]), and finally
  • Reduces the elements into an object where the element names become property names and the values are property values.

Remember that you can only store strings in local storage. That's why the ans object is converted into a JSON string before using it with .setItem().

const Q = {
  quiz: [{
    question: "Where was the Boston tea party?",
    options: ["New York", "Detroit", "Boston", "Reno"]
  }, {
    question: "Where would you find Venice Beach?",
    options: ["Detroit", "Venice", "Paris", "Los Angeles"]
  }, {
    question: "Where would you find Queens?",
    options: ["London", "Paris", "Stockholm", "New York"]
  }, {
    question: "Where is Greenwich Village?",
    options: ["London", "Paris", "Stockholm", "New York"]
  }, {
    question: "Where would you find the Gateway Arch?",
    options: ["St. Quentin", "St. Louis", "St. Anton", "San Francisco"]
  }]
}, quiz = document.getElementById("quiz");
var url = "quiz.json";
// In your live application: Uncomment the following line
url = "https://jsonplaceholder.typicode.com/users/7"; // Working test URL for fetch

function save(ev) {
  ev.preventDefault();
  const ans = [...document.querySelectorAll('input[type=radio]:checked')].reduce((a,{name,value}) =>(a[name] = value, a), {});
  // Local storage cannot be used in Stack Overflow snippets, so here is console.log instead:
  console.log(ans);
  // In your live application: Uncomment the following line
  // localStorage.setItem("quiz",JSON.stringify(ans))
}
fetch(url).then(r=>r.json()).then(object=>{
  // Remove the next line:
  object = Q; // Use the static quiz defined in Q instead ...

  let json = object;
  let keyList = Object.keys(json.quiz);

  for (let i = 0; i < keyList.length; i++) {
    let key = keyList[i];
    let questionItem = json.quiz[key];
    let html = "<div>";
    html += "<div><h2>Question " + (i + 1) + ": " + questionItem.question + "</h2></div>";
    html += "<div>";
    for (let i = 0; i < questionItem.options.length; i++) {
      html += "<label>";
      html += "<input type=\"radio\" id=\"q\" name=\"qzz" + key + "_option\"  value=\"" + questionItem.options[i] + "\"> " + questionItem.options[i];
      html += "</label><br>";
    }

    quiz.innerHTML += html;
  }
  quiz.innerHTML += "<input type=\"submit\" value=\"submit\">";
  quiz.onsubmit = save;
});
<form id="quiz"> </form>

Answer №2

There seems to be an error in your save function. It appears that you are missing a quotation mark after radio:

var g1 = document.querySelector('input[type="radio"]');

Furthermore, your question is a bit unclear. However, if you are attempting to determine whether the radio button is checked or not, you should access the checked property and save it to localStorage. If you want to save the state for all buttons, consider using querySelectorAll. See example below for accessing a single input's checked value:

function save() {
  // you can directly access it on this line
  var g1 = document.querySelector('input[type="radio]').checked;
  localStorage.setItem("g1", g1);
}

Lastly, it seems like you are not calling the save() function. If your intention is to store the radios' checked state in localStorage when clicked, you might want to add an event listener to the submit button. Here's an example:

<form id="quiz"> </form>
    <script>

        let object;
        let httpRequest = new XMLHttpRequest(); 
        httpRequest.open("GET", "quiz.json", true);
        httpRequest.send();
        httpRequest.addEventListener("readystatechange", function () {
        if (this.readyState === this.DONE) {
                object = JSON.parse(this.response);
                console.log(object)
            }
            let json = object

            let quiz = document.getElementById("quiz");
            let keyList = Object.keys(json.quiz);

            for (let i = 0; i < keyList.length; i++) {
                let key = keyList[i];
                let questionItem = json.quiz[key];
                let html = "<div>";
                html += "<div><h2>Question " + (i + 1) + ": " + questionItem.question + "</h2></div>";
                html += "<div>";
                for (let i = 0; i < questionItem.options.length; i++) {
                    html += "<div >";
                    html += "<input type=\"radio\" id=\"q\" checked=\"checked\" name=\"qzz" + key + "_option\"  value=\"" + questionItem.options[i] + "\">" + questionItem.options[i] ;
                    html += "</div>";
                }

                quiz.innerHTML += html;
            }
            quiz.innerHTML += "<input type=\"submit\" value=\"submit\">";       
 
function save() {
  // you can directly access it on this line
  var g1 = document.querySelector('input[type="radio]').checked;
  localStorage.setItem("g1", g1);
}

let submitButton = document.querySelector('input[type="submit"]');
submitButton.onclick = (event) => {
  /* this prevents page refresh and submission to the backend which is a form default */
  event.preventDefault();
  // then we call the save function here
  save();
};

});

If this resolved your issue, please consider marking it as the answer.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Dynamically transcluding multiple elements in Angular

Angular 1.5 introduces the option to multi-transclude. An interesting feature would be the ability to transclude a variable number of items into a directive and specify their names and positions at a later stage (for example, in the link/compile functions ...

Preserving state during navigation and router refresh in Next.js version 13

In the component below, we have a Server Component that fetches and renders data. When router.refresh() is called on click, it reruns the page and refetches the data. However, there is an issue with Nextjs preserving the state. Even though the server compo ...

Tips for concealing the Google Chrome status bar from appearing on a webpage

I have been intrigued by the rise of Progressive Web Apps (PWAs) and I am eager to dive into understanding them better. One common feature I have noticed in PWAs is the ability to hide the browser chrome, including the URL bar, back button, search fields, ...

The images in the React slick carousel appear to be slightly out of

I'm experiencing blurriness in my carousel when it animates with card items. Despite searching for a solution, I haven't found one yet. My tech stack includes Next.js and TypeScript. const ref = useRef<any>(); const settings = { arro ...

Tips for transferring an entire array to a servlet and retrieving it efficiently

I have been attempting to collect all jqgrid data into one array and send it to a servlet. So far, I have tried the following code snippet: var rows= jQuery("#list").jqGrid('getRowData'); var paras=new Arr ...

Perform an action when a button is clicked in a VueJs single-page application

How can I trigger the refreshMailList function when clicking on the mail-list component? This is my Vue instance with a custom mail-list component: Vue.component('mail-list', { props: ['inboxmail'], template: ` <div> ...

How can I adjust the number of columns displayed per page on a Bootstrap Studio website?

Currently, I am utilizing Bootstrap studio to design a website featuring multiple cards on each page. Initially, I incorporated cards from the sb-admin-2 template and everything was proceeding smoothly. In my bootstrap studio interface, the three-column ca ...

When copying text from React-PDF Display, the values may appear altered or varied

This snippet of text was excerpted from a brief SHA provided at the git summit. Generated using React-pdf, this is a PDF document with some interesting quirks. Although the displayed text reads as 4903677, it changes to •G07THH when copied. The font ...

Exploring nested elements in MongoDB with the help of Node.js API

In my current Node.JS API, I have a function written like this: Board.find({ users : req.user._id}) This function is designed to find all documents where the user's id is inside the array named users. For example, it will successfully fin ...

Having trouble sending a post request to the /register endpoint

Recently, I've been working on setting up a user registration process using Node.js. However, I've encountered an issue where every time I send a POST request with email and password, I receive a 404 error in Postman stating "Cannot POST /signup" ...

Await that's locked within a solo asynchronous function

async function submitForm(e){ e.preventDefault() console.log(e.target) try { const response = await axios.post('/api/<PATH>', {username, password}); console.log(response.data); const token = response.data.token if (t ...

Making a POST request with C++ using the Casablanca library

I'm currently developing a customized Minecraft launcher and encountering some obstacles. My task involves sending a POST request containing JSON data to "" and then receiving and parsing the JSON response. Unfortunately, I'm facing difficulties ...

How to extract data-bound value from a <span> element using Angular

I have a table that serves as a form, with most of the cells containing input fields. <td><input id="testingInput2" type="number" placeholder="0"step="1" ng-model="addResources.one"> </td> <td><input id="testingInput2" type=" ...

Sorting customization within a complex nested array structure

Sorting a nested array can sometimes be tricky. Consider a JSON structure like the one shown below: var orders = [{ 'orderId': 1, 'sales': [{ 'salesNumbers': 3 }] }, { 'orderId': 2, ...

Dealing with issues of toggling visibility with jQuery when using a dropdown menu

Inside a hidden drop down div, the focus is on "DC" right now. In the image below, we are looking at sales: HTML: <td class="edit"> <select class="touch" style="display: none;"> <option value="11">Rebuying</option><option value ...

Animating back with a jQuery if statement

Is there a way to implement an if statement that triggers an animation when the right image reaches +400px, and then animates back to -400px upon hovering over the image? $('#left img').mouseenter(function() { $('#right img').animate ...

Nested loop combining Callback and Promise with two API requests

I apologize for the lackluster title, but I couldn't come up with anything more suitable. If this issue has already been addressed, please let me know in the comments and I will delete it promptly. However, keep in mind that this is a specific questio ...

Guide on inserting a MUI datepicker string value into the object state

Currently, I am in the process of developing a todo-list application that includes fields for description, priority, and date. To capture the priority and description inputs, I utilize TextFields which trigger the {inputChanged} function. Within this funct ...

Troubleshooting the "@material-ui/core" issue in React: Step-by-step guide

Issue with React: Unable to locate the '@material-ui/core' module in 'C:\Users\user\Downloads\inTech'22-Web Development (EDUGEN)\edu-gen\src\components' Resolution Command: To resolve, run npm in ...

A step-by-step guide to accessing Chrome performance metrics using JavaScript

By utilizing Chrome Dev Tools, I am able to perform the following actions: Begin by opening Chrome Dev Tools (simply right click on any page in Chrome and select "inspect") Navigate to the "performance" tab Click on the record button Interact with a butt ...