=======动态生成面板=========
根据这个面板可以拼接where像
where
(用户 like 值 or 行业 = 值)
or (用户 in (值列) and 行业 not int(值列) )
......
因为使用了textarea,所以可以像in这种连接符,可以定规则为每行是集合中个值,
========面板form提交后产生$_POST===========
array(1) {
["where"]=>
array(2) {
[0]=>
array(2) {
[0]=>
array(2) {
["ifOperator"]=>
string(0) ""
["ifValue"]=>
string(0) ""
}
[1]=>
array(3) {
["cellOperator"]=>
string(2) "or"
["ifOperator"]=>
string(0) ""
["ifValue"]=>
string(0) ""
}
}
[1]=>
array(3) {
["rowOperator"]=>
string(2) "or"
[0]=>
array(2) {
["ifOperator"]=>
string(0) ""
["ifValue"]=>
string(0) ""
}
[1]=>
array(3) {
["cellOperator"]=>
string(2) "or"
["ifOperator"]=>
string(0) ""
["ifValue"]=>
string(0) ""
}
}
}
}
=========代码(有bug)===========
<style>
.area{border:1px dotted black; padding:5px;}
.vals{width:100px; height:50px;border:1px solid black;}
</style>
<form method="POST" >
<fieldset>
<legend>条件组 <a href="javascript:void(0);" οnclick="addWhere();">添加一组条件</a> <a href="javascript:void(0);" οnclick="removeWhere();">移除尾组</a> </legend>
<div id="whereBar">
</div>
</fieldset>
<input type="submit" />
</form>
<script>
var wheres = [
{
tab : '用户'
}
,{
tab : '行业'
}
];
var symbol = [//通用字段比较符
{value :'', text : '禁用'}
,{value : '=', text : '等于'}
,{value : '>', text : '大于'}
,{value : '>=', text : '大于或等于'}
,{value : '<', text : '小于'}
,{value : '<=', text : '小于或等于'}
,{value : '!=', text : '不等于'}
,{value : 'LIKE', text : '包含'}
,{value : 'NOT LIKE', text : '不包含'}
,{value : 'IN (...)', text : '在...中'}
,{value : 'NOT IN (...)', text : '不在...中'}
,{value : 'BETWEEN', text : '在...之间'}
,{value : 'NOT BETWEEN', text : '不在...之间'}
,{value : 'IS NULL', text : '为空'}
,{value : 'IS NOT NULL', text : '非空'}
];
var contactOperator = [//通用连结符
{value : 'or', text : 'or'}
,{value : 'and', text : 'and'}
];
function addWhere() {
if (! window.whereLen) {
window.whereLen = 0;
}
var namePre = 'where[' + window.whereLen + ']';
var divHtml = '';
var sels = {//行连接符
name : namePre + '[rowOperator]'
,options : contactOperator
};
if (window.whereLen > 0) {//第一行不需要连接符
divHtml += ' <= ';
}else {
sels.arrs = ['disabled="true"'];
divHtml += ' ';
}
divHtml += connatSelect(sels) + ' ( ';
sels.arrs = null;//恢复
for (var i = 0; i < wheres.length; i++) {
var input = [//传送字段代表名
'type=button'
,'value="' + wheres[i].tab + '"'
,'name="' + namePre + '[fields][' + i + '][ifFiled]"'
];
wheres[i].text = contactInput(input);
wheres[i].name = namePre + '[fields][' + i + '][ifOperator]';
wheres[i].options = symbol;
if (i > 0) {//不是首个,增加连接符
sels['name'] = namePre + '[fields][' + i + '][cellOperator]';//改写成列连结符
divHtml += ' + ' + connatSelect(sels) + ' + ';
}
divHtml += ' <span class="area">' + connatSelect(wheres[i]);
divHtml += ' <textarea class="vals" name="' + namePre + '[fields][' + i + '][ifValue]"></textarea> ';
divHtml += '</span> ';
}
divHtml += ')';
var div = document.createElement("DIV");
div.innerHTML = divHtml;
getObj('whereBar').appendChild(div);
window.whereLen++;
}
function getObj(id) {
return document.getElementById(id);
}
function connatSelect(obj) {
if (! obj) {
return '';
}
if (! obj.arrs) {
obj.arrs = [];
}
var html = (obj.text ? obj.text + ' ' : '') + '<select' + (obj.name ? ' name="' + obj.name + '" ' : '');
for (var i = 0; i < obj.arrs.length; i++) {
html += ' ' + obj.arrs[i] + ' ';
}
html += '>';
if (! obj.options) {
obj.options = [];
}
for (var i = 0; i < obj.options.length; i++) {
var forObj = obj.options[i];
html += '<option value="' + (forObj.value ? forObj.value : '') + '">' + (forObj.text ? forObj.text : '') + '</option>';
}
html += '</select>';
return html;
}
function contactInput(obj) {
var html = '<input ';
for (var i = 0; i < obj.length; i++) {
html += ' ' + obj[i] + ' ';
}
html += '/>';
return html;
}
function removeWhere() {
if (! window.whereLen || window.whereLen < 1) {
return;
}
var obj = getObj('whereBar').children[window.whereLen - 1];
if (! obj) {
return;
}
getObj('whereBar').removeChild(obj);
window.whereLen--;
}
</script>
<pre>
<?php
var_dump($_POST);
=======正常动作的代码js=======
/*============主站导入js==========*/
var wheres = [//用于配合拼接select方法生成条件列,这里是结合php动态输出的,这样修改php配置时就能改变这里
{
tab : '省市'
,tip:"看注册可选项"
,arrs : ['class="fieldName "']
}
,
{
tab : '部门'
,tip:"看注册可选项"
,arrs : ['class="fieldName "']
}
,
{
tab : '所属行业'
,tip:"看注册可选项"
,arrs : ['class="fieldName "']
}
,
{
tab : '职位'
,tip:"看注册可选项"
,arrs : ['class="fieldName "']
}
,
{
tab : '性别'
,tip:"输入男或女"
,arrs : ['class="fieldName "']
}
];
var symbol = [//通用字段比较符, php动态输出
{value :'', text : '禁用本条件'},
{value :'=', text : '等于'}
,
{value :'>', text : '大于'}
,
{value :'>=', text : '大于或等于'}
,
{value :'<', text : '小于'}
,
{value :'<=', text : '小于等于'}
,
{value :'!=', text : '不等'}
,
{value :'LIKE', text : '包含'}
,
{value :'NOT LIKE', text : '不包含'}
,
{value :'IN', text : '在...里面'}
,
{value :'NOT IN', text : '不在...里面'}
,
{value :'BETWEEN', text : '在..二者之间'}
,
{value :'NOT BETWEEN', text : '不在..二者之间'}
,
{value :'IS NULL', text : '空值'}
,
{value :'IS NOT NULL', text : '非空值'}
];
var contactOperator = [//通用连结符,php动态输出
{value :'OR', text : '或者'}
,
{value :'AND', text : '并且要'}
];
function addWhere() {//动态生成一行条件组
if (! window.whereLen) {
window.whereLen = 0;
}
var namePre = 'where[' + window.whereLen + ']';
//用于配合php []对象数组,name命名方式与php array写法一样
//这里在生成一行条件组时,只要是利用name命名处理好提交后php时形成如下规则数组
//每一行条件位于一个与其它行条件组平等的数组中
//每列条件成一个数组,都位于当行数组中的某个key
//这样安排$_POST数据,对于php处理就非常的方便了.
var divHtml = '';
var sels = {//行连接符select
name : namePre + '[logicOperatorRow]'
,options : contactOperator
};
if (window.whereLen > 0) {//第一行时是不需要连接符
divHtml += ' <= ';
}else {//首组条件
sels.arrs = ['disabled="true"'];//为了保持平整,禁用而不是移除
divHtml += ' ';
}
divHtml += connatSelect(sels) + ' ( ';
sels.arrs = null;//为非首行恢复禁用
for (var i = 0; i < wheres.length; i++) {//列出所有的列条件
var input = [//传送字段代表名
'type=hidden'
,'value="' + wheres[i].tab + '"'
,'name="' + namePre + '[fields][' + i + '][fieldName]"'
];
wheres[i].text = wheres[i].tab + contactInput(input);
wheres[i].name = namePre + '[fields][' + i + '][fieldOperator]';
wheres[i].options = symbol;
if (i > 0) {//不是首个,增加连接符
sels['name'] = namePre + '[fields][' + i + '][logicOperatorField]';//改写成列连结符
divHtml += ' + ' + connatSelect(sels) + ' + ';//为非首列加上逻辑连接select
}
divHtml += ' <span class="area">' + connatSelect(wheres[i]);//字段连接符select
divHtml += ' <textarea class="vals" name="' + namePre + '[fields][' + i + '][fieldValue]" title="' + wheres[i].tip + '"></textarea> ';
/*
* 这里使用textarea做为值输入原因是为了方便,
* 像in连接符需要多个子值,每行相当一个子值即可解决,如果需要换行符话,可以使用自定字符组标志到php中再处理
*/
divHtml += '</span> ';
}
divHtml += ')';
var div = document.createElement("DIV");
div.innerHTML = divHtml;
getObj('whereBar').appendChild(div);
window.whereLen++;
}
function getObj(id) {
return document.getElementById(id);
}
function connatSelect(obj) {//通用select拼接方法
if (! obj) {
return '';
}
if (! obj.arrs) {
obj.arrs = [];
}
var html = (obj.text ? obj.text + ' ' : '') + '<select' + (obj.name ? ' name="' + obj.name + '" ' : '');
for (var i = 0; i < obj.arrs.length; i++) {//拼接属性
html += ' ' + obj.arrs[i] + ' ';
}
html += '>';
if (! obj.options) {
obj.options = [];
}
for (var i = 0; i < obj.options.length; i++) {//拼接option
var forObj = obj.options[i];
html += '<option value="' + (forObj.value ? forObj.value : '') + '">' + (forObj.text ? forObj.text : '') + '</option>';
}
html += '</select>';
return html;
}
function contactInput(obj) {//通用input拼接方法
var html = '<input ';
for (var i = 0; i < obj.length; i++) {//拼接属性
html += ' ' + obj[i] + ' ';
}
html += '/>';
return html;
}
function removeWhere() {//移除一行条件组,当时考虑移除当前点中的,后来发现会让条件组的name命名出现断层,所以了为了方便php使用
//移除最后一行的方式
if (! window.whereLen || window.whereLen < 1) {
return;
}
var obj = getObj('whereBar').children[window.whereLen - 1];
if (! obj) {
return;
}
getObj('whereBar').removeChild(obj);
window.whereLen--;
}
function importSite(obj) {//提交按钮,利用form方式提交后php,接着php处理完后,如果需要下轮处理,php调用js给这个form写上位移标志
//然后再js动态submit() form,这样比较方便
if (! window.whereLen || window.whereLen < 1) {//只简单的进行检测
showErr( '至少配置一行条件', obj);
return false;
}
var fieldOperatorsel = $('.fieldName');
var allDisabled = 1;
for (var i = 0; i < fieldOperatorsel.length; i++) {//不允许全部禁用条件,这样就没必要提交
if ($(fieldOperatorsel.get(i)).val() != '') {
allDisabled = 0;
break;
}
}
if (allDisabled) {//全禁用,不必提交
showErr( '不能把所有条件禁用', obj);//在某个对象上显示错误提示
return false;
}
showErr( '', obj);//清空旧的错误信息
if (getObj('runLoop').value <= 0) {//人工点击
window.importStoping = 0;
if (! importTip()) return false;//反悔提交,与本功能无关
return confirm('你确定条件设置符合要求了吗?');//没做太多检测,提示一下比较好.
}
}
function importSiteAuto(i) {//用户改变为停止状态,下轮form提交回调有延时性,所以使用标志变量处理
if (window.importStoping) {//要求停止,submit()方法不会触发onsubmit事件,必须在这里处理
return false;
}
resetrunLoop(i);//连续新轮回调,回调前改变php处理标志位
getObj('importSiteForm').submit();//
}
function resetrunLoop(i) {
if (isNaN(i)) i = 0;
getObj('runLoop').value = i * 1;
}
/*============主站导入js==========*/
/*========其它不重要方法=======*/
function importReturn(str, hideLoad) {//php处理完成后在一个div显示处理结果
element_div_tip($("#editForm"), decodeURIComponent(str));
if (hideLoad) {//如果是结束了,可以取消form防止点击层
$("#ajaxLoadGif").css("display", "none");
}
}
function stopImport() {//标志停止所有回调
window.importStoping = 1;
importReturn("停止导入", 1);
}
function importTip() {//无关本功能的提示
if (0 >= $('#emailGroup').val()) {
return confirm("你确定是导入到全站,而不是当前的分组?");
}
return true;
}
function showErr(str, obj) {//在对应的对象显示出错提示
if (undefined == str) {
str = '';
}
if (! obj || ! $('.' + obj.id + 'ERR').get(0)) {
alert(str);
}
$('.' + obj.id + 'ERR').get(0).innerHTML = str;
}
/*========应用样图==========*/
/*======form代码=====*/
<fieldset>
<legend><b>导入方式C</b><br>从主站会员系统中选择筛选条件导入 <a οnclick="addWhere();" href="javascript:void(0);">添加一组条件</a>
<a οnclick="removeWhere();" href="javascript:void(0);">移除尾组条件</a></legend>
<div class="siteWhere">
<form enctype="multipart/form-data" οnsubmit="return importSite(this);" method="POST" id="importSiteForm" name="importSiteForm" target="upload_file_frame" accept-charset="utf-8" action="http://edm.q/index.php/home/email/importSite"> <input type="hidden" id="runLoop" name="runLoop" value="0">
<div id="whereBar">
</div>
<br><input type="submit" value="开始转移式导入">
<span class="importSiteFormERR error">
</span></form></div>
</fieldset>