Partial view not serializing in ajax Post request MVC - razor

Implementing the auto save functionality for my page. so after certain interval calling action Autosave(). But my page having begin form including the Partial view. The code for after interval call is working fine.
<script type="text/javascript">
window.setInterval(function () {
var form = $("#addpost");
$.ajax({
url: '#Url.Action("AutoSavePostAction", "MyControllerName")',
data: form.serialize(),
type: 'POST',
success: function (data) {
$("#Id").val(data);
}
});
}, 30000);
View is :
#using (Html.BeginForm("SavePostAction", "MyControllerName", FormMethod.Post, new { enctype = "multipart/form-data", id="addpost" }))
{
.................
#Html.Partial("_TextPostPartial", Model);
.................
}
SavePostAction is after calling submit. On this submission, getting the value from Partial view, which is not an issue.
But in ajax call somehow partial view does not included in serialization.
Here _TextPostPartial having CKEditor which is strongly bind with Model.
Like Partial view having :
<textarea id="Description" name="Description">#Html.Raw(Model.Description)</textarea>
Edited:
[HttpPost]
public ActionResult AutoSavePostAction(PostDTO postDTO, FormCollection postFormCollection)
{
}
[HttpPost]
[MemberFunction]
public ActionResult SavePostAction(PostDTO postDTO, FormCollection postFormCollection)
{
}

You need to assign the value of the CKEditor to the input before serializing the form data
window.setInterval(function () {
$("#Description").val(CKEDITOR.instances['Description'].getData()); // add this
var form = $("#addpost");
$.ajax({
url: '#Url.Action("AutoSavePostAction", "MyControllerName")',
data: form.serialize(),
type: 'POST',
success: function (data) {
$("#Id").val(data);
}
});
}, 30000);

Related

AJAX hiddenfield submit instead of form does not work

I have trouble sending AJAX post request to controller. The following code works:
var path = $(this).prop("value");
var token = $('[name=__RequestVerificationToken]').val();
var headers = {};
headers["__RequestVerificationToken"] = token;
var ids = $("#ids").val();
var formData = new FormData();
formData.append('ids', ids);
$.ajax({
url: path,
type: "POST",
cache: false,
headers: headers,
data: formData,
async: false,
processData: false,
contentType: false,
success: function (result) {
document.write(result);
document.close();
console.log("YES");
},
error: function () {
alert("Error.");
}
});
Here is the Controller Method:
[AjaxOnly]
[HttpPost]
[ValidateAntiForgeryToken]
[OutputCache(NoStore = true, Location = OutputCacheLocation.None)]
public ActionResult MyMethod(string aString)
The call to the Controller works fine, but as expected aString in Controller-Function parameter is null.
What I actually want to do is not to POST the formData ($("#myForm").serialize();) in the data field of the AJAX post, but an hiddenField:
var aString = $("#ids").val();
So when I put the aString variable in the data field of Ajax call instead of formData the call to my function does not work anymore and I get 500 error.
Anyone can help how to POST this hiddenfield value instead of formData?
MyForm:
#{
ViewBag.Title = "MyForm";
#model MyFormModel
}
#using (Html.BeginForm("MyForm", "MyController", FormMethod.Post, new { id = "MyForm" }))
{
<div class="tab-content" id="tabContent">
content
</div>
#Html.Partial("_MyFormPopup")
Partial:
#using (Html.BeginForm("MyMethod", "MyController", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="modal fade">
content
</div>
#Html.Hidden("ids")
Controller Code:
[AjaxOnly]
[HttpPost]
[ValidateAntiForgeryToken]
[OutputCache(NoStore = true, Location = OutputCacheLocation.None)]
public ActionResult MyMethod(string ids)
{
string[] IdsFunktions = ids.Split(new string[] { ";" },
....
return RedirectToAction("MyForm");
}
So in order for your code to work you need to correctly name your formData variables, here are the two variants:
If you want to have a aString variable on your Controller then your AJAX post code should post like this:
var formData = new FormData();
formData.append('aString', $("#ids").val());
$.ajax({
url: path,
type: "POST",
cache: false,
headers: headers,
data: formData,
async: false,
success: function (result) {
document.write(result);
document.close();
},
error: function () {
alert("Error.");
}
});
Another solution would be in the case you want to post all form fields data by using data: $("#myForm").serialize() you must change the Controller reference variable names and reference each field by its form name, e.g if you have only one hidden field then:
[AjaxOnly]
[HttpPost]
[ValidateAntiForgeryToken]
[OutputCache(NoStore = true, Location = OutputCacheLocation.None)]
public ActionResult MyMethod(string ids, string fieldNameOne, string fieldNameTwo, etc...)

get html 5 date input field and pass to .net controller

On my razor page, I have a simple date picker that looks like this:
<input type="date" name="lessonsStart">
How would I go about getting the value of that and sending it to my controller?
Whenever I send data to my controller from a razor page, the format always looks something like this:
<a asp-action="LessonIndex" asp-route-id="#item.Id">#Html.DisplayFor(modelItem => item.Name)</a>
which sends an "item.Id" to my controller called LessonIndex().
So I'm not sure how I'd get the date value and send it.
The controller looks like this:
public IActionResult LessonIndex(datetime startDate) {
var response = getLessons(startDate);
return response.Results;
}
Is there a specific format I need to use?
Note that the date is not used in a model, it just needs to be sent to a controller.
Thanks!
Assuming this is related to mvc the controller would have a method associated with the post that you would perform to get the data from the form back to the controller. This uses javascript to post data to your LessonIndex() method.
<!--top of your page.-->
#inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
#functions{
public string GetAntiXsrfRequestToken()
{
return Xsrf.GetAndStoreTokens(Context).RequestToken;
}
}
<input type="date" id="lessonStart" name="lessonStart" />
<input type="Submit" id="PostButton" name="PostButton" Value="Go" />
#section Scripts{ // razor section at the bottom of mvc page 'cshtml'.
<script type="javascript">
$(function(){
$("#PostButton").click(function(){
var url = '#Url.Action("LessonIndex", "Lesson")'; //assuming controller is named Lesson
var date= new Date(this.value).ToDateString();
$.ajax({
url: url,
type: "POST",
data: "lessonStart=" + date,
headers:{
"RequestVerificationToken": '#GetAntiXsrfRequestToken()'
},
success: function(response){
console.log(response);
},
error: function(e){
console.log(e.error);
}
});
});
}
</script>
}
this also assumes that the method looks like this
public class LessonController : Controller{
[HttpPost]
[AutoValidateAntiforgeryToken]
public IActionResult LessonIndex(DateTime lessonStart){
var response = getLessons(lessonStart);
return View(response.results);
}
}
" Note that the date is not used in a model, it just needs to be sent to a controller. "
You could use the ajax to pass the date as QueryString to the method in the controller.
Here is the test example
<input type="date" name="lessonsStart" id="lessonsStart">
#section Scripts
{
<script type="text/javascript">
$("#lessonsStart").change(function () {
var inputDate = new Date(this.value).toDateString();
$.ajax({
type: "post",
url: "/ControllerName/lessonindex?startdate=" + inputDate,
success: function () { }
});
});
</script>
}
The method in controller
[HttpPost]
public IActionResult LessonIndex(DateTime startDate)
{
return Json(startDate);
}
<div class="demo-section k-content">
<h4>Remind me on</h4>
#(Html.Kendo().DateTimePicker()
.Name("datetimepicker")
.Value(DateTime.Now)
.HtmlAttributes(new { style = "width: 100%", title = "datetimepicker" })
.DateInput()
)
</div>

