I need to insert an Item's HTML Media

I am trying to dynamically insert an item’s HTML media into a modal. I have figured out how to fetch the information from the api, but I can’t get it to work.

What it says on the “Edit Media” page (it works if I copy paste, but that’s not an option):

<div class="sampleMap-html"><iframe allow="geolocation" allowfullscreen="" frameborder="0" height="1000px" src="https://storymaps.arcgis.com/stories/a9afe7aa0a844f40b94d598cdc6e67ce" width="100%"></iframe></div>

What the fetch API brings up (doesn’t work):

"<p class=\"sampleMap-html\"><iframe allow=\"geolocation\" allowfullscreen=\"\" frameborder=\"0\" height=\"1000px\" src=\"https://storymaps.arcgis.com/stories/a9afe7aa0a844f40b94d598cdc6e67ce\" width=\"100%\"></iframe></p>\r\n"

After I stripslashes() (doesn’t work):

"<div class="sampleMap-html"><iframe allow="geolocation" allowfullscreen="" frameborder="0" height="1000px" src="https://storymaps.arcgis.com/stories/a9afe7aa0a844f40b94d598cdc6e67ce" width="100%"></iframe></div>rn"

I can console.log() the 2nd and 3rd, but can’t get it to add it to the DOM. I’ve tried to insert the entire chunk. I’ve tried to insert just the src. I’ve tried to edit the original HTML to change the double quotes to single quotes in case that had an effect. I’ve tried to edit the original HTML to remove the \r\n at the end in case that had an effect. I feel like I’ve tried so many methods that continue to not work.

Any suggestions?

This is my code for the whole HTML block. The “Learn Modal” doesn’t work, but that’s a different question.

<div class="preview-block clearfix">[items item_set=109 num=0 sort=foaf:lastName]</div>
<!-- The Modal Template for Learn -->

<div class="modal modal-content" id="learnModalTemplate" style="display:none;"><span class="close">&times;</span>

<div class="item-learn-content">&nbsp;</div>
</div>
<!-- The Modal Template for Map -->

<div class="modal modal-content" id="mapModalTemplate" style="display:none;"><span class="close">&times;</span>

<div class="item-map-content html-media" height="100%" id="item-html" width="100%">&nbsp;</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
    const items = document.querySelectorAll('.resource.item');
    
    items.forEach(function(item) {
        // Extract the item ID from the title link
        const idMatch = item.querySelector('h4 a').getAttribute('href').match(/\/item\/(\d+)/);
        const itemID = idMatch ? idMatch[1] : null;
		var itemData;
		var values;

        // Create clones of the modal templates
        const learnModalClone = document.getElementById('learnModalTemplate').cloneNode(true);
        learnModalClone.id = 'learnModal' + itemID;
        const mapModalClone = document.getElementById('mapModalTemplate').cloneNode(true);
        mapModalClone.id = 'mapModal' + itemID;
        
        // Insert the cloned modals into the DOM
        item.appendChild(learnModalClone);
        item.appendChild(mapModalClone);

        // Button Learn
        const buttonLearn = document.createElement('a');
        buttonLearn.innerHTML = '<img src="https://www.andrewwyattmaginn.org/Digital_Humanities/files/asset/889b2c4047cc3e527d23e28ea0c5c1ce5e5cf040.png" alt="Learn Modal">';
        buttonLearn.addEventListener('click', function() {
            learnModalClone.style.display = 'block';
			fetchItem(itemID);
		 });
		
        // Button Map
        const buttonMap = document.createElement('a');
        buttonMap.innerHTML = '<img src="https://www.andrewwyattmaginn.org/Digital_Humanities/files/asset/1d1a43687f7f93dc180a5c90eb396967a0938cc3.png" alt="Map Modal">';
        buttonMap.addEventListener('click', function() {
            mapModalClone.style.display = 'block';
            // Request the HTML source URL for the item
			fetchMedia(itemID);
				
        });
	

        // Append buttons to the item
        item.appendChild(buttonLearn);
        item.appendChild(buttonMap);

        // Add close event handlers
        learnModalClone.querySelector('.close').addEventListener('click', function() {
            learnModalClone.style.display = 'none';
        });

        mapModalClone.querySelector('.close').addEventListener('click', function() {
            mapModalClone.style.display = 'none';
        });
    });


