How can i do search inside same page in MVC Razor - asp.net-mvc

How can i do search inside same page in MVC Razor? For example; my page do not any result when open if i search return.i must use IEnumerable<model> for getting result but if i use IEnumerable<model> for empty page, i am getting error.
Search page
#model IEnumerable<SearchResult>
<span>Search results:</span>
<p>
#foreach(var item in Model)
{
#item.Title<br/>
}
</p>

You need to return empty model for such case. for example in controller code:
public ActionResult Test()
{
// some actions
return View(new List<SearchResult>());
}
in that case it will send empty model, and won't fail.

You can create a model that contain the search properties and the result list.
Model
Public class MySearchModel{
public string searchInput { get; set; }
public List<mySearchResultModel> resultList { get; set; }}
Controller
public ActionResult Index()
{
var model = new MySearchModel();
return View(model);
}
[HttpPost]
public ActionResult Index(MySearchModel model)
{
model.searchInput //filter
model.mySearchResultModel = //query where filter
return View(model);
}
View
#model MySearchModel
<div>
#Html.LabelFor(x => x.searchInput)
#Html.TextBoxFor(x => x.searchInput)
</div>
<span>Search results:</span>
#foreach (var item in Model.mySearchResultModel){
#item.Title<br />
}
Another way to accomplish the same is to add your search inputs and map them to the controller action that you are posting using the input name:
Controller
public ActionResult Index()
{
var model = new mySearchResultModel();
return View(model);
}
[HttpPost]
public ActionResult Index(mySearchResultModel model, string searchInput)
{
model.mySearchResultModel = //query where filter (searchInput)
return View(model);
}
View
#model IEnumerable<mySearchResultModel>
<input type="text" name="searchInput"/>
Search results:
#foreach(var item in Model) { #item.Title<br/> }

Related

How do I get a strongly typed DropDownList to bind to a control Action

I've just started a new MVC project and I'm having trouble getting the post result from a form.
This is my Model Class :
public class User
{
public int id { get; set; }
public string name { get; set; }
}
public class TestModel
{
public List<User> users { get; set; }
public User user { get; set; }
public SelectList listSelection { get; set; }
public TestModel()
{
users = new List<User>()
{
new User() {id = 0, name = "Steven"},
new User() {id = 1, name = "Ian"},
new User() {id = 2, name = "Rich"}
};
listSelection = new SelectList(users, "name", "name");
}
}
This is my view class
#model MvcTestApplicaiton.Models.TestModel
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#using (Html.BeginForm())
{
#Html.DropDownListFor(x => x.user, #Model.listSelection)
<p>
<input type="submit" value="Submit" />
</p>
}
#if (#Model.user != null)
{
<p>#Model.user.name</p>
}
And this is my controller :
public class TestModelController : Controller
{
public TestModel model;
//
// GET: /TestModel/
public ActionResult Index()
{
if(model ==null)
model = new TestModel();
return View(model);
}
[HttpPost]
public ActionResult Test(TestModel test)
{
model.user = test.user;
return RedirectToAction("index", "TestModel");
}
}
The drop down list appears just fine but I can't see to get the ActionResult Test function to run. I thought it would just bind itself with reflection but whatever is wrong, I can't see it.
You have two main errors in your code.
As Brett said you're posting to the Index method, but you don't have Index method that supports POST verb. The easiest way to fix is to change Html.BeginForm() with Html.BeginForm("Test", "TestModel")
You're using Html.DropDownListFor in a wrong way. You could pass only a value types there, because don't forget that the View will generate an HTML page. So instead of User in your Model you should have an UserID and in your View you should have #Html.DropDownListFor(x => x.UserID, #Model.listSelection). And finally in your Action you should query your data source to get the details for the user with this ID.
Hope this helps.
Looks like you're posting back to index. Either use a GET Test() action method, or specify the ACTION parameter in BeginForm().
For example,
#using (Html.BeginForm("Test", "TestModel"))
{
#Html.DropDownListFor(x => x.user, #Model.listSelection)
<p>
<input type="submit" value="Submit" />
</p>
}
Or use a view named Test (rename index.cshtml to test.cshtml):
public ActionResult Test()
{
if(model ==null)
model = new TestModel();
return View(model);
}

getting values View data in controller