Append additional HTML result in calling MVC action by Ajax in DNN8

I'm new in DNN development.
I have created a very simple module in Visual studio--- A textbox and a button.
I just want to call the action in a controller by click the button, then show the return result in the textbox.
The code call the action success, but not sure why append lots of HTML inforation in the result.
Here is the action in the controller:
public ActionResult test1()
{
return Content("Return something");
}
Here is the Ajax code from the View:
$(document).ready(function () {
$("#btnSub").click(function () {
//alert(this.action);
$.ajax({
type:"GET",
contentType:"application/text",
url: "#Url.Action("test1", "Sky")",
data:"",
dataType: "text",
success: function (data) { $("#txtResult").val(data); alert("Success!") },
error:function(){alert("Failed!")}
});
});
});
And here is the result show in the textbox:
Anyone can let me know why the HTML information returned? Actually, I don't need it.
Thanks
Unfortunately, as described in DNN8 MVC unsupported features, it's not yet possible to return a JsonResult. So the solution I used is to return an ActionResult (although the function returns Json):
public ActionResult Test()
{
return Json(new { success = true });
}
On jquery side, I setup ajax call to receive result as html. This avoid the browser to display a parsing error. Finally, just need to remove the html part and manually parse the response. It's not very clean, but the only solution I found until DNN support JsonResult.
$.ajax({
url: '#Url.Action("Index", "Contact")',
type: 'POST',
dataType: 'html',
data: $('#contact-form input').serialize(),
success: function (response) {
jsonPart = response.substring(0, response.indexOf("<!DOCTYPE html>"));
var data = JSON.parse(jsonPart);
if (data.success) {
alert("Great");
}
},
error: function (jqXHR, textStatus, errorThrown) {
alert("Error!");
}
});
EDIT : Improved solution
DNN8 now support IMvcRouteMapper. You can then register a route in RouteConfig.cs. Once done, you can call the function using following URL :
/DesktopModules/MVC/ModuleName/Controller/Action
The action can return a JsonResult. But pay attention, if you just call that function, it will fail with a null exception on ModuleContext. You have to include in the ajax call the following header :
headers: {
"ModuleId": #Dnn.ModuleContext.ModuleId,
"TabId": #Dnn.ModuleContext.TabId,
"RequestVerificationToken": $("input[name='__RequestVerificationToken']").val()
}
You can find the module complete code here.
This is a working ajax call in DNN 9. You dont have to use #urlaction it will give whole html as well as data. dnn.getVar("sf_siteRoot", "/") +
"DesktopModules/MVC/ModuleName/Controller/Action", this does the trick and don't forget to add the header otherwise it will throw 500 error.
$.ajax({
url: dnn.getVar("sf_siteRoot", "/") +
"DesktopModules/MVC/ModuleName/Controller/Action",
type: 'POST',
contentType: "application/json; charset=utf-8",
dataType: 'json',
data: "{ 'id':" + JSON.stringify(3543)+" }",
headers: {
"ModuleId": #Dnn.ModuleContext.ModuleId,
"TabId": #Dnn.ModuleCon`enter code here`text.TabId,
"RequestVerificationToken":
$("input[name='__RequestVerificationToken']").val()
},
success: function (response) {
debugger;
},
error: function (errmsg) {
alert("Error!");
}
});
Your controller should be
[HttpPost]
public ActionResult ActionName(int id)
{
var data = id;
return BuidJsonResult(true,data);
}
Happy Coding :)

