get HtmlHelper.textbox value as query string mvc - c#

I have the following idea that i am trying to implement
#foreach (var item in Model)
{
<div>User: #item.Name<br />
Scores: #item.scores<br />
#Html.TextBox("lastvisit");
#Html.ActionLink("Update item", "updateMyItem", new { name = item.Name, lastvisit=????? })
</div>
}
I have seen this SO question Pass text in query string, but that is not what i want..
so my question is ..
in the above code how can I replace the (?????) with the value of the textbox(lastvisit)
and send the value as a querysting in the URL of the action link ??
Notice that I opted not to use a webform for my own reason and I know how to do it with webform.submit(), but my main concern is how to extract the value of #HTMLhelper.textbox()..
:)

Something like this might help. For this to work you need to render unique IDS for the links and textboxes.
Here is an example
Action method with a simple model
public ActionResult Index(int? id)
{
List<MyModel> mod = new List<MyModel>() {
new MyModel { SelectedValue = 1 } ,
new MyModel {SelectedValue = 2},
new MyModel {SelectedValue = 3}
};
return View(mod);
}
And this is the view with the script.
#model List<MVC3Stack.Models.MyModel>
#{
ViewBag.Title = "Home Page";
var i = 1;
}
<h2>#ViewBag.Message</h2>
<script type="text/javascript">
$(document).ready(function () {
var lastVisits = $("input[id*='lastVisit']");
$(lastVisits).each(function () {
var i = this.id.substring(this.id.length - 1);
var link = $("[id='testLink" + i + "']");
if (link) {
var _href = $(link).attr("href");
$(link).attr("href", _href + "&lastvisit=" + $(this).val());
}
});
});
</script>
#foreach (var item in Model)
{
#Html.TextBox("lastVisit" + i, item.SelectedValue )
#Html.ActionLink("TestLink", "Index", "Home", new { id = "testLink" + i });
<br />
i++;
}
<input type="button" value="GetFile" id="getFile" />
here is a snapshot with the changed link
Hope this helps.
EDIT
My bad. Here is the update javascript which can do the trick.
$(document).ready(function () {
var lastVisits = $("input[id*='lastVisit']");
$(lastVisits).each(function () {
$(this).change(function () {
var i = this.id.substring(this.id.length - 1);
var link = $("[id='testLink" + i + "']");
if (link) {
var _href = $(link).attr("href");
$(link).attr("href", _href + "?lastvisit=" + $(this).val());
}
});
});
});

Ok Nilesh I will answer my own question.. but I will cheat from your solution lol cuz it is inspiring .. thanx in advance
<script type="text/javascript">
$(document).ready(function () {
var myMainPath = "updateMyItem";
$("a").each(function(){
var name =$(this).parent("div").child("#itemName").val();
var visit = $(this).parent("div").child("#lastvisit").val();
$(this).attr('href', myMainPath +'?name=' + name + '&lastVisit='+ visit);
});
});
</script>
#foreach (var item in Model)
{
<div>User: <span id="itemName">#item.Name</span><br />
Scores: #item.scores<br />
#Html.TextBox("lastvisit", new { id="lastvisit"});
Update item
</div>
}
you see it can be done by javascript , but i was mistaken to think that you can manipulate it via Razor on the server ..

I know this post is old, but i just started learning MVC thanks to the asp.net/mvc/ website and i faced a similar problem during the tutorial. My Index action expects 2 parameters which define sorting and filtering (through the macthing of a substring) of a set of record displayed in the view. My problem is that i can't sort a filtered subset, since the view is called but no parameter for filtering is passed once i activate the sorting clicking on the link of the header.
#* Index.cshtml *#
#using (Html.BeginForm())
{
<p>
Find by name: #Html.TextBox("SearchString")
<input type="submit" value="Search" />
</p>
}
. . .
<!-- header -->
<table><tr><th>
#Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.NameSortParm })
</th>
. . .
//controller.cs
public ActionResult Index(string sortOrder, string searchString){...}
I thought i needed to access the TextBox, but apparently i just need to use the provided ViewBag object as already seen in this example!
#* Index.cshtml *#
#using (Html.BeginForm())
{
<p>
Find by name: #Html.TextBox("SearchString")
<input type="submit" value="Search" />
</p>
}
. . .
<!-- header -->
<table><tr><th>
#Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.NameSortParm, searchString = ViewBag.SearchString })
</th>
. . .
//controller.cs
public ActionResult Index(string sortOrder, string searchString)
{
ViewBag.SearchString = searchString;
. . .
}
Maybe a similar behaviour could have been used for solving the problem that originated this post, i don't know.

