XForm - Same Id for all fields

Vote:
 

Hi,

CMS version: 7.19.1

We are having an issue in our QA enviornment where XForm is generating following HTML. (Works fine in Dev)

...

Title



.....




....

HTML is

m.Block.Form)>
@using (Html.BeginXForm(Model.Block.Form, new { Action = Model.Block.ActionUrl.ToString() }))
{
Html.RenderXForm(Model.Block.Form);
}

I am bit stuck, Where and what I need to investigate on QA enviornments?

Regards
Khurram

#119605
Mar 31, 2015 12:55
Vote:
 

Input_496658235 is same for input and select

/K

#119607
Mar 31, 2015 12:59
Vote:
 

Any help?
/K

#119980
Apr 08, 2015 13:50
Vote:
 

There is view somewhere inside episrever client resources called InputFragment.ascx. it's used to render inputs and is responsible for this faulty rendering.
it renders ids as follows:

<% string inputId = "Input_" + new Random(DateTime.Now.Millisecond).Next(Int32.MaxValue); %>


Random is recreated each time and if time hasn't changed it will produce same value.
Yuo should simply create your own view with some other way to gerate id's, for example use static random suorce or guids.

#120095
Apr 10, 2015 9:23
Vote:
 

I'm having the same issue where the IDs for the fields are all different in dev but are the same when deployed. Why would this be different between environments? I'd rather not create the view as described as if it works on one platform it should work on another.

#122733
Jun 11, 2015 11:18
Vote:
 

As you see, random is created with milisecond as  seed, so if dev environment  is slow enough so that time happens to change between subsequent inputs, then the ids will differ. In production everything is most probably fast enough, so the milisecond will be the same and id will be the same.

#122734
Jun 11, 2015 11:53
Vote:
 

Hi there and thanks for the response. I'm now looking at creating my own view, I presume I need to add this to the project and then set up a virtualPathMapping in EPiServerFramework.config to point to my view? If so how do I determine the virtual path that is currently being used.

I've found the default InputFragment.ascx file in the zip file EPiServer.Shell.UI.zip (under \Util\Views\Shared\EditorTemplates)

#122812
Jun 15, 2015 16:38
Vote:
 

The only thing you have to do is create your own view, for example InputFragment.cshtml (or .ascx), and put it in ~/Views/Shared/EditorTemplates/ in your project and make sure the PartialViewLocationFormats of your view engine includes "~/Views/Shared/EditorTemplates/{0}.cshtml" and/or "~/Views/Shared/EditorTemplates/{0}.ascx".

If you're using Razor you can create your own view engine that looks like this:

public class MyRazorViewEngine : RazorViewEngine
{
    public MyRazorViewEngine()
    {
        PartialViewLocationFormats = PartialViewLocationFormats.Union(new[]
                                {
                                "~/Views/Shared/EditorTemplates/{0}.cshtml",
                                }).ToArray();
    }
}

Register the view engine on application start in Global.asax.cs:

protected void Application_Start()
{
    ViewEngines.Engines.Insert(0, new MyRazorViewEngine());
}
#122910
Jun 17, 2015 15:19
Vote:
 

Thanks Mattias, but will this actually override the view being used by XForms? Isn't there more to it than you describe?

#122916
Jun 17, 2015 15:55
Vote:
 

I don't know what EPiServer version you're on but on 7.19 it's all it takes. I'm doing it myself in a project of ours.

#122928
Jun 18, 2015 8:40
Vote:
 

