JS in indesign. autotag error - javascript

I'm trying to apply tags to all the EPS files in the document.
My code:
#target indesign
var allItems=app.activeDocument.pageItems.everyItem().getElements().slice(0);
for(var i=0;i<allItems.length;i++)
{
var allInnerItems = allItems[i].allPageItems;
for(var j=0;j<allInnerItems.length;i++)
{
(allInnerItems[j].toString() == "[object EPS]") ?
allInnerItems[j].parent.autoTag() : alert('false');
}
}
The code finds all EPS and applies to their Rectangle objects AutoTag method. But I was given the error: "The object or the parent story is already tagged or cannot be taged". Besides if i choose some rectangle object with EPS and click the function "AutoTag" in user interface, it will work.
Maybe somebody knows, what should I do?
Thanks in advance!

I think this should work for what you are trying to do.
In the inner loop you forgot to change i++ to j++.
Also, you don't have to get the string value of an object to test against it (ie. .toString() == "[object EPS]"), you can just ask for its constructor.
Finally, if you don't want any more errors for elements that are already tagged, you can add a condition to your if statement that tests whether or not the pageItem has an associatedXMLElement before attempting to autoTag() it.
var allItems = app.activeDocument.pageItems.everyItem().getElements();
for(var i=0; i<allItems.length; i++)
{
var allInnerItems = allItems[i].allPageItems;
for(var j=0;j<allInnerItems.length; j++)
{
var item = allInnerItems[j];
if (item.constructor == EPS && !item.parent.associatedXMLElement) {
item.parent.autoTag()
} else {
alert('false');
}
}
}

Related

String control in loops

I have a big question.
I have many Strings in my Programm and want to check these Strings on there values.
I wrote a Loop for it, but insted of the Definition of an String he is creating a new value. It's basicly really difficult to discribe, also because i am basicly German.
But i can give you my current code, so maybee you will see what I mean:
{
var Loch1G = $('#m1-Rundenanalyse-Datum').val(); //In the strings just the number is changing
var Loch2G = $('#m1-Rundenanalyse-Turnier').val();
x=1
while (x <= 2) {
if ("Loch" + x + "G" == ""){ //Next String is genrated (x=x+1)
alert("Eingabe war leer");
}
x=x+1
}
}
How can I solve this?
I'd suggest using an array to store the values you want to check:
var lochs = [];
lochs.push($('#m1-Rundenanalyse-Datum').val());
lochs.push($('#m1-Rundenanalyse-Turnier').val());
for (var i = 0, len = lochs.length; i < len; i++){
if (lochs[i] == ''){
alert("Eingabe war leer");
}
}
JS Fiddle demos: passes (no alert), fails (alert)
This suggestion is based on my presumption that you're trying to create the names of the vars you want to check, which won't work, whereas this approach lets you store all values (however many) in the same array and then iterate over that array to find any values that are equal to an empty string.
If you really want to stick with your current approach, you could do the following:
{
window.Loch1G = $('#m1-Rundenanalyse-Datum').val(); //In the strings just the number is changing
window.Loch2G = $('#m1-Rundenanalyse-Turnier').val();
var x=1;
while (x <= 2) {
if (window["Loch" + x + "G"] == ""){ //Next String is genrated (x=x+1)
alert("Eingabe war leer");
}
x=x+1;
}
}
But I can't think why you'd want to; plus the use of global variables is poor practice as it explicitly makes those variables available to every closure within the document, which allows them to be easily, and accidentally, overwritten.
In a reasonably up-to-date browser, that implements Array.prototype.every, you could dispense with the explicit iteration:
var lochs = [];
lochs.push($('#m1-Rundenanalyse-Datum').val());
lochs.push($('#m1-Rundenanalyse-Turnier').val());
if (!lochs.every(function(a){ return a !== ''; })) {
alert("Eingabe war leer");
}
JS Fiddle demos: passes (no alert), fails (alerts).

How do I correctly use an iteration value in JavaScript?

