I'm trying to dynamically set the StudentIds by letting the user select check boxes for the reports they want. When they click the ActionLink, I use jQuery to set the values of the ids in a hidden field. I need the Action Link to read the ids from hidden field.
The values are getting set in the hidden field, but they are not being passed to the controller from the actionLink.
I need to pass the ReportIds to the controller.
#Html.ActionLink("PrintMed", "GetMedEdVerificationReport", "Student", new { studentIdList = Model.ReportIds }, new { #class = "button print_selected print_selectedMedEd disabled" })
#Html.HiddenFor(model => model.ReportIds)
javascript
$('.print_selectedMedEd').bind('click', function () {
var ids = getPrintIds();
if (ids.length == 0) {
return false;
}
$('#ReportIds').val(ids.toString());
return true;
});
When the asp.net mvc render your ActionLink it will generate a link with a parameter that you have on the model. Event you change the value of the model, it will not change the value on the output generated by ActionLink.
Given this, you have to se again the value, try to generate an ACtionLink without the argument:
#Html.ActionLink("PrintMed", "GetMedEdVerificationReport", "Student", null, new { #class = "button print_selected print_selectedMedEd disabled" })
On the javascript side, you could try using the on method to bind a event handler and call the preventDefault method from the event argument, for sample:
$('.print_selectedMedEd').on('click', function (e) {
e.preventDefault();
var ids = getPrintIds();
if (ids.length > 0) {
$('##Html.IdFor(model => model.ReportIds)').val(ids.toString());
// make an url to redirect
var url = $(this).prop("href") + "?studentIdList=" + ids.toString();
// redirect using the generated url
window.location.href = url;
}
});
Remember to use the Html.IdForm() to make sure you have the right id for a specific property.
That is because #Html.ActionLinkdoesn't use the hidden fields to make the request. Once the action link renders it becomes
PrintMed
so you would need to modify the html on the anchor tag.
You should be using Html.Beginform instead in order to pass along the model.
#using (Html.BeginForm("GetMedEdVerificationReport", "Student", FormMethod.Post, null))
{
#Html.HiddenFor(model => model.ReportIds)
<input type="submit" value="PrintMed" />
}
#Html.HiddenFor(modelItem => item.OrderId)
<td>
<input type="button" value="Pickup" onclick="location.href='#Url.Action("Edit", "Assignment", new { ID = item.OrderId })'" />
Related
I have two models called channels and programs.. in showing the dropdown of channels and all I want is that when I select any channel, the view will show the programs of the specific channel. Problem is when I select any channel, it takes the value of channel and return it to the controller and apply filtering logic and pass the data to the new View..Although the view is executing all values properly on the browser it is not visible.. any help would be grateful.
View Code:
#model SitefinityWebApp.Mvc.Models.Channel
#Html.DropDownListFor(m => m.Title, Model.Items, "Select Channel-", new { #id = "ddl" })
<div id="myddl">
</div>
<script>
$('#ddl').change(function () {
var selectedValue = $('#ddl').val();
$.post('#Url.Action("GetProgramByChannel", "Channels")', { selection : selectedValue }, function (data) {
});
});
</script>
GetProgramByChannel Method Taking the selected value
public ActionResult GetProgramByChannel(string selection)
{
var model = new ProgramsModel();
return View("ProgramsByChannel", model.GetChildItemsOfChannel(selection));
}
ProgramsByChannelView
#model SitefinityWebApp.Mvc.Models.Channel
<div id="ddl">
#foreach (var item in Model.Programs)
{
#Html.DisplayFor(m => item.Title) <br />
#Html.DisplayFor(m => item.ShortDescription) <br />
#Html.DisplayFor(m => item.LongDescription) <br />
}
</div>
Because,with your current code, when user make a selection on the dropdown, you are making an ajax call and the result (the new view result with channels will come as the response for this ajax call) is not being used anywhere.
Instead of doing the ajax call, you can make a new GET request to the action method which will return the view.
$('#ddl').change(function () {
var v = $(this).val();
var url ='#Url.Action("GetProgramByChannel", "Channels")?selection='+v;
window.location.href=url;
});
If you do not want to issue a new GET request,but want to show the result in the same view, then all you have to do is update the DOM with the results coming back from the ajax call.
$('#ddl').change(function () {
var v = $(this).val();
var url ='#Url.Action("GetProgramByChannel", "Channels")';
$.post(url, { selection : v} ,function(result){
$("#myddl").html(result); //update the myddl div
});
});
Now you have to make sure that your action method return a view without layout as you are looking for the partial page result. You can use the PartialView method to do so.
public ActionResult GetProgramByChannel(string selection)
{
var model = new ProgramsModel();
return PartialView("ProgramsByChannel", model.GetChildItemsOfChannel(selection));
}
Also, I see you are overwriting the Id value of dropdown to ddl. Why would you do that ? What is wrong with Title being the Id value of the SELECT element ? If you do not override, the helper will generate the SELECT element with Title as the value of Id and name attributes
I'm unsure if this is possible but I want to use jQuery to assign value from my bound model to different textboxes inside a PartialView.
Originally when the page loads, it populates correctly with all of the model information. However I would like to implement a DDL to view historical updates (retrieved from my pre-populated DB).
I am able to call an Action method inside my respective controller which accepts a revisionID. I have verified that the method is returning the correct data.
Please see below for my code snippets:
Partial View:
$('#revisionDDL').change(function () {
var selectedRevisionID = $(this).val();
if (selectedRevisionID == '') {
selectedRevisionID = #Model.RevisionID - 1;
}
var url = '#Url.Action("GetAgreementByRevision")';
$.get(url, { revisionID: selectedRevisionID }, function () {
$('#ChangeReason').val('#Model.ChangeReason');
})
});
Input element:
<div class="input-group">
<span class="input-group-addon" id="change-reason">Change Reason</span>
#Html.TextAreaFor(m => m.ChangeReason, new { #class = "form-control", #rows = "1" })
</div>
Controller method:
public ActionResult GetAgreementByRevision(int revisionID)
{
Agreement revisedAgreement = new Agreement();
revisedAgreement = _agreementService.GetAgreementDetailsByRevision(revisionID);
return PartialView("AgreementDetailsFormPartial", revisedAgreement);
}
If I am not able to accomplish this, what would be my other options?
Your method in the controller returns PartialView which returns HTML content and you're trying to pass that HTML content as a value in the text area - this is not how it should work. You should return Json(revisedAgreement, JsonRequestBehavior.AllowGet); and then access this object in JavaScript.
$.get(url, { revisionID: selectedRevisionID }, function (data) {
// 'data' is your Agreement object
$('#ChangeReason').val(data.SomePropertyHere);
});
I'm stuck with a very basic detail in a view.
I want to be able to let the user filter the results in the Index view.
To do this I've created a dropdown list, which gets populated thourgh my viewmodel:
#using (Html.BeginForm("Index", "Captains", FormMethod.Get)) {
<div class="row">
<div class="dropdown">
#Html.DropDownList("Name", new SelectList(Model.SomeProperty), new { id = "FilterList" })
</div>
</div>
#* ... *#
}
Additionally I have a small jQuery snippet to submit the form on the change event:
$('#FilterList').on('change', function () {
var form = $(this).parents('form');
form.submit();
});
The route I have created for this looks like this:
routes.MapRoute(
name: "IndexFilter",
url: "{controller}/{action}/{Name}",
defaults: new { Name = UrlParameter.Optional}
);
After the submit event I get redirected to the url /Index?Name=ChosenValue
This is filtering totally correct. However I'd like to get rid of the querystring and transform the route to /Index/ChosenValue.
Note: "Name", "ChosenValue" & "SomeProperty" are just dummy replacements for the actual property names.
Instead of submitting the form, you can concatenate /Captains/Index/ with the selected value of the dropdown and redirect to the url using window.location.href as below
$('#FilterList').on('change', function () {
window.location.href = '/Captains/Index/' + $(this).val();
});
I think you're looking for the wrong routing behavior out of a form submit. The type of route resolution that you're hoping to see really only happens on the server side, where the MVC routing knows all about the available route definitions. But the form submission process that happens in the browser only knows about form inputs and their values. It doesn't know that "Name" is a special route parameter... it just tacks on all the form values as querystring parameters.
So if you want to send the browser to /Index/ChosenValue, but you don't want to construct the URL from scratch on the client, you need to construct the URL on the server when the view is rendering. You could take this approach:
<div class="row">
<div class="dropdown">
#Html.DropDownList("Name", new SelectList(Model.SomeProperty),
new {
id = "FilterList",
data_redirect_url = #Url.Action("Index", "Captains", new { Name = "DUMMY_PLACEHOLDER" })
})
</div>
</div>
Above you're setting the URL with a dummy "Name" value that you can replace later, then you'll do the replacement with the selection and redirect in javascript:
$('#FilterList').on('change', function () {
var redirectUrl = $(this).data('redirect-url');
window.location.href = redirectUrl.replace("DUMMY_PLACEHOLDER", $(this).val());
});
If you are wanting to drop the query string off the url because it looks weird, then change your FormMethod.Post.
However, to really answer your question, I've tried the following successfully (Note: this might be considered a hack by some)
In short: update the action url on the form element when the list changes, client side.
$('#FilterList').on('change', function () {
var form = $(this).parents('form');
var originalActionUrl = form.attr("action");
var newActionUrl = originalActionUrl + "/" + $(this).val();
form.attr("action", newActionUrl);
console.log(form.attr("action"));
form.submit();
});
You will need to change your controller's signature to match whatever optional param value you specify in your route config. In your example, "Name".
Controller
[HttpGet]
[Route("~/search/{clause}/{skip?}")]
public async Task<ActionResult> Search(string clause, int skip = 0)
{
...
}
View
#using (Html.BeginForm("Index", "search", FormMethod.Get))
{
#Html.TextBox("clause", null, new { #class = "form-control col-md-4" })
...
}
Rendered Html
<form action="/search" method="get">
<input id="clause" name="clause" type="text" value="test">
</form>
I am using [HttpGet] partly because i want the search to be accessing via http://myapp.com/search/<search values>
When i navigate to http://myapp.com/search/test, everything seems fine, but when i try to enter my new search term in the textbox and hit enter or submit, it navigates to http://myapp.com/search?clause=newsearch
What should I do so that my textbox will navigate to http://myapp.com/search/newsearch instead?
Your form generates http://myapp.com/search?clause=newsearch because a browser has no knowledge of your routes (c# code running on your server).
In order to generate your preferred url (http://myapp.com/search/newsearch), you need javascript to intercept and cancel the default submit, and build a url to navigate to. Using jQuery:
$('form').submit(function() {
var baseUrl = $(this).attr('action'); // or var baseUrl = '#Url.Action("Index", "search")';
var url = baseUrl + '/' + $('clause').val(); // add value for skip if required
location.href = url; // redirect
return false; // cancel the default submit
});
I have the following situation:
Into a view I define a link in this way:
<a href="#Url.Action("Edit", "Vulnerability", new { id = Model.Id })" data-mini="true" data-inline="true" data-role="button" >Annulla</a>
As you can see when the user click the link it is executed the Edit() method ot the VulnerabilityController class passing and Id value
Ok, this works fine but in this view I want have something like I have in a controller, this thing:
return new RedirectResult(Url.Action("Edit", "Vulnerability", new { id = vulnId }) + "#tab-2");
As you can see in this second version I always call the Edit() method of the VulnerabilityController class but the value of Id variable is something like "1234#tab-2"
Can I do something like this in my view and not only in my controller?
If you want to render (include) the results of some action inside your View you can use Html.Action:
#Html.Action("Edit", "Vulnerability", new { id = vulnId + "#tab-2" })
See MSDN
For doing this using Razor Syntax, you can try like this:
#Html.ActionLink("Annulla", "Edit", "Vulnerability", new { id = Model.Id },
new{ #data_mini="true", #data_inline="true", #data_role="button"})