TwitterBootStrapMVC Dropdownlist Selected Value - c#

I can't get the selected values from the following dropdownlist, here how I generate the list:
In the repository:
public IQueryable<OhaType> GetAllOhaTypes ()
{ return db.OhaType.OrderBy(d => d.Name); }
In the controller:
....
var OhTypes = _medicationRepository.GetAllOhaTypes();
ViewBag.OhTypes = new SelectList(OhTypes, "OhaTypeId", "Name");
.....
In the View:
#foreach (var item in this.Model.OhaMedication)
{
<tr>
<td>
#(Html.Bootstrap().DropDownList("OhaTypeId", (SelectList)ViewBag.OhTypes)
.HtmlAttributes(new
{
Name ="OhaTypeId",
style = "width: 300px;"
}).Size(InputSize.Small)
.Class("form-group input-sm").Id("OhaTypeId")
.ShowValidationMessage(true))
</td>
.....
I get the first item of the list displayed not the correct value. I get the correct values in other fields from the table.
I also tried "#HTML.DropdownList(...)", same issue.
Would appreciate your suggestions.

Related

Add custom item on SelectListItem in If condition in a controller ASP.Net MVC

Trying to populate a DropDownList depending on logged in windows user's username. However, the list should have only one item if the condition fails.
Problem: The custom item is not added to the list when condition meets. Looked at lot of posts on SO but with no luck. Any direction would help.
Controller:
public ActionResult Location()
{
UserPermissionDataContext dbContext = new UserPermissionDataContext();
var viewModel = new UserDetail();
var locationList = new SelectList(
(
from t in dbContext.UserDetails
where t.username.Equals(System.Environment.UserName)
select new SelectListItem{Text = t.location, Value = t.level}
), "Value", "Text");
if (locationList.Select(i => i.Value).Contains("Global"))
ViewData["Locations"] = locationList;
else
ViewData["Locations"] = new SelectList(locationList, "Value", "No Access");
return View(viewModel);
}
View:
<tr>
<td>Global</td>
<td>
<div>
#Html.DropDownList("location", (SelectList)ViewData["Locations"])
</div>
</td>
</tr>
What would be the steps to generate a list in that case when condition failes with one item only which would have the item as "No Access".
You can use this
if (locationList.Any(i => i.Value.Contains("Global")))

Get a determined value inside a dropdowList

I'm doing a page to edit a product,the product have some characteristics,i'm using a getAll to recover all of the characteristics.
model.Listcharacteristics= v_ProdutoCharacteristicsMetodos.GetAll(EmpresaId)
.Select(x => new ProdutoCharacteristicsModel()
{
Apagado = x.Apagado,
DeAte = x.DeAte,
DepartamentoId = x.DepartamentoId,
Descricao = x.Descricao,
Description = x.Description,
Fator = x.Fator,
Keywords = x.Keywords,
MostrarHome = x.MostrarHome,
NCM = x.NCM,
Ordem = x.Ordem,
PessoaId = x.PessoaId,
ProdutoFamiliaId = x.ProdutoFamiliaId,
UrlImagem = x.UrlImagem
})
.ToList();
But i have a method that can get the product characteristic by the product ID,so in the edit page,i need to show the currently characteristic instead of the default value,how i can select which value show first select in the dropDowList?
In the BLL i created this.
model.Produto.ProdutoFamilia = v_ProdutoFamiliaMetodos.GetById(produtoempresa.ProdutoFamiliaId).Descricao;
I'm passing produtoempresa (The product)and ProdutoFamiliaId is the caractheristic ID,i'm getting a string with the name of the characteristic,this name its what i have to show the default value.
The html is this.
<tr>
<td>
#if (this.Model.ListFamilia != null && (this.Model.ListFamilia.Count > 0))
{
for (int i = 0; i < Model.ListFamilia.Count; i++)
{
#Html.HiddenFor(model => model.ListFamilia[i].ProdutoFamiliaId)
#Html.HiddenFor(model => model.ListFamilia[i].Descricao)
}
}
#Html.DisplayNameFor(model => model.Produto.ProdutoFamiliaId)*
</td>
<td>
#Html.DropDownListFor(model => model.Produto.ProdutoFamiliaId, new SelectList(Model.ListFamilia, "ProdutoFamiliaId", "Descricao", Model.Produto.ProdutoFamiliaId), String.Empty)
</td>
</tr>
In the dropdowList the default value showing must be the model.Produto.ProdutoFamilia.
You usually render the dropdown box and set the selected value in the html. This is done with the
<select name="hall" id="hall" value="3">
<option selected="selected">1</option>
<option>2</option>
<option>3</option>
</select>
This will have the first option selected in your dropdown list. From your method that can get the product characteristic you should be able to calculate which option you want to append
selected="selected"
Hope this helps

Get ID of control from View into Controller

