Skip to content

Commit f3b5d7a

Browse files
committed
Starting up chapter 6
1 parent 255ac3a commit f3b5d7a

File tree

5 files changed

+160
-30
lines changed

5 files changed

+160
-30
lines changed

index.html

Lines changed: 69 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -310,9 +310,9 @@ <h4 class="exercise-start">
310310
<pre><code class="lang-JavaScript">@Component({
311311
selector: &quot;my-app&quot;,
312312
template: `
313-
&lt;TextField hint=&quot;Email Address&quot; keyboardType=&quot;email&quot;
313+
&lt;TextField hint=&quot;Email Address&quot; id=&quot;email&quot; keyboardType=&quot;email&quot;
314314
autocorrect=&quot;false&quot; autocapitalizationType=&quot;none&quot;&gt;&lt;/TextField&gt;
315-
&lt;TextField hint=&quot;Password&quot; secure=&quot;true&quot;&gt;&lt;/TextField&gt;
315+
&lt;TextField hint=&quot;Password&quot; id=&quot;password&quot; secure=&quot;true&quot;&gt;&lt;/TextField&gt;
316316

317317
&lt;Button text=&quot;Sign in&quot;&gt;&lt;/Button&gt;
318318
&lt;Button text=&quot;Sign up for Groceries&quot;&gt;&lt;/Button&gt;
@@ -365,9 +365,9 @@ <h4 class="exercise-start">
365365
selector: &quot;my-app&quot;,
366366
template: `
367367
&lt;StackLayout&gt;
368-
&lt;TextField hint=&quot;Email Address&quot; keyboardType=&quot;email&quot;
368+
&lt;TextField hint=&quot;Email Address&quot; id=&quot;email&quot; keyboardType=&quot;email&quot;
369369
autocorrect=&quot;false&quot; autocapitalizationType=&quot;none&quot;&gt;&lt;/TextField&gt;
370-
&lt;TextField hint=&quot;Password&quot; secure=&quot;true&quot;&gt;&lt;/TextField&gt;
370+
&lt;TextField hint=&quot;Password&quot; id=&quot;password&quot; secure=&quot;true&quot;&gt;&lt;/TextField&gt;
371371

372372
&lt;Button text=&quot;Sign in&quot;&gt;&lt;/Button&gt;
373373
&lt;Button text=&quot;Sign up for Groceries&quot;&gt;&lt;/Button&gt;
@@ -450,9 +450,9 @@ <h4 class="exercise-start">
450450
selector: &quot;my-app&quot;,
451451
template: `
452452
&lt;StackLayout&gt;
453-
&lt;TextField hint=&quot;Email Address&quot; keyboardType=&quot;email&quot;
453+
&lt;TextField hint=&quot;Email Address&quot; id=&quot;email&quot; keyboardType=&quot;email&quot;
454454
autocorrect=&quot;false&quot; autocapitalizationType=&quot;none&quot;&gt;&lt;/TextField&gt;
455-
&lt;TextField hint=&quot;Password&quot; secure=&quot;true&quot;&gt;&lt;/TextField&gt;
455+
&lt;TextField hint=&quot;Password&quot; id=&quot;password&quot; secure=&quot;true&quot;&gt;&lt;/TextField&gt;
456456

457457
&lt;Button text=&quot;Sign in&quot;&gt;&lt;/Button&gt;
458458
&lt;Button text=&quot;Sign up for Groceries&quot;&gt;&lt;/Button&gt;
@@ -579,7 +579,7 @@ <h4 class="exercise-start">
579579
}
580580
</code></pre>
581581
<p>Next, find the first <code>&lt;TextField&gt;</code> in your component’s <code>template</code> and replace it with the code below, which adds a new <code>text</code> attribute:</p>
582-
<pre><code class="lang-XML">&lt;TextField hint=&quot;Email Address&quot; keyboardType=&quot;email&quot; [text]=&quot;email&quot;
582+
<pre><code class="lang-XML">&lt;TextField hint=&quot;Email Address&quot; id=&quot;email&quot; keyboardType=&quot;email&quot; [text]=&quot;email&quot;
583583
autocorrect=&quot;false&quot; autocapitalizationType=&quot;none&quot;&gt;&lt;/TextField&gt;
584584
</code></pre>
585585
<div class="exercise-end"></div>
@@ -599,7 +599,7 @@ <h4 class="exercise-start">
599599
</h4>
600600

601601
<p>In <code>app/app.component.ts</code>, find the find the first <code>&lt;TextField&gt;</code>, and replace it with the <code>&lt;TextField&gt;</code> below, which introduces a new <code>[(ngModel)]</code> attribute:</p>
602-
<pre><code class="lang-XML">&lt;TextField hint=&quot;Email Address&quot; keyboardType=&quot;email&quot; [(ngModel)]=&quot;email&quot;
602+
<pre><code class="lang-XML">&lt;TextField hint=&quot;Email Address&quot; id=&quot;email&quot; keyboardType=&quot;email&quot; [(ngModel)]=&quot;email&quot;
603603
autocorrect=&quot;false&quot; autocapitalizationType=&quot;none&quot;&gt;&lt;/TextField&gt;
604604
</code></pre>
605605
<div class="exercise-end"></div>
@@ -671,9 +671,9 @@ <h4 class="exercise-start">
671671
</code></pre>
672672
<p>Instead of storing data on the <code>AppComponent</code> directly, you’re now using the <code>User</code> model object, which is reusable outside of this page and even outside of this application. You instantiate an instance of the <code>User</code> class in a new <code>constructor</code> function, which Angular 2 invokes when it bootstraps your application.</p>
673673
<p>Your final step is to use this new model object in your template. To do that, replace the two existing <code>&lt;TextField&gt;</code>s with the code shown below, which updates the <code>[(ngModel)]</code> bindings to point at the new <code>User</code> object:</p>
674-
<pre><code class="lang-XML">&lt;TextField hint=&quot;Email Address&quot; keyboardType=&quot;email&quot; [(ngModel)]=&quot;user.email&quot;
674+
<pre><code class="lang-XML">&lt;TextField hint=&quot;Email Address&quot; id=&quot;email&quot; keyboardType=&quot;email&quot; [(ngModel)]=&quot;user.email&quot;
675675
autocorrect=&quot;false&quot; autocapitalizationType=&quot;none&quot;&gt;&lt;/TextField&gt;
676-
&lt;TextField hint=&quot;Password&quot; secure=&quot;true&quot; [(ngModel)]=&quot;user.password&quot;&gt;&lt;/TextField&gt;
676+
&lt;TextField hint=&quot;Password&quot; id=&quot;password&quot; secure=&quot;true&quot; [(ngModel)]=&quot;user.password&quot;&gt;&lt;/TextField&gt;
677677
</code></pre>
678678
<p>TODO: Better explanation. Move the full template into the login.html file and use <code>templateUrl</code>. </p>
679679
<p>If you got lost during this section, here’s a copy-and-paste friendly version of the full <code>app.component.ts</code> you should have at this point:</p>
@@ -1314,7 +1314,7 @@ <h4 class="exercise-start">
13141314
<h2 id="plugins-and-npm-modules">Plugins and npm modules</h2>
13151315
<p>As you build more complex apps, you&#39;ll likely run into functionality that is not implemented in the NativeScript modules. But no worries, as NativeScript lets you leverage <a href="https://www.npmjs.com/">npm</a> (node package manager) to import npm modules into your apps. Alternately, you can install NativeScript plugins, which are simply npm modules that can access native code and use Android and iOS SDKs, if required. </p>
13161316
<p>In this chapter, you&#39;ll install and use and external email validator module to verify the format of email addresses as they are entered on the registration screen. Then, you&#39;ll add a NativeScript plugin, <a href="https://www.npmjs.com/package/nativescript-social-share">NativeScript social share</a>, to let users share their grocery lists using their device&#39;s native sharing widget.</p>
1317-
<h3 id="using-an-npm-module-in-your-app">Using an npm module in your app</h3>
1317+
<h3 id="using-npm-modules">Using npm modules</h3>
13181318
<p>It would be nice to be able to make sure people are entering well-formatted email addresses into your app on the registration screen. You could write this functionality yourself, but validating email addresses is <a href="http://stackoverflow.com/questions/46155/validate-email-address-in-javascript">surprisingly tricky</a>, and it&#39;s a lot easier to use one of many npm modules that already provide this validation. For Groceries let&#39;s see how to add this <a href="https://www.npmjs.com/package/email-validator">email-validator module</a> to test for valid addresses.</p>
13191319
<h4 class="exercise-start">
13201320
<b>Exercise</b>: Install the email validator module
@@ -1376,7 +1376,7 @@ <h4 class="exercise-start">
13761376
<blockquote>
13771377
<p><strong>WARNING</strong>: Not all npm modules work in NativeScript apps. Specifically, modules that depend on Node.js or browser APIs will not work, as those APIs do not exist in NativeScript. The NativeScript wiki contains a <a href="https://github.com/NativeScript/NativeScript/wiki/supported-npm-modules">list of some of the more popular npm modules that have been verified to work in NativeScript apps</a>.</p>
13781378
</blockquote>
1379-
<h3 id="using-a-nativescript-plugin-in-your-app">Using a NativeScript plugin in your app</h3>
1379+
<h3 id="using-nativescript-plugins">Using NativeScript plugins</h3>
13801380
<p>NativeScript plugins are npm modules that have the added ability to run native code and use iOS and Android frameworks. Because NativeScript plugins are just npm modules, a lot of the techniques you learned in the previous section still apply. The one big difference is in the command you use to install plugins. Let&#39;s look at how it works by installing the NativeScript social share plugin.</p>
13811381
<h4 class="exercise-start">
13821382
<b>Exercise</b>: Install the social sharing plugin
@@ -1432,9 +1432,63 @@ <h4 class="exercise-start">
14321432

14331433
</div>
14341434
<div class="chapter">
1435-
<h2 id="running-native-code">Running native code</h2>
1436-
<h3 id="accessing-native-apis">Accessing native APIs</h3>
1437-
<h3 id="branching-ios-android-code">Branching iOS &amp; Android code</h3>
1435+
<h2 id="accessing-native-apis">Accessing native APIs</h2>
1436+
<p>The beauty of NativeScript is that you can write a native iOS or Android app in JavaScript, XML, and CSS without touching Swift, Objective-C, or Java, if you choose. But what if you want to present a different, more platform-specific UI to your users? Or if you want to access an iOS or Android API that NativeScript doesn&#39;t expose through a NativeScript module or plugin?</p>
1437+
<p>NativeScript gives you the option to dig into native code as needed, and to do so without leaving JavaScript. To show how this works in action, let&#39;s tweak a few of the UI elements in your app using native code.</p>
1438+
<h3 id="accessing-ios-apis">Accessing iOS APIs</h3>
1439+
<p>Ask the reader to remember that the hint text color in the app doesn’t look good.</p>
1440+
<p>Show images.</p>
1441+
<p>Explain how NativeScript doesn’t currently expose a way to style a text field’s hint color (although <a href="https://github.com/NativeScript/NativeScript/issues/712">there is an open issue requesting the feature</a>).</p>
1442+
<p>Show how you can Google something like “style UITextField hint text” and find iOS code that accomplishes that task.</p>
1443+
<h4 class="exercise-start">
1444+
<b>Exercise</b>: ???
1445+
</h4>
1446+
1447+
<p>Open <code>app/utils/hint-util.ts</code> and paste in the following code:</p>
1448+
<pre><code class="lang-TypeScript">import {Color} from &quot;color&quot;;
1449+
import {TextField} from &quot;ui/text-field&quot;;
1450+
1451+
declare var NSAttributedString: any;
1452+
declare var NSDictionary: any;
1453+
declare var NSForegroundColorAttributeName: any;
1454+
1455+
export function setHintColor(args: { view: TextField, color: Color }) {
1456+
var dictionary = new NSDictionary(
1457+
[args.color.ios],
1458+
[NSForegroundColorAttributeName]
1459+
);
1460+
args.view.ios.attributedPlaceholder = NSAttributedString.alloc().initWithStringAttributes(
1461+
args.view.hint, dictionary);
1462+
}
1463+
</code></pre>
1464+
<p>Next, open up <code>app/pages/login/login.component.ts</code> and paste in the following imports at the top of the file:</p>
1465+
<pre><code class="lang-TypeScript">import {setHintColor} from &quot;../../utils/hint-util&quot;;
1466+
import {TextField} from &quot;ui/text-field&quot;;
1467+
</code></pre>
1468+
<p>After that, add the following function to the file’s <code>LoginPage</code> class:</p>
1469+
<pre><code class="lang-TypeScript">setTextFieldColors() {
1470+
var email = &lt;TextField&gt;this.page.getViewById(&quot;email&quot;);
1471+
var password = &lt;TextField&gt;this.page.getViewById(&quot;password&quot;);
1472+
1473+
var mainTextColor = new Color(this.isLoggingIn ? &quot;black&quot; : &quot;#C4AFB4&quot;);
1474+
email.color = mainTextColor;
1475+
password.color = mainTextColor;
1476+
1477+
var hintColor = new Color(this.isLoggingIn ? &quot;#ACA6A7&quot; : &quot;#C4AFB4&quot;);
1478+
setHintColor({ view: email, color: hintColor });
1479+
setHintColor({ view: password, color: hintColor });
1480+
}
1481+
</code></pre>
1482+
<p>Finally, add a call to the new <code>setTextFieldColors()</code> in <code>toggleDisplay()</code>, immediately after the existing <code>this.isLoggingIn = !this.isLoggingIn</code> line:</p>
1483+
<pre><code class="lang-TypeScript">this.setTextFieldColors();
1484+
</code></pre>
1485+
<div class="exercise-end"></div>
1486+
1487+
<p>Talk about what just happened.</p>
1488+
<p>TODO: Insert gifs</p>
1489+
<p>Transition to Android API discussion.</p>
1490+
<h3 id="accessing-android-apis">Accessing Android APIs</h3>
1491+
<h3 id="customizing-the-status-bar">Customizing the status bar</h3>
14381492

14391493
</div>
14401494
<div class="chapter">

src/chapters/chapter2.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,9 @@ Open `app/app.component.ts` and replace the existing `@Component` with the follo
138138
@Component({
139139
selector: "my-app",
140140
template: `
141-
<TextField hint="Email Address" keyboardType="email"
141+
<TextField hint="Email Address" id="email" keyboardType="email"
142142
autocorrect="false" autocapitalizationType="none"></TextField>
143-
<TextField hint="Password" secure="true"></TextField>
143+
<TextField hint="Password" id="password" secure="true"></TextField>
144144
145145
<Button text="Sign in"></Button>
146146
<Button text="Sign up for Groceries"></Button>
@@ -195,9 +195,9 @@ In `app.component.ts`, add a `<StackLayout>` element within your component’s `
195195
selector: "my-app",
196196
template: `
197197
<StackLayout>
198-
<TextField hint="Email Address" keyboardType="email"
198+
<TextField hint="Email Address" id="email" keyboardType="email"
199199
autocorrect="false" autocapitalizationType="none"></TextField>
200-
<TextField hint="Password" secure="true"></TextField>
200+
<TextField hint="Password" id="password" secure="true"></TextField>
201201
202202
<Button text="Sign in"></Button>
203203
<Button text="Sign up for Groceries"></Button>
@@ -300,9 +300,9 @@ Open your app’s `app/app.component.ts` file and add a `styleUrls` property suc
300300
selector: "my-app",
301301
template: `
302302
<StackLayout>
303-
<TextField hint="Email Address" keyboardType="email"
303+
<TextField hint="Email Address" id="email" keyboardType="email"
304304
autocorrect="false" autocapitalizationType="none"></TextField>
305-
<TextField hint="Password" secure="true"></TextField>
305+
<TextField hint="Password" id="password" secure="true"></TextField>
306306
307307
<Button text="Sign in"></Button>
308308
<Button text="Sign up for Groceries"></Button>

src/chapters/chapter3.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export class AppComponent {
6464
Next, find the first `<TextField>` in your component’s `template` and replace it with the code below, which adds a new `text` attribute:
6565

6666
``` XML
67-
<TextField hint="Email Address" keyboardType="email" [text]="email"
67+
<TextField hint="Email Address" id="email" keyboardType="email" [text]="email"
6868
autocorrect="false" autocapitalizationType="none"></TextField>
6969
```
7070

@@ -92,7 +92,7 @@ To fix this, you need to switch to Angular 2’s two-way data binding syntax.
9292
In `app/app.component.ts`, find the find the first `<TextField>`, and replace it with the `<TextField>` below, which introduces a new `[(ngModel)]` attribute:
9393

9494
``` XML
95-
<TextField hint="Email Address" keyboardType="email" [(ngModel)]="email"
95+
<TextField hint="Email Address" id="email" keyboardType="email" [(ngModel)]="email"
9696
autocorrect="false" autocapitalizationType="none"></TextField>
9797
```
9898

@@ -198,9 +198,9 @@ Instead of storing data on the `AppComponent` directly, you’re now using the `
198198
Your final step is to use this new model object in your template. To do that, replace the two existing `<TextField>`s with the code shown below, which updates the `[(ngModel)]` bindings to point at the new `User` object:
199199

200200
``` XML
201-
<TextField hint="Email Address" keyboardType="email" [(ngModel)]="user.email"
201+
<TextField hint="Email Address" id="email" keyboardType="email" [(ngModel)]="user.email"
202202
autocorrect="false" autocapitalizationType="none"></TextField>
203-
<TextField hint="Password" secure="true" [(ngModel)]="user.password"></TextField>
203+
<TextField hint="Password" id="password" secure="true" [(ngModel)]="user.password"></TextField>
204204
```
205205

206206
TODO: Better explanation. Move the full template into the login.html file and use `templateUrl`.

src/chapters/chapter5.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ As you build more complex apps, you'll likely run into functionality that is not
44

55
In this chapter, you'll install and use and external email validator module to verify the format of email addresses as they are entered on the registration screen. Then, you'll add a NativeScript plugin, [NativeScript social share](https://www.npmjs.com/package/nativescript-social-share), to let users share their grocery lists using their device's native sharing widget.
66

7-
### Using an npm module in your app
7+
### Using npm modules
88

99
It would be nice to be able to make sure people are entering well-formatted email addresses into your app on the registration screen. You could write this functionality yourself, but validating email addresses is [surprisingly tricky](http://stackoverflow.com/questions/46155/validate-email-address-in-javascript), and it's a lot easier to use one of many npm modules that already provide this validation. For Groceries let's see how to add this [email-validator module](https://www.npmjs.com/package/email-validator) to test for valid addresses.
1010

@@ -87,7 +87,7 @@ In general npm modules greatly expand the number of things you're able to do in
8787

8888
> **WARNING**: Not all npm modules work in NativeScript apps. Specifically, modules that depend on Node.js or browser APIs will not work, as those APIs do not exist in NativeScript. The NativeScript wiki contains a [list of some of the more popular npm modules that have been verified to work in NativeScript apps](https://github.com/NativeScript/NativeScript/wiki/supported-npm-modules).
8989
90-
### Using a NativeScript plugin in your app
90+
### Using NativeScript plugins
9191

9292
NativeScript plugins are npm modules that have the added ability to run native code and use iOS and Android frameworks. Because NativeScript plugins are just npm modules, a lot of the techniques you learned in the previous section still apply. The one big difference is in the command you use to install plugins. Let's look at how it works by installing the NativeScript social share plugin.
9393

0 commit comments

Comments
 (0)