Commits

Andreas Wagner committed 52ad0ae Draft Merge with conflicts

Merge branch 'multisection_tooltip' into develop

Conflicts:
leaflet-search.js

Comments (0)

Files changed (4)

demos/multisection.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
+<html xmlns="http://www.w3.org/1999/xhtml"> 
+<head> 
+<title></title> 
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
+<link rel="stylesheet" href="/leaflet/leaflet.css" />
+<link rel="stylesheet" href="../leaflet-search.css" />
+<link rel="stylesheet" href="../style.css" />
+</head>
+
+<body>
+<h3><a href="../">Leaflet.Control.Search</a></h3>
+
+<h4>Multi-Section Tooltip Example: <em>display results under headers by type of geographic feature.</em></h4>
+<div id="map"></div>
+
+<div id="post-it">
+<b>Search values:</b><br />
+OpenStreetMap Data offer by MapQuest Open Platform<br />
+<small><a href="http://open.mapquestapi.com/nominatim/">open.mapquestapi.com</a></small>
+</div>
+
+<script src="/leaflet/leaflet.js"></script>
+<script src="../leaflet-search.js"></script>
+<script>
+
+	var map = new L.Map('map', {zoom: 9, center: new L.latLng([41.575730,13.002411]) });
+	map.addLayer(new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'));	//base layer
+	
+	var jsonpurl = 'http://open.mapquestapi.com/nominatim/v1/search.php?json_callback={c}&q={s}&format=json&osm_type=N&limit=100';
+	//third party jsonp service	
+
+	function filter(rawjson) {	//callback that remap fields name
+		var json = {},
+			key, loc, section;
+		
+		for(var i in rawjson)
+		{
+			key = rawjson[i].display_name;	//search key
+			loc = L.latLng( rawjson[i].lat, rawjson[i].lon );
+			section = rawjson[i].class;
+			json[ key ]= loc;	//key,value format
+			json[key].section = section;	//search key
+			//json[key].formatted = key + ' -- <b>' + section + '</b>';
+		}
+	
+		return json;
+	}
+
+	map.addControl( new L.Control.Search({searchJsonpUrl: jsonpurl, searchJsonpFilter: filter, searchLimit: 5 }) ); // TODO: pass hierarchy array here..or somewhere.
+
+</script>
+
+<div id="copy">powered by <a href="mailto:stefano.cudini@gmail.com">Stefano Cudini</a></div>
+</body>
+</html>
 		<li><a href="demos/ajax.html">Ajax</a></li>
 		<li><a href="demos/jsonp.html">Jsonp</a></li>
 		<li><a href="demos/jsonp-filtered.html">Jsonp Filtered</a></li>
+		<li><a href="demos/multisection.html">Multi-Section Tooltip</a></li>
 		<li><a href="demos/ajax-bulk.html">Bulk data</a></li>	
 	</ul>
 </div>

leaflet-search.css

 }
 
 
+.leaflet-control-search .tooltip-section {
+	background: #ccc;
+	border:solid 0;
+}

leaflet-search.js

 	_createTip: function(text) {
 		var tip = L.DomUtil.create('a', 'search-tip');
 			tip.href = '#',
-			tip.innerHTML = this._recordsCache[ text ].formatted ? this._recordsCache[ text ].formatted : text;
+			tip.innerHTML = this._recordsCache[ text ].formatted ? this._recordsCache[ text ].formatted : text; // Default to plain text if no formatted text is available.
 		//TODO add new option: the callback for building the tip content from text argument
 
 		this._tooltip.currentSelection = -1;  //inizialized for _handleArrowSelect()
 	},
 
 //////end DOM creations
-	
+	_groupBy: function( arr, by ) {
+		var groups = {},
+		group,
+		values,
+		i = arr.length,
+		j,
+		key;
+
+		// make sure we specified how we want it grouped
+		if( !by ) { return arr; } // TODO: If hierarchy is not defined or is of length 1, just return flat json with no section.
+		while( i-- ) {
+
+			// find out group values for this item
+			values = ( typeof(by) === "function" && by( arr[i] ) || 
+					typeof arr[i] === "object" && arr[i][by] || 
+					arr[i] );
+
+			// make sure our group values are an array
+			values = values instanceof Array && values || [ values ]; // If not an array put them in an array.
+
+			// group
+			group = groups;
+			for( j = 0; j < values.length; j++ ) { // Vertical search. # of sections
+				key = values[j];
+				group = ( group[key] || ( group[key] = j === values.length - 1 && [] || {} ) );
+			}
+			// for the last group, push the actual item onto the array
+			group = ( group instanceof Array && group || [] ).push( arr[i] );
+		}
+
+		return groups;
+	},	
+
+	_toTree: function(treeObj) {
+		var ul = document.createElement("div");
+		for(var obj in treeObj) {
+			if (treeObj[obj] instanceof Array) { // leaf.
+				ul.appendChild(this._createTip(obj));
+				continue;
+			}
+			else { // branch
+				ul.innerHTML += obj;
+				ul.className = "tooltip-section";
+			}
+			ul.appendChild(this._toTree(treeObj[obj]));
+		}
+		return ul;
+	},
+
 	_showTooltip: function() {	//Filter this._recordsCache with this._input.values and show tooltip
 
 		if(this._input.value.length < this.options.minLength)
 			ntip = 0;
 		
 		this._tooltip.innerHTML = '';
-
-		for(var key in this._recordsCache)
-		{
+		
+		var recordsArray = [];
+		for (var key in this._recordsCache) {
 			if(regSearch.test(key))//search in records
 			{
 				if (ntip == this.options.tooltipLimit) break;
-				this._tooltip.appendChild( this._createTip(key) );
+				this._recordsCache[key].key = key;
+				recordsArray.push(this._recordsCache[key]);
 				this._recordsCache[ key ]._index = ntip;
 				ntip++;
 			}
 		}
+
+		var groups = this._groupBy( recordsArray, function( item ) { return [ item.section, item.key ]; } );
+		this._tooltip.appendChild(this._toTree(groups));
 		
 		if(ntip > 0) {
 			this._tooltip.style.display = 'block';
 		}
 	},
 	
-	//FIXME _handleAutoresize Should resize max search box size when map is resized.
+	// TODO: Should resize max search box size when map is resized.
 	_handleAutoresize: function() {	//autoresize this._input
 	//TODO refact _handleAutoresize now is not accurate
 		if(this.options.autoResize && (this._container.offsetWidth + 45 < this._map._container.offsetWidth))
 			this._input.size = this._input.value.length<this._inputMinSize ? this._inputMinSize : this._input.value.length;
 	},
 
+	// FIXME: Scrolling Up should work better with multisection tooltips.
 	_handleArrowSelect: function(velocity) {
 	
 		var searchTips = this._tooltip.getElementsByTagName('a');