Creating your own table with CommandArgument buttons in ASP.NET MVC - asp.net-mvc

I'm trying to implement something like this:
<div>
<table>
<thead>
<tr>
<td>Port name</td>
<td>Current port version</td>
<td>New port version</td>
<td>Update</td>
</tr>
</thead>
<% foreach (var ip in Ports) { %>
<tr>
<td>
<%= ip.PortName %>
</td>
<td>
<%= ip.CurrentVersion %>
</td>
<td>
<%= ip.NewVersion %>
</td>
<td>
<asp:Button ID="btnUpdate" runat="server" Text="Update" CommandArgument="<% ip.PortName %>" />
</td>
</tr>
<% } %>
</table>
</div>
The button's CommandArgument property is where my code complains about not being able to resolve symbol ip. Is there any way to do what I'm trying to do?
­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

You don't want to use a Webforms button in ASP.NET MVC. MVC is a completely different way of working, and you no longer have the WebForms abstraction.
You have 2 different options you can either replace your asp:Button with an input tag or use a standard hyperlink instead. If you use the input option then you will need to wrap in a form element. The form action should point to a Controller action.

You can't use webform controls in ASP.NET MVC in a trivial manner because they rely on things that are stripped out in MVC. Instead you add a button in two ways, both using the HtmlHelper on the ViewPage:
You can add a button in a form, which is easily handeled in a controller if you have a form for each single button:
<% using(Html.BeginForm("Update", "Ip", new {portName = ip.PortName} )) { %>
....
<input name="action" type="submit" value="Update">
<% } %>
BeginForm() will default to the same controller and action as the view was created from. The other way is to add a link instead, which is more fitting to your example of iterating through a list. For example lets say you have IpController
<%= Html.ActionLink("Update IP", "Update", "Ip",
new {
portName = ip.PortName
})
%>
The link will go to the Update action in IpController with the given portName as parameter. In both cases you'll need this action in IpController:
public ActionResult Update(string portName) {
// ...
}
Hope this helps.

I think you have to enclose your block in Form tags ans runat=server.

FWIW,
I think this text is missing an equals sign:
CommandArgument="<% ip.PortName %>"
Should be
CommandArgument="<%= ip.PortName %>"

Related

Make a ASP.Net MVC Site, filtering the content

I recently started an MVC project to query and to report the company's users, everything seemed to be fine, except when I made a finduser form, I got all stuck!
you see I want the operator to be able to find the appropriate user by entering either hos pin,serial or calling number but the action links I make for the search operation all fail because they are made at the form_load time and so the empty string of text boxes get injected to them.
So my requests are:
How to make this filters work.
Now a little Ajax textbox suggester on user pin or serial would be great, please gimme a hint or two.
<table>
<tr>
<td>
PIN:</td>
<td>
<asp:TextBox ID="txt_pin" runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<td>
Serial Number:</td>
<td>
<asp:TextBox ID="txt_sn" runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<td>
CallingNumber:</td>
<td>
<asp:TextBox ID="txt_callingNo" runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<td>
CalledThisNumberToday:</td>
<td>
<asp:TextBox ID="txt_calledNo" runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<td>
</td>
<td>
</td>
</tr>
<tr>
<td>
</td>
<td>
</td>
</tr>
</table>
<%:Html.ActionLink("Search for user", "Details", new { pin = txt_pin.Text })%>
<asp:TextBox>? In an ASP.NET MVC application? I am afraid you got it all wrong.
I would recommend you going through the getting started tutorials here in order to learn the basic concepts of ASP.NET MVC: http://asp.net/mvc
In ASP.NET MVC you use models and in the views you use helpers in order to generate input fields.
So in your case you could design a view model:
public class SearchViewModel
{
public string Pin { get; set; }
public string SerialNumber { get; set; }
public string CallingNumber { get; set; }
public string CalledThisNumberToday { get; set; }
}
then you could design a controller action which will pass this view model to the view for rendering the search form:
public ActionResult Index()
{
var model = new SearchViewModel();
return View(model);
}
and finally in your strongly typed view you would use HTML helpers:
<%# Page
Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<AppName.Models.SearchViewModel>" %>
<asp:Content ID="MainContent" ContentPlaceHolderID="MainContent" runat="server">
<%= Html.ValidationSummary() %>
<% using (Html.BeginForm()) { %>
<div>
<%= Html.LabelFor(x => x.Pin) %>
<%= Html.EditorFor(x => x.Pin) %>
</div>
<div>
<%= Html.LabelFor(x => x.SerialNumber) %>
<%= Html.EditorFor(x => x.SerialNumber) %>
</div>
<div>
<%= Html.LabelFor(x => x.CallingNumber) %>
<%= Html.EditorFor(x => x.CallingNumber) %>
</div>
<div>
<%= Html.LabelFor(x => x.CalledThisNumberToday) %>
<%= Html.EditorFor(x => x.CalledThisNumberToday) %>
</div>
<p><input type="submit" value="Search for user" /></p>
<% } %>
</asp:Content>
and the final step would be to implement the controller action that will perform the search and to which this form will be subimtted:
[HttpPost]
public ActionResult Index(SearchViewModel model)
{
if (!ModelState.IsValid)
{
// the model was not valid => redisplay the form
// so that the user can fix his errors
return View(model);
}
// TODO: perform the search
...
}
Along with Darin's excellent answer (which you really need to follow in order to do things the "MVC" way...), you can also do AJAX filtering on a table using jQuery. There's even a plugin for jQuery that makes live table filtering as simple as adding a script reference and a textbox, then a couple lines of Javascript code to wire up the search. This will end up looking something like this:
<script language="javascript" type="text/javascript" src="/Scripts/jquery.js"></script>
<script language="javascript" type="text/javascript" src="/Scripts/jquery.uitablefilter.js"></script>
<script language="javascript" type="text/javascript">
$(document).ready(function () {
$("#myFilter").keyup(function () {
$.uiTableFilter($("#myTable"), $(this).val());
});
});
</script>
<input type="text" id="myFilter" />
<table id="myTable">
...
</table>
As you start typing in the filter box, the table will be automatically filtered to only show rows that contain the specified value.
As for auto-complete suggestions, you might want to look into jQUery UI - they've got
support for auto-complete using several different mechanisms to provide the hint values.

