MVC Ajax.BeginForm JavaScript parameters - javascript

I have an AJAX form where the url id needs to be from JavaScript
#using(Ajax.BeginForm("Add","Comments", new { ArticleID = 3 }, new AjaxOptions { UpdateTargetId="Comments"}))
Where ArticleID = 3 should be replaced so that the ArticleID value is set equal to the result of a called Javascript function. Something like
JS:
function GetArticleID()
{
return 3;
}
Razor:
#using(Ajax.BeginForm("Add","Comments", new { ArticleID = GetArticleID() }, new AjaxOptions { UpdateTargetId="Comments"}))
Controller:
public ActionResult Add(int ArticleID, Comment model)
{
}
How can I use JavaScript function result as BeginForm parameter?

The line #using(Ajax.BeginForm(" will be executed by razor on server. At that time it does not have any knowledge of the javascript methods in your client browser. So you cannot mix a javascript function there.
I prefer to write clean custom code to do the ajax form submit (instead of using Ajax.BeginForm) because it allows me to customize any way i want.
Keep your form as a normal form.
#using(Html.BeginForm("Add","Comments"))
{
<input type="hidden" name="ArticleId" id="ArticleId" value=""/>
<input name="CommentText" type="text" />
<input type="submit" id="saveCmntBtn" />
}
Now listen to the click event of the submit button. Assign the ArticleId value to the input field, get the serialized version of the form and post to server. You may use jQuery serialize() method to get the serialized version of your form.
$(function(){
$("#saveCmntBtn").click(function(e){
e.preventDefault();
$("#ArticleId").val(GetArticleID());
var f=$(this).closest("form");
$.post(f.attr("action"),f.serialize(),function(res){
$("#Comments").append(res);
});
});
});

Related

Ajax call goes only one time ASP.Net MVC5

I am writing an AJAX function in ASP.Net MVC5 and I am getting a problem that the form AJAX request goes only one time. It is a search page. After I choose the filter I press search I get the correct result. However if I changed the filter and click the search submit again, nothing will happen.
var ajaxFormSubmit = function() {
var $form = $(this);
var options = {
url: $form.attr("action"),
type: $form.attr("method"),
data: $form.serialize()
};
$.ajax(options).done(function (data) {
var target = $($form.attr("data-enbw-target"));
target.replaceWith(data);
debugger;
});
return false;
};
$("form[data-enbw-ajax='true']").submit(ajaxFormSubmit);
<form method="get" id="documentForm" action="#Url.Action("Index", "DocumentSearch")" def data-enbw-ajax="true" data-enbw-target="#documentSearchResult">
<button type="submit" id="submitbtn" name="submitbtn" tabindex="100" class="k-button">
<img src="~/Content/search_small_icon.png" />
#WebResources.DocumentSearchButton
</button>
</form>
#Html.Partial("Results", #Model)
public ActionResult Index(DocumentSearchInput model)
{
if (Request.IsAjaxRequest())
{
return PartialView("Results", result);
}
return View(result);
}
I do not get any error. and when I get a debugger; in javascript. the new data is correct. can you please help me.
You are replacing the form in your ajax success. As such, the new form will not have the submit binding on it. If you truely want to do this you will have to rebind to the new form, or possibly use a delegate instead.
$('parentSelector').on('event', 'childSelector', function(){});
parentSelector - A parent element of the child that pre-exists the child element and should typically not be removed/created during the page lifespan.
childSelector - A selector for the element that will be created/changed/removed at some point in the lifespan of the page.
I found the answer.
the problem wasn't with the submit. the problem was with re-writing the data.
$.ajax(options).done(function (data) {
$("#documentSearchResult").empty();
$("#documentSearchResult").html(data);
});
simply, I empty the div then write inside.

Calling an Action Method based on the value of DropDownList and the model