function fetchResTemp() {
  //for "People-Mapping Migration";
  const apiResTemp = '/Digital_Humanities/api/items/resource-templates/4'; 
    fetch (apiResTemp)
      .then (response => {
        return response.json();
      })
      .then (dataTemp => {
        dataTemp['o:resource_template_property'].forEach(resProperty => {
          const markup = '<div class="property"><dl><dt>${resProperty["o:alternate_label"]}</dt></dl></div>';
          document.querySelector('.item-learn-content').insertAdjacentHTML('beforeend', markup);
        });
      })
	  .catch(error => {
		console.error('There has been a problem with your fetch operation:', error);
	  });
}


function fetchItem(itemID) {
  // Construct the API endpoint URL using the provided item ID
  const apiItem = '/Digital_Humanities/api/items/' + itemID;
//  const apiItem = '/Digital_Humanities/api/items/100';
    // Use Fetch API to retrieve the item details
    fetch(apiItem)
      .then (response => {
        return response.json();
      })
      .then (dataItem => {
        var all = [];
        for (var property in dataItem) {
          all.push(property + ': ' + dataItem[property]);
        }
        document.querySelector('.item-learn-content').innerText = dataItem;
        console.log(dataItem);
      })
	  .catch(error => {
		console.error('There has been a problem with your fetch operation:', error);
	  });

}

function stripslashes(str) {
  return str.replace(/\\(.?)/g, (s, n1) => {
    switch (n1) {
      case '\\':
        return '\\';
      case '0':
        return '\u0000';
      case '':
        return ''; // This is for the edge case where a '\' is at the end of the string
      default:
        return n1;
    }
  });
}

function fetchMedia(itemID) {
const apiMedia = '/Digital_Humanities/api/media' + '?' + 'item_id=' + itemID;
fetch(apiMedia)
  .then(response => {
    return response.json();
    console.log(response.json());
  })
  .then(mediaItems => {
    const htmlItem = mediaItems.find(m => m['o:ingester'] === 'html');
    if (htmlItem) {
      const mediaHTML = stripslashes(JSON.stringify(htmlItem['data']['html']));
      console.log(mediaHTML);                      
 
	  addMedia = () => {
        const itemHTML = document.getElementById('item-html');
		itemHTML.appendChild(mediaHTML);
	  }
	}
  })
}

})
</script>

The extra slashes you’re seeing: I’m pretty sure those are there just because you’re calling JSON.stringify on the html value. If you just take the [data][html] value it should be fine as-is already.

As for using it, you can’t just take HTML as text and insert it with appendChild, you’d want to use innerHTML or other similar functionality.

Thank you. Takinging out the stringify and the stripslashes made a big difference (I can tell from the console.log(mediaHTML);.

I did put the console.log(mediaHTML); in the wrong place–it was supposed to be within the if (html)... statement, not after it.

I tried so many methods:

itemHTML.appendChild(mediaHTML);
itemHTML.insertAdjacentElement("afterbegin", mediaHTML);
itemHTML.insertAdjacentText("beforeend", mediaHTML);
itemHTML.insertAdjacentHTML("beforeend", mediaHTML);
itemHTML.innerText = mediaHTML;
itemHTML.innerHTML = mediaHTML;
itemHTML.outerText = mediaHTML;
itemHTML.outerHTML = mediaHTML;

I did just find that the outerHTML does work if I hit the button twice. I tried going back and checking some of the others, but they didn’t. Any idea why this ONE method works, and only after the second click?