0

My Get function works fine and the search textbox shows but when I enter the user ID and click search, it goes directly to the post function. It is supposed to go to the Get function again to show the data . after the data shows and whether I selected from the checkboxes or not, I click save and then it is supposed to go to the POst function. What am I doing wrong?

GET function :


    [HttpGet]
        public ActionResult Index(int? SearchId)
        {
            var viewModel = new UserViewModel();

            if (SearchId != null)
            {
                var userDepartments = db.TBL_User_Dep_Access.Where(x => x.UserID == SearchId).Select(x => x.Dep_ID).ToList();
                List<UserDepartmentViewModel> udeptVM = db.TBL_Department.Select(i => new UserDepartmentViewModel
                {
                    Dep_Id = i.Department_ID,
                    Dep_Name = i.Department_Name,
                    IsChecked_ = userDepartments.Contains(i.Department_ID)

                }).ToList();


                var userPermissions = db.TBL_UserPermissions.Where(x => x.UserID == SearchId).Select(m => m.PermissionID).ToList();
                List<UsrPERViewModel> upVM = db.TBL_Permissions.Select(i => new UsrPERViewModel
                {
                    Id = i.PermissionID,
                    Name = i.PermissionName,
                    IsChecked = userPermissions.Contains(i.PermissionID)
                }).ToList();

                viewModel.Departments = udeptVM;
                viewModel.Permissions = upVM;
            }

            return View(viewModel);
        }

My View:


    @model  Staff_Requisition.Models.UserViewModel


@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>

<style>
    .list-group {
        max-height: 300px;
        margin-bottom: 10px;
        overflow: scroll;
        -webkit-overflow-scrolling: touch;
    }
</style>


@using (Html.BeginForm("Index", "TBL_UserPermission"))
{
    @Html.AntiForgeryToken()

    <body class="nav-md">
        <div class="container body">
            <div class="main_container">
                            <div class="title_right">
                                <div class="col-md-5 col-sm-5 col-xs-12 form-group pull-right top_search">
                                    <div class="input-group">
                                        @Html.TextBox("SearchId", "", null, new { @id = "SearchId", @placeholder = "Search for...", @class = "form-control" })
                                        <span class="input-group-btn">
                                            <input class="btn btn-default" value="Search" type="submit">Go! />
                                        </span>
                                                                <ul>
                                                                    @if (Model.Permissions != null)
                                                                    {
                                                                        foreach (var P in Model.Permissions)
                                                                        {
                                                                            <li>
                                                                                <p>

                                                                                    @Html.CheckBoxFor(modelItem => P.IsChecked, new { @class = "flat", @value = P.IsChecked })
                                                                                    @Html.DisplayFor(modelItem => P.Name, new { @class = "DepartmentName", @value = P.Name })
                                                                                    @Html.HiddenFor(modelItem => P.Id, new { @class = "Dep_Id", @value = P.Id })



                                                                                </p>
                                                                            </li>
                                                                        }
                                                                    }

                                                                </ul>

                                                            <ul class="to_do">
                                                                @if (Model.Departments != null)
                                                                {
                                                                    foreach (var D in Model.Departments)
                                                                    {
                                                                        <li>
                                                                            <p>

                                                                                @Html.CheckBoxFor(modelItem => D.IsChecked_, new { @class = "flat", @value = D.IsChecked_ })
                                                                                @Html.DisplayFor(modelItem => D.Dep_Name, new { @class = "DepartmentName", @value = D.Dep_Name })
                                                                                @Html.HiddenFor(modelItem => D.Dep_Id, new { @class = "Dep_Id", @value = D.Dep_Id })
                                                                            </p>
                                                                        </li>
                                                                    }
                                                                }

                                                            </ul>

                                                <div class="col-xs-12 col-sm-6 emphasis">
                                                    <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </body>
}

My POST function:


     [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Index(UserViewModel user_Pers)
        { 

                //remove user with specified ID from database 
                db.TBL_UserPermissions.RemoveRange(db.TBL_UserPermissions.Where(c => c.UserID == user_Pers.SearchId));
                db.TBL_User_Dep_Access.RemoveRange(db.TBL_User_Dep_Access.Where(c => c.UserID == user_Pers.SearchId));

                //for each permission that's checked add user to the table
                foreach (var u in user_Pers.Permissions)
                {
                    if (u.IsChecked)
                    {
                        TBL_UserPermissions Tup = new TBL_UserPermissions();
                        Tup.UserID = user_Pers.SearchId;
                        Tup.PermissionID = u.Id;
                        Tup.IsActive = true;
                        db.TBL_UserPermissions.Add(Tup);
                    }

                }
                db.SaveChanges();

                foreach (var d in user_Pers.Departments)
                {
                    if (d.IsChecked_)
                    {
                        TBL_User_Dep_Access Tud = new TBL_User_Dep_Access();
                        Tud.UserID = user_Pers.SearchId;
                        Tud.Dep_ID = d.Dep_Id;
                        Tud.IsActive = true;
                        db.TBL_User_Dep_Access.Add(Tud);

                    }
                }
                db.SaveChanges();

            return RedirectToAction("myInfo");
        }

BTW I removed most of the div in the view manually for simplicity, so it's okay if an opening or closing doesn't match.

2766
  • 145
  • 11
  • Any submit type button put inside a form will submit the form when it is clicked. You should create another form outside the main form and put the search button and search textbox inside it. Or you need to have `type="button"` for the current search button and use ajax to call the Index controller action. – Chetan Dec 22 '19 at 08:16
  • The BeginForm helper without the method param will always call the POST action with the same name of your view. To avoid confusion I would use a different name for your POST action (Edit seems to be more correct also for the GET part) – Steve Dec 22 '19 at 08:26
  • hi @Steve to be sure, you suggest that the index Get leave it as it is and the Post make it Edit. Or change both of them to edit ?? – 2766 Dec 22 '19 at 08:51
  • @ChetanRanpariya I'm going to try two forms method now – 2766 Dec 22 '19 at 08:52
  • I would change both. You are editing the User, Index is usually for listings with many ViewModels to show. – Steve Dec 22 '19 at 08:57
  • @ChetanRanpariya it won't work. gave me an error of the resource is not found. and I changed the post function name. – 2766 Dec 22 '19 at 09:28
  • your form have 2 submit button. On clicking both the submit button I will hit the Post method only. here are some option to handle this scenario: https://stackoverflow.com/questions/442704/how-do-you-handle-multiple-submit-buttons-in-asp-net-mvc-framework – Rajesh G Dec 22 '19 at 09:40
  • @Steve should I change the name of the view also. make it Edit. – 2766 Dec 22 '19 at 09:41
  • Hi, @ChetanRanpariya do you have an example on the ajax of the button I'm going to write? this is my last resort. I really hope it works. – 2766 Dec 22 '19 at 10:09

1 Answers1

0

As has been pointed out in the comments, in your code you have 1 form whereas to solve the problem you are talking about you need 2 forms. One form responsible for the search get request and the other responsible for the user post.

Here is a simple example of a search form and an update form on the same page.

The viewmodel and controller

using System.Web.Mvc;

namespace SearchAndSubmit.Controllers
{
    public class UserViewModel
    {
        public int? Id { get; set; }
        public string Name { get; set; }
    }

    public class HomeController : Controller
    {
        [HttpGet]
        public ActionResult Edit(int? SearchId)
        {
            var viewModel = new UserViewModel();


            if (SearchId != null)
            {
                viewModel.Id = SearchId;
               //logic to search for user and create viewmodel goes here              
            }

            return View(viewModel);
        }   

        [ValidateAntiForgeryToken]
        [HttpPost]
        public ActionResult Edit(UserViewModel user_Pers)
        {
            //validation and create update logic goes here
            return RedirectToAction("Index");    
        }    
    }
}

The view

@model  SearchAndSubmit.Controllers.UserViewModel    

@{
    ViewBag.Title = "Edit/create user";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>@ViewBag.Title</h2>    

@*This is the search form it does a get request*@
@using (Html.BeginForm("edit", "home", FormMethod.Get))
{    
    @Html.TextBox("SearchId", "", null, new { @id = "SearchId", @placeholder = "Search for...", @class = "form-control" })
    <span>
        <input value="Search" type="submit">
    </span>    
}

@*This is the form for updating the user it does a post*@
@using (Html.BeginForm("edit", "home", FormMethod.Post))
{

    @Html.AntiForgeryToken()    
    @Html.HiddenFor(c => c.Id)

    <p>
        @Html.LabelFor(c => c.Name)
        @Html.TextBoxFor(c => c.Name)
    </p>

    <div>
        <input type="submit" value="Save" />
    </div>
}
Dave Barnett
  • 2,045
  • 2
  • 16
  • 32