i did this all but now how to get values being typed in Textbox, password box etc in CONTROLLER. I defined all necessary methods, boxes and buttons etc. So the only problem is to get values in controller and then to send them to model for accessing db data
.csHtml
#using (Html.BeginForm("register","Home", FormMethod.Post, new {id="submitForm"}))
{
<div>
<i>#Html.Label("Name:")</i>
#Html.TextBox("txtboxName")
</div>
<div>
<i>#Html.Label("Email:")</i>
#Html.TextBox("txtboxEmail")
</div>
<div>
<i>#Html.Label("Password:")</i>
#Html.Password("txtboxPassword")
</div>
<div>
<button type="submit" id="btnSubmit" name="Command" value="Submit">Submit</button>
</div>
}
Controller code:
namespace LoginSys.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Registration";
return View();
}
[HttpPost]
public ActionResult register(string command, FormCollection formData )
{
if (command == "submit")
{
var name = formData["txtboxName"];
var email = formData["txtboxEmail"];
}
return View();
}
}
}
i'm intentionally using this way of coding it instead of complex and advance one. Just help me to get values in controller
[HttpPost]
public ActionResult register(YOURMODEL model)
{
//db operation
return View();
}
NOTE: make sure your textbox name should be same as your model name
You should use viewmodels. create a model for the view that can be posted to the action. However, if you wish to continue your current approach you need to change the controller action to something like this:
[HttpPost]
public ActionResult register(string btnSubmit, string txtboxName, string txtboxEmail, string txtboxPassword)
{
if (command == "submit")
{
}
return View();
}
if this doesn't work, you can test it by using this:
[HttpPost]
public ActionResult register(FormCollection form)
{
if (command == "submit")
{
}
return View();
}
When you debug you can check the 'form' parameter and see that your fields exists in the form, and get the proper names for the parameters you need.

ASP.NET MVC Dropdown Selected Item

