Does javascript cache DOM elements? - javascript

I'm using mootools to toggle the display (and existence) of two DOM elements in one of my forms. Then, I am using javascript to validate the form to make sure that all of the required fields were filled in. The problem is that the the browser seems to be caching the elements. For example, I have html like this:
<input name="inputbox" id="inputbox" type="text" />
<select name="selection" id="selection">...</select>
And the javascript for validation is something like this:
if (form.inputbox != null && form.inputbox.value == "") {
//don't submit form
{
else if (form.selection != null && form.selection.value == 0) {
//don't submit form
}
Now, this works fine when the page is first loaded and the input element has been removed. However, when I click the button that replaces the input element with the select element, from then on the form.inputbox and form.selection in the javascript code contain the respective element as it was in its last state in the DOM - even if it is no longer in the DOM. So is the javascript caching the DOM and not updating the elements when they are removed from the DOM? What is going on here, and, more importantly, how should I go about fixing it?
Edit: I am using mootools to do the removing and replacing of the elements, the documentation for the respective functions can be found here and here.

Evaluating an element by name (form.elementName) when non-existent returns undefined. Evaluating the property value of an object ($('elementId')) returns null. Undefined and null are treated differently.

Well, I can answer the second part of my question now: how to fix it. If you are using mootools, then use the dollar function (or getElementById might work) instead of using form.selection and form.inputbox:
if ($("inputbox") != null && $("inputbox").value == "") {
//don't submit form
{
else if ($("selection") != null && $("selection").value == 0) {
//don't submit form
}
It works, but I don't have an explanation for why the other didn't...

Related

Disambiguate HTML form `action` property from input element with `name="action"`

<form action="theurl"><input name="somethingelse"></form>
<form action="theurl"><input name="action"></form>
// document.forms[0].action == 'theurl'
// document.forms[1].action == '[object HTMLInputElement]'
// document.forms[1].getAttribute('action') == 'theurl'
The first form works as expected.
For the second form, is there a way for document.forms[1].action to refer to the form's action property instead of the input element with name="action"? Obviously getAttribute() will work, but for learning purposes, is there another way to do this?

Change input value or add a new input if it doesn't exist

Background: I need to append certain data to post; similar to what jQuery's ajaxSetup does that for asynchronous requests except I need it for native form submits.
I need to be able to add a couple of form fields to a form before it is submitted, but I want to make sure I don't add duplicate fields in case they're already there (i.e. original submit failed because of validation or something).
At first I thought something like this would be nice and coherent:
$("form").live("submit", function ()
{
var $this = $(this);
($this.find('#stuff') ||
$this.append('<input type="hidden" id="stuff" name="stuff" />'))
.val('some value');
// carry on with the native submit
// this is actually correct, as opposed to $this.submit()
// which would create a loop
this.submit();
});
Meaning look for #stuff, if it's not found create it, then set its value to "some value". However because the result of the .find() is actually a jQuery wrapper, it would be implicitly converted to a true meaning that even if there are no matching elements found, the .append() code would never be executed.
Is there a nice way to tackle this whole "look for an element and create it if it doesn't already exist" scenario?
change $this.find('#stuff') to $this.find('#stuff').length
edit
if you want to be able to all of it in one statement you can do
(
($this.find('#stuff').length && $this.find('#stuff')) ||
$('<input type="hidden" id="stuff" name="stuff" />').appendTo($this)
).val('some val');
To keep checking logic readable one would expand the conditional:
if ($this.find('#stuff').length) {
$this.find('#stuff').val('some val');
} else {
$this.append('<input type="hidden" id="stuff'" name="stuff" value="some val" />');
}
Alternatively one could just remove and re-add the element... I know, "dom operations are expensive" but if there are several fields to be operated on it's just so much prettier this way:
$this.find('#stuff', '#stuff2', ...).remove()
.append('<input type="hidden" id="stuff" name="stuff" value="some val" />...');

javascript/jquery- how to check, if an element has text attribute or not

Is there some way of determining at run time, if an element returns value for element.text() or not? Using javascript or jquery?
I.E. some way of checking if an element is pure text, or it is some other type of element?
Why I need a solution to the above---
I am trying to parse through some complicated forms with totally different coding styles (in the way, for example, text values for elements of a radio button may be enclosed in label tags, or they may be directly given, or they may be enclosed in span tags, and so on...)
So I need to parse the form with the form id as wrapper,
now if the text value for a radio button is enclosed in span, and current selected element is radio button, then next element will be the span tag (opening) which I want to do nothing with and move on. The one after that will be the text, and this I want to obtain using this.text().
Hence the whole question...
You can use nodeType to check if an element is pure text (in which case its value will be 3)
<div id="wrapper"><input type='radio' />some text here</div>
$('#wrapper').contents().each(function()
{
alert(this.nodeType);
});
It will alert 1 (for input) and 3 (for text). For type=3, you can use text() to get text value
Note- It'll also taken into account white spaces (as text nodes).
var attr = $(this).attr('name');
// For some browsers, `attr` is undefined; for others,
// `attr` is false. Check for both.
if (typeof attr !== 'undefined' && attr !== false) {
// ...
}
Another way to check:
if( typeof( $(this).attr('name') ) != 'undefined' ) { // ... }
you can create you own extension method of jQuery:
$.fn.hasAttr = function(name) {
return this.attr(name) !== undefined;
};
$(document).ready(function() {
if($('.edit').hasAttr('id')) {
alert('true');
} else {
alert('false');
}
});
<div class="edit" id="div_1">Test field</div>
hi you can check the type of element as follow
<form >
<input type="text" id="a" value="abc"/>
</form>
<script>
var type = document.forms[0].elements[0].type;
alert(type);
</script>

How to enable/disable text field on radio button interaction?

Cannot get this to work. First time using variables passed into functions. Unchecking radio button should disable form field and vice versa. lineid variable distinguishes this radio/text input pair from 10 others.
My code:
<script type="text/javascript">
function disablefield(lineid){
if (document.getElementById(lineid).checked == true){
document.dupedit.lineid.disabled = false;
} else {
document.dupedit.lineid.disabled = true;
}
}
</script>
Subset of my HTML.
You need to pass a string into your disablefield function, so put the value in quotes when you pass it in. Something like:
<input onclick="disablefield('2671997')" />
This is because document.getElementById expects a string, not an integer.
Secondly, to enable/disable the field, you need to use disabled = true; rather than = 'disabled'.
document.dupedit.lineid is looking a for a field with name "lineid", which doesn't exist in your form. I would suggest giving the field an id and using document.getElementById again instead.
If you want to continue using the name attribute, you will have to use document.getElementsByName instead. This returns an array of matching elements (since multiple elements can share the same name), but if in your code you know that the element in question is the only one with that name, you can do this:
document.getElementsByName(lineid)[0].disabled = true;
You can see a working version (I think this is how you wanted it anyway) here. And here is a version using getElementsByName.
You are missing a closing brace on the function:
function disablefield(lineid){
if (document.getElementById(lineid).checked == true){
document.dupedit.lineid='enabled';
}else{
document.dupedit.lineid='disabled';
}
} //<-- here
Also, can I suggest you pass this to the function. Then you don't have to call getElementById
<input onclick='disablefield(this)' type.....
function disablefield(obj){
if (obj.checked == true){
document.dupedit.lineid='enabled';
}else{
document.dupedit.lineid='disabled';
}
}
I think what you need is to re-think the code.
Don't use ID on the checkbox. Better move that ID to the text field you want to disable/enable and check whether that field is disabled/enabled, not the checkbox itself
use cleaner JS.
Please, take a look at the jsFiddle, I have compiled for you. Does it do what you expect, Dan?

Validation in jsp using javascript

'
<TD CLASS="input-label" VALIGN="top">A:</TD>
out.println(widget_renderer.getEditableField("A"));
<TD CLASS="input-label" VALIGN="top">B:</TD>
out.println(widget_renderer.getEditableField("B"));
I want to make the attribute B field required based on the values entered for attribute field A. Also would liek to validate it and print error message
I did the below on jsp page:-
<TD CLASS="input-label" VALIGN="top">A:</TD>
out.println(widget_renderer.getEditableField("A"));
String ppn = (String)dataBean.getItemEntityData().get("A");
System.out.println(dataBean.getItemEntityData().get("A"));
if (ppn != null && (ppn == "A1" || ppn == "A2" || ppn == "A3" || ppn == "A4"))
{
>
<TD VALIGN="top"><SPAN CLASS="req-indicator">*</SPAN></TD>
< } >
,<TD CLASS="input-label" VALIGN="top">B:</TD>
out.println(widget_renderer.getEditableField("B"));
Please suggest
The original JSP code is irrelevant. Open the JSP page in your webbrowser, rightclick the page and choose View Source. All this generated HTML code which you now see is now really relevant for JavaScript since that's the only what it can see and access.
It's unclear what "widget" framework you're using since you didn't tell/tag anything about it, while that's unrelated to JSP. Anyway, if it has done its job right, then you should see <input> elements with an id attribute in the generated HTML code like so:
<input type="text" id="someId">
Now, in the JS code you can easily grab elements from the HTML DOM using document.getElementById().
var inputElement = document.getElementById('someId');
If it's an input element, then you can get its value as follows:
var inputValue = inputElement.value;
You can compare string values in JavaScript as follows:
if (inputValue == 'foo') {
// Value is foo.
} else {
// Value is not foo.
}
Note that this is not the way to compare strings in Java! You would rather use String#equals() for this.
You can also grab a different element from the DOM, e.g. a <div id="message"> which you've added yourself.
var messageElement = document.getElementById('message');
You can in turn set some text in its body as follows:
messageElement.firstChild.nodeValue = 'some message';
Do the math :)
See also:
W3Schools JavaScript tutorial
W3Schools HTML DOM tutorial
Essential JavaScript - tutorial
By the way, the "style" you're using in your code is pretty old fashioned. It might happen that you inherited a legacy project, okay, but that 90's style is really not the right way to start HTML/JSP with nowadays.

Categories

Resources