I think (but haven't tested) you can use "local" editor templates without custom view engine. Local editor template should be with higher priority over editor templates coming from Cms .zip file.

#122963
Jun 19, 2015 0:41
Vote:
 

Well I've tried both methods suggested by Valdis and Mattias and my custom view is not being picked up.

I have added a view in the project, path ~/Views/Shared/EditorTemplates/InputFragment.cshtml, and this is not picked up so I added the custom view engine as suggested by Mattias and registered this in Application_Start event and it's still not being picked up.

Is there anything obvious that I've missed? The original file is .ascx and I have added .cshtml, do I need to do anything extra for this?

Thanks,

Mark

#122976
Jun 22, 2015 10:30
Vote:
 

Hmm, strange. I have this working in a project running EPiServer 7.19.2. What version are you on? And are you using Razor and MVC in your project?

#122977
Jun 22, 2015 10:43
Vote:
 

We're using  7.19.2 as well and yes we are using Razor and MVC

#122984
Jun 22, 2015 11:38
Vote:
 

This is what my view engine PartialViewLocationFormats look like:

PartialViewLocationFormats = new[]
                                  {
                                    "~/Views/Shared/Blocks/{0}.cshtml",
                                    "~/Views/Shared/{0}.cshtml",
                                    "~/Views/Shared/PagePartials/{0}.cshtml",
                                    "~/Views/Shared/EditorTemplates/{0}.cshtml",
                                    "~/Views/{1}/{0}.cshtml"
                                  };

I just noticed I had to touch web.config or recompile for changes in InputFragment.cshtml to be registered.

#122987
Jun 22, 2015 12:23
Vote:
 

Hi Mattias,

I now have the following based on your snippet:


    public class MyIntranetRazorViewEngine : RazorViewEngine
    {
        public MyIntranetRazorViewEngine()
            {
                PartialViewLocationFormats = new[]
                                        {
                                        "~/Views/Shared/EditorTemplates/{0}.cshtml"
                                        };
            }
    }

This class is in a folder called Business which is in the root of the project (does this need to be somewhere else?).

I have performed IIS reset and rebuilt the project several times and the custom view is still not being picked up.

Any other suggestions?

Thanks,

Mark

#123071
Jun 24, 2015 13:03
Vote:
 

I was wrong about "no need to have a custom view engine". I thought EPiServer was using EditorFor, instead of manual partial view find for the fragment.

Can you add following code in your view and paste what's result of variable "partialView": 

@{
    var viewEngineWrapper = ServiceLocator.Current.GetInstance<CachingViewEnginesWrapper>();
    ViewEngineResult partialView = viewEngineWrapper.FindPartialView(ViewContext, "SubmitFragment");
}

Also you may want to check out ViewEnginesCollection, to make sure that your view is registered correctly. Can you dump content of:

System.Web.Mvc.ViewEngines.Engines
#123107
Jun 25, 2015 7:01
Vote:
 

Just to be sure, you have added a regular textbox to the XForm and still, the custom InputFragment.cshtml is not loaded? For other types of form elements you need to add custom fragments for them as well.

When I tested this I added this markup in InputFragment.cshtml:

@model EPiServer.XForms.Parsing.InputFragment

<label title="@Model.Title" for="@Model.Reference">
    @Html.DisplayFor(m => m.Label)
</label>

@Html.TextBox(Model.Reference, Server.HtmlDecode(Model.Value) ?? string.Empty, new { size = Model.Size, @class = Model.Class })
@Html.ValidationMessage(Model.ValidationReference)

Everything was loaded as expected, however when I made changes to the markup I had to touch web.config or rebuild.

As a next step I would do as Valdis says, but replace SubmitFragment with InputFragment. ;)

You can put this code in any of your page views to see the results.

#123110
Jun 25, 2015 8:38
Vote:
 

Hi Mattias and Valdis,

I've found out the problem and got it working. I noticed that the application start event in Global.asax wasn't firing which meant that the custom view engine was not being inserted. I traced this to the namespace in the markup not matching the namespace in the codebehind file, now these match the view engine is being inserted and the correct view is being used.

Thank you both ever so much for your help with this,

Mark

#123119
Jun 25, 2015 11:14
Vote:
 

Hi

Mark A,
Advise me please which response you will like me to mark as answer :)

Mattias and Valdis,
Thanks a lot

Regards
/K

#123124
Edited, Jun 25, 2015 11:37
Vote:
 

Hi K,

I followed the advice of Mattias from his post of June 17 2015, 15:19 so this was the answer, although Valdis provided some good pointers as well especially from his post of June 25 2015, 7:01

Mark

#123126
Jun 25, 2015 11:54
Vote:
 

However, 8.x they changed from Randon to Guid.New().

Also, I would recommend to insert ViewEngine from initializable module, as Global.asax may be actually optional to have in the site at all.

#123135
Jun 25, 2015 13:51
Vote:
 

I agree about the initializable module recommendation. My bad for choosing the easiest road. :)

#123137
Jun 25, 2015 14:15
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.