现在有这么个需求,图一所示,称红线框这一行为searchRow,当searchRow获取焦点时,搜索按钮显示出,当searchRow失去焦点时,搜索按钮消失掉,当鼠标点击带看房源下面的input时,弹出图二所示的层,用户输入数据后,将数据显示到层上,当用户填写searchRow的数据后,点击搜索,按填写的内容,输出相应的结果,图三所示:
图一
图二
图三
当删除指定的搜索条件后,searchRow中相应条件也会清除。且图二所示数据有相应的格式要求,当弹层中最后一个input的值不为空时,假如第二个input没有输入数据,那么写到带看房源下input中的数据为1# #34#4;当弹层中最后一个input为空时,假如第三个input不会空,那么写到带看房源下的input中的数据为1#2#34。
产品交互逻辑大致就是这样,接下来就是程序设计思路:
整套系统采用的是dojo的模块化思路,这里只列出组件实现交互的相应方法:
define('my/grid', ['XX'], function() { var Grid = { ...... useSearch: function() { /** * 1、使用场景是假定每次搜索都重载页面,这样就不会存在查找元素个数问题且不需要记录并维护元素数据,因每次能获取到的都是最新的 * 2、表单元素的查找采用原生的form.elementName方式,因应用中肯定需要定义元素的name,所以可以规避掉各浏览器差异 */ // TODO 条件不在同一表单里,清除时查找有问题 var $advancedSearchBtn = $('[role="advancedSearchBtn"]', this.pageSection.top); // 高级搜索按钮 var $advancedSearchPanel = $('[role="advancedSearchPanel"]', this.pageSection.mainHD); // 高级搜索面板 var $advancedSearchConditions = $('[role="advancedSearchConditions"]', this.pageSection.mainHD); // 高级搜索已搜索条件区域 var $advancedSearchFormContainer = this.pageSection.main; // 整个表单容器,可能包含多个表单,用于查找搜索条件对应的表单元素 var $advancedSearchClose = $('[role="advancedSearchClose"]', $advancedSearchPanel); var $form = $advancedSearchFormContainer.find('form'); // 没有表单就不干了 if (!$form.length) { return; } var conditionItemLength = $advancedSearchConditions.find('[role="conditionItem"]').length; // 已经输出的条件个数 // 没有条件显示,就隐藏搜索区域 if (!conditionItemLength) { $advancedSearchConditions.hide(); } // 搜索面板显示切换 $advancedSearchBtn.click(function() { var $self = $(this); $advancedSearchPanel.toggle(); $self.toggleClass('btn-link').toggleClass('btn-link-cur'); window.updateFrame(); }); // 关闭搜索面板 $advancedSearchClose.click(function() { $advancedSearchPanel.hide(); window.updateFrame(); }); // 删除搜索条件 $advancedSearchConditions.on('click', '[role="conditionItem"] .close', function(event, isTirgger) { var $self = $(this), $conditionItem = $(this).closest('[role="conditionItem"]'), name = $conditionItem.attr('name'), value = $conditionItem.attr('value'); var $formEl = $advancedSearchFormContainer.find(':input[name="'+ name +'"]'); if (!$formEl.length) { alert('没有找到对应的表单元素啊!'); return; } // 存在NodeList的节点,比如checkbox这样的,和同一条件在多个区域,因此需要each $formEl.each(function() { var formEl = this; switch (formEl.type) { case 'text': case 'hidden': formEl.value = ''; break; case 'checkbox': // 针对这两种类型应该在元素中指定真实的id值,用value="1"的方式写在条件元素上,多个值用","分隔 case 'radio': if (value) { _value = value.split(','); } for (var j = 0; j < _value.length; j++) { if (formEl.value == _value[j]) { formEl.checked = false; break; } } break; case 'select-one': // 与checkbox和radio的处理一样,就在元素上写上当前搜索的值 for (var j = 0, l = formEl.options.length; j < l; j++) { var option = formEl.options[j]; if (option.value == value) { option.selected = false; break; } } // ie中手动更新select选中状态,认为第一个元素是默认空值 formEl.options[0].selected = true; break; default: alert('未捕获的表单元素类型!'); break; } }); //将弹层搜索同级的input中的值也动态修改掉 //var $searchRow = $('[role="searchRow"]', this.pageSection.mainBD); //var $openlayer = $('[role="openlayer"]', $searchRow); var $layer=$formEl.parent(); //当前弹层 var $input=$('input[type="text"]', $layer); var str = ""; $input.each(function(){ if($(this).val() != ""){ str += $(this).val() + "#"; }else{ str += " " + '#'; } }); var strVal=str.substr(0,str.length-1); //去除掉字符串尾巴为空的字符和'#' while(strVal.charAt(strVal.length-1) == " "){ strVal=strVal.substr(0,strVal.length-2); } $layer.parent().siblings().val(strVal); $layer.parent().css("display","none"); console.log(1); // 删除条件元素从页面上 $conditionItem.remove(); if (!--conditionItemLength) { $advancedSearchConditions.hide(); } //$form.trigger('submit'); if(!isTirgger){ $form.trigger('submit'); } // 不冒泡 return false; }); // 清空搜索条件 $advancedSearchConditions.find('[role="conditionClear"]').click(function() { $advancedSearchConditions.find('[role="conditionItem"] .close').trigger('click', [true]); $form.trigger('submit'); }); }, userSearchRow: function() { var $searchRow = $('[role="searchRow"]', this.pageSection.mainBD); var $searchBtn = $('[role="searchBtn"]', $searchRow); var searchBtnHover = false; $searchRow.focusin(function(e) { $(this).addClass('search-focus'); }).focusout(function(e) { if (!searchBtnHover) { $(this).removeClass('search-focus'); } }); $searchBtn.hover(function() { searchBtnHover = true; },function(){ searchBtnHover = false; }); /*兼容chrome 点击checkbox不出现搜索按钮*/ var $input = $('input[type="checkbox"]',$searchRow); $input.click(function(){ $searchRow.addClass('search-focus'); }); }, layerSearch: function(){ var self=this; self.dataParam={}; var $searchRow = $('[role="searchRow"]', this.pageSection.mainBD); var $openlayer = $('[role="openlayer"]', $searchRow); //var $layer=$('[role="popup"]' , $searchRow); var $confirm=$('[role="confirm"]' , $searchRow); var $cancel=$('[role="cancel"]' , $searchRow); $openlayer.focusin(function(e){ $(this).siblings().css("display","block"); }); $confirm.click(function(){ var $layer=$(this).parent(); //当前弹层 var $input=$('input[type="text"]', $layer); var str = ""; $input.each(function(){ if($(this).val() != ""){ str += $(this).val() + "#"; }else{ str += " " + '#'; } }); var strVal=str.substr(0,str.length-1); //去除掉字符串尾巴为空的字符和'#' while(strVal.charAt(strVal.length-1) == " "){ strVal=strVal.substr(0,strVal.length-2); } $layer.siblings().val(strVal); $layer.css("display","none"); //兼容chrome $searchRow.focus(); }); $cancel.click(function(){ $(this).parent().css("display","none"); //兼容chrome $searchRow.focus(); }); /*点击页面其它区域隐藏搜索弹层 $openlayer.click(function() { $layer.toggle().attr(app.posAttrName, 'layerPopup'); return false; }); $layer.bind('hide.fangyun', function() { $openlayer.trigger('click'); }).bind('click', function(event) { //千万不能用return false,用的话会导致菜单中的a链接不可用,因为return false = stopPropagation(取消冒泡) + preventDefault(取消默认行为) //return false; event.stopPropagation(); // 防止冒泡到document后触发hide }); */ } ...... } return Grid; })