2012-03-05 98 views
1

我无法让我的多选框筛选系统正常工作。我会解释这个问题,我在这里完成的关于stackoverflow的研究,以及之后为什么还需要帮助。用多个[和相交]复选框筛选Google Map标记

我的问题是,当我逐渐取消选择它们时,我的复选框无法恢复标记。当我点击它们时,这些过滤器会很好地工作,因为它们逐渐淡化与它们相关的标记。然而,在取消选择几个复选框之后,所有标记都会返回到屏幕上,而最后一个框在最终未点击时不会执行任何操作。

这是该项目的临时网址:http://www.lcc.gatech.edu/~amartell6/php/main12.php

这是我卡住代码:

//this getJson function exists within an init funciton where a map 
//has already been called 
$.getJSON(theUrl,function(result){ 



    $.each(result, function(i, item){ 

     //get Longitude 
     var latCoord = item.coordinate; 
     var parenthCoord = latCoord.indexOf(","); 
     var partiaLat = latCoord.substr(1,parenthCoord-1); 
     var lat = parseFloat(partiaLat); 
     //alert(lat); 

     //get Latitude 
     var lngCoord = item.coordinate; 
     var commaCoord = lngCoord.indexOf(","); 
     var partiaLng = lngCoord.substr(commaCoord+1); 
     var lng = parseFloat(partiaLng); 
     //alert(lng); 


     // display ALL the story markers 
     var storyMarker; 
     storyMarker = new google.maps.Marker({ 
      position: new google.maps.LatLng(lat, lng),// ----- > whithin the mutidimentional array, 
      map: map 
     }); 


     //display the stories by clicking on the markers 
     google.maps.event.addListener(storyMarker, 'click', function() { 
      var from = "From "; 
      if(item.end_date != ""){ 
       item.end_date = " to " + item.end_date; 
      } 
      else{ 
       from = ""; 
      } 

      $('#output').html(
       '<p><span class="selected">Type of Entry: </span>' + 
       item.entry_type + ' <br/><br/>'+ 
       '<span class="selected">Title: </span>'+ item.entry_title + '<br/><br/>' + 
       '<span class="selected">Date(s):</span><br/>'+ from +item.start_date+ 
       //' to '+item.end_date+'<br/><br/>'+ 
       item.end_date+'<br/><br/>'+ 
       '<span class="selected">Content:</span><br/><br/> '+ item.entry 
       +'</p>' 
      ); 
     });// end of story displays 


     //call filters from filter funciton 
     filter('#evacuation-filter',item.evacuation,"Yes"); 
     filter('#evacuation-order-filter',item.evacuation_order,"Yes"); 
     filter('#w-nearby-filter',item.w_nearby,"Yes"); 
     filter('#hurricane-reached-filter',item.hurricane_reached,"Yes"); 
     filter('#outdoors-filter',item.in_out_doors,"Outdoors Most of the Time"); 
     filter('#indoors-filter',item.in_out_doors,"Indoors Most of the Time"); 
     filter('#food-filter',item.food,"Yes"); 
     filter('#windows-filter',item.windows,"Yes"); 
     filter('#power-filter',item.power,"Yes"); 
     filter('#wounded-filter',item.wounded,"Yes"); 
     filter('#looting-filter',item.looting,"Yes"); 
     filter('#blackouts-filter',item.blackouts,"Yes"); 
     filter('#trees-filter',item.trees,"Yes"); 
     filter('#powerlines-filter',item.powerlines,"Yes"); 
     filter('#light-filter',item.light,"Yes"); 
     filter('#sidewalks-filter',item.sidewalks,"Yes"); 
     filter('#buildings-filter',item.buildings,"Yes"); 
     filter('#flooding-filter',item.flooding,"Yes"); 


     //FILTER FUNCTION 
     //first parameter is the checkbox id, the second is the filter criteria 
     //(the filter function has to be called within the $.each loop to be within scope) 

     var otherFilter = false; 

     function filter(id, criterion1, value){ 

      var activeFilters = []; 

      $(id).change(function() { 
       //evalute if the checkbox has been "checked" or "unchecked" 
       var checkBoxVal = $(id).attr("checked"); 

       //if it's been checked: 
       if(checkBoxVal=="checked"){ 
        //1 - Get markers that don't talk about the filter 
        if(criterion1!=value && storyMarker.getVisible()==true){ 
         //2 - fade them away, and leave only those meet the criteria 
         storyMarker.setVisible(false); 
         otherFilter = true; 
         activeFilters.push(criterion1); 
         //document.getElementById("text3").innerHTML=activeFilters+"<br/>"; 
         //alert(activeFilters.push(criterion1) +","+criterion1.length); 
        } 
       } 
       //if it's been unchecked: 
       else if(checkBoxVal==undefined){ 
        //1 - Get markers that don't talk about the filter 
        if(criterion1!=value && storyMarker.getVisible()==false){ 
         //2 - Show them again 
         storyMarker.setVisible(true); 
         otherFilter = false; 
         activeFilters.pop(criterion1); 
         //alert(activeFilters.pop(criterion1) +","+criterion1.length); 
        } //end of if to cancel filter and bring markers and stories back 
       } 

      }); // end of change event 

     } // end of filter function 


     //var otherDropDown = false; 
     filter2("#media-filter",item.media); 
     filter2("#authorities-filter",item.authorities); 

     //--------------- 

     function filter2(id2,criterion2){ 

      $(id2).change(function() { 
       //get the value of the drowpdown menu based on its id 
       var dropDownVal = $(id2).attr("value"); 
       var all="All"; 
       //if the value isn't "All", other filters have not been applied, and marker is on screen 
       if(dropDownVal!=all && otherFilter==false){ 
        //1 - check if the marker doesn't comply with filter 
        if(criterion2!=dropDownVal){ 
         //2 - fade them away if not, and leave only those meet the criteria 
         storyMarker.setVisible(false); 
        //3 - If the marker does comply with it 
        }else if(criterion2==dropDownVal){ 
         //4 - keep it there 
         storyMarker.setVisible(true); 
        }//end of filter applier 
       //else if if the value IS "All", filters have not been applied, and marker is faded 
       }else if(dropDownVal==all && otherFilter==false){ 
        //select all the possible values for the cirterion 
        if(criterion2!=undefined){ 
         //and show all those markers 
         storyMarker.setVisible(true); 
        } 
       } 
      }); 
     } //end of function filter2 



    }); // end of $.each 
}); // end of $.getJSON 

