动态克隆表单的jQuery图像验证 [英] jQuery Image Validation For Dynamically Cloned Form

查看:60
本文介绍了动态克隆表单的jQuery图像验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a form in my HTML that will get cloned and appended dynamically when the user hits the #addOne button. The form gets validated successfully for any input errors, the only problem that I am facing right now is that it's not working correctly for images. Let's say I upload an image for the first form, it works perfect. But when I click the #addOne button and upload an image for the second form, that's when the problems arise. Prior to even uploading an image for the second form, it's already displaying the image from the previous form on to the page. Uploading an image for this form, will not update form 2. Rather, it'll change form 1's displayed image. How can I make it so that each form displays it's own uploaded image and is validated properly? Here's my 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);
    }
  });
}

推荐答案

我的克隆建议是:

从不克隆已检测到的元素.

Never clone elements that have been instrumented.

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

By instrumented, I mean they have JavaScript behavior set up on them, like event handling.

请执行以下操作:

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

(1) Clone the elements before they have been instrumented and keep the clone in a variable.

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

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

(2) Provide a function that will instrument the set of elements that are to be cloned.

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

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

(3) Call the function for the sets that are already on the page.

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

(4)如果要添加另一组元素,请 克隆克隆 并添加它,然后在其上调用函数.

(4) When you want to add another set of the elements, clone the clone and add it, and call the function on it.

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

  initializeForm($newForm, numPagesTemp--);

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

jsfiddle

您还需要将验证器对象存储在名为validator的变量中.

You also need to store the validator object in a variable named validator.

var validator = $form.validate({


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


Also, you should avoid duplicate id values when cloning. You have an id on the form submit button, but it does not appear to be needed, so perhaps you can just remove that.

这篇关于动态克隆表单的jQuery图像验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