复选框的多个条件

时间:2015-03-15 17:33:07

标签: javascript php jquery mysql html5

我有一个名为student_db的表,如下所示: -

Name    Gender  Grade   City
John    Male    2   North
Dave    Male    4   North
Garry   Male    3   North
Chirsty Female  5   East
Monica  Female  4   East
Andrew  Male    3   East
Patrick Male    7   South
Maria   Female  3   South

我需要选择3名学生列表,学生姓名作为输入。但是有一些限制:

1)必须选择1名女性。

2)可以选择来自同一城市的最多2人。

3)所选3人的等级总和不得超过11。

4)一旦完成三次有效选择,其余复选框应自动冻结。

5)如果在选择某人时违反任何约束,则取消选中该特定选择并向用户显示警告消息。

是否可以在复选框中添加如此多的约束?


修改

我设法添加了2个约束: -

1)如果等级总和超过11,将显示警告消息。

2)一旦进行了三次有效选择,休息复选框将被冻结。

这是我尝试过的: -

<script src="http://code.jquery.com/jquery-1.9.1.js" type="text/javascript"></script>
<script type="text/javascript">
    jQuery(function() {
        var max = 3;
        var checkboxes = $('input[type="checkbox"]');

        checkboxes.change(function() {
            var current = checkboxes.filter(':checked').length;
            checkboxes.filter(':not(:checked)').prop('disabled', current >= max);
        });
    });
</script>

<script>
    function jsFunction(element) {
        var sum = 0,i;
        var elements = document.getElementsByClassName('chkbox');

        for (i = 0; i<elements.length; i++) {
            if (elements[i].checked) {
                sum += parseInt(elements[i].value);
            }
        }

        if (sum > 11) {
            alert("11 maximum grade allowed !!");
            element.checked = false;
        }
    }
</script>

<form name='checkbox1[]' method="post" action="select_student.php">       
    <label class="cb1" for="checkbox1"> </label>
    <input type="hidden" name="checkbox1[]" id="check" value="null">

    <?php
        session_start();
        mysql_connect("localhost", "my_db", "my_password") or die (mysql_error ());
        mysql_select_db("my_db") or die(mysql_error());
        $strSQL = "SELECT Name,Grade FROM student_db";
        $rs = mysql_query($strSQL);
        echo "<b><h2>List of Students :-</h2></b>";

        while($row = mysql_fetch_array($rs)) {
            $man = $row['Name'];
            echo '<input type="checkbox" value="'.$row['Name'].'|'.$row['Grade'].'" class="chkbox"  name="checkbox1[]" onchange="jsFunction(this)" />';
            echo $man;
        }
    ?>
    <br>

    <input type="submit" value="SUBMIT" id="button1" style= "height:40px; width:150px; font-weight: bold; font-size:10;">
</form>

JS函数用于检查等级总和是否超过11,并且一旦进行了3次有效选择,jQuery函数就会冻结其他框。但我无法添加其他约束。

1 个答案:

答案 0 :(得分:1)

对不起延迟回复!昨天我被其他一些东西搞砸了,今天早上不得不接回来。 。 。希望这会帮助你。

你所拥有的是一个非常好的开始。 。 。这是我建议的一些变化:

1)首先,一些HTML更改:

  • 将所有学生数据(即“性别”,“成绩”和“城市”值)存储为复选框中的data属性,如下所示:

    <input type="checkbox" value="NAME_VALUE" class="chkbox" name="checkbox1[]"
           data-gender="GENDER_VALUE" data-grade="GRADE_VALUE" data-city="CITY_VALUE"
           onchange="jsFunction(this)" />
    
  • 接下来,由于您已经在使用jQuery,为了清晰和以后易于维护,请动态应用onchange事件侦听器,而不是将其硬编码到输入中,如下所示:

    <input type="checkbox" value="NAME_VALUE" class="chkbox" name="checkbox1[]"
           data-gender="GENDER_VALUE" data-grade="GRADE_VALUE" data-city="CITY_VALUE" />
    

    。 。 。并且,在脚本中,页面加载后:

    $(".chkbox").on("change", jsFunction);
    
  • 最后(就像抬头一样),如果你打算给我们一个带有<label>属性的for标签(例如,你正在为你的“隐藏”输入显示一个),您需要在id中使用匹配的<input>属性,才能将它们配对。

