views:

309

answers:

4

I've got a nice MVC app running now, and I'm adding some AJax functionality. I have a table which displays 10 items, only certain users can see certain items. When the user adds a new post I've set-up the ajax to save the new entry.

However I then need to update the table, I cant find out from JQuery what status the user is (And hence what they can see) so I cant just insert a new row (As some users cant see that row). If this was web-forms I would likly have a page that dumps the table and then i would use JQuery to load the contents of that trimed down 'page' into the relevent slot on the current page.

Whats the best way to achieve this with MVC?

Thanks

+1  A: 

Use PartialView functionality that will return just the <table> you need. In your main page it will be included but in your Ajax call it will only emit HTML back to the client that you can use to replace existing <table> element.

Robert Koritnik
This seems to be what Im looking for. However how can I add a partial view to the page via Jquery AJAX whenever i try to navigate to a partial view i get the 404.THanks
Pino
A: 

If I understand you correctly, you're saying that user A is viewing a list of entries and user B (In some other part of the world. maybe) posts a new entry. You want the list on user A's screen to update, but only if the new entry is one that user A is allowed to see?

If this is the case, you can have a timer running on the page and, when the timer triggers, it causes an AJAX call to the server, asking if there are any new entries for the user. The identity of the user and - therefore - which items they can see, should be determined from the session (Exactly how this works depends on your particular architecture, but I'd guess that you're already doing this, to display the list of items for user A to start with)

There are all sorts of fine details to consider here...

  1. How often should the timer trigger, in order to get updates in a timely manner, but without causing too much traffic to the server
  2. Should you simply update the entire list (This makes the code simple) or should you only download new items (This makes the logic more complicated, but also keeps the traffic smaller)
  3. How do you ensure that you correctly identify the user, and correctly filter the entries to show only the relevant ones.

It's a relatively simple scenario - and ones that's no too uncommon - but it needs to be approached in a sensible manner to prevent complication setting in.

belugabob
A: 

It's not hard to add a cookie which will store the current status of the user, or you can simply add another Ajax call to find out whether the user is authorized or no. you simply create some items in your controller to handle all the situations: whether user is authorized or no, what you show/hide from them.

what exactly do you need thou?

ifesdjeen
+1  A: 

As @Robert Koritnik suggests, the best way to handle this is using a PartialView. I would suggest having two separate controller actions -- one that handles the original request and another that handles the AJAX new entry. Both actions would call the same logic to get the data for the table. The former would put the data into the view model along with other page data. The latter would package the data into a model for the partial view.

Model classes

public class PageViewModel
{
    ....
    public IEnumerable<TableViewModel> TableData { get; set; }
}

public class TableViewModel
{
    ...
}

Controller Code

[AcceptVerbs( HttpVerbs.Get )]
public ActionResult Index()
{
    var model = new PageViewModel();
    model.TableData = GetTableForUser( this.User );

    return View( model );
}

[AcceptVerbs( HttpVerbs.Post )]
public ActionResult AddEntry( ... )
{
    ...  add the new entry ...
    var model = GetTableForUser( this.User );

    return PartialView( "TableView", model );
}


private TableViewModel GetTableForUser( IIdentity user )
{
  ...
}

View Code

Main View

<% Html.RenderPartial( "TableView", model.TableData ); %>

<script type="text/javascript">
    $('#entryForm').submit( function() {
        $.post( '<%= Url.Action( "addentry", "controller" ) %>',
                $('#entryForm').serialize(),
                function(data) {
                   $('#table').replaceWith( data );
                },
                'html' );
        return false;
    });
</script>

TableView

<table id="table">
<% foreach (var row in Model) { %>
    <tr>
     ...
    </tr>
<% } %>
</table>
tvanfosson