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