How generate MVC View Controls dynamically? - asp.net-mvc-4

Is possible to generate controls in View depending on data returned from DB
Example
Model
public string Type{ get; set; }
Controller
public ActionResult Index()
{
return View(db.TypeModel.ToList());
}
View
#model IEnumerable<Sample.Models.TypeModel>
#foreach (var item in Model)
{
<tr>
<td>
#*if Item in model is T generate text box, if C generate text..*#
</td>
</tr>
}

There are multiple solutions to this kind of problem, I personally think that you should take a look in EditorFor html helper.
This method generates different HTML markup depending on the data type
of the property that is being rendered, and according to whether the
property is marked with certain attributes. https://msdn.microsoft.com/en-us/library/system.web.mvc.html.editorextensions.editorfor%28v=vs.118%29.aspx?f=255&MSPPError=-2147217396
Your code can look like this...
#model IEnumerable<Sample.Models.TypeModel>
#foreach (var item in Model)
{
<tr>
<td>
#Html.EditorFor(m=> item.Property,item.Type)
</td>
</tr>
}

Related

Showing a substring of text that contains HTML

I am implementing something similar to a blog engine, where on the entry page I would like to see a listing of my posts, and, for each, its title and a short piece of its body content.
This body content is HTML, and is stored in the database as a string, so, it's not enough to just show a substring of it, because it might break the HTML structure.
I guess the algorithm would be: render the string to HTML and extract only the first X characters of it.
Is there any solution for this problem?
Here is a working demo like below:
View:
#model IEnumerable<Post>
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Title)
</th>
<th>
#Html.DisplayNameFor(model => model.Body)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.Body)
</td>
</tr>
}
</tbody>
</table>
Controller:
public IActionResult Test()
{
var model = new List<Post>()
{
new Post(){ Title="asp.net core mvc",Body="<html><div><h1>The Model-View-Controller (MVC) architectural pattern separates an application into three main groups of components: Models, Views, and Controllers. This pattern helps to achieve separation of concerns. Using this pattern, user requests are routed to a Controller which is responsible for working with the Model to perform user actions and/or retrieve results of queries. </h1></div></html>"},
new Post(){Title="asp.net core razor pages",Body="<html><div>Razor Pages is designed to make common patterns used with web browsers easy to implement when building an app. Model binding, Tag Helpers, and HTML helpers all just work with the properties defined in a Razor Page class.</div></html>"}
};
foreach(var item in model)
{
item.Body= Regex.Replace(item.Body, #"<[^>]+>| ", String.Empty);
item.Body= item.Body.AsSpan(0, 30).ToString()+"...";
}
return View(model);
}
Result:

Display specific data with parameter using Stored Procedure

Hi I have error in regards with my displaying specific data. I passed a parameter through a model and I get error on regarding creating a new instance. here is my code:
Controller
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult ViewEmployeeSalary(spGetSalaryPerEmployee getsal)
{
var salary = _Context.Set<spGetSalaryPerEmployee>().FromSql("spGetSalaryPerEmployee #empID = {0}", getsal.EmployeeID).AsNoTracking();
return View(salary);
}
View
This the button where you click to redirect to the details page
#foreach(var item in Model)
{
a class="btn btn-primary btn-sm" asp-controller="Salary" asp-action="ViewEmployeeSalary" asp-route-id="#item.EmployeeId"><span class="glyphicon glyphicon-dashboard" style="vertical-align:middle;margin-top: -5px"></span> Salary Details</a>
}
Here is the page where it views the details
#model PEMCOLoan.DAL.Entities.spModels.spGetSalaryPerEmployee
#{
ViewBag.Title = "Salary Details";
}
<h2>#Html.DisplayFor(model => model.FullName)'s Salary Details</h2>
<table class="table">
<tr>
<td class="form-horizontal">ID:</td>
<td>#Html.DisplayTextFor(model => model.EmployeeID)</td>
</tr>
<tr>
<td class="form-horizontal">Salary Amount:</td>
<td>#Html.DisplayFor(model => model.Salary)</td>
</tr>
<tr>
<td class="form-horizontal">Remarks:</td>
<td>#Html.DisplayTextFor(model => model.Remarks)</td>
</tr>
</table>
I get this error:
I don't really what really happens but stated the I need to create an instance.
I have still a little knowledge about asp.net core and ef core and still studying for this language for now. I really need your help in regards with this since I'm a bit new with this language.
Any suggestion would be a greatly appreciated!
Your controller method needs to return single record as error states. Now it returns a list, so you need to change to something like this:
var salary = _Context.Set<spGetSalaryPerEmployee>().FromSql("spGetSalaryPerEmployee #empID = {0}", getsal.EmployeeID).AsNoTracking().SingleOrDefault();
//salary now is single record
return View(salary);
And maybe you need to check salary variable is not null before passing it to view, because then you'll have errors there.

select a specific value in a drop down list options in mvc

