首页 > 网页设计 > 怎样保存 Checkbox 值

怎样保存 Checkbox 值

预备知识点:

01 二进制数值:
02 0的二进制数值是   0
03 1的二进制数值是   1
04 2的二进制数值是  10
05 3的二进制数值是  11
06 4的二进制数值是 100
07 5的二进制数值是 101
08 6的二进制数值是 110
09 ...
10 在 php 中可以通过 decbin() 函数将十进制数字转换为二进制数字.
11
12 位运算符 & (按位与), 什么是 & 运算呢?
13 以 $c = $a & $b 表达式为例, & 运算是将 $a, $b 的二进制数值相比较, 只要两个二进制数中某位都是1, 则结果的二进制数中该位都为1, 否则结果为 0.
14
15 假设:
16 $a 的值为 2 (十进制), 它的二进制数值为  10
17 $b 的值为 4 (十进制), 它的二进制数值为 100
18 那么 $c 为 0 (十进制) 因数 $a & $b 的结果为 000(二进制数值), 转换为十进制数值就为 0
19
20 假设:
21 $a 的值为 2 (十进制), 它的二进制数值为  10
22 $b 的值为 6 (十进制), 它的二进制数值为 110
23 那么 $c 为 2 (十进制) 因数 $a & $b 的结果为 010(二进制数值), 转换为十进制数值就为 2
24
25 Javascript/php/mysql 都支持 & 运算.

OK. 进入正题:
我们现在要记录用户的兴趣爱好, 兴趣爱好有很多选项, 可以复选, 表现在页面上就是一堆的 checkbox , 它看起来像是这样子的

1 <input type="checkbox" name="hobby[]" value="aa">爱好1 <br>
2 <input type="checkbox" name="hobby[]" value="bb">爱好2 <br>
3 <input type="checkbox" name="hobby[]" value="cc">爱好3 <br>
4 <input type="checkbox" name="hobby[]" value="dd">爱好4 <br>
5 <input type="checkbox" name="hobby[]" value="ee">爱好5 <br>
6 <input type="checkbox" name="hobby[]" value="ff">爱好6 <br>
7 <input type="checkbox" name="hobby[]" value="gg">爱好7 <br>

假设用户勾选的是 "爱好1", "爱好3", "爱好5", 我们要怎么把用户勾选的值保存到数据库呢?

方法1:

1 用特定的分隔符(比如,)把用户勾选的 value 值串连起来? 那么保存到数据库中的值应该是 "aa,cc,ee"
2 还有别的方法吗?

方法2:

1 保存到数据库的值是 "1010100" , 这个字串是怎么得来的呢? 设计这种方法的思想是这样的: 数据库中保存一个长度与复选框个数一样的字符串, 这个字串中的第一位就表示第一个复选框, 如果第一个复选框的勾选了, 那字串的第一位就是1. 同样的道理所以字串的第3位,第5位值为1, 其它位值为0.
2 还有别的方法吗?

我用的是方法3:

1 重新设计 checkbox 的值, 将它们设置成2的N(N>=0)次方. 它看起来像这样子:
2 <input type="checkbox" name="hobby[]" value="1" >爱好1 <br>
3 <input type="checkbox" name="hobby[]" value="2" >爱好2 <br>
4 <input type="checkbox" name="hobby[]" value="4" >爱好3 <br>
5 <input type="checkbox" name="hobby[]" value="8" >爱好4 <br>
6 <input type="checkbox" name="hobby[]" value="16">爱好5 <br>
7 <input type="checkbox" name="hobby[]" value="32">爱好6 <br>
8 <input type="checkbox" name="hobby[]" value="64">爱好7 <br>
9 而我要保存到数据库中的值是 21, 没错, 它是一个数字, 它是怎么来的呢? 1+4+16 = 21, 它就是将用户勾选的复选框 value 值累加而以.

为什么是2的N(N>=0)次方? ( 1, 2, 4, 8, 16, 32, ... )

