2

When I use the BeginFormSitefinity helper the form disappears after submitting, and then the postback is done.

The expected behavior would be only the postback to be done. I went to the browser and investigated and I found out that when you use BeginFormSitefinity an extra script is added to your html.

That script basically creates a new form with display = none. And appends your form to the "invisible" form, and thus your form disappears after submitting.

I'm using Sitefinity 8.1, and I would like to know if is there any way to avoid this?

This is the script added (I have no control over it):

<script type="text/javascript">
            (function () {
                var container = document.getElementById("myForm2");
                if (container === null)
                    return;

                var inputs = container.querySelectorAll("input");
                var allInputs = document.forms["aspnetForm"].querySelectorAll('input');
                for (var i = 0; i < allInputs.length; i++) {
                    allInputs[i].addEventListener("invalid", function(event) {
                        if (Array.indexOf(inputs, document.activeElement) >= 0 && Array.indexOf(inputs, event.target) < 0)
                            event.preventDefault();
                    }, true);
                }

                var submitClick = function () {
                    var isValid = true;
                    for (var i = 0; i < inputs.length; i++) {
                        if (typeof inputs[i].willValidate !== "undefined" && inputs[i].willValidate)
                            isValid = inputs[i].validity.valid && isValid;

                        if (typeof jQuery !== "undefined" && typeof jQuery.validator !== "undefined")
                            isValid = jQuery(inputs[i]).valid() && isValid;
                    }

                    if (isValid) {
                        var form = document.createElement("form");

                        form.style.display = "none";
                        form.setAttribute("action", "/order-calendar/Search");
                        form.setAttribute("method", "POST");
                        form.setAttribute("enctype", document.forms["aspnetForm"].getAttribute("enctype"));
                        form.setAttribute("encoding", document.forms["aspnetForm"].getAttribute("encoding"));                            

                        form.appendChild(container);

                        document.body.appendChild(form);

                        // We prevent kendo upload widget from submitting empty inputs.
                        var kInputs = container.querySelectorAll(".k-upload input[type='file']");
                        for(var i = 0; i < kInputs.length; i++) {
                            var kInput = kInputs[i];
                            if (!kInput.value) {
                                // Prevent submitting an empty input
                                kInput.setAttribute("disabled", "disabled");

                                window.setTimeout(function() {
                                    kInput.removeAttribute("disabled");
                                }, 0);
                            }
                        }

                        form.submit();

                        return false;
                    }
                };

                var handleFormSubmitElements = function (elementName) {
                    var allSubmitElements = container.getElementsByTagName(elementName);
                    var elementCount = allSubmitElements.length;
                    while(elementCount) {
                        typeAttr = allSubmitElements[elementCount - 1].getAttribute("type");
                        if(typeAttr == "submit") {
                            allSubmitElements[elementCount - 1].onclick = submitClick;
                        }
                        elementCount--;
                    }
                };

                handleFormSubmitElements("input");
                handleFormSubmitElements("button");
            })();
        </script>

