Dave
Dave

Reputation: 23

Insert dynamic data into bootstrap modal from array object - vanilla javascript

Hi I am trying to dynamically enter data into my modal but am having trouble getting the correct data.
i will briefly explain my project -
I have 2 dropdown menus.
Those menus are populated by options dynamically entered from 2 arrays.
when you select one or both options from the select menus a new array is made.
The new array is then filtered and returns only matching results as buttons.
The Buttons open a modal where i would like a gif displayed.
Now here is where i am stuck, I am getting data to appear in the modal but it is not the data specific to its button, instead it displays the 1st gif from the new array.
array object looks like this
{bodyPart: 'neck', equipment: 'body weight', gifUrl: 'http://d205bpvrqc9yn1.cloudfront.net/1403.gif', id: '1403', name: 'neck side stretch', …}


working code snippet
https://jsfiddle.net/q08dw5mn/
html
<div class="row-md-6 offset-md-2">
  <div class="col-sm-10" style="border:1px solid blue">
    Logo goes here 

    <div class="row">
      <div class="col-8 col-sm-6" style="border:1px solid red">
        <div id="exercises" class="bg-primary align-items-center dropdown"></div> <!--------Dropdown Buttons-->
      </div>
      <div class="col-4 col-sm-6 resultdiv" style="border:1px solid red">
        <div id="data"></div> <!--Result Data-->
      </div>
    </div>
  </div>
</div>

<!--! Modal -->
<div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalLongTitle">Modal title</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div id="modalImg" class="modalBody">
        <!-- MODAL IMAGE GOES HERE -->
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
      </div>
    </div>
  </div>
</div>


javascript

const dataDiv = document.getElementById("data")
const apiURL = 'https://exercisedb.p.rapidapi.com/exercises/bodyPart/%7Bchest%7D'

let mainList = []
let bodypartsList = []
let equipmentList = []


async function getApiURL(endpoint, value) {
    const response = await fetch(`https://exercisedb.p.rapidapi.com/exercises/${endpoint}/${value}`, {
        "method": "GET",
        "headers": {
            "x-rapidapi-host": "exercisedb.p.rapidapi.com",
            "x-rapidapi-key": "360a6abca3mshcfce9cbd521f228p1e181djsn14d1d0e4c955"
        }
    })
    const data = await response.json();
    if (endpoint == "bodypart") {
        bodypartsList = data
    } else {
        equipmentList = data
    }
    mergeLists()
}

function mergeLists() {
    mainList = bodypartsList.concat(equipmentList);
    displayData(mainList)
}


//bodypart code
const bodyparts = ["Body Parts", "back", "cardio", "chest", "lower arms", "lower legs", "neck", "shoulders", "upper arms", "upper legs", "waist"]
const equipment = ["Equipment", "assisted", "band", "barbell", "body weight", "cable", "dumbbell", "kettlebell", "leverage machine", "medicine ball", "resistance band", "roller", "rope", "smith machine", "trap bar", "weighted"]


const exercises = document.getElementById("exercises");


window.addEventListener("load", function () {
    createDropdown("bodypart", bodyparts);
})
window.addEventListener("load", function () {
    createDropdown("equipment", equipment);
})


function createDropdown(name, items) {
    const select = document.createElement("select"); //---create the select element
    select.className = "selectMenu"
    select.name = name
    select.id = name
    for (let i = 0; i < items.length; i++) { //---as long as 'i' is less than the number of items increase by 1
        const item = items[i]; //---declaring 'i' as items
        const option = document.createElement("option"); //---create options for select
        option.setAttribute("value", item); //---places item value into options
        option.innerHTML = item; //---change content of options to items
        select.appendChild(option); //---append options to select

    }
    exercises.appendChild(select); //---append select to exercises div


    select.addEventListener("change", function () {
        const item = select.value;
        dataDiv.innerHTML = ''; //<------Clears previous results from page
        getApiURL(name, item);
    })
}


function displayData(data) {
    let d1 = document.getElementById("equipment")
    let d2 = document.getElementById("bodypart")
    let result = data;
    if (d1.selectedIndex > 0) {
    const selected = d1.value;
    result = result.filter(({equipment}) => equipment.includes(selected));
    }

    if (d2.selectedIndex > 0) {
    const selected = d2.value;
    result = result.filter(({bodyPart}) => bodyPart.includes(selected));
    }

    //Filter based on value
    // const result = data.filter(word => {
    //     let check = word.name.indexOf(d1.value)
    //     let check2 = word.name.indexOf(d2.value)
    //     if (check !== -1 || check2 !== -1) {
    //         return word
    //     } else {
    //         return 
            
    //     }
    // });
    const unique = [];
    const uniqueImg = [];

    //Filter our duplicates
    result.map(x => unique.filter(a => a.id == x.id).length > 0 ? null : unique.push(x));
    console.log(unique);

    result.map(x => uniqueImg.filter(a => a.id == x.id).length > 0 ? null : uniqueImg.push(x));
    console.log(uniqueImg);

    unique.forEach(element => {
        const div = document.createElement("div");
        const button = document.createElement("button");
        button.ID = "myBtn"
        // const img = document.createElement("img");
        
        // img.className = "appGifs"
        button.innerHTML = element.name
        // img.src = element.gifUrl
        div.appendChild(button)
        // modalImg.appendChild(img)
        div.className = "card"
        dataDiv.appendChild(div)

        button.className = "dButtons";
        button.setAttribute('data-toggle', 'modal');
        button.setAttribute('data-target', '#exampleModalCenter');
        button.setAttribute('type', 'button');
    });
    
    uniqueImg.forEach(element => {
        const modalImg = document.getElementById("modalImg")
        const img = document.createElement("img");
        img.className = "appGifs"
        img.src = element.gifUrl
        modalImg.innerHTML = (img.gifURL)
        modalImg.appendChild(img)
    });
}

