I have an input form which looks like this:
<input type="number" value="0.00" step="0.05">
I found the step function which technically solves my increment problem changing it to 0.05 instead of the default 1. I have however not found a solution where I can change the increment without changing the valid inputs.
The input can take any number but the most common values will be in increments of 0.05. Is there a work-around for this? A solution using JavaScript is also more than welcome.
Thank you very much!
EDIT:
Adding nonvalidateto the html form-tag solved this for me. Now pressing the buttons use the increments I want but when I need to specify more accurately than the steps the form still accepts the values.
<form action="/run" novalidate>
<input type="number" value="0.00" step="0.05">
<input type="submit">
</form>
Using novalidate in the form tag will get rid of the validation for the whole form but keep the increments implemented by step.
Update
"I did add nonvalidate to the form tag. It let's me do what I want as of now but it might not be the best solution."
If you don't want your form "compromised" by novalidate, then have 2 forms:
Form A [No action or method]
All user interaction and calculations are here.
All inputs can be modified without worrying about built-in validation from the form.
Form B [Set action and method optional target]
The submit button resides within
Add a hidden input for each value on Form A you want to submit and ensure each has a name attribute and value.
Any client-side validation should be done here.
With that setup you'll need an event like onbeforesubmit so the values of Form A can transfer over to Form B before it submits to the server. Unfortunately I don't think it exist as a standard, but to emulate it is simple:
formA.onsubmit = b4Submit;
function b4Submit(event) {
hidden_Input_In_FormA.value = number_Input_With_Crazy_Step_In_FormA.value
return true;
}
So this contrived example shows an event handler that gets the value from one form then stores it in the other form. Next it continues by submitting whatever data it has. This is due to the callback returning true, should false be returned, the callback function itself dies and so does the submit event along with it.
The Demo has been updated to do what was just described above. Note: there are no novalidate attributes in use. The second form (Form B or form#tx) is sending text from a hidden input as far as it's concerned. A number like -103.002684109 is not valid if it's from an <input type='number'> but from a text or hidden input, it is just text (although I believe the actual data in most form controls is actually a string not a number).
"The input can take any number but the most common values will be in increments of 0.05. Is there a work-around for this? A solution using JavaScript is also more than welcome."
You can change any attribute you want on any tag AFAIK. Programatically the syntax is simple with Plain JavaScript:
Object.property = "string"
Object: a referenced <element> tag
property: when you reference an standard attribute like a property it's becomes a property.
string: the value must be a string
Here's a basic way of changing a standard attribute programmatically:
var obj = document.querySelector('a');
obj.href = "https://google.com"; //
The following Demo uses:
Document.Forms
HTMLFormElement.elements
HTMLFormControlsCollection
Dot Notation
Demo
Demo can send to a live test server the response is sent to an iframe to view
var ui = document.forms.ui;
var tx = document.forms.tx;
var u = ui.elements;
var x = tx.elements;
var D = u.digit;
var C = x.cache;
var lo = u.min;
var hi = u.max;
var inc = u.step; // I think this what you specificly
var t = u.type;
var chg = u.change;
chg.onclick = chgAttr;
tx.onsubmit = cacheVal;
function chgAttr(e) {
D.min = lo.value;
D.max = hi.value;
D.step = inc.value;
D.type = t.value;
}
function cacheVal(e) {
C.value = D.value;
return true;
}
body {
font: 400 16px/1.5 'Consolas'
}
#digit {
margin-right: 15px;
}
input,
output,
button,
select,
option,
label {
display: inline-block;
font: inherit
}
select {
padding: 3px 5px
}
[type='submit'] {
float: right;
}
<!doctype html>
<html>
<head>
<title></title>
<meta charset='utf-8'>
<style></style>
</head>
<body>
<form id='ui' oninput='out.value = digit.value'>
<fieldset>
<legend>Click Button to Change Input</legend>
<input id='digit' min='' max='' step='' type='number'>
<button id='change' type='button'>CHANGE</button>
<output id='out' for='digit'></output>
</fieldset>
<fieldset>
<legend>Attribute Adjustments</legend>
<input id='min' min='-2147483648' max='2147483648' type='number' placeholder='min'>
<input id='max' min='-2147483648' max='2147483648' type='number' placeholder='max'>
<input id='step' type='number' placeholder='step'>
<label for='type'>Type:
<select id='type'>
<option>number</option>
<option>text</option>
<option>range</option>
<option>hidden</option>
<option>color</option>
<option>time</option>
</select>
</label>
</fieldset>
</form>
<form id='tx' action='https://httpbin.org/post' method='post' target='response'>
<input id='cache' name='cache' type='hidden'>
<input type='submit'>
</form>
<iframe src='about:blank' name='response'></iframe>
<script></script>
</body>
</html>
Related
I have a login form on a modal jquery dialog with the usual 2 text INPUTs. When I enter a login name and password then click the submit, the call back function is called.
The first thing the callback does is try to extract the values of the two INPUTs, but the values returned are empty strings (I have a breakpont here, and have even stepped through the jquery processing of the objects - they objects are correctly identified as the fields on the form, but value="" for both).
At this point I can still see the values in the form, and when the callback exits and the focus goes back to the form, the values are still in the INPUTS. I also tried .prop("value") rather than .val(), but the result was the same.
I just can't figure why I can't read the values - any help appreciated.
<form id="cp-loginform" action="/cypo/index.php" method="POST" >
<input type="hidden" name="Login" value="Login">
<input type="hidden" name="pp" value="0" />
<input type="text" id="cp-loginname" name = "loginname" placeholder = "Login ID" class="loginforminput cp-width-50" autofocus >
<input type="password" id="cp-password" name = "password" placeholder = "password" class="loginforminput cp-width-50"></p>
<input type="submit" id="cp-submit" name = "submit" onclick="ProcessLogin()" ></p>
</form>
function ProcessLogin() {
var loginval = $("#cp-loginname").val();
var passwordval = $("#cp-password").val();
console.log(loginval.concat(" ",passwordval));
}
PROBLEM RESOLVED:
I felt that this was a scope issue. The form itself was obviously OK (if submitted from the dialog it worked) - it was just the attempt to check the INPUT values using jquery that wasn't working.
I found that my select had to start with the dialog element and include a descendent path to my INPUTs. It's as if the dialog puts a wrapper around the elements inside so they are no longer visible as owned by the document.
If I login with xxx and zzz and step therough the following code I see this:
var loginval = $("#cploginname").val(); << = ""
var passwordval = $("#cppassword").val(); << = ""
var loginval = $("#cp-loginform #cploginname").val(); << = ""
var passwordval = $("#cp-loginform #cppassword").val(); << = ""
var loginval = $("#cpdialog #cp-loginform #cploginname").val(); << = "xxx"
var passwordval = $("#cpdialog #cp-loginform #cppassword").val(); << = "zzz"
console.log(loginval.concat(" ",passwordval));
I can't say I understand what's going on, but I have a solution so I am happy. Thanks to all who answered.
FINAL WORD
Thanks to #CMedina, I now understand. The form was defined in a hidden DIV at the top of my BODY section, and I passed $("#loginform") to a f() that created the dialog. The dialog was added to the DOM just before the . I had missed the fact that my original form was still in the DOM, so I was referencing that, not the dialog copy. When I included the dialog wrapper in the path, I finally 'found' the second copy.
Your button is the type submit (their natural behavior is to send the form). Remove the onclick in your button html.
<input type="submit" id="cp-submit" name = "submit">
You must add preventDefault to prevent submit the form and do what you want. Add the code JS for the button onclick event
$("#cp-submit").on("click", function(e){
e.preventDefault();
var loginval = $("#cp-loginname").val();
var passwordval = $("#cp-password").val();
console.log(loginval.concat(" ",passwordval));
});
Result: https://jsfiddle.net/cmedina/svjqb2a4/
Try it :
<html>
<head>
</head>
<body>
<form id="cp-loginform" action="/cypo/index.php" method="POST">
<input type="hidden" name="Login" value="Login">
<input type="hidden" name="pp" value="0" />
<input type="text" id="cp-loginname" name = "loginname" placeholder = "Login ID" class="loginforminput cp-width-50" autofocus >
<input type="password" id="cp-password" name = "password" placeholder = "password" class="loginforminput cp-width-50">
<input type="submit" id="cp-submit" name ="submit" onclick="ProcessLogin(event)">
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
function ProcessLogin(e) {
e.preventDefault();
var loginval = $("#cp-loginname").val();
var passwordval = $("#cp-password").val();
alert(loginval.concat(" ",passwordval));
}
</script>
</body>
</html>
Very new to JavaScript/HTML, help!
I have 2 text boxes and a submit button. I am trying to retrieve the data from each of them using JavaScript and for the time being, simply put them into an alert box.
However, on clicking the button, the alert just reads 'undefined', help!
Here's a code snippet:
function submitApp() {
var authValue = document.getElementsByName("appAuthor").value;
var titleValue = document.getElementsByName("appTitle").value;
alert(authValue);
}
<input type="text" name="appAuthor" size="" maxlength="30" />
<input type="text" name="appTitle" maxlength="30" />
<input type="button" value="Submit my Application!" onclick="submitApp()" />
getElementsByName() returns a list. So you can grab the first item in the list:
document.getElementsByName("appAuthor")[0].value
.getElementsByName() method returns an array-like node list, so you'll need to specify an index in order to retrieve a specific input's value (because the value property only applies to DOM elements, not an entire list).
function submitApp() {
var authValue = document.getElementsByName("appAuthor")[0].value;
var titleValue = document.getElementsByName("appTitle")[0].value;
alert(authValue);
}
Just add this jQuery to a document.ready section like this:
$(document).ready(function() {
$('#submit').on('submit', function(e) {
e.preventDefault();
submitApp();
});
function submitApp() {
var authValue = document.getElementsByName("appAuthor")[0].value;
var titleValue = document.getElementsByName("appTitle")[0].value;
alert(authValue);
}
});
<input type="submit" id="submit" value="Submit my Application!">
If you want to submit the form remove the e.preventDefault();, but if you just want the value updated keep it in there to prevent form submition.
You could potentially change the button type into a submit-type and do something like this:
$('body').find('form').on('submit', function(e){
e.preventDefault();
var authValue = $('input[name="appAuthor"]').val();
var titleValue = $('input[name="appTitle"]').val();
//...here do whatever you like with that information
//Below empty the input
$('input').val('');
})
Or just interpret the form as an array to make your life easier and clean the code up.
When you use getElementsByName or getElementsByClassName, it returns array of elements, so you should put index to access each element.
authValue = document.getElementsByName("appAuthor")[0].value;
I'd like to be able to find the number value of the courseAmount input field upon submit, and then generate new input fields (into the hourForm form underneath the initialForm) through the onsubmit method in javascript, and then retrieve the value from each of the generated input fields upon the submission of the hourForm form and place those values into an array.
However, I'm having difficulty with actually generating the input fields with javascript, and I suspect that I'm having difficulty with retrieving the value of the courseAmount input and porting that to my createInput() function, but I'm not exactly sure if that's the issue.
Here's my HTML:
<!DOCTYPE html>
<head>
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<form id="initialForm" method="post" onsubmit="createInput()" action="">
<label>Number of hours for which you would like to study</label>
<input type="number" name="overallHours" id="overallHours" class="stored" min="1" max="20" step="1" value="1"/>
<label>Number of courses you would like to study for</label>
<input type="number" name="courseAmount" id="courseAmount" class="stored" min="1" max="20" step="1" value="1"/>
<input type="submit" class="submitStudy" value="Submit"/>
</form>
<form id="hourForm" method="post" onsubmit="calcHours">
<label>State the desired time spent working in each course</label>
</form>
</body>
And here's my Javascript:
var notedOverallHours = document.getElementById("overallHours").value * 60;
var courseNumberTotal = document.getElementById("courseAmount").value;
var counter = 0;
function createInput() {
var newForm = document.getElementById("hourForm");
document.getElementById("initialForm").style.display = "none";
document.getElementById("hourForm").style.display = "block";
for (i = 0; i <= courseNumberTotal; i++) {
newForm.innerHTML = "<label>Course #" + (counter + 1) + "</label>" + "<input type='number' name='courseHours' class='newInputs' min='1' max='9' step='1' value='1'/>";
counter++;
}
newForm.innerHTML = "<input type='submit' value='submit'/>";
}
Can someone help me figure this Javascript out? My JSFiddle attempts have been futile because JSFiddle does not take kindly to forms reloading the page.
Thank you!
From the mdn page about innerHTML: "Removes all of element's children, parses the content string and assigns the resulting nodes as children of the element." https://developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML
Generally speaking you do not want to use innerHTML at all. There is almost always a better approach. In this case this will be createElement and appendChild.
Furthermore, there is no such thing as "onsubmit" method. What you are calling like that is an HTML attribute which registers a handler for the submit event. http://www.quirksmode.org/js/introevents.html
However using html attributes has its serious drawbacks: http://www.quirksmode.org/js/events_advanced.html
Considering all that, here is what I would do: http://jsfiddle.net/ashnur/rwod4z1d/
HTML:
<form id="initialForm" method="post" action="">
<label>Number of hours for which you would like to study</label>
<input type="number" name="overallHours" id="overallHours" class="stored" min="1" max="20" step="1" value="1" /><hr>
<label>Number of courses you would like to study for</label>
<input type="number" name="courseAmount" id="courseAmount" class="stored" min="1" max="20" step="1" value="1" /><hr>
<input type="submit" class="submitStudy" value="Submit" />
</form>
<form id="hourForm" method="post" >
<label>State the desired time spent working in each course</label><hr>
</form>
js:
var notedOverallHours = document.getElementById("overallHours").value * 60;
var courseNumberTotal = document.getElementById("courseAmount").value;
var counter = 0;
var initialForm = document.getElementById("initialForm");
var hourForm = document.getElementById("hourForm");
initialForm.addEventListener('submit', createInput);
hourForm.addEventListener('submit', calcHours);
function calcHours() {}
function createInput(ev) {
ev.preventDefault(); // this is not needed if you are using a bare button and the click event
var newForm = document.getElementById("hourForm");
initialForm.style.display = "none";
hourForm.style.display = "block";
for (i = 0; i <= courseNumberTotal; i++) {
addControl(newForm, "Course #" + (counter + 1));
counter++;
}
var submit = document.createElement('input');
submit.type = 'submit';
submit.value = 'submit';
newForm.appendChild(submit);
}
function addControl(form, labelText) {
var label = document.createElement('label');
var input = document.createElement('input');
var hr = document.createElement('hr');
input.type = 'number';
input.name = 'courseHours';
input.classname = 'newInputs';
input.min = '1';
input.max = '9';
input.step = '1';
input.value = '1';
label.textContent = labelText;
form.appendChild(label);
form.appendChild(input);
form.appendChild(hr);
}
As Tobias correctly pointed out, your form submission event is allowed to continue which results in a page refresh and a "reset" of all plain JavaScript data. Furthermore, you are not capturing your values (notedOverallHours and courseNumberTotal) on form submission (after the user has entered an amount), but rather when your page initializes (before the user has input anything).
So, to go about fixing this, first a tiny modification to your HTML:
...
<form id="initialForm" method="post" action="">
...
Notice that I deleted the onsubmit attribute from your form. We can capture that with an event in JavaScript itself.
Next attach an event listener to your form which prevents it from submitting and calls your createInput() function:
document.getElementById("initialForm").addEventListener('submit', function (e) {
e.preventDefault();
createInput();
});
This will attach an eventListener that listens to the submit event on your initialForm element. The first parameter is the type of event you want to listen for (submit in this case), the second is the callback you want to have fired.
The callback function always gets the event passed in (the e argument). By calling preventDefault on this event we can stop it from bubbling up and actually causing a page refresh.
Next we call the createInput() function which, after some modifications, looks like this:
function createInput() {
var notedOverallHours = document.getElementById("overallHours").value * 60;
var courseNumberTotal = document.getElementById("courseAmount").value;
var newForm = document.getElementById("hourForm");
document.getElementById("initialForm").style.display = "none";
document.getElementById("hourForm").style.display = "block";
// Add our elements
for (i = 1; i <= courseNumberTotal; i++) {
var child = document.createElement('li');
child.innerHTML = "<label>Course #" + (i) + "</label>" + "<input type='number' name='courseHours-"+ i+"' class='newInputs' min='1' max='9' step='1' value='1'/>";
newForm.appendChild(child);
}
// Add our button
var button = document.createElement('li');
button.innerHTML = "<input type='submit' value='submit'/>";
newForm.appendChild(button);
}
As you can see, I capture the notedOverallHours and courseNumberTotal variables inside the createInput() function, so they will carry whichever value was set during the form submission event.
Then we iterate over each course number. Instead of replacing the innerHTML, we first create an element (li in our case) and fill that element with a HTML string. Next we append this child element to the parent form.
Inside the loop I have removed the counter variable as you can simply use the value of i inside the loop, no need to create an extra variable. I also appended the name attribute for each child with i, so not to get any name clashes.
At the end of our function we simply create and append a new li element containing the submit button.
You can optimize this further by actually creating the label and input elements with the createElement function and set its attributes and text individually with plain JavaScript setters, instead of dumping everything inside li elements as I've done here to keeps things a bit more simple for now. I`ll leave that up as an exercise :)
I have created a rough JSFiddle with this exact code here.
When the createInput() function is called you are not having the desired results because you are reseting the newForm.innerHTML in each iteration of the loop and then again at the end. Rather than using = you should be using += to append the desired text rather than replace the existing text.
// Replacing the contents of newForm.innerHTML
newForm.innerHTML = "foo";
// Appending to newForm.innderHTML (You want to do this)
newForm.innerHTML += "foo";
Another problem is that when you press submit the page is reloading before createInput() is able to have the desired result. You most likely want to stop the page actually submitting and thus reloading when you press the submit button. To do this you can change the onsubmit attribute for the form to "return createInput()" and then add the line return false; to the end of the createInput() function to indicate to the browser that you do not wish to submit the form.
I'm having some trouble with getting Javascript to pass a value (which is stored in local storage) into a textfield. Ideally, I'd like for someone to be able to click the 'apply here' button on one page, have the job number stored in local storage and then have it auto-populate the job number field on my application page with the job number.
This is what I've got so far, I have a feeling that I haven't assigned things correctly.
html (on submit page)
<p>
<form id="applyjob1" action="enquire.html" method="get">
<input type="submit" id="job1" value="Apply for Job" />
</form>
</p>
html (field I'm trying to put data into)
Job Reference Number <input required="required" id="jobNo" name="jobno" type="text" /> </br />
Javascript
window.onload = function init() {
var jobID = document.getElementById("job"); /*button name */
jobID.onsubmit = passJob; /*executes passJob function */
}
function passJob(){
var jobSubmit = localstorage.jobID("1984"); /*assigns localstorage*/
if (jobSubmit != undefined){
document.getElementById("jobNo").value = localstorage.jobID;
}
I think this code would work for your fuction.
function passJob(){
localStorage.setItem("jobID", "1984");
if (localStorage.jobID != undefined) {
document.getElementById("jobNo").value = localStorage.jobID;
}
}
You are assigning the jobSubmit wrongly. To set item, use localStorage.setItem('key', value). Note the casing as it matters.
So basically you should do
var jobSubmit = localStorage.setItem(,"jobID", "1984"); // assigns jobSubmit
And I don't see any element with id="job"
I have the following function:
function updateInput(ish){
document.getElementById("BetAmount").value = ish;
}
I have the following HTML inputs:
<input class="defaultText" type="number" name="BetAmount" id="BetAmount" onchange="updateInput(this.value)">
<input type="number" name="PotentialGain" id="PotentialGain" />
When users enter in a bet amount number(BetAmount), I would like to instantly show a calculated PotentialGain, which, for example, can be found by multiplying a constant by the specified bet amount entered in by the user.
I'm not very familiar with JavaScript, so any help is greatly appreciated!
Your code is almost correct - you are showing the result in the BetAmount field so no change is visible.
Change your code to:
document.getElementById("PotentialGain").value = ish;
Here's a working demo. I changed the event to onkeyup as onchange only happens on blur - i.e. when a field loses focus.
Here is the final JQuery function that I used.
function changeBet(bet) {
var moneyline = <?php echo json_encode($win) ?>;
var gain = moneyline * bet;
document.getElementById("PotentialGain").value = gain;
}
Along with these inputs:
<input type="text" name="BetAmount[]" id="BetAmount" onkeyup="changeBet(this.value);" >
<input type="number" name="PotentialGain" id="PotentialGain" />