2009年3月14日星期六

解决AJAX表单用POST方式提交Checkbox复选框的问题

用AJAX的POST方式提交表单,函数如下:

function createXMLHttp()
{
var xmlhttp = false;
try
{
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
try
{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (E)
{
xmlhttp = false;
}
}

if (!xmlhttp && typeof XMLHttpRequest != 'undefined')
{
xmlhttp = new XMLHttpRequest();
}

return xmlhttp;
}

function getRequestBody(oForm)
{
var aParams = new Array();

for (var i=0 ; i < oForm.elements.length; i++)
{
var sParam = encodeURIComponent(oForm.elements[i].name);
sParam += "=";
sParam += encodeURIComponent(oForm.elements[i].value);
aParams.push(sParam);
}

return aParams.join("&");
}

function sendPostRequest()
{
var oForm = document.forms[0];
var sBody = getRequestBody(oForm);

var xmlhttp = createXMLHttp();
xmlhttp.open("POST", oForm.action, true);

xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState == 4)
{
if (xmlhttp.status == 200)
{
// success
}
else
{
// failed
}
}
};

xmlhttp.send(sBody);
}


一个含有复选框的表单:

<form id="Reg-form" name="Reg-form" onsubmit="sendPostRequest(); return false;"
action="submit.php" method="post" encType="multipart/form-data">
<input type="checkbox" name="os[]" value="1" autocomplete="off">Linux<br>
<input type="checkbox" name="os[]" value="2" autocomplete="off">Mac OS<br>
<input type="checkbox" name="os[]" value="3" autocomplete="off">Windows<br>
<input id="submit" type="submit" value="Submit" name="submit">
</form>


直接用浏览器提交,服务器端的$_POST['os']只有选中项的值,但用sendPostRequest()提交,不管是否选中选项,$_POST['os']永远包含所有选项的值。

针对这个问题,常见的解决方法是不使用POST方式,而用GET方式来提交表单,比如这篇文章:
http://www.captain.at/howto-ajax-form-post-get.php

既然AJAX总是提交所有选项的值,那就把选项的值默认设为空,当选中的时候再赋值,就能保证服务器端只接收到选中项的值了。

方法是用一个函数来设置选项的值,把选项的值先保存在alt属性中:

<form id="Reg-form" name="Reg-form" onsubmit="sendPostRequest(); return false;"
action="submit.php" method=post encType=multipart/form-data>
<input type="checkbox" name="os[]" alt="1" value="" autocomplete="off" onclick="checkboxValue(this);">Linux<br>
<input type="checkbox" name="os[]" alt="2" value="" autocomplete="off" onclick="checkboxValue(this);">Mac OS<br>
<input type="checkbox" name="os[]" alt="3" value="" autocomplete="off" onclick="checkboxValue(this);">Windows<br>
<input id="submit" type="submit" value="Submit" name="submit">
</form>
<script language="JavaScript">
function checkboxValue(obj)
{
if(obj.checked)
{
obj.value = obj.alt;
}
else
{
obj.value = "";
}
}
</script>