Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
d62e16f
Starting tutorial 01
braughtg Jun 29, 2026
b31b371
adds FarmData2 logo
braughtg Jun 29, 2026
85654a8
adds title and paragraph
braughtg Jun 29, 2026
410970f
adds unordered list of features
braughtg Jun 29, 2026
45582d5
adds a link to the FarmData2 repo on GitHub
braughtg Jun 29, 2026
48b8928
adds missing heading and changes title
braughtg Jun 29, 2026
57e6e67
adds css style sheet to index.html
braughtg Jun 29, 2026
3719341
added a different font to the page
braughtg Jun 29, 2026
c54f1fb
adds background color and styles body
braughtg Jun 29, 2026
8d7bf79
styles the heading
braughtg Jun 29, 2026
e83b2a5
centers the FarmData2 logo
braughtg Jun 29, 2026
bc7e506
Merge branch 'main' into tutorial-01-html-css
braughtg Jun 30, 2026
dbdcba1
Merge branch 'main' into tutorial-01-html-css
braughtg Jul 1, 2026
0008572
adds script/main.js and links in index.html
braughtg Jul 9, 2026
cf30a8e
adds the image changer
braughtg Jul 9, 2026
2cdda2f
adds the custom greeting
braughtg Jul 9, 2026
71bca3e
fixes null username issue
braughtg Jul 9, 2026
226cafa
Merge branch 'main' into t01-html-css-js
braughtg Jul 12, 2026
3a48c82
adds flashword directory and starter code
braughtg Jul 12, 2026
e07b31b
fixes broken cdn link
braughtg Jul 12, 2026
8b84a40
add answer input field
braughtg Jul 12, 2026
8bf3d63
adds answer checking
braughtg Jul 12, 2026
bca1ec9
refactors feedback into a div
braughtg Jul 12, 2026
7974445
factors out checkAnswer method
braughtg Jul 12, 2026
1b6b6a4
adds cloaking to remove raw code flash
braughtg Jul 12, 2026
06c65af
adds the reset button
braughtg Jul 12, 2026
632d18e
uses template element in place of div
braughtg Jul 13, 2026
41cdee8
adds array of words examples to data
braughtg Jul 13, 2026
e8f5de0
adds examples of the use of v-for
braughtg Jul 13, 2026
0cbc6f3
removes v-for examples
braughtg Jul 13, 2026
4f5f0dd
add event example code
braughtg Jul 13, 2026
3fca5c0
adds v-on for enter key to check answer
braughtg Jul 13, 2026
d167a4c
adds images for correct/incorrect answers
braughtg Jul 13, 2026
9f012ca
refactor img binding and add alt text
braughtg Jul 13, 2026
c754245
create error and indicator when empty word is checked
braughtg Jul 13, 2026
52a2c0e
refactor validation coloring to bind style
braughtg Jul 13, 2026
840903a
adds show hint checkbox
braughtg Jul 13, 2026
6264b91
adds difficulty level inputs
braughtg Jul 13, 2026
477ad64
add textarea example
braughtg Jul 13, 2026
58c7c12
adds fullname computed property example
braughtg Jul 24, 2026
c42763d
adds method example and cleans formatting
braughtg Jul 24, 2026
9f98fca
adds the shortSpanishWords computed property
braughtg Jul 24, 2026
063d6ef
adding the watch example
braughtg Jul 24, 2026
263cc96
Merge branch 'main' into t03-vue2
braughtg Aug 28, 2026
9435efd
adds the error css class
braughtg Aug 29, 2026
dfc686c
removes class binding for text input
braughtg Aug 29, 2026
f1dc9df
finish merge of main
braughtg Aug 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"eslint",
"flashword",
"husky",
"lightpink",
"keyup",
"linkcheck",
"lintstaged",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added web-projects/first-website/images/fd2-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 46 additions & 0 deletions web-projects/first-website/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<link href="styles/style.css" rel="stylesheet" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap"
rel="stylesheet"
/>
<script async src="scripts/main.js"></script>
<title>The FarmData2 Project</title>
</head>
<body>
<h1>The FarmData2 Project</h1>

<img
src="images/fd2-logo.png"
alt="The FarmData2 Logo showing a carrot on a mobile phone screen."
/>

<p>
<a href="https://github.com/FarmData2/FarmData2">FarmData2</a> aims to
extend farmOS by adding data input forms, reporting, and analytics that
support the day-to-day operation of diversified vegetable farms, while
also facilitating the keeping of records necessary for organic
certification and for the study of sustainable farming practices.
</p>

<p>
FarmData2 contains features for recording the following activities that
are likely to occur on a small diversified vegetable farm.
</p>
<ul>
<li>Tray seeding</li>
<li>Direct seeding</li>
<li>Cover crop seeding</li>
<li>Transplanting</li>
<li>Soil disturbance</li>
</ul>

<button>Change user</button>
</body>
</html>
34 changes: 34 additions & 0 deletions web-projects/first-website/scripts/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const myImage = document.querySelector('img')

myImage.addEventListener('click', () => {
const mySrc = myImage.getAttribute('src')
if (mySrc === 'images/fd2-logo.png') {
myImage.setAttribute('src', 'images/fd2-logo-orange.png')
} else {
myImage.setAttribute('src', 'images/fd2-logo.png')
}
})

let myButton = document.querySelector('button')
let myHeading = document.querySelector('h1')

function setUserName() {
const myName = prompt('Please enter your name.')
if (!myName) {
setUserName()
} else {
localStorage.setItem('name', myName)
myHeading.textContent = `Mozilla is cool, ${myName}`
}
}

