innerHTML javascript dynamic - javascript

I am currently having some issues with the innerHTML function in a little javascript project. Essentially, I have a few HTML form checkboxes which change a number (that is displayed on the same page) depending on whether they are checked or not. The idea is very much like an IP address. The result is a number between 0 and 255.
What I want to do however is that whenever the user clicks on a checkbox, I need that number to change dynamically. Idea resembles the concept that is used when we write a question on this forum. As you type, the text below changes dynamilly to show exactly what is changed as it changes.
My code isn't working too well. Could you help me please? It keeps giving me the message "undefined" instead of the sum. Thanks for your help.
JavaScript
function displayOctets01(){
var octet01 = new Array(8);
octet01[0] = document.getElementById('octect0101');
octet01[1] = document.getElementById('octect0102');
octet01[2] = document.getElementById('octect0103');
octet01[3] = document.getElementById('octect0104');
octet01[4] = document.getElementById('octect0105');
octet01[5] = document.getElementById('octect0106');
octet01[6] = document.getElementById('octect0107');
octet01[7] = document.getElementById('octect0108');
var firstOctect;
if(octet01[0]==true){
firstOctect+=1;
}
else if(octet01[1]==true){
firstOctect+=2;
}
else if(octet01[2]==true){
firstOctect+=4;
}
else if(octet01[3]==true){
firstOctect+=8;
}
else if(octet01[4]==true){
firstOctect+=16;
}
else if(octet01[5]==true){
firstOctect+=32;
}
else if(octet01[6]==true){
firstOctect+=64;
}
else if(octet01[7]==true){
firstOctect+=128;
}
document.getElementById("octets01").innerHTML = firstOctect;
}
else if(octet01[7]==true){
firstOctect+=128;
}
document.getElementById("octets01").innerHTML = firstOctect;
}
I suspect that something might be wron with how I am handling the variables.
DEMO: http://jsfiddle.net/3TyV3/

The first problem is that the firstOctet variable isn't initialized. That needs to be set to 0 at the beginning of your function. Also, without knowing the purpose of your program, it seems that you don't want to be using else if - you need to check every checkbox. Also, you shouldn't be comparing the element with == true, you should check its checked property Also, your jsFiddle was set to run onLoad, so the function wasn't globally available. Finally, you didn't have an element with the id "octets01" to output to. Try this:
function displayOctets01() {
var octet01 = [],
firstOctect = 0;
octet01[0] = document.getElementById('octect0101');
octet01[1] = document.getElementById('octect0102');
octet01[2] = document.getElementById('octect0103');
octet01[3] = document.getElementById('octect0104');
octet01[4] = document.getElementById('octect0105');
octet01[5] = document.getElementById('octect0106');
octet01[6] = document.getElementById('octect0107');
octet01[7] = document.getElementById('octect0108');
if (octet01[0].checked === true) {
firstOctect += 1;
}
if (octet01[1].checked === true) {
firstOctect += 2;
}
if (octet01[2].checked === true) {
firstOctect += 4;
}
if (octet01[3].checked === true) {
firstOctect += 8;
}
if (octet01[4].checked === true) {
firstOctect += 16;
}
if (octet01[5].checked === true) {
firstOctect += 32;
}
if (octet01[6].checked === true) {
firstOctect += 64;
}
if (octet01[7].checked === true) {
firstOctect += 128;
}
document.getElementById("octets01").innerHTML = firstOctect;
}
DEMO: http://jsfiddle.net/3TyV3/2/
Although I won't lie, I'd reorganize some things. Here's how I would do it:
window.onload = function () {
var checkboxes = document.querySelectorAll('[name="featuresOctet01"]'),
i;
for (i = 0; i < checkboxes.length; i++) {
addEvent(checkboxes[i], "click", clickHandler);
}
};
function addEvent(element, eventName, callback) {
if (element.addEventListener) {
element.addEventListener(eventName, callback, false);
} else if (element.attachEvent) {
element.attachEvent("on" + eventName, callback);
} else {
element["on" + eventName] = callback;
}
}
function clickHandler() {
var firstOctect = 0,
checkboxes = document.querySelectorAll('[name="featuresOctet01"]'),
i, cur;
for (i = 0; i < checkboxes.length; i++) {
cur = checkboxes[i];
if (cur.checked) {
firstOctect += Math.pow(2, i);
}
}
document.getElementById("octets01").innerHTML = firstOctect;
}
DEMO: http://jsfiddle.net/3TyV3/3/
It uses unobtrusive JavaScript by binding the events in JavaScript, not the inline HTML. I did use the click event instead of change because old versions of IE has weird behavior for it with checkboxes/radio buttons. The addEvent function is just a simple function for binding events in new browsers as well as old IE.
It selects all elements with the name "featuresOctet01" and adds the event to each. Then, in the handler, it loops through each checkbox, sees if it's checked, and then adds a value based on 2^i.
References:
addEventListener: https://developer.mozilla.org/en-US/docs/DOM/EventTarget.addEventListener
document.querySelectorAll: https://developer.mozilla.org/en-US/docs/DOM/Document.querySelectorAll
Math.pow: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/pow