I have a dropdownlist in my View. I need to enable the user to select a value from the dropdownlist and click a button/ActionLink to call another action method in the same controller. The values that needs to be passed to the new ActionMethod are the ID of the selected Value from the dropdownlist and also the ID of the model which is being passed into the View. The model and the Dropdownlist are not linked together by any means.
I have tried onchnage = document.location.href to set the path of the action method and pass a single value to the action method. But the issue with document.location.href is that it appends the url to the existing url which is not appreciated; i.e, the final url turns out be localhost:port/controller1/action1/controller1/action2 which should have been simply localhost:port/controller1/action2
I am looking for a way where it could be done without using javascript as I have already tried it.
Code in the View
#using (Html.BeginForm("Copy","SetValues",FormMethod.Post))
{
<p>
#Html.DropDownList("OptionValueID", null, "Select")
<input type="submit" value="Copy" />
//This is the preferable method though
#*#Html.ActionLink("Copy", "Copy", "SetValues", new { #OptionValueID = #ViewBag.id,#CopyID = CopyDDL.SelectedValue},null)*#
</p>
}
The copy function is going to take two arguments: Id of the selected item and ID that is being passed through ViewBag.id
The View that is being returned by View would a different View
JavaScript that I have tried
<script language="javascript" type="text/javascript">
function copy(_OptionValueID)
{
var url = "/SetValues/Copy";
$.ajax({
url: url,
data: { copyid: _OptionValueID},
type: "POST",
success: function (data) { }
});
response();
}
</script>
It doesn't evaluate at all.
Action Method that calls this View
public ActionResult Index(int id)
{
var ov = db.OptionValue.Include(x => x.Option).FirstOrDefault(x => x.OptionValueID == id);
var opid = ov.OptionID;
var op = db.Option.Include(x => x.TechnicalCharacteristic).FirstOrDefault(x => x.OptionID == opid);
var tcid = op.TechnicalCharacteristicID;
var tc = db.TechnicalCharacteristic.Include(x => x.TcSets).FirstOrDefault(x => x.TechnicalCharacteristicID == tcid);
var tcset = tc.TcSets;
var opv = db.OptionValue.FirstOrDefault(x => x.OptionValueID == id);
ViewBag.OptionValue = opv.OptionVal;
ViewBag.Option = opv.Option.OptionName;
ViewBag.Lsystem = opv.Option.Lsystem.LsystemName;
ViewBag.FamilyName = opv.Option.Lsystem.LsystemFamily.FamilyName;
ViewBag.OptionValID = id;
ViewBag.OptionID = opv.OptionID;
var setValue = db.SetValue.Where(x=>x.OptionValueID==id).OrderBy(x=>x.TcSet.SetName);
ViewBag.OptionValueID = new SelectList(db.OptionValue.Where(x=>x.OptionID==opid), "OptionValueID", "OptionVal");
return View(setValue.ToList());
}
I ahve checked most question relating to this, but none had the overhead of passing two parameters without using a model.
UPDATE: making it more clear
public ActionResult copy(int OptionValueID,int CopyID)
{
//do Something
return View("Error");
}
Above is the Copy Method
OptionValueID = ViewBag.OptionValID //Got from the Action Method Index of SetValues
CopyID = Value from the DropDownlist
Edit Based on Answer
#using (Html.BeginForm("Copy","SetValues",FormMethod.Post))
{
<p>
#Html.DropDownList("CopyID", null, "Select")
<button type="submit" id="Copy" data-id="#ViewBag.OptionValID"> Copy </button>
</p>
}
now the page is being redirected but the no parameters are being passed. Should I be adding routevalues?
You cannot do it without javascript. Your ActionLink() method is parsed on the server before its sent to the client, so any route values are the initial values in the controller, not any edited values the user makes in the view. In order to respond to client side events you need javascript.
You can use ajax to post the values to the server method.
Include a button and handle its click event
<button type="button" id="Copy" data-id="#ViewBag.id">Copy</button>
Script
var url = '#Url.Action("Copy", "SetValues")';
$('#Copy").click(function() {
var optionID = $(this).data('id');
var copyID = $('#OptionValueID').val();
$.get(url, { OptionValueID: optionID, copyID : CopyID }, function(response) {
// do something with the response
});
});
or alternatively if you wanting to redirect, then replace the $.get() with
location.href = url + '?OptionValueID=' + optionID + '&CopyID=' + copyID;
Edit
Based on revised question and comments, if you wanting to post and redirect, there is no need for any javascript or the link. The dropdownlist needs to be #Html.DropDownList("CopyID", null, "Select") so that its selected value is bound to method parameter int CopyID and since the OptionValueID is not edited, then either add its value as a route parameter in the form
#using (Html.BeginForm("Copy", "SetValues", new { OptionValueID = ViewBag.OptionID }, FormMethod.Post))
or add a hidden input for the value
<input type="hidden" name="OptionValueID" value="#ViewBag.OptionID" />