In my MVC application I have a view where I will display different data from a SQL table. This will generate different amount of drop down lists and text boxes, depending on what is passed in from the Model.
My issue is if I want to then use that data I can't seem to figure out how I can relate control X to object Y in SQL. For example, if I have 2 textboxes that I want to do an update on, then when the Post happens in my application the FormCollection parameter will let me see the Value of the objects, but not their control name or any form of identifying factor.
I could set the Value to a combination of the entered value + a name, then split this, but it seems very much like a lazy workaround.
I've tried to assign an ID to each, for example:
#foreach (DataObject item in Model.AllDataObjects)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Data)
</td>
<td>
#if (item.Rule.Contains("Yes;No"))
{
#Html.DropDownListFor(model => item.Value, new List<SelectListItem>
{
new SelectListItem {Text="Yes", Value="Yes"},
new SelectListItem {Text="No", Value="No" }
}, new { #id = item.ObjectId });
}
else
{
#Html.TextAreaFor(model => item.Value, new { style = "width: 400px;", #rows = 5, #id = item.ObjectId })
}
</td>
</tr>
}
Edit: The following is my Post ActionResult method in the Controller, albeit it isn't complete as I can't figure out how to get an ID for the control from the FormCollection
[HttpPost]
[ValidateInput(false)]
public ActionResult UpdateData(FormCollection collection, int objectId=0)
{
try
{
int propertyTypeId = 0;
string propertyValue = string.Empty;
// Get all the control values from the collection
string[] allValues = new string[] { };
IValueProvider valueProvider = collection.ToValueProvider();
foreach(string key in collection.Keys)
{
ValueProviderResult result = valueProvider.GetValue(key);
allValues = result.RawValue as string[];
}
ObjectData objectData = _execution.GetObjectDetails(0);
UpdateDataResponse result = _execution.UpdateData(0, objectId,
objectValue, UserName);
return RedirectToAction("Details",
new { ObjectId = objectData.ObjectId, error = result.ErrorMessage });
}
catch (Exception ex)
{
// My exception handling here
}
}
So I can see in the mark-up that the controls are assigned the object ID as their own ID, but how can I get this back? When I check FormCollection I only see the values for each control, but no way of identifying which is which.
Edit: I'm using MVC version 4.
A form only submits the values of its successful controls (as name/value pairs based on the controls name and value attributes) so if you do not generate a control for the ObjectId properties, they will not be submitted.
However, you current use of foreach loop will not allow you to obtain any meaning information from the data which is posted because all your names are identical and there is no way to reliable match up which value belongs to which item in the collection. Instead use a for loop or EditorTemplate in the view and bind to your model, rather than using FormCollection.
The view should be
#for (int i = 0; i < Model.AllDataObjects.Count; i++)
{
<tr>
<td>#Html.DisplayFor(m => m.AllDataObjects[i].Name)</td>
<td>#Html.DisplayFor(m => m.AllDataObjects[i].Data)</td>
<td>
#Html.HiddenFor(m => m.AllDataObjects[i].ObjectId)
#if (Model.AllDataObjects[i].Rule.Contains("Yes;No"))
{
#Html.DropDownListFor(m => m.AllDataObjects[i].Value, new SelectList(new string[]{ "Yes", "No" }));
}
else
{
#Html.TextAreaFor(m => m.AllDataObjects[i].Value, new { style = "width: 400px;", #rows = 5 })
}
</td>
</tr>
}
And assuming the model in the view is #model MyModel, change the POST method to
[HttpPost]
[ValidateInput(false)]
public ActionResult UpdateData(MyModel model)
and the value of model.AllDataObjects will contain a collection with its ObjectId and Value properties correctly bound.
For more information on why using a foreach loop will not work, refer to this answer.

MVC WebGrid Dynamic Content