I am creating a 'simple' javaScript function which basically displays new information on the page when a user clicks next or previous.
The information is taken from an array and I want to use either i++ or i-- to call an element of the array.
Heres my JavaScript:
var titles = ["Dundalk", "Navan", "Drogheda", "Dublin"];
var i = 0;
function next()
{
i++;
if (i == titles.length)
{
i = 0;
}
var object = document.getElementById('tname');
object.innerHTML = titles[i];
}
function prev()
{
if (i == 0)
{
i = titles.length;
}
i--;
var object = document.getElementById('tname');
object.innerHTML = titles[i];
}
The problem is, when I run this code in my HTML page, I get an 'UNDEFINED' result. The JavaScript is not recognizing that i has been initialized as 0 in the beginning.
If i change titles[i] to titles[2], for example, the correct text is displayed in HTML.
What am I forgetting or how can I overcome this?
Thanks
The fact that you're seeing undefined indicates that you're accessing an array index which hasn't been set. Your code looks fine at a glance, so I would guess that there's some more code you're not showing which also uses i as a loop variable and leaves it set to a value > titles.length after the code above has run.

Can I select 2nd element of a 2 dimensional array by value of the first element in Javascript?

I have a JSON response like this:
var errorLog = "[[\"comp\",\"Please add company name!\"],
[\"zip\",\"Please add zip code!\"],
...
Which I'm deserializing like this:
var log = jQuery.parseJSON(errorLog);
Now I can access elements like this:
log[1][1] > "Please add company name"
Question:
If I have the first value comp, is there a way to directly get the 2nd value by doing:
log[comp][1]
without looping through the whole array.
Thanks for help!
No. Unless the 'value' of the first array (maybe I should say, the first dimension, or the first row), is also it's key. That is, unless it is something like this:
log = {
'comp': 'Please add a company name'
.
.
.
}
Now, log['comp'] or log.comp is legal.
There are two was to do this, but neither avoids a loop. The first is to loop through the array each time you access the items:
var val = '';
for (var i = 0; i < errorLog.length; i++) {
if (errorLog[i][0] === "comp") {
val = errorLog[i][1];
break;
}
}
The other would be to work your array into an object and access it with object notation.
var errors = {};
for (var i = 0; i < errorLog.length; i++) {
errors[errorLog[i][0]] = errorLog[i][1];
}
You could then access the relevant value with errors.comp.
If you're only looking once, the first option is probably better. If you may look more than once, it's probably best to use the second system since (a) you only need to do the loop once, which is more efficient, (b) you don't repeat yourself with the looping code, (c) it's immediately obvious what you're trying to do.
No matter what you are going to loop through the array somehow even it is obscured for you a bit by tools like jQuery.
You could create an object from the array as has been suggested like this:
var objLookup = function(arr, search) {
var o = {}, i, l, first, second;
for (i=0, l=arr.length; i<l; i++) {
first = arr[i][0]; // These variables are for convenience and readability.
second = arr[i][1]; // The function could be rewritten without them.
o[first] = second;
}
return o[search];
}
But the faster solution would be to just loop through the array and return the value as soon as it is found:
var indexLookup = function(arr, search){
var index = -1, i, l;
for (i = 0, l = arr.length; i<l; i++) {
if (arr[i][0] === search) return arr[i][1];
}
return undefined;
}
You could then just use these functions like this in your code so that you don't have to have the looping in the middle of all your code:
var log = [
["comp","Please add company name!"],
["zip","Please add zip code!"]
];
objLookup(log, "zip"); // Please add zip code!
indexLookup(log, "comp"); // Please add company name!
Here is a jsfiddle that shows these in use.
Have you looked at jQuery's grep or inArray method?
See this discussion
Are there any jquery features to query multi-dimensional arrays in a similar fashion to the DOM?

Need help with setting multiple array values to null in a loop - javascript

I have been working on creating a custom script to help manage a secret questions form for a login page. I am trying to make all the seperate select lists dynamic, in that if a user selects a question in one, it will no longer be an option in the rest, and so on. Anyways, the problem I am having is when I try to set the variables in the other lists to null. I am currently working with only 3 lists, so I look at one list, and find/delete matches in the other 2 lists. Here is my loop for deleting any matches.
for(i=0; i<array1.length; i++) {
if(array2[i].value == txtbox1.value) {
document.questions.questions2.options[i] = null
}
if(array3[i].value == txtbox1.value) {
document.questions.questions3.options[i] = null
}
}
This works fine if both the matches are located at the same value/position in the array. But if one match is at array1[1] and the other match is at array3[7] for example, then only the first match gets deleted and not the second. Is there something I am missing? Any help is appreciated. Thanks!
I don't see too many choices here, considering that the position in each array can vary.
Do it in separate loops, unless of course you repeat values in both arrays and share the same position
EDTI I figured out a simple solution, it may work, create a function. How about a function wich recives an array as parameter.
Something like this:
function finder(var array[], var valueToFound, var question) {
for (i=0; i<array.lenght; i++) {
if (array[i].value == valueToFound) {
switch (question) {
case 1: document.questions.questions1.options[i] = null;
break;
}
return;
}
}
}
I think i make my point, perhaps it can take you in the right direction
My bet is that the code isn't getting to array3[7] because either it doesn't exist or that array2 is too short and you're getting a JavaScript exception that's stopping the code from doing the check. Is it possible that array2 and array3 are shorter than array1?
It is more code, but I would do it like this:
var selectedvalue == txtbox1.value;
for(i=0; i<array2.length; i++) { // iterate over the length of array2, not array1
if(array2[i].value == selectedvalue) {
document.questions.questions2.options[i] = null;
break; // found it, move on
}
}
for(i=0; i<array3.length; i++) {
if(array3[i].value == selectedvalue) {
document.questions.questions3.options[i] = null;
break; // you're done
}
}

Internet Explorer 7 - Javascript 'undefined' not testing

I'm having trouble with some JS in IE7. I'm testing to see if a certain object has a className (its possibly an HTMLElement object from the DOM) assigned.
Now, testing the page in Firefox tells me that Yes, the variable is undefined (all my tests below do the Alert().
In IE, none of the tests pass, the variable gets assigned on the last IF statement, and during the last Alert() IE chucks an "className is null or not an object" error, based on the fn_note.className statement.
Here's the code:
var fn_note;
var kids = area.childNodes;
for (var l = 0; l < kids.length; l++){
//DEBUG check if the found var exists
if (kids[l].className == null){
//then the className var doens't exist
alert ('the classsname for the following var is null: --'+kids[l]+'--');
}
if (kids[l].className == undefined){
//then the className var doens't exist
alert ('the classsname for the following var is undefined: --'+kids[l]+'--');
}
if (kids[l].className == ''){
//then the className var doens't exist
alert ('the classsname for the following var is an empty string: --'+kids[l]+'--');
}
if (typeof kids[l].className === 'undefined'){
//then the className var doens't exist
alert ('the classsname for the following var is NEW TYPEOF TEST: --'+kids[l]+'--');
}
if (kids[l].className == 'fn-note') { /* (/fn-note$/).test(kids[l].className) IE doesn't really like regex. por supuesto */
//we have found the div we want to hide
fn_note = kids[l];
}
}
alert('the clicked on className is '+area.className+'name of the found div is '+fn_note.className);
Please let me know what I am doing wrong. I know its probably something basic but I just can't see it ATM.
Thanks in advance.
I think that what you get from the property is not a string, but an object of the type 'undefined'. Try this:
if (typeof(kids[l].className) == 'undefined') {
As far as I can see the only thing you really want to know is if there's a childNode with className 'fn-note' in the childNodes collection. So do a somewhat more rigourous test:
for (var l = 0; l < kids.length; l++){
if (kids[l]
&& kids[l].className
&& kids[l].className.match(/fn\-note$/i)) {
fn_note = kids[l];
}
}
This should be sufficient (do mind escaping the dash in the regexp).

Categories