开发者问题收集

如何以分步形式进行验证?

2019-09-12
120

我有一个包含三个步骤的表单:选择饮料、选择吃和发送。我在验证方面遇到了一些问题。现在我的验证仅在提交时有效。但我需要在每个步骤(在下一个按钮上)进行验证。怎么做?

$.validity = {
  defaults: {
    errors: {
      badInput: 'Bad input',
      customError: 'Custom error',
      patternMismatch: 'Pattern mismatch',
      rangeOverflow: 'Range overflow',
      rangeUnderflow: 'Range underflow',
      stepMismatch: 'Step mismatch',
      tooLong: 'Too long',
      tooShort: 'Too short',
      typeMismatch: 'Type mismatch',
      valueMissing: 'Value missing'
    },
    unknownError: 'Unknown error',
    output: function(input, message) {
      console.log('validity.output', input, message);
    },
    getMessage: function(input) {
      if (input.validity.valid)
        return '';

      for (var error in this.errors) {
        if (input.validity[error])
          return this.errors[error];
      }

      return this.unknownError;
    }
  }
};

$.fn.validity = function(options) {
  options = $.extend({}, $.validity.defaults, options);

  return this.each(function() {
    var component = $(this);
    var form = component.closest('form');
    var elements = $(form.prop('elements'));

    elements.on('input', function() {
      options.output(this, options.getMessage(this));
    });

    form.on('submit', function(e) {
      if (this.checkValidity())
        return;

      e.preventDefault();
      e.stopPropagation();

      elements.trigger('input');
    });

    form.attr('novalidate', true);
  });
}

var mainForm = '.form';
$(mainForm).validity({
  output: function(input, message) {
    var field = $(input).closest('.form__field');
    field.toggleClass('m-error', !!message);
    field.find('.form__error').text(message);
  }
});

var base = '.form';
$(base).each(function() {
  var component = $(this);
  var slideList = component.find(base + '__container');
  var slides = component.find(base + '__section');
  var prev = component.find('.js-prev');
  var next = component.find('.js-next');
  var activeIndex = 0;

  function setActive(index) {
    index = (index + slides.length) % slides.length;
    slideList.css({
      left: index * -100 + '%'
    });
    activeIndex = index;
  }

  prev.click(function(e) {
    e.preventDefault();
    setActive(activeIndex - 1);
  });

  next.click(function(e) {
    e.preventDefault();

    setActive(activeIndex + 1);
  });

  setActive(activeIndex);

  var mediaItems = component.find('.form__section .media-item');

  mediaItems.each(function() {
    var mediaItem = $(this);
    var radio = mediaItem.find('input[type="radio"]').first().attr('checked');

    if (radio) {
      mediaItem.addClass('media-item_checked');
    } else {
      mediaItem.removeClass('media-item_checked');
    }
  });

  mediaItems.on('click', function(e) {
    e.preventDefault();
    var mediaItem = $(this);
    var mediaItems = $(this).closest('.form__section').find('.media-item');
    var radio = mediaItem.find('input[type="radio"]');

    mediaItems.removeClass('media-item_checked');
    mediaItem.addClass('media-item_checked');
    radio.prop('checked', !radio.prop('checked'));

    setActive(activeIndex + 1);
  });
});
.form {
  overflow: hidden;
}

.form__container {
  position: relative;
  left: 0;
  display: flex;
  transition: .5s;
}

.form__section {
  flex-shrink: 0;
  width: 100%;
  transition: .5s;
}

.form__actions {
  display: flex;
  justify-content: space-between;
}

.form__actions_end {
  justify-content: flex-end;
}

.form__error {
  color: red;
}

.media {
  display: flex;
  margin-bottom: 20px;
}

.media-item {
  width: 200px;
  border: 3px solid transparent;
  background-color: gray;
  margin: 0 10px;
  padding: 20px;
  cursor: pointer;
}

.media-item_checked {
  border-color: red;
}

.media input[type="radio"] {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="" class="form">
  <div class="form__container">
    <div class="form__section">
      <div class="form__field">
        <div class="media">
          <div class="media-item">
            Tea
            <input class="eventTrigger icon-input" name="Lead.LeadData.Heating" type="radio" required>
          </div>
          <div class="media-item">
            Coffie
            <input class="eventTrigger icon-input" name="Lead.LeadData.Heating" type="radio" required>
          </div>
        </div>
        <div class="form__error"></div>
      </div>
      <div class="form__actions form__actions_end">
        <input type="button" value="Next" class="js-next" />
      </div>
    </div>
    <div class="form__section">
      <div class="form__field">
        <div class="media">
          <div class="media-item">
            Roll
            <input class="eventTrigger icon-input" name="Lead.LeadData" type="radio" required>
          </div>
          <div class="media-item">
            Banana
            <input class="eventTrigger icon-input" name="Lead.LeadData" type="radio" required>
          </div>
        </div>
        <div class="form__error"></div>
      </div>
      <div class="form__actions">
        <input type="button" value="Back" class="js-prev" />
        <input type="button" value="Next" class="js-next" />
      </div>
    </div>
    <div class="form__section">
      Send form
      <div class="form__actions">
        <input type="button" value="Back" class="js-prev" />
        <input type="submit" value="Send form" />
      </div>
    </div>
  </div>
</form>
2个回答

您可以在 javascript 中逐个验证字段:

使用:

onClick='validatefunction()'

更多信息请见: 使用 javascript 进行实时验证 - onchange 仅触发一次

Ggs
2019-09-12
  1. 为每个步骤的下一个按钮赋予不同的类名(“js-next1,js-next2)”。
  2. 现在将这些按钮绑定到点击事件(函数),以便在点击这些按钮时验证必填字段。
Happs
2019-09-12