Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ayse-Nidal-mad-libz #169

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
59 changes: 59 additions & 0 deletions madLibz/Ayse-Nidal-mad-libz/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Re:Coded Mad Libz

## What is Mad Libs?
See [wikipedia](https://en.wikipedia.org/wiki/Mad_Libs). Yes, I know this section is short, do not skip this, **please read what Mad Libs is or the rest of this will make no sense**. In normal mad libs, you usually just insert the word, but in this version, it's more like a "fill in the blank" of an existing story.

## Instructions

### Collaboration requirements
Please don't split the code. Write every line of code together. In each group, every person should understand every line of code. See [pair programming](Pair_programming).

### Write a story

In `story.txt`, you'll find a brief story **that you need to replace with your own**. By the way, for the purposes of [parsing](https://en.wikipedia.org/wiki/Parsing), you're only allowed to use periods and commas as grammar.

Confusingly, you should write out the full story, although the "blanks" will be anywhere a grammar part is denoted. The reason for this will be apparent later in some of the extra challenges.

For example:
* `Louis[n]`: normally it says Louis, but the user should replace it with a *noun*
* `went[v]`: normally it says went, but the user should replace it with a *verb*
* `[a]` for adjective...

Note that when you write a story, the period and commas should go after the part of speech, e.g., `Louis[n].` (NOT `Louis.[n]`).

### Code

In this project, you will be using HTML, CSS, and JS in unison in order to create a variant of a Mad Libs game with the story of your choice.

Below, we discuss the requirements. We use the word "input" to refer to the blanks in the Mad Libs story.

Here is a very, very simple visual example of what it might look like; however, all styling is at your liberty in this project.

### Barebones Example
![Example](https://i.imgur.com/ZRNvFC7.png)

#### Functional requirements

0. **Parsing the story:** I've already written some code for you that reads in the file `story.txt` into a string. However, you need to process it into a format that will allow you to keep track of "blanks." See `madlibs.js` for further instructions. You will likely want to [read about regular expressions](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/regular-expressions/) (yes, this is extra expected reading :) ). It's possible, but annoying, to do this without regular expressions.

1. **Showing the story:** It should show **two copies** of the story. In one copy ("edit view"),
all words in the story with blanks (e.g., `Louis[n]`, `went[v]`, ...) are replaced with inputs. This should be in `div.madLibsEdit`. In the second copy ("preview"), it should show the same story, but formatted prettily (without the blanks!). Refer to the example picture above.

2. **Hotkeys:** When the user presses `Enter` in an input, it should move the cursor to the next input in the story.

3. **Constraining user inputs:** An input should be allowed to have a maximum of 20 characters.

4. **Live update:** Whenever the user updates a blank in the edit view, it should update the preview any time a new character is typed (hint: this is handling an event of sorts). The user should **not** have to click a button in order to update the preview.

5. **Story length:** Your story should have at least 10 blanks.

#### Styling requirements

0. **Responsiveness**: When the screen is small, the story should take the full width of the screen. When the screen is larger, as on a computer. Values "small" and "large" are up to you to decide.

1. **Flexbox**: Use at least one flexbox.

2. **Highlighting currently focused input**: There should be three possible styles of inputs (style is a vague word here, they just need to be distinguishable to the user):
* currently highlighted input (if the user is typing in one)
* filled out input (the user has already put a word there -- might require JS here ;) )
* empty input (the user has not already put a word there).
9 changes: 9 additions & 0 deletions madLibz/Ayse-Nidal-mad-libz/do-not-touch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* DO NOT TOUCH ANY OF THE CODE BELOW HERE.
*
* Or you will be very sad.
*/
const getRawStory = () => {
return fetch('./story.txt')
.then(response => response.text());
};
Binary file added madLibz/Ayse-Nidal-mad-libz/img/lp.jpg
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 madLibz/Ayse-Nidal-mad-libz/img/lp1.jpg
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 madLibz/Ayse-Nidal-mad-libz/img/lp9.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions madLibz/Ayse-Nidal-mad-libz/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>repl.it</title>
<link href="style.css" rel="stylesheet" type="text/css" />
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Pangolin&display=swap" rel="stylesheet">
</head>
<body>
<h1 class="header">Little Prince</h1>
<div class="container">
<div class='madLibsEdit'>
</div>
<div class='madLibsPreview'>
</div>
</div>
<script src="do-not-touch.js"></script>
<script src="madlibs.js"></script>
</body>
</html>
206 changes: 206 additions & 0 deletions madLibz/Ayse-Nidal-mad-libz/madlibs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
/**
* Complete the implementation of parseStory.
*
* parseStory retrieves the story as a single string from story.txt
* (I have written this part for you).
*
* In your code, you are required (please read this carefully):
* - to return a list of objects
* - each object should definitely have a field, `word`
* - each object should maybe have a field, `pos` (part of speech)
*
* So for example, the return value of this for the example story.txt
* will be an object that looks like so (note the comma! periods should
* be handled in the same way).
*
* Input: "Louis[n] went[v] to the store[n], and it was fun[a]."
* Output: [
* { word: "Louis", pos: "noun" },
* { word: "went", pos: "verb", },
* { word: "to", },
* { word: "the", },
* { word: "store", pos: "noun" }
* { word: "," }
* ....
*
* There are multiple ways to do this, but you may want to use regular expressions.
* Please go through this lesson: https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/regular-expressions/
*/

function parseStory(rawStory) {
// Your code here.
// console.log(rawStory)
// splitting punctuation of dots and commas
const dot = /[.]/g;
const comma = /[,] /g;
rawStory = rawStory.replace(dot, " .");
rawStory = rawStory.replace(comma, " , ");
// console.log(rawStory)
// splitting the story.txt
const splitArray = rawStory.split(' ');
// console.log(splitArray)

const arrayOfObjects = []
// console.log(newObject)

// looping over the story.txt array
for(let i = 0; i < splitArray.length; i++){
const newObject = {}
// checking if the word has [a]
if (splitArray[i].includes ('[a]')) {
// splitting the word from [a] and getting the word value of first index
newObject.word = splitArray[i].split('[a]')[0];
newObject.pos = 'adjective';
}
// checking if the word has [v]
else if (splitArray[i].includes ('[v]')) {
// splitting the word from [v] and getting the word value of first index
newObject.word = splitArray[i].split('[v]')[0];
newObject.pos = 'verb';
}
// checking if the word has [n]
else if (splitArray[i].includes ('[n]')) {
// splitting the word from [n] and getting the word value of first index
newObject.word = splitArray[i].split('[n]')[0];
newObject.pos = 'noun';
}
else {
// else the word itself
newObject.word = splitArray[i];
}
// pushing our object into our empty array
arrayOfObjects.push(newObject)
}
// console.log(arrayOfObjects)
// returns the array
return arrayOfObjects; // This line is currently wrong :)


}

/**
* All your other JavaScript code goes here, inside the function. Don't worry about
* the `then` and `async` syntax for now.
*
* You'll want to use the results of parseStory() to display the story on the page.
*/

/* PESUDOCODE
1.display the story in the first div
- iterate the story array
- check if the story has pos
* if it has, create input
* else the word itself

2.display the story in the second div
- iterate the story array
- check if the story has pos
* if it has, create span for blanks
* else the word itself
- we need an event for live update here

3.hotKeys
- when the user presses enter the cursor will move to the next input. we need an event for this
*/
getRawStory()
.then(parseStory)
.then((processedStory) => {
console.log(processedStory);
madLibsEdit(processedStory);
madLibsPreview(processedStory);
hotKeys();

// for displaying the story in the first div madLibsEdit, we crate a function
function madLibsEdit(text) {
// console.log(text)
const madLibsEdit = document.querySelector('.madLibsEdit');
let inP = document.createElement("p")
madLibsEdit.appendChild(inP)
let inputIdNumber = 0

// text is our story here. so we are looping the story.txt array. it equals to our arrayOfObjects
text.map(story => {
// story equals to newObject. we are checking if we have pos in the object
if(story.pos){
// console.log(story)
let input = document.createElement("input")
input.setAttribute("placeholder", `${story.pos}`)
input.setAttribute("type", "text")
input.setAttribute("maxlength", "20")
input.setAttribute("class", "inputClass")
input.id = `inputId${inputIdNumber++}`
input.style.marginRight = "5px"
input.style.marginBottom = "5px"
inP.appendChild(input)
} else {
inP.innerHTML += ` ${story.word} `
}
})
}
// for displaying the story in the second div madLibsPreview, we crate a function
function madLibsPreview(text) {
// we are selecting every input in the story
const allInputs = document.querySelectorAll("input");
const madLibsPreview = document.querySelector('.madLibsPreview');
let outPre = document.createElement("p")
madLibsPreview.appendChild(outPre)
let spanIdNumber = 0

// text is our story here. so we are looping the story.txt array. it equals to our arrayOfObjects
text.map(story => {
if(story.pos){
// story equals to newObject. we are checking if we have pos in the object. we are replacing inputs with blansk if we have a pos. else the word itself.
const span = document.createElement("span");
span.id = `spanId${spanIdNumber++}`
span.setAttribute("class", "spanClass")
span.style.marginRight = "5px"
// span.innerText = `(${story.pos}) `;
span.innerText = "________";
outPre.appendChild(span);
} else {
outPre.innerHTML += ` ${story.word} `
}
})

// we are looping our inputs in the story
for (let i = 0; i < allInputs.length ; i++){
const input = document.querySelector(`#inputId${i}`)
const span = document.querySelector(`#spanId${i}`)
// we are adding a keyup event son that we can get the value of the input whenever the input changes
input.addEventListener("input", function(e) {
if(input.value) {
span.innerHTML = input.value
} else {
span.innerHTML = "______"
}
})
}
}
});

// if the user presses "enter", the cursor will move to the next input
function hotKeys() {
// we are selecting every input in the story
const allInputs = document.querySelectorAll("input");

// we are looping our inputs in the story
for (let i = 0; i < allInputs.length; i++) {
const input = document.querySelector(`#inputId${i}`);

input.addEventListener("keydown", function (e) {
// if the user presses "enter", the cursor will move to the next input
if (e.key === "Enter") {
console.log(e.key)
document.querySelector(`#inputId${i+1}`).focus()
}
})
}
}








1 change: 1 addition & 0 deletions madLibz/Ayse-Nidal-mad-libz/story.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Once, when I was six years old, I saw[v] a marvellous[a]picture in a book on rainforests called Real-Life[n] Stories. It depicted a boa constrictor swallowing a wild animal. Here is a replica of the picture. I thought[v] a great[a] deal about goings-on in the jungle[n] and, in turn, with a crayon, managed to produce my first drawing. My drawing was not of a hat[n]. It showed[v] a boa constrictor digesting an elephant[n]. I then drew[v] the insides of the boa constrictor, so that the grown-ups could understand.
75 changes: 75 additions & 0 deletions madLibz/Ayse-Nidal-mad-libz/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/**
* Your CSS goes here.
*/
body {
background: url(img/lp9.jpeg);
background-position: center;
background-size: cover;
}

.container {
display: flex;
flex-wrap: wrap;
width: 100%;
}

.header {
text-align: center;
font-family: 'Pangolin', cursive;
font-size: 45px;
letter-spacing: 2px;
color: rgb(80, 13, 13);
text-shadow:
1px 0px 1px #ccc, 0px 1px 1px #eee,
2px 1px 1px #ccc, 1px 2px 1px #eee,
3px 2px 1px #ccc, 2px 3px 1px #eee,
4px 3px 1px #ccc, 3px 4px 1px #eee,
5px 4px 1px #ccc, 4px 5px 1px #eee,
6px 5px 1px #ccc, 5px 6px 1px #eee,
7px 6px 1px #ccc;
}

.madLibsEdit , .madLibsPreview {
width: 45%;
border: 2px solid #FC0;
border-radius: 15px;
box-shadow: 0 0 5px 5px #f3d660;
margin: 1rem auto;
padding: 1rem;
/* color: #5747EC; */
font-weight: bold;
background-color: rgba(255, 255, 255, 0.2);
}

.madLibsEdit p, .madLibsPreview p {
line-height: 2.5rem;
text-shadow: 1px 1px 2px rgb(247, 212, 212);
letter-spacing: 1px;
}

.inputClass {
border: 2px solid #FC0;
border-radius: 5px;
padding: 3px;
outline: none;
background-color: rgba(255, 255, 255, 0.7);
padding-left: 7px;
}

.inputClass::placeholder {
font-weight: 600;
}

.spanClass {
/* color: rgb(73, 189, 6); */
font-weight: bolder;
/* font-style: italic; */
background: #FC0;
letter-spacing: 0;
}

@media screen and (max-width: 768px) {
.madLibsEdit , .madLibsPreview {
width: 100%;
}
}