I'm using partial views in a loop and this is generating multiple id="item_itemD" inputs (I'm using Html.HiddenFor to generate the input).
What can I do to use partials so my markup can be html 4.01 strict?
Thank you
You could pass in an integer value to the partial and append that to the ID before incrimenting for the next itteration.
var counter = 0;
foreach(var item in items)
{
Html.RenderPartial("MyPartial",counter);
counter ++
}
If you're already passing a model to your partial view, you might consider creating a basic view model contining your current object and the int as properties.
Html.RenderPartial("MyPartial", new MyViewModel{Counter = counter; Model = item}
Related
In NatTable I am adding a row in filtered table. After removing the filter, the newly added row moves to last position in the table.
But I want to it to stay in the same position, that is next to the row which I added when the table is filtered.
I am currently using the RowInsertCommand. I don't want to add row via model or list which used to populated the table. I want to achieve only via NatTable commands. Is it possible?
It is always hard to follow the explanations and the issue without example code. But I assume you simply copied code from the NatTable examples, so I will explain your issue based on that.
First, the RowInsertCommand has several constructors. If you are using a constructor without a rowIndex or rowPositionparameter, the new object will ALWAYS be added at the end of the list.
When using the filter functionality in NatTable with GlazedLists, the list that is wrapped in the body DataLayer is the FilterList. If you are operating on the FilterList for calculating the rowIndex where the new object should be added and have the FilterList as base list in the RowInsertCommandHandler, the place where the new object is added is transformed between the FilterList and the base EventList, which might not be the desired result.
To solve this you need to create the RowInsertCommandHandler by using the base EventList.
EventList<T> eventList = GlazedLists.eventList(values);
TransformedList<T, T> rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);
SortedList<T> sortedList = new SortedList<>(rowObjectsGlazedList, null);
this.filterList = new FilterList<>(sortedList);
this.baseList = eventList;
bodyDataLayer.registerCommandHandler(new RowInsertCommandHandler<>(this.baseList));
The action that performs the add operation then of course needs to calculate the index based on the base EventList. The following code is part of the SelectionAdapter of an IMenuItemProvider:
int rowPosition = MenuItemProviders.getNatEventData(event).getRowPosition();
int rowIndex = natTable.getRowIndexByPosition(rowPosition);
Object relative = bodyLayerStack.filterList.get(rowIndex);
int baseIndex = bodyLayerStack.baseList.indexOf(relative);
Object newObject = new ...;
natTable.doCommand(new RowInsertCommand<>(baseIndex + 1, newObject));
I'm trying to produce a runtime table. Below class and codes are simplified version of my final purpose.
class AppModel {
int appID;
String appName;
AppModel({this.appID, this.appName});
}
I'm calculating, fetching some another data and trying to fill the following object like this:
// _newApps value is between 1-30 mostly but not limited
List<AppModel> theList = [];
for (int i = 0; i < _newApps; i++) {
AppModel _newRecord = AppModel();
_newRecord.appID = _getNewAppID();
_newRecord.appName = _getNewAppName();
theList.add(_newRecord);
}
So the question is the code creates a new AppModel instance for only adding the element to the list for every iteration inside the for loop. According to my program logic, this event can be repeated 100-150 times sometimes.
Is it normal or is there any more memory efficient way to do so?
Thank you in advance.
I would like to point out (a better approach) that instead of for Loop you could have used the map method on the Apps List you have. And instead of creating a object every time in the Loop create a constructor for returning the object instance using the required details.
Hope you find it useful.
I am using mvc 4, i have a form in a view (not binded to a model), its using standard html elements.
I want to populate a dropdownlist from a list value (i.e return from controller action)
also based on the selection of a value from the first dropdownlist i want to populate a second dropdownlist
can someone please guide
for the first dropdownlist you loop thru all the available options and add in <option> tags inside <select> for the second dropdownlist you need to either make bunch drop downs and hide/show them, or you create one big list and remove invalid entries base on the first list's selection. You would definitely need to do javascript for 2nd list.
If you don't want to use a Model (you should though), you will have to add the items to ViewData
I'll stub something out for you and you can complete the rest.
Inside your controller, create a list object of what you need. If you are using EntityFrameWork this will look familiar.
var list = context.Table.ToList();
List<System.Web.Mvc.SelectListItem> ddlItems = new List<System.Web.Mvc.SelectListItem>();
foreach (var item in list)
{
ddlItems.Add(new SelectListItem(){ Text = item.Text, Value = item.Value.ToString()});
}
ViewData["DDLItems"] = ddlItems;
#Html.DropDownListFor(x => x.LeagueId,
new SelectList((System.Collections.IEnumerable)ViewData["DDLItems"], "Value", "Text")
, "--Select League--", new { id = "league" })
You can define your second dropdownlist with just a placeholder until the cascade effect happens.
#Html.DropDownListFor(x => x.DivisionId, Enumerable.Empty<SelectListItem>(),
"--Select Division--", new { id = "ddlDivision" })
Your going to need to use JQuery and fire and event when the dropdown changes, and then use Ajax to make a call back to the controller. Theres 2348239 examples online about making Ajax calls, know how to do that because it's done all the time in MVC.
I'll let you figure that part out. One hint, inside the Ajax call you can pass data to the controller. something like this data: { leagueId: value } where value is the value of the dropdownlist you want to cascade off of. leagueId must match type and name of the parameter your controller will expect.
Return a Json object from your controller like so...
public JsonResult GetDivisions(int leagueId)
{
var division = //similar to before, fill a list.
return Json(divisions, JsonRequestBehavior.AllowGet);
}
And then in the success function of your Ajax call, you will populate the Second dropdownlist.
success: function (data) {
$.each(data, function (index, item)
$('#ddlDivision')
.append($('<option></option>')
.val(item.Value)
.html(item.Text))
item.Value and item.Text can be anything, just as long as the Json you return as the properties of Text and Value
IE...
var divisions = (from x in context.Division
select new
{
Text = league + " " + x.Region,
Value = x.DivisionId
}).ToList();
I'm trying to employ a technique that I came across that seems quite clean.
Previously, my Partial had the loop inside of it. I was looping through the mode within the Partial... but then I came across an example where the foreach loop existed in the main page, while the partial was just the meat of the loop.
They accomplished it like so:
<% int index = 1; // iteration
foreach (var item in Model.Deal) { %>
<% Html.RenderPartial("DealList", item, new ViewDataDictionary {{ "index", index }}); %>
<% i++; // increase the interation
} %>
But in my example, I'm using a ViewModel, and now that I'm in the partial, I can't access "item" like I used to be able to. Instead my only option is Model.Deal ...
What is the point of passsing "item" with the RenderParial helper if I can't access it by saying item.StoreName? Note, both the View and the Partial are strongly typed to the same ViewDataModel.
Inside of the partial "DealList" your model will be whatever item is in the main view. Inside of the partial view, Model.Deal refers to a Deal object inside of item (from the main view).
This means that your StoreName property will be accessible as Model.StoreName within your partial view.
As a side note, I put together an extension method to deal with rendering of multiple partial views so as to not require the looping.
The new method is called RenderPartials:
public static void RenderPartials(this HtmlHelper helper, string partialViewName, IEnumerable models, string htmlFormat)
{
foreach (var view in models.Select(model => helper.Partial(partialViewName,model)))
{
helper.ViewContext.HttpContext.Response.Output.Write(htmlFormat, view.ToHtmlString());
}
}
Using this method you can simple say:
<% Html.RenderPartials("DealList",Model.Deal); %>
inside your main view, without the loop.
There's some more information about this here which explains more about the htmlFormat parameter etc.
Hope this is helpful to you.
#model IEnumerable<dynamic>
#foreach (dynamic m in Model)
{
#Html.Partial(MVC.Lists.Messages.Views._SingleMessage, (object)m)
}
What is the best way of handling trying to get data from a DataReader that has more than one column with the same name?
Because of the amount of work involved and because we don't want to lose support from a vendor by changing the stored procedures we are using to retrieve the data, I am trying to find another way to get access to a column that shows up more than once in a datareader without having to rewrite the stored procedures.
Any Ideas?
EDIT:
Ok, the function that actually populates from a datareader is used in multiple places so there is a possibility that the function can be called by different stored procedures. What I did was to do a GetName using the index to check if it is the correct column, and if it is, then pull its value.
If you know the index of the column, then access it by the index.
Can't you use column ordinals? 0 for the 1st, 1 for the 2nd, and so on?
You will have to reference the column by index no; i.e. reader[5].ToString(); to read the data in column 5.
Based on original poster's approach described in the "Edit" paragraph, here's an extension method that will give the value based on the column name and the index of that name, e.g., 0 for the first instance of name, 1 for the second, etc:
using System;
namespace WhateverProject {
internal static class Extentions {
// If a query returns MULTIPLE columns with the SAME name, this allows us to get the Nth value of a given name.
public static object NamedValue(this System.Data.IDataRecord reader, string name, int index) {
if (string.IsNullOrWhiteSpace(name)) return null;
if (reader == null) return null;
var foundIndex = 0;
for (var i = 0; i < reader.FieldCount; i++) {
if (!reader.GetName(i).Equals(name, StringComparison.CurrentCultureIgnoreCase)) continue;
if (index == foundIndex) return reader[i];
foundIndex++;
}
return false;
}
}
}
Use it thus:
var value1 = reader.NamedValue("duplicatedColumnName", 0);
var value2 = reader.NamedValue("duplicatedColumnName", 1);