I need to generate a list of years to select from, with the current year being selected by default. Nothing complex. I'm setting the first item in the list as "selected". The list shows the first item has Selected = true when stepping through the code, but when the view loads, the current year is not selected, and the attribute isn't added to the HTML. Here's the code to generate the year list:
public int CurrentYear { get { return DateTime.Now.Year; } }
public int FiscalYear { get; set; }
public List<SelectListItem> FiscalYearList
{
get
{
var yearList = new List<SelectListItem>();
for (var i = 0; i <= 5; i++)
{
yearList.Add(new SelectListItem
{
Text = (CurrentYear - i).ToString(),
Value = (CurrentYear - i).ToString(),
Selected = (i == 0)
});
}
return yearList;
}
}
}
And here is the cshtml code:
<select id="FiscalYearList" asp-for="FiscalYear" asp-items="Model.FiscalYearList" class="form-control">
<option>---Select---</option>
</select>
The answer to this was unintuitive. I set the "default" selected year as the value of "asp-for", and got rid of the manual setting of the selected item value.
public int FiscalYear { get { return DateTime.Now.Year; } }
public List<SelectListItem> FiscalYearList
{
get
{
var yearList = new List<SelectListItem>();
for (var i = 0; i <= 5; i++)
{
yearList.Add(new SelectListItem
{
Text = (FiscalYear - i).ToString(),
Value = (FiscalYear - i).ToString()
});
}
return yearList;
}
}
<select id="FiscalYearList" asp-for="FiscalYear" asp-items="Model.FiscalYearList" class="form-control">
<option>---Select---</option>
</select>
This set the value of "FiscalYear" as the selected item in the drop-down. So setting this value explicitly in code was ignored, but it works like this. Strange.
I'm having a bit of trouble passing the variable score, that is a variable in my Evaluation class, that is initialized here in my [httpPost]ifstatements(Evaluation model) method in my Quiz controller to a view belonging to a different controller of a different class. When the score is greater than zero, i.e i answer at least one question correct, I am brought to the results view and the score is shown to me. But im having trouble printing that score out in another view called Index that is part of my index method in my LEADERBOARD controller of the LEADERBOARD class
Quiz Controller
public ActionResult ifStatement()
{
var evalVM = new Evaluation();
//the below is hardcoded for DEMO. you may get the data from some
//other place and set the questions and answers
var q1 = new Question { ID = 1, QuestionText = "1. Which of the following shows the correct syntax for an if statement?" };
q1.Answers.Add(new Answer { ID = 12, AnswerText = "a. if expression" });
q1.Answers.Add(new Answer { ID = 13, AnswerText = "b. if { expression }" });
q1.Answers.Add(new Answer { ID = 14, AnswerText = "c. if ( expression ){}" });
q1.Answers.Add(new Answer { ID = 15, AnswerText = "d. expression if" });
evalVM.Questions.Add(q1);
return View(evalVM);
}
[HttpPost]
public ActionResult ifStatement(Evaluation model)
{
int score = 0;
if (ModelState.IsValid)
{
using (UsersContext db = new UsersContext())
{
foreach (var q in model.Questions)
{
var qId = q.ID;
List<string> listSelectedAnswer = new List<string>();
listSelectedAnswer.Add("14");
listSelectedAnswer.Add("19");
listSelectedAnswer.Add("22");
listSelectedAnswer.Add("25");
listSelectedAnswer.Add("28");
listSelectedAnswer.Add("33");
foreach (string answer in listSelectedAnswer)
{
foreach (var answer2 in model.Questions)
{
if (answer == answer2.SelectedAnswer)
{
score = score + 3;
}
}
}
model.Score = score;
ViewBag.score = model.Score;
if (score > 0)
{
return View("results");
}
else
{
//score = 0;
//return Content("Please check all answers have been submitted!");
return Content("Error, please ensure all questions have been answered. You may use the back button to continue the Quiz."); //PRG Pattern
}
}
}
}
model.setScore(score);
return View("ThankYou");
}
Leaderboard Controller
public class LeaderboardController : Controller
{
UsersContext db = new UsersContext();
//
// GET: /Leaderboard/
TutorialEntities t = new TutorialEntities();
Evaluation e = new Evaluation();
public ActionResult Index()
{
// Evaluation ev = new Evaluation();
// var tutorial = t.Evaluations.ToList();
//ViewBag.Scores = t.Evaluations.Select(a => a.Score).ToList();
//ViewBag.Scores = e.getScore();
//ViewBag.Score = e.getScore();
ViewBag.Users = db.UserProfiles.ToList();
ViewBag.Scores = t.Evaluations.ToList();
return View();
}
}
Index View
<h2>Leaderboard</h2>
#foreach (var item2 in ViewBag.Users)
{
<p>
Score: #ViewBag.Score
</p>
}
#foreach (var item in ViewBag.Users)
{
<p>
UserID: #item.UserId
<br />
UserName: #item.UserName
<br />
</p>
}
All that shows on the page when i go this view is the name of the people who are registered on my website and their id but score is blank! I cant seem to get my head around it i have tried numerous ways but it seems it cant see the score that is being initialised in the ifstatement method
Your controller sets viewbag.scores, however your view is trying to access viewbag.score?
I have a table in database
I've been able to show the list of TypeName in my dropdownlist in my View
Currently i'm doing this is my controller
[HttpGet]
public ActionResult CreateModule()
{
var moduleTypes = _db.ModuleTypes.Select(moduleType => moduleType.TypeName).ToList();
var model = new CreateModule
{
TypeNames = moduleTypes.Select(m => new SelectListItem
{
Value = m,
Text = m,
})
};
return View(model);
}
and in view
<div class ="input-block-level">#Html.DropDownListFor(model => model.SelectedModuleTypeName, Model.TypeNames)</div>
That results to something like this
based upon my code, I'll get the TypeName from the view in my controller's post method.
How I can I change my code in order to access Id of the TypeName in controller?
Modify your Action:
public ActionResult CreateModule()
{
var moduleTypes = _db.ModuleTypes.Select(moduleType => new { TypeName = moduleType.TypeName, Id = moduleType.Id }).ToList();
var model = new CreateModule
{
TypeNames = moduleTypes.Select(m => new SelectListItem
{
Value = m.Id.ToString(),
Text = m.TypeName,
})
};
return View(model);
}
Select multiple items instead of single
var moduleTypes = _db.ModuleTypes
.Select(
moduleType => new {
Id = moduleType.Id
TypeName = moduleType.TypeName}
).ToList();
var model = new CreateModule
{
TypeNames = moduleTypes.Select(m => new SelectListItem
{
Value = m.Id.ToString(),
Text = m.TypeName,
})
};
The first statement is creating anonymous object using linq, and second statement is using it to create CreateModule
I am using this code in my view:
#(Html.Telerik().TreeView()
.Name("AjaxTreeView")
.BindTo(Model, (item, category) =>
{
// bind initial data - can be omitted if there is none
item.Text = category.Name;
item.Action("Details", "Categories", new { Id = category.Id });
item.Value = category.Id.ToString();
item.LoadOnDemand = category.NOChildren > 0;
})
.DataBinding(dataBinding => dataBinding
.Ajax().Select("_TreeViewAjaxLoading", "Categories")
)
)
It works fine (ajaxified expand and collapse). The action links work fine but only for the root nodes. My current controller that spews out JSON for the ajax load:
[Transaction]
[HttpPost]
public ActionResult _TreeViewAjaxLoading(TreeViewItem node)
{
int? ParentId = !string.IsNullOrEmpty(node.Value) ? (int?)Convert.ToInt32(node.Value) : null;
var nodes = from item in CategoryRepository.GetChildren(ParentId)
select new TreeViewItem
{
Text = item.Name,
Value = item.Id.ToString(),
LoadOnDemand = item.NOChildren > 0
};
return new JsonResult { Data = nodes };
}
does not set the action link. How can I set the action link here? Thanks.
Christian
This seems to do the trick:
[Transaction]
[HttpPost]
public ActionResult _TreeViewAjaxLoading(TreeViewItem node)
{
int? ParentId = !string.IsNullOrEmpty(node.Value) ? (int?)Convert.ToInt32(node.Value) : null;
UrlHelper u = new UrlHelper(this.ControllerContext.RequestContext);
var nodes = from item in CategoryRepository.GetChildren(ParentId)
select new TreeViewItem
{
Text = item.Name,
Value = item.Id.ToString(),
LoadOnDemand = item.NOChildren > 0,
Url = u.Action("Details", "Categories", new { Id = item.Id} )
};
return new JsonResult { Data = nodes };
}
Basically I am looking to insert an item at the beginning of a SelectList with the default value of 0 and the Text Value of " -- Select One --"
Something like
SelectList list = new SelectList(repository.func.ToList());
ListItem li = new ListItem(value, value);
list.items.add(li);
Can this be done?
There really isn't a need to do this unless you insist on the value of 0. The HtmlHelper DropDownList extension allows you to set an option label that shows up as the initial value in the select with a null value. Simply use one of the DropDownList signatures that has the option label.
<%= Html.DropDownList( "DropDownValue",
(IEnumerable<SelectListItem>)ViewData["Menu"],
"-- Select One --" ) %>
I got this to work by Populating a SelectListItem, converting to an List, and adding a value at index 0.
List<SelectListItem> items = new SelectList(CurrentViewSetups, "SetupId", "SetupName", setupid).ToList();
items.Insert(0, (new SelectListItem { Text = "[None]", Value = "0" }));
ViewData["SetupsSelectList"] = items;
This is possible.
//Create the select list item you want to add
SelectListItem selListItem = new SelectListItem() { Value = "null", Text = "Select One" };
//Create a list of select list items - this will be returned as your select list
List<SelectListItem> newList = new List<SelectListItem>();
//Add select list item to list of selectlistitems
newList.Add(selListItem);
//Return the list of selectlistitems as a selectlist
return new SelectList(newList, "Value", "Text", null);
I liked #AshOoO's answer but like #Rajan Rawal I needed to preserve selected item state, if any. So I added my customization to his method AddFirstItem()
public static SelectList AddFirstItem(SelectList origList, SelectListItem firstItem)
{
List<SelectListItem> newList = origList.ToList();
newList.Insert(0, firstItem);
var selectedItem = newList.FirstOrDefault(item => item.Selected);
var selectedItemValue = String.Empty;
if (selectedItem != null)
{
selectedItemValue = selectedItem.Value;
}
return new SelectList(newList, "Value", "Text", selectedItemValue);
}
private SelectList AddFirstItem(SelectList list)
{
List<SelectListItem> _list = list.ToList();
_list.Insert(0, new SelectListItem() { Value = "-1", Text = "This Is First Item" });
return new SelectList((IEnumerable<SelectListItem>)_list, "Value", "Text");
}
This Should do what you need ,just send your selectlist and it will return a select list with an item in index 0
You can custome the text,value or even the index of the item you need to insert
Here html helper for you
public static SelectList IndividualNamesOrAll(this SelectList Object)
{
MedicalVarianceViewsDataContext LinqCtx = new MedicalVarianceViewsDataContext();
//not correct need individual view!
var IndividualsListBoxRaw = ( from x in LinqCtx.ViewIndividualsNames
orderby x.FullName
select x);
List<SelectListItem> items = new SelectList (
IndividualsListBoxRaw,
"First_Hospital_Case_Nbr",
"FullName"
).ToList();
items.Insert(0, (new SelectListItem { Text = "All Individuals",
Value = "0.0",
Selected = true }));
Object = new SelectList (items,"Value","Text");
return Object;
}
The .ToList().Insert(..) method puts an element into your List. Any position can be specified. After ToList just add .Insert(0, "- - First Item - -")
Your code
SelectList list = new SelectList(repository.func.ToList());
New Code
SelectList list = new SelectList(repository.func.ToList().Insert(0, "- - First Item - -"));
May not sound very elegant, but I usually do something like this:
var items = repository.func.ToList();
items.Insert(0, new funcItem { ID = 0, TextValue = "[None]" });
ViewBag.MyData = new SelectList(items);
Okay I like clean code so I made this an extension method
static public class SelectListHelper
{
static public SelectList Add(this SelectList list, string text, string value = "", ListPosition listPosition = ListPosition.First)
{
if (string.IsNullOrEmpty(value))
{
value = text;
}
var listItems = list.ToList();
var lp = (int)listPosition;
switch (lp)
{
case -1:
lp = list.Count();
break;
case -2:
lp = list.Count() / 2;
break;
case -3:
var random = new Random();
lp = random.Next(0, list.Count());
break;
}
listItems.Insert(lp, new SelectListItem { Value = value, Text = text });
list = new SelectList(listItems, "Value", "Text");
return list;
}
public enum ListPosition
{
First = 0,
Last = -1,
Middle = -2,
Random = -3
}
}
Usage (by example):
var model = new VmRoutePicker
{
Routes =
new SelectList(_dataSource.Routes.Select(r => r.RouteID).Distinct())
};
model.Routes = model.Routes.Add("All", "All", SelectListHelper.ListPosition.Random);
//or
model.Routes = model.Routes.Add("All");
As this option may need in many different manners, i reached to conclusion to develop an object so that it can be used in different scenarios and in future projects
first add this class to your project
public class SelectListDefaults
{
private IList<SelectListItem> getDefaultItems = new List<SelectListItem>();
public SelectListDefaults()
{
this.AddDefaultItem("(All)", "-1");
}
public SelectListDefaults(string text, string value)
{
this.AddDefaultItem(text, value);
}
public IList<SelectListItem> GetDefaultItems
{
get
{
return getDefaultItems;
}
}
public void AddDefaultItem(string text, string value)
{
getDefaultItems.Add(new SelectListItem() { Text = text, Value = value });
}
}
Now in Controller Action you can do like this
// Now you can do like this
ViewBag.MainCategories = new SelectListDefaults().GetDefaultItems.Concat(new SelectList(db.MainCategories, "MainCategoryID", "Name", Request["DropDownListMainCategory"] ?? "-1"));
// Or can change it by such a simple way
ViewBag.MainCategories = new SelectListDefaults("Any","0").GetDefaultItems.Concat(new SelectList(db.MainCategories, "MainCategoryID", "Name", Request["DropDownListMainCategory"] ?? "0"));
// And even can add more options
SelectListDefaults listDefaults = new SelectListDefaults();
listDefaults.AddDefaultItme("(Top 5)", "-5");
// If Top 5 selected by user, you may need to do something here with db.MainCategories, or pass in parameter to method
ViewBag.MainCategories = listDefaults.GetDefaultItems.Concat(new SelectList(db.MainCategories, "MainCategoryID", "Name", Request["DropDownListMainCategory"] ?? "-1"));
And finally in View you will code like this.
#Html.DropDownList("DropDownListMainCategory", (IEnumerable<SelectListItem>)ViewBag.MainCategories, new { #class = "form-control", onchange = "this.form.submit();" })
A work-around is to use #tvanfosson's answer (the selected answer) and use JQuery (or Javascript) to set the option's value to 0:
$(document).ready(function () {
$('#DropDownListId option:first').val('0');
});
Hope this helps.
Try something like the following code:
MyDAO MyDAO = new MyDAO();
List<MyViewModel> _MyDefault = new List<MyViewModel>() {
new MyViewModel{
Prop1= "All",
Prop2 = "Select all"
}
};
ViewBag.MyViewBag=
new SelectList(MyDAO
.MyList().Union(
_MyDefault
), "Prop1", "Prop2");
I don't if anybody else has a better option...
<% if (Model.VariableName == "" || Model.VariableName== null) { %>
<%= html.DropDpwnList("ListName", ((SelectList) ViewData["viewName"], "",
new{stlye=" "})%>
<% } else{ %>
<%= html.DropDpwnList("ListName", ((SelectList) ViewData["viewName"],
Model.VariableName, new{stlye=" "})%>
<% }>