0

I am trying to build a page with list of users. The goal is, that when you click "Details" link in the row, I would like to render partial view in the page using javascript or jQuery, So I dont need to reload the page. I have found many solutions (for example this), but I cant get it working, since I know next to nothing about javascript at the moment so I dont know how to connect what i found to code I have.

This is my partial view (i am not sure if it is correct as I wasnt able to even try to render it so far):

@model AdminDMS.Models.User

<h2>Details</h2>

<fieldset>
    <legend>User</legend>

    <div class="display-label">
         @Html.DisplayNameFor(model => model.Guid)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Guid)
    </div>

    <div class="display-label">
         @Html.DisplayNameFor(model => model.TrusteeType)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.TrusteeType)
    </div>

    <div class="display-label">
         @Html.DisplayNameFor(model => model.Username)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Username)
    </div>

    <div class="display-label">
         @Html.DisplayNameFor(model => model.Email)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Email)
    </div>

    <div class="display-label">
         @Html.DisplayNameFor(model => model.LastLogin)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.LastLogin)
    </div>

    <div class="display-label">
         @Html.DisplayNameFor(model => model.PasswordChanged)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.PasswordChanged)
    </div>

    <div class="display-label">
         @Html.DisplayNameFor(model => model.IsUsingTempPassword)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.IsUsingTempPassword)
    </div>
