Включить кнопку «Отправить» только в случае изменения значения - PullRequest
0 голосов
/ 27 апреля 2018

Сценарий:

У меня есть форма, которая может иметь или не иметь значение. Первоначально кнопка отправки будет отключена. Если я что-то изменяю в элементе формы, мне нужно включить кнопку отправки. Но если я изменю текстовое поле имени, которое имеет значение «SAM», на «SAM2», что включает кнопку отправки, но если я снова изменю значение имени на его исходное значение «SAM», то оно считается не тронутым, и кнопка отправки должна быть инвалиды.

Текущая реализация:

С того момента, как я использовал событие change, чтобы включить кнопку отправки, но если я верну значение назад, кнопка все еще будет включена.

Код:

HTML:

<form id="specgeneralform">
<div class="row">
    <div class="col-3">
        <div class="form-group">
            <label for="spec-detail-outsource">Outsource</label>
            @Html.DropDownListFor(m => m.OutSource, outsourcelistItems, "Please Select", new { @id = "spec-detail-outsource" })
        </div>
    </div>
    <div class="col-3 lsc-optional-hide" id="vendor-block">
        <div class="form-group">
            <label for="spec-detail-vendors">Vendor</label>
            @Html.DropDownListFor(m => m.VendorID, new SelectList(Model.listVendors, "VendorID", "VendorName"), "Please Select", new { @id = "spec-detail-vendors" })
        </div>
    </div>
    <div class="col-3 lsc-optional-hide" id="plant-block">
        <div class="form-group">
            <label for="spec-detail-plant">Plant</label>
            @Html.DropDownListFor(m => m.PlantID, new SelectList(Model.listPlants, "PlantID", "PlantName"), "Please Select", new { @id = "spec-detail-plant" })
        </div>
    </div>
    <div class="col-3 lsc-optional-hide" id="dsc-block">
        <div class="form-group">
            <label for="spec-detail-dsclocation">DSC Location</label>
            @Html.DropDownListFor(m => m.DscLocationID, new SelectList(Model.listDSCLocations, "PlantID", "PlantName"), "Please Select", new { @id = "spec-detail-dsclocation" })
            @Html.HiddenFor(x => x.DscLocationID)
        </div>
    </div>
    <div class="col-3 lsc-optional-hide" id="cost-block">
        <div class="form-group">
            <label for="spec-detail-cost">Cost</label>
            <div class="input-group input-group-sm">
                <div class="input-group-prepend">
                    <span class="input-group-text">$</span>
                </div>
                @Html.TextBoxFor(x => x.Cost, new { @class = "form-control small" })
                <div class="input-group-append">
                    @Html.DropDownListFor(m => m.CostUOM, costuomlistItems, "Please Select", new { @id = "spec-detail-unit" })

                </div>
            </div>
        </div>
    </div>
</div>
<div class="row">
    <div class="col-12">
        <div class="form-group">
            <label for="comment">Comments</label>
            @Html.TextAreaFor(x => x.BuyerComments, new { @class = "form-control" })
            <label id="BuyerComments-error" class="error invalid-feedback" for="BuyerComments">Comments must not be more than 1000 characters</label>
        </div>
    </div>
</div>
<div class="row" style="padding-bottom: 15px;">
    <div class="col-12">
        <button id="spec-detail-general-save" type="button" class="btn lsc-btn-primary float-right" disabled="disabled">SAVE CHANGES</button>
    </div>
</div>
</form>

JS:

$(":input").change(function () {

    if ($("#specgeneralform").valid()) {
        unsaved = true;
        $("#spec-detail-general-save").prop("disabled", false);
    }
    else {
        unsaved = false;
        $("#spec-detail-general-save").prop("disabled", true);
    }
});

Посоветуйте, пожалуйста, какой лучший способ сделать это?

ОБНОВЛЕНИЕ # 1

Я опробовал решение @ Takit-Isy, оно сработало для всех элементов, кроме этого

