-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
training/1-introduction/1.3-why-elm.md |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Learning Elm - Rough Rough Rough Draft (WIP) | ||
|
||
There are some tutorials and guides to getting started with Elm. However, sometimes the guides are a little generalized in a way that is not quite as helpful as a knowing a target audience. The goal of this Elm guide is to target JavaScript developers, so knowledge of JavaScript will be assumed and talked about. If you new to programming and feel up to Elm (which is awesome!) I recommend searching Richard Feldman's talks on Elm. They are a little outdated due to a version update recently to Elm, but they are excellent for getting your head wrapped around the ideas that drive Elm. At the same time read through: http://guide.elm-lang.org/ | ||
|
||
## Assumptions | ||
|
||
Some assumptions I am making about the reader is: | ||
|
||
1. You can use your terminal for your particular OS | ||
2. You have some programing experience and understand the basics well | ||
3. You are open minded about functional programming | ||
|
||
## Understating the Directory Structure | ||
|
||
### Tutorial | ||
|
||
The tutorial folder is the place where we work through learning Elm and implementing our project | ||
|
||
### JS-Example | ||
|
||
The `js-example` folder is the folder where I quickly through together an example final project. Mostly to give me clarity on direction on helping JavaScript developers understand Elm. | ||
|
||
|
||
## Questions? | ||
|
||
File a github issue. | ||
|
||
## Contribute | ||
|
||
Yes Please! | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
"use strict"; | ||
|
||
/** | ||
This is not to be an example of "how to" in JavaScript | ||
Actually this code is most likely bad and I would not recommend it. | ||
It was written just to get a basic working example of our final project. | ||
**/ | ||
|
||
let state = { users: [], currentUser: {}, search: "" }; | ||
|
||
const getUsers = (amount) => { | ||
return axios.get(`http://api.randomuser.me/?results=${amount}`) | ||
} | ||
|
||
const parseRanomUsers = _.flowRight(_.get("results"), _.get("data")); | ||
|
||
const update = (action, state = {}, data) => { | ||
switch (action) { | ||
case "updateUsers": | ||
const newState = _.assign({ users: data }, state, {}); | ||
const evt = new CustomEvent("$updatedState", newState); | ||
document.dispatchEvent(evt); | ||
return newState; | ||
case "updateCurrentUser": | ||
const nState = _.assign({ currentUser: data }, (state || {}), {}); | ||
const _e = new CustomEvent("$updatedState", { detail : nState }); | ||
document.dispatchEvent(_e); | ||
return nState | ||
default: | ||
const e = new CustomEvent("$updatedState", state); | ||
return state; | ||
} | ||
} | ||
|
||
const renderUserProfile = (employee) => { | ||
const div = document.createElement("div"); | ||
const h1 = document.createElement("h1"); | ||
h1.innerHTML = `${employee.name.first} ${employee.name.last}` | ||
div.appendChild(h1); | ||
div.appendChild(renderUserProfileImage(employee)); | ||
div.appendChild(renderEmployeeInformation(employee)); | ||
return div; | ||
} | ||
|
||
const renderUserProfileImage = (user) => { | ||
const img = document.createElement("img"); | ||
const div = document.createElement("div"); | ||
div.classList.add("img-container"); | ||
img.src = user.picture.large; | ||
div.appendChild(img); | ||
return div; | ||
} | ||
|
||
const renderEmployeeInformation = user => { | ||
const div = document.createElement("div"); | ||
const employeeInfo = _.pick(["email", "login", "cell"], user); | ||
const info = _.map(e => { | ||
const p = document.createElement("p"); | ||
if (_.isObject(employeeInfo[e])) { | ||
p.innerHTML = `<b>Username</b>: ${employeeInfo[e].username}`; | ||
return p; | ||
} | ||
switch (e) { | ||
case "email": | ||
p.innerHTML = `<b>Email</b>: ${employeeInfo[e]}`; | ||
break; | ||
case "cell": | ||
p.innerHTML = `<b>Cell</b>: ${employeeInfo[e]}`; | ||
break; | ||
} | ||
|
||
return p; | ||
}, _.keys(employeeInfo)); | ||
|
||
_.each((p) => div.appendChild(p), info); | ||
div.classList.add("employee-info") | ||
return div; | ||
} | ||
|
||
const renderEmployeeList = (users) => { | ||
const div = document.createElement("div"); | ||
const input = document.createElement("input"); | ||
const ul = document.createElement("ul"); | ||
const appendLi = _.flowRight( | ||
_.each(li => ul.appendChild(li)), | ||
_.map(renderUserDirectory) | ||
); | ||
appendLi(users) | ||
input.placeholder = "Search"; | ||
input.value = state.search; | ||
input.addEventListener("input", onEmployeeSearch) | ||
div.classList.add("employee-directory"); | ||
div.appendChild(input); | ||
div.appendChild(ul); | ||
return div; | ||
} | ||
|
||
const renderUserDirectory = user => { | ||
const li = document.createElement("li"); | ||
li.innerHTML = `${user.name.first} ${user.name.last}`; | ||
li.addEventListener("click", onEmployeeNameclick); | ||
return li; | ||
} | ||
|
||
const render = (html, node) => { | ||
node.innerHTML = ""; | ||
node.appendChild(html); | ||
document.querySelector("input").focus(); | ||
}; | ||
|
||
const main = () => { | ||
if (!_.isEmpty(state.users)) { | ||
renderMain(); | ||
} | ||
else { | ||
getUsers(50) | ||
.then(results => { | ||
const newState = update("updateUsers", state, parseRanomUsers(results)); | ||
renderMain(newState); | ||
}); | ||
} | ||
} | ||
|
||
const renderMain = (newState) => { | ||
const currentUser = _.isEmpty(state.currentUser) ? newState.users[0] : state.currentUser; | ||
if (newState && newState.users) { | ||
state.users = newState.users; | ||
render(renderEmployeeList(newState.users), document.querySelector(".directory")); | ||
} | ||
|
||
render(renderUserProfile(currentUser), document.querySelector(".profile")); | ||
} | ||
|
||
const onEmployeeNameclick = (e) => { | ||
const lastName = _.last(e.target.innerHTML.split(" ")); | ||
update("updateCurrentUser", null, {name: lastName}) | ||
} | ||
|
||
const onEmployeeSearch = (e) => { | ||
const value = e.target.value; | ||
state.search = value; | ||
if (value === "") { | ||
renderMain(state); | ||
return null; | ||
} | ||
const filteredEmpolyees = _.filter(user => { | ||
return _.contains(value, user.name.last); | ||
}, state.users); | ||
|
||
render(renderEmployeeList(filteredEmpolyees), document.querySelector(".directory")); | ||
} | ||
|
||
document.addEventListener("$updatedState", ({ detail }) => { | ||
if (detail !== null) { | ||
const currentUserLastName = detail.currentUser.name; | ||
const newUser = _.head(_.filter(user => { | ||
return _.get("name.last", user) === currentUserLastName; | ||
}, state.users)); | ||
state = _.assign({ currentUser: newUser }, state, {}) | ||
|
||
const _e = new CustomEvent("$updatedStateComplete", { detail : state }); | ||
document.dispatchEvent(_e); | ||
} | ||
}); | ||
|
||
document.addEventListener("$updatedStateComplete", main); | ||
document.addEventListener("DOMContentLoaded", main) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500" rel="stylesheet"> | ||
<link rel="stylesheet" href="styles.css"> | ||
<meta charset="UTF-8"> | ||
<title>Company Directory</title> | ||
</head> | ||
<body> | ||
|
||
|
||
<div class="container"> | ||
<div class="directory"></div> | ||
<div class="profile"></div> | ||
</div> | ||
<script src="node_modules/axios/dist/axios.js"></script> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash-fp/0.10.4/lodash-fp.min.js"></script> | ||
|
||
<script src="app.js"></script> | ||
</body> | ||
</html> |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.