Skip to content

Commit 34b430c

Browse files
committed
Finishing the section on the GridLayout
1 parent eb228fd commit 34b430c

File tree

2 files changed

+211
-0
lines changed

2 files changed

+211
-0
lines changed

index.html

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,6 +1159,98 @@ <h4 class="exercise-start">
11591159

11601160
<p>Show an image of the list with backend-driven data. Talk about how the next step is letting users add to the list.</p>
11611161
<h3 id="gridlayout">GridLayout</h3>
1162+
<p>Introduce what a grid layout actually is. Should be able to copy from the existing guide liberally.</p>
1163+
<h4 class="exercise-start">
1164+
<b>Exercise</b>: ???
1165+
</h4>
1166+
1167+
<p>Open <code>app/pages/list/list.html</code> and paste in the following code:</p>
1168+
<pre><code class="lang-XML">&lt;GridLayout rows=&quot;auto, *&quot;&gt;
1169+
1170+
&lt;GridLayout row=&quot;0&quot; columns=&quot;*, auto&quot; class=&quot;add-bar&quot;&gt;
1171+
&lt;TextField id=&quot;grocery&quot; hint=&quot;Enter a grocery item&quot; col=&quot;0&quot;&gt;&lt;/TextField&gt;
1172+
&lt;Image src=&quot;res://add&quot; col=&quot;1&quot;&gt;&lt;/Image&gt;
1173+
&lt;/GridLayout&gt;
1174+
1175+
&lt;ListView [items]=&quot;groceryList&quot; row=&quot;1&quot; class=&quot;small-spacing&quot;&gt;
1176+
&lt;template #item=&quot;item&quot;&gt;
1177+
&lt;Label [text]=&quot;item.name&quot; class=&quot;medium-spacing&quot;&gt;&lt;/Label&gt;
1178+
&lt;/template&gt;
1179+
&lt;/ListView&gt;
1180+
1181+
&lt;/GridLayout&gt;
1182+
</code></pre>
1183+
<div class="exercise-end"></div>
1184+
1185+
<p>Show an image of what this looks like first and then break down the syntax in detail.</p>
1186+
<p>Now let’s make the add button actually work.</p>
1187+
<h4 class="exercise-start">
1188+
<b>Exercise</b>: ???
1189+
</h4>
1190+
1191+
<p>Open <code>app/pages/list/list.html</code> and give the existing <code>&lt;TextField&gt;</code> a new <code>[(ngModel)]</code> attribute so that it looks like this:</p>
1192+
<pre><code class="lang-XML">&lt;TextField id=&quot;grocery&quot; [(ngModel)]=&quot;grocery&quot; hint=&quot;Enter a grocery item&quot; col=&quot;0&quot;&gt;&lt;/TextField&gt;
1193+
</code></pre>
1194+
<p>Next, give image a new tap attribute binding, so that the full <code>&lt;Image&gt;</code> looks like this:</p>
1195+
<pre><code class="lang-XML">&lt;Image src=&quot;res://add&quot; id=&quot;add-image&quot; (tap)=&quot;add()&quot; col=&quot;1&quot;&gt;&lt;/Image&gt;
1196+
</code></pre>
1197+
<p>Next, open <code>app/pages/list/list.component.ts</code> and add the following property to the <code>ListPage</code> class (right below <code>groceryList</code>):</p>
1198+
<pre><code class="lang-TypeScript">grocery: string;
1199+
</code></pre>
1200+
<p>Next, add the following two inputs to the top of the <code>list.component.ts</code> file:</p>
1201+
<pre><code class="lang-TypeScript">import {TextField} from &quot;ui/text-field&quot;;
1202+
import {topmost} from &quot;ui/frame&quot;;
1203+
</code></pre>
1204+
<p>Then, add the following <code>add()</code> function to the existing <code>ListPage</code> class:</p>
1205+
<pre><code class="lang-TypeScript">add() {
1206+
if (this.grocery.trim() === &quot;&quot;) {
1207+
alert(&quot;Enter a grocery item&quot;);
1208+
return;
1209+
}
1210+
1211+
// Dismiss the keyboard
1212+
var groceryTextField = &lt;TextField&gt;topmost().currentPage.getViewById(&quot;grocery&quot;);
1213+
groceryTextField.dismissSoftInput();
1214+
1215+
this._groceryListService.add(this.grocery)
1216+
.subscribe(
1217+
groceryObject =&gt; {
1218+
this.groceryList.unshift(groceryObject);
1219+
this.grocery = &quot;&quot;;
1220+
},
1221+
() =&gt; {
1222+
alert({
1223+
message: &quot;An error occurred while adding an item to your list.&quot;,
1224+
okButtonText: &quot;OK&quot;
1225+
});
1226+
this.grocery = &quot;&quot;;
1227+
}
1228+
)
1229+
}
1230+
</code></pre>
1231+
<p>Finally, open <code>app/shared/grocery/grocery-list.service.ts</code> and paste the following function into the <code>GroceryService</code> class:</p>
1232+
<pre><code class="lang-TypeScript">add(name: string) {
1233+
var headers = new Headers();
1234+
headers.append(&quot;Authorization&quot;, &quot;Bearer &quot; + Config.token);
1235+
headers.append(&quot;Content-Type&quot;, &quot;application/json&quot;);
1236+
1237+
return this._http.post(
1238+
Config.apiUrl + &quot;Groceries&quot;,
1239+
JSON.stringify({ Name: name }),
1240+
{ headers: headers }
1241+
)
1242+
.map(res =&gt; res.json())
1243+
.map(data =&gt; {
1244+
return new Grocery(data.Result.Id, name);
1245+
})
1246+
.catch(this.handleErrors);
1247+
}
1248+
</code></pre>
1249+
<div class="exercise-end"></div>
1250+
1251+
<p>Remind people that the final code for the tutorial is up on GitHub.</p>
1252+
<p>Talk about the code you just wrote.</p>
1253+
<p>Show a gif of the page in action.</p>
11621254
<h3 id="activityindicator">ActivityIndicator</h3>
11631255

