繁体   English   中英

动态复制表单的jQuery图像验证

[英]jQuery Image Validation For Dynamically Cloned Form

我的HTML中有一个表单,当用户点击#addOne按钮时,该表单将被克隆并动态添加。 该表单已成功针对任何输入错误进行了验证,我现在面临的唯一问题是它无法正确处理图像。 假设我上传了第一种形式的图片,效果很好。 但是,当我单击#addOne按钮并为第二个表单上传图像时,就出现了问题。 甚至在为第二个表单上传图像之前,它已经将前一个表单的图像显示在页面上。 上载此表单的图像不会更新表单2。相反,它将更改表单1的显示图像。 如何使每个表单显示其自己的上载图像并正确验证? 这是我的jsFiddle

的HTML

<div class="article_properties">

  <form class="article_properties_form" action="" method="POST" enctype="multipart/form-data">
    <p style="display: inline">Page Number</p>
    <div style="background-color: #FF355E; padding: 5px; display: inline; margin-left: 5px">

      <p style="display: inline" class="pageNumber"></p>
    </div>
    <textarea style="display: none" class="inputNumber" name="pages"></textarea>
    <p>Image</p>
    <input style="padding: 0px" type="file" name="image" class="pageImg">
    <div class="imgContainer">
    </div>
    <p>Subtitle</p>
    <input type="text" name="subtitle">

    <p>Text</p>
    <textarea name="text" rows="4"></textarea>
    <input id="properties_btn" type="submit" value="Submit/Update" name="properties_submit">
    <hr style="border: 1px dotted lightgray; margin-bottom: 50px">
  </form>


  <a style="display: none; text-align: center; margin: 50px; font-size: 25px" class="expand" href="#">

  </a>
</div>
<!--End of article properties div-->
<div id="addOne">
  <p>+Add page</p>
</div>

<div class="nextBtn" style="display: none">
  <p>Finalize my article</p>
</div>

jQuery的

var numPagesTemp = 4;
$('.pageNumber:last').text(numPagesTemp);
$('.inputNumber:last').text(numPagesTemp);
//Invoke functions for first form
add_validation_for_forms();
add_image_construction();

//Form validation
function add_validation_for_forms() {
  $(".article_properties_form").each(function() {
    $(this).validate({
      errorElement: 'div',

      rules: {
        image: {
          required: true,
          extension: "jpg|jpeg|png",
          minImageSize: {
            width: 600,
            height: 400
          }
        },

        subtitle: {
          required: true,
          minlength: 2,
          maxlength: 25
        },
        text: {
          required: true,
          minlength: 35,
          maxlength: 275
        }
      },

      messages: {
        image: {
          required: "This page needs an image",
          extension: "You're only allowed to upload jpg or png images."
        },

        subtitle: {
          required: "You have to provide a subtitle for this page!",
          minlength: "Your subtitle must be at least 2 characters long",
          maxlength: "Your subtitle must be less than 25 characters long"
        },
        text: {
          required: "Please enter text for this page",
          minlength: "Your text must be at least 35 characters long",
          maxlength: "Your text must be less than 275 characters long"
        },
      },
    });
  });
}
//Adding a form
$('#addOne').click(function() {

  numPagesTemp--;

  var articlePropsTemplate = $('.article_properties_form:last').clone();
  articlePropsTemplate.show();
  $('.article_properties').append(articlePropsTemplate);

  var articlePropsExpand = $('.expand:last').clone();
  articlePropsExpand.text("Expand " + numPagesTemp);
  articlePropsExpand.hide();

  $('.article_properties').append(articlePropsExpand);

  $('.pageNumber:last').text(numPagesTemp);
  $('.inputNumber:last').text(numPagesTemp);
  articlePropsTemplate[0].reset();
  add_validation_for_forms();

  add_image_construction();
  articlePropsTemplate.validate().resetForm();

  if (numPagesTemp == 1) {
    $('#addOne').hide();
    $(".nextBtn").show();
  }

});

//Adding Method
$.validator.addMethod('minImageSize', function(value, element, minSize) {
  var imageSize = $(element).data('imageSize');
  return (imageSize) && (imageSize.width >= minSize.width) && (imageSize.height >= minSize.height);
}, function(minSize, element) {
  return ($(element).data('imageSize')) ? ("Your image's size must be at least " + minSize.width + "px by " + minSize.height + "px") : "Selected file is not an image.";
});

