0

I am using Razor Pages. I have a form that allows you to either buy or sell. I need to change a value of the OrderType field in the OrderPlacement model, depending on whether the user buys or sells. I accomplish this using javascript.

<input type="hidden" asp-for="@Model.OrderPlacement.OrderType" />
<input class="btn-primary" type="button" value="Buy" asp-page-handler="Buy" onclick="SubmitBuyOrder();" />
<input class="btn-primary" type="button" value="Sell" asp-page-handler="Sell" onclick="SubmitSellOrder();" />

And here is my JavaScript:

function SubmitSellOrder() {
  document.getElementById('OrderPlacement_OrderType').value = 'Sell';
  document.getElementById('OrderForm').submit();
}

function SubmitBuyOrder() {
  document.getElementById('OrderPlacement_OrderType').value = 'Buy';
  document.getElementById('OrderForm').submit();
}

Here are my backend methods:

public async Task<IActionResult> OnPostBuyAsync()
{
    OrderPlacementResponse response = new OrderPlacementResponse();

    try
    {
        if (!ModelState.IsValid)
            return Page(); //Display User Errors
        else
        {
            //Do Some Stuff
        }


    }
    catch (Exception ex)
    {
        //TODO: Log Errors
        //TODO: Redirect to Error Page
        return RedirectToPage("/Error"); //show errors
    }

}



public async Task<IActionResult> OnPostSellAsync()
{
    OrderPlacementResponse response = new OrderPlacementResponse();

    try
    {
        if (!ModelState.IsValid)
            return Page(); //Display User Errors
        else
        {
            //Do Some Stuff
        }


    }
    catch (Exception ex)
    {
        //TODO: Log Errors
        //TODO: Redirect to Error Page
        return RedirectToPage("/Error"); //show errors
    }

}

The backend methods are not being hit. But I see the javascript methods being hit.

I tried using the regular method of having the buttons submit directly where type="submit". But I still need to have the OrderType change depending on which button is pressed, so I still need the type to remain as "button" and the onclick to call the javascript methods.

Also, I cannot set this value (OrderType) in the backend because there is validation that is run before the backend method is hit.

What is wrong with my existing code, that it will not submit?

HoboJeff
  • 101
  • 1
  • 1
  • 8
  • 1
    *I tried using the regular method of having the buttons submit directly as submit-type buttons* <-- Buttons with `type=button` don't submit anything. Buttons that either don't have their `type` set or have `type="submit"` do. – Scott Marcus Jan 03 '23 at 22:13
  • @ZubairAhmd `value` is a property, not a method. It doesn't take any arguments. And, it's unclear what you are even trying to say with your comment as setting the value has nothing to do with form submission. – Scott Marcus Jan 03 '23 at 22:21
  • Sorry, I'm not the best with expressing my thoughts. I made some edits. The button is currently of type 'button'. I tried to change it to 'submit', and that works, but the problem is I still need to call the javascript methods in the "onclick" before the form is submitted. The value I am referring to is the value of "Model.StockDetails.OrderType". – HoboJeff Jan 03 '23 at 22:38
  • 1
    Use `type="submit"` and in the event handler, use the `event` argument and call `event.preventDefault()` to stop the form's submission. After that, call your other functions that you need called and after that use `formReference.submit()` to manually submit the form. – Scott Marcus Jan 04 '23 at 14:29
  • @Scott Marcus oh bless you, good friend. I will try that now! – HoboJeff Jan 04 '23 at 16:44

1 Answers1

0

Here is a working demo you could follow:

View

@page
@model IndexModel
<form id="OrderForm" method="post">
    <input type="hidden" asp-for="@Model.OrderPlacement.OrderType" />
    <input class="btn-primary" type="submit" value="Buy" asp-page-handler="Buy" 
                               onclick="SubmitBuyOrder(event)" />
    <input class="btn-primary" type="submit" value="Sell" asp-page-handler="Sell"
                               onclick="SubmitSellOrder(event);" />
</form>

@section Scripts
{
    <script>
        function SubmitSellOrder(e) { 
            e.preventDefault();
            document.getElementById('OrderPlacement_OrderType').value = 'Sell';
            var url = document.activeElement.getAttribute("formaction");
            document.getElementById('OrderForm').action=url;
            document.getElementById('OrderForm').submit(); 
        }

    function SubmitBuyOrder(e) {
        e.preventDefault();
        document.getElementById('OrderPlacement_OrderType').value = 'Buy'; 
        var url = document.activeElement.getAttribute("formaction");
        document.getElementById('OrderForm').action=url;
        document.getElementById('OrderForm').submit(); 
    }
    </script>
}

Be sure your backend contains such property with [BindProperty] attribute:

[BindProperty]
public OrderPlacementResponse OrderPlacement { get; set; }

Besides, you can also combine to one function like below:

@page
@model IndexModel
<form id="OrderForm" method="post">
    <input type="hidden" asp-for="@Model.OrderPlacement.OrderType" />
    <input class="btn-primary" type="submit" value="Buy" asp-page-handler="Buy"  />
    <input class="btn-primary" type="submit" value="Sell" asp-page-handler="Sell"  />
</form>

@section Scripts
{
    <script>
        $("#OrderForm").on("submit",function(e){
            e.preventDefault();
            var orderType= $(this).find("input[type=submit]:focus").val();
            document.getElementById('OrderPlacement_OrderType').value = orderType;
            var url = document.activeElement.getAttribute("formaction");
            document.getElementById('OrderForm').action=url;
            document.getElementById('OrderForm').submit();
        })
    </script>
}
Rena
  • 30,832
  • 6
  • 37
  • 72