passing vars from Index View to Create View - asp.net-mvc-3

I have 2 dropdownlists on the Index page, and I wish to pass the id's of the selected items to the Create Page, so that I can populate the 2 dropdownlists on the Create page the same as the Index page.
Can you please suggest how I can do this?
At the moment I have this in the Index View :-
#Html.ActionLink("Create New", "Create", new { LeagueId = "ddlLeagues" }, new { ClubId = "ddlClubs" })
And then in the Controller :-
public ActionResult Create(int LeagueId, int ClubId)
{
var _LeagueID = LeagueId;
var _ClubID = ClubId;
Any help is very much appreciated!
Thanks

You can do it as described in this post:
ActionLink routeValue from a TextBox
you basically need to wrap your dropdowns with a form that routes to the create function, and the submit will take care of passing those values to your controller because they will be in the form data:
#using(Html.BeginForm("Create", "Footballer", FormMethod.Get))
{
#Html.DropDownList("LeagueId", Model.Leagues)
#Html.DropDownList("ClubId", Model.Clubs)
<input type="submit" value="Create"/>
}
If you are using a strongly typed model that has Properties for LeagueId and ClubId then use:
#Html.DropDownListFor(m => m.LeagueId, Model.Leagues)
#Html.DropDownListFor(m => m.ClubId, Model.Clubs)
Model.Clubs and Model.League are the IEnumerables that you will use to populate your dropDowns ofcourse
in your controller make sure you have the following:
[HttpGet]
public ActionMethod Create(int LeagueId, int ClubId)
{
//return your Create View
}
[HttpPost]
public ActionMethod Create(FormCollection data)
{
//Perform the create here
}

You can add a route into the application RegisterRoutes :
routes.MapRoute(
"CreateFootBallerWith2ComboOptions",
"{controller}/{action}/{LeagueId}/{ClubId}",
new { controller = "Footballer", action = "Create", LeagueId = -1, ClubId = -1 } // Default Values
);
You can then use what Bassam suggest with the ActionLink which is a Html Helper.
#Html.ActionLink("Create New", "Create",
new { LeagueId = 1, ClubId = 213 });
or use directly from the browser using :
localhost:7246/Footballer/Create/1/5

Related

Paging is not working on GridMvc its Reloading the page

i have two method httpget as
public ActionResult MiReport()
{
return View();
}
and httppost as
public ActionResult GetReportView(string startdate,string enddate) {
ReportModel Obj = new ReportModel( startdate, enddate );
return PartialView("GetReportView",Obj );
}
I am binding grid as
#using GridMvc.Html
<div class="col-md-12">
<h4><strong>REPORT</strong></h4>
#Html.Grid(Model.lstReport).Columns(columns => {
columns.Add(c => c.rep).Titled("REP");
columns.Add(c => c.businessName).Titled("BUSINESS NAME");
columns.Add(c => c.contactNmae).Titled("CONTACT NAME");
}).WithPaging(10)
</div>
I am showing it on View its loading the first 10 row fine but when i am clicking on paging button its calling the Get method and page is getting reloded.
Please help me.
Thanks in Advance.
You need to have your grid be given a name like this (Index.cshtml):
.WithPaging(10, 10, "grid1")
Now in the Index method change it to :
public ActionResult Index(String grid1 = "")
Now when you click on the page, you will see page number in the url as grid1=3,this will be read into parameter grid1 of Index method.
Now in this method check:-
if (!String.IsNullOrEmpty(grid1))
{
//my grid was populated based on PersonnelId selected in some dropdown on the view.You can use the variable in which you stored your key.
id = TempData["TimeOffPersonnelID"].ToString();
}
Hope this helps!!

Partial view returns the Model with empty fields