//Image Uploading
var $properties_btn = $('properties_btn'),
  $imgContainer = $('.imgContainer'),
  $pageImg = $('.pageImg');

function add_image_construction() {

  $('.pageImg').change(function() {
    $pageImg.removeData('imageSize');
    $imgContainer.hide().empty();

    var file = this.files[0];

    if (file.type.match(/image\/.*/)) {
      $properties_btn.attr('disabled', true);

      var reader = new FileReader();

      reader.onload = function() {
        var $img = $('<img />').attr({
          src: reader.result
        });

        $img.on('load', function() {
          $imgContainer.append($img).show();

          $pageImg.data('imageSize', {
            width: $img.width(),
            height: $img.height()
          });

          $img.css({
            width: '400px',
            height: '200px'
          });

          $properties_btn.attr('disabled', false);

          validator.element($pageImg);
        });
      }

      reader.readAsDataURL(file);
    } else {
      validator.element($pageImg);
    }
  });
}

我的建议是:

切勿克隆已检测的元素。

通过检测,我的意思是他们身上设置了JavaScript行为,例如事件处理。

而是执行以下操作:

(1)在插入元素之前先对其进行克隆,然后将克隆保留在变量中。

var $CLONED_FORM = $('.article_properties_form:first').clone();

(2)提供一个功能,该功能将检测要克隆的元素集。

function initializeForm($form, pageNum) {
  // Set up form validation here.
  // Also attach the change-event handler for the file input here.
}

(3)调用页面上已经存在的集合的函数。

$('.article_properties_form').each(function() {
  initializeForm($(this), numPagesTemp--);
});

(4)当您要添加另一组元素时, 克隆克隆并添加它,然后在其上调用函数。

$('#addOne').click(function() {
  var $newForm = $CLONED_FORM.clone().appendTo('.article_properties').show();

  initializeForm($newForm, numPagesTemp--);

  if (numPagesTemp == 0) {
    $('#addOne').hide();
    $(".nextBtn").show();
  }
});

jsfiddle


您还需要将Validator对象存储在一个名为validator的变量中。