if (!localStorage.getItem('name')) {
setUserName()
} else {
const storedName = localStorage.getItem('name')
myHeading.textContent = `FarmData2 is cool, ${storedName}`
}

myButton.addEventListener('click', () => {
setUserName()
})
37 changes: 37 additions & 0 deletions web-projects/first-website/styles/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
html {
/* px means "pixels". The base font size is now 10 pixels high */
font-size: 10px;
/* Replace PLACEHOLDER with the font-family property value you got from Google Fonts */
font-family: 'Roboto', sans-serif;
background-color: #b8fdb1;
}

h1 {
font-size: 60px;
text-align: center;
margin: 0;
padding: 20px 0;
color: #12601b;
text-shadow: 3px 3px 1px #b8fdb1;
}

p,
li {
font-size: 16px;
line-height: 2;
letter-spacing: 1px;
}

body {
width: 600px;
margin: 0 auto;
background-color: #ff9500;
padding: 0 20px 20px 20px;
border: 5px solid black;
}

img {
display: block;
margin: 0 auto;
max-width: 100%;
}
85 changes: 85 additions & 0 deletions web-projects/flashword/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
const Flashword = {
data() {
return {
wordA: 'hola',
wordB: 'hello',
answer: '',
correct: null,
showFeedback: false,
image: null,
imageAlt: null,
hasError: false,
inputBackgroundColor: 'white',
showHint: false,
level: 'easy',
sentence: '',
lastName: '',
firstName: '',
firstNameAndLastName: '',

// Array example
spanishWords: ['hola', 'adios', 'uno', 'dos'],

// Object example
word: { a: 'hola', b: 'hello' },

// Array of objects example
words: [
{ wordA: 'hola', wordB: 'hello' },
{ wordA: 'adios', wordB: 'goodbye' },
{ wordA: 'uno', wordB: 'one' },
{ wordA: 'dos', wordB: 'two' },
],
}
},
computed: {
fullName() {
return this.firstName + ' ' + this.lastName
},
shortSpanishWords() {
return this.spanishWords.filter((word) => word.length <= 3)
},
},
watch: {
firstName() {
this.firstNameAndLastName = this.firstName + ' ' + this.lastName
},
lastName() {
this.firstNameAndLastName = this.firstName + ' ' + this.lastName
},
},
methods: {
getFullName() {
return this.firstName + ' ' + this.lastName
},
checkAnswer() {
if (this.answer == '') {
this.hasError = true
this.inputBackgroundColor = 'lightpink'
return
}

this.hasError = false
this.inputBackgroundColor = 'white'

this.correct = this.wordB == this.answer

if (this.correct) {
this.image = 'correct'
this.imageAlt = 'Green check mark.'
} else {
this.image = 'incorrect'
this.imageAlt = 'Red X.'
}

this.showFeedback = true
},
reset() {
this.answer = ''
this.showFeedback = false
},
},
}

// eslint-disable-next-line no-unused-vars, no-undef
const app = Vue.createApp(Flashword).mount('#app')
119 changes: 119 additions & 0 deletions web-projects/flashword/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<!doctype html>
<html lang="en">
<head>
<title>FlashWord</title>
<meta charset="utf-8" />

<script src="https://unpkg.com/vue@3/dist/vue.global.js" defer></script>
<script src="app.js" defer></script>

<style>
label {
display: block;
}

input,
button {
display: block;
margin: 10px 0px;
}

.correct {
color: green;
}

.incorrect {
color: red;
}

[v-cloak] {
display: none;
}

.error {
background-color: lightpink;
}
</style>
</head>

<body>
<h1>FlashWord</h1>

<div id="app" v-cloak>
What is the English translation of the word <strong>{{ wordA }}</strong>?

<input
type="text"
v-model="answer"
v-on:keyup.enter="checkAnswer()"
v-bind:style="{'background-color' : inputBackgroundColor}"
/>

<input type="checkbox" id="showHint" v-model="showHint" />
<label for="showHint">Show hint?</label>

<div v-if="showHint">A hint would appear here.</div>

<p v-if="hasError">You must enter an answer.</p>

<p v-if="answer != ''">You answered: {{ answer }}</p>

<button v-on:click="checkAnswer()">Check answer</button>

<template v-if="showFeedback">
<img
v-bind:alt="imageAlt"
v-bind:src='"https://s3.amazonaws.com/codewithsusan/circle-" + image + "@2x.png"'
/>
<p v-if="correct" class="correct">You got it!</p>
<p v-else class="incorrect">Sorry, please try again.</p>
<button v-on:click="reset()">Reset</button>
</template>

<h2>Difficulty level radios:</h2>
<input type="radio" id="easy" value="easy" name="level" v-model="level" />
<label for="easy">Easy</label>

<input
type="radio"
id="moderate"
value="moderate"
name="level"
v-model="level"
/>
<label for="moderate">Moderate</label>

<input
type="radio"
id="difficult"
value="difficult"
name="level"
v-model="level"
/>
<label for="difficult">Difficult</label>

<h2>Difficulty level select dropdown:</h2>
<select v-model="level">
<option value="easy">Easy</option>
<option value="moderate">Moderate</option>
<option value="difficult">Difficult</option>
</select>

<h2>Use the word in a sentence</h2>
<textarea v-model="sentence"></textarea>

<p>{{ sentence }}</p>

<p>First name: <input type="text" v-model="firstName" /></p>
<p>Last name: <input type="text" v-model="lastName" /></p>

<p>Hello {{ fullName }}</p>
<p>Hello {{ getFullName() }}</p>
<p>Hello {{ firstNameAndLastName }}</p>

<ul>
<li v-for="word in shortSpanishWords">{{ word }}</li>
</ul>
</div>
</body>
</html>