How to pass a value to razor variable from javascript variable?

How to pass a value to razor variable from javascript variable, is it possible asp.net mvc razor view engine?
#{
int a = 0;
}
<script>
var b = ...
#a = b;
</script>
You can't. and the reason is that they do not "live" in the same time.
The Razor variables are "Server side variables" and they don't exist anymore after the page was sent to the "Client side".
When the server get a request for a view, it creates the view with only HTML, CSS and Javascript code. No C# code is left, it's all get "translated" to the client side languages.
The Javascript code DOES exist when the view is still on the server, but it's meaningless and will be executed by the browser only (Client side again).
This is why you can use Razor variables to change the HTML and Javascript but not vice versa. Try to look at your page source code (CTRL+U in most browsers), there will be no sign of C# code there.
In short:
The server gets a request.
The server creates or "takes" the view, then computes and translates all the C# code that was embedded in the view to CSS, Javascript, and HTML.
The server returns the client side version of the view to the browser as a response to the request. (there is no C# at this point anymore)
the browser renders the page and executes all the Javascript
But it would be possible if one were used in place of the variable in #html.Hidden field.
As in this example.
#Html.Hidden("myVar", 0);
set the field per script:
<script>
function setMyValue(value) {
$('#myVar').val(value);
}
</script>
I hope I can at least offer no small Workaround.
Okay, so this question is old... but I wanted to do something similar and I found a solution that works for me. Maybe it might help someone else.
I have a List<QuestionType> that I fill a drop down with. I want to put that selection into the QuestionType property on the Question object that I'm creating in the form. I'm using Knockout.js for the select binding. This sets the self.QuestionType knockout observable property to a QuestionType object when the user selects one.
<select class="form-control form-control-sm"
data-bind="options: QuestionTypes, optionsText: 'QuestionTypeText', value: QuestionType, optionsCaption: 'Choose...'">
</select>
I have a hidden field that will hold this object:
#Html.Hidden("NewQuestion.QuestionTypeJson", Model.NewQuestion.QuestionTypeJson)
In the subscription for the observable, I set the hidden field to a JSON.stringify-ed version of the object.
self.QuestionType.subscribe(function(newValue) {
if (newValue !== null && newValue !== undefined) {
document.getElementById('NewQuestion_QuestionTypeJson').value = JSON.stringify(newValue);
}
});
In the Question object, I have a field called QuestionTypeJson that is filled when the user selects a question type. I use this field to get the QuestionType in the Question object like this:
public string QuestionTypeJson { get; set; }
private QuestionType _questionType = new QuestionType();
public QuestionType QuestionType
{
get => string.IsNullOrEmpty(QuestionTypeJson) ? _questionType : JsonConvert.DeserializeObject<QuestionType>(QuestionTypeJson);
set => _questionType = value;
}
So if the QuestionTypeJson field contains something, it will deserialize that and use it for QuestionType, otherwise it'll just use what is in the backing field.
I have essentially 'passed' a JavaScript object to my model without using Razor or an Ajax call. You can probably do something similar to this without using Knockout.js, but that's what I'm using so...
I see that this problem was discussed some time ago, but if anyone 'll meet with this again, here is my solution:
In your *.cshtml View file:
<script>
var data = JsFunction("#Html.Raw(Model.Path)");
$(function () {
$("#btn").click(function () {
var model = { Id: '#Html.Raw(Model.Id)', Data: data }
$.ajax({
type: "POST",
url: "/Controller/Action",
data: model,
datatype: "html",
success: function() {
console.log('Success');
}
});
});
});
</script>
JavaScript variable model is something that I need to pass to Razor ViewModel.
It can be done with ajax request.
You just need to have proper argument/s in your action, that matches Json object created in JavaScript.
Hope it'll help someone!
Step: 1 Your Html,
First Store the value in your localstorage using javascript then add the line like below ,this is where you going to display the value in your html, my example is based on boostrap :
<label for="stringName" class="cols-sm-2 control-
label">#Html.Hidden("stringName", "")</label>
Step:2 Javascript
$('#stringName').replaceWith(localStorage.getItem("itemName"));
here is my solution that works:
in my form i use:
#using (Html.BeginForm("RegisterOrder", "Account", FormMethod.Post, new { #class = "form", role = "form" }))
{
#Html.TextBoxFor(m => m.Email, new { #class = "form-control" })
#Html.HiddenFor(m => m.quantity, new { id = "quantity", Value = 0 })
}
in my file.js I get the quantity from a GET request and pass the variable as follows to the form:
$http({
method: 'Get',
url: "https://xxxxxxx.azurewebsites.net/api/quantity/" + usr
})
.success(function (data){
setQuantity(data.number);
function setQuantity(number) {
$('#quantity').val(number);
}
});
Yes You Can
Asp.net MVC razor
I have 2 Input
<input id="TXTCount" type="number" readonly="readonly" class="form-control text-center text-bold" step="1" min="0" max="10000" value="1" inputmode="numeric" />
<input id="TXTTOTal" type="number" readonly="readonly" class="form-control text-center text-bold" step="1" min="0" max="10000" value="1" inputmode="numeric" />
C# In view
#{string WatsMSG = "xxx";}
And WhatsApp Link
<a class="btn btn-success" id="WatsSendApi" href="https://api.whatsapp.com/send?phone=0000&text=#WatsMSG">
<b class="text-black" style="font-size:small"> whatsapp </b><i class="fa fa-whatsapp" style="color:white"></i> </a>
And In jQuery
<script>
$("#WatsSendApi").click(function () {
var StringMSG;
StringMSG=("Ineed : ");
StringMSG += (" Item Name : ");
StringMSG +='#item.ITName' ;
StringMSG += (" Count: ");
StringMSG += $('#TXTCount').val();
StringMSG += (" Price: ");
StringMSG += '#item.ITPrice';
StringMSG += (" Total: ");
StringMSG += $('#TXTTOTal').val();
alert(StringMSG);
this.href = this.href.replace("xxx", StringMSG);
});
</script>
I am passing script value And Model value to C# string
Razor View Server Side variable can be read to Client Side JavaScript using #
While
and JavaScript client side variable can read to Razor View using #:

requesting a server by checking/unchecking checkboxes

I'm trying to code a web page that contains two checkboxes and to send a request to my web server for each check/uncheck. I have to check at server side which checkboxes are checked and which are not to make some specific operations.
Form (snippet of code) :
<form method="get" action="#Url.Action("Index")" data-monitoring-ajax="true" data-monitoring-target="#ListeAlertes">
<input type="checkbox" name="affiche" value="fixees" id="fixees" style="margin-left:40px;margin-right:3px;" checked /> Alertes fixées
<input type="checkbox" name="affiche" value="nonFixees" id="nonFixees" style="margin-left:10px;margin-right:3px;" checked /> Alertes non-fixées
</form>
monitoring.js
$(function () {
var ajaxFormSubmit = function () {
var $form = $(this);
var options = {
url: $form.attr("action"),
type: $form.attr("method"),
data: $form.serialize()
};
$.ajax(options).done(function (data) {
var $target = $($form.attr("data-monitoring-target"));
$target.replaceWith(data);
});
return false;
}
$("form[data-monitoring-ajax='true']").submit(ajaxFormSubmit);
});
Note : I've included monitoring.js into the web page.
Any brilliant idea, please ?
Since the options seem to represent the same item just in a different state, you really only need one checkbox.
The Html
<input type="checkbox" id="enableAlerts" style="margin-left:40px;margin-right:3px;" /> Alertes fixées
The javascript (jQuery)
With this, you can subscribe to the change event to know when to send the request to the server.
$("#enableAlerts").change(function(){
$.post("/Controller/UpdateAlerts",
{ enableAlerts: this.checked },
function(data){ console.log("Successfully saved user options!"); });
});
In the above script we listen for the change event to fire and when it does, we post our data to the server so it can process it. If the server returns a 200 status code, it will write to the console that it was successful. Since only one checkbox is being sent, there isn't any reason to wrap the checkbox in a form and serialize the form to send to the server.
The Server code
Now all you need is a controller/action to call to update the option on the server.
[HttpPost]
public HttpStatusCodeResult UpdateAlerts(bool enableAlerts)
{
//Save to database
return new HttpStatusCodeResult(HttpStatusCode.OK);
}
The above code allows the javascript code to post the data to the server. In this case I allowed the value to be nullable and default to false if so. After that, do what you need to and return a response code so the client-side code can inform the user of the status of their request.
In response to comment by user
In this case wrapping it in a form would be correct. The majority of the steps are similar with minor modifications.
Html
<form method="post" id="filterOptions">
<input type="checkbox" name="Checkbox1" value="true" />
<input type="checkbox" name="Checkbox2" value="true" />
</form>
Javascript
$("#filterOptions input[type='checkbox']").change(function () {
var form = $("#filterOptions").serialize();
$.post("/Controller/AjaxFilteredList",
form,
function (data) { console.log("Retrieved data successfully!") });
});
The Model
public class MyModel
{
public bool Checkbox1 { get; set; }
public bool Checkbox2 { get; set; }
}
The model's property names must match the name of the property, case-insensitive. This is made easier if you make this a ViewModel and pass it into the repective View and use Html.CheckboxFor(m => m.Checkbox1) to render the checkbox.
The controller action
[HttpPost]
public ActionResult AjaxFilteredList(MyModel model)
{
//check you viewmodel's variables to get your list
return PartialView("_FilteredList", filteredList);
}
The above assumes you have a partial view named "_FilteredList" and a variable named "filteredList" in-scope with the results you want to render.
Use .change()
$("form[data-monitoring-ajax='true'] input[type='checkbox']").change(function(){
//make your Ajax Call here and send name of the checkbox or id of the checkobox
});
Attribute Equals Selector [name="value"]

Why XmlHttpRequest is sent though ClientValidation is failed?

I have many AJAX forms on the page and on button click I need to submit them all. Regular **forms.each(function (index, form) { $(form).submit();} won't work for me because in this way ONLY the last form will be submitted eventually. Therefore, I need submit them via $.ajax(...). But I want to enable submit ONLY and ONLY if form is VALID
On "submitForms" click the function "submitTest" is invoked.
From jQuery documantation "submitHandler" would be called if form is VALID.
So, the validation works and "submitHandler" is NOT invoked if form is INVALID. BUT, the XmlHttpRequest is sent anyway, though "submitHandler" isn't invoked.
Where is my mistake? Or is there other way to do it?
Thank you
<% using (Ajax.BeginForm("FormPost", "Customer", null, new AjaxOptions() { HttpMethod = "POST" }, new { #class = "form-container" }))
{ %>
<%: Html.TextAreaFor(m => m.Name, new { width = 440, height = 100 })%>
<input type="button" value="submitForms" />
<% }%>
<script type="text/javascript">
function submitTest(){
var forms = $(".form-container");
forms.each(function (index, form) {
$(form).validate({
submitHandler: function (form) {
$.ajax(
{
....
});
}
});
});
forms.each(function (index, form) {
$(form).submit();
});
}
</script>
EDITED
Most likely it's due to the Ajax.BeginForm as that sets up an onclick and an onsubmit handler. Which probably winds up triggering first before your validate submit handler.
UPDATE
If you want to keep using the ajax form in the module where you plan on submitting the form via jQuery.ajax, you can do the following.
$(function() {
$('.form-container').removeAttr('onsubmit').removeAttr('onclick');
});
This will remove the handlers Ajax.BeginForm puts on the form tag. You'll need a way to not include this script in the other module though.

Categories

Resources