Engage Your Audience with Interactive Polls and Quizzes - A Step-by-Step Guide
John Selvinraj
Posted on October 16, 2023
One of the most requested features from our customers was the ability to create polls and quizzes. We are excited to announce that this feature is now available!
Polls are a great way to get feedback from your audience, learn more about their interests, and engage them in a two-way conversation. Want to get feedback on the session? Create a poll. Let your audience rate the session as good or bad.
The questions can be made single-choice or multiple-choice. The feedback example discussed above would be a single-choice question. Whereas if you want to conduct market research on say what social media platform everyone in the room uses. That would require a multiple-choice question.
Needless to say, polls can enhance audience engagement and add interactivity to virtual meetings, conferences, or live streams. They also enable you to collect well-organized data by posing direct questions.
Create polls in 100ms rooms in the following way:
Once a poll is created and launched by a peer, other peers with permission to view the polls can interact with it.
Moreover, the Polls can be extended to create quizzes as well.
To delve a bit deeper, quizzes operate on a similar principle to polls, albeit with a twist.
In the world of quizzes, questions come with designated correct and incorrect answers, adding an element of assessment and knowledge evaluation to the interactive experience. It can be used to craft educational assessments, test comprehension, and promote active learning through engagement.
Let’s get into the mix of building things using 100ms Polls and Quizzes.
How to enable polls and quizzes for your rooms on the 100ms dashboard?
- Access the 100ms Dashboard: Begin by visiting the 100ms dashboard.
- Choose or Create a Template: Select the template where you want to enable polls and quizzes. Alternatively, create a new template by clicking the 'Create Template' button.
- Access Template Configuration: Click on the 'Configure' button within your chosen template.
- Assign Poll Creation Privileges: Select which role(s) should have the ability to create polls.
- Set Permissions: In the 'Permissions' section, activate the following toggles: ◦ 'Create polls and quizzes' ◦ 'Read polls and quizzes'
- Exclusive Interaction: If certain role(s) should only participate in polls without creating them, enable only the 'Read polls and quizzes' toggle for those roles.
How to add Polls to React sample app?
Let’s add polls to a React sample app to see how easy it is.
Start by creating a new React project (I’ll use Vite to create one) by running the following command:
npm create vite@latest my-polls-app -- --template react
This would create a new project folder my-polls-app
in your desired directory with React configured in it.
Now, to quickly add the 100ms React SDK and enable live audio-video in our app, we will follow the React Quickstart Guide here.
Once done, we should have a React project with audio-video calling using 100ms set up.
The complete React Quickstart Guide code can be found here.
Create a new folder in the src
directory called Components
and add two subfolders Poll
and UI
to it. These folders would have the code for the necessary UI and Poll components.
We start by creating a Modal.jsx
file inside the UI
folder. This file would have the following code:
import { Fragment } from "react";
import ReactDOM from "react-dom";
import classes from "./Modal.module.css";
const Backdrop = (props) => {
return <div className={classes.backdrop} onClick={props.onClose}></div>;
};
const ModalOverlay = (props) => {
return (
<div className={classes.modal}>
<div className={classes.content}>{props.children}</div>
</div>
);
};
const portalElement = document.getElementById("overlays");
const Modal = (props) => {
return (
<Fragment>
{ReactDOM.createPortal(
<Backdrop onClose={props.onClose} />,
portalElement
)}
{ReactDOM.createPortal(
<ModalOverlay>{props.children}</ModalOverlay>,
portalElement
)}
</Fragment>
);
};
export default Modal;
The Modal component is made up of the Backdrop
and ModalOverlay
. The ModalOverlay
would provide a white background to lay the children on passed to it using props.
You’d notice we have imported a css file but haven’t defined it yet. So, inside the same UI
folder create a new file called Modal.module.css
and add the following to it:
.backdrop {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
z-index: 20;
background-color: rgba(0, 0, 0, 0.75);
}
.modal {
position: fixed;
top: 20vh;
left: 5%;
width: 90%;
background-color: #546e7a;
padding: 1rem;
border-radius: 14px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
z-index: 30;
animation: slide-down 300ms ease-out forwards;
}
@media (min-width: 768px) {
.modal {
width: 40rem;
left: calc(50% - 20rem);
}
}
@keyframes slide-down {
from {
opacity: 0;
transform: translateY(-3rem);
}
to {
opacity: 1;
transform: translateY(0);
}
}
Lastly, to complete our Modal, we also need to modify the index.html
in the root of the project directory to add another div
with id="overlays"
before the root div
as below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>100ms Polls Demo</title>
</head>
<body>
<div id="overlays"></div>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
Now, we will work on a form to create a poll. Start by creating a form as follows:
import Modal from ".././UI/Modal";
import { Button } from "@100mslive/roomkit-react";
import { useState } from "react";
import { useHMSActions } from "@100mslive/react-sdk";
import "../../styles.css";
const PollForm = (props) => {
const hmsActions = useHMSActions();
const [inputs, setInputs] = useState({});
return (
<Modal onClose={props.onClose}>
<form onSubmit={handleSubmit}>
<label>
Enter a Name for the Poll:
<div className="input-container">
<input
type="text"
name="name"
value={inputs.name || ""}
onChange={handleChange}
/>
</div>
</label>
<label>
Enter a question for the Poll:
<div className="input-container">
<input
type="text"
name="text"
value={inputs.text || ""}
onChange={handleChange}
/>
</div>
</label>
<label>
Enter the First Value:
<div className="input-container">
<input
type="text"
name="first"
value={inputs.first || ""}
onChange={handleChange}
/>
</div>
</label>
<label>
Enter the Second Value:
<div className="input-container">
<input
type="text"
name="second"
value={inputs.second || ""}
onChange={handleChange}
/>
</div>
</label>
<input type="submit" />
</form>
</Modal>
);
};
export default PollForm;
You’ll notice we are having the user input a name for the poll, a question and two options to choose from. To manage changes in values and successfully submit the form, we add the following functions.
const handleChange = (event) => {
const name = event.target.name;
const value = event.target.value;
setInputs((values) => ({ ...values, [name]: value }));
};
const handleSubmit = async (event) => {
event.preventDefault();
const id = Date.now().toString();
await hmsActions.interactivityCenter
.createPoll({
id,
title: inputs.name,
type: "poll",
rolesThatCanViewResponses: ["host"],
})
.then(() => handleCreate(id))
.catch((err) => console.log(err.message));
};
const handleCreate = async (id) => {
console.log("POLL CREATED with ${id}");
await hmsActions.interactivityCenter.addQuestionsToPoll(id, [
{
text: inputs.text,
type: "single-choice",
options: [
{
text: inputs.first,
isCorrectAnswer: false,
},
{
text: inputs.second,
isCorrectAnswer: false,
},
],
skippable: true,
},
]);
await hmsActions.interactivityCenter.startPoll(id);
};
The handleChange
takes any changes in the text input fields and sets the inputs
variable accordingly. On form submission, the handleSubmit
is called which uses the useHMSActions
hook to create a new poll.
Once a poll is created, handleCreate
is run to addQuestionsToPoll
and also startPoll
using the same hmsActions
.
The complete PollForm.jsx
file would then look as this.
Next, we return to our App.jsx
file to display the PollForm
when the user clicks on a Create Poll
button.
Start by importing the following:
import { useState } from "react";
import { Button } from "@100mslive/roomkit-react";
We will use useState
to manage the state of the PollForm
if we need to show or hide it.
const [pollFormIsShown, setPollFormIsShownn] = useState(false);
const showPollFormHandler = () => {
setPollFormIsShownn(true);
};
const hidePollFormHandler = () => {
setPollFormIsShownn(false);
};
Add the PollForm
component and a button with showPollFormHandler
being passed to it as below:
{pollFormIsShown && <PollForm onClose={hidePollFormHandler} />}
<Button onClick={showPollFormHandler}>Create Poll</Button>
Once this is done, we should be able to toggle and view the PollForm
and dismiss it by clicking the backdrop area. We should also be able to create and start a poll with the name, question and choices entered by the user.
Let us now work to show the Poll to any other users using our app.
We can use the useHMSNotifications
hook to be notified when a new poll is started. We will use this to show a toast using react-toastify
when a new poll has begun.
Add the package by running: npm install --save react-toastify
Add the following imports to the App.jsx
file.
import {
selectIsConnectedToRoom,
selectLocalPeerID,
useHMSActions,
HMSNotificationTypes,
useHMSStore,
useHMSNotifications,
} from "@100mslive/react-sdk";
import { ToastContainer, toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import { useEffect, useState } from "react";
Initialise notifications and localPeerID to use them as follows:
const notification = useHMSNotifications();
const localPeerID = useHMSStore(selectLocalPeerID);
Using useEffect
we check for any new notifications. Add the following code to App.jsx
const [pollNotificationData, setPollNotificationData] = useState();
useEffect(() => {
if (!notification) {
return;
}
switch (notification.type) {
case HMSNotificationTypes.POLL_STARTED:
if (notification.data.startedBy !== localPeerID) {
console.log("NOTIFICATION RECEIVED");
console.log(notification.data);
setPollNotificationData(notification.data);
toast(`A new Poll is available: ${notification.data.title}!`);
}
break;
default:
break;
}
}, [notification]);
Lastly, add <ToastContainer />
to the return of App.jsx
to view a toast when some other remote user creates a new poll. Notice how we have added a check to not show toast to the local peer itself.
Now, we want to be able to cast our vote on the created poll. To do that we again start by showing a modal with the poll data for the users to vote. To the App.jsx
add the following:
const [pollModalIsShown, setPollModalIsShown] = useState(false);
const showPollModalHandler = () => {
setPollModalIsShown(true);
};
In the return, add a ViewPoll
component as follows:
{pollModalIsShown && (
<ViewPoll pollNotificationData={pollNotificationData} />
)}
Let us now work on this component. Create a new file called ViewPoll.jsx
inside the Poll
folder in the Components
directory. First, create a basic form layout with radio buttons using the same Modal
component we had created earlier.
import Modal from "../UI/Modal";
import { useState } from "react";
import { Button } from "@100mslive/roomkit-react";
import { useHMSActions } from "@100mslive/react-sdk";
import { toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
const ViewPoll = (props) => {
return (
<Modal onClose={props.onClose}>
<h1>Poll: {props.pollNotificationData.title}</h1>
<h3>{props.pollNotificationData.questions[0].text}</h3>
<form onSubmit={handleSubmit}>
<div className="radio">
<label>
<input
type="radio"
value={props.pollNotificationData.questions[0].options[0].index}
checked={Number(selectedOptionIndex) === 1}
onChange={handleChange}
/>
{props.pollNotificationData.questions[0].options[0].text}
</label>
</div>
<div className="radio">
<label>
<input
type="radio"
value={props.pollNotificationData.questions[0].options[1].index}
checked={Number(selectedOptionIndex) === 2}
onChange={handleChange}
/>
{props.pollNotificationData.questions[0].options[1].text}
</label>
</div>
<br />
<Button type="submit">Submit</Button>
</form>
</Modal>
);
};
export default ViewPoll;
And, lastly, add functions to handle changes made in the form and submission as follows:
const actions = useHMSActions();
const [selectedOptionIndex, setSelectedOptionIndex] = useState();
function handleChange(event) {
setSelectedOptionIndex(event.target.value);
}
const handleSubmit = async (event) => {
event.preventDefault();
await actions.interactivityCenter.addResponsesToPoll(
props.pollNotificationData.id,
[
{
questionIndex: props.pollNotificationData.questions[0].index,
option: Number(selectedOptionIndex),
},
]
);
toast(`Vote done!`);
};
Notice how we are using the useHMSActions
hook to addResponsesToPoll
by passing the poll id obtained from the data passed in as props.
With this done, our application should now be ready to test!
The code for this project is available on GitHub here.
The React app that we’ve built here allows you to create the poll, add single-choice questions as well, and start it for remote users. Using the 100ms SDK, we can also create multiple-choice polls and quizzes as mentioned in the article before.
With the ability to curate customized polls, incorporate thought-provoking questions, and initiate real-time participation from remote users through the React app, a world of engaging possibilities opens up. The dynamic fusion of technology and user interaction empowers developers to not only enhance the virtual experience but also extract valuable data and insights.
Ready to dive in? To grasp the full extent of what's achievable and delve into practical steps, look at our comprehensive documentation.
- Get started on the web here.
- Add Polls to your Android or iOS app.
- Join our discord server in case of any doubts and to help us build it further.
Posted on October 16, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 29, 2024