Html.BeginForm not passing parameter - asp.net-mvc

I have the following code that populates a Drop Down List and auto submits a form but it’s not passing the id back to the controller.
<script type="text/javascript">
$(function () {
$("#ArticleID").change(function () {
$('#TheForm').submit();
});
});
</script>
#using (Html.BeginForm("Details", "Article", FormMethod.Post, new { id = "TheForm" })){
#Html.DropDownList("ArticleID", (SelectList)ViewBag.ArticleId, "Select Article")
}
I get:
/Article/Details
But need:
/Article/Details/1
I’m following a tutorial that stops at this point. I’m not quite sure what is going on here regarding TheForm I tried to put ArticleID but that didn’t work. How do I do this?
I've also tried it without jQuery like this,
#using (Html.BeginForm("Details", "Article", FormMethod.Post, new { id = "TheForm" })){
#Html.DropDownList(
"ArticleID",
(SelectList)ViewData["Articles"],
"Please Select an Article",
new
{
onchange = "document.getElementById('TheForm').submit();"
})
}
But it doesn't send the parameter through either.

There is a built in way to render this without selecting the action:
var actionUrl = '#Url.Action("Details", "Article")/' + $('#ArticleID').val();

The url is determined before the page is rendered in the following line:
#using (Html.BeginForm("Details", "Article", FormMethod.Post, new { id = "TheForm" }))
which renders:
<form action="/Article/Details" id="TheForm" method="post">
Since the value that you want to add to the Url, ArticleID, is determined by the dropdown selection, you'll need to manipulate the action attribute of the form using JavaScript.
Something like this would probably work:
<script type="text/javascript">
$(function () {
$("#ArticleID").change(function () {
// The following line was changed to use #naspinski's suggestion
var actionUrl = '#Url.Action("Details", "Article")/' + $('#ArticleID').val();
$('#TheForm').attr('action', actionUrl);
$('#TheForm').submit();
});
});
</script>
With that said, this feel awkward to me. It may be worth considering how that value needs or will be used. Does it really need to be part of a route? If not, you can avoid this manipulating the action attribute altogether.

Related

After grecaptcha.execute(), form.submit not working on ASP.Net MVC 5 form

The form in question is a simple form with reCaptcha v2 on it. Upon clicking the submit button Google challenges the user (me) with the reCaptcha. Every time Google is validating I am a human, the onSubmit is called, the form is serialized correctly, but the form.submit() does not invoke the ASP.Net MVC controller on the server. When Google reCaptcha is removed, the controller is called just fine so I don't think it is anything to do with the ASP.Net code.
JavaScript is not my strong point, so I am assuming a dumb mistake in trying to call the submit. What do I have wrong here?
<script>
var onSubmit = function (token) {
var form = $("form"); // $("#feedbackForm");
console.log(form.serialize());
form.submit();
}
var onGrecaptchaError = function (token) {
grecaptcha.reset();
}
var onloadCallback = function() {
grecaptcha.render('submit', {
'sitekey' : '#reCaptchaPublic',
'callback': onSubmit,
'error-callback': onGrecaptchaError,
'size': 'invisible'
});
};
</script>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
and the razor form code:
#using (Html.BeginForm("Email", "Home", FormMethod.Post, new { id = "feedbackForm" }))
{
#* [SNIP] *#
<div class="formfield clear">
<button id="submit" class="btnSubmit">Send To Leadership</button>
</div>
}
After much searching I finally discovered that you cannot give the submit button an id of submit, that was the problem!

How to pass an actionlink's results to a partialview placeholder?

