Reputation: 33
I have a random name generator code that involves css, and javascript. As the code stands now, I can input any name (regardless of gender), hit the generate button, and a random first and last name will pop up. The only problem is, I want to be able to create separate buttons for male, female, and unisex names.
I tried creating separate div ids for the name and female names, duplicating the javascript and changing the portion of the code to 'femalename' and 'malename' but that ruined the formatting and made it so that, when I press one of the generate buttons, both divs generate a name.
<!DOCTYPE HTML>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head>
<title>Random name generator</title>
<meta charset='utf-8' />
<style type='text/css'>
#name {
color : #444;
font : bold 51px times, Times New Roman, times-roman, georgia, serif;
letter-spacing : -2px;
line-height : 44px;
text-align : center;
text-transform: uppercase;
}
#refresh {
font : normal 11px Gill Sans, Verdana;
letter-spacing : 2px;
line-height : 14px;
text-align : center;
text-transform : uppercase;
}
a {
color : #666;
}
a:hover {
color : #999;
}
</style>
</head>
<body>
<script type='text/javascript'>
first = ['abbie ', 'abby ', 'abu ', 'alec ', 'alek ', 'aleksander ', 'alex ', 'alexander ', 'aaron ', 'adam ', 'andrew ', 'anthony ', 'archer ', 'arthur ', 'austin '];
last = ['williamson', 'davidson', 'edwards', 'ingram', 'olsen'];
name = "";
length = Math.floor(Math.random()) + 1;
for (i = 0; i < length; i++)
name += (first[Math.floor(Math.random()*first.length)]
+ last[Math.floor(Math.random()*last.length)]);
name = name.charAt(0) + name.slice(1);
document.write("<p id='name'>" + name + "</p>");
</script>
<p id="refresh">
<a href='#' onclick='window.location.reload()'>generate a new one</a>
</p>
</body>
</html>
Upvotes: 3
Views: 1529
Reputation: 3761
Here's an answer with a single array for the firstNames. The structure of the first names has been changed to an array of objects.
I did use a lot of ES6 'fat-arrow' functions, and tried to make the functions as reusable as possible. This was actually sort of fun! ;)
const resultsPane = document.querySelector('.random-name-results ul'),
generateBtn = document.querySelector('.refresh-random-name');
const filterByGender = gender => name => gender.includes(name.gender);
const getRandom = arr => arr[Math.floor(Math.random() * arr.length)];
const findName = (gender) => {
const firstNames = [
{
name: 'abigail',
gender: 'female',
variations: ['abigail', 'abbie', 'abby']
},
{
name: 'abu',
gender: 'neutral',
variations: ['abu']
}, {
name: "alec",
gender: "neutral",
variations: ['alec', 'alex', 'alexander', 'alek', 'aleksander']
}, {
name: 'aaron',
gender: 'male',
variations: ['aaron', 'aron', 'aram', 'aroon', 'arrun', 'arun', 'aharon']
}, {
name: 'adam',
gender: 'male',
variations: ['adam', 'addam', 'adham', 'atem']
}, {
name: 'andrew',
gender: 'male',
variations: ['andrew', 'andy', 'andre', 'andrej']
}, {
name: 'addison',
gender: 'neutral',
variations: ['addison', 'addy', 'addie']
}, {
name: 'cameron',
gender: 'neutral',
variations: ['cameron', 'cam', 'cammie']
}, {
name: 'kathryn',
gender: 'female',
variations: ['kathryn', 'katherine', 'kathy', 'catherine', 'cathy', 'kate', 'katy', 'cate', 'katya']
}
];
const last = ['williamson', 'davidson', 'edwards', 'ingram', 'olsen'];
const findGender = filterByGender(gender),
filteredList = firstNames.filter(findGender),
firstName = getRandom(getRandom(filteredList).variations),
lastName = getRandom(last);
return `${firstName} ${lastName}`
}
generateBtn.addEventListener("click", function(){
const gender = document.querySelector("input[name='gender']:checked").value;
let name = findName(gender),
nameEl = document.createElement('li');
nameEl.innerText = name;
resultsPane.innerText = "";
resultsPane.appendChild(nameEl);
})
.random-name-container {
width: 96vw;
height: 95vh;
border: 2px solid palevioletred;
border-radius: 2vmin;
padding: .5vmin;
display: grid;
grid-template-areas: 'head head'
'actions results'
'actions foot';
grid-template-rows: 8vh 1fr 30px;
grid-template-columns: 30vw 1fr;
overflow: scroll;
}
.random-name-container header {
grid-area: head;
background-color: bisque;
}
header h1 {
margin: auto auto 0 auto;
}
header p {
margin: 0;
}
.random-name-container footer {
grid-area: foot;
background-color: bisque;
}
.random-name-results {
grid-area: results;
background-color: gainsboro;
width: 100%;
height: 100%;
}
.random-name-actions {
display: flex;
grid-area: actions;
flex-direction: row;
flex-wrap: wrap;
}
.random-name-actions > * {
width: 95%;
}
.random-name-actions fieldset > * {
display: block;
}
<article class='random-name-container'>
<header>
<h1>Random Name Generator</h1>
<p>Choose your preferred gender, and give it a spin!</p>
</header>
<section class='random-name-results'>
<ul></ul>
</section>
<section class='random-name-actions'>
<fieldset>
<label><input type='radio' name='gender' value='female neutral' checked />Female</label>
<label><input type='radio' name='gender' value='male neutral' />Male</label>
<label><input type='radio' name='gender' value='neutral' />Gender-neutral</label>
</fieldset>
<input type='button' class='refresh-random-name btn' value='Generate another!'>
</section>
<footer>The name game</footer>
</article>
Upvotes: 0
Reputation: 223
I would alter the function to accept a gender within the HTML, as well as run the function on load.
Here is also an example with an "any gender" option: https://codepen.io/kboedges/pen/qeXmqK?editors=1111
const maleFirst = ["abu", "alec", "alek"];
const femaleFirst = ["abbie", "abby", "katie", "leah"];
const last = ["williamson", "davidson", "edwards", "ingram", "olsen"];
// Function
function generateName(gender) {
const randomLast = last[Math.floor(Math.random() * last.length)];
const randomMaleName = `${maleFirst[Math.floor(Math.random() * maleFirst.length)]} ${randomLast}`;
const randomFemaleName = `${femaleFirst[Math.floor(Math.random() * femaleFirst.length)]} ${randomLast}`;
// Insert into HTML
const p = document.getElementById('name');
p.innerHTML = gender === 'female' ? randomFemaleName : randomMaleName;
}
// On first run
generateName('male');
#name {
color: #444;
font: bold 51px times, Times New Roman, times-roman, georgia, serif;
letter-spacing: -2px;
line-height: 44px;
text-align: center;
text-transform: uppercase;
}
#refresh {
font: normal 11px Gill Sans, Verdana;
letter-spacing: 2px;
line-height: 14px;
text-align: center;
text-transform: uppercase;
}
a {
color: #666;
}
a:hover {
color: #999;
}
<p id='name'></p>
<p id="refresh">Generate a...
<a href='#' onclick="generateName('female')">female name</a>
<a href='#' onclick="generateName('male')">male name</a>
</p>
Upvotes: 0
Reputation: 4236
How do you like this?
const
// Identifies HTML elements
buttons = document.getElementsByClassName("btns"),
display = document.getElementById("display"),
// Identifies arrays of names
girls = ['abbie', 'abby'],
boys = ['abu', 'alec', 'arthur'],
whatevs = ['alex', 'archer', 'austin'],
lastNames = ['williamson', 'davidson', 'edwards', 'ingram', 'olsen'];
// Runs the makeName function when a button is clicked
document.addEventListener("click", makeName);
// Defines the makeName function (`event` is the triggering click event)
function makeName(event){
// Remembers what was clicked
const clickedThing = event.target;
// Declares a variable to hold the appropriate array
let chosenList;
// Makes sure the click was on a button before proceeding
if(clickedThing.classList.contains("btns")){
// Sets the appropriate list depending on which button was clicked
if(clickedThing.value == "girl"){ chosenList = girls; }
else if(clickedThing.value == "boy"){ chosenList = boys; }
else { chosenList = whatevs; }
// Identifies names (retrieved using the `randFrom` function)
const
first = randFrom(chosenList), // Chooses a name from the specified list
last = randFrom(lastNames), // Chooses a lastName
fullName = `${first} ${last}`; // Puts them together
// Shows the result on the page
display.innerHTML = fullName;
}
}
// Gets a random element from an array
function randFrom(array){
const index = Math.floor(Math.random() * array.length);
return array[index];
}
#display {
color: #444;
font: bold 51px times, Times New Roman, times-roman, georgia, serif;
letter-spacing: -2px;
line-height: 44px;
text-align: center;
text-transform: uppercase;
}
<button class="btns" value="girl">girl</button>
<button class="btns" value="boy">boy</button>
<button class="btns" value="whatevs">whatevs</button>
<p id="display"></p>
Upvotes: 2
Reputation: 401
if i didn't miss understand you need two actions to create and display names in different containers.
<!DOCTYPE HTML>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head>
<title>Random name generator</title>
<meta charset='utf-8' />
<style type='text/css'>
.name {
color : #444;
font : bold 51px times, Times New Roman, times-roman, georgia, serif;
letter-spacing : -2px;
line-height : 44px;
text-align : center;
text-transform: uppercase;
}
.refresh {
font : normal 11px Gill Sans, Verdana;
letter-spacing : 2px;
line-height : 14px;
text-align : center;
text-transform : uppercase;
}
a {
color : #666;
}
a:hover {
color : #999;
}
</style>
</head>
<body>
<p id="firstName" class="name"></p>
<p class="refresh">
<a href='#' onclick='generateName("firstName")'>generate a first name</a>
</p>
<p id="secondName" class="name"></p>
<p class="refresh">
<a href='#' onclick='generateName("secondName")'>generate a second name</a>
</p>
<script type='text/javascript'>
function generateName(containerId) {
first = ['abbie ', 'abby ', 'abu ', 'alec ', 'alek ', 'aleksander ', 'alex ', 'alexander ', 'aaron ', 'adam ', 'andrew ', 'anthony ', 'archer ', 'arthur ', 'austin '];
last = ['williamson', 'davidson', 'edwards', 'ingram', 'olsen'];
name = "";
length = Math.floor(Math.random()) + 1;
for (i = 0; i < length; i++)
name += (first[Math.floor(Math.random()*first.length)] + last[Math.floor(Math.random()*last.length)]);
name = name.charAt(0) + name.slice(1);
document.getElementById(containerId).innerHTML = name;
}
</script>
</body>
</html>
Upvotes: 0