I have a view that the model is IEnumerable. the view is the mvc basic view that is created upon creating new controller with read write actions.
I do not want that the edit action will call a different view, i want to add a button in the index view that by pressing the button in a specific row the button will call the action result with the model that was "pressed" and from there the logic will continue.
The View
#model IEnumerable<V1_ILotto.Areas.Admin.Models.WithdrawalModel>
#{
ViewBag.Title = "בקשות משיכה";
}
<h2>בקשות משיכה</h2>
#using (Html.BeginForm("Approve", "Withdrawals", FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.User)
</th>
<th>
#Html.DisplayNameFor(model => model.WithdrawalAmount)
</th>
<th>
#Html.DisplayNameFor(model => model.Balance)
</th>
<th>
#Html.DisplayNameFor(model => model.IsApproved)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.User)
</td>
<td>
#Html.DisplayFor(modelItem => item.WithdrawalAmount)
</td>
<td>
#Html.DisplayFor(modelItem => item.Balance)
</td>
<td>
<p>
<input type="submit" value="Submit" />
</p>
</td>
</tr>
}
</table>
}
The Controller
[HttpPost]
public ActionResult Approve(WithdrawalModel withdrawalmodel)
{
if (ModelState.IsValid)
{
//logic for updating the db
return RedirectToAction("Index");
}
return View(withdrawalmodel);
}
Note : the view is in not getting a single model but IEnumerable of that model
only for helpers (except display) tie the data to the model. If you want data passed back you need to put your values in at least a hidden for
#Html.HiddenFor(x => x.Balance)
etc
Related
I am doing my first ever mvc application and I am kind of stuck. What I'm trying to do is filter the existing table based on the selection from the dropdown list.
I have a Course table and a Teacher table and I'd like to be able to filter the Courses by who is teaching them.
This is my controller so far:
namespace TTimetable.Controllers
{
public class CoursesController : Controller
{
private TimetabledbEntities db = new TimetabledbEntities();
// GET: Courses
public ActionResult Index(int teacher)
{
ViewBag.Teacher = new SelectList(db.Teacher, "teacher_Id", "lastName");
var course = db.Course.Include(c => c.Classroom).Include(c => c.Teacher);
return View(course.ToList());
}
This is my View:
#model IEnumerable<TTimetable.Models.Course>
#{
ViewBag.Title = "Courses";
}
<h2>Courses</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.name)
</th>
<th>
#Html.DisplayNameFor(model => model.course_start)
</th>
<th>
#Html.DisplayNameFor(model => model.course_end)
</th>
<th>
#Html.DisplayNameFor(model => model.Classroom.classroom_no)
</th>
<th>
teacher
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.name)
</td>
<td>
#Html.DisplayFor(modelItem => item.course_start)
</td>
<td>
#Html.DisplayFor(modelItem => item.course_end)
</td>
<td>
#Html.DisplayFor(modelItem => item.Classroom.classroom_no)
</td>
<td>
#Html.DisplayFor(modelItem => item.Teacher.firstName)
</td>
</tr>
}
</table>
<h2>Courses taught by:</h2>
#Html.DropDownList("Teacher", "Select teacher")
So far I was only able to make the dropdown list display the teachers from the database. Anyone who could help me with this? It'll be much appreciated. Thanks
You will need to have your dropdown list post back to the server. This can be accomplished by wrapping the dropdown in a form, and adding javascript to submit the form:
using (Html.BeginForm("Index", "Courses", FormMethod.Get))
{
Html.DropDownList("Teacher", ViewBag.Teacher, "Select teacher", new { onchange = #"form.submit();" });
}
Suggest you to use to Odata approach , when you have multiple filters , for a single table . It will be easy for you in the future.
http://www.c-sharpcorner.com/UploadFile/4d9083/creating-simple-cascading-dropdownlist-in-mvc-4-using-razor/
combining both the techniques can help you.
here viewbag should be casted as it is dynamic type object.
#Html.DropDownList("Teacher", (SelectList)ViewBag.Teacher, "Select teacher", new { onchange = #"form.submit();" });
hope it helps for your solution.
I have this partial View as below:
#model IPagedList<Student>
<h2>List of Students</h2>
<div id="studentList">
<div class="pagedList" data-uwa-target="#studentList">
#Html.PagedListPager(Model,page=>Url.Action("Index",new { page }),
PagedListRenderOptions.MinimalWithItemCountText)
</div>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.LastName) //here error
</th>
<th>
#Html.DisplayNameFor(model => model.FirstName) //here error
</th>
<th>
#Html.DisplayNameFor(model => model.City) //here error
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.City)
</td>
</tr>
}
</table>
<div class="row">
<div class="col-sm-6" id="slid">
<button id="export" class="btn btn-default btn-primary" onclick="location.href='#Url.Action("ExportInCSVFormat")';return false;">Export Student List in CSV Format</button>
</div>
<div class="col-sm-4" id="excelSlide">
<button id="excelExport" class="btn btn-default btn-success" onclick="location.href='#Url.Action("ExportStudentsInExel")';return false;">Export Student List in Excel Format</button>
</div>
</div>
My Index.cshmtl is :
#model IPagedList<Student>
#{
ViewBag.Title = "Index";
}
#Html.Partial("_Student", Model)
My StudentController is
public ActionResult Index(int page=1)
{
var model = dbAllStudents.Students
.OrderByDescending(p => p.LastName)
.ToPagedList(page, 10);
return View(model);
}
The problem happens to "#Html.DisplayNameFor(model => model.LastName)". It is saying that " IPaged does not contatin a definition for LastName.
I have an idea that the problem is caused because to the Index method of Student Controller I need to add .Select but I am not sure for that. I would really appreciate if someone can help me
It's not working, because overloaded method which you want to use doesn't fit with your interface. It's for IEnumerable<> types. You can access to the first element in the list and it should returns you correct value even if list is empty.
Change your table definition to:
<table class="table">
<tr>
<th>
#Html.DisplayNameFor( => Model[0].LastName)
</th>
<th>
#Html.DisplayNameFor(_ => Model[0].FirstName)
</th>
<th>
#Html.DisplayNameFor(_ => Model[0].City)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(_ => item.LastName)
</td>
<td>
#Html.DisplayFor(_ => item.FirstName)
</td>
<td>
#Html.DisplayFor(_ => item.City)
</td>
</tr>
}
</table>
and everything will be ok.
INSERT INTO SaleItem (ProdId, SaleQuantity) SELECT ProdId, BasketProdQuantity FROM Basket;
This is my SQL command and I want to use it with a button on a view. But I don't know how to references method with button on view. And should I use SqlConnection connection = new SqlConnection(connectionString) I already connect my DB with WebConfig and it connected as DefaultConnection.
EDIT:
I'm new at MVC and Web coding so I don't know what to do.
[HttpPost]
public ActionResult Buy(SaleItem saleitem)
{
if (ModelState.IsValid)
{
string query = "INSERT INTO SaleItem (ProdId, SaleQuantity) SELECT ProdId, BasketProdQuantity FROM Basket";
db.Database.ExecuteSqlCommand(query);
db.SaveChanges();
return RedirectToAction("Index", "Basket");
}
return View(saleitem);
}
and there is the view that I want to use buy method.
#model IEnumerable<VeriPark001.Models.Basket>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Product.Book.BookName)
</th>
<th>
#Html.DisplayNameFor(model => model.BasketProdQuantity)
</th>
<th>
#Html.DisplayNameFor(model => model.Product.ProdPrice)
</th>
<th>
Total
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Product.Book.BookName)
#Html.DisplayFor(modelItem => item.Product.MovieDVD.DVDName)
#Html.DisplayFor(modelItem => item.Product.MusicCD.CDName)
</td>
<td>
#Html.DisplayFor(modelItem => item.BasketProdQuantity)
</td>
<td>
#Html.DisplayFor(modelItem => item.Product.ProdPrice)
</td>
<td>
#(item.Product.ProdPrice * item.BasketProdQuantity)
</td>
<td>
<button>#Html.ActionLink("Delete", "Delete", new { id = item.BasketId })</button>
<button>#Html.ActionLink("Update quantity", "Edit", new { id = item.BasketId })</button>
</td>
</tr>
}
</table>
<p>
<button>I WANT TO CALL ACTION HERE. I search for how to do that and couldn't find a proper way.</button>
<button>#Html.ActionLink("Products", "Index", "Product")</button>
</p>
You can use Html.BeginForm and send a post request to your controller action.
Replace your
<p>
<button>I WANT TO CALL ACTION HERE. I search for how to do that and couldn't find a proper way.</button>
<button>#Html.ActionLink("Products", "Index", "Product")</button>
</p>
with
#using (Html.BeginForm("Buy", "YourController", FormMethod.Post))
{
// Input for your SaleItem model
<button class="btn btn-group btn-group-sm" type="submit">Submit</button>
}
Since your Buy action requires a SaleItem model I'll leave it up to you.
I keep getting an error message along the lines of:
..but this dictionary requires a model item of type..
My view I'm trying to put the partial view into is:
#using TheNovelMachine.Models
#model TheNovelMachine.Models.Account
#{
ViewBag.Title = "Details";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<img id="homeimage" src="~/Image/front-page-book.jpg" alt="The Novel Machine" />
<div id="text" class="col-lg-12">
<h1>Profile</h1>
<div class="col-lg-6 no-gutter">
<h2>#Html.DisplayFor(model => model.Username)</h2>
<h4>#Html.DisplayFor(model => model.FullName)</h4>
<p>#Html.DisplayFor(model => model.Email)</p>
</div>
<div class="col-lg-6 pull-right text-right no-gutter">
<img class="profilepic" src="~/Image/#(Html.DisplayFor(model => model.Username)).jpg" />
</div>
<div class="col-lg-12 no-gutter">
<hr/>
<h4>#Html.DisplayFor(model => model.Username)'s Novels</h4>
#{
Html.RenderPartial("~/Views/Shared/_NovelProfile.cshtml");
}
</div>
</div>
And the Partial View is:
#using System.Web.DynamicData
#using TheNovelMachine.Models
#model IEnumerable<TheNovelMachine.Models.Novel>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Title)
</th>
<th>
#Html.DisplayNameFor(model => model.Genre)
</th>
<th>
#Html.DisplayNameFor(model => model.Abstract)
</th>
<th>
#Html.DisplayNameFor(model => model.Privacy)
</th>
<th>
#Html.DisplayNameFor(model => model.AccountId)
</th>
</tr>
#foreach (var item in Model.Where(i => i.AccountId.ToString() == Url.RequestContext.RouteData.Values["id"].ToString())) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.Genre)
</td>
<td>
#Html.DisplayFor(modelItem => item.Abstract)
</td>
<td>
#Html.DisplayFor(modelItem => item.Privacy)
</td>
<td>
#Html.DisplayFor(modelItem => item.AccountId)
</td>
</tr>
}
</table>
Your partial view is expecting this model (you are declaring it at the top of you partial view)
#model IEnumerable<TheNovelMachine.Models.Novel>
You should pass that model in this line:
#{
Html.RenderPartial("~/Views/Shared/_NovelProfile.cshtml", Model.Novels);
}
That should work, assuming Model.Novels is of this type IEnumerable<TheNovelMachine.Models.Novel> or it can be converted to that type.
Here you have an example with more details, but the idea is the same. If you don't pass this as a parameter, then the partial view can't be constructed (that's why you are getting that error).
MSDN Documentation here for RenderPartial method.
So even though there are other answers as to what you need to do, here is what is actually happening, so you know in the future.
#Html.RenderPartial("_NovelProfile");
would be the same code as:
#Html.RenderPartial("_NovelProfile", Model)
So, I am new to MVC, and I have a partial view with IEnumerable model, in which I have few fields I would like to be editable.
#model IEnumerable<Allocations>
<p>
#Html.ActionLink("Create New", "AddAllocation", "Admin")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Description)
</th>
<th>
#Html.DisplayNameFor(model => model.Percentage)
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
#Html.EditorFor(modelItem => item.Percentage)
</td>
<td>#Html.HiddenFor(modelItem => item.ID)</td>
<td>
#Html.ActionLink("Save", "EditAllocation", "Admin", null, new { id= item.ID })
</td>
</tr>
}
</table>
I want to be able to pass the entered/changed textbox values to the controller action. I understand, I can do that using JQuery if it wasn't a IEnumerable model view. I might be missing something here, and would appreciate if someone could direct me in the right direction.