Okay, so in my page I have a list of links:
#foreach (var item in Model)
{
#Html.ActionLink(item.Name, "Recruitments", new { Id = item.Id })
<br />
}
And what I want is for the partialview to return somewhere else on the page, in a placeholder I've set aside.
Is this possible? Or do I have to use jquery ajax calls instead somewhere?
you can #Ajax.ActionLink in asp.net mvc, it has different overloads you can use according to your requirements here is the code:
#Ajax.ActionLink("ActionName", // action name
"Recruitments", //controller name
new { Id = item.Id }, // route values
new AjaxOptions { HttpMethod = "GET", //HttpMethod Get or Post
InsertionMode = InsertionMode.Replace, // Replace content of container
UpdateTargetId = "Container", // id of element in which partial view will load
OnComplete = "Completed();" }) // js function to be executed when ajax call complete
<div id="Container">
</div>
<script>
function Completed()
{
alert("completed");
}
</script>
I did had a problem with partial for your problem post some code so I understand your problem.
Either you should use a razor helper, either you simply use jquery to manipulate the dom.
note that jquery is pretty simple
$("#selectorOnYourPlaceHolder").html($("#selectorOnYourLinks").html());
$("#selectorOnYourLinks").html("")
You want to do this with Ajax:
$.ajax({
type: "GET", url: "somePageOrHandler.aspx", data: "var1=4343&var2=hello",
success: function(data)
{
$('#someDivInPlaceHolder').html( data);
}
});

Unobtrusive validation doesn't work with Ajax.BeginForm

I have View with Model1 where I put Ajax.BeginForm() and in this View i have PartialView with Model2 where i put Ajax.BeginForm(). So only in first form working unobtrusive validation. Why only in first form working validation?
first View
#model Model1
#using (Ajax.BeginForm("Action1","Controller",null,new AjaxOption(){ onSuccess = "alert('=)')"},null)
{
<intput type="submit" value="Save" />
}
Model2 model2 = new Model2();
#Html.EditorFor(m=>model2)
**In Model2 view i have. **
#model Model2
#using (Ajax.BeginForm("AddStreet","Controller",new AjaxOption(){onSuccess = "alert('=)'")},option,null)
{
#Html.LabelFor(m => Model.Name):
#Html.TextBoxFor(m => Model.Name)
#Html.ValidationMessageFor(m => Model.Name)
<intput type="submit" value="Save" />
}
Thanks #Darin Dimitrov for answer.
That's because the second view is loaded with AJAX at a later stage and you need to call $.validator.unobtrusive.parse(...)
immediately after its contents is injected into the DOM in order to enable unobtrusive validation. Look at the following blog post for more details.
So in your case, instead of alerting in the OnSuccess callback of the first AJAX call, subscribe to a javascript function which will invoke this method:
#using (Ajax.BeginForm(
"Action1",
"Controller",
null,
new AjaxOptions {
OnSuccess = "onSuccess",
UpdateTargetId = "result"
},
null)
)
{
<input type="submit" value="Save" />
}
and then in your javascript file:
var onSuccess = function(result) {
// enable unobtrusive validation for the contents
// that was injected into the <div id="result"></div> node
$.validator.unobtrusive.parse($(result));
};
You need to add those 2 files in you Partial View even if it is already in the Shared/_Layout.cshtml:
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
Or place this in your Partial:
<script type="text/javascript" language=javascript>
$.validator.unobtrusive.parse(document);
</script>
This solution worked best for me.
$.validator.unobtrusive.parse(document);
The answer of Darin Dimitrov only works when validate() of the jquery validate plugin has not been called until the Ajax success handler is called. I can't think of a scenario where this could be the case, thus i wonder why the answer was accepted as correct.
Perhaps a change in the jquery validate code in the past now causes the following issue:
The issue is that validate() executes the following line first
// Check if a validator for this form was already created
var validator = $.data( this[ 0 ], "validator" );
if ( validator ) {
return validator;
which means that the validator object is returned when validate() is called without and further handling of the options passed.
This also means that a later call to $.validator.unobtrusive.parse(...) or $.validator.unobtrusive.parseElement(...) which executes a
$form.validate(this.options) <- this.options holds the new rules parsed from HTML
to update the options of the validator has no effect because the options are not processed at all.
The solution here is to update the validator manually like
var $htmlCode = $("your html");
$.validator.unobtrusive.parse($htmlCode, true); // true means no validate() call
// now get the validation info collected in parse()
var validationInfo = $form.data("unobtrusiveValidation");
var $validator = $form.validate(); // get validator and ...
$validator.settings.rules = validationInfo.options.rules; // ... update its rules
$validator.settings.messages = validationInfo.options.messages; // ... update its messages
Revalidating the form (e.g. clicking submit) should now result in the expected results.
Here is a full example witch also includes code from the already accepted answer:
Razor
#using (Ajax.BeginForm(
"Action1",
"Controller",
null,
new AjaxOptions {
OnSuccess = "onSuccess",
UpdateTargetId = "result"
},
null)
)
{
<input type="submit" value="Save" />
}
Javascript
var onSuccess = function(result) {
var $htmlCode = $(result);
$.validator.unobtrusive.parse($htmlCode, true); // true means no validate() call
// now get the validation info collected in parse()
var validationInfo = $form.data("unobtrusiveValidation");
var $validator = $form.validate(); // get validator and ...
$validator.settings.rules = validationInfo.options.rules; // ... update its rules
$validator.settings.messages = validationInfo.options.messages; // ... update its messages
};
--
As a side note, manually updating the validator is also possible by using the rules() method like
$yourHtmlField.rules( "add", {
required: true,
messages: {
required: "Required input"
}
});
as this directly updates the rules of the validator without the unobtrusive stuff. But then the data-val attributes are rendered useless.
You have to add a reference to jquery.unobtrusive-ajax.js to enable the validation within Ajax Form
Something like this:
<script type="text/javascript" src="/Scripts/jquery.unobtrusive-ajax.js"></script>

