0
votes

I have a form with fields with data-* attributes. I used formData = $('#userAnswersForm').serializeArray(). It only serialized the name and value attributes. Below is a sample fragment of the rendered form and Json data. How do I get the data-* attributes and their respective value into the result? Thanks.

<td>
  <div class="flex-start-row-wrap">
    <fieldset>
        <div class="custom-control custom-radio">
            <input name="Q8" class="custom-control-input" id="Q8-25" type="radio" value="25" data-useranswerid="" data-userid="0">
          <label class="custom-control-label" for="Q8-25">Yes</label>
        </div>
        <div class="custom-control custom-radio">
            <input name="Q8" class="custom-control-input" id="Q8-26" type="radio" checked="" value="26" data-useranswerid="9" data-userid="0">
          <label class="custom-control-label" for="Q8-26">No</label>
        </div>
    </fieldset>
  </div>
</td>

[{
    "name": "Q1",
    "value": ""
  },
  {
    "name": "Q5",
    "value": ""
  },
  {
    "name": "Q6",
    "value": "25"
  },
  {
    "name": "Q8",
    "value": "26"
  },
  {
    "name": "Q11",
    "value": "one of the committee(s)"
  },
  {
    "name": "CSRF-TOKEN-MY-TOKEN",
    "value": "CfDJ8Ko6GnaLDwVBtvo4KV3EVp159qlxOvH96mT41L2szq0QwcocKo5ArhFJuSL7xMoW8hRMKCnJNagD0HRfT6-YqcJzOdPaUrtLRLs2uuIxhz4J5UyWoLo2oWZmcM-sSMy-m-7nU6fkVLIPhymD5T8yrW0"
  }
]
1
i think you need to manually get the required values in array and then convert that to json ? - Swati

1 Answers

0
votes

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
      });
    }
  }
}