asp.net mvc calling different usercontrol from different view

I Have a View Folder
FrontEnd
JobDetails.ascx (View)
Another View Folder
Job
Apply.ascx (view)
I have a Apply (a href) in jobdetails which have a show and hide div mechanism for apply (Rendering Apply.ascx in JobDetails
<div id="div1" style="visibility:hidden">
<% Html.RenderPartial("../../Views/Jobs/Create"); %>
</div>
my create View in job
<% using (Html.BeginForm("Create", "Jobs", FormMethod.Post, new { enctype = "multipart/form-data" }))
{%>
<%: Html.ValidationSummary(true) %>
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td></td>
</tr>
<tr>
<td>
<% } %>
the question is that how would i go back in the JobDetails View if some Error occurs in my create form to display the errors there . I am at lost here , hope that the question is clear enough.
Probably the simplest way to handle this is to do the post of the apply via AJAX and simply render the apply form with the errors in place by replacing the existing HTML with that returned when the apply fails. If javascript is turned off, then it will render just the failed application but that seems like a reasonable trade-off to me.

ASP.NET MVC - PartialView not refreshing

I have a user control: VendorDDL.ascx, with the following code:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<List<MeetingCalendar.Models.Vendor>>" %>
<table>
<tr>
<th></th>
<th>
VendorId
</th>
<th>
VendorName
</th>
</tr>
<% foreach (var item in Model) { %>
<tr>
<td></td>
<td>
<%= Html.Encode(item.VendorId) %>
</td>
<td>
<%= Html.Encode(item.VendorName) %>
</td>
</tr>
<% } %>
</table>
My view: Create.aspx, has the following code snippet:
<p>
<label for="VendorNameSearch">Vendor Name:</label>
<input type="text" name="VendorNameSearch" id="VendorNameSearch" style="width:100px" />
<input type="submit" value="search" />
</p>
<% Html.RenderPartial("VendorDDL", MeetingCalendar.Controllers.HomeController.VendorsToSelect); %>
And everything works fine when I load up the Create view. The VendorDDL control is populated with the default values that are found in the VendorsToSelect. My controller has a List<Vendor> VendorsToSelect, which is getting updated properly.
Here is the problem: when the user clicks the SEARCH button, this fires off code in the Controller: return PartialView("VendorDDL", VendorsToSelect); I can see that VendorsToSelect is getting populated correctly based upon the user search.
I can step through the code, line-by-line, and see that immediately after return PartialView("VendorDDL", VendorsToSelect);, the debugger goes directly to the VendorDDL.ascx, and I can see that the Model is properly populated with the new VendorsToSelect, and the item.VendorId and item.VendorName are showing the correct values. But when debugging is done, and the Create view is shown, the VendorDDL control is not showing the new data.
Any suggestions?
I think that the output of your controller is discarded because the view (Create) has the same Html.RenderPartial("VendorDDL", MeetingCalendar.Controllers.HomeController.VendorsToSelect) as during initial load.
If I understand your problem correctly (and admittedly, without looking at the controller I may not) - you need to pass the model dynamically. The simplest (but not the most efficient) way would be to have jquery call $.load("/Home/VendorDDL") that would populate with the whole model; and then on submit hijax the form and pass form data to the same controller action.

Editable "GridView" like control in ASP.NET MVC

I'm trying to build a Editable GridView like control (Order column) with this code in the view:
<table>
<tr>
<th>
Name
</th>
<th>
Order
</th>
<th>
<img alt="Save order" src="<%= Url.Content("~/Content/minisave.png") %>" />
</th>
<th></th>
</tr>
<% foreach (var item in Model) { %>
<tr>
<td>
<%= Html.Encode(item.Name) %>
</td>
<td colspan="2">
<%= Html.TextBox("Order", item.Order, new { size = "3" }) %>
</td>
<td>
<%= Html.ActionLink("Edit", "Edit", new { id=item.id }) %> |
<%= Html.ActionLink("Details", "Details", new { id=item.id })%>
</td>
</tr>
<% } %>
</table>
The result table look like:
The questions are: How I receive this data in my controller? I need a form tag around the table? How I know which Order value belongs to which record?
A couple extra questions: If you see the code I add the size attribute to the input tab but when the browser renders it, the input is larger, how can I fix it?
Thanks for your help!
I've done this before. I did it by having the ID as part of the name, and a form around the entire table. That way the controller pulled all the data from all the rows and updated it all at once like a spreadsheet.
That works well for a unit of work, where you edit the page and save it, though of course you'd need to consider how to cope with your locking strategy, be it optimistic or pessimistic.
However, these days a better alternative might be to use ajax to submit specific values, somewhat like Google Spreadsheet, maybe?

How to select and pass data from the view

I'm starting to develop in ASP.NET and I can't find any example of a very simple use-case:
I've got some model objects displayed on a view.
I added a checkbox so that the user can choose the one he/she wants to see.
Then the user clicks on a link and he/she should see the model objects he/she selected displayed in another view.
1) What's the best way to get the selected items list?
At the moment I decorated my model with an IsSelected property because that's what I'd do in a ViewModel but that may not be the right answer.
2) How to pass the selected data to the next controller?
In all the examples that I've seen, data is "hardcoded" in the link and is per-object.
I haven't seen any example of a user-selection in any sample from the ASP MVC site.
EDIT: I'm afraid it wasn't that clear. What I've got is that:
<table style="width: 100%;">
<% foreach (Vehicle vehicle in Model)
{ %>
<tr>
<td>
<% 'Here be bound checkbox' %>
</td>
<td>
<%= Html.ActionLink("Show", "Index", "Map", vehicle.Name, null) %>
</td>
<td >
<%= Html.Encode(vehicle.Name) %>
</td>
<td >
<%= Html.Encode(vehicle.LastPositionReceived) %>
</td>
<td >
<%= Html.Encode(vehicle.Status) %>
</td>
<td >
<%= Html.Encode(vehicle.LocationDescription) %>
</td>
</tr>
<% } %>
</table>
By clicking on the Show link, I can already show a SINGLE item details.
Now I'd like to have the checkbox bound to a property of my model so that I can then trigger an action (with a link or a button) so that only the SELECTED items are sent to the controller.
This is the part that I haven't seen any examples about.
I could add
<% TempData.Add("Vehicles", Model); %>
somewhere and then the vehicles would be passed to the controller but I still need a way to bind the IsSelected property to the model (I don't want to hook up the Checked event and do it manually).
I hope that makes things a bit clearer.
(Thanks for the quick reply BTW ;) )
Honestly, you are not giving much information for us to give a proper answer. But here is a simple example of how you could accomplish what I think you described.
Suppose this is the part in your view where you are listing the selections to the user :
<%foreach (YourModel m in (List<YourModel>)ViewData["ModelsToList"]) {%>
<p>
<input name="selection" type="radio" value="<%=m.ID%>" id="model-<%=m.ID%>" />
<label for="model-<%=m.ID%>"><%=m.Name%></label>
</p>
<%}%>
Then you post that form to a controller action like this :
public ActionResult ShowSelectedModel(int selection) {
YourModel selectedModel = yourModelRepository.getModel(selection);
return View(selectedModel);
}
Then in your ShowSelectedModel view you can display the user's selection.
Was that what you had in mind?

Resources