Search and display on same page in mvc2 asp net

have a simple search form with a textbox. And upon submitting the form I send the contents of the textbox to a stored procedure which returns to me the results. I want the results to be displayed on the same page the form was, except just below it.
Right now I'm doing the following but it's not working out exactly the way I want:
sathishkumar,
You don't tag the question as being an ajax related solution or not. I'm going to present a simple ajax approach which may or may not be suitable.
in the controller:
public ActionResult Search(string searchTerm)
{
// you don't add code re your stored proc, so here is a repo based approach
var searchItems = _repository.Find(x => x.searchfield.Contains(searchTerm));
return PartialView("SearchPartial", searchItems);
}
main view (index.aspx or whatever) (below where your main content is defined, add):
<div id="searchResults"></div>
in another part of the page (semi psuedo-code):
<script type="text/javascript">
function getSearchResults() {
// #yoursearchbox is a textbox on the index.aspx aview
var tdata = { searchTerm: $('#yoursearchbox').val()};
// or your data in the format that will be used ??
$.ajax({
type: "GET",
data: tdata,
url : '<%= Url.Action("Search", "Home") %>',
success: function (result) { success(result); }
});
});
function success(result){
$("#searchResults").html(result);
}
</script>
You'd then add a partial view SearchPartial.ascx that contained your model for the search results.
Hope this helps.
You can use Ajax to solve the problem.
<div>
`#using (Ajax.BeginForm("action", "controller", new AjaxOptions
{
UpdateTargetId = "results",
HttpMethod = "GET",
}))
{
#Html.TextBox()
<input type="submit" value="Search" />
}`
<div id="results"></div>
</div>

DropDown list onchange event and AJAX in MVC

I have a code block in my MVC view as follows:
<%using (Ajax.BeginForm("MyAction", new { action = "MyAction", controller = "Home", id = ViewData["selected"].ToString() }, new AjaxOptions { UpdateTargetId = "Div1" }))
{ %>
<%=Html.DropDownList("ddl", ViewData["MyList"] as SelectList, new { onchange = "this.form.submit()" })%>
<%} %>
I want to set the value of ViewData["selected"] so that i can send it to the desired action.
Can anyone please suggest how can i do this?
thanks!
Instead of using a form, why not use a jQuery onChange event on your drop down?
$(document).ready(function() {
$("#ddl").change(function() {
var strSelected = "";
$("#ddl option:selected").each(function() {
strSelected += $(this)[0].value;
});
var url = "/Home/MyAction/" + strSelected;
$.post(url, function(data) {
// do something if necessary
});
});
});
ViewData is not the place to pass data back to the server side. Values of html input controls within form tag are conveniently available in action method. You can get these values either from various types of action method arguments (model, formcollection etc).
Here is a link to free asp.net mvc ebook tutorial. Is a good resource for asp.net mvc.
Found solution at this post it is just small chnge
Yes, that’s right – only change is replacing:
onchange = “this.form.submit();”
with:
onchange = “$(this.form).submit();”

Resources