我发现one related blog post。这个建议给标记添加一个类别。但是,当我这样做时,滤镜仍然以相同的方式工作。我认为这是因为每个过滤器都被编程为隐藏符合其选择标准的每一个标记,但是每个标记具有不止一个属性,它们可以被过滤。

你知道是否有办法让脚本检测到有多少过滤器指向同一个标记,并且只有在没有过滤器指向它时才显示它回来?这是我对如何解决它的猜测,即使我不知道如何在代码中实现它。

最后,如果您知道替代方法来使过滤器正常工作,请告诉我。

+0

我与朋友分享了此代码。在他看来,问题是过滤功能的整个逻辑是有缺陷的,并建议从头重新编写它。他说该功能不起作用,因为它目前正在相互独立地处理过滤选项。相反,我可以先检查是否至少有一个框被选中。下一步将是检查其中有多少人确实被检查。最后,这些框应该将它们附加的过滤选项组合成一个条件语句,以显示/隐藏标记。问题在于编码。我还没有想法。 – asraelarcangel 2012-03-05 23:25:52

回答

1

我在几年前创建了一个具有类似逻辑的应用程序http://www.ioos.gov/catalog/但它是用于GMap 2.0,但我认为逻辑将是相同的。 我的做法是扩展谷歌地图标记对象(已经臃肿)与我想过滤他们的功能。 这些将是您存储在“点击”侦听器中的所有属性,可能还有更多: item.title,item_start_date等,无论你最终想要过滤你的标记。

var all_markers = []; 
storyMarker.end_date = item.end_date; 
storMarker.title = item.title; 
... 
all_markers.push(storyMarker); 

然后,当你想过滤环通的所有标记,检查对过滤条件并调用setVisible(真)或false需要标记值。

+0

非常感谢。我正在测试你的解决方案。在阅读您的答案之前,我已经找到了另一种权利,但我认为这不是最有效的方法。 – asraelarcangel 2012-03-06 02:53:28

1

Erik已经为我的问题提供了解决方案。但是,我认为社区可能从阅读其他选项中受益,我想分享我提出的解决方案。即使它不是最有效的,它也可以工作。

在我刚才提到的代码,我宣布在一次所有storyMarkers图时初始化:

 // display ALL the story markers 
     var storyMarker; 
     storyMarker = new google.maps.Marker({ 
      position: new google.maps.LatLng(lat, lng),// ----- > whithin the mutidimentional array, 
      map: map 
     }); 

现在,我添加了一个新的参数标记,但不是创建一个变量作为例如我在其他帖子中发现的这个参数是一个空数组:

storyMarker.pointer = []; 

上一个过滤函数有三个级别。第一级在复选框中检测到更改。第二个验证复选框是否已被选中或未选中。第三级在e-v-e-r-y标记上运行过滤器,以显示或隐藏它。

这是我的解决方案开始的地方。在过滤函数的最内在if语句中,我在指针数组中添加了一个自定义元素:

storyMarker.pointer.push(“element”);

在这之后,我嵌套了一个新的if语句来检查数组是否为空。如果它确实不是空的,程序将隐藏该数组所属的标记。

该程序反转了未选中框时的逻辑。它调用过滤器,从与该标记关联的数组中减去一个元素,然后检查是否有其他标记与其关联。系统现在只显示数组为空的标记。

//alert(storyMarker.pointer); 
     function filter(id,criterion,value){ 
      $(id).change(function() { 
       var checkBoxVal = $(id).attr("checked"); 
       if(checkBoxVal=="checked"){ 
        if(criterion!=value){ 
         storyMarker.pointer.push("element"); 
         //alert("array length: "+storyMarker.pointer.length); 
         if(storyMarker.pointer.length>0){ 
          storyMarker.setVisible(false); 
         } 
        } 
       } 
       else if(checkBoxVal!="checked"){ 
        if(criterion!=value){ 
         storyMarker.pointer.pop("element"); 
         //alert("array length: "+storyMarker.pointer.length); 
         if(storyMarker.pointer.length<=0){ 
          storyMarker.setVisible(true); 
         } 
        } 
       } 
      }); 
     } 

总之,如果用户点击多个标记,脚本仍会多次点击一个标记。系统现在可以识别一个标记指出了多少次,并且只显示完全没有指针的那个。