HappyHobbit
HappyHobbit

Reputation: 33

Javascript: Dynamically inserting svgs from an array

Building a quiz, and running into an svg snag. I have a folder full of svgs that I would like to appear in each of the multiple choice options (each svg is specific to each answer). Right now, they're looped through, but I can't get a pathway correct in order for them to appear as the ACTUAL svgs instead of just their name (Q1_A, Q1_B and so on). Thus far I've tried using template literals ( icon.innerHTML = /icons/${questions[choicesCounter].icons['choice' + number]}) as well as just using the pathway (tested with, and w/o "") in the array (choice1:/icons/Q1_A.svg). They all come back as undefined or with some other sort of error. Suggestions?

//Questions Array
let questions =[
    {
        question:"Do you mind crowds?",
        icons:{
            choice1: "Q1_A.svg",
            choice2: "Q1_B.svg",
            choice3: "Q1_C.svg",
            choice4: "Q1_D.svg",
        },
        choices:{
            choice1: "Crowds don't bother me",
            choice2:"I prefer to get off the beaten path",
            choice3:"I don't care either way",
            choice4:"Crowds mean there is something worth looking at",
        }
    },
    {
        question:"Where would you like to stay on your trip?",
        icons:{
            choice1:"Q2_A.svg",
            choice2:"Q2_B.svg",
            choice3:"Q2_C.svg",
            choice4:"Q2_D.svg",
        },
        choices:{
            choice1:"Hotel",
            choice2:"Tent",
            choice3:"RV",
            choice4:"Cabin"
        }
    },
    {
        question:"What activities do you enjoy?",
        icons:{
            choice1:"Q3_A.svg",
            choice2:"Q3_B.svg",
            choice3:"Q3_C.svg",
            choice4:"Q3_D.svg",
        },
        choices:{
            choice1: "Animal Watching",
            choice2:"Hiking",
            choice3:"Kayaking",
            choice4:"Biking"
        }
    }];
    
//Convert to an array, so you can use array functions on it
const icon= Array.from(document.getElementsByClassName('choice_icon'));
const choice= Array.from(document.getElementsByClassName('choice_text'));

let choicesCounter=0;

//Loop through the arry
iconsLoop = () => {
    icon.forEach(icon => {
        const number = icon.dataset['number'];
        icon.innerHTML =questions[choicesCounter].icons['choice' + number];
    });
};

iconsLoop();
.multiple-choice-container{
    display: flex;
    flex-wrap: wrap;
    justify-content:center;
}

.choice_container{
    height: 8rem;
    width: 7rem;
    display: flex;
    flex-direction: column;
    justify-content:center;
    align-items: center;
    font-size: 1rem;
    text-align: center;
    margin: 1rem;
    border: solid #DDDDDD .2px;
}

.choice_container:hover{  
    background:#30638E;
    color: #fdfdfd;
    border:none;
    cursor: pointer;
    transform: translateY(-0.2rem);
    transition: transform 150ms;
    box-shadow: 0px 7px 4px 0px rgba(50, 50, 50, 0.75);
}

.choice_container:hover > .choice_prefix{
    cursor: pointer;
    background: #003D5B;
}

.choice_container:hover > .choice_text{
    color: #fdfdfd;
}
.choice_icon{
    display:flex;
    justify-content: center;
    align-items: center;
    height:4rem;
    width: 3rem;
    background:#30638E;
    color:#fdfdfd;
    margin-bottom: .5rem;
}

.choice_text{
    margin-left:.5rem;
    width:100%;
    border-left: 0;
    font-size: 1rem;
}
               <div class="choice_container">
                    <p class="choice_icon" data-number = '1'>A</p>
                    <p class="choice_text" data-number = '1'> Choice 1</p>
                </div>
                <div class="choice_container ">
                    <p class="choice_icon" data-number = '2'>B</p>
                    <p class="choice_text" data-number = '2'> Choice 2</p>
                </div>
                <div class="choice_container" >
                    <p class="choice_icon" data-number = '3'>C</p>
                    <p class="choice_text" data-number = '3'> Choice 3</p>
                </div>
                <div class="choice_container" >
                    <p class="choice_icon" data-number = '4'>D</p>
                    <p class="choice_text" data-number = '4'> Choice 4</p>
                </div>
              </div>

Upvotes: 1

Views: 114

Answers (1)

Jamiec
Jamiec

Reputation: 136174

Using template literals works, but you need to embed the svg in an img tag if you're setting the innerHTML property.

A little hard to demo, but the below should illustrate the point

//Questions Array
let questions = [{
  question: "Do you mind crowds?",
  icons: {
    choice1: "Q1_A here",
    choice2: "Q1_B here",
    choice3: "Q1_C here",
    choice4: "Q1_D here",
  },
  choices: {
    choice1: "Crowds don't bother me",
    choice2: "I prefer to get off the beaten path",
    choice3: "I don't care either way",
    choice4: "Crowds mean there is something worth looking at",
  }
}]

//Convert to an array, so you can use array functions on it
const icon = Array.from(document.getElementsByClassName('choice_icon'));
const choice = Array.from(document.getElementsByClassName('choice_text'));

let choicesCounter = 0;

//Loop through the arry
iconsLoop = () => {
  icon.forEach(icon => {
    const number = icon.dataset['number'];
    icon.innerHTML = `<img src="http://placeholder.pics/svg/100x100/888888/EEE/${questions[choicesCounter].icons['choice' + number]}">`;
  });
};

iconsLoop();
.multiple-choice-container {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.choice_container {
  height: 8rem;
  width: 7rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  font-size: 1rem;
  text-align: center;
  margin: 1rem;
  border: solid #DDDDDD .2px;
}

.choice_container:hover {
  background: #30638E;
  color: #fdfdfd;
  border: none;
  cursor: pointer;
  transform: translateY(-0.2rem);
  transition: transform 150ms;
  box-shadow: 0px 7px 4px 0px rgba(50, 50, 50, 0.75);
}

.choice_container:hover>.choice_prefix {
  cursor: pointer;
  background: #003D5B;
}

.choice_container:hover>.choice_text {
  color: #fdfdfd;
}

.choice_icon {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 4rem;
  width: 3rem;
  background: #30638E;
  color: #fdfdfd;
  margin-bottom: .5rem;
}

.choice_text {
  margin-left: .5rem;
  width: 100%;
  border-left: 0;
  font-size: 1rem;
}
<div class="choice_container">
  <p class="choice_icon" data-number='1'>A</p>
  <p class="choice_text" data-number='1'> Choice 1</p>
</div>
<div class="choice_container ">
  <p class="choice_icon" data-number='2'>B</p>
  <p class="choice_text" data-number='2'> Choice 2</p>
</div>
<div class="choice_container">
  <p class="choice_icon" data-number='3'>C</p>
  <p class="choice_text" data-number='3'> Choice 3</p>
</div>
<div class="choice_container">
  <p class="choice_icon" data-number='4'>D</p>
  <p class="choice_text" data-number='4'> Choice 4</p>
</div>
</div>

Upvotes: 1

Related Questions