Related

Unable to toggle div display using Javascript

I have written some vanilla JS in order to hide/display some divs, depending on the value of one of the fields in them.
My problem is that, while hiding them appropriately is working by default, trying to make them appear again, I am having issues as using getElementById is returning nulls.
I've googled and found numerous examples where similar code has worked and I cannot figure out why mine isn't actually working.
The JS I've written is below:
var hidden = false
document.addEventListener("keypress", function(event) {
if (event.key == '`') {
if (hidden == false) {
resultEntries = document.getElementsByClassName('result-row');
for (i = 0; i < resultEntries.length + 1; i++) {
var x = document.getElementById('root_cause_' + i)
if (x != null) {
var value = x.options[x.selectedIndex].value;
console.log('value' + value)
if (value == '') {
row = document.getElementById('line_' + i)
row.style.display = 'none';
}
}
}
hidden = true
} else {
resultEntries = document.getElementsByClassName('result-row');
for (i = 0; i < resultEntries.length + 1; i++) {
row = document.getElementById('line_' + i) // This is what is returning null
console.log(row)
row.style.display = 'block';
}
hidden = false
}
}
});
You overshoot your elements with the + 1 in the for loops
If you need this 1 based (not recommended) it is
for (let i = 1; i <= resultEntries.length; i++)
Also I think you can simplify this. Here is my guess without seeing the HTML
const resultEntries = document.querySelectorAll('.result-row');
document.addEventListener("keypress", function(event) {
if (event.key !== '`') return;
resultEntries.forEach((res, i) => {
let x = document.getElementById('root_cause_' + i)
if (x) {
let value = x.value;
console.log('value' + value)
document.getElementById('line_' + i).hidden = value === '';
}
})
});
Answering to save people from spending more time on this:
The issue was that my loop was starting from 0 while the elements were starting from line_1, meaning I was later on trying to alter the style of a null element.

How to underline charachters in InDesign with JavaScript?

