I'm working on an online form for attendees of a conference to fill out. Each person enters the amount of minutes they attended for a certain session. The minutes convert to Credit Hours in a form field like so:
<div class="col3">
<form onsubmit="return false" oninput="document.getElementById('MK1').innerHTML = (Math.floor((MC06.value/50) * 2) / 2).toFixed(1)">
<input name="MC06" id="MC06" onkeyup="disableField06()" type="number" min="0" max="50" placeholder="0-75 minutes" step="any" />
</div>
<div class="col1">
<output name="MK1" id="MK1">0</output>
</form>
</div>
In case you're wondering, the disableField function disables another session for the same time slot. No problems there. No problems with the placeholder either, thanks to a script I found here.
The hours for Subject Category (MK in this case) are collected in a function when the user clicks the Submit button:
var MK1 = document.getElementById("MK1").value;
var MK2 = document.getElementById("MK2").value;
var MK3 = document.getElementById("MK3").value;
var MK4 = document.getElementById("MK4").value;
var MK5 = document.getElementById("MK5").value;
var MK6 = document.getElementById("MK6").value;
document.getElementById("MK").value = parseFloat(MK1) + parseFloat(MK2) + parseFloat(MK3) + parseFloat(MK4) + parseFloat(MK5) + parseFloat(MK6);
Finally, the subjects and their total hours per attendant are displayed in a table at the bottom.
<div class="table-row">
<div class="col2">Marketing: </div>
<div class="col4"><input type = "text" id = "MK" name = "MK"></div>
</div>
This works fine in Chrome, but in IE9 (the company browser) I get NaN. How can I fix this?
I fixed it.
I changed the code for lines like
var MK1 = document.getElementById("MK1").value;
to
var MK1 = document.getElementById("MK1").innerHTML;
That worked for the data called back from the input fields. The code that totals all the subjects' credit hours together still returned NaN. I changed those lines back to .value, and it worked! Looks like IE9 has a narrower scope for .value than other browsers.
Related
I have a form that has a mobile field. On submit button I put an event to add a value to the mobile field (it adds the country region code automatically which is a fixed value of "11"), so when the user clicks on Submit, the JS adds the "11" value to the mobile so the this field goes to the data base like this "1155555555" (the user just typed "55555555").
Ok, the problem is that if the user left an empty field (all fields are required), and clicks on Submit, the form won´t be sent but it will add the value "11" to the mobile field no matter what, and when the user fills up the empty field and click on Submit for the second time, it will add AGAIN the value "11", so the mobile goes like "111155555555", and so on and so forth.
Basically, what I need is to prevent this function from happening multiple times. It has to happen only once. How do I achieve this using JS?
HTML:
<input id="mobile" name="MOBILE" type="tel"><input type="number" value="11" id="front" class="hide">
<button type="submit" onclick="append11()">SUBMIT</button>
JS:
function append11(){
var mobilenumber = document.getElementById("mobile");
var front = document.getElementById("front").value;
mobilenumber.value=front+mobilenumber.value;
alert(mobilevalue.value);
}
Why you don't append the 11 in the function?
Like:
function append11(){
var mobilenumber = document.getElementById("mobile");
mobilenumber.value="11"+mobilenumber.value;
alert(mobilevalue.value);
}
I think you should heed the comment responses to your original question. Your approach has some risks.
But I'll assume you're a beginner who's just trying to learn how to do something like what you're asking about, so the javascript below applies a few principles you might consider.
function isNumberValid9(num) {
console.log(num, num.length);
//check string length and pattern
//this could be combined into a single regex, e.g.: mobileValue.match("^[0-9]{9}$")
var isValid9 = num.length === 9 && num.match("^[0-9]+$");
console.log(isValid9); //display the value about to be returned
return isValid9;
}
/* Conditionally prepend "11" */
function maybeAppend11() {
var mobilenumber = document.getElementById("mobile");
var mobileValue = mobilenumber.value;
//only prepend "11" if the number matches your expected pattern and length
if (isNumberValid9(mobileValue)) {
var front = document.getElementById("front").value;
mobilenumber.value = front + mobileValue;
}
alert(mobilenumber.value);
}
<input id="mobile" name="MOBILE" type="tel" value="555555555"><input type="number" value="11" id="front" class="hide">
<button type="submit" onclick="maybeAppend11()">SUBMIT</button>
here at work our helpdesk-members have to write a lot of support tickets and send them via Mail to the IT.
It takes a lot of time, because the common way to do the task is to search for an already send ticket and to rewrite it by hand.
Although I'm fairly new to javascript, I managed to write a so called "ticket-generator". It contains the input fields, stores the input in localstorage and generates at the end the complete text, inserts it in an outlook mail-body and we are ready to hit the "send" button within seconds.
My problem now:
I'd like to let people choose how many predefined input-fields they need, if they want to write multiple tickets at once.
This is where I'm stuck:
The html:
<form id="ticketform">
<input id="projectselection" name="projectselection1" list="projects" placeholder="Choose project...">
<datalist id="projects">
<option value="Project1"></option>
<option value="Project2"></option>
<option value="Project3"></option>
</datalist>
<br>
<input id="numberoftickets" type="number" placeholder=" Choose the number of tickets...">
</form>
<button id="newForm" onclick="newnew()">DO IT!</button>
<div id="dynamicInput">
</div>
The script:
function newnew() {
let inputNumberoftickets = document.getElementById("numberoftickets").value;
localStorage.setItem("selectionNumberoftickets", inputNumberoftickets);
let original = document.getElementById("projectselection");
let clone = original.cloneNode(true);
let y = inputNumberoftickets;
let formform = document.getElementById("ticketformular");
let text = "";
for (i = 1; i <= y; i++) {
document.getElementById("dynamicInput").innerHTML = text += 'Ticket ' + i + "<br>" +
original.setAttribute("id", ticketformular + i) +
document.getElementById("dynamicInput").appendChild(clone) + "<br>";
This is the result i get:
Ticket 1
undefined[object HTMLInputElement]
Ticket 2
undefined[object HTMLInputElement]
Ticket 3
undefined[object HTMLInputElement]
Did a lot of research but somehow I'm complete stuck.
Even when I set the project input in local storage to define the
field i got no output.
Thanks in advance.
Wish you a nice day.
I'm trying to make a sort of questionnaire/quiz in javascript for my website. The questionnaire is spread on 5 pages, each page has a question. I want to use the GET method so the URL of each page looks something like that:
(I must keep the GET method because I want to use for something else).
First question: http://website.com/quiz/first?q=1
Second question: http://website.com/quiz/second?q=133
Third question: http://website.com/quiz/third?q=133
Fourth question: http://website.com/quiz/fourth?q=1332
Fifth question: http://website.com/quiz/fifth?q=13324
The user lands on the first page --> get a radio input form --> checks one --> gets redirected to the second page --> etc...
The ?q= is a variable containing the answers, for example ?q=133 means the user picked the following answers:
In the first question, he checked the radio input of the value 1
In the second question, he checked the radio input of the value 3
In the third question, he checked the radio input of the value 3
(so 133 means the user check the 1 for the first question, 3 for the second, 3 for the third.)
I managed to make the variables work:
answPre: gets the previous answer from the form GET (?q=1).
answCurrent: gets the radio input checked from the current page.
urlVal: an combination of the two (answPre+answCurrent)
so I'd like urlVal to be the value that gets transferred from a page to the other.
But I don't want to have both urlVal and the "q" value (name of checked radio) in the url.
What's the right thing to do?
can I hide the "q" value from the URL?
or can I "overwrite" the q value and put instead urlVal?
I'm lost and would appreciate any help, thanks for your help and your time!
function displayRadioValue() {
// var pageURL = window.location.href;
var fakeURL="website.com/quiz/first?q=1"
var answPre = fakeURL.substr(fakeURL.lastIndexOf('=') + 1); //get the previous page's answer.
//get the current page's answer
var ele = document.getElementsByName('q');
for(j = 0; j < ele.length; j++) {
if(ele[j].checked)
var answCurrent= document.getElementById("demo2").innerHTML = ele[j].value;
}
var array = [answPre,answCurrent]; //combine answPre + answNew
var urlVal = "";
var i;
for (i = 0; i < array.length; i++) {
urlVal += array[i];
}
document.getElementById("demo1").innerHTML = answPre;
document.getElementById("demo3").innerHTML = urlVal;
//document.getElementById("fquiz").submit();// Form submission
}
<html>
<body>
<h2>second.html</h2>
<b>answPre: </b><span id="demo1"></span><br>
<b>answCurrent: </b><span id="demo2"></span><br>
<b>urlVal: </b><span id="demo3"></span><br>
<!-- <b>final answNew: </b><span id="demo4"></span><br> -->
<hr>
<form id="fquiz" method="GET" action="third.html">
<p>Who are you going with?</p>
<input type="radio" name="q" value="1" id="yes"
onClick="javascript: displayRadioValue()">Solo<br>
<input type="radio" name="q" value="2" id="no"
onClick="javascript: displayRadioValue()">Couple<br>
<input type="radio" name="q" value="3" id="no"
onClick="javascript: displayRadioValue()">Family with kids<br>
<input type="radio" name="q" value="4" id="no"
onClick="javascript: displayRadioValue()">Group of friends<br>
<p>(then it takes you to third.html with hopefully this url: ../third.html?q=XX where XX is urlVal)
</form>
</body>
</html>
I've made a few changes to your code to modernize it a bit.
I moved the binding of the event handlers to the JavaScript from the HTML. Generally speaking I like to keep my HTML about the structure and the JavaScript about the behavior.
I added code to grab the step from the URL in addition to the previous answers.
I used querySelector to retrieve the selected radio button, using the :checked pseudo-selector.
I used join('') on the array of answers to make it easier to read.
In the HTML, I used <p> elements for everything that needed to be in one line, rather than tacking a <br> at the end of each line. That's just a personal preference.
I wrapped the radio buttons and their text in <label> elements. This helps in accessibility and to give a larger target for people to click on (clicking on the entire label checks the radio, rather than just the radio itself).
I also changed the name of the URL parameter to urlVal rather than q, but I'm not sure I understood that part of your question. I'm not using the form submission process at all with this code, relying instead on changing the location directly...
Do note that running the code here on Stack Overflow won't redirect correctly, since of course there's nothing at example.com/quiz/second listening, and Stack Snippets are sandboxed anyway. You'll need to adjust the code for your specific use in any case.
// Use JavaScript to attach event handlers to HTML elements.
document.querySelectorAll('input[name="q"]').forEach(el => el.addEventListener('click', displayRadioValue));
function displayRadioValue() {
// var pageURL = window.location.href;
var fakeURL = "example.com/quiz/first?q=1"
var step = fakeURL.substring(fakeURL.lastIndexOf('/') + 1, fakeURL.indexOf('?'));
var answPre = fakeURL.substr(fakeURL.lastIndexOf('=') + 1); //get the previous page's answer.
//get the current page's answer
// The :checked pseudo-class makes it easier to find the checked radio button
var el = document.querySelector('input[name="q"]:checked');
var answCurrent = document.getElementById("demo2").innerHTML = el.value;
var array = [answPre, answCurrent]; //combine answPre + answNew
// The join method is easier to use than looping.
var urlVal = array.join('');
document.getElementById("demo1").innerHTML = answPre;
document.getElementById("demo3").innerHTML = urlVal;
switch (step) {
case 'first': step = 'second'; break;
case 'second': step = 'third'; break;
case 'third': step = 'final'; break;
default: return;
}
location.href = `example.com/quix/${step}?urlVal=${urlVal}`;
}
.form-group { margin: 0; }
<h2>second.html</h2>
<!-- <br> is a presentational element; better just to split up lines with paragraphs -->
<p class="form-group"><b>answPre: </b><span id="demo1"></span></p>
<p class="form-group"><b>answCurrent: </b><span id="demo2"></span></p>
<p class="form-group"><b>urlVal: </b><span id="demo3"></span></p>
<!-- <p class="form-group"><b>final answNew: </b><span id="demo4"></span></p> -->
<hr>
<form id="fquiz" method="GET" action="third.html">
<p>Who are you going with?</p>
<!-- <br> is a presentational element; better just to split up lines with paragraphs -->
<!-- Always use <label> elements to label form fields -->
<!-- IDs must be unique to a document. They did not appear relevant here. -->
<p class="form-group"><label><input type="radio" name="q" value="1">Solo</label></p>
<p class="form-group"><label><input type="radio" name="q" value="2">Couple</label></p>
<p class="form-group"><label><input type="radio" name="q" value="3">Family with kids</label></p>
<p class="form-group"><label><input type="radio" name="q" value="4">Group of friends</label></p>
<p>(then it takes you to third.html with hopefully this url: ../third.html?q=XX where XX is urlVal)</p>
</form>
I'm just learning HTML, CSS, and Javascript and having a tough time grasping the JS. I've been working on this simple issue now for literally 6 hours. I've checked plenty of posts on SO, W3, re-read relevant chapters in Jon Duckett's book, and tried every combination I could think of in the code.
What I need to do is take a username from an input field and run it through a function to change it in some way. I've seen other's posts with similar questions but haven't been able to create a solution yet. The issue that keeps happening is that when I place what should be the user input back to the page it uses the actual words name.toUpperCase() rather than the value I've given the variable name. I tried converting the name to uppercase in its own statement and then assigning that a variable, but that didn't work either. It seems like my js is never giving "name" a value to begin with.
JS:
var name = document.getElementById('nameEntry');
var compliment = document.getElementById('compliment');
var input = document.getElementById('submitjs');
input.onclick = transformName;
function transformName () {
var elcompliment = document.getElementById('compliment');
elcompliment.textContent = 'name.toUpperCase( )' + ' YOU ROCK!';
};
HTML:
<div class="jsform">
<h2> Enter your name and see it change!</h2>
<input type="text" name="nameEntry" id="nameEntry" />
<input type="submit" name="submitjs" value="submit" id="submitjs"/>
<div>
<p id="compliment">Great Job!</p>
</div>
</div>
Since you are retrieving input value using element's id, there is no need for form.
function transformName () {
var name = document.getElementById('nameEntry').value;
var compliment = document.getElementById('compliment');
compliment.innerHTML = name.toUpperCase( ) + ' YOU ROCK!';
};
<div class="jsform">
<h2> Enter your name and see it change!</h2>
<input type="text" name="nameEntry" id="nameEntry" />
<input type="button" onclick="transformName()" value="Transform me"/>
<div>
<p id="compliment">Great Job!</p>
</div>
</div>
The name variable currently refers to DOM element. The value property returns the data entered in the input element.
The value property sets or returns the value of the value attribute of a text field.
var name = document.getElementById('nameEntry').value;
var compliment = document.getElementById('compliment');
var input = document.getElementById('submitjs');
input.onclick = transformName;
function transformName () {
var name = document.getElementById('nameEntry').value;
var elcompliment = document.getElementById('compliment');
elcompliment.innerHTML = name.toUpperCase()+' YOU ROCK!';
};
<div class="jsform">
<h2> Enter your name and see it change!</h2>
<input type="text" name="nameEntry" id="nameEntry" />
<input type="submit" name="submitjs" value="submit" id="submitjs" />
<div>
<p id="compliment">Great Job!</p>
</div>
</div>
Ok, So I have an html form that is displayed like so:
<span style='required'>*</span> - Indicates required field.
<div class='fields'>Swiped Information</div>
<input type=text name='swiped' id='swiped'>
</div>
<div class='fields'>First Name</div>
<input type=text name='first_name' id='first_name'><span style='required'>*</span>
</div>
<div class='fields'>Last Name</div>
<input type=text name='last_name' id='last_name'><span style='required'>*</span>
</div>
<div class='fields'>Expiration</div>
<input type=text size=8 name='expiration' id='expiration'><span style='required'>*</span>(MMYY)
</div>
<div class='fields'>CVV Code</div>
<input type=text size=8 name='cvv' id='cvv'><span style='required'>*</span>
</div>
<div class='fields'>Credit Card Number</div>
<input type=text name='card' id='card'><span style='required'>*</span>
</div>
<hr>
<div class='buttons'></div>
<a onclick="readCard();" style="cursor:pointer; color:red;">Swipe Credit Card</a>
</div>
My knowledge of this kind of stuff is very poor. I have a basic little Credit Card Reader that plugs into my computer via USB. I am wanting to be able to swipe a credit card and have my website parse the information into the form fields that are above.
I have added an onclick=readCard(); event to a link below my form and when that is pushed java script is initiated to put focus on the Swiped Information field which will store the string of data from the magnetic stripe reader.
function readCard () {
document.getElementById('swiped').focus();
}
My thoughts would be that the employee would hit "Swipe Credit Card" which would make the Swiped Card Information field have focus and would fill that field with the string, then the javascript would break that information up into pieces and fill the form accordingly.
I have searched high and low to try and find a solution and the closest I could come was a tutorial that used asp.net as the language and I can't do that. Either PHP or JavaScript. Thanks in advance.
All I need to do is break that long string up into multiple and display the appropriate parts in the html form.
P.S. I'm not worried about form validation ATM, I will be taking care of that after I manage to make it fill the form fields! Thanks!
UPDATE:
I created a JSFiddle although the java script I put in doesn't appear to be working.
http://jsfiddle.net/r8FJX/
UPDATE:
As per the comments below, I have added an example of the data sent from my card reader to the computer. I went in and replaced every number in the string with randomly typed fake numbers and replaced my name with a fake one. (Sorry scammers!)
%B6545461234613451^DOE/JOHN^00000000000000000000000?;6545461234613451=984651465116111?
I am assuming this how the code above is laid out, I can't find any documentation:
%Bcardnumber^lastname/firstname^expDate?;cardnumber=expDate?
Option 1)
var card_data = "%B6545461234613451^DOE/JOHN^00000000000000000000000?;6545461234613451=984651465116111?"
var details1 = card_data.split("^");
var card_number = details1[0];
card_number = card_number.substring(2);
var names = details1[1].split("/");
var first_name = names[1];
var last_name = names[0];
var details2 = details1[2].split(";");
details2 = details2[1].split("=");
var exp_date = details2[1];
exp_date = exp_date.substring(0, exp_date.length - 1);
exp_date = exp_date.substring(2, 3) + "/" + exp_date.substring(0,1);
Option 2)
var pattern=new RegExp("^\%B(\d+)\^(\w+)\/(\w+)\^\d+\?;\d+=(\d\d)(\d\d)\d+$");
var match = pattern.exec(card_data);
card_number = match[1];
first_name = match[3];
last_name = match[2];
exp_date = match[5] + "/" + match[4];
Then Do:
document.getElementById("first_name").value = first_name;
document.getElementById("last_name").value = last_name;
document.getElementById("card").value = card_number;
document.getElementById("expiry").value = exp_date;
I had success with the follow for expiration date:
exp_date = exp_date.substring(2, 4) + "/" + exp_date.substring(1, 3);
Just For Future viewers like myself that was searching. The expiry needed to be adjusted. This will make the expiry look like... 10/18. Not 10/81 like I was getting...
Below shows the corrected formatted date of ex: 10/18 not 10/81 or 1/1
exp_date = exp_date.substring(2, 4) + "/" + exp_date.substring(0,2);
(For future people trying to parse USB credit card reader data)
There are two (sometimes 3) tracks of data, they are separated with ?. The expiry date is duplicated on the first track and the second track. If you want to read enough data to charge a credit card you can ignore the Track 2 data (everything from the ; onwards).
The CVC is not stored on the magnetic stripe data. You'll have to disable the CVC check in your payment processor. With Stripe you can do it at https://dashboard.stripe.com/radar/rules.
let parse = readerData => {
let card = readerData.match(/%B([0-9]+)\^([A-Z /.]+)\/([A-Z /.]*)\^([0-9]{2})([0-9]{2})/);
let lastName = card[2].trim();
// 'LASTNAME/FIRSTNAME.MR' is possible
let firstName = card[3].trim().split('.')[0];
let fullName = `${firstName} ${lastName}`;
return {
exp_month: card[5],
exp_year: card[4],
number: card[1],
name: fullName,
};
}
parse('%B6545461234613451^DOE/JOHN^21040000000000000000000?;this part does not matter')
// {exp_month: "04", exp_year: "21", number: "6545461234613451", name: "JOHN DOE"}
If you're using Stripe.js v2 you can pass the object returned by parse() directly to Stripe.card.createToken().
I've seen LASTNAME/FIRSTNAME MIDDLENAME in sample data, this code should turn that into FIRST MIDDLE LAST.
Read https://en.wikipedia.org/wiki/Magnetic_stripe_card#Financial_cards for more info.
I don't know if doing this is legal. Newer USB credit card readers encrypt the data they read (you have to send the data to their api (and pay them) to decrypt it).
If you're having issues with the regex try https://regex101.com/ for debugging it.