3

I am aware this topic has been in many developers' interest and has been talked about in many forums, but I haven't been able to find the right answer that quite solves my issue. Perhaps I haven't tried hard enough to seek the answer, in which case it would be nice if you fellow developers could let me know of any useful forums.

The issue that I am having is simply the traditional HTML action not calling the controller ActionResult method.

I have a partial view called "_Form.cshtml" as follows:

<_Form.cshtml>

<form action="@Url.Action("Temp_Form", "Product")" method="post" class="k-content" id="tempForm">
    @Html.AntiForgeryToken()
    @Html.ValidationSummary()
    <fieldset>
    <p class="lead">Please fill in the following form.</p>
    <br />

    <div class="form-horizontal">
        <div class="form-group">
            @Html.Label("Brand", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @(Html.Kendo().DropDownList()
                .Name("ddlBrand")
                .OptionLabel("--- Select ---")
                .HtmlAttributes(new { id = "brand", required = "required", data_required_msg = "Select Brand", @class = "form-control" })
                .DataTextField("Name")
                .DataValueField("Id")
                .BindTo(Products.ProductBrandCollection.LoadAll())
                )
                <span class="k-invalid-msg" data-for="ddlBrand"></span>
            </div>
        </div>
        <div class="form-group">
            @Html.Label("Range", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @(Html.Kendo().TextBox()
                .Name("tbRange")
                .HtmlAttributes(new { required = "required", validationmessage = "Enter Range" })
                )
                <span class="k-invalid-msg" data-for="tbRange"></span>
            </div>
        </div>
    </div>

    <div id="buttondiv">
        <div class="column">
            <div class="vis" id="submitbutton">
                @(Html.Kendo().Button()
                .Name("btnSubmit")
                .HtmlAttributes(new { type = "submit", @class = "button-next" })
                .Icon("arrowhead-e")
                .Content("SUBMIT")
                .Events(e => e.Click("submit"))
                )
            </div>
        </div>
    </div>
    </fieldset>
</form>

In the main view "Product.cshtml", I have the following javascript click event for submit button:

function submit(e) {
    // handles hiding and showing divs
}

Here is my ActionResult "Temp_Form", which is in "ProductController.cs":

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Temp_Form(string ddlBrand, string tbRange)
{
    TempData["brand"] = ddlBrand;
    TempData["range"] = tbRange;
    return Content("");
}

I am sussing it is either "@Url.Action("ActionMethod", "Controller")" <- this part not being correctly formatted or having both "type="submit" and ".Events(e => e.Click("submit"))" for the submit button.

**For a reason, I am not using Html.BeginForm() to call the controller method. So my option is to use the traditional form to pass data from the view to controller with submit button.

I have also tried..

<form action="myController/myAction" method="POST">

the above format but my ActionResult is still not called.

I don't think my main view is causing the ActionResult not to fire since it only has two cascaded DropDownLists that selects a correct form on the client side.

Could someone please identify what I'm doing wrong or advice me with alternatives? As I mentioned above, I am not by any chance using Html.BeginForm() simply because I have those Telerik Kendo Validations that seem to work with only the traditional form..

Many thanks in advance!

YoOuch
  • 43
  • 1
  • 8
  • 6
    Why are you not using `Html.BeginForm()`? Why do you have `@Html.AntiForgeryToken()` outside the form tags? What is the code in your `function submit(e) {` ? –  Jun 12 '15 at 00:48
  • "I am not by any chance using Html.BeginForm() simply because I have those Telerik Kendo Validations that seem to work with only the traditional form.." For some reasons, if I change to Html.BeginForm(), the validation messages do not appear. I eliminated the submit(e) simply because I didn't think it is relevant to this topic since it only handles hiding and displaying divs. – YoOuch Jun 12 '15 at 00:53
  • Not familiar with Kendo Validations, but possibly because `@Html.BeginForm()` will add `novalidate="novalidate"` (but you could just as easily use `@Html.BeginForm()` and set the `novalidate` attribute to an empty string. However this has nothing to do with your issue since `action="@Url.Action("Temp_Form", "Product")"` will generate the correct url. You can easily test this by commenting out the `@(Html.Kendo().Button()...` and replace with `` which should then post to your method. –  Jun 12 '15 at 00:59
  • 1
    In which case, is your `Temp_Form()` method decorated with the `[ValidateAntiForgeryToken]` attribute? (if not it will not hit the method) –  Jun 12 '15 at 01:04
  • 1
    Sanity checks: (a) What happens if you don't handle the submit event in your JS? (b) Inspect with your browser tools and look into the request/response traffic (and even script errors, if you have js in the pipeline). – EdSF Jun 12 '15 at 01:13
  • @StephenMuecke I decorated Temp_Form() with [ValidateAntiForgeryToken] but it still doesn't hit the breakpoint.. What else can I do? – YoOuch Jun 12 '15 at 01:30
  • Did you do the test I suggested (replace the Kendo button with a normal submit button)? –  Jun 12 '15 at 01:31
  • @EdSF I commented out .Events(e => e.Click("submit")) <- this line but still does not hit the method.. – YoOuch Jun 12 '15 at 01:32
  • @StephenMuecke Yes I did, but the situation hasn't changed – YoOuch Jun 12 '15 at 01:33
  • What does your browser's Request traffic look like? Use browser dev tools to see if it actually does, where (target) and what (data, data format, etc). it's sending somewhere.... – EdSF Jun 12 '15 at 01:34
  • You have indicated this is a partial view. What is in the main view - are there any `
    ` tags in the main view?
    –  Jun 12 '15 at 01:39
  • @EdSF I have no idea how to check that.. All I can say is I use Chrome.. – YoOuch Jun 12 '15 at 01:42
  • @StephenMuecke I don't have any sort of forms in the main view. Just two cascaded dropdowns to choose a form. I heard nested forms never work. – YoOuch Jun 12 '15 at 01:43
  • @StephenMuecke I briefly explain how my system works. In the main view, there are two dropdowns (Category and Type) then one of three partial views (different product info forms) is selected. In the partial views there is a "NEXT" button that switches divs (just hiding and displaying) and the button type is submit. The divs go "Product Info" -> "Description" -> "Retail Info" -> "Distributor" -> "Confirmation" -> "Confirmed". I'm working on the first part where I pass Product Info to controller method. – YoOuch Jun 12 '15 at 01:55
  • `Ctrl`+`Shift`+`i ` (Windows) will open Chrome Dev Tools. You should look into `Console` (script errors, if any) and `Network` tabs (to inspect each request and subsequent response). They will both be extremely helpful in inspecting what actually goes on between browser and server. If you say your controller isn't "hit" then Visual Studio debugging won't help you. You will likely find out why using Browser dev tools... – EdSF Jun 12 '15 at 01:56
  • @AUSupernova, Can you show the code for your `function submit(e)` method. Based on you description I can't see how any of this can work since if a submit was performed, hiding and showing divs in javascript would not work –  Jun 12 '15 at 02:05
  • @StephenMuecke Please check the edited code above with the entire submit(e) function in my main view. I called submit(e) in my actual program goNext(e). It is literally the entire code for the function. – YoOuch Jun 12 '15 at 02:29
  • @AUSupernova, this is a ridiculous amount of code that makes no sense. If the form where actually to submit then everything your doing in that script would be immediately discarded since doing a submit means you leave the page! Its hard to understand what your trying to achieve with all this. Even worse is that you are not biding to a model and nowhere in your POST method to you perform any validation (What is the point all all this client side validation when you dont validate on the server). –  Jun 12 '15 at 03:31
  • Best guess is you want some kind of muli-step wizard, in which case I suggest you look at [this answer](http://stackoverflow.com/questions/25643394/mvc-force-jquery-validation-on-group-of-elements/25645097#25645097) –  Jun 12 '15 at 03:32
  • @StephenMuecke thanks for your time on this issue and your advice. My situation is a bit complex since I am not using the Model at all, instead I am using CodeFluent Entities Framework as an alternative. I will look into the link you provided and seek if there is a better and more secure way to accomplish my task. – YoOuch Jun 12 '15 at 03:44
  • @AUSupernova, I cant comment on why the submit event is not occurring (I have exhausted everything I can think of), but the key point is that if it did submit, then everything inside your `submit(e)` function where you add and remove class names etc. is just pointless because when you submit you leave the page and render a new page (unless you use ajax to post your form) –  Jun 12 '15 at 03:49

2 Answers2

2

The issue is you are handling the Submit of the form with a JavaScript event...

So if you want to keep your JS event for your submit button click you need to use Ajax call from your JS method to do the POST to the action, something like:

$.ajax({
    url: '/Product/Temp_Form',
    data: $('#tempForm').serialize(),
    type: 'POST',
});
Aram
  • 5,537
  • 2
  • 30
  • 41
  • So I ended up using your way @Aram and everything works as I wanted my system to perform. Thank you for your advice! – YoOuch Jun 15 '15 at 01:21
0

You are using Razor syntax so do not use form tag directly, use Html.BeginForm() as below.

@using(Html.BeginForm("Temp_Form", "Product", FormMethod.Post, new {@class = "k-content", @id="tempForm" }))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary()
    <fieldset>
        //your HTML here
    </fieldset>
}

Also if possible use strongly typed models instead of loose string properties like ddlBrand and tbRange.

Chaitanya Gadkari
  • 2,669
  • 4
  • 30
  • 54