In a web application using ASP.NET MVC 3, I pass from the controller a model with initialized properties as parameter to a partial view.
The view displays a dialog with a single textbox and on submit an action in the starting controller is fired (the action takes the same model type as parameter). The problem is that at this point only the property relative to the textbox field has a value, the one inserted by the user, while all the others are null, even if in the view they had a proper value.
How can I do in order to keep the properties from the view to controller once the submit button is clicked?
EDIT (added code):
//---------- This method in the controller call the Partial View and pass the model --------
[HttpPost]
public PartialViewResult GetAddCustomFormerClubDialog()
{
var order = GetCurrentOrder();
//Order has here all properties initialized
var dialogModel = new dialogModel<Order> { Entity = order, ControllerAddEntityActionName = "SelectOrder"};
return PartialView("Dialogs/AddOrder", dialogModel);
}
//----------------- Here the Partial View -----------------------------------
#model FifaTMS.TMS.Presentation.Model.Wizard.WizardDialogModel<Club>
<div>
#using (Ajax.BeginForm(Model.ControllerAddEntityActionName, "Orders", new AjaxOptions { HttpMethod = "POST"}))
{
#Html.LabelFor(a => a.Entity.Name)
#Html.TextBoxFor(a => a.Entity.Name, new { #class = "isrequired", style="width: 250px;" })
}
</div>
//-------- Here the method from the view (in the same controller as the first code portion) -----
[HttpPost]
public JsonResult SelectOrder(dialogModel<Order> OrderModel)
{
var order= OrderModel.Entity;
// But order has only the property Name set (in the view)
...
}
I was able to solve the issue simply by adding an hidden field for each needed property, like:
#Html.HiddenFor(p => p.Entity.OrderId, new { id = "OrderId" })
This is because from the PartialView a new instance of the Model is created and sent to the controller. Therefore only the properties set in the form are taken (in my case the only field was the OrderName related to the TextBox in the PartialView).

MVC3: Batch edit attendence and pass the model to a Review Action

I have an Index.cshtml view:
#model AttendenceModel
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm("VisOppsummering", "Attendences", new { AttendenceModel = Model }, FormMethod.Post))
{
#Html.DisplayFor(m => m.ClassName)
#Html.EditorFor(m => m.Attendences)
<button type="submit">Next</button>
}
and an Editor Template Attendence.cshtml:
#model Attendence
#Html.DisplayFor(m => m.Student.Name)
#Html.RadioButtonFor(m => m.Attended, true, new { id = "attendence" })
Teachers can check off all students that attended school and than pass on the changed model to "Review" action where they can review all the attendended and not attended students and Submit. I want to use MVC best practice for this. AttendenceModel has several properties and a generic list Attendences which is List.
I've tried following without success. Model is empty.:
[HttpPost]
public ActionResult Review(AttendenceModel model)
{
if (TryUpdateModel(model))
{
return View(model);
}
}
The following argument to your BeginForm helper is meaningless:
new { AttendenceModel = Model }
you cannot pass complex objects like this. Only simple scalar values. You could use hidden fields in your form for all properties that cannot be edited and visible input fields for the other. Or even better: use a view model which will contain only the properties that can be edited on the form and an additional id which will allow you to fetch the original model from the database and using the TryUpdateModel method update only the properties that were part of the POST request:
[HttpPost]
public ActionResult Review(int id)
{
var model = Repository.GetModel(id);
if (TryUpdateModel(model))
{
return View(model);
}
...
}
as far as the view is concerned it would become:
#model AttendenceViewModel
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm("Review", "SomeControllerName"))
{
#Html.HiddenForm(x => x.Id)
#Html.DisplayFor(m => m.ClassName)
#Html.EditorFor(m => m.Attendences)
<button type="submit">Next</button>
}

Editor templates/BeginForm does not update the values after returning from action but while debugging i see the data

