0

I have maintenance task website that lists out the tasks for a machine. the MachineDetails page:

 @page "/MachineDetails/{MachineName}"
 @inherits MachineDetailsBase

 <h3>Machine Details for @Machine.MachineName</h3>
 <table class="table table-bordered table-striped table-hover">
    <thead>
        <tr>
            <th scope="col">Description</th>
            <th scope="col">Repeat<br />(Days)</th>
            <th scope="col">Exp Dur<br /> (Min)</th>
            <th scope="col">Next Due</th>
            <th scope="col">Owner</th>
            <th scope="col">Perform<br />Task</th>
        </tr>
    </thead>
    @foreach (var t in Machine.TasksForMachine)
    {
        <tr scope="row">
            <td>@t.TaskDescription</td>
            <td>@t.TaskRepeatDays</td>
            <td>@t.TaskMinutes</td>
            <td>@t.NextDue.Value.ToShortDateString()</td>
            <td>@t.TaskOwnerType</td>               
            <td style="text-align:center"><button class="btn btn-primary" @onclick="(() => ShowPerformTask(t.TaskId))"> <img src="/css/open-iconic/svg/check.svg" height="12" /></button></td>                
        </tr>
    }
</table>

The MachineDetailsBase is:

  public class MachineDetailsBase : ComponentBase
  {
    [Inject]
    public IMaintenancePMRepository repo { get; set; }
    [Inject]
    NavigationManager NavigationManager { get; set; }
    [Parameter]
    public string MachineName { get; set; }
    public MachineForTasks Machine {get;set;}        
    // other details

    protected override async Task OnInitializedAsync()
    {
        GetSelectedMachine(MachineName);
        EmployeeList = repo.GetEmployeeList().ToList();
        StatusLoookup = repo.GetStatusList().ToList();            
    }

    private void GetSelectedMachine(string inputName)
    {
        Machine= repo.GetAllEquipment().Where(m => m.EquipmentName == inputName).FirstOrDefault(); ;
    }

    public void ShowPerformTask(int  taskID)
    {
      NavigationManager.NavigateTo("/PerformTask/" + taskID.ToString());
    }

on the task page I perform the necessary work and then attempt to call the NavigationManager again to get back to the original page.

The relevant code on PerformTaskBase does the same basic thing code to get back:

razor page code:

        <div class="row">
            <div class="col-sm-4 ">
                <button class="btn btn-primary" @onclick="(() => ClosePerformTask(true))"> Save </button>
            </div>
            <div class="col-sm-4 ">
                <button class="btn btn-secondary" @onclick="(() => ClosePerformTask())"> Don't Save</button>
            </div>
        </div>

then the code behind:

  public void ClosePerformTask(bool SaveTask = false)
  {
     if (SaveTask)
        {                
            repo.PerformTask(TaskRecord);
            TaskToPerform.NextDue = DateTime.Today.AddDays(TaskToPerform.TaskRepeatDays.GetValueOrDefault());
            repo.UpdateTask(TaskToPerform);                
        }

        NavigationManager.NavigateTo("/MachineDetails/" + MachineID);
    }

the MachineDetails page loads for a split second, then the PerformTask page opens back up.

Putting breakpoints in the code behind of the MachineDetails page, I don't see anything other than the OnInitializedAsync() fire at all. How can I get the MachineDetails page to load and not return back to the PerformTask?

4
  • Would you please show your code... Commented May 27, 2020 at 20:36
  • what code would be relevant? pretty much everything except the NavigationManager is simply calls to the repo. For instance the OnInitializedAsync() of MachineDetails has GetSelectedMachine() Commented May 27, 2020 at 20:42
  • Your code is fine. It should work. But it doesn't, and with a typical behavior of NavigationManager.NavigateTo. Without seeing the context, nothing further can be said. Commented May 27, 2020 at 20:46
  • will edit the original question to try to show more context. Commented May 27, 2020 at 20:51

1 Answer 1

3

My answer is based on the supposition that this code is residing within a form element...

div class="row">
        <div class="col-sm-4 ">
            <button class="btn btn-primary" @onclick="(() => 
           ClosePerformTask(true))"> Save </button>
        </div>
        <div class="col-sm-4 ">
            <button class="btn btn-secondary" @onclick="(() => 
                        ClosePerformTask())"> Don't Save</button>
        </div>
    </div>

Am I right.

If yes, the explanation for this behavior is very simple: Using the input button without setting up the type attribute is equivalent to setting up the type attribute to submit. When you click on either buttons a traditional post back to the server takes place in addition to the navigation by the NavigationManager. But you do not post back in an SPA app. This means going out of the navigation space of your application... To remedy this, add the type attribute to both buttons with button value: <button type="button"> This won't allow the post back, and the Navigation will occur as expected.

Hope this helps...

Sign up to request clarification or add additional context in comments.

2 Comments

Yes that is in a form — I will try that first thing tomorrow back at work. I think you’ve got it though :). Thanks for your help.
that worked -- thanks. I'm new to web programming and thought that the form tag was essentially just a logical grouping of related controls.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.