Pass dropbox value to a HttpGet action submit button click?

Basically I'm trying to pass the value of my dropbox to a get action.
The submit-button re-directs to the correct action , but what is the correct way to add the value of the dropbox with the re-direction?
My view:
#model TrackerModel
#using (Html.BeginForm("MyAction", "MyController", FormMethod.Get, new { ???}))
{
<div>
<strong>#Html.LabelFor(m => m.CustomerName)</strong>
#Html.TextBoxFor(m => m.CustomerName, new { type = "hidden", #class = "customer-picker" })
</div>
<button class="styledbutton" onclick="window.location.href='/Tracker/Index'">Cancel</button>
<button type="submit" value="submit" id="selectCustomer-button" class="styledbutton">Submit</button>
}
[HttpGet]
public ActionResult MyAction(IPrincipal user, Tracker model)
Customer-picker
$(document).ready(function () {
CustomerPicker();
});
function CustomerPicker() {
$('.customer-picker').select2({
placeholder: 'Select customer',
minimumInputLength: 1,
ajax: { // instead of writing the function to execute the request we use Select2's convenient helper
url: '/JsonData/GetCustomers',
type: 'POST',
dataType: 'json',
data: function (term) {
return {
query: term // search term
};
},
results: function (data) { // parse the results into the format expected by Select2.
// since we are using custom formatting functions we do not need to alter remote JSON data
return { results: data };
}
},
formatResult: function (data) {
return data;
},
formatSelection: function (data) {
return data;
}
});
}
I was expecting the value to be within my Tracker model parameter in the action, but this returns nulls. Also I'm not sure what to place in the "new" parameter in the form tag?
I also tried the following but all I get returning to the controller is text:"".
#Html.TextBoxFor(m => m.CustomerName, new { type = "hidden", #id = "selectedCustomer", #class = "customer-picker" })
<script type="text/javascript">
$(function () {
$("#Form1").submit(function (e) {
alert("boo");
e.preventDefault();
var selectCustValue = $("#selectedCustomer").val();
$.ajax({
url: '/CalibrationViewer/SentMultipleCalsToCustomer',
data: { text: selectCustValue }
});
});
});
OK got it,
var selectCustValue = $("#s2id_CustomerName span").text();
Found another piece of code the used the customer-picker and the javascript associated with view used the above.
I viewed the page source and it still show's both id and name as CustomerName, it has something to do with the "Select 2" helper.
I may get slated for marking this as the answer, considering I should have figured it out earlier, but there you have it !

ASP.NET MVC Show View after Ajax call to a Controller

I have a View with a submit form: when I click it a jquery/ajax function is called. This function has to encode the View Model, call a Controller action and show the View returned.
Now, this is my function:
<script type="text/javascript">
function Analyze() {
var urlact = '#Url.Action("Analysis")';
var model = '#Html.Raw(Json.Encode(Model))';
$.ajax({
data: model,
type: "POST",
url: urlact,
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (data) {
//WHAT HERE??
}
});
}
</script>
And the Analysis action is a kind of
public ViewResult Analysis(IEnumerable<Azienda> aziende) {
Debug.WriteLine(aziende.Count());
return View(aziende);
}
Returning a View!
How can I display that View on success:function(data)?
I tried changing dataType to html and calling on success alert(data) but I had problems with the encoded model, I tried commenting the contentType line but same model-encoding issue.
Does someone know how to do that?
A js/query/ajax workaround-trick is fine, too.
Thanks you all!
Use
return PartialView()
instead of
return View()
in your controller. Then in the success function in your ajax call, use the jQuery .html() function to update the element you wish to update in your html. See Query.html() and View() vs. PartialView()
Create a separate partial view with aziende as its model and return this in your Analysis action and then append the result to a div in your view:
//action returning a partial view
public ActionResult Analysis(IEnumerable<Azienda> aziende)
{
Debug.WriteLine(aziende.Count());
return PartialView("_partialView", aziende);
}
//then append the result to a div in your javascript
success: function (data) {
$("#some-div").html(data);
}