Javascript / jQuery - 验证表单所需的最少评论数

Javascript / jQuery - validate the minimum number of comments required for a form

我有一个 table,每个问题都有一些问题(通过 <select> 元素选择)和评论(在 <textarea> 元素中)。所有问题都是必需的,但我只需要填写一定数量的评论才能提交。我正在从 SQLite 中的 table 生成评论和问题输入,所以我不能在任何地方硬编码 require,因为它会在所有这些地方。解决方案可以在 Javascript 代码或 Ruby ERB 中。

我有一个问题和评论计数器,我确信我可以以某种方式在解决方案中使用它。我是 Javascript 的新手,不知道如何让它发挥作用。

这是我实现此功能的尝试:

 <table class="sortable">
  <tr>
    <th></th>
  </tr>

<% data.each.with_index do |data,index|%>
<%if data[0] >= 6 && data[0] <= 20%>
  <tr>
    <td><%=data[1]%></td><td><select name="<%=index%>">
      <option value=""></option>
      <option value="Yes">Yes</option>
      <option value="No">No</option>
      <option value="na">N/a</option>
    </select>

<div class="accordion">Comment</div>
  <div class="panel">
    <textarea class="comments" name="comment<%=index%>" rows="4" cols="15"></textarea>
  </div>
  </td>
  </tr>
<% end %>
<% end %>
</table>
 $('select').change(function() {
// get all selects
var allSelects = $('select');

  // set values count by type
 //var yes = 0;
//var no = 0;
// var na = 0;
var total = 0;

// for each select increase count
$.each(allSelects, function(i, s) {
    // increase count
    if($(s).val() == 'Yes' ) { total++; }
    if($(s).val() == 'No') { total++; }
    if($(s).val() == 'na') { total++; }
});

// update count values summary
$('.cnt-yes').text(yes);
$('.cnt-no').text(no);
$('.cnt-na').text(na);
$('.cnt-total').text(total);
 if (total > 19) {
alert('You have completed this ......')

};

var commentstotal = 0;
$('select').change(function() {

$('.comment-total').text(commentstotal);

});

$(".comments").on("blur", function(){
$(this).val() ? commentstotal++ : commentstotal--;
$('.comment-total').text(commentstotal);
})

HTML 和 Javascript 非常接近您想要的,真正需要的只是很小的改动。缺少一些元素,并进行了一些重新格式化以提高可读性和一致性。这个名为 Form comment validation 的 jsFiddle 显示了实际的解决方案。

HTML 代码(假设它存在于 <form> 元素中):

<table class="sortable">
  <th>
    <td></td>
  </th>

<% data.each.with_index do |data,index| %>
  <% if data[0] >= 6 && data[0] <= 20 %>
    <tr>
      <td>
        <%=data[1]%></td><td><select name="<%=index%>">
          <option value=""></option>
          <option value="Yes">Yes</option>
          <option value="No">No</option>
          <option value="na">N/A</option>
        </select>

        <div class="accordion">Comment</div>
          <div class="panel">
            <textarea class="comments" name="comment<%=index%>" rows="4" cols="15"></textarea>
        </div>
      </td>
    </tr>
  <% end %>
<% end %>
</table>

<fieldset>
  <legend>Totals</legend>
  <p>Yes choices: <span id="cnt-yes"></span></p>
  <p>No choices: <span id="cnt-no"></span></p>
  <p>N/A choices: <span id="cnt-na"></span></p>
  <p>Total choices: <span id="cnt-total"></span></p>
  <p>Comments: <span id="comment-total"></span></p>
  <p>Progress: <span id="progress-message"></span></p>
</fieldset>

<input type="submit" value="Submit!">

这包括以下更改:

  • 更正了 table header
  • <th> 元素的使用
  • 添加了 <fieldset> 来存放计数和进度消息
  • 添加了 submit 按钮以演示 enable/disable 功能

Javascript代码:

var submit = $("input[type='submit']");  // Submit button (to enable/disable dynamically)
var allSelects = $("select");
var cnt_yes = $("#cnt-yes");
var cnt_no = $("#cnt-no");
var cnt_na = $("#cnt-na");
var cnt_total = $("#cnt-total");
var progress_message = $("#progress-message");
var allComments = $(".comments");
var comment_total = $("#comment-total");    

var comments_required = 1;    // <== Change this to set the number of comments required
var comment_minimum_length = 8;  // <== Change this to set the minimum accepted length of a comment

function process_choice() {
    // get all selects

    // set values count by type
    var count_yes = 0;
    var count_no = 0;
    var count_na = 0;
    var count_total = 0;
    var count_comments = 0;
    var complete = true;

    // for each select increase count
    $.each(allSelects, function(i, s) {
        // increase count
        switch ($(s).val()) {
        case "Yes":
            ++count_yes;
            break;
        case "No":
            ++count_no;
            break;
        case "na":
            ++count_na;
            break;
        default:
            complete = false;
            break;
        }
    });

    count_total = count_yes + count_no + count_na;

    $.each(allComments, function() {
        count_comments += $(this).val().length >= comment_minimum_length ? 1 : 0;
    });

    // update count values summary
    cnt_yes.text(count_yes);
    cnt_no.text(count_no);
    cnt_na.text(count_na);
    cnt_total.text(count_total);
    comment_total.text(count_comments);

    if (count_comments < comments_required) {
        var count_remaining = comments_required-count_comments
        $("#progress-message").text("Only " + count_remaining + " choice" + (count_remaining > 1 ? "s" : "") + " left to complete.");
        complete = false;
    } else {
        $("#progress-message").text("The required number of comments has been satisfied.");
    }

    if (complete) {
        submit.removeProp("disabled");
    } else {
        submit.prop("disabled","disabled");
    }
};

allSelects.change(process_choice);
allComments.blur(process_choice);

process_choice();

更新后的 Javascript 包括以下更改:

  • jQuery 选择器移动到脚本的顶部以缓存结果(首选静态 HTML 像这样)
  • 将以前的匿名事件回调函数变成一个命名函数用于初始化目的(见最后一项)
  • 取消注释并重命名 yesnona 变量以演示如何动态更新计数
  • if..if..if 更改为 switch 语句,因为选项对于给定的选择是互斥的
  • 将个人总数添加到 count_total 以供后续使用
  • 添加了评论的最小可接受长度检查
  • 添加了根据是否已做出所有选择和最少评论数来跟踪表单是否 complete
  • 已将总计更新为新 <fieldset> 显示中的 <span> 个元素
  • 更新了进度消息以包括剩余评论数或已满足要求
  • enabled/disabled submit 未选择选项或评论太少时的按钮
  • 为更改事件注册了新的命名函数
  • 在启动时调用新命名的函数来初始化页面状态,从而保证页面状态从一开始就是in-sync