Same HTML widget on 2 layouts

Hello.

I’m working on making a website in Hype. I was working on making a Contact page and for that, I made a simple form in HTML. Now, the website is going on Netlify, and thus, no PHP support. I found out this, https://github.com/dwyl/learn-to-send-email-via-google-script-html-no-server to send HTML forms without mailto and PHP.

If you’ll scroll till here, https://github.com/dwyl/learn-to-send-email-via-google-script-html-no-server#10-submit-the-form-using-javascript-ajax, you’ll find that we need to run a script at the bottom of the page, that is, just before </body> tag for it to work. Now, that’s not possible in Inner HTML as the tags like <body>, get stripped. Thus, I had to use HTML widget.

The problem is, I have 2 layouts, 1920px and 425px. Now, because the 2 layouts have their independent DOM elements, I had to add the same form as a HTML widget on both the layouts. I named them differently. But, in the export, I’m getting only one iframe. Shouldn’t I be getting 2 different iframes? Because, what’s happening is, the HTML widget code used on 425px layout is getting exported and is getting loaded even on the 1920px version and thus, scrollbars are appearing around it.

I’ve used Hype for a few months now, and I’m still struggling to understand this HTML widget feature. I really love Inner HTMLs, but, the necessity of the script is creating problem. Is there some workaround where I can possibly ditch the iframes?

I’m sorry, I can’t share the file.

It is hard to know for certain without seeing the document (or one that reproduces the problem you are seeing).

The main question I have is how this would generally work if two forms are on the same page – this is what would happen in a two layout scenario. It may not work at all this way; I would do some vanilla HTML testing.

If so, it is true that you could probably put everything (the form and the script call) within an HTML Widget - iframe. As a performance optimization, if two HTML Widgets have identical source then they will share the same code for the iframe, but I don’t see how this would be a problem since they are two separate elements. As iframes, they are completely isolated from anything else happening on the page.

Anyways, looking at the 2nd link you sent, I believe they are recommending having the script appear at the bottom of the body simply because it executes code immediately and expects the DOM and any required elements to already exist.

If you didn’t go an HTML Widget route and wanted the code to execute on the same page context as the rest of your Hype animation, you might be able to dynamically add the script at ‘On Layout Load’ time (example code here). Perhaps you could have two scripts for each layout?

So, this is what is happening. The code for the widget on both the layouts is exactly the same, and thus, they're resulting into exporting just 1 iframe file. However, the problem is, in the preview, the browser doesn't show any scrollbars and it looks normal. However, when I check the exported files, it shows scrollbars around the form. The weird part is, the export looks fine in Chrome on macOS, and the problem is visible in Chrome on Windows.

Here's en example file: Problem.hype.zip (27.0 KB)

Till then, I'll try the onload way.

So, this is the code I added to a function in the Hype document which I run at on Layout Load:

var bodyElement = document.getElementsByTagName('body')[0];
var scriptElement = document.createElement('script');
scriptElement.data-cfasync = 'false';
scriptElement.type = 'text/javascript';
scriptElement.src = '${resourcesFolderName}/form-submission-handler.js';
bodyElement.appendChild(scriptElement);

However, it works only if I remove the scriptElement.data-cfasync = 'false'; part, or else, it results in an error. How can I add that part?

In any case, however, the form submission doesn’t work as expected, that it, I don’t get the thank you message, instead, get the JSON output.

Here’s the file (without scriptElement.data-cfasync = 'false';): Problem 2.hype.zip (25.5 KB)

EDIT: I believe, the data-cfasync = 'false'; is not really required, as it probably is important only if we use CloudFlare.

I think you need to give the code for form-submission-handler.js a look to fully figure out what is going on. This line can help explain what is going on:

document.addEventListener("DOMContentLoaded", loaded, false);

The code you are installing doesn’t do anything until there’s a DOMContentLoaded event where it does its loading. However, by the time the code has been called in the On Layout Load handler, this even has already happened, so it never installs the submit handlers. Further, if you were to just put this in the head of the document, it would be too early since Hype sets up its DOM after DOMContentLoaded.

Ultimately for this to work, you’ll need to change the form-submission-handler.js code. One strategy would be to just add a loaded(); call at the end of the file (within the anonymous function scope though!). I was able to get the message to appear for me that way.

A small tip; it looks like the javascript is getting cached a bit too aggressively; you can do some cache busting by adding a random argument to the script path like:

scriptElement.src = "${resourcesFolderName}/form-submission-handler.js?" + Math.random();

I hope that helps point you in a working direction.

I'm sorry, I don't know about anonymous function scope. Are you suggesting to just add a loaded(); at the end of the file?

Yes, the bottom of the code would look like:

    function enableAllButtons(form)
    {
      var buttons2 = form.querySelectorAll("*");
      for (var i = 0; i < buttons2.length; i++)
        {
          buttons2[i].disabled = false;
        }
    }

    loaded(); // new line to make sure it is called immediately

  })();

I only did basic testing with the one layout though; there might be other issues to reason through.

1 Like

Okay, well, thanks. I’ll test this out futher.

Hello, really sorry for bumping this one up again, but, could you please share the file in which you could get it working? I tried implementing everything from this discussion, and I’m still getting the JSON result.

I only tested on the desktop layout:

Problem-fixed.hype.zip (38.1 KB)

Got it. Thanks a lot!

1 Like