I started writing this piece of code for InDesign to underline all letters except from the one with descendants, and added a dialog window to chose stroke and offset of the line.
Now I have two problems:
the program underlines all letters
the stroke and offset won't change
I'm a beginner in Javascript and it's the first time coding for InDesign. Does someone have a clue? Thank you!
// UNDERLINE ALL BUT NO DESCENDANTS
//Make certain that user interaction (display of dialogs, etc.) is turned on.
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
if (app.documents.length != 0){
try {
// Run script with single undo if supported
if (parseFloat(app.version) < 6) {
main();
} else {
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "Expand State Abbreviations");
}
// Global error reporting
} catch ( error ) {
alert( error + " (Line " + error.line + " in file " + error.fileName + ")");
}
}else{
alert("Open a document first before running this script.");
}
///MAIN FUNCTION
function main(){
if(app.selection.length != 0){
myDisplayDialog();
}
}
//INTERFACE
function myDisplayDialog(){
//declare variables
//general
var myDoc = app.activeDocument;
var mS = myDoc.selection;
// dialog
var myDialog = app.dialogs.add({name:"Underliner"});
var myLabelWidth = 70;
with(myDialog.dialogColumns.add()){
with(borderPanels.add()){
with(dialogColumns.add()){
with(dialogRows.add()){
staticTexts.add({staticLabel:"Stroke:", minWidth:myLabelWidth});
staticTexts.add({staticLabel:"Offset:", minWidth:myLabelWidth});
}
}
with(dialogRows.add()){
staticTexts.add({staticLabel:""});
var myStroke = measurementEditboxes.add({editValue:1, editUnits:MeasurementUnits.points});
var myOffset = measurementEditboxes.add({editValue: 15, editUnits:MeasurementUnits.points});
}
}
}
var myResult = myDialog.show();
if(myResult == true){
var myStroke = myStroke.editValue;
var myOffset = myOffset.editValue;
myDialog.destroy();
underline(mS,myStroke,myOffset);
}
else{
myDialog.destroy();
alert("Invalid page range.");
}
}
//REAL FUNCTION
function underline(charList,stroke, offset){
var len = charList.length;
const doNotUnderline = ['g','j','p','q','y'];
for (var i=0; i < len; i++){
try{
var myChar = charList[i];
//console.log(typeof myText);
if (includes(myChar, doNotUnderline) == false)
{
myChar.underline = true;
myChar.underlineWeight == stroke;
myChar.underlineOffset == offset;
} else {
myChar.underline = false;
}
}catch(r){
alert(r.description);
break;
}
}
}
//function to know if char is in array
function includes(elemento,array)
{
var len = array.length;
for(var i=0; i<len ;i++)
{
if(array[i]==elemento){return true;}
}
return false;
}
Try these changes in the function underline():
//REAL FUNCTION
function underline(words,stroke, offset) { // <------ here 'words' instead of 'charList'
var charList = words[0].characters; // <------ here get 'characters' of the 'words'
var len = charList.length;
const doNotUnderline = ['g','j','p','q','y'].join(); // <------- here '.join()'
for (var i=0; i < len; i++){
try{
var myChar = charList[i];
// if (includes(myChar, doNotUnderline) == false) // <----- no need
if (doNotUnderline.indexOf(myChar.contents) < 0) // <------ 'indexOf()' instead of 'includes()'
{
myChar.underline = true;
myChar.underlineWeight = stroke; // <------- here '=' instead of '=='
myChar.underlineOffset = offset; // <------- here '=' instead of '=='
} else {
myChar.underline = false;
}
}catch(r){
alert(r.description);
break;
}
}
}
Probably there can be another improvements as well. It's need additional researches. But if you change these lines it should work to a degree.
And there is one little thing that improves user experience greatly: to keep last used values in the input fields. It can be done pretty easy, let me know it you need it.
Update
Here is the way I'm using to store and restore any preferences of my scripts.
Add somewhere at the start of your script these lines:
// get preferences
var PREFS = { stroke: 1, offset: 15 }; // set default prefs
var PREFS_FILE = File(Folder.temp + '/underline_prefs.json'); // the file with preferences
if (PREFS_FILE.exists) PREFS = $.evalFile(PREFS_FILE); // get the prefs from the file
Now you can use the global values PREFS.stroke and PREFS.offset anywhere you want. In your case they go here:
with(dialogRows.add()){
staticTexts.add({staticLabel:""});
var myStroke = measurementEditboxes.add({editValue:PREFS.stroke, editUnits:MeasurementUnits.points});
var myOffset = measurementEditboxes.add({editValue:PREFS.offset, editUnits:MeasurementUnits.points});
}
This way script will get the stroke and weight from the file underline_prefs.json that will be stored in the standard temporary folder of current user.
Final step is to save the values back into the file after the script got them from the dialog window.
I'd put this piece of code here:
if (myResult == true) {
var myStroke = myStroke.editValue;
var myOffset = myOffset.editValue;
myDialog.destroy();
underline(mS, myStroke, myOffset);
// save preferences here
PREFS.stroke = myStroke;
PREFS.offset = myOffset;
PREFS_FILE.open('w');
PREFS_FILE.write(PREFS.toSource());
PREFS_FILE.close();
} else {
myDialog.destroy();
alert("Invalid page range.");
}
Voilá. Now don't need to type the values every time they differ from default ones.

Trouble working out whether one attribute of an object is greater that another attribute of that object

I am comparing two attributes of the same object to work out which one is larger, if one is larger then it sets another attribute to True.. else it sets it to false.
Here is my function:
country.prototype.cure = function(){
for (var i = 0; i<this.diseases.length; i++)
{
console.log(this.health);
console.log(this.diseases[i].cureLevel);
if (this.heatlh >= this.diseases[i].cureLevel)
{
this.diseases[i].cured = true;
createDiseaseTable();
}
else
{
this.diseases[i].cured = false;
}
}
}
NOTE: this.health = 39000000 and this.diseases[i].cureLevel = 2500000
The problem is that whenever I run the function, despite this.health being larger it will always miss the if and go straight to the else...
Try this:
country.prototype.cure = function(){
for (var i = 0; i<this.diseases.length; i++)
{
var a=parseInt(this.health);
var b=parseInt(this.diseases[i].cureLevel);
if (a >= b)
{
this.diseases[i].cured = true;
createDiseaseTable();
}
else
{
this.diseases[i].cured = false;
}
}
}

