I am using `#Html.Textbox("searchString") in Razor view page. I need this value of textbox in
#Html.ActionLink("View Items", "Index", new { id = item.transaction_id, searchString = "Value of textbox"}).
Of course the search string part in html action link is not working right now but i need this as i have specific route which works according to search string.
How do i pass value of textbox to action link?
i check this this,this,this and this.
What i tried is
<script type = "text/javascript">
var value = document.getElementbyID("searchString").Text;
var link = #Html.ActionLink("View Items", "Index", new { id = item.transaction_id, searchString = -1});
link.replace(-1,value);
</script>
Still no luck. I understand Razor renders at server side.
UPDATE
i have following textbox on the top of view:
#using (Html.BeginForm("Index", "trans_junction", FormMethod.Get))
{
<p>
Request No: #Html.TextBox("searchString")
<span><input type="submit" value="Search Request" /></span>
</p>
}
This textbox is search box in which user can search items.
there is an Action link as follows:
#Html.ActionLink("View Items", "Index", new { id = item.transaction_id }) |
and a route config:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}/{searchString}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional, searchString= UrlParameter.Optional }
);
}
}
Now i need to pass the values as my route map via actionlink. As suggested in answer by StephenMuecke, i tried to modify my #using (Html.BeginForm("Index", "trans_junction", FormMethod.Get)) with #using (Html.BeginForm("Index", "trans_junction", new { id = item.transaction_id }, FormMethod.Get))
but item is not accessible there.
When user click search button, url is http://localhost:57286/trans_junction/Index?searchString=20
if user click on Action link url is http://localhost:57286/trans_junction/Index/88
but i actually need is http://localhost:57286/trans_junction/Index/88/20
which preserve the the result of search and also pass the id.
I am adding screenshots for better understanding.
This is index view without search.
This is search result with searchString = 10.
This is after clicking the action link i.e. View Items, Here search results are not preserved.
Rather than manually trying to manipulate a link using javascript, use a form with method="get". Inside your loop
#using (Html.BeginForm("Index", "trans_junction", new { id = item.transaction_id }, FormMethod.Get))
{
#Html.TextBox("SearchString")
<button type="submit">View Items"</button> // style as a link if desired
}
which will make a GET call to
[HttpGet]
public ActionResult Index(int id, string searchString)
which assumes you have a specific route definition with
url: "trans_junction/Index/{id}/{searchstring}",
defaults: new { controller = "trans_junction", action = "Index" }
Edit (based on updated question details)
When your returning the filtered results, you will also need to pass back the value of searchString to the view so that in can be used to generate the route value in the ActionLink() methods, for example
ViewBag.Filter = searchString;
return View(....);
and then modify the links to
#Html.ActionLink("View Items", "Index", new { id = item.transaction_id, searchString = ViewBag.Filter })
You need to set the value on an event such as clicking on the ActionLink otherwise how do you know the value of the searchString textbox to replace in the Actionlink. Add this javascript on your page.
$(function(){
$("#myLink").click(function(){
var link = $(this).attr("href");
link.replace(-1, $(#searchString).val());
var link = $(this).attr("href", link);
});
});
And you Razor view actionlink needs to be
#Html.ActionLink("View Items", "Index", new { id = item.transaction_id, searchString = "-1"})
Try:
#{
var value = Request.Form["inputID"];
}
p.s. why aren't you using a form in stead of the link and submit the form when someone enters a searchString?
whoever downvoted this answer you could argument why or come up with a better solution? because in his case, searchString = Request.Form["inputID"]; should do what he is asking for.
Related
I have url problem when doing search on page. So, I have Index View with a year textbox and a search button inside a form using GET method
Index.cshtml
#using (Html.BeginForm("Search", "Service", new { Year = Model.Year }, FormMethod.Get))
{
<p>
<div class="form-inline">
#Html.EditorFor(model => model.Year, new { htmlAttributes = new { #class = "form-control", #placeholder = "Enter Year" } })
<button type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-search"></span> Search</button>
</div>
</p>
}
I put Search as actionName in BeginForm because when redirect to Service/Index the service data should not be loaded at the first time. So, I'm using another Action, "Search" to handle this request, if the user doesn't enter the year then it will load all of the data, but if the user enter the year it will load the data based on the year.
Here is the controller to handle the request
ServiceController.cs
public ActionResult Index()
{
var vm = new ServiceIndexViewModel();
return View(vm);
}
public async Task<ActionResult> Search(int? year)
{
var vm = new ServiceIndexViewModel();
if (ModelState.IsValid)
{
var list = await service.Search(year);
vm.Services = AutoMapper.Mapper.Map<IEnumerable<ServiceListViewModel>>(list);
}
return View("Index", vm);
}
and the custom route to handle the routing
RouteConfig.cs
routes.MapRoute(
"ServiceSearch",
"Service/Search/{Year}",
new { controller = "Service", action = "Search", Year = UrlParameter.Optional }
);
// default route
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Company", action = "Index", id = UrlParameter.Optional }
);
but I've got the url like this:
http://localhost:18132/Service/Search?Year= or http://localhost:18132/Service/Search?Year=2017
and I want the url to be displayed like this
http://localhost:18132/Service/Search or http://localhost:18132/Service/Search/Year/2017
What's wrong with my routing? How to solve this?
First of all your route should be defined like this:
routes.MapRoute(
"ServiceSearch",
"Service/Search/Year/{Year}",
new { controller = "Service", action = "Search", Year = UrlParameter.Optional });
But your problem is something else your code is not falling to this defined route and it falls to the default route. Make sure that the default route is bellow this route if it's still not working comment me here and I will tell you what I have in my mind.
I have a weird problem with some routing in MVC. Here's my scenario:
The user gets presented to the front page, once visiting the site: testproject.com:57416/Home.
The user has a menu on the left side, with the menu item "Solutions".
The user presses the menu item "Solutions" and the menu item expands, showing 5 sub items.
The user presses the sub item "Demo", and redirects to testproject.com:57416/Solutions/SetLayout?layoutString=page1%7Csize15
As the param layoutString is defined, the grid (DevExpress) know how to filter the data to show.
The grid is presented to the user, and (s)he can now navigate around the grid, manipulating the layout.
The user now wants to see the clean Demo layout again, and (s)he presses the menu item "Solutions" -> sub item "Demo".
The action ActionResult SetLayout(string layoutString) is not hit in this case, but instead the action ActionResult Index() is hit, thereby not setting the layout as the layoutString is not sent in as a param
The url that the user is redirected to, looks like this: testproejct.com:57416/Solutions?undefined=undefined
This might be a bit tiresome to read through, but it's the best way possible for me to explain my scenario as I have never seen anything like this before in MVC. I truly have no idea what's going on, and why the action ActionResult SetLayout(string layoutString) is not hit the second time.
I suppose I should show some code so we can narrow down the possibilities.
_Layout.cshtml (has menu items)
<li class="has-submenu">
Solutions
<ul class="nav sub-menu-list">
<li>
#Html.ActionLink("Demos", "SetLayout", "Solutions", new { layoutString = "page1|size15" }, null)
</li>
</ul>
</li>
ActionResult SetLayout(string layoutString)
public ActionResult SetLayout(string layoutString)
{
Session["Layout"] = layoutString;
return RedirectToAction("Index", "Solutions");
}
ActionResult Index()
public ActionResult Index ()
{
using(var db = new DataBasecontext())
{
var list = db.Solutions.ToList();
return View(list);
}
}
EDIT
I've found out that this only happens when I'm inside the same controller. The controller holding the action ActionResult SetLayout(string layoutString) is the SolutionsController. If I'm coming from, let's say the AccountController everything works fine, but changing from SolutionsController to another action in the SolutionsController doesn't work.
Come to think of it, could have something to do with my map routes?
routes.MapRoute(
name: "ControllerIdActionId",
url: "{controller}/{id}/{action}/{id2}",
default : new { id2 = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
default : new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Solutions",
url: "{controller}/{id}/{action}",
default : new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Seems that the layoutString parameter has missing parameter value on its second firing, thus empty string value inserted into Session key (and Javascript function related to that Session treat the empty string as undefined).
public ActionResult SetLayout(String layoutString)
{
// Test if the string is null or empty before filling session key,
// if it is empty one, leave the session key as is
if (!String.IsNullOrEmpty(layoutString)) {
Session["Layout"] = layoutString;
}
return RedirectToAction("Index", "Solutions");
}
Perhaps this is not the best way to do, I just viewed from SetLayout method perspective to fill Session key with proper query string.
Pass 5th parameter as null in your actionlink as below:
#Html.ActionLink("Demos", "SetLayout", "Solutions", new { layoutString = "page1|size15" },null)
I have not tested it but may be it is the issue..
I managed to solve the problem on my own.
I'm not quite sure what the issue was, but changing the Html.ActionLink() into Html.RouteLink()'s I was able to define what MapRoute to use.
I solved it by using the following MapRoute
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
)
I could then use the Html.RouteLink like so:
Html.Routelink("Demos", //Display text
"Default", //The MapRoute to use
new { layoutString = "page1|size15|", //The param (layoutString)
controller = "Solutions", //The controller
action = "SetLayout" }) //The action
I made no changes to the action:
public ActionResult SetLayout(string layoutString)
{
Session["Layout"] = layoutString;
return RedirectToAction("Index", "Solutions");
}
I recently discovered Areas in ASP.NET MVC 4, which I have successfully implemented, but I'm running into troubles with the #Html.ActionLink helper in my Razor views. The URL this helper generates always seems to be relative to the URL of the current page.
I have my web site configured in IIS 7 (Win7) as an Application virtual directory at /Foo.
I have two Areas registered: Admin and Blogs. I have the default code in the AdminAreaRegistration.cs and BlogsAreaRegistration.cs files. I added namespaces = new[] { "MvcProject.Controllers" } to the defaults of the default RouteConfig:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new {
controller = "Home", action = "Index", id = UrlParameter.Optional,
namespaces = new[] { "MvcProject.Controllers" }
}
);
}
}
When I go to the home page for my site: http://localhost/Foo, it correctly loads the "home" page for my site. At this point, all the action links have their correct URLs.
Sample code from MvcProject/Views/Shared/_Layout.cshtml
<h2>Main Navigation</h2>
<ul>
<li>#Html.ActionLink("Home", "Index", "Home")</li>
<li>#Html.ActionLink("Blogs", "Index", "Blogs/Home")</li>
<li>#Html.ActionLink("Admin", "Index", "Admin/Home")</li>
</ul>
This is correctly rendering the HTML as:
<h2>Main Navigation</h2>
<ul>
<li>Home</li>
<li><a href="/Foo/Blogs/Home"></li>
<li><a href="/Foo/Admin/Home"></li>
</ul>
When I navigate in the browser to "Blogs" for instance, this URL correctly loads in the browser: /Foo/Blogs/Home.
Now the links in my main navigation change their URLs to:
<h2>Main Navigation</h2>
<ul>
<li>Home</li>
<li><a href="/Foo/Blogs/Blogs/Home"></li>
<li><a href="/Foo/Blogs/Admin/Home"></li>
</ul>
Notice that "Blogs/" is appended to the IIS virtual directory name, so that /Foo/Blogs/Home is now /Foo/Blogs/Blogs/Home.
The controllers and views are rendering fine, it's just the calls to #Html.ActionLink in my MvcProject/Views/Shared/_Layout.cshtml view are not working as I expected.
It feels like I'm missing something trivial, but no amount of searching has come up with an answer. Every blog post and tutorial I've found for implementing Areas in ASP.NET MVC4 makes no mention of changes in how #Html.ActionLink behaves.
I hate answering my own question, but #Matt Bodily put me on the right track.
The #Html.Action method actually invokes a controller and renders the view, so that wouldn't work to create a snippet of HTML in my case, as this was causing a recursive function call resulting in a StackOverflowException. The #Url.Action(action, controller, { area = "abc" }) does indeed return the URL, but I finally discovered an overload of Html.ActionLink that provided a better solution for my case:
#Html.ActionLink("Admin", "Index", "Home", new { area = "Admin" }, null)
Note: , null is significant in this case, to match the right signature.
Documentation: #Html.ActionLink (LinkExtensions.ActionLink)
Documentation for this particular overload:
LinkExtensions.ActionLink(Controller, Action, Text, RouteArgs, HtmlAttributes)
It's been difficult to find documentation for these helpers. I tend to search for "Html.ActionLink" when I probably should have searched for "LinkExtensions.ActionLink", if that helps anyone in the future.
Still marking Matt's response as the answer.
Edit: Found yet another HTML helper to solve this:
#Html.RouteLink("Admin", new { action = "Index", controller = "Home", area = "Admin" })
How I redirect to an area is add it as a parameter
#Html.Action("Action", "Controller", new { area = "AreaName" })
for the href portion of a link I use
#Url.Action("Action", "Controller", new { area = "AreaName" })
Just to add up my bit:
Remember, you're gonna need to have at least 2 areas in your MVC application to get the routeValues: { area="" } working; otherwise the area value will be used as a query-string parameter and you link will look like this: /?area=
If you don't have at least 2 areas, you can fix this behavior by:
1. editing the default route in RouteConfig.cs like this:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { area = "", controller = "Home", action = "Index", id = UrlParameter.Optional }
);
OR
2. Adding a dummy area to your MVC project.
Below are some of the way by which you can create a link button in MVC.
#Html.ActionLink("Admin", "Index", "Home", new { area = "Admin" }, null)
#Html.RouteLink("Admin", new { action = "Index", controller = "Home", area = "Admin" })
#Html.Action("Action", "Controller", new { area = "AreaName" })
#Url.Action("Action", "Controller", new { area = "AreaName" })
<a class="ui-btn" data-val="abc" href="/Home/Edit/ANTON">Edit</a>
<a data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#CustomerList" href="/Home/Germany">Customer from Germany</a>
<a data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#CustomerList" href="/Home/Mexico">Customer from Mexico</a>
Hope this will help you.
I want to pass the Html.Textbox value to a controller from anchor tag, so that I can search the value passed to a controller. Please tell me how can I achieve this.
#p
public ActionResult Index(string String)
{
}
#Html.TextBox("String")
use jquery
#Html.TextBox("String", null, new { #class="txtString" })
#p
then in your script
$('.txtString').on('blur', function(){
$('.linkAction').attr('src', '#Url.Action("Index", "Home", new { text = "----" })'.replace("----", $('.txtString').val()));
});
You don't have to use jQuery. If you're doing a HttpPost, you just need the "name" of the textbox.
On your page:
#using (Html.BeginForm("Index", FormMethod.Post)) {
#Html.TextBox(string.Empty, new { name = "textbox" })
<input type="submit">Submit</input>
}
Then in your controller:
[HttpPost]
public ActionResult Index(string textbox) {
// The name of the string parameter must match the name given to the TextBox element on the page.
}
#using (Html.BeginForm("Index", "Home", null, FormMethod.Post, new {#id = "my-form"}))
{
#Html.TextBox("String")
}
<a href="javascript:document.getElementById('my-form').submit();>#p</a>
You can use FormMethod.Post or FormMethod.Get. The latter will append ?String= to the url.
Good Day,
This is my first question, so please be kind. I have just made the move from forms to mvc.
I have made the following route (below). I constructed a partial view that also contains 2 other partial views (as seen below).
When submitted the url will be something like 'Find/Index?Region=3&Interest=1'
What is the best way to create a friendly url matching the route defined
'Find/Index/In-Wales-3/Sport-1'? I could post and then redirect, but I thought this maybe inefficient. A better approach maybe to use jquery?
Please also indicate if the design used is correct or if it could be improved upon? The reason for separating the views, is because they are used on multiple views.
Thanks in advance!
Route Config
routes.MapRoute(
name: "Find",
url: "{controller}/{action}/In-{region}-{rid}/{interest}-{iid}",
defaults: new { controller = "Find", action = "Index", region = UrlParameter.Optional,
rid = UrlParameter.Optional,
interest = UrlParameter.Optional,
iid = UrlParameter.Optional
});
Partial View That Is Rendered On Master Page
#model SimpleFriendFinderModel
<h1>Find</h1>
<div>
#using (Html.BeginForm("Index", "Find", FormMethod.Get))
{
#Html.Partial("_RegionDropDown", #Model.Regions)
#Html.Partial("_InterestDropDown", #Model.Interests)
<div>
<button>SEARCH</button>
</div>
}
</div>
Region Partial View
#model IEnumerable<Region>
<select id="Region" name="Region">
<option>REGION</option>
#{ foreach(var item in Model) {
<option value="#item.RegionID">#item.RegionName</option>
}
}
</select>
The other partial view is a replica of Region but obviously a different model.
For the PartialViews; it is the way to go if you re-use it on other pages. You can think of it a bit as 'encapsulated logic'.
UPDATE: Ignore the above if you are just using a partial view for a dropdownlist. There is a HtmlHelper, Html.DropDownListFor() for that.
For the first part; the order is relevant:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Pretty",
url: "{controller}/{action}-{id}/Something",
defaults: new { controller = "Test", action = "Foo", id = UrlParameter.Optional }
);
//default route
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
for example will work if you would like to format the URL like:
http://local:23802/Test/Foo-5/Something