Related

MVC View data doesn't update on jQuery Post but does on Form submit button click

I have a DropDownListFor in my view that selects a date from a list of dates on the server. When I use a jQuery .on "change" $.post operation to post the date I select back to the controller, it correctly gets the updated data value from the server and updates the view model, but then it doesn't get displayed in the browser. It keeps the previous value instead. But if I click a submit button in the view's form instead, it correctly updates the data field with the data from the server. How I post the dropdown list selection determines whether my data field updates correctly or not.
Does anyone have any suggestions on how I can get the jQuery post to update my data field in the view instead of keeping the previous value ?
Here's my View Model:
public class HtmlData
{
public string FileDateListSelection { get; set; }
public List<SelectListItem> FileDateList { get; set; }
public string ServerData { get; set; }
public HtmlData(string selectedDate, List<SelectListItem> fileDateList, string serverData)
{
FileDateListSelection = selectedDate;
FileDateList = fileDateList;
ServerData = serverData;
}
}
Here's my View:
#model MvcJqueryTest.Models.HtmlData
#using (Html.BeginForm("SubmitButtonDateChange", "Home", FormMethod.Post, new { id = "dateSelectionForm" }))
{
<div class="row">
<div class="col-md-4">
<div id="dateList">
#Html.DropDownListFor(m => m.FileDateListSelection, Model.FileDateList)
</div>
</div>
<div class="col-md-2">
<div id="buttons">
<input type="submit" name="submit" value="Fetch" id="fetchButton" />
<input type="submit" name="submit" value="Reset" id="resetButton" />
</div>
</div>
</div>
}
<div class="row">
<div class="col-md-8">
<br />
<h3>#Model.ServerData</h3>
<br />
</div>
</div>
<script type="text/javascript">
$('#FileDateListSelection').on("change", function () {
var menuDateSelected = $('#FileDateListSelection').val();
$.post(
'#Url.Action("JqueryDateChange", "Home")',
{ selectedDate: menuDateSelected },
function (response) {
}
);
});
</script>
Here's my Home Controller Methods:
public ActionResult Index(string dateString)
{
DateTime compareTime = DateTime.Today;
if (!string.IsNullOrEmpty(dateString))
compareTime = DateTime.Parse(dateString);
string quote = "Now is the winter of our discontent";
if (compareTime < DateTime.Today)
quote = "Made glorious summer by this sun of York";
string selectedDate = FileOperations.GetDateList(compareTime, out List<SelectListItem> dateList);
HtmlData hd = new HtmlData(selectedDate, dateList, quote);
return View(hd);
}
[HttpPost]
public ActionResult SubmitButtonDateChange(string FileDateListSelection, string submit)
{
string selectedDate = FileDateListSelection;
if (submit.Equals("Reset", StringComparison.OrdinalIgnoreCase))
selectedDate = DateTime.Now.Date.ToString("d", CultureInfo.GetCultureInfo("en-US"));
return RedirectToAction("Index", "Home", new { dateString = selectedDate });
}
[HttpPost]
public ActionResult JqueryDateChange(string selectedDate)
{
return RedirectToAction("Index", "Home", new { dateString = selectedDate });
}
The GetDateList method just returns a SelectListItem list of dates of files in a folder for the dropdown list, and selects one date as the selected item in the list. If the selected date is before today, the h3 tag containing the view model's "ServerData" property in the view shows "Now is the winter of our discontent". If the selected date is after midnight today, the h3 tag shows "Made glorious summer by this sun of York".
When I change the selection in the dropdown list, the JqueryDateChange controller method executes, and does a RedirectToAction to the Index method with the selected date as a parameter, which fills in the view model with the correct data for the "ServerData" property. But the "ServerData" value in the model is not displayed in the browser. It always retains the previous value, even though I can see the correct value there in the debugger when I set a break on <h3>#Model.ServerData</h3> in the view.
When I click the Fetch or Reset buttons in the view's form, the SubmitButtonDateChange controller method executes, and also does a RedirectToAction to the Index method with the selected date as a parameter. That also fills in the view model with the correct value for the "ServerData" property, but then it is correctly updated in the browser, showing the new value based on the dropdown list selection.
I was originally using $.ajax to post the new dropdown list suggestion, but that had the same problem. I also tried moving the "#Model.ServerData" inside the Form's curly brackets, but that didn't help, either. I found some info about ModelState that I thought might help, but when I looked at it in the debugger, it only had one key/value pair for the dateString parameter, so I couldn't see how to use it to fix the problem.
I think a AJAX solution would suffice to your scenario. You can do the following.
First, define a unique id for your HTML element, where you would show the value of ServerData:
<div class="row">
<div class="col-md-8">
<br />
<h3 id="serverDataID">#Model.ServerData</h3>
<br />
</div>
</div>
Then you need to define your AJAX call like this:
<script type="text/javascript">
$('#FileDateListSelection').on("change", function () {
var menuDateSelected = $('#FileDateListSelection').val();
var json = {
menuDateSelected: menuDateSelected
};
var options = {};
options.url = "#Url.Action("JqueryDateChange", "Home")";
options.type = "POST";
options.data = {"json": JSON.stringify(json)};
options.dataType = "json";
options.success = function (data) {
if (data.status == "true") {
$('#serverDataID').html(data.quoteString);
}
else {
alert("Some Error");
}
};
options.error = function (data) {
alert("Error while calling function");
console.log(data);
};
$.ajax(options);
});
</script>
And your Controller method will return a JsonResult to handle the callback:
using System.Web.Script.Serialization;
[HttpPost]
public JsonResult JqueryDateChange(string json)
{
var serializer = new JavaScriptSerializer();
dynamic jsondata = serializer.Deserialize(json, typeof(object));
//Get your variables here from AJAX call
var dateString = Convert.ToString(jsondata["menuDateSelected"]);
DateTime compareTime = DateTime.Today;
if (!string.IsNullOrEmpty(dateString))
compareTime = DateTime.Parse(dateString);
string quote = "Now is the winter of our discontent";
if (compareTime < DateTime.Today)
quote = "Made glorious summer by this sun of York";
string selectedDate = FileOperations.GetDateList(compareTime, out List<SelectListItem> dateList);
return Json(new { status = "true", quoteString = quote }, JsonRequestBehavior.AllowGet);
}

