caitlinp
caitlinp

Reputation: 183

Reload page based on a selection from drop down list MVC

I have a working solution, but I don't know how to reload the page after a certain ID is selected from the drop down list. My list is being populated from the DB. When I select it, I can see the ID and the corresponding data for it. However, there is no change on the screen.

Model class:

 public List<Hello> getID()
        {
            var que = (from rel in db.Table1
                       select new Hello
                       {
                           ID = rel.R_ID
                       }).ToList();
            return que;
        }

public List<Hello> getStuff()
        {
            var que = (from wre in db.View
                       select new Hello
                       {
                           ID = wre.R_ID,
                           Summary = wre.Summary,
                           Description = wre.Description

                       }
         }

getHello() is the same exact method as the getStuff(), just accepts a string ID parameter.

Controller class:

public ActionResult Index()
        {
            var model = test.getStuff();
            ViewBag.IDs = new SelectList(test.getID(), "", "ID");
            return View(model);
        }

[HttpPost]
        public JsonResult getDataBySelectedID(string selectedId)
        {
            var que = test.getHello(selectedId);
             return Json(que, JsonRequestBehavior.AllowGet);

        }

Partial_View Class:

 <div class="container">
        <table id="myTable" align="left">
            <tr>
                <th>@Html.DisplayNameFor(model => model.R_ID)</th>
                <th>@Html.DisplayNameFor(model => model.Summary)</th>
                <th>@Html.DisplayNameFor(model => model.Description)</th>
            </tr>

     @foreach (var item in Model)
        {
          <tr id="Home">

              <td>@Html.DisplayFor(x => item.R_ID)</td>
              <td>@Html.DisplayFor(x => item.Summary)</td>
              <td>@Html.DisplayFor(x => item.Description)</td>
           </tr>
         }
  </table>
 </div>

View Class:

@Html.DropDownList("ID", ViewBag.IDs as SelectList) 

    <script>

     $(document).ready(function () {
         $("#ID").on("change", function () {
                var selectedId = this.value;
                var url = "/Sample/getDataBySelectedID";

                $.ajax({
                    method: "POST",
                    dataType: "json",
                    url: url,
                    data: {
                        selectedId: selectedId
                    }
                });
            });
         });
   </script>

@foreach (var item in Model)
            {
                <tr>
                    <td>
                        @{Html.RenderPartial("Partial_Index", item);}
                    </td>
                </tr>
            }

How would I be able to reload the page with the selected value and its corresponding data?

Any help would be appreciated!

Thank you.

Upvotes: 1

Views: 2798

Answers (2)

Jack
Jack

Reputation: 1493

As described in the comments, you'll have to load your data into your page somehow. I recommend you do this through partial views.

1) Create a reusable Partial View

First, create a partial view that references your model. To do this, create a view as you normally would for your controller, and tick the "Partial View" option. Make sure to select your model in the model dropdown.

Then, move your .cshtml that references your model from your current view to your partial view. For example, if you have a table that lists out the fields of your model, you would cut the entire table into your partial view. You want to include the minimal amount of code needed in the partial view (aka, don't copy your entire view into it).

2) Reference the Partial View in your Current View

Now that you have your partial view set up, you should use it in your existing view to load the table. You should make sure this works first before continuing. You can use the @Html.RenderPartial(string ViewName, object Model) helper method to render it. Read more. So, you might place this line where your now-cut-code was: @RenderPartial("MyPartialView", model), where "MyPartialView" is the name of your partial view, and model is the model object that you want to pass into the partial view.

3) Add Methods to Render Partial View on Controller

At this point, you just need to be able to update your partial view after using AJAX. First, you need to add the ability to render the Partial View as a string so that you can easily inject it into your view. I recommend you do this by implementing a controller interface and letting your controller inherit the needed methods from that. In my programs, I have the following controller interface that my controllers inherit from:

public class IBaseController : Controller
    {    
        internal string PartialViewToString(string partialViewName, object model = null)
        {
            ControllerContext controllerContext = new ControllerContext(Request.RequestContext, this);

            return ViewToString(
                controllerContext,
                ViewEngines.Engines.FindPartialView(controllerContext, partialViewName) ?? throw new FileNotFoundException("Partial view cannot be found."),
                model
            );
        }

        protected string ViewToString(string viewName, object model = null)
        {
            ControllerContext controllerContext = new ControllerContext(Request.RequestContext, this);

            return ViewToString(
                controllerContext,
                ViewEngines.Engines.FindView(controllerContext, viewName, null) ?? throw new FileNotFoundException("View cannot be found."),
                model
            );
        }

        protected string ViewToString(string viewName, string controllerName, string areaName, object model = null)
        {
            RouteData routeData = new RouteData();
            routeData.Values.Add("controller", controllerName);

            if (areaName != null)
            {
                routeData.Values.Add("Area", areaName);
                routeData.DataTokens["area"] = areaName;
            }

            ControllerContext controllerContext = new ControllerContext(HttpContext, routeData, this);

            return ViewToString(
                controllerContext,
                ViewEngines.Engines.FindView(controllerContext, viewName, null) ?? throw new FileNotFoundException("View cannot be found."),
                model
            );
        }
        private string ViewToString(ControllerContext controllerContext, ViewEngineResult viewEngineResult, object model)
        {
            using (StringWriter writer = new StringWriter())
            {
                ViewContext viewContext = new ViewContext(
                    ControllerContext,
                    viewEngineResult.View,
                    new ViewDataDictionary(model),
                    new TempDataDictionary(),
                    writer
                );

                viewEngineResult.View.Render(viewContext, writer);

                return writer.ToString();
            }
        }
    }

Then, on your controller you can inherit from this interface like so:

public class ExampleController : IBaseController
{

}

Now, you can use the new methods to easily render your partial view to a string.

In your getDataBySelectedID action, this is what you'll want to do.

[HttpPost]
public JsonResult getDataBySelectedID(string selectedId)
{
    var que = test.getHello(selectedId);
    string partialViewString = PartialViewToString("MyPartialView", que);
    return Json(partialViewString, JsonRequestBehavior.AllowGet);
}

You may need to modify the above statement to fit your uses, but it should get you close.

4) Inject Partial View into Page on AJAX Success

Now, we've setup a Partial View to handle the model data that we want to update. We've updated our view to load from the Partial View by default. We've implemented a controller interface that will let use render that Partial View to a string so that we can inject it into our page. Now, we just need to do that injection.

First, wrap the previous setup @Html.RenderPartial() statement in a div. Let's give it the ID partialViewDiv. This will let us easily target it with jQuery.

 $(document).ready(function () {
     $("#ID").on("change", function () {
            var selectedId = this.value;
            var url = "/Sample/getDataBySelectedID";

            var $partialViewDiv = $('#partialViewDiv');

            $.ajax({
                method: "POST",
                dataType: "json",
                url: url,
                data: {
                    selectedId: selectedId
                }
            })
                .done(function (response, status, jqxhr) {
                   $partialViewDiv.html(response);
                   // Do any other updates here.
                })
                .fail(function (reponse, status, error) {
                    $partialViewDiv.html('');
                    // Handle your error here.
                });
        });
     });

Again, these is mostly pseudo-code so you may have to make some modifications. But, at this point, you should be roughly where you need to be. The AJAX call should update your view by reloading the partial view with your new model data.

Tips

  • Loading a partial view like this may break some jQuery event handlers, depending on your application. If that happens, take a look at this.
  • You can return any string from the Controller with your AJAX call. You could, if needed, return different partial views than what you originally loaded. Just use the methods from the interface and you can render whatever you need.

The above code is only some general guidelines. Without knowing your full implementation, I can't provide 100% working, bug free code. But, post here if you have any issues and I'll try to help.

Upvotes: 2

henkthefixer
henkthefixer

Reputation: 15

A solution i see is with php

location.reload();

That is how you reload but if you want to reload with data you could use something like

window.location.replace("PathToThePage.php?YourDataName=YourData");

Upvotes: 0

Related Questions