#using (Ajax.BeginForm("SaveItemAndProperties", "HomeBuilder",
new AjaxOptions
{
UpdateTargetId = "divSaveItemAndProps",
InsertionMode = InsertionMode.Replace
}))
{
#Html.EditorForModel()
<input type="submit" value="Submit" />
}
In Model which is called from EditorForModel
#Html.EditorFor(m => m.PropertyValues)
PropertyValues is a list of properties and is a calling a EditorTemplate.
From the Action I change the value and then try to update the data back to the View
[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
public PartialViewResult SaveItemAndProperties(PropertyBuilderViewModel modelValues)
{
//Change on property in modelValues
return PartialView("PropertyBuilderControl", modelmodelValues);
}
When i am debugging i see the data propertly but it does not display in the view.
Any idea why it is doing so.
What are you changing in your action? HTML helpers such as TextBoxFor, HiddenFor, DropDownListFor, CheckBoxFor, ... first look at ModelState when binding and after that in the model. So if in your controller action you intend to do something like this:
[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
public PartialViewResult SaveItemAndProperties(PropertyBuilderViewModel modelValues)
{
modelValues.Foo = "some new value";
return PartialView("PropertyBuilderControl", modelmodelValues);
}
make sure you remove that value from the model state or you won't see any updates once you render the view again:
[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
public PartialViewResult SaveItemAndProperties(PropertyBuilderViewModel modelValues)
{
ModelState.Remove("Foo");
modelValues.Foo = "some new value";
return PartialView("PropertyBuilderControl", modelmodelValues);
}

dropdownlist set selected value in MVC3 Razor

Here is my model:
public class NewsCategoriesModel {
public int NewsCategoriesID { get; set; }
public string NewsCategoriesName { get; set; }
}
My controller:
public ActionResult NewsEdit(int ID, dms_New dsn) {
dsn = (from a in dc.dms_News where a.NewsID == ID select a).FirstOrDefault();
var categories = (from b in dc.dms_NewsCategories select b).ToList();
var selectedValue = dsn.NewsCategoriesID;
SelectList ListCategories = new SelectList(categories, "NewsCategoriesID", "NewsCategoriesName",selectedValue);
// ViewBag.NewsCategoriesID = new SelectList(categories as IEnumerable<dms_NewsCategory>, "NewsCategoriesID", "NewsCategoriesName", dsn.NewsCategoriesID);
ViewBag.NewsCategoriesID = ListCategories;
return View(dsn);
}
And then my view:
#Html.DropDownList("NewsCategoriesID", (SelectList)ViewBag.NewsCategoriesID)
When i run, the DropDownList does not select the value I set.. It is always selecting the first option.
You should use view models and forget about ViewBag Think of it as if it didn't exist. You will see how easier things will become. So define a view model:
public class MyViewModel
{
public int SelectedCategoryId { get; set; }
public IEnumerable<SelectListItem> Categories { get; set; }
}
and then populate this view model from the controller:
public ActionResult NewsEdit(int ID, dms_New dsn)
{
var dsn = (from a in dc.dms_News where a.NewsID == ID select a).FirstOrDefault();
var categories = (from b in dc.dms_NewsCategories select b).ToList();
var model = new MyViewModel
{
SelectedCategoryId = dsn.NewsCategoriesID,
Categories = categories.Select(x => new SelectListItem
{
Value = x.NewsCategoriesID.ToString(),
Text = x.NewsCategoriesName
})
};
return View(model);
}
and finally in your view use the strongly typed DropDownListFor helper:
#model MyViewModel
#Html.DropDownListFor(
x => x.SelectedCategoryId,
Model.Categories
)
just in case someone comes with this question, this is how I do it, please forget about the repository object, I'm using the Repository Pattern, you can use your object context to retrieve the entities. And also don't pay attention to my entity names, my entity type Action has nothing to do with an MVC Action.
Controller:
ViewBag.ActionStatusId = new SelectList(repository.GetAll<ActionStatus>(), "ActionStatusId", "Name", myAction.ActionStatusId);
Pay attention that the last variable of the SelectList constructor is the selected value (object selectedValue)
Then this is my view to render it:
<div class="editor-label">
#Html.LabelFor(model => model.ActionStatusId, "ActionStatus")
</div>
<div class="editor-field">
#Html.DropDownList("ActionStatusId")
#Html.ValidationMessageFor(model => model.ActionStatusId)
</div>
I think it is pretty simple, I hope this helps! :)
I drilled down the formation of the drop down list instead of using #Html.DropDownList(). This is useful if you have to set the value of the dropdown list at runtime in razor instead of controller:
<select id="NewsCategoriesID" name="NewsCategoriesID">
#foreach (SelectListItem option in ViewBag.NewsCategoriesID)
{
<option value="#option.Value" #(option.Value == ViewBag.ValueToSet ? "selected='selected'" : "")>#option.Text</option>
}
</select>
Well its very simple in controller you have somthing like this:
-- Controller
ViewBag.Profile_Id = new SelectList(db.Profiles, "Id", "Name", model.Profile_Id);
--View (Option A)
#Html.DropDownList("Profile_Id")
--View (Option B) --> Send a null value to the list
#Html.DropDownList("Profile_Id", null, "-- Choose --", new { #class = "input-large" })
Replace below line with new updated working code:
#Html.DropDownList("NewsCategoriesID", (SelectList)ViewBag.NewsCategoriesID)
Now Implement new updated working code:
#Html.DropDownListFor(model => model.NewsCategoriesID, ViewBag.NewsCategoriesID as List<SelectListItem>, new {name = "NewsCategoriesID", id = "NewsCategoriesID" })
I want to put the correct answer in here, just in case others are having this problem like I was. If you hate the ViewBag, fine don't use it, but the real problem with the code in the question is that the same name is being used for both the model property and the selectlist as was pointed out by #RickAndMSFT
Simply changing the name of the DropDownList control should resolve the issue, like so:
#Html.DropDownList("NewsCategoriesSelection", (SelectList)ViewBag.NewsCategoriesID)
It doesn't really have anything to do with using the ViewBag or not using the ViewBag as you can have a name collision with the control regardless.
I prefer the lambda form of the DropDownList helper - see MVC 3 Layout Page, Razor Template, and DropdownList
If you want to use the SelectList, then I think this bug report might assist - http://aspnet.codeplex.com/workitem/4932
code bellow, get from, goes
Controller:
int DefaultId = 1;
ViewBag.Person = db.XXXX
.ToList()
.Select(x => new SelectListItem {
Value = x.Id.ToString(),
Text = x.Name,
Selected = (x.Id == DefaultId)
});
View:
#Html.DropDownList("Person")
Note:
ViewBag.Person and #Html.DropDownList("Person") name should be as in view model
To have the IT department selected, when the departments are loaded from tblDepartment table, use the following overloaded constructor of SelectList class. Notice that we are passing a value of 1 for selectedValue parameter.
ViewBag.Departments = new SelectList(db.Departments, "Id", "Name", "1");
For anyone that dont want to or dont make sense to use dropdownlistfor, here is how I did it in jQuery with .NET MVC set up.
Front end Javascript -> getting data from model:
var settings = #Html.Raw(Json.Encode(Model.GlobalSetting.NotificationFrequencySettings));
SelectNotificationSettings(settings);
function SelectNotificationSettings(settings) {
$.each(settings, function (i, value) {
$("#" + value.NotificationItemTypeId + " option[value=" + value.NotificationFrequencyTypeId + "]").prop("selected", true);
});
}
In razor html, you going to have few dropdownlist
#Html.DropDownList(NotificationItemTypeEnum.GenerateSubscriptionNotification.ToString,
notificationFrequencyOptions, optionLabel:=DbRes.T("Default", "CommonLabels"),
htmlAttributes:=New With {.class = "form-control notification-item-type", .id = Convert.ToInt32(NotificationItemTypeEnum.GenerateSubscriptionNotification)})
And when page load, you js function is going to set the selected option based on value that's stored in #model.
Cheers.

Resources