Calling a partial view in mvc3 - asp.net-mvc

This might be a duplicate title but I have a different question. I have this code
public ActionResult _FieldAssignmentView()
{
Shift shift = new Shift();
Person person = new Person();
Signatory sig = new Signatory();
ViewBag.ShiftId = new SelectList(db.Shifts, "ShiftId", "ShiftDesc", shift.ShiftId);
var empid = (from p in db.People join s1 in db.Employees on p.PersonId equals s1.PersonId select new { CompleteName = p.CompleteName, s1.EmployeeId });
ViewBag.EmployeeID = new SelectList(empid, "EmployeeId", "CompleteName", null).OrderBy(m => m.Text);
if (Roles.IsUserInRole(User.Identity.Name, "divisionhead") && Roles.IsUserInRole(User.Identity.Name, "director"))
{
return PartialView("_FieldAssignment");
}
else
{
return PartialView("_FieldAssignmentForEmployee");
}
// return View();
}
Now my question it is possible to return two(2) partial view?.
I have four partial views (1,2,3,4) and I duplicate the view 1 and 4 for the employee log.in to disabled a certain button. For example the employee will log.in view 1 and 4 will return in my else code.
If possible how?. Thanks.

For example the employee will log.in view 1 and 4 will return in my
else code. If possible how?
You can create another container partial view in which you include the other 2 partial views.
LoggedInUserView.cshtml
#Html.Partial("_FieldAssignment")
#Html.Partial("_FieldAssignmentForEmployee")
Now in your else condition, you can return this view
return PartialView("LoggedInUserView.cshtml");
If you want to disable a button in any of these views, You can add a boolean property to your view model and set the value in your action method and use that to conditionally show a disabled/enabled button
public class FieldAssignmentViewModel
{
public bool IsAllowedToAssign {set;get;}
}
and in your action method,
var vm = new FieldAssignmentViewModel();
vm.IsAllowedToAssign = true; // Set this value based on your custom condition.
return View(vm);
Now, the view you are passing this object should be strongly typed to our view model.
_FieldAssignment.cshtml
#model FieldAssignmentViewModel
#using(Html.BeginForm())
{
#if(Model.IsAllowedToAssign)
{
<input type="submit" value="Assign" />
}
else
{
<input type="button" disabled value="Assign" />
}
}

Related

"Object Does not Contain definition for Obtained" ASP.Net MVC [duplicate]

can someone tell me what I'm doing wrong? :-)
I have this simple query:
var sample = from training in _db.Trainings
where training.InstructorID == 10
select new { Something = training.Instructor.UserName };
And I pass this to ViewBag.
ViewBag.Sample = sample;
Then I want to access it in my view like this:
#foreach (var item in ViewBag.Sample) {
#item.Something
}
And I get error message 'object' does not contain a definition for 'Something'. If I put there just #item, I get result { Something = SomeUserName }
Thanks for help.
This cannot be done. ViewBag is dynamic and the problem is that the anonymous type is generated as internal. I would recommend you using a view model:
public class Instructor
{
public string Name { get; set; }
}
and then:
public ActionResult Index()
{
var mdoel = from training in _db.Trainings
where training.InstructorID == 10
select new Instructor {
Name = training.Instructor.UserName
};
return View(model);
}
and in the view:
#model IEnumerable<Instructor>
#foreach (var item in ViewBag.Sample) {
#item.Something
}
If you want to send in ViewData For example and don't want to send in model
you could use the same could as in the upper answer
and in the Controller
enter code here
ViewData[Instractor] = from training in _db.Trainings
where training.InstructorID == 10
select new Instructor {
Name = training.Instructor.UserName
};
and in the view you need to cast this to
`IEnumerable<Instructor>`
but to do this you should use
#model IEnumerable<Instructor>
Then you could do something like this
IEnumerable<instructors> Instructors =(IEnumerable<Instructor>)ViewData[Instractor];
then go with foreach
#foreach (var item in Instructors ) {
#item.Something
}

Reference DropDownList selected value from enclosing Form

