Insert new rows into existing table on view - asp.net-mvc

This is my table in the view (cshtml) :
<table id="tblketquatk" class="thongke2socuoi">
<tbody>
<tr>
<th>Số</th>
<th>Ngày về gần nhất</th>
<th>Số lần xuất hiện</th>
<th>Số ngày chưa về</th>
</tr>
</tbody>
</table>
In the controller :
[HttpPost]//Run action method on form submission
public ActionResult LastTwoSubmit(string cityID, string numbers, int days, bool onlySpecial)
{
// get the result from sql server based on the parameters
// now i want to append the result to the table tblketquatk
return View();
}
Now I want to append the result to the table tblketquatk, is there anyway to do this without using Javascript?
I've done this before using JQuery, which will use Ajax to append the result into the exisiting table without reloading the page.
Link to JsFiddle for a better look.
What I want is how to insert the newly returned dataset into the table, and the parameters on the form remain unchanged/reset.
Any help is greatly appreciated!

You need models to bind to so that model can be returned to the view
public class SearchViewModel
{
public int Days { get; set; }
....
}
public class MainViewModel
{
public SearchViewModel Search { get; set; }
// Add a property for the collection of items you are rendering in the table
}
View
#model MainViewModel
#using (Html.BeginForm())
{
#Html.TextBoxFor(m => m.Search.Days)
....
<input type="submit" ... />
}
// add loop to create table rows
Controller
[HttpPost]
public ActionResult LastTwoSubmit(MainViewModel model)
{
// use the values of model.Search to query the database and add to the model collection
return View(model);
}
because you form properties are now bound to a model and your returning that model, the values will be retained when you return the view.

Related

Model send from PartialView to controller

I start work in asp.net-mvc and I have problem to send model from partialview to controller.
So first this is the way I create partialview
#Html.Partial("Weather", ShopB2B.Controllers.HomeController.GetWeather())
GetWeather() is controller metod that initializes first data to model. Model looks like this
public class Weather_m
{
public IEnumerable<SelectListItem> City_dropdown { get; set; }
public string Temperature { get; set; }
}
It is nesesery to DropDownListFor, and partialview looks like this
#model ShopB2B.Models.Weather_m
#using (#Html.BeginForm("GetWeatherNew", "Home", new { weather = Model }, FormMethod.Post))
{
<table>
<tr>
<td>#Html.DropDownListFor(x => x.City_dropdown, Model.Miasta_dropdown)</td>
</tr>
<tr>
<td>#Html.LabelFor(x => x.Temperature, Model.Temperatura)</td>
<td><<input type="submit" value="Send" class="submitLink" style=" height: 40px;" /></td>
</tr>
</table>
}
And here is problem because I want send this model to controller and then check which field is selected, add something, and send this model again to partialview. Any idea, how to do it?????
You really should not be getting the data for your ViewModel type on view rendering.
Your data is type of ShopB2B.Models.Weather_m. Your strongly typed partial view expects this, this is all good. But instead of getting your ShopB2B.Models.Weather_m instentiated with ShopB2B.Controllers.HomeController.GetWeather(), you should create a ViewModel and return it to your strongly typed view, say MyViewModel. This should wrap an instance of ShopB2B.Models.Weather_m. So in your main view, your view would be strongly typed for:
#model ShopB2B.Models.MyViewModel
and you render your partial view like
#Html.Partial("Weather", Model.MyWeather_m)
I usually wrap the partial view inside the form as well, like:
#using (#Html.BeginForm("GetWeatherNew", "Home", new { weather = Model }, FormMethod.Post))
{
#Html.Partial("Weather", Model.MyWeather_m)
}
Hope this helps.
You should define the property bind to Dropdown appropriately. Since, you have defined the city_dropdown defined as IEnumarable so model binding will fails while sending from data to server due to data type mismatch (at client side City_dropdown will be generated as string for select control). In this case, you should change the property of Model as follows.
public class Weather_m
{
public string City_dropdown { get; set; }
public string Temperature { get; set; }
}
And
#Html.DropDownListFor(x => x.City_dropdown, Model.Miasta_dropdown)

