Build table using partial view with Ajax requests - asp.net-mvc

I need to dynamically create (insert) a new table row every time user presses button (using Ajax). My partial view structure:
<tr>
<td><td>
<td><td>
...
</tr>
When I need insert new row at the end I can do something like this:
element_table.innerHTML += ajax_data
But what I must do when I need to place it between other rows?
I can return only [td] elements and wrap them in [tr] clientside created element (tr.innerHTML = ajax_data) but I don't think this is a good idea.
Any ideas?
Are there any common practises?

The easiest way is to use jQuery with your Ajax response. It can be as simple as
$('#table').append(response)
to append a row. It's also possible to insert the new row at a specific index:
$('#my_table > tbody > tr').eq(index).after(response);
Note that index is 0 based.

Related

How does a clickableRow work with passing data in asp.net mvc

I have a view that will display a table and each row in the table is setup as a "clickableRow" which I point to a controller which will point to the new view, my question is how do I pass the information from that clickable row so I can utilize it in the next view/controller.
For example:
foreach (var item in Model.results)
{
Html.AntiForgeryToken();
<tr class="clickableRow" onclick="location.href='#Url.Action("InstructorCourseDetailView", "Course")'">
<td>#Html.Encode(item.courseName)</td>
<td>#Html.Encode(item.courseNumber)</td>
<td>#Html.Encode(item.courseInstructor)</td>
<td>#Html.Encode(item.courseSchedule)</td>
</tr>
}
I want to take that particular item and pass it to a view that will display all of that particular course's information which was found with a database query. I would think it would do something with passing that course's "courseID" to the controller..
I'm just not sure how this works or if there is maybe a better way to do this.
You can pass a third parameter to the Url.Action, it will contains the data that you would like to send to the next control.
#Url.Action("InstructorCourseDetailView", "Course", new { item.courseID })

Nested Datatables Single Row Selection

I have multiple datatables whose are in single selection mode. I know how many datatables I have and how to reference to them because I append an index to their widgetVar attribute. So I can reference them by the "non-safe" operation var dt = eval('dt' + index).
The issue I am facing is every time I select a row in one of the nested dataTables the selection is remaining on the other ones and I want to clean them.
I've tried something like:
<p:ajax event="rowSelect" onstart="deseleccionarTablas()"/>
function deseleccionarTablas()
{
for (i=0; i < dtEstacionesSeleccionadas.getPaginator().cfg.rows; i++)
{
var dt = eval('dt' + i);
dt.unselectAllRows();
}
};
dtEstacionesSeleccionadas is the "container" or "root" table and works in "lazy" mode with paginator, so a variable number of nested dataTables may be shown. The code above doesn't work because it unselects everything, even the last row I selected, as expected. And I want that last one to remain selected.
Any ideas? Thank you.
Instead of using JavaScript, why don't you update them on the server side? Each table should have the selection="#{mrBean.selectedRow}" attribute. You only need to set all of those things to null in the actionListener of the <p:ajax event="rowSelect">. Then, a simple update="table1 table2 ... tablen" will solve you problem.

asp.net mvc: What is the correct way to return html from controller to refresh select list?

