A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/pme123/Binding.scala-Google-Maps/commit/34b9e095d1e9d9632f011e7a95889b9e05e50225 below:

show possible addresses in a list · pme123/Binding.scala-Google-Maps@34b9e09 · GitHub

@@ -62,7 +62,7 @@ And replace the `main` method from the ScalaJSExample:

62 62

```

63 63

Now you should see the map on `localhost:9000`

64 64 65 -

### Add Bindings.scala

65 +

## Add Bindings.scala

66 66

The dependency is already there, so no work there.

67 67

So first we add a textfield and a button:

68 68

```Scala

@@ -85,7 +85,7 @@ And in the `index.scala.html` add `<div id="map-control"></div>` as first div.

85 85 86 86

Now check `localhost:9000` if everything works as expected.

87 87 88 -

### Putting everything together

88 +

## Putting everything together

89 89

We would like to search for an address and see it on the map.

90 90

So first let us <b>prepare the needed Google map</b> code.

91 91

To make the map available, provide it and its options as a variables:

@@ -101,10 +101,10 @@ To make the map available, provide it and its options as a variables:

101 101

```

102 102 103 103

Provide a function that:

104 -

1) takes the address (String) from the input

105 -

2) gets a GeocoderResult (Position) from the Google map API

106 -

3) centers the the map to the position

107 -

4) sets a marker to the position

104 +

1. takes the address (String) from the input

105 +

2. gets a GeocoderResult (Position) from the Google map API

106 +

3. centers the the map to the position

107 +

4. sets a marker to the position

108 108

```Scala

109 109

private def geocodeAddress(address: String) { // 1

110 110

val geocoder = new Geocoder()

@@ -153,12 +153,103 @@ Now the `main` function looks as simple as:

153 153

google.maps.event.addDomListener(window, "load", initialize)

154 154

}

155 155

```

156 +

## Dive a bit deeper

157 +

Ok lets add a list that shows possible Addresses for our input, from where we can select one, or just take the first.

158 +

First we need another datatype where we can pass around the possible addresses:

159 +

```Scala

160 +

private val possibleAddrs: Var[Seq[GeocoderResult]] = Var(Seq())

161 +

```

162 +

We need to redo our Address fetching function a bit:

163 +

```Scala

164 +

private def possibleAddresses(address: String) {

165 + 166 +

val callback = (results: js.Array[GeocoderResult], status: GeocoderStatus) =>

167 +

if (status == GeocoderStatus.OK) {

168 +

possibleAddrs.value = results.to[Seq]

169 +

.take(5)

170 +

} else {

171 +

window.alert("Geocode was not successful for the following reason: " + status)

172 +

}

173 + 174 +

new Geocoder().geocode(GeocoderRequest(address), callback)

175 +

}

176 +

```

177 +

We provide two helper function that will display the Address on the map

178 +

```Scala

179 +

private def selectAddress() {

180 +

val value = possibleAddrs.value

181 +

if(value.nonEmpty)

182 +

selectAddress(value.head)

183 +

else

184 +

window.alert("There is no Address for your input")

185 +

}

186 + 187 +

private def selectAddress(address: GeocoderResult) {

188 +

gmap.setCenter(address.geometry.location)

189 +

val marker = new google.maps.Marker(

190 +

google.maps.MarkerOptions(map = gmap

191 +

, position = address.geometry.location))

192 +

}

193 +

```

194 +

We adjust our render function:

195 +

```Scala

196 +

@dom private lazy val render: Binding[HTMLElement] = {

197 +

<div>

198 +

<input id="searchInput" class="prompt" type="text" placeholder="Address..." oninput={event: Event =>

199 +

val value: String = searchInput.value

200 +

if (value.length > 2)

201 +

possibleAddresses(value)}/>

202 +

<button class="ui primary button" onclick={event: Event =>

203 +

selectAddress()}>

204 +

Search Address

205 +

</button>

206 +

<div>

207 +

<ol>

208 +

{for (addr <- possibleAddrs.bind) yield

209 +

<li>

210 +

{addr.formatted_address}<button onclick={event: Event =>

211 +

selectAddress(addr)}>select</button>

212 +

</li>}

213 +

</ol>

214 +

</div>

215 +

</div>

216 +

}

217 +

```

218 +

Now it gets tricky. If you refresh `localhost:9000` you will get a Compile Exception: `'each' instructions must be inside a SDE block`.

219 +

Ok, that suggest to extract the `<li>` part:

220 +

```Scala

221 +

...

222 +

<ol>

223 +

{for (addr <- possibleAddrs.bind) yield

224 +

renderPosAddr(addr: GeocoderResult).bind}

225 +

</ol>

226 +

...

227 + 228 +

@dom private def renderPosAddr(addr: GeocoderResult): Binding[HTMLElement] = {

229 +

<li>

230 +

{addr.formatted_address}<button onclick={event: Event =>

231 +

selectAddress(addr)}>select</button>

232 +

</li>

233 +

}

234 +

```

235 +

That was not enough - still the same exception!

236 +

Now we need to do it like this (explained here: [Stackoverflow](https://stackoverflow.com/questions/42498968/when-i-use-binding-scala-i-got-the-error-each-instructions-must-be-inside-a-sd/42498969#42498969) )

237 +

```Scala

238 +

...

239 +

<ol>

240 +

{Constants(possibleAddrs.bind.map(addr =>

241 +

renderPosAddr(addr)): _*).map(_.bind)}

242 +

</ol>

243 +

...

244 +

```

245 +

Now everything compiles and we can search our Addresses!

246 + 156 247

## Conclusion

157 248

It's quite interesting to see a stream based Framework (Binding.scala) next to the callback based API (Google maps).

158 249

- The Binding.scala solution is really elegant.

159 250

- I had, still have some problems that there are compile time exceptions shown by the IDE (Intellij). Some I could get rid of by adding implicit conversions.

160 251

- The usage of scala XML to declare the HTML-DOM is really nice. You literally can copy your HTML code directly, just adding the dynamic parts.

161 -

- However for parameters that expect other types than String, you need again implicit conversions.

252 +

- Only drawback: for parameters that expect other types than String, you need again implicit conversions.

162 253 163 254

## Improvements

164 255

Please let me know if there are things:


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4