I have a form where people can add more input with a button.
The javascript function clones the "origin-item", but I can't seem to get the function to correctly update the value in #id_nested-TOTAL_FORMS and __prefix__ does not get replaced with a counter-number, It just copies and adds __prefix__ instead of 1 or 2 and so on.
Anyone know what is wrong with the function?
The script was found here: https://github.com/rotaris/dynamicformdjango/blob/master/todo/templates/edit_items_in_list.html
<input id="id_nested-TOTAL_FORMS" name="nested-TOTAL_FORMS" type="hidden" value="1">
<input id="id_nested-INITIAL_FORMS" name="nested-INITIAL_FORMS" type="hidden" value="0">
<input id="id_nested-MAX_NUM_FORMS" name="nested-MAX_NUM_FORMS" type="hidden" value="1000">
<div id="origin-item" class="hide item">
<div id="div_id_nested-__prefix__-name">
<label for="id_nested-__prefix__-name">Name</label>
<div class="controls col-lg-10">
<input id="id_nested-__prefix__-name" name="nested-__prefix__-name" type="text" />
</div>
</div>
<p><a id="add-new-item" href="#">Add new person</a></p>
<script type="text/javascript">
var prefix = 'nested';
var MAX_FORMS = '1000';
var MIN_FORMS = 1;
/*
* Perform any enhancements you'd like to a given item here
* e.g. add datepicker widgets, popovers etc.
*/
function enhanceItem(item) {
$('.btn.delete', item).popover({
offset: 10
});
}
function enhanceItems() {
$('.item').each(function() {
enhanceItem(this);
});
}
/*
* The opposite of enhanceItem()
*/
function diminishItem(item) {
$('.btn.delete', item).unbind();
}
function diminishItems() {
$('.item').each(function() {
diminishItem(this);
});
}
$(document).ready(function() {
enhanceItems();
});
function getFormCount() {
return parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
}
function updateFormCount(newValue) {
$('#id_' + prefix + '-TOTAL_FORMS').val(newValue);
}
/*
* ====================================================
* General Notes: 'Form' and 'Item' are used somewhat interchangeably.
* ====================================================
*/
$.fn.clearForm = function() {
return this.each(function() {
var type = this.type, tag = this.tagName.toLowerCase();
if (tag == 'form')
return $(':input',this).clearForm();
if (type == 'text' || type == 'password' || tag == 'textarea')
this.value = '';
else if (type == 'checkbox' || type == 'radio')
this.checked = false;
else if (tag == 'select')
this.selectedIndex = -1;
});
};
/*
* Given an element, this function replaces a given string/regex
* with another specified replacement (new_value) within the element
*/
function updateElement(el, target_regex, replacement) {
var id_regex = target_regex;
if ($(el).attr("for")) {
$(el).attr("for", $(el).attr("for").replace(id_regex, replacement));
}
if (el.id) {
el.id = el.id.replace(id_regex, replacement);
// Update the value of the hidden ID
// This hidden ID represents the ID of the model instance
var hidden_ID_patt = new RegExp('id_(' + prefix + '-\\d+)-id');
// Only update if an ID exists (i.e. if a corresponding model instance exists)
if (hidden_ID_patt.test(el.id)) {
$(el).val(new_value + 1);
}
}
if (el.name) {
el.name = el.name.replace(id_regex, replacement);
}
}
/*
* Given an element, this function replaces (the first?) occurence of a number
* that follows a specific prefix (e.g. 'exampleprefix-n')
* with another specified number (new_value) within the element
* where n is a number
*/
function updateElementIndex(el, prefix, new_value) {
var id_regex = new RegExp('(' + prefix + '-\\d+-)');
var replacement = prefix + '-' + new_value + '-';
updateElement(this, id_regex, replacement);
}
function reapplyEnhancements() {
// Apply some fresh enhancements
diminishItems();
enhanceItems();
}
/*
* btn = the button (or link or some source object) that instigated this action
* prefix = the prefix used in the formset (?)
*/
function addItem(btn, prefix) {
var formCount = getFormCount();
// You might like/want to do some validation before proceeding in this function
// i.e. before adding an item
// In this case, I'm limiting it to max number of forms
if (formCount < MAX_FORMS) {
// Clone a item (without event handlers) from the first item
//var item = $(".item:first").clone(false).get(0);
// Clone the origin item
var item = $("#origin-item").clone(false).get(0);
$(item).removeAttr("id");
$(item).removeClass("hide");
// Clear its values
$(':input', item).clearForm();
// Insert it after the last item
$(item).removeAttr('id').hide().insertAfter("form .item:last").slideDown(300);
$(':input, label', item).each(function() {
// Relabel/rename all the relevant bits
// '__prefix__' comes from #origin-item
// see 'empty_form': https://docs.djangoproject.com/en/1.4/topics/forms/formsets/#empty-form
var target_regex = new RegExp('(' + prefix + '-__prefix__-)');
var replacement = prefix + '-' + formCount + '-';
updateElement(this, target_regex, replacement);
// Remove error classes
$(this).removeClass("error");
});
reapplyEnhancements();
// Update the total form count (in the management form)
updateFormCount(formCount + 1);
}
else {
// Feel free to notify the user using some other technique instead of an JS alert
alert("Sorry, you can only have a maximum of " + MAX_FORMS + " goals.");
}
}
/*
* Relabel all items
*/
function relabelItems() {
var forms = $('.item'); // Get all the forms
// Update the total number of forms (likely 1 less than before)
$('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
var i = 0;
// Go through the forms and set their indices, names and IDs
for (formCount = forms.length; i < formCount; i++) {
$(":input, label", forms.get(i)).each(function() {
updateElementIndex(this, prefix, i);
});
}
}
/*
* Removes an item from a list of items
*/
function removeItem(btn, prefix) {
var formCount = getFormCount();
// Do some validation before proceeding
// In this case, just make sure there is at least one item
if (formCount > MIN_FORMS) {
var item = $(btn).parents('.item');
// Delete the item
$("*", item).fadeOut();
$(item).animate({'backgroundColor':'#fb6c6c'}, 300).slideUp('slow', function() {
$(item).remove();
relabelItems();
});
// Apply enhancements
enhanceItems();
}
else {
// Feel free to notify the user using some other technique instead of an JS alert
alert("Come on now, you need to have at least a minimum of " + MIN_FORMS + " item(s).");
}
}
// JavaScript to create a new items/entries
$(document).ready(function() {
$('#add-new-item').click(function(e) {
addItem(this, prefix);
return false;
});
$('a.delete').live("click", function(e) {
removeItem(this, prefix);
return false;
});
});
</script>
The bugs in this code seem to be caused by the variable named prefix being used for 2 different tasks.
Here it is used like this
$('#id_' + prefix + '-TOTAL_FORMS').val(newValue);
where I assume prefix is assigned '_prefix_', but later it is used like this
var target_regex = new RegExp('(' + prefix + '-__prefix__-)');
where I assume prefix is assigned 'id'
If you where to sort out the variable prefix to only contain one type of piece of information, by have 2 variables with different names.
I'm pretty sure everything would fall into place.
Related
I am trying to evaluate when the user inputs nothing (an empty string) or anything besides a number (Not a number). After I console log the an input of empty string a NaN is returned. I am not sure why the else-if statement is never recognized if I test for both an empty string or NaN value. This also ultimately affects my average total score.
const equationTag = document.querySelector('div#equation');
const inputBtn = document.querySelector('input.submit-btn');
const incorrectTag = document.querySelector('p#incorrect');
const correctTag = document.querySelector('p#correct');
const counterTag = document.querySelector('div#counter');
const exitButton = document.querySelector('button.exit-btn');
const displayButton = document.querySelector('button.display-btn');
const resultModal = document.querySelector('section.stats-section');
const averageP = document.querySelector('p.avg');
const guessP = document.querySelector('p.total-guesses');
let points = 0;
let correctGuesses = 0;
let incorrectGuess = 0;
let totalGuesses = 0;
/*
Takes a min and max value as parameters, and
returns a randomized integer
*/
function getRandomValue(min, max) {
let r = Math.floor(Math.random() * (max - min + 1)) + min;
return r;
}
// Displays multiplcation equation on the user interface
function displayEquation() {
equationTag.textContent = `${integerOne} x ${integerTwo}=`;
}
// Returns the product of the two integers
function getProduct() {
return integerOne * integerTwo;
}
/*
Event listener grabs user input on click
and clears user input afterwards
*/
inputBtn.addEventListener('click', () => {
const inputTag = document.querySelector('#num');
const answer = parseFloat(inputTag.value);
evaluateAnswer(answer);
inputTag.value = "";
inputTag.focus();
})
/*
Event listener grabs user input on enter key
and clears user input afterwards
*/
document.addEventListener("keydown", (event) => {
if (event.key === "Enter") {
const inputTag = document.querySelector('#num');
const answer = parseFloat(inputTag.value);
evaluateAnswer(answer);
inputTag.value = "";
inputTag.focus();
}
})
exitButton.addEventListener('click', () => {
setDisplayNone(resultModal);
})
displayButton.addEventListener('click', () => {
setDisplayBlock(resultModal);
})
/*
Takes a integer user input as an argument
and compares whether the answer is correct or not.
*/
function evaluateAnswer(input) {
console.log('Input value on eval ', input); // double checking value
if (input !== getProduct()) {
subtractPoint();
incorrectGuess++;
} else if (input === ' ' || isNaN()) { // I am not sure why it's never evaluated
console.log('Input value is empty or not a number ', input);
} else {
addPoint();
correctGuesses++;
}
totalGuesses++;
restartGame();
guessP.textContent = "Incorrect Guesses= " + incorrectGuess;
let average = (correctGuesses / totalGuesses);
let precisionAvg = roundToPrecision(average, 2);
averageP.textContent = `${(precisionAvg * 100).toFixed(2)}%`;
// console.log('Total guesses: ', totalGuesses);
// console.log('Incorrect ', incorrectGuess);
// console.log("Average: ", average)
}
/*
Evaluates if the points are less
than zero then restart points to 0
else minus a point.
*/
function subtractPoint() {
if (points <= 0) {
points = 0;
} else {
points -= 1;
}
setDisplayBlock(incorrectTag);
setDisplayNone(correctTag);
incorrectTag.textContent = ('Incorrect: ' + integerOne + ' x ' + integerTwo + ' = ' + getProduct());
setPoint();
}
// Sets new updated point
function setPoint() {
counterTag.textContent = points;
}
// Adds a point and updates earned points
function addPoint() {
points += 1;
correctTag.textContent = ('Correct!');
setDisplayBlock(correctTag);
setDisplayNone(incorrectTag);
setPoint();
}
/*
Resets game and gets two new random integers
and calls the displayEquation function.
*/
function restartGame() {
integerOne = getRandomValue(0, 12);
integerTwo = getRandomValue(0, 12);
displayEquation();
}
// sets css display block and opacity 1 on element
function setDisplayBlock(displayResult) {
displayResult.style.display = 'block';
displayResult.style.opacity = 1;
}
// sets css display none and opacity 0 on element
function setDisplayNone(displayResult) {
displayResult.style.display = 'none';
displayResult.style.opacity = 0;
}
/*
Takes a value as a parameter, and integer as a parameter
returns a rounded value with two decimal places at most
https://stackoverflow.com/questions/11832914/how-to-round-to-at-most-2-decimal-places-if-necessary/11832950#11832950
*/
function roundToPrecision(value, decimals = 2) {
const pow = Math.pow(10, decimals);
return Math.round((value + Number.EPSILON) * pow) / pow;
}
// run game on load
let integerOne = getRandomValue(0, 12);
let integerTwo = getRandomValue(0, 12);
displayEquation();
<body>
<header>
<h1 id="title">Multiply Me</h1>
</header>
<main>
<div id="equation"></div>
<div id="counter">0</div>
<input type="number" id="num" value="" title="input">
<input type="submit" class="submit-btn">
<button type="submit" class="display-btn" value="Show Results">+</button>
<div id="response">
<p id="correct"></p>
<p id="incorrect"></p>
</div>
<section class="stats-section">
<h3 class="h3-title">Overall Results:</h3>
<button class="exit-btn">x</button>
<article class="article-stats">
<p class="total-guesses"></p>
<p class="avg"></p>
</article>
</section>
</main>
</body>
Several issues apart from not using isNaN correctly
You cannot see if a value is a single space after parseFloating it.
I would suggest
const answer = inputTag.value;
evaluateAnswer(answer);
where you have this. Note the order and that I test the positive outcome before the negative
function evaluateAnswer(input) {
input = input.trim();
if (input === "" || isNaN(input)) {
console.log('Input value is empty or not a number ', input);
return; /* Any need to continue? */
} else if (input === getProduct()) {
addPoint();
correctGuesses++;
} else {
subtractPoint();
incorrectGuess++;
}
You must first check that the input value is not empty, so you must modify the order of the condition. And it is better to add a return to exit the function when no value is entered so that a new question is not generated.
function evaluateAnswer(input) {
console.log('Input value on eval ', input); // double checking value
if (input === '' || isNaN(input)) { // I am not sure why it's never evaluated
console.log('Input value is empty or not a number ', input);
return;
} else if (input !== getProduct()) {
subtractPoint();
incorrectGuess++;
} else{
addPoint();
correctGuesses++;
}
totalGuesses++;
restartGame();
guessP.textContent = "Incorrect Guesses= " + incorrectGuess;
let average = (correctGuesses / totalGuesses);
let precisionAvg = roundToPrecision(average, 2);
averageP.textContent = `${(precisionAvg * 100).toFixed(2)}%`;
}
Hi i am using Javascript to Call a API for Pricefeed from Coingecko. I use a Function to add Div's from a button for choosing Coins that will display Prices in different "spaces".
HTML:
<button onclick="add_coin('coinspaceA', window.countA); return false;">Add Coin</button>
<button onclick="add_coin('coinspaceB', window.countB); return false;">Add Coin</button>
<button onclick="add_coin('coinspaceC', window.countV); return false;">Add Coin</button>
i call the Function fetch_coinlist() before the closing Body Tag
JS:
window.countA = 0;
window.countB = 0;
window.countC = 0;
var coins = {};
function fetch_coinlist(){
fetch("https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=100&page=1&sparkline=false")
.then(
function(response) {
if (response.status !== 200) {
alert('Can Not get Price Api! Status: ' +
response.status);
return;
}
// Examine the text in the response
response.json().then(function(data) {
coins = {};
for (let i = 0, l = data.length; i < l; i++) {
let {id, ...info} = data[i];
coins[id] = info;
}
});
}
)
.catch(function(err) {
alert('Can Not get Price Api! Status: ' + err);
});
}
function add_coin(space) {
if (space == "coinspaceA") {
coinspace(space, window.countA);
}
if (space == "coinspaceB") {
coinspace(space, window.countB);
}
if (space == "coinspaceC") {
coinspace(space, window.countC);
}
}
function coinspace(space, count){
const div = document.createElement('div');
count += 1;
div.id = space + count;
if (space == "coinspaceA"){
window.coinspace1 = count;
}
if (space == "coinspaceB"){
window.coinspace2 = count;
}
if (space == "coinspaceC"){
window.coinspace3 = count;
}
div.innerHTML = (`
<input type="button" value="-" class="curser-del" onclick="remove_coin(this,'` + space + `')"/>
<select id="` + space + count + `select" placeholder="Choose Coin"></select>
<input type="numbers" >
<label id="` + space + count + `info">Coins</label>
`);
document.getElementById(space).appendChild(div);
show_coinlist(space, count);
}
function show_coinlist(space, count){
for (let id in coins) {
let item = coins[id];
console.log(item);
const toplist = document.createElement("option");
toplist.value = id;
console.log(toplist.value);
// selector actions
const selector = document.querySelector("#" + space + count + "select");
const info = document.querySelector("#" + space + count + "info");
console.log(selector);
console.log(info);
selector.addEventListener('change', event => {
info.innerHTML = "Selected item: " + coins[toplist.value].name + " : " + coins[toplist.value].current_price;
});
console.log(coins[toplist.value].name);
console.log(coins[toplist.value].current_price);
toplist.innerHTML = item.symbol.toUpperCase() + " - " + item.name;
console.log(toplist.innerHTML);
console.log(toplist);
document.getElementById("#" + space + count + "select").appendChild(toplist);
}
}
When i use the selector on its own with a static ID it works and i get the Price Displayed from the Coin i choose, in the example above it gives me the right Values to the Console but when i try to run the loop it gets aborted after the first cycle with the error:
Uncaught TypeError: Cannot read property 'appendChild' of null
I tryed to put the script at the End of the Site so everything can load, but it does not change the Error, i tryed with static ID this works but i need to have as many selections as the User wants to add, i tryed to put selector Actions outside the loop but it did not work either. When i use console.log(toplist) before ...appendChild(toplist) it gives me the correct option i try to append,
<option value="bitcoin">BTC - Bitcoin</option>
but the loop stops with the Error: Uncaught TypeError: Cannot read property 'appendChild' of null, what am i doing wrong?
What I want is, after the user enters the number of subjects, the system will show the number of input box according to the number of subjects entered, then when the user clicks on the button, it should show the sum. I tried many ways, but I failed to show the sum, anyone knows what is the mistake I made?
Below is my code:
function select() {
var x = parseInt(document.getElementById('1').value);
if (document.getElementById('1').value == "") {
alert("Please fill up number of subject");
} else if (isNaN(x) == true) {
alert("Please fill up number of subject with number");
} else {
var subject = parseInt(document.getElementById('1').value);
var sum = 0;
for (var num = 1; num <= subject; num++) {
document.write("Enter the mark for subject " + num + " : ");
var value = parseFloat(document.write("<input/><br>"));
sum += value;
}
var calc = document.write("<button>Next</button><br>");
calc.onclick = function() {
next()
};
function next() {
document.write("Total marks: " + sum + "%");
}
}
}
<html>
<body>
Enter the number of subject: <input type="text" onkeypress="return/[0-9]/i.test(event.key)" id="1" value=""><br>
<button onclick="select()">Check</button><br>
</body>
</html>
That's how I have rewritten a big part of your code. I have place inline comments to explain what I do.
function select() {
var x = parseInt(document.getElementById('1').value, 10);
// Getting the div that wraps the initial form.
var formWrapper = document.querySelector('.formWrapper');
// Getting the div, that is going to display the new fields and the results.
var results = document.querySelector('.results');
// I have switch your statement from x == '' to '' === x as it
// consists a good practice
if ( '' === x ) {
alert("Please fill up number of subject");
// I have remove the isNaN(x) == true, because the isNan will
// be either true or false.
} else if ( isNaN(x) ) {
alert("Please fill up number of subject with number");
} else {
// Using parseInt(x, 10) to set the base.
var subject = parseInt(x, 10);
// In this array, I store the auto-generated fields.
var fieldsList = [];
// Removing the first div from the DOM
formWrapper.parentElement.removeChild(formWrapper);
for ( var num = 1; num <= subject; num++ ) {
// I am creating a new field
var newField = document.createElement('input');
// I push the field into the array I made for the fields.
fieldsList.push(newField);
// I append the field in the HTML
results.appendChild(newField);
// I create a <br> tag
var br = document.createElement('br');
// And I append the tag in the DOM
results.appendChild(br);
}
// I create the button that is going to handle the Next functionality
var nextButton = document.createElement('button');
// I set the button text
nextButton.innerText = 'Next';
// I add an Event Listener for the click event.
nextButton.addEventListener(
'click',
function() {
// I reset the sum to 0
var sum = 0;
// I itterate the fields auto-generated and saved in the array
fieldsList.forEach(
function(field) {
// I get the value
sum += parseInt(field.value, 10);
}
);
// I create the field that is going to display the output
let resultText = document.createElement('div');
// I set the text based on the sum
resultText.innerText = "Total marks: " + sum + "%";
// I append the text message to the DOM
results.appendChild(resultText);
}
);
// I append the button to the DOM
results.appendChild(nextButton);
}
}
<html>
<body>
<div class="formWrapper">
Enter the number of subject: <input type="text" onkeypress="return/[0-9]/i.test(event.key)" id="1" value=""><br>
<button onclick="select()">Check</button><br>
</div>
<div class="results"></div>
</body>
</html>
Fiddle: http://jsfiddle.net/qfn04xzj/
var a, b;
$('input:not([type=password]), textarea, select').on('focus', function(event) {
a = performance.now();
});
$('input:not([type=password]), textarea, select').on('blur', function(event) {
b = performance.now();
$('#console').append( $(this).attr('name') + ' took ' + (b - a) + ' ms.' + "<br/>");
});
... works but it measures time between focus and blur.
Is there any way I could measure the actual time — the time it took to type or time between two value changes?
You should first define what actual time means. If you mean the time between the first and last keystroke, then the following code should work. It creates an object for each time the user focuses on the input and listens for every keystroke, keeping record of the first and last keystrokes. When the input is blurred, it computes the difference between the two.
Of course, the user can still type a couple of characters, go for a cup of coffee and then return and type the others, which will result in a very long time of activity. There is no way to know how much time the user has spent actually staring at the input. You could, however, define a "timeout" or period of inactivity after which you assume that the user is idle.
Fiddle
$('input:not([type=password]), textarea, select').on('focus', function() {
new EditingSession($(this));
});
/**
* Represents the period of time during which the user is focused on
* the input.
*/
function EditingSession(input){
var firstKeydownTime = null;
var lastKeydownTime = null;
var sessionId = makeRandomId();
input.on("keydown." + sessionId, function(){
// User typed something
var time = performance.now();
lastKeydownTime = time;
if(firstKeydownTime === null){
firstKeydownTime = time;
}
});
input.on("blur." + sessionId, function(){
// Editing session finished.
// Detach all handlers
input.off("." + sessionId);
// Print time between first and last keydown
var time;
if(firstKeydownTime === null){
time = 0;
} else {
time = lastKeydownTime - firstKeydownTime;
}
$('#console').append(input.attr('name') + ' took ' + time + ' ms.' + "<br/>");
});
}
// Borrowed from http://stackoverflow.com/questions/1349404/generate-a-string-of-5-random-characters-in-javascript
function makeRandomId() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for( var i=0; i < 5; i++ )
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
Instead of getting the time difference between keydown and keyup (which is silly :)) you need to simply get one single performance.now() timestamp and store it into a b variable for a later "input" event time-difference comparison.
var $fields = $('input:not([type=password]), textarea, select'),
$console = $("#console"),
$total = $("#totTime"),
tot=0, a=0, b=0;
$fields.on('input', function() {
a = performance.now();
var diff = (a - b)|0; // |0 prevents floated results (happens in FF)
$console.append( this.name +" took "+ diff +" ms"+ this.value +"<br>");
$total.text("Total time: "+ (tot+=diff) +" ms");
b = a; // Store a into b for later use.
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="totTime"></div>
<input type="text" name="" id="">
<div id="console"></div>
Performance-wise (since you're dealing with hopefully time accuracy) cache your Elements selectors into variables, that way you'll prevent parsing again the DOM in the search for your elements on every input event.
Also "input" as event is quite enough to handle all you need from copy-paste, change etc...
This will give you total time typing: Fiddle
<input type="text" name="" id="">
<div id="total"></div>
<div id="console"></div>
JS
$('input:not([type=password]), textarea, select').on('input change keyup', function (event) {
if (event.type == 'input') {
$('#console').append("input: " + $(this).val() + "<br/>");
}
if (event.type == 'change') {
$('#console').append("change: " + $(this).val() + "<br/>");
}
});
var a, b, total = 0;
$('input:not([type=password]), textarea, select').on('keydown', function (event) {
a = performance.now();
});
$('input:not([type=password]), textarea, select').on('keyup', function (event) {
b = performance.now();
var net = (b - a);
$('#console').append($(this).attr('name') + ' took ' + net + ' ms.' + "<br/>");
var final = total += net;
$('#total').text('Total time typing: ' + final + ' ms.');
});
I'm trying to make JS output a full name based on input from both radio buttons and text. I'm having an issue as I want it to output the person's choice, yet whenever I click male or female, it's always displaying as Male (plus the text). The code I've got at the moment for the output is:
window.onload = initAll;
function initAll() {
document.getElementById("sillySubmit").onclick = function() {
document.getElementById("msgField").innerHTML = getSillyName();
return false;
}
}
function getSillyName() {
var x = $('input[id]').click(function() {
($('input[id]:checked').val());
});
var lastName1 = ["lots of names"];
var lastName2 = ["lots more names" ];
var lastNm = document.getElementById("lName").value.toUpperCase();
var validName = true;
if (lastNm == "") {
validName = false;
}
else {
var lastNum1 = lastNm.charCodeAt(0) - 65;
var lastNum2 = lastNm.charCodeAt((lastNm.length-1)) - 65;
if (lastNum1 < 0 || lastNum1 > 25 || lastNum2 < 0 || lastNum2 > 25) {
validName = false;
}
}
if (!validName) {
document.getElementById("lName").focus();
document.getElementById("lName").select();
return "I say. Something gone a bit squiffy here. Try again...";
}
return "Your name is " + x + ' ' + lastName1[lastNum1] + ' '
+ lastName2[lastNum2]; //add in comparisons later on
}
where 'x' is representing male and 'y' is female. What can I add/change so that it displays the correct preference?
I can't see your html, so I have to guess a lot. I assume you have a lot of input elements, all with an id-attribute, and your female/male buttons are two of them. Those buttons have a value being either 'on' or 'off', and in some browsers its always 'on'. So don't look for value. Further radio buttons have a property checked being either true or false.
You don't need to attach a click-handler to get the state.
So the first lines of your getSillyName() could look like:
function getSillyName() {
var x;
if (document.getElementById(/* female id here */).checked) {
x = 'Mrs.' // change string to whatever you want to see
} else if (document.getElementById(/* male id here */).checked) {
x = 'Mr.' // as above
} else x = 'cat'; // possibly both are unchecked
/* the very important next line in your code should be: */
console.log(x);
/* this important line move step by step further down your code */
console.log(/* and put in here what you want to check */);
/* rest of code here */
}
After that your element #msgField should show something.
What can I add/change so that it displays the correct preference?
If I understood correctly, the answer will be: parentheses.
The code will become:
"Your name is " + (x || y) + ' ' + lastName1[lastNum1] + ' ' + lastName2[lastNum2];
Try defining the first name before returning the value.
if(gender == 'male')
firstname = ...
else
firstName = ...
return 'Your name is ' + firstname + ' ' + lastName1[lastNum1] + ' ' + lastName2[lastNum2];
I hope that helps.