What I am trying to achieve is hard to explain, so please let me know if I can provide more information. I have a feeling that I am trying to use WebGrids beyond their means, so if anyone has any open source alternatives that would do what I am trying, that would also be helpful.
I need to build a WebGrid from the ground up, because the content returned to it (columns and values) changes depending on other criteria on my form. I have this working in a few simple lines of code in a Table, but I wanted to use WebGrid for the styling, sorting and paging.
#model DocumentSearchViewModel
#if ((this.Model != null) && (this.Model.SearchResults != null) && (this.Model.SearchResults.Count() > 0))
{
<table>
<thead>
<tr>
<th>Document</th>
#foreach (var metadata in this.Model.SearchResults.Metadata)
{
<th>
#metadata.InstanceFieldName
</th>
}
</tr>
</thead>
<tbody>
#foreach (var document in this.Model.SearchResults)
{
<tr>
<td>
#Html.ActionLink(document.Id.ToString(), "Details", new { id = document.Id })
</td>
#foreach (var metadata in document.Metadata)
{
<td>
#metadata.Value
</td>
}
</tr>
}
</tbody>
</table>
}
So to explain the model structure, The SearchResults has an IEnumerable<MetadataModel>, and this MetadataModel has properties of InstanceFieldName and Value. When a search is performed, every result will always have the same number of Metadata, and the same InstanceFieldNames, but different values, however a quick change of a field on the form, and a new search could return a new set of results (Again with the same set of Metadata as each other, but different to the first set of results)
The columns of the grid correspond to the Metadata InstanceFieldName, and the content the Value.
So I have made my best attempt using WebGrid, but the best I can get is a grid with the right column headers, and the right number of rows, the columns have the right data, but each row is the same (copied from the last row).
#{
var grid = new WebGrid(canPage: true, canSort: true, rowsPerPage: Model.PageSize, sortFieldName: Model.Sort, sortDirectionFieldName: Model.SortDir);
grid.Bind(Model.SearchResults, rowCount: Model.DocumentCount);
List<WebGridColumn> cols = new List<WebGridColumn>();
foreach(var metadata in Model.SearchResults.Select(r => r.Metadata).FirstOrDefault())
{
var col = new WebGridColumn();
col.ColumnName = metadata.InstanceFieldName;
col.Header = metadata.InstanceFieldHeader;
col.Style = "gridRow";
col.CanSort = true;
cols.Add(col);
}
foreach (var result in Model.SearchResults)
{
foreach (var col in cols)
{
var metadataValue = result.Metadata.Single(m => m.InstanceFieldName == col.ColumnName).Value;
col.Format = (item) => #Html.Raw("<text>" + metadataValue + "</text>");
}
}
}
#if ((this.Model != null) && (this.Model.SearchResults != null) && (this.Model.SearchResults.Count() > 0))
{
#grid.GetHtml(htmlAttributes: new { id = "documentGrid" }, rowStyle: "gridRow", alternatingRowStyle: "gridRowAlt", columns: cols)
}
What I'm trying to work out is how and if possible to generate the columns first, and then populate the rows into these columns.
Any help is really appreciated, thanks, Mark
You are feeding the rows with the same value, you should change the Format:
col.Format = (item) => #Html.Raw(item.metadataValue);

How to perform a simple multiple selection in a table ASP.NET MVC4

Here is what my view looks like:
#model Affiliate
<div class="box paint color_16">
<div class="title">
<h4><i class="icon-tasks"></i><span>#Model.CompanyName's Commissions</span> </h4>
</div>
<div class="content top ">
<div class="subtitle">
#Html.ActionLink("Void", "DeleteInvoice", new { commList = "??", affId = Model.Id }, new { #class = "btn" })
#Html.ActionLink("Create Invoice", "CreateInvoice", new { commList = "??", affId = Model.Id }, new { #class = "btn" })
#Html.ActionLink("Pay", "PayInvoice", new { commList = "??", affId = Model.Id }, new { #class = "btn" })
</div>
<table class="table table-striped table-hover">
<tr>
<h3>Commissions</h3>
</tr>
<tr>
<td></td>
<td>Amount</td>
<td>Status</td>
<td>Action</td>
</tr>
#foreach (var item in Model.Commissions)
{
<tr>
#if (item.Status == ViewBag.PaymentStatus || ViewBag.PaymentStatus == "All")
{
<td>#Html.CheckBox("commId", new { value = item.Id })</td>
<td>#Html.DisplayFor(x => item.PayoutAmount)</td>
<td>#Html.DisplayFor(x => item.Status)</td>
}
</tr>
}
</table>
</div>
What I want to be able to do is when I hit an actionlink on the top, grab all the items from the table that are checked, and pass that list of id's to the controller logic. I am assuming a viewmodel may be the solution, something like this:
public Affiliate affilite { get; set; }
public List<int> selectedItems { get; set; }
etc.
But how to I get the selected Items into that VM selectedItems container?
Based off your comments, you don't seem to be looking for the most "correct" answer, but rather just a quick and dirty "how would I do this" answer. If you just want to pass the list, you could setup your controller action like this:
public ActionResult MyAction(int[] id)
{
...
}
Or, you seem to indicate it is strongly typed to a view model with a property that contains a List (I would shorten the name of the property, you'll see why in a second).
In javascript, the easiest thing to do would be to use jQuery to bind a click event on your hyperlink that gets the list of items that are checked and appends that to the query string.
$("#myLink").click(function()
{
var url = "site.com/action?";
var ids = $(".table").find("input:checked");
ids.each(function()
{
url += "id=" + $(this).val() + "&"
});
window.location = url;
});
Basically, you want to create one long query string with the action parameter's name repeated over and over, which identifies an array. It looks something like this (id is for int[] id in MyAction):
id=15&id=20&id=25&id=30&....
And then once the query string is built, redirect the user to that url. MVC should then be able to bind that to an array and you're all set.
That's basically the idea, anyway; the syntax and the javascript I wrote could be way off so don't copy my code and expect it to work as is - I wrote that off the top of my head. If your action is bound to a viewmodel, then you need to set the parameter in the query string to the name of the property of your model:
selectedids=1&selectedids=2&selectedids=3...
Or, if the array is a property of an object, which is a property of the model...
model.selectedids=1&model.selectedids=2&model.selectedids=3...
You'll just need to play around with it some.
Use html checks inside form tag ( you could use helpers too) and post the model to a post action.
MVC will serialize the model automatically

Categories

Resources