Выберите элементы, отсутствующие в форме сериализации? - PullRequest
0 голосов
/ 07 мая 2018

В функции отправки я пытаюсь отфильтровать скрытое поле из формы сериализации, а затем сравнить текущие данные с ранее сохраненными данными. Если данные совпадают, пользователь должен увидеть сообщение. Одна проблема, с которой я столкнулся, связана с выбором элементов формы. Почему-то элемент формы select не включен в данные формы сериализации. Я проверил, и если я не использую .find(), то я вижу выбрать элемент формы. Есть ли причина, по которой выбор не включен в одном случае, а в другом?

var frmOriginalData;

$('.frm-Submit').on('submit', submitAdminFrm);

function submitAdminFrm(e) {
  e.preventDefault(); // Prevnts default form submit.
  var frmID = e.currentTarget.id,
    recID = $('#frm_recordid').val(),
    frmCurrentData = $("#" + frmID).find("input:not('.no-serialize')").serialize();

  console.log(recID + '\n' + frmCurrentData + '\n' + frmOriginalData);

  if (recID && frmCurrentData == frmOriginalData) {
    alert('Nothing changed on the form.');
  } else {
    frmOriginalData = $("#" + frmID + " input:not('.no-serialize')").serialize();
  }
}
<script language="javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script language="javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<form name="frmSave" id="frmSave" class="frm-Submit" autocomplete="off">
  <input type="hidden" class="form-control no-serialize" name="frm_recordid" id="frm_recordid" value="34">
  <div class="form-group required">
    <label class="control-label" for="fname"><span class="label label-primary">First Name:</span></label>
    <input type="text" class="form-control" name="frm_firstname" id="frm_firstname" placeholder="Enter First Name" maxlength="50" required>
  </div>
  <div class="form-group required">
    <label class="control-label" for="lname"><span class="label label-primary">Last Name:</span></label>
    <input type="text" class="form-control" name="frm_lastname" id="frm_lastname" placeholder="Enter Last Name" maxlength="50" required>
  </div>
  <div class="form-group required">
    <label class="control-label" for="activestaff"><span class="label label-info">Active:</span></label>
    <select class="form-control is-staff" name="frm_active" id="frm_active" required>
      <option value="0">No</option>
      <option value="1">Yes</option>
    </select>
  </div>
  <div class="row">
    <div class="form-group col-xs-12 col-sm-12 col-md-1 col-lg-1">
      <button type="submit" name="frm_submit" id="frm_submit" class="btn btn-primary">Submit</button>
    </div>
  </div>
</form>

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

Вы не получаете select, потому что вы определенно ищете input элементов:

frmCurrentData = $("#" + frmID).find("input:not('.no-serialize')").serialize();
// -----------------------------------^

select элементы не являются input элементами.

Вы могли бы использовать псевдокласс jQuery :input вместо:

frmCurrentData = $("#" + frmID).find(":input:not('.no-serialize')").serialize();
// -----------------------------------^

Пример:

var frmOriginalData;

$('.frm-Submit').on('submit', submitAdminFrm);

function submitAdminFrm(e) {
  e.preventDefault(); // Prevnts default form submit.
  var frmID = e.currentTarget.id,
    recID = $('#frm_recordid').val(),
    frmCurrentData = $("#" + frmID).find(":input:not('.no-serialize')").serialize();

  console.log(recID + '\n' + frmCurrentData + '\n' + frmOriginalData);

  if (recID && frmCurrentData == frmOriginalData) {
    alert('Nothing changed on the form.');
  } else {
    frmOriginalData = $("#" + frmID + " input:not('.no-serialize')").serialize();
  }
}
<script language="javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script language="javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<form name="frmSave" id="frmSave" class="frm-Submit" autocomplete="off">
  <input type="hidden" class="form-control no-serialize" name="frm_recordid" id="frm_recordid" value="34">
  <div class="form-group required">
    <label class="control-label" for="fname"><span class="label label-primary">First Name:</span></label>
    <input type="text" class="form-control" name="frm_firstname" id="frm_firstname" placeholder="Enter First Name" maxlength="50" required>
  </div>
  <div class="form-group required">
    <label class="control-label" for="lname"><span class="label label-primary">Last Name:</span></label>
    <input type="text" class="form-control" name="frm_lastname" id="frm_lastname" placeholder="Enter Last Name" maxlength="50" required>
  </div>
  <div class="form-group required">
    <label class="control-label" for="activestaff"><span class="label label-info">Active:</span></label>
    <select class="form-control is-staff" name="frm_active" id="frm_active" required>
      <option value="0">No</option>
      <option value="1">Yes</option>
    </select>
  </div>
  <div class="row">
    <div class="form-group col-xs-12 col-sm-12 col-md-1 col-lg-1">
      <button type="submit" name="frm_submit" id="frm_submit" class="btn btn-primary">Submit</button>
    </div>
  </div>
</form>

:input соответствует элементам input, select, textarea и button.


Примечание 1 : Вы не ставите кавычки вокруг субселектора в псевдоклассе :not(). E.g.:

frmCurrentData = $("#" + frmID).find(":input:not('.no-serialize')").serialize();
// Remove these quotes --------------------------^-------------^

Примечание 2 : у вас уже есть элемент form в e.currentTarget (а также this, кстати), поэтому нет необходимости получать его id а затем посмотрите снова:

frmID = e.currentTarget.id
// ...
frmCurrentData = $("#" + frmID).find(...)

Вместо этого просто используйте то, что у вас уже есть:

frmCurrentData = $(e.currentTarget).find(...
// or
frmCurrentData = $(this).find(...
0 голосов
/ 07 мая 2018

Вы выбираете только input элементов: .find("input:not('.no-serialize')"). Вам нужно сделать:

.find("input:not('.no-serialize'), select:not('.no-serialize')")

или

.find('input, select').not('.no-serialize')

или

.find(':input').not('.no-serialize')

Но учтите, что при :input документы jQuery рекомендуют:

Для достижения максимальной производительности при использовании: input для выбора элементов, сначала выберите элементы, используя чистый селектор CSS, затем используйте .filter (": input").

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...