Yes, it requires manual construction of the JSON object. I also have to create a C# postback model to be bound to the JSON. I set all properties in the model to string because if form element has data it the property in the item will be int. If no value, the property in the item will be string. Here is my code.
$("#submit").click(function(e) {
e.preventDefault();
let formPostBackUrl: string = $("form[id='userAnswersForm']").attr("action");
if ($("form[id='userAnswersForm']").valid()) {
let formData: Array < any > = new Array();
let stringfiedFormData: string = "";
//formData = serializeTheForm($("form[id='userAnswersForm']"));
formData = manuallyCreateTheJson();
if (formData.length > 0) {
stringfiedFormData = JSON.stringify(formData);
console.log('stringfiedFormData', stringfiedFormData);
$.ajax({
type: "POST",
url: formPostBackUrl,
data: stringfiedFormData,
headers: {
"CSRF-TOKEN-PCC-FIT": $('input[name="CSRF-TOKEN-PCC-FIT"]').val(),
'Accept': 'application/json',
},
contentType: "application/json;charset=utf-8"
}).done(function(result) {
console.log('postback result', result.message);
alert(result.message);
}).fail(function(error) {
console.log('postback error', error.message);
alert(error.message);
});
}
}
});
function manuallyCreateTheJson() {
const userID: string = $('form #userID').val();
const facilityRelationshipID: string = $('form #facilityRelationshipID').val();
const facilityID: string = $('form #facilityID').val();
const fiscalYear: string = $('form #fiscalYear').val();
const target = $("select, textarea, input:checked, input[type='number'], input[type='text']");
let userAnswers: Array < any > = new Array();
target.each(function() {
let thisTargetElement: any = $(this).get(0);
let $this: any = $(this);
console.log('$this', $this);
let item = {};
item['Name'] = $this.attr('name');
item['FacilityRelationshipID'] = facilityRelationshipID;
item['FacilityID'] = facilityID;
item['FiscalYear'] = fiscalYear;
item['UserID'] = userID;
if ($this.data('useranswerid'))
item['UserAnswerID'] = $this.data('useranswerid').toString();
else
item['UserAnswerID'] = '';
switch (thisTargetElement.tagName.toLowerCase()) {
case 'select':
if ($this.val()) {
item['Value'] = $this.val();
}
break;
case 'textarea':
if ($this.text().trim().length !== 0) {
item['Value'] = $this.text();
}
break;
case 'input':
if ($this.val()) {
item['Value'] = $this.val();
}
break;
}
if (item['Value']) //has value
userAnswers.push(item);
});
console.log('userAnswers', userAnswers);
return userAnswers;
}
/// <summary>
/// Edit user answer to a question with AJAX post of JSON object
/// ToDo: need to allow multiple choices to be nested in the payload
/// </summary>
/// <param name="collection"></param>
/// <returns></returns>
//resumbit user answers to questionnaire
// POST: UserAnswer/Edit/5
[HttpPost]
//[ValidateAntiForgeryToken]
public IActionResult Edit([FromBody] IList < JsonPostBackModel > collection) {
if (collection == null || collection.Count() == 0) {
Response.StatusCode = 200;
return new JsonResult(new {
message = "Nothing answered so nothing saved"
});
} else {
try {
foreach(JsonPostBackModel answer in collection) {
if (!string.IsNullOrEmpty(answer.Value)) {
UserAnswer thisAnswer = new UserAnswer();
//ToDo: exam each answer before executing the post method in the repository to post to the database
}
}
Response.StatusCode = 200;
return new JsonResult(new {
message = "Answers are saved"
});
} catch (Exception ex) {
Debug.Print(ex.Message);
Response.StatusCode = 500;
return new JsonResult(new {
message = ex.Message
});
}
}
}