Implementing pagin / sorting / filtering in View with POST Form

I have an application in MVC 4 / C# / Visual Studio 2010 SP1. It is to create UI for storing collections of books. The information I want to store are: a name of a collection, a date on creation, and the list of books. A number of books is to be added from the database that stores all the books. Actually, another view is to edit books themselves.
So far, I have designed my View such that it shows form fields for name of collection and date on creation. But underneath I included list of all books to be selected.
Selecting them in the edit / create view means they are added to collection. I thought I could implement paging / sorting / filtering for the list of books as the number may become too large to show it on one page. My idea is to add PartialView with a list of books. The PartialView can be invoked by jQuery by .post() that is trggered by events like clicking on a page number, table column etc. The PartialView would store a page no., a sort criterium, filter criteria in some hidden fields and based on their values it would generate portion of the list. Hidden fields would be updated from the model but would also pass paging / sorting back to action.
I run into problem of how to put everything together in POST form. I would like a user to click page numbers while the previously selected books would still be selected. I don't know how to refresh a PartialView and keep books' state. I hope it is possible. If not, what would you recommend?
Thanks
Below is my application.
The model of a book:
// Entity
public class Book
{
public string Title { get; set; }
public string Author { get; set; }
public DateTime DatePublished { get; set; }
}
ViewModels:
// BookToSelect view model
public class BookToSelect : Book
{
public bool Isselected { get; set; }
public static IList<BookToSelect> MapBooksToBooksToSelect(IList<Book> list, bool isselected = false)
{
return list.Select(x => new BookToSelect() { //...})
}
public static IList<Book> MapBooksToSelectToBooks(IList<BookToSelect> list)
{
return list.Select(x => new Book() { //... })
}
}
// List of books view model
public class ListOfBooks
{
public IList<BookToSelect> Books { get; set; }
public DateTime DayOnCreationThe { get; set; }
public string CollectionName { get; set; }
public static IList<Book> GetListOfBooks()
{
return new List<Book>() {
// ... set of new Books() { },
};
}
}
Controller / Action:
public class TestCollectionController : Controller
{
[HttpGet, ActionName("Edit")]
public ActionResult Edit_GET()
{
ListOfBooks ViewModel = new ListOfBooks();
ViewModel.Books = ListOfBooks.GetListOfBooksToSelect();
ViewModel.DayOnCreation = DateTime.Today;
ViewModel.CollectionName = "List of random books";
return View(ViewModel);
}
[HttpPost, ActionName("Edit")]
public ActionResult Edit_POST(ListOfBooks ViewModel)
{
return View(ViewModel);
}
}
and View:
#using MvcDbContext.ViewModels
#model ListOfBooks
#{
ViewBag.Title = Model.CollectionName;
}
<h2>#Model.CollectionName</h2>
#using (Html.BeginForm())
{
#Html.EditorFor(m => m.CollectionName)
#Html.EditorFor(m => m.DayOnCreation)
<table>
<tr>
<th class="display-label">#Html.DisplayNameFor(m => m.Books.FirstOrDefault().Isselected)</th>
<th class="display-label">#Html.DisplayNameFor(m => m.Books.FirstOrDefault().Title)</th>
<th class="display-label">#Html.DisplayNameFor(m => m.Books.FirstOrDefault().Author)</th>
<th class="display-label">#Html.DisplayNameFor(m => m.Books.FirstOrDefault().DatePublished)</th>
</tr>
#for (int i = 0; i < Model.Books.Count(); i++)
{
<tr>
#Html.EditorFor(m => m.Books[i])
</tr>
}
<tr>
<td colspan="3"><input type="submit" name="SaveButton" value="Save" /></td>
</tr>
</table>
}
As you've already determined, if you switch out the HTML with the next page, all the inputs, included their state, are replaced as well. As a result, the only way to handle this is to offload the state into an input outside of the replacement.
The simplest way to handle this would most likely be creating a hidden input that will consist of a comma-delimited string of ids of selected items. Just add some JS that will watch the checkboxes or whatever and add or remove items from this hidden input. You can then just post this string back and use Split to turn it into a list of ids that you can use to query the appropriate books and add them to the collection on the entity.

ASP MVC3 - passing collection item into partial view

I have a view model that I've created with a collection (a List) of a separate model. In our database, we have two tables: BankListMaster and BankListAgentId. The primary key of the "Master" table serves as the foreign key for the Agent Id table.
As the Master/Agent ID tables have a one-to-many relationship, the view model I've created contains a List object of BankListAgentId's. On our edit page, I want to be able to both display any and all agent Ids associated with the particular bank, as well as give the user the ability to add or remove them.
I'm currently working through Steve Sanderson's blog post about editing a variable length list. However, it doesn't seem to cover this particular scenario when pulling existing items from the database.
My question is can you pass a specific collection item to a partial view, and if so how would you code that into the partial view correctly? The following code below states that
The name 'item' does not exist in the current context
However, I've also tried using a regular for loop with an index and this syntax in the partial view:
model => model.Fixed[i].AgentId
but that just tells me the name i does not exist in the current context. The view will not render using either method.
Below is the code from the view
#model Monet.ViewModel.BankListViewModel
#using (Html.BeginForm())
{
<fieldset>
<legend>Stat(s) Fixed</legend>
<table>
<th>State Code</th>
<th>Agent ID</th>
<th></th>
#foreach(var item in Model.Fixed)
{
#Html.Partial("FixedPartialView", item)
}
</table>
</fieldset>
}
Here is the partial view
#model Monet.ViewModel.BankListViewModel
<td>
#Html.DropDownListFor(item.StateCode,
(SelectList)ViewBag.StateCodeList, item.StateCode)
</td>
<td>
#Html.EditorFor(item.AgentId)
#Html.ValidationMessageFor(model => model.Fixed[i].AgentId)
<br />
Delete
</td>
And here is the view model. It currently initialized the Fixed/Variable agent Id lists to 10, however that is just a work-around to get this page up and running. In the end the hope is to allow the lists to be as large or small as needed.
public class BankListViewModel
{
public int ID { get; set; }
public string BankName { get; set; }
public string LastChangeOperator { get; set; }
public Nullable<System.DateTime> LastChangeDate { get; set; }
public List<BankListAgentId> Fixed { get; set; }
public List<BankListAgentId> Variable { get; set; }
public List<BankListAttachments> Attachments { get; set; }
public BankListViewModel()
{
//Initialize Fixed and Variable stat Lists
Fixed = new List<BankListAgentId>();
Variable = new List<BankListAgentId>();
Models.BankListAgentId agentId = new BankListAgentId();
for (int i = 0; i < 5; i++)
{
Fixed.Add(agentId);
Variable.Add(agentId);
}
//Initialize attachment Lists
Attachments = new List<BankListAttachments>();
Attachments.Add(new BankListAttachments());
}
}
The problem is with your partial view. In your main view, in the loop, you're passing a BankListAgentId object. However, your partial view's Model type is #model Monet.ViewModel.BankListViewModel.
Furthermore, you are trying to access a variable called item in your partial view, when none exist. Instead of using item to access your data, use Model like in any other view. Each view (even a partial one) has it's own Model type.
Your partial view should look something like this:
#model Monet.ViewModel.BankListAgentId
<td>
#Html.DropDownListFor(model => model.StateCode,
(SelectList)ViewBag.StateCodeList, Model.StateCode)
</td>
<td>
#Html.EditorFor(model => model.AgentId)
#Html.ValidationMessageFor(model => model.AgentId)
<br />
Delete
</td>
The model you are passing into the Partial View is a BankListAgentId--- because you are looping over a collection of them when you are creating the partial view.
You're doing everything right so far. You're looping through your list, call the partial for each list item and passing the item into the partial. It seems that the part you're missing is that when you pass the item into the partial, the item becomes the model for the partial. So you interact with it like you would in any other views, i.e. #Model.BankName, #Html.DisplayFor(m => m.BankName), etc.

MVC ASP.Net how do I add a second model to a view? i.e. Add a dropdown list to a page with a html grid?

I have been able to find lots of examples of adding a Dropdown list to a view but I need to add a dropdown list to a view that also has a Webgrid on it. This entails two different models and from what I see I can only have one per view.
The DDL will be filled from one model and the grid from the other.
I'm just trying to filter the displayed data in the grid with the data selected in the ddl.
Any examples or articles would be greatly appreciated.
TIA
Create a ViewModel that has the data for both your grid and your DropDownList. Use this ViewModel object as the model for your view.
See Steve Michelotti's post for different strategies on implementing the ViewModel pattern.
Something like this, for example:
public class MyViewModel
{
public List<Row> RowsForGrid { get; set; }
public SelectList ItemsForDropdown { get; set; }
}
Since you're trying to filter the displayed data in the grid, I'd do it this way:
In the main view I'd call a partial view. In your case the partial view will hold the DropDownList data. Something like this:
#Html.Partial("DropDownView", ViewBag.DropDownViewModel as DropDownViewModel)
In your controller action you'd fill the DropDownViewModel with the DropDownList data and would pass the DropDownViewModel to the ViewBag like this:
DropDownViewModel dropDownViewModel = new DropDownViewModel();
DropDownViewModel.Items = GetDropDownData(); // Fetch the items...
ViewBag.DropDownViewModel = dropDownViewModel;
ViewModel (DropDownViewModel.cs)
public class DropDownViewModel
{
public SelectList Items { get; set; }
}
Partial View (DropDownView.cshtml)
#model DropDownViewModel
#using (Html.BeginForm("YourControllerAction", "YourControllerName", FormMethod.Get))
{
#Html.Label("Search") #Html.DropDownList("YourDataId", Model.Items, String.Empty)
<input type="submit" value="Search" id="submit"/>
}
"YourDataId" will be a parameter for the action method and will contain the value selected by the user like this:
public virtual ActionResult Index(int? YourDataId, GridSortOptions sort)
{
...
}

Passing View Model to ASP.NET MVC 3 Edit Controller

When passing a view model (as below) to a view, how can I ensure that the checkboxes I'm creating (mapped to item "Product" in here) get passed back to the controller?
I've included my view model and "post" product controller below.
Unfortunately, when posted back to the controller, "Products" is null.
namespace MyProject.Models
{
public class ChartViewModel
{
public Chart ChartItem { get; set; }
public IEnumerable<Product> Products { get; set; }
}
}
Controller:
[Authorize]
[ValidateInput(false)]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(ChartViewModel objChartViewModel)
{
if (!TryUpdateModel(objChartViewModel))
{
return View(objChartViewModel);
}
else
{
} return View("Details", objChartViewModel);
}
How the checkboxes are added to my view, mapped to the "Product" object within my view model:
#{
foreach (MyProject.Models.Product objProduct in Model.Products)
{
#Html.CheckBox("product" + objProduct.Id, Model.ChartItem.ChartProducts.Select(t => t.ProductId).Contains(objProduct.Id));
#String.Format("{0} {1}", objProduct.Manufacturer.Name, objProduct.Name);<br />
}
}
You can send your lists (IEnumerable<T>) down to the view but when they don't come back up to the controller. The only properties of your ViewModel that have values are those with exactly matching items in the forms collection. So add a properties to your ViewModel like SelectedProductID.
This sets up a drop down list that sends its selected value back to the controller:
<div class="editor-field">
#Html.DropDownListFor(m => m.SelectedEmployeeID,
new SelectList(Model.EmployeeList, "EmployeeID", "EmployeeName"), "--Please select an Employee--")
#Html.ValidationMessageFor(model => model.SelectedEmployeeID)
</div>
Notice: the property being set is SelectedEmployeeID but this comes from the EmployeeList.
In your case the values many be in the collection (only "checked" checkboxes get sent in a post) so you could do:
string value = collection["myProductID"];
if its there its checked.
sorry for the messiness, this was in a bit of a rush. See this for more info:
MVC 3 form post and persisting model data

Resources