2)至于你的脚本,我把以下内容汇总在一起,完成了你正在寻找的所有验证检查,并标准化了你的一些编码(你对jQuery和vanilla JS的使用非常复杂)。

var MAX_CHECKED = 3;
var MAX_GRADE = 11;

$("document").ready(function() {
    $(".chkbox").on("change", jsFunction);
});

function jsFunction() {
    var sum = 0;
    var cities = [];

    var elements = $(".chkbox");
    var checkedElements = elements.filter(":checked");

    checkedElements.each(function() {
        sum += parseInt($(this).data("grade"), 10);
        cities.push($(this).data("city"));
    });

    var uniqueCities = cities.filter(function(currentCity, cityIndex, cityArray) {
        return (cityIndex === cityArray.indexOf(currentCity));
    });

    if (sum > MAX_GRADE ) {
        alert(MAX_GRADE + " maximum grade allowed!!");
        $(this).prop("checked", false);
    }
    else if (uniqueCities.length !== cities.length) {
        alert("You may not select more than one student from each city!!");
        $(this).prop("checked", false);
    }
    else {
        if (checkedElements.length >= MAX_CHECKED) {
            if (checkedElements.filter("[data-gender='Female']").length < 1) {
                alert("At least one female student must be selected!!");
                $(this).prop("checked", false);
            }
            else {
                elements.filter(':not(:checked)').prop('disabled', true);
            }
        }
        else {
            elements.filter(':not(:checked)').prop('disabled', false);
        }
    }
}

大多数代码应该非常简单。 。 。让我谈谈几个关键或更复杂的部分。 。

  • Globals - 我将您的全局变量(MAX_CHECKEDMAX_GRADE)设置在任何函数的顶部和外部,以便它们可以在任何地方访问并且易于更新(即,您没有必须搜索代码才能找到它们。
  • “设置代码” - 我将您的设置代码从您jQuery(function() {的{​​{1}}移到了$("document").ready(function() {,仅仅是为了实现可读性。 :)他们做同样的事情。
  • 事件绑定复选框 - 正如我所提到的,我使用$(".chkbox").on("change", jsFunction);动态而不是内联。此外,您会注意到我更改了选择器。由于每个复选框都标有“chkbox”类,我根据它选择,它明显快于$('input[type="checkbox"]')
  • 验证逻辑 - 基本上,您希望尽快捕获无效条目,并且您的规则分为两类:可以在满足最大选择数之前检查的规则以及需要最大值的规则。 “最高等级”和“独特城市”检查应该在被击中后立即被捕获,但您必须等到达到最大选择,然后才能检查性别,因为用户可以随时检查女学生如果他们尚未达到最大值
  • uniqueCities - 用于创建此值的函数并不像其他代码那样直截了当,所以我会稍微澄清一下。它使用.filter原生的Arrays方法,将选择内容减少到唯一值。它通过执行回调来执行此操作,该回调检查当前项的索引(即cityIndex)是否与该值的第一个实例的索引相同(即,数组中的currentCity)(即cityArray)。如果是,则将该值添加到“已过滤”数组(即uniqueCities)。
  • “undisabling” - 我在else语句中添加了一个语句,如果已经进行了最大数量的选择,则会重新启用复选框,但其中一个未选中。这将允许用户在某些时候改变他们的想法,即使他们已经达到了最大值。

一些额外的笔记

1)您最多需要将Patrick的值更改为“6”,以便检查“至少一个女性”逻辑是否正常工作。 。 。目前,来自独特城市的所有男学生的最低组合是约翰,加里和帕特里克,但他们的成绩总数为12,所以它首先触发“等级总和太高”验证。 :)

2)虽然我没有为此编写代码,但您还需要为“提交”按钮开发此验证逻辑的一个版本。如果你不这样做,那么有人可以选择两个男孩并点击“提交”,并且永远不会触发“至少一个女性”逻辑。

一种方法是将“至少一个女性”验证放在自己的方法中并从“我刚刚点击复选框”验证和“我刚刚点击提交按钮”验证中调用。主要区别在于,对于提交,在触发“女性”检查之前,您不会检查是否已经进行了最大选择次数。这也是添加“至少有一个选择”验证的好地方。