How to validate just one checkbox?

I'm working on a piece of code from an open source library called gvalidator. The following checkbox validate function only works when I have two or more checkboxes. For some reason the if(elements[i]checked) line is not returning true when elements only has 1 object in the array.
Anyone have a guess as to why this is happening? Thanks!
this.validate = function() {
// Check if the form has a value set for this checkbox
// by cycling through all of the checkboxes
var elements = document.forms[0].elements[this.field.name];
if(undefined == elements.length){
x = elements;
elements = new Array(x);
}
for (i = 0; i < elements.length; i++) {
if (elements[i].checked) {
document.write(elements[i].name);
this.setState(ONEGEEK.forms.FIELD_STATUS_OK);
return true;
} else {
if (this.modified !== true || !this.isRequired) {
this.setState(ONEGEEK.forms.FIELD_STATUS_INFO);
} else {
this.setState(ONEGEEK.forms.FIELD_STATUS_EMPTY);
}
}
}
return false;
};
Jan was right... almost. The following is required in the function validate as the the form.elements function won't always return an array - it returns an element in the case there is only 1 match:
// Check if the form has a value set for this checkbox
// by cycling through all of the checkboxes
var elements = document.forms[0].elements[this.field.name];
if (elements.length === undefined) {
elements = [ elements ];
}
It is also required in the setup function before it adds the validation events in the first place:
this.setup = function() {
...
// Add events to ALL of the items
var elements = document.forms[0].elements[this.field.name];
if (elements.length === undefined) {
elements = [ elements ];
}
for (i = 0; i < elements.length; i++) {
_du.addEvent(elements[i], 'click', this.applyFieldValidation(this));
_du.addEvent(elements[i], 'click', this.applyContextInformation(this));
_du.addEvent(elements[i], 'change', this.applyFieldModification(this));
}
}
I have updated the source code at code http://code.google.com/p/gvalidator/, the latest binary is available for download here: http://code.google.com/p/gvalidator/downloads/list.
There are some serious and some minor flaws in your code. This is how it should look like. Test this code and tell me if it still does not work and provide any error messages in the error console.
this.validate = function () {
// Check if the form has a value set for this checkbox
// by cycling through all of the checkboxes
var elements = document.forms[0].elements[this.field.name];
if (elements.length === undefined) {
elements = [ elements ];
}
for (var i = 0, ii = elements.length; i < ii; ++i) {
if (elements[i].checked) {
document.write(elements[i].name);
this.setState(ONEGEEK.forms.FIELD_STATUS_OK);
return true;
} else {
if (this.modified !== true || !this.isRequired) {
this.setState(ONEGEEK.forms.FIELD_STATUS_INFO);
} else {
this.setState(ONEGEEK.forms.FIELD_STATUS_EMPTY);
}
}
}
return false;
};

How can i give a limit to an append function with javascript?

I have an append button which appends endlessly if you click it endlessly.
Lets say i want this button to do this 10 times.
Let me tell you in fantasy code :p what i was thinking so that i can learn from my mistakes; ( i know its wrong but hey im learning)
thismany = 1;
appendbutton.onClick = "thismany = +1";
if{ thismany = <9}
appendbutton.onClick = disabled
thanks in advance
(function(){
var count = 1;
document.getElementById("the_node_id").onclick = function(){
if(count > 10){
return;
}
do_stuff();
count ++;
};
})()
UPDATE:
var count = 1;
addEvent(append, "click", function(/* someargument */){
if(count > 10){
return;
}
// if you need arguments that are passed to the function,
// you can add them to the anonymous one and pass them
// to appendFunction
appendFunction(/* someargument */);
count++;
});
This is straight javascript. You might also consider looking into a framework such as jQuery to make it easier for you.
This assumes your HTML for the button has id="appendButton" as an attribute.
var count = 0;
document.getElementById("appendButton").onClick = function(e) {
if( count >= 10 ) {
return false;
}
else {
count ++;
document.getElementById("id_of_thing_you_append_to").innerHTML += "Whatever you're appending";
}
}
Using your variable names:
var thismany = 0;
appendbutton.onclick = function() {
if (thismany++ < 10) {
// append things
}
};
Variable encapsulated:
appendbutton.onclick = function() {
if (this.count == undefined) {
this.count = 0;
}
if (this.count++ < 10) {
// append things
}
};

Categories

Resources