01 <?php
02 //我们来看看它们的二进制数值有什么特点.
03 echo decbin(1)."<br>";   //       1
04 echo decbin(2)."<br>";   //      10
05 echo decbin(4)."<br>";   //     100
06 echo decbin(8)."<br>";   //    1000
07 echo decbin(16)."<br>";  //   10000
08 echo decbin(32)."<br>";  //  100000
09 echo decbin(64)."<br>";  // 1000000
10
11 //来看问题: 为什么要把 value 值设置为2的N(N>=0)次方?
12 //因为2的N(N>=0)次方数字的二进制表示一定是最左边第一位是1, 其它位是0,
13 //而正是这样的特性, 使得任意2的N(N>=0)次方数字相加, 都不会在其对应的二进制数字中出现进位的状况.
14 //什么意思? 举个例子:
15 //1+2+4 二进制表示是 1+10+100
16 //1+2+3 二进制表示是 1+10+11  <-- 这样会使右边第一位,第二位出现进位
17
18 //再来看个例子
19 echo decbin(1+2)."<br>";     //    11
20 echo decbin(1+2+4)."<br>";   //   111
21 echo decbin(4+8)."<br>";     //  1100
22 echo decbin(1+4+16)."<br>";  // 10101
23 //结合"任意2的N(N>=0)次方数字相加, 都不会在其对应的二进制数字中出现进位的状况"的特性, 很容易分析出上面例子中的规律:
24 //结果值的二进制数值中如果右边第一位是1, 那么结果值的十进制数值一定是 1+***
25 //结果值的二进制数值中如果右边第二位是1, 那么结果值的十进制数值一定是 2+***
26 //结果值的二进制数值中如果右边第一位是1,右边第二位也是1, 那么结果值的十进制数值一定是 1+2+***
27
28 //我们回到用户勾选爱好复选框保存到数据库中的值 21 (十进制)
29 //通俗点, 我们可以这样理解:
30 //2的N(N>=0)次方数字的和(例如21) 的二进制表示(10101), 从右至左如果第n位为1, 那它十进制一定是 2 的 n-1 次方与其它2的N(N>=0)次方数字的和
31 //所以 21(二进制表示为 10101) 应该是 (2的(1-1)次方)+(2的(3-1)次方)+(2的(5-1)次方) = 1+4+16
32
33 //同样根据"任意2的N(N>=0)次方数字相加, 都不会在其对应的二进制数字中出现进位的状况"的特性, 结合我们已知的 & 运算, 我们能很方便的判断 任意2的N(N>=0)次方数字相加的和中是否存在一个确定的2的N(N>=0)次方数字
34 echo (21 & 1)."<br>";   // 1
35 echo (21 & 2)."<br>";   // 0
36 echo (21 & 4)."<br>";   // 4
37 echo (21 & 8)."<br>";   // 0
38 echo (21 & 16)."<br>";  // 16
39 echo (21 & 32)."<br>";  // 0
40 echo (21 & 64)."<br>";  // 0
41 ?>

我们来看看页面前端 javascript 是怎么保存和还原用户勾选的选项的:

01 <input type="button" value="要保存到数据库中的值" onclick="get_save_value('hobby[]')">
02 <input type="button" value="清除勾选" onclick="clear_all('hobby[]')"> <br>
03 <br>还原勾选框<br>
04 <input type="text" name="set_check_value" id="set_check_value"><br>
05 <input type="button" value='先点击 "清除勾选" 再点我' onclick="set_check('hobby[]', document.getElementById('set_check_value').value)"> <br>
06
07 <script language="JavaScript">
08 /* 重点 */
09 //还原用户的选取项
10 function set_check(name, value){
11     var obj = document.getElementsByName(name);
12     for(var i=0; i<obj.length; i++){
13         if( (obj[i].value & value) == obj[i].value ){
14             obj[i].checked = true;
15         }
16     }
17 }
18
19 /* 这不是重点 */
20 function get_save_value(name){
21     var obj = document.getElementsByName(name);
22     var saveValue = 0;
23     for (var i=0; i<obj.length; i++){
24         if (obj[i].checked){
25             saveValue += parseInt(obj[i].value);
26         }
27     }
28     document.getElementById("set_check_value").value = saveValue;
29     alert(saveValue); //这个就是要存到数据表里的值
30 }
31
32 function clear_all(name){
33     var obj = document.getElementsByName(name);
34     for (var i=0; i<obj.length; i++){
35         obj[i].checked = false;
36     }
37 }
38 </script>

我们来看看后端数据库是查询用户勾选项的:
假设我们 tableName 中的 hobby 字段是保存用户的兴趣爱好值
一个用户一第记录, 如果前面的例子成功记录到数据库中, 那么 tableName 中应该有一条 hobby==21 的值的记录.

view source

print?

01 --要查询选择了"爱好1"或者"爱好3"的用户:
02 --爱好1(value=1)
03 --爱好3(value=4)
04 SQL: SELECT FROM tableName WHERE (hobby&1) OR (hobby&4);
05
06 --要查询选择了"爱好1"并且"爱好3"的用户:
07 --爱好1(value=1)
08 --爱好3(value=4)
09 SQL: SELECT FROM tableName WHERE (hobby&1) AND (hobby&4);
10
11 --要查询只选择了"爱好1"和"爱好3"的用户:
12 --爱好1(value=1)
13 --爱好3(value=4)
14 SQL: SELECT FROM tableName WHERE hobby=(1+4)

本文固定链接: http://www.devba.com/index.php/archives/5234.html | 开发吧

报歉!评论已关闭.