I am new to ASP.NET MVC, particularly ajax operations. I have a form with a jquery dialog for adding items to a drop-down list. This posts to the controller action.
If nothing (ie void method) is returned from the Controller Action the page returns having updated the database, but obviously there no chnage to the form. What would be the best practice in updating the drop down list with the added id/value and selecting the item.
I think my options are:
1) Construct and return the html manually that makes up the new <select> tag
[this would be easy enough and work, but seems like I am missing something]
2) Use some kind of "helper" to construct the new html
[This seems to make sense]
3) Only return the id/value and add this to the list and select the item
[This seems like an overkill considering the item needs to be placed in the correct order etc]
4) Use some kind of Partial View
[Does this mean creating additional forms within ascx controls? not sure how this would effect submitting the main form its on? Also unless this is reusable by passing in parameters(not sure how thats done) maybe 2 is the option?]
UPDATE:
Having looked around a bit, it seems that generating html withing the controller is not a good idea. I have seen other posts that render partialviews to strings which I guess is what I need and separates concerns (since the html bits are in the ascx). Any comments on whether that is good practice.
look at the ContentResult you can specify the mime type of what you return (text/html)
You could alternatively make a control that take a IEnumerable of whatever you put in the selectlist, and build it using the view engine. That way you keep the formatting of the html (in this case a list of options) into a view, and not in your code.
<%# Control Language="C#"Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Article>>"%>
<%foreach (var article in Model){%>
<option><%:article.Title %></option>
<%} %>
I think I would go for that second one
From what I understood, the jQuery dialog contains a form that, when submitted, will post to an action which updates the database with some information. You want to get the newly added database information and update the same form that was used to trigger the database update.
If that is the case, then I think the best clean and logical option is to return JSON serialization of the items to be put in the drop down right after you update the database. Then, using jQuery, you would clear the drop down and append option tags into it.
You can also write a new, seperate action that returns the JSON serialization of the database objects you need. You would have jQuery call another post to this action as a callback to your first ajax post (the one used to update the database).
Here is a quick snippet
public ActionResult UpdateDatabase(string something)
{
/// update the database
IEnumerable<Items> items = getItemsFromDatabase(); // or w/e
var vals = items.Select(x=> new { value = x.ID, text = x.Name }); // something similar
return Json(vals);
}
Personally, I would write a separate function that returns JSON. This ensure separation of concerns, and gives me a function I can use in many different places.
Returning a JsonResult with all the items is the most versatile and least-bandwidth intensive solution as long as you are happy to iterate through the list in jQuery and update your drop-down list.
Using a partial view is nice for HTML that you can .load(...) directly into your select, but less versatile.
I would go with the JsonResult.
In your Controller:
public JsonResult UpdateItem(string sItem)
{
// 1. Insert new item into database if not exist...
// {update code here}
// 2. retrieve items from database:
IEnumerable<Item> Items = GetItems();
// 3. return enumerable list in JSON format:
return new JsonResult{ Data = new {Items = Items, Result = "OK" }};
}
On client-side:
Iterate through Items array and add the items to your list.

What's the best way to respond to checkbox clicks on an MVC list view?

I've got a list view in my MVC app that shows a check box next to each entry:
<% For Each item In Model%>
<%=Html.CheckBox("Selected", item.select_flag, New With {.onclick = "this.form.submit();"})%>
<%=Html.Hidden("ID", item.id)%>
<%=item.name%>
<br/>
<% Next%>
As you can tell from the onclick, I'm submitting the form each time a user clicks a check box. In the controller, my post action looks like this:
<AcceptVerbs(HttpVerbs.Post)> _
Function List(ByVal Selected() As Boolean, ByVal ID() As String) As ActionResult
For i = 0 To ID.Count - 1
If Selected(i) Then
[use ID(i) to update a database row]
End If
Next
Return View(GetTheListOfNamesAndIds())
End Function
So I get an array of Selected values and ID's after each checkbox click. I assumed they would correspond, but I'm finding the two arrays to be out of sync for some reason. It's also a lot of overkill to process the whole list every time a checkbox is clicked, so I'd like to revisit this whole setup.
What's the best way to set this up so that clicking a checkbox will update a specific database row? Can it be done without reloading the list each time?
Consider wrapping each "row" in it's own AjaxForm or using jQuery to do the update via AJAX, then passing the data required for the action via the route values (or form values) in the AJAX get/post. The AjaxForm will want to update some DOM element with new content, but you could get around this by having it update an error message (with nothing if there is success) rather than the actual row and doing any local changes via javascript. With jQuery AJAX you have a lot more options of how you want to handle it but you may have to implement more code on the client side.

Replacing a <tr> using ASP.MVC Ajax

I have the following ajax form tag:
When the form is submitted, the controller returns a partial with a full row to be inserted into the table (the same partial is also used to render the table in the first place).
The idea is that after the user edits an item, the item's row in the table will be replaced with the updated version from the partial. When I point UpdateTargetId to a <div> element it seems to work fine, but when I point it to a <tr> element, it doesn't.
Any help would be greatly appreciated.
I'm assuming that your partial actually renders the entire row. In that case, the default replacement semantics won't work for the <tr> element since you'll be inserting a new row into the existing row and get something like:
<tr><tr>...new contents</tr></tr>
You might want to look at changing the InsertionMode (I forget the other potential options) or having your partial generate just the row contents, i.e., the <td> elements instead of the row itself.
I ended up changing my approach. I changed the controller to return the values of the object in jason and had the view's js function simply update the content of the table row with the new values. Seems to work fine now.
Rich Strahl has an excellent post on how to do Client Templating with jQuery.

Resources