I'm just getting started with MVC5 (from WebForms), and dropdownlist bindings are giving me some fits.
I'd like to get this working using a GET request back to the page, with a selected value parameter. I'm hopeful that I can specify the route arguments in the form itself, so I'd like to reference the DDL's SelectedValue.
<p>
#using (Html.BeginForm("Index", "Profile", FormMethod.Get, new { id = WHATDOIPUTHERE} )) {
#Html.AntiForgeryToken()
#Html.DropDownList("ApplicationID", new SelectList(ViewBag.ApplicationList, "ApplicationID", "ApplicationName", ViewBag.SelectedApplicationId), new {onchange = "this.form.submit();"})
}
</p>
I can make it work with a POST form, but that requires a second controller method so I end up with
public ActionResult Index(long? id) {
ConfigManager config = new ConfigManager();
//handle application. default to the first application returned if none is supplied.
ViewBag.ApplicationList = config.GetApplications().ToList();
if (id != null) {
ViewBag.SelectedApplicationId = (long)id;
}
else {
ViewBag.SelectedApplicationId = ViewBag.ApplicationList[0].ApplicationID; //just a safe default, if no param provided.
}
//handle profile list.
List<ProfileViewModel> ps = new List<ProfileViewModel>();
ps = (from p in config.GetProfilesByApp((long)ViewBag.SelectedApplicationId) select new ProfileViewModel(p)).ToList();
return View(ps);
}
//POST: Profile
//read the form post result, and recall Index, passing in the ID.
[HttpPost]
public ActionResult index(FormCollection collection) {
return RedirectToAction("Index", "Profile", new {id = collection["ApplicationId"]});
}
It would be really nice to get rid of the POST method, since this View only ever lists child entities.
What do you think?
You can update your GET action method parameter name to be same as your dropdown name.
I also made some small changes to avoid possible null reference exceptions.
public ActionResult Index(long? ApplicationID) {
var config = new ConfigManager();
var applicationList = config.GetApplications().ToList();
ViewBag.ApplicationList = applicationList ;
if (ApplicationID!= null) {
ViewBag.SelectedApplicationId = ApplicationID.Value;
}
else
{
if(applicationList.Any())
{
ViewBag.SelectedApplicationId = applicationList[0].ApplicationID;
}
}
var ps = new List<ProfileViewModel>();
ps = (from p in config.GetProfilesByApp((long)ViewBag.SelectedApplicationId)
select new ProfileViewModel(p)).ToList();
return View(ps);
}

from data to controller and passing it to form

I'm doing my first steps in mvc and I need help.
I'm passing data from view to this controller and I need to pass the selected items with there details to a different view (that is a form that the user add his email details) and I cant figure out how to .
This is how I'm getting the details to the controller from the submitted form
public ActionResult list()
{
var AllItems = db.menu.ToList();
Mapper.CreateMap<Menu, SelectableMenu>();
return View(AllItems.Select(m => new SelectableMenu { price = m.price, MenuId = m.MenuId, Name = m.Name })
.ToList());
}
[HttpPost]
public ActionResult List(IEnumerable<SelectableMenu> item)
{
var userSelectedMenu = item.Where(m => m.IsSelected).Select(m => m.Name + m.price + m.MenuId);
if (userSelectedMenu != null && userSelectedMenu.Any())
{
return View("bla");
}
return View();
}
Use method ReditectToActionstring actionName, string controllerName, Object routeValues)
for details go to: http://msdn.microsoft.com/en-us/library/dd460311(v=vs.108).aspx
You can return different view using return View("ViewName",model)
For eg:
[HttpPost]
public ActionResult List(IEnumerable<SelectableMenu> item)
{
var userSelectedMenu = item.Where(m => m.IsSelected).Select(m => m.Name + m.price + m.MenuId);
if (userSelectedMenu != null && userSelectedMenu.Any())
{
return View("YourDiffrentViewName",userSelectedMenu); // This will pass your model to your Different view
}
return View();
}
Then in your new view you will have to strongly typed it with your model.
For eg :
Your view will be as follows:
#model ProjectName.models.YourClassName //Your class/model namespace
#using(Html.BeginForm())
{
#Html.TextBoxFor(m => Model.Property) //This will create textbox for your property
<input type="submit" value="Submit" />
}
For more on stronly typed views visit:
http://www.c-sharpcorner.com/UploadFile/abhikumarvatsa/strongly-typed-views-in-mvc/
http://www.howmvcworks.net/OnViews/BuildingAStronglyTypedView
You will need twosteps for this
Step 1
Make a model(it is more effective) use it in a view to pass your data to controller through post in submission of form.
Step 2
Receive the data into the controller method then use
return View("yourNewpage","yourdatamodelobject"); in the controller action to pass the data in the action result view of another page.
Alternatively, if the view is in another controller
then you can receive data here in the post action method and use Return RedirectToAction("ActionName", "ControllerName", "DataModelObject") to pass to a diffrent controller