</fieldset>`

I am using async controller, these are my Details async actions:

    public void DetailsAsync(Guid guid)
    {
        if (userList == null || DateTime.Now > lastUpdate.AddMinutes(5))
        {
            AsyncManager.OutstandingOperations.Increment();
            client.GetUsersAsync();
            lastUpdate = DateTime.Now;
            AsyncManager.Parameters["guid"] = guid;
        }
    }

    public ActionResult DetailsCompleted(IEnumerable<AdminDMS.Models.User> users)
    {
        if (userList == null || !userList.Equals(users))
            userList = users.ToList<AdminDMS.Models.User>();
        return PartialView("Details", users.Single(user => user.Guid == (Guid)AsyncManager.Parameters["guid"]));
    }

And this is the view:

@model List<AdminDMS.Models.User>

@{
    ViewBag.Title = "Users";
}

<h2>Users</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            Guid
        </th>
        <th>
            Username
        </th>
        <th>
            Email
        </th>
        <th>
            TrusteeType
        </th>
        <th>
            Last Login
        </th>
        <th>
            Last Password Change
        </th>
        <th>
            Temporary Password
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Guid)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Username)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Email)
        </td>
         <td>
            @Html.DisplayFor(modelItem => item.TrusteeType)
        </td>
         <td>
            @Html.DisplayFor(modelItem => item.LastLogin)
        </td>
         <td>
            @Html.DisplayFor(modelItem => item.PasswordChanged)
        </td>
         <td>
            @Html.DisplayFor(modelItem => item.IsUsingTempPassword)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { item.Guid }) |
            @*@Html.ActionLink("Details", "Details", new { item.Guid })*@ |
            @Html.ActionLink("Delete", "Delete", new { item.Guid })
        </td>
    </tr>
}

</table>

<div class="detailsDiv">

</div>

I would like to replace that commented out action link with something, that will render the partial view in "detailsDiv" div that is left empty at the end.

Thanks in advance

UPDATE:

My controller now has this action

public PartialViewResult Details(Guid guid)
        {
            AdminDMS.Models.User user = null;
            UserService.User serviceUser = client.GetUsers().Single(u => u.Guid == guid);
            user = new AdminDMS.Models.User(serviceUser.Guid, serviceUser.TrusteeType, serviceUser.Username, serviceUser.Email, serviceUser.LastLogin, serviceUser.PasswordChanged, serviceUser.IsUsingTempPassword);
            return PartialView("_detailsPartial", user);
        }

_detailsPartial is the detail view (that hasnt changed at all)

this is the current call to controller in view:

@Ajax.ActionLink("Details", "Details", item, new AjaxOptions { UpdateTargetId = "detailsDiv", InsertionMode = InsertionMode.Replace})

This is the div I want to update:

<div id="detailsDiv">

</div>

There is nothing else in the view after this div.

Current result is that the link will open new page in the window and renders partial view (with item details as content)

Community
  • 1
  • 1
Erchi
  • 139
  • 1
  • 12

2 Answers2

0

I suppose the most appropriate thing to use for rendering just a part of the page is AJAX. http://en.wikipedia.org/wiki/Ajax_(programming) Honestely I'm not a pro in Asp.net but I suppose there is a tool kit that does the trick. http://www.asp.net/ajaxlibrary/AjaxControlToolkitSampleSite/

MarGa
  • 711
  • 3
  • 10
  • 23
  • I will definitely check it out, thanks. However I already tried to utilize some samples and I always end up with the code displayed as text or error or something. So I really need to see how should I do it in my code. – Erchi Apr 23 '13 at 08:49
  • See the answer below - currently the problem is that instead of updating div with partial view (first block of code) it opens a page using that partial wiev – Erchi Apr 23 '13 at 12:38
0

I always use this to render a partial view with ajax, this works, if you have any other problems, it is something else :)

@Ajax.ActionLink("blabla", "DetailsCompleted", new { Users= "add users here" }, new AjaxOptions { UpdateTargetId = "detailsDiv"})

EDIT: CONTROLLER action

public PartialViewResult yourpartialname("data here")
{
    "get your data
    return PartialView(data);
}

EDIT 2:

You can do this:

@Ajax.ActionLink("Details", "Details", new {item = item.Guid}, new AjaxOptions {      UpdateTargetId = "detailsDiv", InsertionMode = InsertionMode.Replace}) 

I know this will work, but I don't know if it's a big difference (I'm not that pro either :)), again, I don't know if its a big difference but you can change your partialview result to this:

public PartialViewResult DetailsPartial(Guid item)
    {
        AdminDMS.Models.User user = null;
        UserService.User serviceUser = client.GetUsers().Single(u => u.Guid == guid);
        user = new AdminDMS.Models.User(serviceUser.Guid, serviceUser.TrusteeType, serviceUser.Username, serviceUser.Email, serviceUser.LastLogin, serviceUser.PasswordChanged, serviceUser.IsUsingTempPassword);
        return PartialView(user);
    }

Where DetailsPartial is the name of your partial view You can try this, I would do it this way, else I don't see any problems with your code

LAST EDIT

</footer>
@Scripts.Render("~/bundles/jquery")
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
@RenderSection("scripts", required: false)
</body>
</html>
Dylan Slabbinck
  • 846
  • 1
  • 16
  • 27
  • Now I have problems with asynchronous calls :) the link on the Ajax element looks ok, so I will try to create synchronous version first. – Erchi Apr 23 '13 at 12:16
  • I tried this: ´@Ajax.ActionLink("Details", "Details", item, new AjaxOptions { UpdateTargetId = "detailsDiv"})´ Result being that instead staying on the page and updating div i get redirected to page with partial view (which displays proper data) – Erchi Apr 23 '13 at 12:24
  • you should use in you controller also Partialviewresult instead of Actionresult, if you use this ajax.actionlink – Dylan Slabbinck Apr 23 '13 at 12:30
  • I changed the action to return PartialViewResult, but clicking on the link still opens the result instead of putting it in the div. – Erchi Apr 23 '13 at 12:43
  • You need to add the id="detailsDiv" to the div, it won't work as class, maby that's your problem – Dylan Slabbinck Apr 23 '13 at 12:47
  • I already noticed that and changed it, fixing it had no effect. – Erchi Apr 23 '13 at 12:51
  • I'm out of suggestions, maby you can post your updated controller/view, maby then I know how to fix it :) – Dylan Slabbinck Apr 23 '13 at 13:00
  • seems like comments are not the best place for longer code, will update original question – Erchi Apr 23 '13 at 13:08
  • Done. I suspect it will have something to do with fact I am not passing guid to the action (maybe I shouldn pass guid to it). – Erchi Apr 23 '13 at 13:13
  • I tried passing guid instead of whole item ( item = user in this case). No change in bahevior... – Erchi Apr 23 '13 at 13:29
  • what about the partialview thing, check my answer, I've updated it – Dylan Slabbinck Apr 23 '13 at 13:36
  • If I use that one, It will still open the link in current window, but it seems to use my regular View (I have "Detail" view which is regualr stuff and "_detailPartial" view) – Erchi Apr 23 '13 at 14:15
  • Hey man, just to be sure, are you loading this, (in your layout.cshtml), it should be in your body, under the footer – Dylan Slabbinck Apr 24 '13 at 12:36
  • I didnt. Putting it into _Layout.cshtml didnt work though. I think I will give up on this for some time, I must be doing some stupid mistake somewhere, hopefuly I will discover it when building the application (this was just prototype - a sample). – Erchi Apr 24 '13 at 12:56
  • Check my last edit, It should work when you put it in the right place – Dylan Slabbinck Apr 24 '13 at 13:39
  • You are right, it works! I was right too, I made a stupid mistake - I did have those three lines in the code in footer section, but in incorrect order and that caused problems (I had ` – Erchi Apr 25 '13 at 07:27