This is the last piece of the puzzle for me and have been stuck here for a couple of days, would love it if somebody could help me passed this
Thanks

Upvotes: 0

Views: 1432

Answers (1)

Abdur-Rehman M
Abdur-Rehman M

Reputation: 321

You were not passing the data of the object to the modal. i have made changes to your code and now i pass data when button is clicked.

const dataDiv = document.getElementById("data")
const apiURL = 'https://exercisedb.p.rapidapi.com/exercises/bodyPart/%7Bchest%7D'

let mainList = []
let bodypartsList = []
let equipmentList = []


async function getApiURL(endpoint, value) {
    const response = await fetch(`https://exercisedb.p.rapidapi.com/exercises/${endpoint}/${value}`, {
        "method": "GET",
        "headers": {
            "x-rapidapi-host": "exercisedb.p.rapidapi.com",
            "x-rapidapi-key": "360a6abca3mshcfce9cbd521f228p1e181djsn14d1d0e4c955"
        }
    })
    const data = await response.json();
    if (endpoint == "bodypart") {
        bodypartsList = data
    } else {
        equipmentList = data
    }
    mergeLists()
}

function mergeLists() {
    mainList = bodypartsList.concat(equipmentList);
    displayData(mainList)
}


//bodypart code
const bodyparts = ["Body Parts", "back", "cardio", "chest", "lower arms", "lower legs", "neck", "shoulders", "upper arms", "upper legs", "waist"]
const equipment = ["Equipment", "assisted", "band", "barbell", "body weight", "cable", "dumbbell", "kettlebell", "leverage machine", "medicine ball", "resistance band", "roller", "rope", "smith machine", "trap bar", "weighted"]


const exercises = document.getElementById("exercises");


window.addEventListener("load", function () {
    createDropdown("bodypart", bodyparts);
})
window.addEventListener("load", function () {
    createDropdown("equipment", equipment);
})


function createDropdown(name, items) {
    const select = document.createElement("select"); //---create the select element
    select.className = "selectMenu"
    select.name = name
    select.id = name
    for (let i = 0; i < items.length; i++) { //---as long as 'i' is less than the number of items increase by 1
        const item = items[i]; //---declaring 'i' as items
        const option = document.createElement("option"); //---create options for select
        option.setAttribute("value", item); //---places item value into options
        option.innerHTML = item; //---change content of options to items
        select.appendChild(option); //---append options to select

    }
    exercises.appendChild(select); //---append select to exercises div


    select.addEventListener("change", function () {
        const item = select.value;
        dataDiv.innerHTML = ''; //<------Clears previous results from page
        getApiURL(name, item);
    })
}


function displayData(data) {
    let d1 = document.getElementById("equipment")
    let d2 = document.getElementById("bodypart")
    let result = data;
    if (d1.selectedIndex > 0) {
    const selected = d1.value;
    result = result.filter(({equipment}) => equipment.includes(selected));
    }

    if (d2.selectedIndex > 0) {
    const selected = d2.value;
    result = result.filter(({bodyPart}) => bodyPart.includes(selected));
    }

    const unique = [];

    //Filter our duplicates
    result.map(x => unique.filter(a => a.id == x.id).length > 0 ? null : unique.push(x));
    console.log(unique);

    unique.forEach(element => {
        const div = document.createElement("div");
        const button = document.createElement("button");
        button.ID = "myBtn"
        // const img = document.createElement("img");
        
        // img.className = "appGifs"
        button.innerHTML = element.name
        // img.src = element.gifUrl
        div.appendChild(button)
        // modalImg.appendChild(img)
        div.className = "card"
        dataDiv.appendChild(div)

        button.className = "dButtons";

        button.setAttribute('type', 'button');
        button.onclick = (ev)=> 
        {
           const modalImg = document.getElementById("modalImg")
           const img = document.createElement("img");
           img.className = "appGifs"
           img.src = element.gifUrl
           
           modalImg.innerHTML = ''; // reset
           modalImg.appendChild(img);

           $('#exampleModalLongTitle').text(element.name);
           $('#exampleModalCenter').modal('show');
        }
    });
   
}

Upvotes: 1

Related Questions