I have a DropDownListFor that is on my Index page and one in my Create page. Both dropdownlists serve the same purpose.
What I want is when the user selects an item in the Index dropdownlist in the index page, it saves that selected item's value which is a GUID to the session and when the Create page loads, I want the dropdownlist in there to select the item based on the GUID in the session.
At the moment when the user clicks on "Create" and goes to the create page, I am merely setting up an object and sending that object to the Create View.
Edit:
I am sending the user over to the Create page by doing this:
Html.ActionLink("Create New Listing", "Create", null, new { #class = "btn btn-primary" }))
How do I send the GUID of the selecteditem over to the view?
I guess you have a situation like this. Here is the Index view:
#model Models.IndexViewModel
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#using (Html.BeginForm("SaveGuid", "Flow"))
{
Html.DropDownListFor(x => x.SelectedGuid, Model.Guids, new { onchange = "this.form.submit();" });
}
Here is the Index model:
public class IndexViewModel
{
public Guid SelectedGuid { get; set; }
public SelectList Guids { get; set; }
}
The Index and SaveGuid Action look like this:
private List<Guid> Guids = new List<Guid> { Guid.NewGuid(), Guid.NewGuid() }; // for testing only
public ActionResult Index()
{
var model = new IndexViewModel { Guids = new SelectList(Guids, Guids.First()) };
return View(model);
}
public ActionResult SaveGuid(IndexViewModel model)
{
Session["SelectedGuid"] = model.SelectedGuid;
return new RedirectResult("Create");
}
The Create View looks like this...
#model MvcBootStrapApp.Models.CreateViewModel
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm("SaveGuid", "Flow"))
{
#Html.DropDownListFor(x => x.SelectedGuid, Model.Guids, new { onchange = "this.form.submit();" });
}
#using (Html.BeginForm("SaveCreate", "Flow"))
{
// setup other controls
<input type="submit" value="Submit" />
}
Using a CreateViewModel like this...
public class CreateViewModel
{
public Guid SelectedGuid { get; set; }
public SelectList Guids { get; set; }
// include other model properties
}
The Create and CreateSave ActionResults look like this...
public ActionResult Create()
{
Guid selectedGuid = Guids.First();
if (Session["SelectedGuid"] != null)
selectedGuid = (Guid)Session["SelectedGuid"];
return View(new CreateViewModel
{
Guids = new SelectList(Guids, selectedGuid),
SelectedGuid = selectedGuid
});
}
public ActionResult SaveCreate(CreateViewModel model)
{
// save properties
return new RedirectResult("Index");
}
I used two forms to allow both the change of selected Guid and to postback all the Create properties.
If you want to use Session, what I think you need is to use a form to post to an ActionResult to save the dropdownlist's value and then redirect to the Create page.
public ActionResult SaveGuid(Guid value)
{
Session["SelectedGuid"] = value;
return new RedirectResult("Create");
}
Then in your Create ActionResult, pass the Session value to the Create View's Model.
public ActionResult Create()
{
var selectedGuid = (Guid)Session["SelectedGuid"];
return View(new CreateViewModel { SelectedGuid = selectedGuid, /* include other properties */ };
}
In your view you can set the selected option on the SelectList passed to your DropDownListFor...
#Html.DropDownListFor(
x => x.SelectedGuid,
new SelectList(Model.ListOfStuff, "Key", "Value", Model.SelectedGuid)
)

How do I populate HTML content with new values once data has been changed on postback?

I have MVC3 razor application. Once I'm submitting a form and in Action i'm changing ViewModel content, i can't see new values populated.
There was a topic about that in MVC2 where guys told that it may be fixed in MVC3
http://aspnet.codeplex.com/workitem/5089?ProjectName=aspnet
Can you tell if there is an option to do that or what is the better way(workaround) to update UI without JavaScript using postbacks?
Action:
[HttpPost]
public ActionResult Index(MyViewModel model)
{
model.Value = "new value"
return View("Index", model);
}
UI:
#Html.HiddenFor(x => x.Value)
ViewModel:
public class MyViewModel
{
public string Value { get;set; }
}
Looks like it's using the ModelState values that were posted.
If you clear the ModelState using ModelState.Clear() the new value you set should be in the hidden field.
You should use form and to post it to action.
#model MyViewModel
#using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
#Html.HiddenFor(x=>x.Value)
<input type="submit" value="Submit" />
}
Controller
//
public ActionResult Index()
{
MyViewModel model = new MyViewModel();
model.Value = "old value";
return View("Index", model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
//get posted model values (changed value by view "new value")
string changed_value = model.Value;
// you can return model again if your model.State is false or after update
return View("Index", model);
}

MVC checkbox comeing back null

I have a checkbox, but the form is being submitted the value ticked are not being submited...
Html:
#foreach (var radiobutton in Model.InterestedIn)
{
<span > #Html.CheckBox("selected", radiobutton)
<label>#radiobutton</label></span>
<br />
}
Model:
[Display(Name = "Would you be interested in receiving *")]
public IList<string> InterestedIn { get; set; }
Controller:
IList<string> lists = new List<string>();
lists.Insert(0, "Latest News");
lists.Insert(1, "Special Offers");
lists.Insert(1, "New Products");
model.InterestedIn = lists;
PostMethod:
[HttpPost]
public ActionResult Index(Competition model)
{
if (ModelState.IsValid)
{
I don't that your code will compile at all. The CheckBox helper expects a boolean as second argument whereas you are passing it a string.
Try like this:
#model MyViewModel
#using (Html.BeginForm())
{
foreach (var value in Model.InterestedIn)
{
<span>
<input type="checkbox" name="interestedin" value="#Html.AttributeEncode(value)" />
<label>#value</label>
</span>
<br />
}
<button type="submit">OK</button>
}
This assumes that you have the following view model:
public class MyViewModel
{
[Display(Name = "Would you be interested in receiving *")]
public IList<string> InterestedIn { get; set; }
}
and the following controller:
public class HomeController : Controller
{
public ActionResult Index()
{
IList<string> lists = new List<string>();
lists.Insert(0, "Latest News");
lists.Insert(1, "Special Offers");
lists.Insert(1, "New Products");
var model = new MyViewModel();
model.InterestedIn = lists;
return View(model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
return View(model);
}
}
If you want to use the CheckBox or even better the CheckBoxFor helper you will have to adapt your view model so that it no longer has an IList<string> property but an IList<CheckBoxItemViewModel> property where CheckBoxItemViewModel is another view model that will contain the label and a boolean property indicating whether this value has been selected or not.

Resources