getElementById is returning null - javascript

I'm attempting to read in a file using this form in my :
<form name="UploadForm" method="post">
<input type="hidden" name="MAX_FILE_SIZE" value="100000" />
Choose a CSV file to upload: <input name="upload_file" type="file" /><br />
<input type="submit" value="Upload" onClick="uploadFile()" />
</form>
But when I go to read the value in this function within I receive a "cannon find "elements" of null error:
function uploadFile() {
var file = document.getElementById('UploadForm').elements['upload_file'].value;
var allTextLines = file.split(/\r\n|\n/);
var headers = allTextLines[0].split(',');
var lines = [];
for (var i=1; i<allTextLines.length; i++) {
var data = allTextLines[i].split(',');
if (data.length == headers.length) {
var tarr = [];
for (var j=0; j<headers.length; j++) {
tarr.push(headers[j]+":"+data[j]);
}
lines.push(tarr);
}
}
alert(lines);
};
Does anybody have any ideas as to what I'm doing wrong?

getElementById returns the element with the specified id, but the form doesn't have an id at all. You are using the obsolete name attribute (which was superseded by id when HTML 4 was released in 1998).
Change it to:
<form id="UploadForm" method="post">
(N.B. name is not obsolete on form controls, such as input and select)
Note that your event handler isn't cancelling the default behaviour of the submit button. So as well as running the JS, you will immediately submit the form, leave the page, and cancel the JS (if it does anything asynchronous, which the name suggests it will be).
If you are going to use intrinsic event attributes, then you need to return false if the JavaScript succeeds.
I recommend giving them up in favour of addEventListener though.

Change your input tag to be like this:
<input name="upload_file" id="upload_file" type="file" />
Also change this line from:
document.getElementById('UploadForm').elements['upload_file'].value
to
document.getElementById('upload_file').value

Related

Jquery not returning the values in form INPUTs

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>

IsNullOrEmpty attribute

In HTML exists
required
attribute, which force user to enter some date before submit. But user can type only spaces. Is there attribute which check is typed content is whitespace before postback. In need attibute which works similar to string.IsNullOrWhitespace in c#.
It took me a while to get the Regex right, but the following creates a rule to only select if there's no whitespace:
<input type="text" pattern=".\S*" />
As #Paul S. noted, this isn't checking the first character, so the following will do that:
<input type="text" pattern="^.\S*" />
Also, this does indeed only work in HTML5 browsers, but since the question contained required, I'm assuming there if is some fallback kept in mind.
Using the pattern attribute, you can make it accept only spaces
<form action="?" method="post"> <!-- required for snippet -->
<input type="text" required pattern="\s*"/>
</form>
However, please note that required prevents the submission of empty input (i.e. your "null"), so to permit that remove required so that pattern is doing the requirement checking
<form action="?" method="post"> <!-- required for snippet -->
<input type="text" pattern="\s*"/>
</form>
Lastly, still perform validation on the server as you can never assume a client is a safe source, or conversely, always assume the client is trying to hack you
If you can't assume HTML 5 support, you can shim the behaviour using JavaScript, which would look something like this for required
if(!('required' in document.createElement('input'))) {
window.addEventListener('submit', function (e) {
var form = e.target,
inputs = form.getElementsByTagName('input'),
i;
for (i = 0; i < inputs.length; ++i)
if (inputs[i].getAttribute('required'))
if (!inputs[i].value)
e.preventDefault(); // + warn?
});
}
and for pattern
if(!('pattern' in document.createElement('input'))) {
window.addEventListener('submit', function (e) {
var form = e.target,
inputs = form.getElementsByTagName('input'),
i,
re;
for (i = 0; i < inputs.length; ++i)
if (re = inputs[i].getAttribute('pattern')) {
re = new RegExp('^' + re + '$');
if (!re.test(inputs[i].value))
e.preventDefault(); // + warn?
}
});
}
You could also set useCapture to true for the listener to skip ahead in the queue of handlers, letting you prevent the event reaching other handlers in the case of submission prevented
<
<form onsubmit="alert('Submitted.');return false;"> <input type="text" required="" pattern="(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))" value="" name="dates_pattern2" id="dates_pattern2" list="dates_pattern2_datalist" placeholder="Try it out." autocomplete="off"> <input type="submit" value="»"> <datalist id="dates_pattern2_datalist"> </datalist> </form>

Check if html form values are empty using Javascript

I want to check a form if the input values are empty, but I'm not sure of the best way to do it, so I tried this:
Javascript:
function checkform()
{
if (document.getElementById("promotioncode").value == "")
{
// something is wrong
alert('There is a problem with the first field');
return false;
}
return true;
}
html:
<form id="orderForm" onSubmit="return checkform()">
<input name="promotioncode" id="promotioncode" type="text" />
<input name="price" id="price" type="text" value="€ 15,00" readonly="readonly"/>
<input class="submit" type="submit" value="Submit"/>
</form>
Does anybody have an idea or a better solution?
Adding the required attribute is a great way for modern browsers. However, you most likely need to support older browsers as well. This JavaScript will:
Validate that every required input (within the form being submitted) is filled out.
Only provide the alert behavior if the browser doesn't already support the required attribute.
JavaScript :
function checkform(form) {
// get all the inputs within the submitted form
var inputs = form.getElementsByTagName('input');
for (var i = 0; i < inputs.length; i++) {
// only validate the inputs that have the required attribute
if(inputs[i].hasAttribute("required")){
if(inputs[i].value == ""){
// found an empty field that is required
alert("Please fill all required fields");
return false;
}
}
}
return true;
}
Be sure to add this to the checkform function, no need to check inputs that are not being submitted.
<form id="orderForm" onsubmit="return checkform(this)">
<input name="promotioncode" id="promotioncode" type="text" required />
<input name="price" id="price" type="text" value="€ 15,00" readonly="readonly"/>
<input class="submit" type="submit" value="Submit"/>
</form>
Depending on which browsers you're planning to support, you could use the HTML5 required attribute and forego the JS.
<input name="promotioncode" id="promotioncode" type="text" required />
Fiddle.
Demo: http://jsfiddle.net/techsin/tnJ7H/4/#
var form = document.getElementById('orderForm'),
inputs=[], ids= ['price','promotioncode'];
//findInputs
fi(form);
//main logic is here
form.onsubmit = function(e){
var c=true;
inputs.forEach(function(e){ if(!e.value) {c=false; return c;} });
if(!c) e.preventDefault();
};
//findInputs function
function fi(x){
var f = x.children,l=f.length;
while (l) {
ids.forEach(function(i){if(f[l-1].id == i) inputs.push(f[l-1]); });
l--;
}
}
Explanation:
To stop submit process you use event.preventDefault. Event is the parameter that gets passed to the function onsubmit event. It could be in html or addeventlistner.
To begin submit you have to stop prevent default from executing.
You can break forEach loop by retuning false only. Not using break; as with normal loops..
i have put id array where you can put names of elements that this forum would check if they are empty or not.
find input method simply goes over the child elements of form element and see if their id has been metnioned in id array. if it's then it adds that element to inputs which is later checked if there is a value in it before submitting. And if there isn't it calls prevent default.

Clone form and increment ID

Consider the following form:
<form>
<input type="button" value="Input Button"/>
<input type="checkbox" />
<input type="file" id="file"/>
<input type="hidden" id="hidden"/>
<input type="image" id="image" />
<input type="password" id="password" />
<input type="radio" id="radio" />
<input type="reset" id="reset" />
</form>
Utilizing Javascript (and jQuery), what would be the easiest way to clone the entire form and increment each individual id within, to ensure uniqueness.
Using jQuery I would assume you would clone the form initially via clone() and iterate through the cloned objects id and add the new id fieldname1, fieldname2 etc. However, my knowledge of jQuery isn't too great and this project is almost killing me.
Any help would be great!
You would clone() it, and before attaching the cloned element to the DOM, you'd run through and add the number to each id attribute.
(function() {
var count = 0;
window.duplicateForm = function()
var source = $('form:first'),
clone = source.clone();
clone.find(':input').attr('id', function(i, val) {
return val + count;
});
clone.appendTo('body');
count++;
};
})();
jsFiddle.
This one starts with 0, but you could easily start count with 1.
You could also use a closure if you wanted, i.e.
var cloneForm = function(form, start) {
start = start || 0;
return function() {
var clone = form.clone();
clone.find(':input').attr('id', function(i, val) {
return val + start;
});
start++;
return clone;
};
};
Then you would do...
var cloneContactForm = cloneForm($('#contact-form'), 5);
// Now I want to clone it and put it somewhere.
$(cloneContactForm()).appendTo('body');
jsFiddle.
Here's a solution without updating any ids:
Give all forms the same class
Give all fields a name
Refer to cloned forms relative to all the forms with the class
Refer to fields with their name
Example:
How about giving each cloned form a different id, and then using names for each input element?
<form class="theForm">
<input type="password" name="password" />
</form>
Then Clone it with
container.append($('.theForm:first').clone());
(or cache the first form in a variable).
Finally, access the input fields with:
$('form.theForm:eq(0) [name=password]') // password from first form
$('form.theForm:eq(1) [name=password]') // password from second form
...
If the selector lookup efficiency is a factor here then there are several trivial ways to speed it up, such as caching variables with the different forms, caching $('.theForm') and using the eq() method, etc.
Sample jsFiddle is here: http://jsfiddle.net/orip/dX4sY

click() a button named 'submit' in Javascript

I have this HTML:
<input type="submit" name="submit" value="Invoeren" accesskey="s" class="buttons"/>
I'd like to click() it. I can not change anything on the HTML-side. When I do getElementById("submit").click(), I get this:
>>> document.getElementById("submit").click();
Cannot convert 'document.getElementById("submit")' to object
Any hints?
NOTE: NEVER call anything in a form "submit"! It will hide the form's submit event from script.
You have many ways of accessing the button
document.querySelector("[name=submit]").click(); // first named button
document.querySelector("#form [name=submit]").click(); // in form with id="form"
Old IEs would shadow the name so you could use getElementById on a name but it is not recommended.
Older methods:
document.getElementsByName("submit")[0].click();
where 0 is the first element on the page named submit.
document.forms[0].elements[0].click();
where forms[0] is the first form and elements[0] is the first element
or
document.getElementsByTagName("form")[0].elements[0].click();
where ("form")[0] is the first form on the page and elements[0] is the first element
Since you can't edit the actual HTML (to add the id attribute), and you want this to be cross-browser, you could loop over all of the input elements and check the type and value attributes until it matches your submit button:
function get_submit_button() {
var inputs = document.getElementsByTagName('INPUT');
for(var i=0; i < inputs.length; i++) {
var inp = inputs[i];
if(inp.type != 'submit') continue;
if(inp.value == 'Invoeren' && inp.name == 'submit') {
return inp;
break; // exits the loop
}
}
return false;
}
function click_submit() {
var inp = get_submit_button();
if(inp) inp.click();
}
You are using getElementById but you don't have an id attribute on your input. Just because IE totally fubars the namespace and treats name attributes somewhat like id attributes does not mean that you should.
<input id="submit" ... />
...
document.getElementById('submit').click();
The immediate issue i can see is that you have NOT assigned id submit to your input, so this won't work:
document.getElementById("submit").........
unless you specify the id as well:
<input id="submit" type="submit" name="submit" value="Invoeren" accesskey="s" class="buttons"/>
There is no element with the ID "submit" -- you have an element named "submit". As Dylan points out, jQuery would make everything easier, but you can fix it yourself. If you cannot change the HTML, do something like this:
var buttons = document.getElementsByTagName("submit");
for (var i=0; i < buttons.length; i++) {
var button = buttons[i];
if (button.getAttribute("name") === "submit") {
button.onclick = whatever ...
Your input has no id attribute so it can't be retrieved by id. Use this instead.
<input id="submit" type="submit" name="submit" value="Invoeren" accesskey="s" class="buttons"/>
You might want to look into jQuery. It makes everything so, so much easier.

Categories