ViewBag SelectList not setting selected value - c#

In my view I have:
<tr class="form-group">
<th><label class="control-label">Technician</label></th>
<td>
#Html.DropDownListFor(model => model.UserID, (IEnumerable<SelectListItem>)ViewBag.TechnicianID)
#Html.ValidationMessageFor(model => model.UserID)
</td>
</tr>
And in my controller:
public ActionResult Edit(int? id) {
var salescall = (id != null) ? db.SalesCalls.Find(id) : new SalesCall();
if (salescall == null) {
return HttpNotFound();
}
ViewBag.CompanyID = new SelectList(db.Companies, "CompanyID", "Name", salescall.CompanyID);
var technicians = db.UserProfiles.Select(t => new {
ID = t.ID,
Name = t.FirstName + " " + t.LastName,
}).OrderBy(t => t.Name);
var techID = CurrentUser.UserID(User);
ViewBag.TechnicianID = new SelectList(technicians, "ID", "Name", techID);
return View(salescall);
}
When I debug, the value being passed to techID is the correct value, and that value does exist in the dropdown, but for some reason it is not being selected. How can I make this work?

Change
ID = t.ID,
new SelectList(technicians, "ID", "Name", techID);
To
Id = t.ID,
new SelectList(technicians, "Id", "Name", techID);
My hunch is you are defining Id in the User model. It should have Id and Name.
EDIT
If techID is an integer, make sure you pass in an anonymous object:
new SelectList(technicians, "Id", "Name", new { Id = techID });

Related

How to set a class only to a current object