This is my form (its values are read automatically, that's why onkeydown returns false):

@using (Html.BeginFormSitefinity("Search", "myForm2"))
    {
     <div id="main_content" style="max-width: 600px; max-height:700px;float:left;overflow: hidden;">

     <table>
                <tr><td colspan="2" style="text-align:center;">@Html.Label("City")</td></tr>

                <tr>
                    <td>@Html.Label("Code") </td>
                    <td>

                        @Html.Kendo().TextBoxFor(x => x.Code).HtmlAttributes(new { onkeydown = "return false", style = "color: green; width:100%;", id = "Code" })
                    </td>
                </tr>
                <tr>
                    <td>@Html.Label("City Code") </td>
                    <td>

                        @Html.Kendo().TextBoxFor(x => x.CityCode).HtmlAttributes(new { onkeydown = "return false", style = "color: green; width:100%;", id = "CityCode" })
                    </td>
                </tr>

      </table>

    <input type="submit" class="btn btn-success" value="submit">
}

This is what happens visually:

enter image description here

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Nelssen
  • 1,023
  • 1
  • 17
  • 42
  • Do you return a view from your HttpPost action? – Veselin Vasilev Sep 04 '15 at 05:12
  • Hi @Veselin Vasilev I redirect to action index like this -> **RedirectToAction("")** , I had View("Default") and View("Default", Model). The first one gives me error the second one redirects me to a blank page – Nelssen Sep 04 '15 at 08:36
  • what's the error? just for the test - try with Response.Redirect and see if that works – Veselin Vasilev Sep 06 '15 at 13:16
  • there is noerror, the form just disappears before reaching the server. Response.Redirect didn't helped maybe because it looks a client side problem – Nelssen Sep 07 '15 at 16:37
  • 1
    Maybe you can copy the whole javascript that was generated by the BeginFormSitefinity method and paste it in your view. You can modify it a bit so that it does not sets display = none. You would have to also remove the whole BeginFormSitefinity - you will not need that - just experiment a bit, it should be straightforward – Veselin Vasilev Sep 09 '15 at 01:33
  • I'ts a very nice idea and I'll test it, but it is very strange the need to do this – Nelssen Sep 11 '15 at 09:12
  • @VeselinVasilev i tested your suggestion but only succeeded in changing the behavior from disappearing to moving below the existing asp.net form. is there any other way to workaround this behavior? – SelAromDotNet Jan 12 '16 at 00:42
  • @SelAromDotNet can you share a gist? – Veselin Vasilev Jan 12 '16 at 09:30

2 Answers2

2

if you are using Hybrid MVC (that is the webforms version of MVC widgets) then i believe there is no way to avoid this.

Previous to v8.1 the javascript you posted above was different, and would modify the actual form tag of the webforms page to post to your custom action...

now it appears they submit to a FORM tag built on the fly for MVC widgets...

One thing I've noticed they still have is the id of the FORM tag hard-coded to be "aspnetForm", so if your Master Page doesn't use that explicit, specific ID then that might be a probably cause...

if you set a breakpoint in the action to which your form posts, do you get a hit?

SelAromDotNet
  • 4,715
  • 5
  • 37
  • 59
  • Sorry for the late reply SelAromDotNet. I don't know how do you know it, but yes. they still have the aspnetForm hardcoded, you are obliged to use that name in the masterpage else it will not work. yes, I get an Hit in the action, really don't know how to avoid this. This weekend I'll do what Veselin suggested and other tries. Lets see if this ugly bug will get closed. – Nelssen Oct 02 '15 at 13:40
  • ohhh i totally misunderstood your question. you're saying that SF injects your form into this new dynamic form element, and since it's hidden it makes your form disappear before it finishes the post... In that case, perhaps you can play with the CSS like adding "display: block !important" as well as positioning the new FORM tag that Sitefinity creates so that when it's added it gets placed in the same location. Very hacky, but so is the MVC implementation :/ can't believe I never noticed that it does this, good luck! – SelAromDotNet Oct 02 '15 at 16:12
  • Oh you have test it right now and notice the "bug"? ehehe :) Yeah I'll try it in the weekend because I still have another Sitefinity related issues to solve! – Nelssen Oct 02 '15 at 16:47
  • Puh's answer on this question is totally correct, there is no way to avoid this that I can come up with. the previous implementation used javascript to modify the action of the main asp.net form. apparently they saw fit to change this to appending a form tag (tho still neglected to remove the dependency on "aspnetForm" name). i'm just stunned. – SelAromDotNet Jan 12 '16 at 00:18
2

Our team also had the same issue. Was created support ticket to Telerik. And there is an answer:

Essentially, this is expected behavior when using the BeginFormSitefinity. The reasons this happens is because in ASP.NET web forms only one form with runat="sever" is allowed on a page. This is why the BeginFormSitefinity renders as a div by default and a form is dynamically created and submitted when the submit button is clicked. In order to overcome this behavior you will need to create a custom helper and HybridForm. You can take a look at the following StackOverflow answer for more information on how to create a custom HybridForm.

Community
  • 1
  • 1
pryabov
  • 702
  • 2
  • 7
  • 23
  • 1
    unbelievable. i finally got a chance to test this again and came back here to see if there were any updates. i dont see how implementing your own hybrid form would make any difference, as all this would do is change the behavior from being invisible to making it jump to the bottom of the screen (since it's appended to the body). did your team ever find any way to work around this? – SelAromDotNet Jan 12 '16 at 00:16
  • Unfortunately We don't like a solution what we finally used as workaround. In common *BeginFormSitefinity* HTML helper was excluded from source-code and was written JavaScript code which sends data to server. As an improvement it can works by using HTML tags attributes and initialized only once after page is loaded. But this is not a solution this is just possible workaround... – pryabov Jan 12 '16 at 10:55