why parameter value null when second controller loads in mvc, c#

Note : I'm new to MVC
In my case it has two views and two controllers.I am passing selected item value to the the second controller from first view using ajax.passing is success.
but when second view appears , the value is null.Is this ajax problem or mvc. I can't understand.
this is my first controller and first view
public ActionResult First()
{
//get the location data
var Loc = getData("Location", "", "", "");
List<Firstdata> llc = new List<Firstdata>();
foreach (var val in Loc)
{
llc.Add(new Firstdata
{
Destination =val
});
}
ViewBag.Loc = llc;
return View();
}
first view
<div class="col-md-6 form-group">
<label>Destination</label>
<select class="form-control" id="destination">
#foreach (var item1 in #ViewBag.Loc)
{
<option>#item1.Destination</option>
}
</select>
</div>
<div class="clearfix"></div>
<div class="form-group">
<div class="btn" id="bud">
#Html.ActionLink("GO", "Check","Cruise")
</div>
</div>
ajax passing in first view
<script type="text/javascript">
$("#bud a").click(function () {
var destination = $("#destination").val();
$.ajax({
url: '#Url.Action("Check","Cruise")',
data: { 'destination': destination },
type: "POST",
dataType: "XML",
//contentType: "application/xml",
async: true,
success: function(data){
if (!data)
alert("no xml data returned");
else {
alert("success");
}
//location.href = "~/Views/Cruise/Check.cshtm";
}
});
});
</script>
this is my second controller
public ActionResult Check(string destination)
{
XElement rootele = XElement.Load(Server.MapPath("~/XmlFiles/CruiseData/cruiseprodutstwo.xml"));
var getneededData = rootele.Elements("CruiseProduct")
.Where(l => l.Element("Location").Value == destination)
.Select(s => s.Element("Name").Value);
List<Details> d = new List<Details>();
foreach(var itm in getneededData)
{
d.Add(new Details
{
cruiseName = itm
});
}
ViewBag.needed = d;
return View();
}
** In this point destination is not null and d(ViewBag.needed) is also not null.it shows the count
this is my second view
<div>
#foreach (var itme in #ViewBag.needed)
{
<h2>#itme</h2>
}
</div>
in here loop go through for #ViewBag.needed count and finally display null.no idea what is going.
please help me with this.
I think there is a routing problem there. If you are using default routing that is
routes.MapRoute(name:"Default",
url:"{controller}/{action}/{id}",
defaults:new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
then you need to chagne controller parameter name destination to id
as:
public ActionResult Check(string id)
{
and in JQuery call change it as
$.ajax({
url: '#Url.Action("Check","Cruise")',
data: { 'id': destination },
Or
you can add new route in RouteConfig.cs as
routes.MapRoute(name:"Default",
url:"{controller}/{action}/{destination}",
defaults:new { controller = "Cruise", action = "Check" }
);
For routing you can refer to http://www.niceonecode.com/Q-A/DotNet/MVC/routing-in-mvc-4/20190

Routing Issue on asp.net mvc 5 GET

I am trying to get my product search URL to look like "Products/Search/{search term here}".
I am using attribute based routing and my controller action looks like this:
[HttpGet]
[Route("Products/Search/{searchTerm?}", Name="ProductSearch")]
public ActionResult Search(string searchTerm = "")
{
return View();
}
I have tried using the HTML Helper for BeginForm and BeginRouteForm (shown below) but have not had luck with either. The right action is being called, but my URL looks like "Products/Search?searchTerm"
BeginRouteForm
#using (Html.BeginRouteForm("ProductSearch", new { searchTerm = "" }, FormMethod.Get, new { Class = "navbar-form navbar-right", role = "search" }))
{
<div class="form-group">
#Html.TextBox("searchTerm", null, new { Class = "form-control", placeholder = "Item # or Name" })
</div>
<button type="submit" class="btn btn-default">Search</button>
}
BeginForm
#using (Html.BeginForm("Search", "Products", new { searchTerm = "" }, FormMethod.Get, new { Class = "navbar-form navbar-right", role = "search" }))
{
<div class="form-group">
#Html.TextBox("searchTerm", null, new { Class = "form-control", placeholder = "Item # or Name" })
</div>
<button type="submit" class="btn btn-default">Search</button>
}
I have gone through debugging and the right route is selected, the URL is just not displaying how I wanted it to. What am I missing?
Here is the solution I suggest -
You have the following controller Action -
[HttpGet]
public ActionResult Search(string searchTerm = "")
{
return View();
}
Let the view be -
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script>
$(function () {
$('#click').click(function (e) {
var name = $("#search").val();
var url = '#Url.Action("Search", "Action")' + '/' + name;
window.location.href = url;
});
});
</script>
<input type="text" name="searchText" id="search"/>
<input type="button" value="click" id="click"/>
And when you click the button -
Do not forget to have proper route to be added on to the route configuration -
routes.MapRoute(
name: "searchaction",
url: "{controller}/{action}/{searchTerm}",
defaults: new { controller = "Action", action = "Search" }
);
The problem you think you are experiencing isn't because of anything about ASP.Net MVC. All Html Forms that use the method GET will translate all input elements into QueryString parameters. This is just a W3C standard.
If you want this to work, you'll have to write jQuery to throw an event before the form is submitted, take the text value from the input store it temporarily, empty the input box, and then update the action by appending the temporary value.
I don't think that BeginRouteForm works the way that you're expecting it to. According to the documentation, all that the method does is insert a <form> using the arguments provided. If you had provided something other than an empty string for the route value such as , new { searchTerm = "somesearchterm" }, you would see that show up in the Url as "/product/search/somesearchterm". As it is now, however, the form will be processed as normal, putting the search term on the Url as a normal query parameter.

How do I pass a textbox (DatePicker) variable to my controller using Html.ActionLink?

I have a link that opens a pdf in a new window, without leaving the page. I had this link working...
<script type="text/javascript">
$(function () {
$("#DatePicker").mask("99/99/9999").datepicker({ maxDate: new Date() });
});
if (document.images) {
var pic1 = new Image(100, 200);
pic1.src = '<%=Url.Content("~/images/calendarContent.png") %>'
}
</script>
<%= Html.ActionLink("Click ME", "Controller", "Home", new { id = Model.id }, new { onclick = "stayHomeFunc()"})%></div>
After a review, I have to add a DatePicker function that allows the user to select a date. How do I get to pass that date selection to my controller? This is what I have so far, which returns a null startDate by the way...
Enter Date:<input name="DatePicker" id="DatePicker" type="text" style="width: 80px" />
<%= Html.ActionLink("Click ME", "Controller", "Home", new { id = Model.id, startDate = DatePicker }, new { onclick = "stayHomeFunc()"})%></div>
public ActionResult COntroller(string id, string startDate){...}
Any ideas? Thanks in advance...
You have 2 possibilities:
use a submit button inside the form containing the #DatePicker field. This way you don't need to pass anything, when the form is submitted all input values will automatically be sent to the server:
#using (Html.BeginForm("SomeAction", "Home"))
{
#Html.TextBoxFor(x => x.DatePicker)
<input type="submit" value="Click Me" />
}
if you want to use an anchor you will need to use javascript in order to append the value of the datepicker to the query string. So inside your stayHomeFunc function which is triggered when the link is clicked:
function stayHomeFunc(link) {
var date = $('#DatePicker').datepicker('getDate');
var formattedDate = $.datepicker.formatDate('yy-mm-dd', date);
link.href += '?DatePicker=' + formattedDate;
}
and then don't forget to pass the anchor instance to the onclick event:
<%= Html.ActionLink(
"Click ME",
"SomeAction",
"Home",
new { id = Model.id },
new { onclick = "stayHomeFunc(this)"}
) %>
Personally I would go with the first option as it is semantically more correct and doesn't require any javascript.
Also be careful with the DateTime format that the model binder uses and the differences that exist between GET and POST requests. For more information refer to the following article.
You can also use FormCollection.
VIEW
#using (Html.BeginForm("SomeAction", "Home"))
{
<input type="text" id="DatePicker" name="date">
}
CONTROLLER
public ActionResult SomeAction( FormCollection form)
{
var date = form["date"];
if (date != String.Empty)
{
MyModel model = new MyModel();
model.date= DateTime.Parse(date);
}
return RedirectToAction("YourNewAction", new {date = model.date});
}

Get the values sent from a partial view

I have a form, with a partial view inside it to render several child controls.
Main view :
#model Test_mvc.Models.Entity.Question
#{
ViewBag.Title = "Edit";
Layout = "~/Areas/Admin/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm())
{
#*snip*#
<fieldset>
<legend>Profils</legend>
#Html.Action("CheckboxList", "Profil", new { id_question = Model.id })
</fieldset>
<p>
<input type="submit" value="Enregistrer" />
</p>
}
Profil controller (for the partial view) :
[ChildActionOnly]
public ActionResult CheckboxList(int id_question)
{
var profils = db.Profil.Include("Profil_Question")
.OrderBy(p => p.nom).ToList();
ViewBag.id_question = id_question;
return PartialView(profils);
}
Profil.CheckBoxList view :
#model List<Test_mvc.Models.Entity.Profil>
#foreach (var p in Model)
{
<input type="checkbox" name="profil_#(p.id)"
#if (p.Profil_Question.Where(pc => pc.id_question == ViewBag.id_question).Any())
{
#:checked="checked"
} />
#Html.Label("profil_" + p.id, p.nom)
<br />
}
(I don't want to use #Html.CheckBox because I don't like being sent "true,false" when the checkbox is checked).
Today, if I want to get the checkboxes that have been checked, I do this, but I think it's awful :
Question controller (for the main view) :
[HttpPost]
public ActionResult Edit(Question question)
{
if (ModelState.IsValid)
{
db.Question.Attach(question);
db.ObjectStateManager.ChangeObjectState(question, EntityState.Modified);
db.SaveChanges();
// this is what I want to change :
foreach (string r in Request.Form)
{
if (r.StartsWith("profil_") && (Request.Form[r] == "true" || Request.Form[r] == "on")) {
var p_q = new Models.Entity.Profil_Question();
p_q.id_profil = int.Parse(r.Replace("profil_", ""));
p_q.id_question = question.id;
db.AddToProfil_Question(p_q);
}
}
db.SaveChanges();
return RedirectToAction("Index");
}
return View(question);
}
How would you replace the "foreach" in the last code section ?
Thanks
The first thing I would try would be to give all my checkboxes the same name and put the #id as the value of the box:
#foreach (var p in Model) {
<input type="checkbox" name="profil_checkbox" value="#p.id"
#if (p.Profil_Question.Where(pc => pc.id_question == ViewBag.id_question).Any())
{
#:checked="checked"
} />
#Html.Label("profil_" + p.id, p.nom) <br /> }
Then rather than searching for profil_#id I should get an array of results for profile_checkbox which is much easier to work with. I don't recall exactly how MVC3 processes this, so I can't guarantee what exactly you'll get in the postback, but that should be easy enough to check during debugging.

Categories

Resources