Prompt Title: H5P Add Numbering.

Created 1 year ago
Votes 0
Views 118 times
0
Human: I have an h5p content on my wordpress page. It's only 4 questions and I would like to add a numbering before each one of them. Here's the code. Let me know if we could add a .js file to do this. <script>H5PIntegration = {"baseUrl":"https:\/\/french-lessons.net","url":"\/wp-content\/uploads\/h5p","postUserStatistics":true,"ajax":{"setFinished":"https:\/\/french-lessons.net\/connexion-administrateur\/admin-ajax.php?token=a1b95520ec&action=h5p_setFinished","contentUserData":"https:\/\/french-lessons.net\/connexion-administrateur\/admin-ajax.php?token=709177e701&action=h5p_contents_user_data&content_id=:contentId&data_type=:dataType&sub_content_id=:subContentId"},"saveFreq":false,"siteUrl":"https:\/\/french-lessons.net","l10n":{"H5P":{"fullscreen":"Plein \u00e9cran","disableFullscreen":"Disable fullscreen","download":"Download","copyrights":"Rights of use","embed":"Embed","size":"Size","showAdvanced":"Show advanced","hideAdvanced":"Hide advanced","advancedHelp":"Include this script on your website if you want dynamic sizing of the embedded content:","copyrightInformation":"Rights of use","close":"Close","title":"Titre","author":"Auteur","year":"Year","source":"Source","license":"License","thumbnail":"Thumbnail","noCopyrights":"No copyright information available for this content.","reuse":"Reuse","reuseContent":"Reuse Content","reuseDescription":"Reuse this content.","downloadDescription":"Download this content as a H5P file.","copyrightsDescription":"View copyright information for this content.","embedDescription":"View the embed code for this content.","h5pDescription":"Visit H5P.org to check out more cool content.","contentChanged":"This content has changed since you last used it.","startingOver":"You'll be starting over.","by":"by","showMore":"Show more","showLess":"Show less","subLevel":"Sublevel","confirmDialogHeader":"Confirm action","confirmDialogBody":"Please confirm that you wish to proceed. This action is not reversible.","cancelLabel":"Cancel","confirmLabel":"Confirm","licenseU":"Undisclosed","licenseCCBY":"Attribution","licenseCCBYSA":"Attribution-ShareAlike","licenseCCBYND":"Attribution-NoDerivs","licenseCCBYNC":"Attribution-NonCommercial","licenseCCBYNCSA":"Attribution-NonCommercial-ShareAlike","licenseCCBYNCND":"Attribution-NonCommercial-NoDerivs","licenseCC40":"4.0 International","licenseCC30":"3.0 Unported","licenseCC25":"2.5 Generic","licenseCC20":"2.0 Generic","licenseCC10":"1.0 Generic","licenseGPL":"General Public License","licenseV3":"Version 3","licenseV2":"Version 2","licenseV1":"Version 1","licensePD":"Public Domain","licenseCC010":"CC0 1.0 Universal (CC0 1.0) Public Domain Dedication","licensePDM":"Public Domain Mark","licenseC":"Copyright","contentType":"Content Type","licenseExtras":"License Extras","changes":"Changelog","contentCopied":"Content is copied to the clipboard","connectionLost":"Connection lost. Results will be stored and sent when you regain connection.","connectionReestablished":"Connection reestablished.","resubmitScores":"Attempting to submit stored results.","offlineDialogHeader":"Your connection to the server was lost","offlineDialogBody":"We were unable to send information about your completion of this task. Please check your internet connection.","offlineDialogRetryMessage":"Retrying in :num....","offlineDialogRetryButtonLabel":"Retry now","offlineSuccessfulSubmit":"Successfully submitted results."}},"hubIsEnabled":true,"reportingIsEnabled":true,"libraryConfig":null,"crossorigin":null,"crossoriginCacheBuster":null,"pluginCacheBuster":"?v=1.15.6","libraryUrl":"https:\/\/french-lessons.net\/wp-content\/plugins\/h5p\/h5p-php-library\/js","user":{"name":"Cl\u00e9ment","mail":"[email protected]"},"core":{"styles":["\/wp-content\/plugins\/h5p\/h5p-php-library\/styles\/h5p.css?ver=1.15.6","\/wp-content\/plugins\/h5p\/h5p-php-library\/styles\/h5p-confirmation-dialog.css?ver=1.15.6","\/wp-content\/plugins\/h5p\/h5p-php-library\/styles\/h5p-core-button.css?ver=1.15.6"],"scripts":["\/wp-content\/plugins\/h5p\/h5p-php-library\/js\/jquery.js?ver=1.15.6","\/wp-content\/plugins\/h5p\/h5p-php-library\/js\/h5p.js?ver=1.15.6","\/wp-content\/plugins\/h5p\/h5p-php-library\/js\/h5p-event-dispatcher.js?ver=1.15.6","\/wp-content\/plugins\/h5p\/h5p-php-library\/js\/h5p-x-api-event.js?ver=1.15.6","\/wp-content\/plugins\/h5p\/h5p-php-library\/js\/h5p-x-api.js?ver=1.15.6","\/wp-content\/plugins\/h5p\/h5p-php-library\/js\/h5p-content-type.js?ver=1.15.6","\/wp-content\/plugins\/h5p\/h5p-php-library\/js\/h5p-confirmation-dialog.js?ver=1.15.6","\/wp-content\/plugins\/h5p\/h5p-php-library\/js\/h5p-action-bar.js?ver=1.15.6","\/wp-content\/plugins\/h5p\/h5p-php-library\/js\/request-queue.js?ver=1.15.6"]},"loadedJs":[],"loadedCss":[],"contents":{"cid-3":{"library":"H5P.AdvancedBlanks 1.2","jsonContent":"{\"content\":{\"task\":\"<p>Put the verbs into the correct tense. You'll get individual feedback for typical mistakes.<\\\/p>\\n\",\"blanksList\":[{\"correctAnswerText\":\"doesn't speak\\\/does not speak\",\"incorrectAnswersList\":[{\"showHighlight\":true,\"highlight\":\"-1\",\"incorrectAnswerText\":\"speaks not\\\/speak not\",\"incorrectAnswerFeedback\":\"<div>Remember to use 'do\\\/does' when negating a full verb <em>(speak)<\\\/em>.<\\\/div>\\n\"},{\"showHighlight\":true,\"highlight\":\"-2\",\"incorrectAnswerText\":\"don't speak\\\/do not speak\",\"incorrectAnswerFeedback\":\"<div>You forgot the 'third person singular -s' for simple present <em>(he)<\\\/em>.<\\\/div>\\n\"}]},{\"correctAnswerText\":\"'ve been learning\\\/have been learning\",\"incorrectAnswersList\":[{\"showHighlight\":true,\"highlight\":\"1\",\"incorrectAnswerText\":\"'m learning\\\/am learning\",\"incorrectAnswerFeedback\":\"<div><strong>Present progressive<\\\/strong> <em>(am learning)<\\\/em> is used for something that is going on right now. @present_perf_prog<\\\/div>\\n\"},{\"showHighlight\":true,\"highlight\":\"1\",\"incorrectAnswerText\":\"learned\\\/learnt\",\"incorrectAnswerFeedback\":\"<div><strong>Simple past<\\\/strong> <em>(learned\\\/learnt)<\\\/em> is used if something is over and you just report it. @present_perf_prog<\\\/div>\\n\"},{\"showHighlight\":true,\"highlight\":\"1\",\"incorrectAnswerText\":\"'ve\\\/learned\\\/'ve learnt\\\/have learned\\\/have learnt\",\"incorrectAnswerFeedback\":\"<div>You're nearly there. It's great that you've used <strong>present perfect<\\\/strong> because the action (learning) connects past and present. But it's still going on and you talk about how long it has been going on: use <strong>present perfect progressive<\\\/strong> in such a case. <em>(have\\\/has been + ...ing)<\\\/em><\\\/div>\\n\"}]},{\"correctAnswerText\":\"haven't been\\\/have not been\",\"incorrectAnswersList\":[{\"showHighlight\":true,\"highlight\":\"-1\",\"incorrectAnswerText\":\"hasn't been\\\/has not been\",\"incorrectAnswerFeedback\":\"<div>Remember to use <em>'have'<\\\/em> for <em>I, you, we and they.<\\\/em><\\\/div>\\n\"},{\"showHighlight\":true,\"highlight\":\"1\",\"incorrectAnswerText\":\"wasn't\\\/was not\\\/weren't\\\/were not\",\"incorrectAnswerFeedback\":\"<div>If you want to say that you've (never) done something at some point in your life, you need <strong>present perfect<\\\/strong>. <em>(have\\\/has + past participle) <\\\/em>You've used <strong>simple past<\\\/strong>, which is for reporting about a specific event, typically including an exact time or date.<\\\/div>\\n\"}]},{\"correctAnswerText\":\"'s painting\\\/is painting\",\"incorrectAnswersList\":[{\"showHighlight\":true,\"highlight\":\"1\",\"incorrectAnswerText\":\"paints\\\/paint\",\"incorrectAnswerFeedback\":\"<div>It's right now, so you must use <strong>present progressive<\\\/strong> <em>(am\\\/is\\\/are + ...ing)<\\\/em>.<\\\/div>\\n\"}]}],\"blanksText\":\"<p>!!He!! speaks English but he (not \\\/ !!speak!!) ___________<strong> <\\\/strong>German.<\\\/p>\\n\\n<p>I (learn) ___________ English !!for three years now!!.<\\\/p>\\n\\n<p>!!I!! (not \\\/ be) ___________ to Sweden !!so far!!.<\\\/p>\\n\\n<p>She (paint) ___________ the walls of her house !!now!!.<\\\/p>\\n\"},\"overallFeedback\":[{\"from\":0,\"to\":50,\"feedback\":\"Try again!\"},{\"from\":51,\"to\":75,\"feedback\":\"You've done ok!\"},{\"from\":76,\"to\":100,\"feedback\":\"Good job!\"}],\"behaviour\":{\"mode\":\"selection\",\"selectAlternatives\":\"alternatives\",\"selectAlternativeRestriction\":6,\"spellingErrorBehaviour\":\"warn\",\"caseSensitive\":false,\"autoCheck\":true,\"enableSolutionsButton\":true,\"showSolutionsRequiresInput\":true,\"enableRetry\":true,\"enableCheckButton\":true,\"confirmCheckDialog\":false,\"confirmRetryDialog\":false},\"showSolutions\":\"Voir la correction\",\"tryAgain\":\"Recommencer\",\"checkAnswer\":\"V\\u00e9rifier\",\"notFilledOut\":\"Vous devez avoir rempli tous les blancs avant de voir la correction\",\"tipLabel\":\"Indice\",\"spellingMistakeWarning\":\"V\\u00e9rifiez votre orthographe: @mistake\",\"confirmCheck\":{\"header\":\"Termin\\u00e9 ?\",\"body\":\"Vous \\u00eates s\\u00fbr de vouloir finir ?\",\"cancelLabel\":\"Annuler\",\"confirmLabel\":\"Terminer\"},\"confirmRetry\":{\"header\":\"R\\u00e9essayer ?\",\"body\":\"Vous \\u00eates s\\u00fbr de vouloir r\\u00e9essayer ?\",\"cancelLabel\":\"Annuler\",\"confirmLabel\":\"Confirmer\"},\"scoreBarLabel\":\"Vous avez obtenu :num points sur un total de :points\",\"media\":{\"disableImageZooming\":false,\"type\":{\"params\":{\"decorative\":false,\"contentName\":\"Image\"},\"library\":\"H5P.Image 1.1\",\"subContentId\":\"dcee6122-1ebf-4b6b-91b6-2f1bae280e40\",\"metadata\":{\"contentType\":\"Image\",\"license\":\"U\",\"title\":\"Sans titre Image\",\"defaultLanguage\":\"fr\"}}},\"submitAnswer\":\"Submit\"}","fullScreen":"0","exportUrl":"\/wp-content\/uploads\/h5p\/exports\/advanced-fill-the-blanks-3.h5p","embedCode":"<iframe src=\"https:\/\/french-lessons.net\/connexion-administrateur\/admin-ajax.php?action=h5p_embed&id=3\" width=\":w\" height=\":h\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\" title=\"Advanced fill the blanks\"><\/iframe>","resizeCode":"<script src=\"https:\/\/french-lessons.net\/wp-content\/plugins\/h5p\/h5p-php-library\/js\/h5p-resizer.js\" charset=\"UTF-8\"><\/script>","url":"https:\/\/french-lessons.net\/connexion-administrateur\/admin-ajax.php?action=h5p_embed&id=3","title":"Advanced fill the blanks","displayOptions":{"frame":true,"export":true,"embed":false,"copyright":true,"icon":true,"copy":true},"metadata":{"title":"Advanced fill the blanks","license":"U","defaultLanguage":"fr"},"contentUserData":[{"state":"{}"}],"scripts":["\/wp-content\/uploads\/h5p\/cachedassets\/aca056b04c15f113caf6fcd73cd50aa8843e1b69.js"],"styles":["\/wp-content\/uploads\/h5p\/cachedassets\/aca056b04c15f113caf6fcd73cd50aa8843e1b69.css"]}}};</script> <script> <p><code><div class="h5p-iframe-wrapper"><iframe id="h5p-iframe-3" class="h5p-iframe" data-content-id="3" style="height:1px" src="about:blank" frameBorder="0" scrolling="no" title="Advanced fill the blanks"></iframe></div></code></p>
ChatGPT:

Yes, you can create a JavaScript file to add numbering to the questions in your H5P content. Create a new file called h5p-numbering.js and add the following code:

javascript
document.addEventListener("DOMContentLoaded", function() { var iframe = document.querySelector(".h5p-iframe"); if (!iframe) { return; } iframe.addEventListener("load", function() { var iframeWindow = iframe.contentWindow; if (!iframeWindow) { return; } var iframeDocument = iframeWindow.document; if (!iframeDocument) { return; } var questionElements = iframeDocument.querySelectorAll(".h5p-advanced-blanks .h5p-blanks"); questionElements.forEach(function(questionElement, index) { var questionNumber = index + 1; var numberingElement = iframeDocument.createElement("span"); numberingElement.classList.add("question-number"); numberingElement.textContent = questionNumber + ". "; questionElement.insertBefore(numberingElement, questionElement.firstChild); }); }); });

Now, you need to include this JavaScript file in your WordPress page. Add the following code to your WordPress page (either directly in the page editor or in your theme's header.php or footer.php file, depending on where you prefer to load it):

html
<script src="/path/to/your/h5p-numbering.js"></script>

Make sure to replace /path/to/your/ with the correct path to the h5p-numbering.js file in your WordPress installation.

This JavaScript code will add numbering to the questions in your H5P content when the page is loaded.

Human: I've included the script directly in my Wordpress theme, so I think I don't need to call it on a specific page. However, it doesn't work.
ChatGPT:

I apologize for the confusion. Let's try another approach. Instead of directly modifying your WordPress theme, you can create a custom JavaScript file and enqueue it in your theme's functions.php file. This way, the script will load on all pages.

  1. Create a new JavaScript file, for example h5p-question-numbering.js, and add the following code:
javascript
document.addEventListener("DOMContentLoaded", function () { const h5pIframes = document.querySelectorAll(".h5p-iframe"); h5pIframes.forEach((iframe) => { iframe.addEventListener("load", function () { const h5pContent = iframe.contentWindow.H5P.instances[0]; if (h5pContent) { h5pContent.on("domChanged", function () { const questionElements = iframe.contentWindow.document.querySelectorAll(".h5p-question"); questionElements.forEach((questionElement, index) => { const questionNumber = index + 1; if (!questionElement.querySelector(".h5p-question-number")) { const questionNumberElement = document.createElement("span"); questionNumberElement.className = "h5p-question-number"; questionNumberElement.textContent = `${questionNumber}. `; questionElement.insertBefore(questionNumberElement, questionElement.firstChild); } }); }); } }); }); });
  1. Upload the h5p-question-numbering.js file to your theme folder.

  2. Open your theme's functions.php file and enqueue the script by adding the following code:

php
function my_theme_enqueue_scripts() { wp_enqueue_script( 'h5p-question-numbering', get_template_directory_uri() . '/h5p-question-numbering.js', array(), '1.0.0', true ); } add_action( 'wp_enqueue_scripts', 'my_theme_enqueue_scripts' );

Make sure to adjust the path to the h5p-question-numbering.js file if you've placed it in a subdirectory within your theme.

This code will load the script on all pages, and it will add the numbering to the questions within the H5P content.

Human: All right, I've added the file "h5p-question-numbering.js" /applications/egtwacxrbe/public_html/wp-content/themes/dt-the7 where this is also the functions.php file and I've added "function my_theme_enqueue_scripts() { wp_enqueue_script( 'h5p-question-numbering', get_template_directory_uri() . '/h5p-question-numbering.js', array(), '1.0.0', true ); } add_action( 'wp_enqueue_scripts', 'my_theme_enqueue_scripts' );" to my theme thanks to a snippet plugin, but it doesn't work.
ChatGPT:

I apologize for the inconvenience. Since you're using a snippet plugin, the issue might be related to the use of get_template_directory_uri() in your enqueue function. The get_template_directory_uri() function returns the URI of the parent theme directory, which may not be the correct path if you're using a child theme.

To ensure you have the correct path, you can use get_stylesheet_directory_uri() instead, which will return the URI of the active theme directory (either the parent theme or the child theme).

Please try modifying your snippet to use get_stylesheet_directory_uri():

php
function my_theme_enqueue_scripts() { wp_enqueue_script( 'h5p-question-numbering', get_stylesheet_directory_uri() . '/h5p-question-numbering.js', array(), '1.0.0', true ); } add_action( 'wp_enqueue_scripts', 'my_theme_enqueue_scripts' );

If this still does not work, please check the browser's console for any JavaScript errors or warnings. You can access the console in most browsers by right-clicking on the page, selecting "Inspect" or "Inspect Element", and then navigating to the "Console" tab.

If you find any errors or warnings in the console, please share them here, so we can further investigate the issue.

Human: No, nothing shows up at all. I've seen this topic online. It's gibberish for me, so I don't know but it may help us. Hi We're currently working with a client that uses Moodle with the addition of H5P to offer content to their users. We have noticed that the H5P content is delivered through an iFrame and as such we're not able to inject custom JavaScript code into this which would allow the solution's accessibilioty tools to be used (these are delivered via a javascript include). We did come across this article: https://h5p.org/moodle-customization which seems to offer a way to customise the plugin but after a discussion with the client it seems that this will take a large amount of development from their side and as such it's not a viable solution. Does anyone know of any ways that custom JS can be injected into the H5P iFrame without a fundimantal extension of the renderer? Thanks Log in or register to post comments otacke's picture otacke Thu, 02/10/2022 - 19:26 permalink Hi rob-recite!The effort Hi rob-recite! The effort necessary is implementing one single hook that will basically only add the paths to custom scripts to be loaded. Not sure what "large amount of development" is expected. If your H5P iframe's contents and moodle files tare served from the same domain, then you can access the iframe via DOM and inject your custom scripts that way. Otherwise, you'll have to patch H5P core or moodle's H5P integration and add scripts to be loaded that way. Cheers, Oliver
ChatGPT:

Based on the discussion you shared, it seems like the H5P content is being served within an iframe, which might be the reason your custom JavaScript isn't working as expected. Accessing the content of an iframe that's loaded from the same domain is possible, but you'll need to adjust your approach.

To inject your custom JavaScript into the H5P iframe, you can follow these steps:

  1. First, modify your "h5p-question-numbering.js" script to wrap the entire code inside a function, e.g.:
javascript
function h5pQuestionNumbering() { // Your existing JavaScript code here }
  1. In your main JavaScript file or within a new JavaScript file (e.g., "inject-h5p-question-numbering.js"), add the following code to inject your custom script into the H5P iframe:
javascript
document.addEventListener('DOMContentLoaded', function () { var h5pIframe = document.querySelector('iframe[src*="h5p"]'); if (h5pIframe) { h5pIframe.addEventListener('load', function () { var h5pIframeWindow = h5pIframe.contentWindow; var h5pIframeDocument = h5pIframeWindow.document; var script = h5pIframeDocument.createElement('script'); script.textContent = '(' + h5pQuestionNumbering.toString() + ')();'; h5pIframeDocument.body.appendChild(script); }); } });

This code will wait for the DOM to be fully loaded, then it will find the H5P iframe, and once the iframe is loaded, it will inject your "h5p-question-numbering.js" script into the iframe.

  1. Enqueue the modified "h5p-question-numbering.js" and the new "inject-h5p-question-numbering.js" (if created) in your functions.php or the snippet plugin:
php
function my_theme_enqueue_scripts() { wp_enqueue_script('h5p-question-numbering', get_stylesheet_directory_uri() . '/h5p-question-numbering.js', array(), '1.0.0', true); wp_enqueue_script('inject-h5p-question-numbering', get_stylesheet_directory_uri() . '/inject-h5p-question-numbering.js', array('h5p-question-numbering'), '1.0.0', true); } add_action('wp_enqueue_scripts', 'my_theme_enqueue_scripts');

This should inject your custom JavaScript into the H5P iframe. If it still doesn't work, please check the browser console for any errors or warnings and share them here.

Human: So, I have the file h5p-question-numbering.js with this code function h5pQuestionNumbering() { document.addEventListener("DOMContentLoaded", function () { const h5pIframes = document.querySelectorAll(".h5p-iframe"); h5pIframes.forEach((iframe) =&gt; { iframe.addEventListener("load", function () { const h5pContent = iframe.contentWindow.H5P.instances[0]; if (h5pContent) { h5pContent.on("domChanged", function () { const questionElements = iframe.contentWindow.document.querySelectorAll(".h5p-question"); questionElements.forEach((questionElement, index) =&gt; { const questionNumber = index + 1; if (!questionElement.querySelector(".h5p-question-number")) { const questionNumberElement = document.createElement("span"); questionNumberElement.className = "h5p-question-number"; questionNumberElement.textContent = `${questionNumber}. `; questionElement.insertBefore(questionNumberElement, questionElement.firstChild); } }); }); } }); }); }); } Then the file inject-h5p-question-numbering.js with this code document.addEventListener('DOMContentLoaded', function () { var h5pIframe = document.querySelector('iframe[src*="h5p"]'); if (h5pIframe) { h5pIframe.addEventListener('load', function () { var h5pIframeWindow = h5pIframe.contentWindow; var h5pIframeDocument = h5pIframeWindow.document; var script = h5pIframeDocument.createElement('script'); script.textContent = '(' + h5pQuestionNumbering.toString() + ')();'; h5pIframeDocument.body.appendChild(script); }); } }); Then the snippet function my_theme_enqueue_scripts() { wp_enqueue_script('h5p-question-numbering', get_stylesheet_directory_uri() . '/h5p-question-numbering.js', array(), '1.0.0', true); wp_enqueue_script('inject-h5p-question-numbering', get_stylesheet_directory_uri() . '/inject-h5p-question-numbering.js', array('h5p-question-numbering'), '1.0.0', true); } add_action('wp_enqueue_scripts', 'my_theme_enqueue_scripts'); But it doesn't work, nothing changes.
ChatGPT:

My apologies for the confusion. I see the issue now - the "h5pQuestionNumbering()" function should be called inside the "inject-h5p-question-numbering.js" file rather than inside the "h5p-question-numbering.js" file.

Please change the "h5p-question-numbering.js" file to have the following code:

javascript
document.addEventListener("DOMContentLoaded", function () { const h5pIframes = document.querySelectorAll(".h5p-iframe"); h5pIframes.forEach((iframe) => { iframe.addEventListener("load", function () { const h5pContent = iframe.contentWindow.H5P.instances[0]; if (h5pContent) { h5pContent.on("domChanged", function () { const questionElements = iframe.contentWindow.document.querySelectorAll(".h5p-question"); questionElements.forEach((questionElement, index) => { const questionNumber = index + 1; if (!questionElement.querySelector(".h5p-question-number")) { const questionNumberElement = document.createElement("span"); questionNumberElement.className = "h5p-question-number"; questionNumberElement.textContent = `${questionNumber}. `; questionElement.insertBefore(questionNumberElement, questionElement.firstChild); } }); }); } }); }); });

Then modify the "inject-h5p-question-numbering.js" file to have the following code:

javascript
function h5pQuestionNumbering() { // Your existing JavaScript code here } document.addEventListener('DOMContentLoaded', function () { var h5pIframe = document.querySelector('iframe[src*="h5p"]'); if (h5pIframe) { h5pIframe.addEventListener('load', function () { var h5pIframeWindow = h5pIframe.contentWindow; var h5pIframeDocument = h5pIframeWindow.document; var script = h5pIframeDocument.createElement('script'); script.textContent = '(' + h5pQuestionNumbering.toString() + ')();'; h5pIframeDocument.body.appendChild(script); }); } });

This should work now. If it still doesn't work, please check your browser console for any errors or warnings and share them here.

Human: Nothing at all
ChatGPT:

I apologize for the confusion. I now realize that the approach I suggested might not work due to the security restrictions enforced by browsers. Let's try another method using postMessage to communicate between the main window and the H5P iframe.

Update the "h5p-question-numbering.js" file with the following code:

javascript
document.addEventListener("DOMContentLoaded", function () { const h5pIframes = document.querySelectorAll(".h5p-iframe"); h5pIframes.forEach((iframe) => { iframe.addEventListener("load", function () { iframe.contentWindow.postMessage({ action: 'addQuestionNumbering' }, '*'); }); }); });

Update the "inject-h5p-question-numbering.js" file with the following code:

javascript
function h5pQuestionNumbering() { // Your existing JavaScript code here } window.addEventListener('message', function (event) { if (event.data && event.data.action === 'addQuestionNumbering') { h5pQuestionNumbering(); } });

Now, the main window should be able to communicate with the H5P iframe using postMessage. If it still doesn't work, please check your browser console for any errors or warnings and share them here.

Human: Nothing. I found this other post, maybe it can help you Hello, Iḿ trying to develope a h5p content, but I need to add javascript after the dom has loaded because the js is a complete react app and needs the div container created from the "preloadedJs". I tried to load the js with jquery getscript in the "C.prototype.attach" method with a relativ path. A "test.js" file in the same folder that contains the file with the "C.prototype.attach" function is cannot be found. Does anybody know here, how I can load custom javascript after the dom load has finished? This is my questionnaire.js file: varH5P=H5P|| {}; H5P.Questionnaire= (function ($) { /** * Constructor function. */ functionC(options, id) { // Extend defaults with provided options this.options=$.extend(true, {}, { language:'en' }, options); // Keep provided id. this.id=id; }; /** * Attach function called by H5P framework to insert H5P content into * page * * @param{jQuery}$container */ C.prototype.attach=function ($container) { // Set class on container to identify it as a greeting card // container. Allows for styling later. $container.addClass("h5p-questionnaire"); // Add image if provided. // if (this.options.image &amp;&amp; this.options.image.path) { // $container.append('&lt;img class="greeting-image" src="' + H5P.getPath(this.options.image.path, this.id) + '"&gt;'); // } // Add greeting text. $container.append('&lt;div class="questionnaire" id="learningstyle"&gt;&lt;/div&gt;'); $(document).ready(function () { $.getScript("test.js") .done(function (script, textStatus) { console.log(textStatus); }) .fail(function (jqxhr, settings, exception) { console.log('getscript failed'); console.log('jqxhr'); console.log(jqxhr); console.log('settings'); console.log(settings); console.log('exception'); console.log(exception); }); }); }; returnC; })(H5P.jQuery); Thanx very much. frischi Log in or register to post comments icc's picture icc Tue, 05/15/2018 - 15:47 permalink If you are modifying the If you are modifying the content type you should add the extra file to preloadedJs in the library.json file of the library. If you are extending it you should use the scripts_alter hook/action in a custom plugin or theme, like this example. Log in or register to post comments frischi Tue, 05/15/2018 - 17:55 permalink Ok, but I don`t want to Ok, but I don`t want to create a new Plugin for worpress. I only want to have a h5p content. It should run in moodle, too. But if I load the js in the preloadedJs, it loads before the dom is ready and the react app cant find its container. Isn`t it possible to load the javascript in the h5p content after the preloaded js? Log in or register to post comments icc's picture icc Tue, 05/22/2018 - 16:26 permalink If you modify the content If you modify the content type or plugin files directly the changes will be gone when the next update is applied. With preloadedJs, it will load after the content type code giving you the opportunity to override the functions of the content type. If you only modify the DOM Elements directly from your script you could experience unexpected results. To run after the content type you could use one of these events: H5P.externalDispatcher.on('domChanged', function (e) { ... }); H5P.jQuery(document).ready(function () { ... }); Log in or register to post comments frischi Mon, 05/28/2018 - 13:00 permalink I tried it with H5P.jQuery I tried it with H5P.jQuery(document).ready(function () and getScritp to load a js file. But it`s not possible to load it with a relative path, because the url in wordpress is not the real path and the getScript function uses the url in the Browser. So I got a status 404. Do you have an idea, how it is possible, to load a javascript file using a relative path AFTER the document is ready. Because the react app needs his document root, which I created in the preloadedJs declared file. Log in or register to post comments icc's picture icc Tue, 05/29/2018 - 09:03 permalink It doesn't sound like you're It doesn't sound like you're going about this the correct way. That said, if it's the H5P Libraries path you're looking for you can use: H5P.getLibraryPath('') Log in or register to post comments frischi Tue, 05/29/2018 - 10:46 permalink Ok, thanx.I found another Ok, thanx. I found another solution for me: Generating a custom event on body element an triggering this after the root element for the react app is genrated. $('body').trigger( "learningstyle_created"); So the react js can preload, if I wrap it in: var H5P = H5P || {}; (function ($) { $('body').on( "learningstyle_created", function() { //react start //react end }); })(H5P.jQuery);
ChatGPT:

I see that you've found another solution that might help. Based on the discussion, it seems they're trying to load a React app within an H5P content and faced issues with loading the script at the right time. The solution they found was to trigger a custom event on the body element after the root element for the React app is created.

In your case, you can try modifying the "inject-h5p-question-numbering.js" file and use the custom event approach like this:

javascript
function h5pQuestionNumbering() { // Your existing JavaScript code here } document.addEventListener("h5pContentLoaded", function() { h5pQuestionNumbering(); }); window.addEventListener("message", function (event) { if (event.data && event.data.action === "addQuestionNumbering") { document.dispatchEvent(new CustomEvent("h5pContentLoaded")); } });

And keep the "h5p-question-numbering.js" file as it was in the previous solution:

javascript
document.addEventListener("DOMContentLoaded", function () { const h5pIframes = document.querySelectorAll(".h5p-iframe"); h5pIframes.forEach((iframe) => { iframe.addEventListener("load", function () { iframe.contentWindow.postMessage({ action: "addQuestionNumbering" }, "*"); }); }); });

Please try this method and see if it works. If you still face issues, let me know if there are any errors or warnings in your browser console.

Human: Nothing...
ChatGPT:

I apologize for the inconvenience. Let's try another approach to solve the issue.

  1. First, merge the contents of the h5p-question-numbering.js and inject-h5p-question-numbering.js files into a single file. Let's call this new file h5p-question-numbering-merged.js. Here is the combined code:
javascript
function h5pQuestionNumbering(iframeWindow) { const h5pContent = iframeWindow.H5P.instances[0]; if (h5pContent) { h5pContent.on("domChanged", function () { const questionElements = iframeWindow.document.querySelectorAll(".h5p-question"); questionElements.forEach((questionElement, index) => { const questionNumber = index + 1; if (!questionElement.querySelector(".h5p-question-number")) { const questionNumberElement = document.createElement("span"); questionNumberElement.className = "h5p-question-number"; questionNumberElement.textContent = `${questionNumber}. `; questionElement.insertBefore(questionNumberElement, questionElement.firstChild); } }); }); } } document.addEventListener("DOMContentLoaded", function () { const h5pIframes = document.querySelectorAll(".h5p-iframe"); h5pIframes.forEach((iframe) => { iframe.addEventListener("load", function () { const h5pIframeWindow = iframe.contentWindow; const h5pIframeDocument = h5pIframeWindow.document; var script = h5pIframeDocument.createElement("script"); script.textContent = '(' + h5pQuestionNumbering.toString() + ')(window);'; h5pIframeDocument.body.appendChild(script); }); }); });
  1. Now update your snippet to enqueue only the new merged script:
php
function my_theme_enqueue_scripts() { wp_enqueue_script('h5p-question-numbering-merged', get_stylesheet_directory_uri() . '/h5p-question-numbering-merged.js', array(), '1.0.0', true); } add_action('wp_enqueue_scripts', 'my_theme_enqueue_scripts');

Make sure you have the h5p-question-numbering-merged.js file in the same directory as your theme's functions.php file. Test this approach and let me know if it works. If it doesn't, please provide any error messages or warnings in your browser console.

Human: Nothing. Here's my file h5p-question-numbering-merged.js: function h5pQuestionNumbering() { document.addEventListener("DOMContentLoaded", function () { const h5pIframes = document.querySelectorAll(".h5p-iframe"); h5pIframes.forEach((iframe) =&gt; { iframe.addEventListener("load", function () { const h5pContent = iframe.contentWindow.H5P.instances[0]; if (h5pContent) { h5pContent.on("domChanged", function () { const questionElements = iframe.contentWindow.document.querySelectorAll(".h5p-question"); questionElements.forEach((questionElement, index) =&gt; { const questionNumber = index + 1; if (!questionElement.querySelector(".h5p-question-number")) { const questionNumberElement = document.createElement("span"); questionNumberElement.className = "h5p-question-number"; questionNumberElement.textContent = `${questionNumber}. `; questionElement.insertBefore(questionNumberElement, questionElement.firstChild); } }); }); } }); }); }); } document.addEventListener("h5pContentLoaded", function() { h5pQuestionNumbering(); }); window.addEventListener("message", function (event) { if (event.data &amp;&amp; event.data.action === "addQuestionNumbering") { document.dispatchEvent(new CustomEvent("h5pContentLoaded")); } }); And here's the snippet: function my_theme_enqueue_scripts() { wp_enqueue_script('h5p-question-numbering-merged', get_stylesheet_directory_uri() . '/h5p-question-numbering-merged.js', array(), '1.0.0', true); } add_action('wp_enqueue_scripts', 'my_theme_enqueue_scripts');
ChatGPT:

I apologize for the confusion earlier. Let's try a different approach using a MutationObserver to monitor changes in the DOM. This should enable the script to work regardless of whether the H5P content is loaded in an iframe or directly on the page.

Replace the contents of your h5p-question-numbering-merged.js file with the following code:

javascript
function addQuestionNumbers(iframe) { const h5pContent = iframe.contentWindow.H5P.instances[0]; if (h5pContent) { h5pContent.on("domChanged", function () { const questionElements = iframe.contentWindow.document.querySelectorAll(".h5p-question"); questionElements.forEach((questionElement, index) => { const questionNumber = index + 1; if (!questionElement.querySelector(".h5p-question-number")) { const questionNumberElement = document.createElement("span"); questionNumberElement.className = "h5p-question-number"; questionNumberElement.textContent = `${questionNumber}. `; questionElement.insertBefore(questionNumberElement, questionElement.firstChild); } }); }); } } function processIframes() { const h5pIframes = document.querySelectorAll(".h5p-iframe"); h5pIframes.forEach((iframe) => { iframe.addEventListener("load", function () { addQuestionNumbers(iframe); }); }); } document.addEventListener("DOMContentLoaded", function () { processIframes(); }); // Set up a MutationObserver to monitor the DOM for changes const observer = new MutationObserver(function (mutationsList) { for (const mutation of mutationsList) { if (mutation.type === "childList") { processIframes(); } } }); // Monitor the entire document for changes observer.observe(document.documentElement, { childList: true, subtree: true });

Your PHP snippet should remain the same:

php
function my_theme_enqueue_scripts() { wp_enqueue_script('h5p-question-numbering-merged', get_stylesheet_directory_uri() . '/h5p-question-numbering-merged.js', array(), '1.0.0', true); } add_action('wp_enqueue_scripts', 'my_theme_enqueue_scripts');

With this change, the script should work regardless of how the H5P content is loaded on the page. Please test this approach and let me know if it works for you.

avatar
Clem
Shared 2 prompts
Created 1 year ago

Leave a Comment