i have a list of items(here model). one of the list item - PhoneNumber, i will load values of phoneNUmber from database. user can change the phone number from the dropdownlist. however when view is first loaded, users activephone number should be the selected option in dropdwonlist. users active phone number here is lp.PhoneNumber
i created a ViewData["PhoneNumber"] for #Html.DropDownList("PhoneNumber")
#foreach (var lp in Model)
{
<tr>
<td class ="editor-field"><span class="SpaceForEditorField">#Html.EditorFor(order => lp.rKey)</span></td>
<td class ="editor-field"><span class="SpaceForEditorField">#Html.EditorFor(order => lp.AccountName)</span></td>
<td class ="editor-field"><span class="SpaceForEditorField">#Html.EditorFor(order => lp.AccountNumber)</span></td>
<td class ="editor-field">
<span class="SpaceForEditorField">
#Html.DropDownList("PhoneNumber")
</span>
</td>
</tr>
}
the code here is not displaying the active phone number as selected in dropdownlist, instead jus displays the items in dropdownlist.
i want to set the lp.PhoneNumber as selected item in the ddl "PhoneNumber"
i created ViewData["PhoneNumber"] in the controller as below
public ActionResult LoadOrder(int id, string token)
{
.....
.....
ViewData["PhoneNumber"] = new SelectList(new Ordering().GetPhoneNumberAvailableForOrder(id, token).ToList());
.......
.....
}

Html.BeginForm in a partial view?

I have a block of code that uses the Html.BeginForm to submit a value from textbox to controller. When I put this in a View, it works fine. That is, the controller's action method is called. However, when I place this block of code inside a partial view that will get rendered in the View, the controller's action never gets called.
Not sure if this is the usual behavior or if I am missing something...
#using (Html.BeginForm("TestAction", "Home", FormMethod.Post, new { id = "formId" }))
{<table>
<tr>
<td>Data Date</td>
<td>#Html.TextBox("date")</td>
</tr>
<tr>
<td></td>
<td><input id="btnRun" type="submit" value="submit" /></td>
</tr>
}
Controller:
[HttpPost]
public ActionResult TestAction(string date)
{
[doing something......]
return View();
}
Thanks in advance!
Typically #Html.BeginForm() renders the <form> tag's action to point back to the route details that got it here. Thus in partial views, you're actually rendering back to the outer page. (Yeah, mind-bending.) If you want to specifically direct the form post to a particular route, add additional parameters to the #Html.BeginForm(). See http://msdn.microsoft.com/en-us/library/system.web.mvc.html.formextensions.beginform(v=vs.108).aspx

How to dynamically add a hyperlink (BookmarkablePageLink) to DefaultDataTable that is rendered as an anchor

I have a DefaultDataTable that gets its columns programmatically.
The markup is simple:
<table wicket:id="dataTable" border="0" cellpadding="1" cellspacing="1" width="90%" />
All of the columns are dynamically generated from a passed in LinkedHashMap of labels and attributes:
for (Entry<String, String> entry : entrySet) {
final String label = entry.getKey();
final String attribute = entry.getValue();
columns.add(new PsPropertyColumn(label, attribute) {
#Override
public void populateItem(Item cellItem, String componentId, IModel model)
{
final Object modelObject = model.getObject();
final Object value = PropertyResolver.getValue(attribute, modelObject);
// Add an edit link
BookmarkablePageLink link = new ...;
...
cellItem.add(link);
}
}
}
DefaultDataTable table = new DefaultDataTable("dataTable", columns, dataProvider, MAX_ROWS) {
...
}
add(table);
As many posts have mentioned, this is rendered as a cell with an onclick handler rather than an anchor (<a href="..." />) tag. I want the anchor tag for a couple of reasons, one if which is that I want to add my own onclick handler without having an existing onclick handler in the way.
I have seen the generally accepted solution that says to put an anchor tag inside a panel in the HTML markup, and to add the link inside of a Panel subclass. However, that doesn't give the entire html markup (inside the table), and I think the column () tags must be a part of this markup, which I don't think works with my strategy of dynamically generating the columns (I don't even know or care how many will be asked for). Is there a way to render my dynamically generated columns as anchor tags without specifying in the markup how many there?
Thank you for any help.
I have used nested ListView components to be able to have more control over the layout as below:
html:
<table wicket:id="listViewContainer">
<tr>
<th wicket:id="columnHeaderListView">
<span wicket:id="columnHeaderLabel">Header Label</span>
</th>
</tr>
<tr wicket:id="rowListView">
<td wicket:id="rowColumnListView">
<a href="#" wicket:id="link">
<span wicket:id="linkLabel">Link Label</span>
</a>
</td>
</tr>
</table>
Java:
WebMarkupContainer listViewContainer = new WebMarkupContainer("listViewContainer");
listViewContainer.setOutputMarkupId(true);
add(listViewContainer);
ListView columnHeaderListView = new ListView("columnHeaderListView", columnHeaderList) {
#Override
protected void populateItem(ListItem listItem) {
ColumnHeader ch = (ColumnHeader) listItem.getModelObject();
listItem.add(new Label("columnHeaderLabel", new Model(ch.getLabel())));
}
};
listViewContainer.add(columnHeaderListView);
ListView rowListView = new ListView("rowListView", rowList) {
#Override
protected void populateItem(ListItem listItem) {
Row row = (Row) listItem.getModelObject();
listItem.add(new ListView("rowColumnListView", getRowColumnList(row)){
#Override
protected void populateItem(ListItem li) {
RowColumn rowColumn = (RowColumn) li.getModelObject();
Link link = new BookmarkablePageLink("link",...
li.add(link);
link.add(new Label("linkLabel", new Model(rowColumn.getLabel())));
}
});
}
}
listViewContainer.add(rowListView);