<tr>
   <td>Spec Confirmed:</td>
   <td>
      <label class="switch">
        @Html.CheckBoxFor(x => x.SpecConfirmed)
        <span class="slider round"></span>
      </label>
    </td>
  </tr>
  <tr>
     <td>MDM Override:</td>
        <td>
           <label class="switch">
             @Html.CheckBoxFor(x => x.IsOverride)
             <span class="slider round"></span>
           </label>
         </td>
      </tr> 

поэтому я установил флажок, как этот, который не работает, но остальные работают отлично.

enter image description here

Ответы [ 5 ]

0 голосов
/ 18 июля 2019

Если вы ищете IE совместимый, используйте ниже

Модифицированная версия Такита Иси, которая позаимствовала его у Кита (спасибо, ребята).

   $(document).ready(function () {    
         trackInputs(); 
    });

    var controls = $('form').find(':input');
    var controlValues = [];
    $(controls).each(function (i, element) {
        var ctrl = [element.id, element.value + element.checked]
        controlValues.push(ctrl);
    });
    function trackInputs() {
      var disabled = true;
        $(controlValues).each(function (i, element) {
            if (element[0] != "") {
                var ctr = $("#" + element[0]);
                if ($(ctr).val() + $(ctr).prop( "checked" ) !== element[1]) {
                    disabled = false;
                }
            }
        });
        var submitButton = document.querySelector("[type=submit]");
        if (submitButton != null)
        {
            submitButton.disabled = disabled;
        }
    };
    document.oninput = trackInputs;
    document.onchange = trackInputs;
0 голосов
/ 27 апреля 2018

Пытаясь улучшить ответ Кита, вот что я сделаю:

const inputs = document.querySelectorAll("input, select");
for (const el of inputs){
  el.oldValue = el.value + el.checked;
}

// Declares function and call it directly
var setEnabled;
(setEnabled = function() {
  var e = true;
  for (const el of inputs) {
    if (el.oldValue !== (el.value + el.checked)) {
      e = false;
      break;
    }
  }
  document.querySelector("button").disabled = e;
})();

document.oninput = setEnabled;
document.onchange = setEnabled;
<form>
  input 1: <input value="one"><br>
  input 2: <input value="two"><br>
  select 1:
  <select>
    <option>Bla1</option>
    <option>Bla2</option>
    <option>Bla3</option>
  </select><br>
  Checkbox 1: <input type="checkbox"><br>
  Checkbox 2: <input type="checkbox" checked><br>
  <button action="submit">Save</button>
</form>

Я знаю, как объявить функцию для вызова ее сразу после создания довольно сложно, но это так, и она отлично работает!…

Надеюсь, это поможет.

0 голосов
/ 27 апреля 2018

Поскольку у вас могут быть динамические начальные значения, я предлагаю общий способ. Установите начальное значение всех входных данных в атрибуте данных, чтобы можно было сравнить любое изменение с начальными значениями:

$(document).ready(function(){
     $(":input").each(function(){
        $(this).data("initial",$(this).val());
     })
})

$(":input").change(function () {

    if ($("#specgeneralform").valid() && $(this).val() != $(this).data("initial")) {

        unsaved = true;
        $("#spec-detail-general-save").prop("disabled", false);
    }
    else {
        unsaved = false;
        $("#spec-detail-general-save").prop("disabled", true);
    }
});
0 голосов
/ 27 апреля 2018

Без использования jQuery, вот простой метод ..

test: изменить вход 1 с one и обратно. Выполнить то же самое для входа 2 ..

const inputs = document.querySelectorAll("input");

function saveCurrent() {
  for (const el of inputs) el.oldValue = el.value;
}

function setEnabled() {
  var e = false;
  for (const el of inputs) {
    if (el.oldValue !== el.value) {
      e = true;
      break;
    }
  }
  document.querySelector("button").disabled = !e;
}

document.addEventListener("input", setEnabled);

saveCurrent();
setEnabled();
<form>
  input 1: <input value="one"><br>
  input 2: <input value="two"><br>
  <button action="submit">Save</button>
</form>
0 голосов
/ 27 апреля 2018

В случае изменения выполните итерации input s и убедитесь, что все входные данные не заполнены (или по умолчанию - как 'SAM'). Если так, то отключите кнопку; иначе, включите кнопку. Трудно точно описать, как выполнять итерации, не видя содержимого HTML-формы.

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