List of class properties

I have ASP.NET MVC 4 application with one view model class and about 20 views representing this view model. This views differs only by fields which user can edit. I want to merge all that views to one and define list of properties available to editing in strongly-typed manner. Ideally, I want something like this:
// Action
public ActionResult EditAsEngineer(int id)
{
//...
viewModel.PropertiesToChange = new List<???>()
{
v => v.LotNumber,
v => v.ShippingDate,
v => v.Commentary
};
return View(viewModel);
}
// View
if (#Model.PropertiesToChange.Contains(v => v.LotNumber)
{
#Html.TextBoxFor(m => m.LotNumber)
}
else
{
#Model.LotNumber
}
Is it possible to do something like this? Or is there a better solution?
Thank you.
Why note something like this (its pseudo code)
public class Prop{
string PropertyName {get;set;}
bool PropertyEditable {get;set;}
}
public ActionResult EditAsEngineer(int id)
{
viewModel.PropertiesToChange = new List<Prop>()
{
new Prop{PropertyName = LotNumber, PropertyEditable = true}
};
return View(viewModel);
}
#foreach (var pin Model.PropertiesToChange)
{
if(p.PropertyEditable){
#Html.TextBoxFor(p)
}else{
#Html.DisplayFor(p)
}
}
This will solve HALF of your problem. You will also need to create a IEqualityComparer<Expression> for your code to work (the default is to check for ref-equals).
return from p in typeof(T).GetProperties()
let param = System.Linq.Expressions.Expression.Parameter(typeof(T), "x")
let propExp = System.Linq.Expressions.Expression.Property(param, p)
let cast = System.Linq.Expressions.Expression.Convert(propExp, typeof(object))
let displayAttribute = p.CustomAttributes.OfType<System.ComponentModel.DataAnnotations.DisplayAttribute>()
.Select(x => x.Order).DefaultIfEmpty(int.MaxValue).FirstOrDefault()
orderby displayAttribute
select System.Linq.Expressions.Expression.Lambda<Func<T, object>>(cast, new [] {param});
This will list out ALL the properties for T. You would also probabily want to use Expression<Func<T, object>> as the type for defining your list of properties.
This will allow you to create a generic view over all properties.
Also you will want to wrap this in some kind of a cache, as this code is SLOW.

ASP.NET MVC show collection of data in View inside of TextArea

I access data with:
public ActionResult Index()
{
//IEnumerable<ChatLogs> c = from p in db.ChatLogs select p;
//return View(c);
using (var db = new ChatLogContext())
{
var list = db.ChatLogs.ToList();
return View(list);
}
}
I would like to know how to save this collection of data inside of TextArea in View? When we used webforms we could just textBox.Text = textBox.Text + "some data from database";
View:
#model IEnumerable<Chat.Models.ChatLogs>
#Html.TextArea("chatScreen", new { #Class = "chatScreen" })
Thank you.
I'd suggest that you create a view model. For example:
class ChatLogsViewModel
{
public string LogListString { get; set; }
}
Pass that to the view, instead of passing the raw list:
var list = db.ChatLogs.ToList();
var vm = new ChatLogsViewModel { LogListString = /* convert list to single string here */ };
return View(vm);
And in the view, just do something like this:
#model Your.Namespace.ChatLogsViewModel
#Html.TextAreaFor(model => model.LogListString)
Using view models will make your life easier as soon as you decide that you want to pass more information to the view than what a single domain model can carry.
In you .cshtml view, you can access data using #Model
Now, since you have a list, I'd recommend you join it and then assign it to TextArea like
#{var strList = string.Join(" ", Model)}
#Html.TextArea("myTextArea",strList)

Resources