I have a reservation system in which the date of the reservation is set by DateFrom - DateTo properties range. Now I want to assign the .alert class to those reservations, which are about to expire (1 day to expiration).
The problem is that If a reservation is about to expire, not only this reservation has .alert class set but also all other reservations, so all <tr> are red even though only one is supposed to. How to bind It only to current reservation?
Condition
foreach(Reservation r in res)
{
bool varovani;
if (r.DateTo.AddDays(-1).Day <= DateTime.Now.Day)
{
varovani = true;
}
else
{
varovani = false;
}
ViewBag.Varovani = varovani;
}
Table in View
<tbody>
#foreach (Reservation r in Model)
{
string alertClass = "";
if (ViewBag.Varovani == true)
{
alertClass = "danger";
}
else
{
alertClass = "";
}
<tr class="#alertClass">
<td>#r.Reserved.Id</td>
<td>#r.Name</td>
<td>#r.DateFrom</td>
<td>#r.DateTo</td>
<td>
#Ajax.ActionLink("Detail", "Detail", "Skies", new { id = r.Reserved.Id }, new AjaxOptions() { InsertionMode = InsertionMode.Replace, UpdateTargetId = "modalContent", OnBegin = "openModalWindow" })
</td>
<td>
#Html.ActionLink("Edit", "Edit", "Reservation", new { id = r.Id }, null)
#Html.ActionLink("Delete", "Delete", "Reservation", new { id = r.Id }, new { onclick = "return confirm('Přejete si opravdu smazat tuto výpujčku? " + r.Name + "');" })
</td>
</tr>
}
</tbody>
The reason this is happening is because ViewBag.Varovani is a single bool value. So every time you iterate through you overwrite the "Varovani" bool value. What you want to do is add a property to you Reservation class:
public class Reservation
{
//Rest of class
public bool Varovani => DateTo.AddDays(-1).Day <= DateTime.Now.Day;
}
Then in your view:
<tbody>
#foreach (Reservation r in Model)
{
<tr class="#(r.Varovani ? "danger" : "")">
<td>#r.Reserved.Id</td>
<td>#r.Name</td>
<td>#r.DateFrom</td>
<td>#r.DateTo</td>
<td>
#Ajax.ActionLink("Detail", "Detail", "Skies", new { id = r.Reserved.Id }, new AjaxOptions() { InsertionMode = InsertionMode.Replace, UpdateTargetId = "modalContent", OnBegin = "openModalWindow" })
</td>
<td>
#Html.ActionLink("Edit", "Edit", "Reservation", new { id = r.Id }, null)
#Html.ActionLink("Delete", "Delete", "Reservation", new { id = r.Id }, new { onclick = "return confirm('Přejete si opravdu smazat tuto výpujčku? " + r.Name + "');" })
</td>
</tr>
}
</tbody>
Alternatively you could perform the logic in your view (although I would not recommend it unless you cannot modify the Reservation class):
#foreach (Reservation r in Model)
{
string alertClass = "";
if (r.DateTo.AddDays(-1).Day <= DateTime.Now.Day)
{
alertClass = "danger";
}
else
{
alertClass = "";
}
//Rest of your original Razor
Disclaimer
I have no idea what "Varovani" means, so only use that as your property name if it describes your logic properly.

Concatenate between two Razor elements and save value in Database table column in the POST ActionResult

I have a static dropdownlist and editor need to take the selected value from the dropdownlist and the written value from the editor and make a concatenation between the two values and save it in a Database table column in the post ActionResult:
This is the View:
#Html.DropDownList("Term.Description", new List<SelectListItem>
{
new SelectListItem{ Text="Winter", Value = "Winter-" },
new SelectListItem{ Text="Spring", Value = "Spring-" },
new SelectListItem{ Text="Fall", Value = "Fall-" },
new SelectListItem{ Text="Summer", Value = "Summer-" }
}, new { #class = "description-text" })
#Html.Editor("TermYear","", new { htmlAttributes = new { #class = "description-text", placeholder = "2018", data_placeholder = " " } })
ActionResult:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Term term, int[] applicantTypes)
{
ModelState.Remove("ApplicantTypes");
if (ModelState.IsValid)
{
if (applicantTypes != null && applicantTypes.Length > 0)
{
foreach (var item in applicantTypes)
{
term.ApplicantTypes.Add(db.ApplicantTypes.FirstOrDefault(x => x.ApplicantTypeID == item));
}
}
db.Terms.Add(term);
db.Configuration.ValidateOnSaveEnabled = false;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.ApplicantTypes = new MultiSelectList(db.ApplicantTypes, "ApplicantTypeID", "Name", term.ApplicantTypes.Select(x => x.ApplicantTypeID));
return View(term);
}
Finally, I need the `Term.Description = DropDownListSelectedValue-EditorValue'

Retrieve all item in listbox and select only those which is in db

Using first method I'm setting default subjects in listbox and using second I'm retrieving only these who was selected.
public void SubjectsList()
{
ViewBag.Subjects =
new SelectList(new[] { "Math", "Physic", "English" }
.Select(x => new { value = x, text = x }),
"Value", "Text");
}
public void SubjectsFromDb(int id)
{
var students = _db.Subjects.AsEnumerable().Where(x => x.StudentId == id).Select(q => new SelectListItem
{
Value = q.Name,
Text = q.Name,
}).ToList();
ViewBag.Subjects = students;
}
How can I do that in Listbox was all Subject but selected were only these which is in db?
Here's my listbox
<div class="form-group">
#Html.LabelFor(model => model.Subject, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.ListBoxFor(model => model.Subject,
new MultiSelectList((IEnumerable<SelectListItem>)ViewBag.Subjects, "Value", "Text"),
new { style = "display:block;" })
#Html.ValidationMessageFor(model => model.Subject)
</div>
</div>
Your model property Subject needs to be public IEnumerable<string> Subject { get; set; } although I would suggest it be renamed to Subjects - plural) and you rename the ViewBag property
The in the GET method, assign the existing subjects to the model
var model = yourModel()
{
Subjects = _db.Subjects.Where(x => x.StudentId == id).Select(q => q.Name);
};
ViewBag.SubjectList = new SelectList(new[] { "Math", "Physic", "English" });
return View(model);
Then in the view its
#Html.ListBoxFor(m => m.Subjects, (SelectList)ViewBag.SubjectList)
Side notes:
There is no need for the extra overhead of creating anonymous
objects to generate the SelectList - you can delete .Select(x => new { value = x, text = x }), "Value", "Text")
Since its already a SelectList, there is no need for the extra
overhead of creating another duplicate SelectList in the
ListBoxFor() method

How to bind value to dropdownlist in asp.net mvc?

I have several textboxes and one dropdownlist like:
for (int i = 0; i < count; i++)
{
<tr>
<td>#Html.DropDownListFor(m => m.GetTimeSheetDetails[i].PROJ_ID, (SelectList)ViewBag.ProjectList, "-- Choose a Project --", new { #id = "ddlProjectvalue" })
</td>
<td>#Html.TextBoxFor(m => m.GetTimeSheetDetails[i].SUN_HRS, new { style = "width:50px; height:30px;", #class = "sunhrs" })
</td>
<td>#Html.TextBoxFor(m => m.GetTimeSheetDetails[i].MON_HRS, new { style = "width:50px; height:30px;", #class = "monhrs" })
</td>
<td>#Html.TextBoxFor(m => m.GetTimeSheetDetails[i].TUE_HRS, new { style = "width:50px; height:30px;", #class = "tuehrs" })
</td>
<td>#Html.TextBoxFor(m => m.GetTimeSheetDetails[i].WED_HRS, new { style = "width:50px; height:30px;", #class = "wedhrs" })
</td>
<td>#Html.TextBoxFor(m => m.GetTimeSheetDetails[i].THU_HRS, new { style = "width:50px; height:30px;", #class = "thurhrs" })
</td>
<td>#Html.TextBoxFor(m => m.GetTimeSheetDetails[i].FRI_HRS, new { style = "width:50px; height:30px;", #class = "frihrs" })
</td>
<td>#Html.TextBoxFor(m => m.GetTimeSheetDetails[i].SAT_HRS, new { style = "width:50px; height:30px;", #class = "sathrs" })
</td>
</tr>
</td>
}
and I want to bind data from database to all the fields , every thing is displaying data perfectly, but dropdown list for proj_id is not showing text even though i am passing value to dropdownlist. i am passing like :
public int GetTimsheetData(int empid, TimesheetModel TimesheetModel)
{
// GetimeSheet all the rows according employee name
var emps = (from n in db.TIMESHEETs
where n.RES_ID == empid
select n).ToList();
int count = emps.Count();
HttpContext.Current.Session["count"] = count;
try
{
List<TimesheetModel> emptyList = new List<TimesheetModel>();
TimesheetModel.GetTimeSheetDetails = emptyList; //taking Empty List and bind to GetTimesheetDetails for Add items into it.
//if Employee Name has more than one record.
if (emps.Count() > 0)
{
foreach (var timeSheet in emps)
{
TimesheetModel item = new TimesheetModel();
item.WEEK_CAL_ID = timeSheet.WEEK_CAL_ID;
item.PROJ_ID = timeSheet.PROJ_ID;
item.SUN_HRS = timeSheet.SUN_HRS;
item.MON_HRS = timeSheet.MON_HRS;
item.TUE_HRS = timeSheet.TUE_HRS;
item.WED_HRS = timeSheet.WED_HRS;
item.THU_HRS = timeSheet.THU_HRS;
item.FRI_HRS = timeSheet.FRI_HRS;
item.SAT_HRS = timeSheet.SAT_HRS;
TimesheetModel.GetTimeSheetDetails.Add(item);
}
}
}
catch (Exception ex)
{
throw ex;
}
return count;
}
and returning to controller like :
public ActionResult GetEmployeeDetails(int empId, string btn, TimesheetModel timesheetModel)
{
Employer_BL employerBL = new Employer_BL();
ViewBag.ProjectList = timesheetModel.getProjects;
//If GetTimesheetData returns morethan one record
if (employerBL.GetTimsheetData(empId, timesheetModel) >= 0)
{
timesheetModel.EMP_ID = empId;
//passes model data to View
return View("Timesheet", timesheetModel);
}
TimesheetModel model = new TimesheetModel();
model.EMP_ID = empId;
return View("Timesheet", model);
}
Where am I doing wrong, dropdownlist showing initial index instead of showing text of passing values. Please help me anyone.
in Separate Class I have written like below to get project names:
public SelectList getProjects()
{
IEnumerable<SelectListItem> projectslist = (from proj in res.PROJECTs where proj.IS_DELETED == "N" select proj).AsEnumerable().Select(projt => new SelectListItem() { Text = projt.NAME, Value = projt.ID.ToString() });
return new SelectList(projectslist, "Value", "Text", PROJ_ID);
}
It depends on the ViewBag.ProjectList which I cannot found on your source code. You could populate it with an object of type IEnumerable<SelectListItem> with one of the item Selected properties set to true.
public IEnumerable<SelectListItem> GetList()
{
return (from proj in res.PROJECTs where proj.IS_DELETED == "N" select proj).AsEnumerable().Select(projt => new SelectListItem() { Text = projt.NAME, Value = projt.ID.ToString() }).ToList();
}
on your controller
ViewBag.ProjectList = GetList();
on your view
#{
var projectList =
new SelectList(ViewBag.ProjectList, "Value", "Text", Model.GetTimeSheetDetails[i].PROJ_ID.ToString())
}
#Html.DropDownListFor(m => m.GetTimeSheetDetails[i].PROJ_ID, projectList, "-- Choose a Project --")
You can try like this method:
[NonAction]
private IEnumerable<SelectListItem> GetData()
{
return new List<SelectListItem>()
{
new SelectListItem(){ Text="--Select--", Value="0"},
new SelectListItem(){ Text="A", Value="1"},
new SelectListItem(){ Text="B", Value="2"},
new SelectListItem(){ Text="C", Value="3"},
};
}
Call this function in Action Method
public ActionResult Create()
{
ViewData["categories"] = GetData();
return View();
}
On your html page:
<%= Html.DropDownList("cat", (IEnumerable<SelectListItem>)ViewData["categories"])%>
You can use viewbag . in your controller you can read your data from the database :
public ActionResult Create()
{
ViewBag.ClassName = new SelectList(objclassrep.GetClasslist(), "Id", "ClassName");
}
And in your view model you can read the data from controller like this :
<div class="editor-label">
#Html.LabelFor(model => model.ClassId)
</div>
<div class="editor-field">
#Html.DropDownListFor(x => x.ClassId, (SelectList)ViewBag.ClassName);
#Html.ValidationMessageFor(model => model.ClassId)
</div>
This code automatically binds ids of your data to DDL Here is class id.
This is th getClassList function :
public List<Class> GetClasslist()
{
return _dbcontext.Classes.ToList();
}

NopCommerce - Page Navigation Issue with Telerik-Grid

I am using nopCommerce. I have used telerik-grid to bind data in a table and data binded successfully. I have create method named "EditContact" for Edit operation. but when i clicked Edit link to redirect page named "_CreateOrUpdateContact.cshtml", i got "Page not found" page.
telerik-grid code :
#(Html.Telerik().Grid<AddressModel>()
.Name("vendors-grid")
.Columns(columns =>
{
columns.Bound(x => x.CountryName)
.Width(200).Centered();
columns.Bound(x => x.FirstName)
.Width(200).Centered();
columns.Bound(x => x.LastName)
.Width(200).Centered();
columns.Bound(x => x.Title)
.Width(200).Centered();
columns.Bound(x => x.Email)
.Width(200).Centered();
columns.Bound(x => x.PhoneNumber)
.Width(200).Centered();
columns.Bound(x => x.Address1)
.Width(200).Centered();
columns.Bound(x => x.Id)
.Width(200)
.Centered()
.Template(x => Html.ActionLink(T("Admin.Common.Edit").Text, "Edit", new { id = x.Id }))
.ClientTemplate("" + T("Admin.Common.Edit").Text + "")
.Title(T("Admin.Common.Edit").Text);
columns.Bound(x => x.Id)
.Template(x => Html.ActionLink(T("Admin.Common.Delete").Text, "Delete", new { id = x.Id }))
.ClientTemplate("" + T("Admin.Common.Delete").Text + "")
.Centered().Width(200)
.HeaderTemplate(T("Admin.Common.Delete").Text);
})
.Pageable(settings => settings.PageSize(gridPageSize).Position(GridPagerPosition.Both))
.DataBinding(dataBinding => dataBinding.Ajax().Select("ListContacts", "VendorDetails",new { vendorId = Model.Id }))
.EnableCustomBinding(true))
EditContact.cshtml Code:
#model AddressModel
#using (Html.BeginForm())
{
<div class="section-header">
<div class="options">
<input type="submit" name="save" class="t-button" value="#T("Admin.Common.Save")" />
<input type="submit" name="save-continue" class="t-button" value="#T("Admin.Common.SaveContinue")" />
</div>
</div>
#Html.Partial("_CreateOrUpdateContact", Model)
}
#Html.DeleteConfirmation("vendor-delete")
VendorDetailsController Methods:
[HttpPost, GridAction(EnableCustomBinding = true)]
public ActionResult ListContacts(int vendorId,GridCommand command)
{
if (!_permissionService.Authorize(StandardPermissionProvider.ManageVendors))
return AccessDeniedView();
var Addresses = _addressService.GetVendorAddresses(vendorId);
var gridModel = new GridModel<AddressModel>
{
Data = Addresses.Select(x =>
{
var a = new AddressModel();
PrepareAddressModel(a, x, false);
return a;
}),
Total = Addresses.Count,
};
return new JsonResult
{
Data = gridModel
};
}
// edit vendor contact
public ActionResult EditContact(int id)
{
if (!_permissionService.Authorize(StandardPermissionProvider.ManageVendors))
return AccessDeniedView();
var address = _addressService.GetAddressById(id);
int vendorId = _vendorContactService.GetVendorIdByAddressId(address.Id);
if (address == null)
//No Address found
return RedirectToAction("Edit", new { id = vendorId });
var model = new AddressModel();
model.VendorId = vendorId;
//Ordering Method
model.AvailableCountries.Add(new SelectListItem() { Text = "-- Select --", Value = "0" });
foreach (var c in _countryService.GetAllCountries(true))
model.AvailableCountries.Add(new SelectListItem() { Text = c.Name, Value = c.Id.ToString() });
PrepareAddressModel(model, address, false);
return View(model);
}
Am i doing something wrong?
How can i redirect from telerik grid- Edit Link to _CreateOrUpdateContact.cshtml page?
Please, check if "_CreateOrUpdateContact.cshtml" is in the same location with "EditContact.cshtml". I will suggest you to debug the code. Put a breakpoint at "public ActionResult EditContact(int id)" then check if debug point is hit after clicking the edit link from grid. If it is not hit then there may be some problem in route.
It would be better if you can provide the screen shot of the error you found
you can check the route here in the telerik-grid
columns.Bound(x => x.Id)
.Width(200)
.Centered()
.Template(x => Html.ActionLink(T("Admin.Common.Edit").Text, "Edit", new { id = x.Id }))
.ClientTemplate("" + T("Admin.Common.Edit").Text + "")
.Title(T("Admin.Common.Edit").Text);
as I think the route had a problem I should be like that
columns.Bound(x => x.Id)
.Width(200)
.Centered()
.Template(x => Html.ActionLink(T("Admin.Common.Edit").Text, "EditContact", new { id = x.Id }))
.ClientTemplate("" + T("Admin.Common.Edit").Text + "")
.Title(T("Admin.Common.Edit").Text);

Categories