Charlice Dawson
Charlice Dawson

Reputation: 33

Separating male and female names with javascript/html?

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

Answers (4)

Snowmonkey
Snowmonkey

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

Purple_Kitten
Purple_Kitten

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

Cat
Cat

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

Murat Aras
Murat Aras

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

Related Questions