I am new in Mvc3 my problem is when i simply create MultiSelectList from the data base its working fine but i want to search on the basis of MultiSelectList selected values i cant handle how to do this
http://www.asp.net/mvc/tutorials/javascript/working-with-the-dropdownlist-box-and-jquery/using-the-dropdownlist-helper-with-aspnet-mvc
using above link i am able to create MultiSelectList
kindly help me how to search records on the basis of selected values from MultiSelectList
my question is that should i create another View to fetch record from database but problem is what will be the database query to select records
If you look at the sample source code, you can see that they load the list of countries into a multiselectlist:
public ActionResult MultiCountryVM() {
return View(new CountryViewModel());
}
public ActionResult MultiSelectCountry() {
ViewBag.Countrieslist = GetCountries(null);
return View();
}
private MultiSelectList GetCountries(string[] selectedValues) {
List<Country> Countries = new List<Country>()
{
new Country() { ID = 1, Name= "United States" },
new Country() { ID = 2, Name= "Canada" },
new Country() { ID = 3, Name= "UK" },
new Country() { ID = 4, Name= "China" },
new Country() { ID = 5, Name= "Japan" }
};
return new MultiSelectList(Countries, "ID", "Name", selectedValues);
}
Then on the form post they store the selected values into the ViewBag:
[HttpPost]
public ActionResult MultiSelectCountry(FormCollection form) {
ViewBag.YouSelected = form["Countries"];
string selectedValues = form["Countries"];
ViewBag.Countrieslist = GetCountries(selectedValues.Split(','));
return View();
}
It looks like they are putting it into a ViewBag so they can pass it to the MultiCountryVM view, and not actually doing any query with the data. If you wanted to do a query, you would just create a LINQ query using an appropriate context, which you'd also have to write since they only have context for the music entities.
Related
I have very complex code. I'm developing a web application for many restaurants where people can order online. I have two tables and models for Order, which contains information about User, and OrderDetails which has MenuItems. I created ShoppingCartController which has a ProcessOrder action
public ActionResult ProcessOrder(FormCollection frc)
{
List<Cart> lstCart = (List<Cart>)Session[strCart];
Order order = new Order()
{
Name = frc["Name"],
UserId = User.Identity.GetUserId(),
OrderTime = DateTimeOffset.UtcNow,
PaymentType = "Cash",
Status = "Processing"
};
db.Orders.Add(order);
db.SaveChanges();
foreach (Cart cart in lstCart)
{
OrderDetail orderDetail = new OrderDetail()
{
OrderId = order.Id,
MenuId = cart.Menu.Id,
Quantity = cart.Quantity,
Price = cart.Menu.Price,
RestaurantId = cart.Menu.RestaurantId
};
db.OrderDetails.Add(orderDetail);
db.SaveChanges();
}
Session.Remove(strCart);
return View("OrderSuccess");
}
Also I created an OrderController for displaying list of orders:
public ActionResult Index(int? restaurantId = null)
{
var orders = db.Orders.Include(o => o.User)
.Include(p => p.OrderDetails)
.OrderByDescending(x => x.Id);
return View(orders.ToList());
}
Here I just added restaurantId parameter.
And now I want to display orders by RestaurantId. I thought about taking RestaurantId from OrderDetails->Menu->RestaurantId, but I don't think that it works because OrderDetails of each order can have many RestaurantId.
Should I add RestaurantId column in Order table? Can you suggest an approach?
Order detail has both orderId and RestaurantId thats the table you need to query from!
So I have two models with a one to many relationship. Callout, and shift offer. Callout can have many shift offers.
I want to pass my callout_id to the shift-offer controller. I've done this by modifying the Index() method as follows:
public async Task<ActionResult> Index(long? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
Debug.WriteLine("Callout ID cannot be null");
}
var shift_Offers = db.Shift_Offers.Where(s => s.callout_id_fk == id);
return View(await shift_Offers.ToListAsync());
}
I've also modified one of my HTML action links to call a different page:
#Html.ActionLink("View Callout",
"Index",
"ShiftOffer",
new { area = ""},
new { id=item.callout_id_pk }) |
But here's the kicker, when I try to call Index(long id), it's throwing that bad request error. Why isn't my ID being passed like it is with the default scaffolded links?
Try below
#Html.ActionLink("View Callout",
"Index",
"ShiftOffer",
new { id=item.callout_id_pk },
new { area = ""})
I have a SelectList in my action method. The selected value for SelectList is coming from the action method parameter. The action and view are simple like below:
// Recipe Action
public ActionResult Recipe(int? recipeId)
{
ViewBag.RecipeID = new SelectList(_recipsRecipes, "RecipeID", "RecipeName", recipeId);
return View(new Recipe());
}
//Recipe View
#model RecipeDemo.Models.Recipe
#Html.DropDownList("RecipeID", (SelectList)ViewBag.RecipeID, string.Empty)
I'm using ActionLink below to call the Recipe action.
#Html.ActionLink("Recipe", "Recipe", "Home", new { recipeId = 2 }, null)
It works like I expect, the DropDownList is showing the selected value as the No. 2 (recipeId = 2) item.
Problem
When I change the Recipe action parameter by using route id, like below:
//Recipe View
public ActionResult Recipe(int? id)
{
ViewBag.RecipeID = new SelectList(_recipsRecipes, "RecipeID", "RecipeName", id);
return View(new Recipe());
}
//Recipe View (Same View as above)
#model RecipeDemo.Models.Recipe
#Html.DropDownList("RecipeID", (SelectList)ViewBag.RecipeID, string.Empty)
And I'm using ActionLink below to call the Recipe action.
#Html.ActionLink("Recipe", "Recipe", "Home", new { id = 2 }, null)
The DropDownList is NOT showing the selected value, (id = 2) item. The selection is instead empty.
But I have the correct id value in the SelectList. see below:
Why is this, does anyone know the explanation?
Update:
The model is below:
public class Recipe
{
public int RecipeID { get; set; }
public string RecipeName { get; set; }
}
Well that was certainly interesting. After first confirming the issue with the code you provided, I experimented around and believe I have the root cause. Basically, you are using the same variable name way to often and the model binder appears to be getting confused. You have RecipeId in your route, RecipeId in your View Model and RecipeId as the name of your view bag variable. By altering my variable names, the SelectList works as expected.
The primary issue is naming your SelectList RecipeId which matches a property in your model. When you send the new Recipe(), the model binder is attempting to use that value. In your first example, since you have RecipeId defined in the URL, it is getting it from there. In the second example, there is no RecipeId to pull from the URL and it is null in the model.
Controller
namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
private List<Recipe> Recipes;
public HomeController()
{
Recipes = new List<Recipe>
{
new Recipe {RecipeId = 1, RecipeName = "Test - 1"},
new Recipe {RecipeId = 2, RecipeName = "Test - 2"},
new Recipe {RecipeId = 3, RecipeName = "Test - 3"},
};
}
public ActionResult Index(int? id)
{
ViewBag.MyList = new SelectList(Recipes, "RecipeID", "RecipeName", id);
return View(new Recipe());
}
}
}
Index View
#model MvcApplication1.Models.Recipe
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#Html.DropDownList("MyRecipeId", (SelectList)ViewBag.MyList)
Basically, vary your parameter names a little bit more to help prevent the model binder from getting confused and/or pulling information from the wrong place.
You can verify this in your second example by sending this in your return statement:
Return View(New Recipe{RecipeId = 3});
The option value with 3 will be selected regardless of what the actual Id sent was.
EDIT
An even better option would be to do what I said to do as an example above. By changing your Action to this:
public ActionResult Index(int? id)
{
ViewBag.MyList = new SelectList(Recipes, "RecipeID", "RecipeName");
return View(new Recipe(RecipeId = id));
}
You can leave your view unchanged. Now, the SelectList will pull from the model that you are sending.
I have a pretty simple scenario and I'm sure I'm just missing something obvious. I'm trying to use a ListBox to grab multiple Id's and add them to my model, but no matter what I do, the collection is always null. Here's the code:
The model collections:
public IEnumerable<Model.UserProfile> TravelBuddies { get; set; }
public IEnumerable<int> SelectedTravelBuddies { get; set; }
I populate the TravelBuddies collection in my controller.
The view code:
<div class="module_content">
#if (Model.TravelBuddies.Count() > 0)
{
#Html.ListBoxFor(m => m.SelectedTravelBuddies, new MultiSelectList(Model.TravelBuddies, "Id", "FullName"))
}
else
{
<span>You don't currently have any travel buddies (people who were with you on this trip). Don't worry, you can add some to this trip later if you'd like.</span>
}
</div>
The select list is populated in my view. No problem there. But once I select multiple items and submit my form, the Model.SelectedTravelBuddies collection is always null. Am I missing something obvious? It's been a long night of coding.
Update: Added Controller Code
[HttpGet]
public ActionResult New()
{
Model.Trip trip = new Model.Trip();
ITripService tripService = _container.Resolve<ITripService>();
IUserAccountService userService = _container.Resolve<IUserAccountService>();
int userProfileId = userService.GetUserProfile((Guid)Membership.GetUser().ProviderUserKey).Id;
trip.TripTypes = new SelectList(tripService.GetTripTypes(), "Id", "Name");
trip.TravelBuddies = userService.GetTravelBuddies(userProfileId);
tripService.KillFlightLegTempStorage();
return View(trip);
}
[HttpPost]
public ActionResult New([Bind(Exclude = "TripTypes")] Model.Trip trip)
{
ITripService tripService = _container.Resolve<ITripService>();
if (!ModelState.IsValid)
{
tripService.KillFlightLegTempStorage();
return View(trip);
}
int tripId = tripService.CreateTrip(trip, (Guid)Membership.GetUser().ProviderUserKey);
tripService.KillFlightLegTempStorage();
return RedirectToAction("Details", "Trip", new { id = tripId });
}
Ok so you are binding to SelectedTravelBuddies. When your list is rendered, what is it's name? It's been a long night for me too :) want to make sure it matches the model. Also are you sure the list is in the form element so they are posted?
I am writing an MVC application, and I wanted to do some extra formatting so the phone numbers all are stored the same. To accomplish this I made a simple external function to strip all non-numeric characters and return the formatted string:
public static string FormatPhone(string phone)
{
string[] temp = { "", "", "" };
phone = Regex.Replace(phone, "[^0-9]","");
temp[0] = phone.Substring(0, 3);
temp[1] = phone.Substring(3, 3);
temp[2] = phone.Substring(6);
return string.Format("({0}) {1}-{2}", temp[0], temp[1], temp[2]);
}
There is also regex in place in the model to make sure the entered phone number is a valid one:
[Required(ErrorMessage = "Phone Number is required.")]
[DisplayName("Phone Number:")]
[StringLength(16)]
[RegularExpression("^\\(?([0-9]{3})\\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$",
ErrorMessage = "Please enter a valid phone number.")]
public object phone { get; set; }
This is what I did in the controller:
[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
var customer = customerDB.Customers.Single(c => c.id == id);
try
{
customer.phone = HelperFunctions.FormatPhone(customer.phone);
UpdateModel(customer,"customer");
customerDB.SaveChanges();
return RedirectToAction("Index");
}
catch
{
var viewModel = new CustomerManagerViewModel
{
customer = customerDB.Customers.Single(c => c.id == id)
};
return View(viewModel);
}
}
When I step through this, the string updates then resets back to the format it was before being ran through the function. Also, any of the other fields update with no problem.
Any ideas? Thanks in advance.
Your UpdateModel call is overwriting the customer field. Try swapping these two lines of code:
try
{
UpdateModel(customer,"customer"); <--
customer.phone = HelperFunctions.FormatPhone(customer.phone); <--
customerDB.SaveChanges();
return RedirectToAction("Index");
}