$$epiforms is not defined when using Form in footer

Vote:
 
@* ... *@ @Html.Raw(Html.RequiredClientResources("Header"))

I get this javascript error when adding a EPiServer Forms form to the footer. I guess it has to do with something not loading in the correct order but I can not figure it out.

My Layout.cshtml has the following simplified layout:


 
    @* ... *@ 
    @Html.Raw(Html.RequiredClientResources("Header")) 


    @Html.RenderEPiServerQuickNavigator();
    @Html.FullRefreshPropertiesMetaData();
    @Html.RenderPartial("Header", Model); 
    @RenderBody();
    @Html.RenderPartial("Footer", Model); 
    @Html.Raw(Html.RequiredClientResources("Footer"));


And the footer is containing a regular ContentArea with a Form in it.

Is it some obvious error here? Or how should the correct loading order be?

#177482
Apr 12, 2017 16:39
Vote:
 

I don't use Html.Raw, I have simplified:

<html>
	<head>
		@Html.RequiredClientResources("Header")
	</head>
	<body>
		@Html.RenderEPiServerQuickNavigator()
		@RenderBody()
		@Html.RequiredClientResources("Footer")
	</body>
</html>

BR,

Marija

#177483
Apr 12, 2017 17:06
Vote:
 

I don't think that the answer makes sense without 

@Html.RenderPartial("Footer", Model); 

or is it removing Html.Raw that is the solution to my problem?

#177485
Apr 12, 2017 17:16
Vote:
 

Hi, I've misread your question. 

Html.Raw doesn't matter much (although it looks like you would get three extra ; on the page)

I don't think it should matter much if it is in the footer, unless you have some scripts there? 

I'd suggest you try this quickly on AlloyTech.

#177486
Apr 12, 2017 17:49
Vote:
 

Has anyone solved this yet? Having the same problem.

#207056
Sep 06, 2019 22:01
Vote:
 

I also noticed I do not get this error on pages that have forms in the body, since it loads the script correctly in those cases. Its only on pages that have no forms in the body, but one in the footer that have this issue.

#207057
Sep 06, 2019 22:02
Vote:
 

Hmm...interesting, I've never really thought about this before.

I don't think there is a nice fix for this honestly. The layout is executed after RenderBody, which explains why it isn't working in the footer. To try and put it simply, when it's used in the body the relevant FormContainerBlockController methods (which register all the necessary JS and CSS resources) are firing before Html.RequiredClientResources(RenderingTags.Header). However, because your footer is presumably in your layout (or a partial or whatever) this is happening after RequiredClientResources(RenderingTags.Header).

There are quite a lot of forum posts documenting similar(ish) issues, this one and this one are both kind of interestingalthough they don't solve your issue.

If you need to use Episerver Forms in the footer then the only way I can think around the issue is using a global action filter which registers the required resources. Something like this (but better!):

public class FooterFormActionFilter : IActionFilter
{
    private readonly IContentLoader _contentLoader;

    public FooterFormActionFilter(IContentLoader contentLoader)
    {
        _contentLoader = contentLoader;
    }

    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
    }

    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        // Determine whether an editor has added a form to the footer.

        // Get the Content Reference & try to load the content
        if (!_contentLoader.TryGet<FormContainerBlock>(new ContentReference(123), out var formBlock))
        {
            return;
        }

        var controller = new FormContainerBlockController();

        controller.RegisterScriptResources(formBlock);
        controller.RegisterCssResources();
    }
}

You could register it the same as the one that's in Alloy.

It's not great, but I can't think of a better solution right now!

#207083
Edited, Sep 10, 2019 0:57
Vote:
 

Thanks for the feedback. Thats not an ideal solution but its a step in the right direction. Im apprehensive to put a filter in that runs on every page, and I can't think of a way to tell whether the form resources have already been loaded or not. I would be doubling up and adding more overhead to the page load time. Can you think of a way to detect if form resources have been loaded already?

#207117
Sep 10, 2019 18:00