How can i give a limit to an append function with javascript? - 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
}
};

Related

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.

How To Add Delay To HTML Javascript Function

I have the following script that opens urls in a list:
function openWindow(){
var x = document.getElementById('a').value.split('\n');
for (var i = 0; i < x.length; i++)
if (x[i].indexOf('.') > 0)
if (x[i].indexOf('://') < 0)
window.open('http://'+x[i]);
else
window.open(x[i]);
}
However, I would like to add a delay (let's say about 5 seconds) between opening each url. How can I do this?
I'm not familiar with functions. Usually much better with Linux and such. Your insight is highly appreciated.
A better approach is to use setTimeout() along with a self-executing anonymous function:
function openWindow() {
var i = 0;
var x = document.getElementById('a').value.split('\n');
(function() {
if(typeof x[i] !== 'undefined') {
if(x[i].indexOf('.') > 0) {
if(x[i].indexOf('://') < 0) {
window.open('http://' + x[i++]);
} else {
window.open(x[i++]);
}
}
setTimeout(arguments.callee, 1000);
}
return false;
})();
}
This will guarantee that the next call is not made before your code was executed. I used arguments.callee in this example as a function reference. Once the index no longer exists in the array, by checking if it's undefined, it simply returns false instead of setting another timout.
You can do it like this, to avoid issues caused by setTimeout being non-blocking.
What you need is to wait for the setTimeout to be executed before starting the next iteration.
var i = 0;
function openWindow(){
var x = document.getElementById('a').value.split('\n');
doLoop(x);
}
function doLoop(x)
setTimeout(function () {
if (x[i].indexOf('.') > 0){
if (x[i].indexOf('://') < 0){
window.open('http://'+x[i]);
}else{
window.open(x[i]);
}
}
i+=1;
if(i<x.length){
doLoop(x);
}
}, 5000)
}
Using a self executing function, it'd go like this :
function openWindow() {
var i = 0;
var x = document.getElementById('a').value.split('\n');
(function fn() {
if(x[i].indexOf('.') > 0) {
if(x[i].indexOf('://') < 0) {
window.open('http://' + x[i++]);
} else {
window.open(x[i++]);
}
}
i++;
if( i < x.length ){
setTimeout( fn, 3000 );
}
})();
}
create array x with all url's
var x = [url1, url2, url3, ...];
create a for loop
for(var i = 0; i<x.length; i++) {
setTimeout(function() {
window.open('http://'+x[i])}, 1000); // 1000 for 1 second
}
}
setInterval(function(){window.open('http://'+x[i]);},5000);

My javascript crashes the server

Now before everyone is helpful (seriously, you guys are awesome) I am doing a coding challenge that means I can't get code from other users/people. This does not, however, extend to advice so I wanted to know why my code crashes google chrome. I don't want am not allowed any code so please just point me in the right direction. I am sorry for such an odd request but I am at my wit's end.
http://jsfiddle.net/clarinetking/c49mutqw/9/
var chars;
var keyword = [];
var cipher;
var done = false;
var list1 = [];
var list2 = [];
var list3 = [];
var list4 = [];
var list5 = [];
var keylngth = 0;
$('#apnd').click(function () {
cipher = $('#Input').val();
chars = cipher.split('');
$('#Output').append(chars);
});
$('#key').click(function () {
while (done === false) {
var letter = prompt('insert letter, xyz to close');
keylngth++;
if (letter == 'xyz') {
done = true;
} else {
//Push letter to keyword array
keyword.push(letter);
}
}
});
$('#list').click(function () {
for (i = 0; i < chars.length; i++) {
var x = 1;
for (i = 1; i < keylngth+1; i++) {
if (i/x === 1) {
list1.push(chars[x]);
}
if (i/x === 2) {
list1.push(chars[x]);
}
if (i/x === 3) {
list1.push(chars[x]);
}
if (i/x === 4) {
list1.push(chars[x]);
}
if (i/x === 5) {
list1.push(chars[x]);
}
if (i/x === 6) {
list1.push(chars[x]);
}
if (i/x === 7) {
list1.push(chars[x]);
}
if (i/x === 8) {
list1.push(chars[x]);
}
}
x++;
}
alert(list1);
alert(list2);
});
I apologize to all you coders out there that are probably screaming at me USE A REPEAT LOOP! but for the list function I see no way to. As previously mentioned, no code please unless it's pseudo code :)
In your $('#list').click(function ()) function you are running an infinite for bucle, it's because you use the same i counter for the two for bucles so you javascript will run forerver and crash the browser

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;
}
}
}

innerHTML javascript dynamic

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

Categories

Resources