11641256
</div>

src/chapters/chapter4.md

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,125 @@ Show an image of the list with backend-driven data. Talk about how the next step
301301

302302
### GridLayout
303303

304+
Introduce what a grid layout actually is. Should be able to copy from the existing guide liberally.
305+
306+
<h4 class="exercise-start">
307+
<b>Exercise</b>: ???
308+
</h4>
309+
310+
Open `app/pages/list/list.html` and paste in the following code:
311+
312+
``` XML
313+
<GridLayout rows="auto, *">
314+
315+
<GridLayout row="0" columns="*, auto" class="add-bar">
316+
<TextField id="grocery" hint="Enter a grocery item" col="0"></TextField>
317+
<Image src="res://add" col="1"></Image>
318+
</GridLayout>
319+
320+
<ListView [items]="groceryList" row="1" class="small-spacing">
321+
<template #item="item">
322+
<Label [text]="item.name" class="medium-spacing"></Label>
323+
</template>
324+
</ListView>
325+
326+
</GridLayout>
327+
```
328+
329+
<div class="exercise-end"></div>
330+
331+
Show an image of what this looks like first and then break down the syntax in detail.
332+
333+
Now let’s make the add button actually work.
334+
335+
<h4 class="exercise-start">
336+
<b>Exercise</b>: ???
337+
</h4>
338+
339+
Open `app/pages/list/list.html` and give the existing `<TextField>` a new `[(ngModel)]` attribute so that it looks like this:
340+
341+
``` XML
342+
<TextField id="grocery" [(ngModel)]="grocery" hint="Enter a grocery item" col="0"></TextField>
343+
```
344+
345+
Next, give image a new tap attribute binding, so that the full `<Image>` looks like this:
346+
347+
``` XML
348+
<Image src="res://add" id="add-image" (tap)="add()" col="1"></Image>
349+
```
350+
351+
Next, open `app/pages/list/list.component.ts` and add the following property to the `ListPage` class (right below `groceryList`):
352+
353+
``` TypeScript
354+
grocery: string;
355+
```
356+
357+
Next, add the following two inputs to the top of the `list.component.ts` file:
358+
359+
``` TypeScript
360+
import {TextField} from "ui/text-field";
361+
import {topmost} from "ui/frame";
362+
```
363+
364+
Then, add the following `add()` function to the existing `ListPage` class:
365+
366+
``` TypeScript
367+
add() {
368+
if (this.grocery.trim() === "") {
369+
alert("Enter a grocery item");
370+
return;
371+
}
372+
373+
// Dismiss the keyboard
374+
var groceryTextField = <TextField>topmost().currentPage.getViewById("grocery");
375+
groceryTextField.dismissSoftInput();
376+
377+
this._groceryListService.add(this.grocery)
378+
.subscribe(
379+
groceryObject => {
380+
this.groceryList.unshift(groceryObject);
381+
this.grocery = "";
382+
},
383+
() => {
384+
alert({
385+
message: "An error occurred while adding an item to your list.",
386+
okButtonText: "OK"
387+
});
388+
this.grocery = "";
389+
}
390+
)
391+
}
392+
```
393+
394+
Finally, open `app/shared/grocery/grocery-list.service.ts` and paste the following function into the `GroceryService` class:
395+
396+
``` TypeScript
397+
add(name: string) {
398+
var headers = new Headers();
399+
headers.append("Authorization", "Bearer " + Config.token);
400+
headers.append("Content-Type", "application/json");
401+
402+
return this._http.post(
403+
Config.apiUrl + "Groceries",
404+
JSON.stringify({ Name: name }),
405+
{ headers: headers }
406+
)
407+
.map(res => res.json())
408+
.map(data => {
409+
return new Grocery(data.Result.Id, name);
410+
})
411+
.catch(this.handleErrors);
412+
}
413+
```
414+
415+
<div class="exercise-end"></div>
416+
417+
Remind people that the final code for the tutorial is up on GitHub.
418+
419+
Talk about the code you just wrote.
420+
421+
Show a gif of the page in action.
422+
304423
### ActivityIndicator
305424

306425

0 commit comments

Comments
 (0)