var validator = $form.validate({

另外,克隆时应避免重复的id值。 您在表单提交按钮上有一个id ,但是似乎不需要它,因此也许您可以删除它。

我需要使用我的代码

编辑,更新

class="properties_btn"替换为id="properties_btn"以防止将重复的id附加到document change事件时定义的validator

 $(function() { var numPagesTemp = 4; $('.pageNumber:last').text(numPagesTemp); $('.inputNumber:last').text(numPagesTemp); //Invoke functions for first form add_validation_for_forms(); add_image_construction(); //Form validation function add_validation_for_forms() { $(".article_properties_form").each(function() { $(this).validate({ errorElement: 'div', rules: { image: { required: true, extension: "jpg|jpeg|png", minImageSize: { width: 600, height: 400 } }, subtitle: { required: true, minlength: 2, maxlength: 25 }, text: { required: true, minlength: 35, maxlength: 275 } }, messages: { image: { required: "This page needs an image", extension: "You're only allowed to upload jpg or png images." }, subtitle: { required: "You have to provide a subtitle for this page!", minlength: "Your subtitle must be at least 2 characters long", maxlength: "Your subtitle must be less than 25 characters long" }, text: { required: "Please enter text for this page", minlength: "Your text must be at least 35 characters long", maxlength: "Your text must be less than 275 characters long" }, }, }); }); } //Adding a form $('#addOne').click(function() { numPagesTemp--; var articlePropsTemplate = $('.article_properties_form:last') .clone(); articlePropsTemplate.find("img").remove(); $('.article_properties').append(articlePropsTemplate); var articlePropsExpand = $('.expand:last').clone(); articlePropsExpand.text("Expand " + numPagesTemp); articlePropsExpand.hide(); $('.article_properties').append(articlePropsExpand); $('.pageNumber:last').text(numPagesTemp); $('.inputNumber:last').text(numPagesTemp); $("form:last")[0].reset(); add_validation_for_forms(); // add_image_construction(); articlePropsTemplate.validate().resetForm(); if (numPagesTemp == 1) { $('#addOne').hide(); $(".nextBtn").show(); } }); //Adding Method $.validator.addMethod('minImageSize', function(value, element, minSize) { var imageSize = $(element).data('imageSize'); return (imageSize) && (imageSize.width >= minSize.width) && (imageSize.height >= minSize.height); }, function(minSize, element) { return ($(element).data('imageSize')) ? ("Your image's size must be at least " + minSize.width + "px by " + minSize.height + "px") : "Selected file is not an image."; }); //Image Uploading // var $properties_btn = $('.properties_btn'), // $imgContainer = $('.imgContainer'), // $pageImg = $('.pageImg'); function add_image_construction() { $(document).on("change", ".pageImg", function(e) { var form = $(this).closest("form"); var validator = form.validate(); $(this).removeData('imageSize'); form.find('.imgContainer').hide().empty(); var file = this.files[0]; if (file.type.match(/image\\/.*/)) { form.find('.properties_btn').attr('disabled', true); var reader = new FileReader(); reader.onload = function() { var $img = $('<img />').attr({ src: reader.result }); $img.on('load', function() { form.find('.imgContainer').append($img).show(); $(e.target).data('imageSize', { width: $img.width(), height: $img.height() }); $img.css({ width: '400px', height: '200px' }); form.find('.properties_btn').attr('disabled', false); validator.element(e.target); }); } reader.readAsDataURL(file); } else { validator.element(e.target); } }); } }) 
 form { border: 1px solid blue; padding: 10px; margin: 10px; } 
 <script src="https://code.jquery.com/jquery-3.0.0.js"></script> <script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.15.0/jquery.validate.min.js"></script> <script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.15.0/additional-methods.min.js"></script> <div class="article_properties"> <form class="article_properties_form" action="" method="POST" enctype="multipart/form-data"> <p style="display: inline">Page Number</p> <div style="background-color: #FF355E; padding: 5px; display: inline; margin-left: 5px"> <p style="display: inline" class="pageNumber"></p> </div> <textarea style="display: none" class="inputNumber" name="pages"></textarea> <p>Image</p> <input style="padding: 0px" type="file" name="image" class="pageImg"> <div class="imgContainer"> </div> <p>Subtitle</p> <input type="text" name="subtitle"> <p>Text</p> <textarea name="text" rows="4"></textarea> <input class="properties_btn" type="submit" value="Submit/Update" name="properties_submit"> <hr style="border: 1px dotted lightgray; margin-bottom: 50px"> </form> <a style="display: none; text-align: center; margin: 50px; font-size: 25px" class="expand" href="#"> </a> </div> <!--End of article properties div--> <div id="addOne"> <p>+Add page</p> </div> <div class="nextBtn" style="display: none"> <p>Finalize my article</p> </div> 


这是您要实现的简化版本,没有验证上传的文件

 // maximum number of `form` elements which `document` should contain var n = 4; // display `form` index function handleLabel() { $("label").html(function(index, html) { return "form #" + index }) } handleLabel(); function processFile() { // preview uploaded image $("<img>", {src: URL.createObjectURL(this.files[0])}) .insertAfter(this.nextElementSibling).after("<br>"); } // handle file upload; delegate event to `document` $(document).on("change", ":file", processFile); // append cloned `form` to page $("button").on("click", function() { // if less than `n` forms if ($("form").length < 4) { // copy last `form` `.outerHTML` instead of using `.clone()` $($("form:last")[0].outerHTML) // remove `img` from `html` .find("img").remove().end() .insertAfter("form:last"); // update `form` `label` elements handleLabel(); } else { // detach `click` event from `button` // when four `form` elements exist in `document` $(this).off("click") } }); // handle `form` submit event $(document).on("submit", "form", function(e) { var img = $(this).find("img")[0]; // check `img` `width`, `height` if (img.naturalWidth < 600 || img.naturalHeight < 400) { e.preventDefault(); this.reset(); alert("invalid img width or height") } }) 
 form { border: 1px solid blue; padding: 10px; margin: 10px; } 
 <script src="https://code.jquery.com/jquery-3.0.0.js"></script> <form> <fieldset> <label></label><br> <input name="file" type="file" accept=".jpg,.jpeg,.png" required /> <br> <input type="submit" /> </fieldset> </form> <button> add form </button> 

jsfiddle https://jsfiddle.net/hLjvffpv/5/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM