Javascript Disable form field element by id (id is an array) - javascript

I am building a recurring events module to drop into a form, this module has several fields.
I have named and ID'd each of this module using array notation. EG:
id='recurring_event_options[yearly][by_date_day_number]'
In my JS I need to target all fields with the matching id recurring_event_options
I have some JS working nicely that enables (non disabled) fields as needed, but before i run this i need to disable all the fields in this module.
I have been using somthing similar to this to disable the fields:
function disableForm(theform) {
if (document.all || document.getElementById) {
for (i = 0; i < theform.length; i++) {
var formElement = theform.elements[i];
if (true) {
formElement.disabled = true;
}
}
}
}
As you can see, that going to hit every field in the form - thats not what i want - only to disable the fields that belong to the recurring_event_options parent ID.
I have a feeling I probably cant use [] notation in IDs, so suggestions welcome!

First of all i think it is not a good idea to use [].
You can use a hyphen - or underscore _ to separate the values:
id='recurring_event_options-yearly-by_date_day_number'
Now you can disable:
function disableForm(theform) {
for (i = 0; i < theform.length; i++) {
var formElement = theform.elements[i];
if (formElement.id.indexOf("recurring_event_options") !== -1) {
formElement.disabled = true;
}
}
}
This should work. but in my opinion it will be much better if you use a class instead:
<input type="text" class="recurring_event_options prop2 prop3" />
because the class attribute is designed to support multiple values, separated by a space

Related

Javascript function parameters in Acrobat

Hopefully you all don't get pissed at me for such a seemingly simple question..
Basically, I have a PDF form that I'm scripting with javascript.
I have a bunch of check boxes that I would like to set required and/or not required based on other inputs and I'm trying to repeat code as little as possible, especially since there's a ton of inputs.
Right now, the best way I can accomplish what I'm attempting is by setting a function for each instance of inputs as follows:
function setWalkwayNotRequired() {
this.getField("sidewalkAsphalt").required = false;
this.getField("sidewalkConcrete").required = false;
this.getField("sidewalkPavers").required = false;
this.getField("sidewalkCondition").required = false;
}
I would then call this function based on the input of a certain checkbox:
if (this.getField("sidewalkNone").value == "Yes") {
setSidewalkNotRequired();
}
Then all of the above-mentioned fields would be set to not required.
I feel like there should be a way to create a single "setRequired" or "setNotRequired" function to take a parameter of the field in question.
In my mind that would look something like this:
function setRequired(a, b, c, d) {
this.getField(a).required = true;
this.getField(b).required = true;
this.getField(c).required = true;
this.getField(d).required = true;
}
I would then call on that function for all instances, for example, walkways (like that above) or driveways, etc. like so:
if (this.getField("sidewalkNone").value == "Off") {
setRequired('"sidewalkAsphalt"', '"sidewalkConcrete"', '"sidewalkPavers"', '"sidewalkCondition"');
}
Again, in my mind what would then be output based on the above code once the function is called is something like:
if (this.getField("sidewalkNone").value == "Off") {
this.getField("sidewalkAsphalt").required = true;
this.getField("sidewalkConcrete").required = true;
this.getField("sidewalkPavers").required = true;
this.getField("sidewalkCondition").required = true;
}
Doing it the way I did in the first code block would require me to create separate functions for each set of checkboxes, creating a lot of code in an already huge file. The second way would allow me to use 1 function over and over throwing the field names as parameters depending on where I'm at in the PDF.
I'm also not very clear on if it's even legal to declare the parameters as I did with the '"..."' quotes; I did that because I need the double quotes inside the this.getField().
Again, I'm sorry if this is novice, I've just been trying to play with the code for a while now and can't get it to work.
Any input would be amazing.
You could just pass in an Array of field names:
function setRequired( fieldNames, isRequired = true ) {
for( var i = 0; i < fieldNames.length; i++ ) {
var fieldName = fieldNames[i];
this.getField( fieldName ).required = isRequired;
}
}
Usage:
if( this.getField("sidewalkNone").value == "Off" ) {
setRequired( [ "sidewalkAsphalt", "sidewalkConcrete", "sidewalkPavers", "sidewalkCondition" ] );
}
If you use hierarchical naming with dot notation, you can set properties on the parent to affect all children. For example, if you name the fields "sidewalk.Asphalt", "sidewalk.Concrete", and "sidewalk.Pavers"...
this.getField("sidewalk").required = true;
... will set all the children to be required.

.hide() is not a function error when executing from a loop

I want to be able to loop over a few different labels and hide their content based on if a radio button is check or not. This is the solution I came up with, but I keep getting an error in the console.
var hazardOptions = $(".js-hazardous-option");
var hazard = $("input[name=Hazardous]");
for (var i = 0, len = hazard.length; i < len; i++) {
if (hazard[i].id === "HazardousYes" && hazard[i].checked) {
for (var ii = 0, length = hazardOptions.length; ii < length; ii++) {
hazardOptions[ii].show();
}
} else if (hazard[i].id === "HazardousNo" && hazard[i].checked) {
for (var iii = 0, leng = hazardOptions.length; iii < leng; iii++) {
hazardOptions[iii].hide();
}
}
}
The error I get is:
hide() is not a function
Not sure what I'm missing, I've tried having a look online for a similar issue, but with no luck. I'm pretty sure that the problem is here: hazardOptions[iii].hide(); but not really sure why and/or how to fix it.
When you have a list of objects from a JQuery selector, if you try to access them via index you actually get the DOM element back and not the JQuery object. It's confusing for sure but it is in the documentation.
What you effectively need to do is turn it back into a JQuery object:
$(hazardOptions[iii]).hide();
Or you can use the eq() function with does provide the JQuery object ad thus still has the hide() function:
hazardOptions.eq(iii).hide();
Most probably you need to wrap it with $
$(hazardOptions[ii]).hide()
As you currently have it, if hazard.id === "HazardousYes", you are showing all hazardOptions, and if it is "HazardousNo"you are hiding all of them.
You can call .show() and .hide() on a jQuery collection and it will apply that to all elements in the collection. The below code will replicate the logic of your original code, however, the hazardOptions final show/hide state will be solely determined by the last hazard that is checked and has an id equal to "HazardousYes" and "HazardousNo". This may be what you want, but I would imagine it's not.
var hazardOptions = $(".js-hazardous-option");
var hazards = $("input[name=Hazardous]");
hazards.each(function (index, hazard) {
if (hazard.checked) {
if (hazard.id === "HazardousYes") {
hazardOptions.show();
} else if (hazard.id === "HazardousNo") {
hazardOptions.hide();
}
}
}
Edit - Come to think of it, if you don't have elements with duplicate IDs, You can make this really simple:
hazardOptions.show($("#HazardousYes").is(":checked"));
hazardOptions.hide($("#HazardousNo").is(":checked"));

Javascript - check Checkboxes does not work

Recently I tried to get a small javascript to work, which shall only check some checkboxes. The problem is, I have no clue about Javascript and therefore I am a bit lost whilst looking at the google results.
So far I used a syntax checker I have found online which gave no errors (a good sign, but it's not working anyway).
To prevent you from asking, the submitted name of the checkboxes is right (;
This is my code so far, any help would be appreciated and thanks in advance!
function checkAll(name) {
var flag = 0;
//get all checkboxes with that name
var checkboxes = document.getElementsByName(name);
//look if the check all box is checked or not, set the flag
if (document.getElementByName('check_all').checked === true) {
flag = 1;
}
for (var i = 0; i < checkboxes.length; i++) {
//check the boxes or uncheck them
if (flag == 1) {
checkboxes[i].checked = true;
}
else {
checkboxes[i].checked = false;
}
}
}
There's no document.getElementByName function to obtain a single element by name. You'll either need to change that to an ID and use:
if(document.getElementById('check_all').checked === true) {
flag = 1;
}
Or use document.getElementsByName('check_all')[0] in place of document.getElementByName('check_all'). This assumes that there's only a single element on the page with the name check_all, though; if there are multiple you'll want to consider some other way of uniquely identifying them (such as IDs).

ID Ends With in pure Javascript

I am working in a Javascript library that brings in jQuery for one thing: an "ends with" selector. It looks like this:
$('[id$=foo]')
It will find the elements in which the id ends with "foo".
I am looking to do this without jQuery (straight JavaScript). How might you go about this? I'd also like it to be as efficient as reasonably possible.
Use querySelectorAll, not available in all browsers (like IE 5/6/7/8) though. It basically works like jQuery:
http://jsfiddle.net/BBaFa/2/
console.log(document.querySelectorAll("[id$=foo]"));
You will need to iterate over all elements on the page and then use string functions to test it. The only optimizations I can think of is changing the starting point - i.e. not document.body but some other element where you know your element will be a child of - or you could use document.getElementsByTagName() to get an element list if you know the tag name of the elements.
However, your task would be much easier if you could use some 3rd-party-javascript, e.g. Sizzle (4k minified, the same selector engine jQuery uses).
So, using everything that was said, I put together this code. Assuming my elements are all inputs, then the following code is probably the best I am going to get?
String.prototype.endsWith = function(suffix) {
return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
function getInputsThatEndWith(text) {
var result = new Array();
var inputs = document.getElementsByTagName("input");
for(var i=0; i < inputs.length; i++) {
if(inputs[i].id.endsWith(text))
result.push(inputs[i]);
}
return result;
}
I put it on JsFiddle: http://jsfiddle.net/MF29n/1/
#ThiefMaster touched on how you can do the check, but here's the actual code:
function idEndsWith(str)
{
if (document.querySelectorAll)
{
return document.querySelectorAll('[id$="'+str+'"]');
}
else
{
var all,
elements = [],
i,
len,
regex;
all = document.getElementsByTagName('*');
len = all.length;
regex = new RegExp(str+'$');
for (i = 0; i < len; i++)
{
if (regex.test(all[i].id))
{
elements.push(all[i]);
}
}
return elements;
}
}
This can be enhanced in a number of ways. It currently iterates through the entire dom, but would be more efficient if it had a context:
function idEndsWith(str, context)
{
if (!context)
{
context = document;
}
...CODE... //replace all occurrences of "document" with "context"
}
There is no validation/escaping on the str variable in this function, the assumption is that it'll only receive a string of chars.
Suggested changes to your answer:
RegExp.quote = function(str) {
return str.replace(/([.?*+^$[\]\\(){}-])/g, "\\$1");
}; // from https://stackoverflow.com/questions/494035/#494122
String.prototype.endsWith = function(suffix) {
return !!this.match(new RegExp(RegExp.quote(suffix) + '$'));
};
function getInputsThatEndWith(text) {
var results = [],
inputs = document.getElementsByTagName("input"),
numInputs = inputs.length,
input;
for(var i=0; i < numInputs; i++) {
var input = inputs[i];
if(input.id.endsWith(text)) results.push(input);
}
return results;
}
http://jsfiddle.net/mattball/yJjDV/
Implementing String.endsWith using a regex instead of indexOf() is mostly a matter of preference, but I figured it was worth including for variety. If you aren't concerned about escaping special characters in the suffix, you can remove the RegExp.quote() bit, and just use
new RegExp(suffix + '$').
If you know the type of DOM elements you are targeting,
then get a list of references to them using getElementsByTagName , and then iterate over them.
You can use this optimization to fasten the iterations:
ignore the elements not having id.
target the nearest known parent of elements you want to seek, lets say your element is inside a div with id='myContainer', then you can get a restricted subset using
document.getElementById('myContainer').getElementsByTagName('*') , and then iterate over them.

jQuery form zip code to state function

I'm trying to convert a preexisting javascript function into a jQuery function.
The function comes from http://javascript.internet.com/forms/zip-to-state.html
and aims to convert a user-entered zip code into a state. I'm using jQuery 1.3.2, with all the necessary plugins, but I'm not very familiar with jQuery syntax and how to convert this from plain ol' Javascript syntax.
The setState function takes two parameters, the zip code element and the state element, so I'm trying to do something like this:
$('$zip_code').change( function () { setState($(this), $('#state')); });
Any thoughts on this syntax? Thanks, Dakota
function getState(zip) {
if ((parseInt(zipString.substr(zip / 4, 1), 16) & Math.pow(2, zip % 4)) && (zip.length == 5))
for (var i = 0; i < stateRange.length; i += 7)
if (zip <= 1 * stateRange.substr(i, 5))
return stateRange.substr(i + 5, 2);
return null;
}
function setState(txtZip, optionBox) {
if (txtZip.value.length != 5 || isNaN(txtZip.value / 4)) {
optionBox.options[0].selected = true;
alert("Please enter a 5 digit, numeric zip code.");
return;
}
var state = getState(txtZip.value);
for (var i = 0; i < optionBox.options.length; i++)
if (optionBox.options[i].value == state)
return optionBox.options[i].selected = true;
for (var i = 0; i < optionBox.options.length; i++)
if (optionBox.options[i].value == "XX")
return optionBox.options[i].selected = true;
}
You can leave the getState and setState functions just as they are, but you should really read up on jQuery before you go asking questions on how to use it. If you don't even know the syntax, you might want to read up on how to use it.
Like Aberon said, use blur in this situation and change '$zip_code' to '#zip_code', where 'zip_code' corresponds to:
<input type="text" id="zip_code" name="whatever_you_want" />
You also want a select box with an id of 'state':
<select id="state">
... options ...
</select>
Aberon's solution still wont work, however, because it is incomplete...
$('#zip_code').blur( function () { setState($(this)[0], $('#state')[0]); });
You want to get the value from the zip_code input element, thus the val() call. You also want the DOM element for the select box with id == 'state', so instead of using the array returned by $('#state'), you want the first element.
Try it out, I hope this helped.
-Stephen
Unless your zip field is a drop down you would probably be better off using either blur or keyup in your function.
$('#zip_code').blur( function () { setState($(this), $('#state')); });
I also changed $zip_code to #zip_code.

Categories