Skip to main content
Known Participant
April 7, 2015
Answered

object is undefined : why?

  • April 7, 2015
  • 2 replies
  • 1520 views

Hi all.

I'm working on a script to facilitate the creation and editing of books in InDesign. I'm not a programmer, and besides a few lines of code written by me, the script consists of code found and adapted to the purpose.

I have a problem related to two objects (left_box and right_box) : they appear to be undefined, therefore I can not operate on the elements that populate the listboxes that are contained in the objects themselves.

I have reviewed the code many times but I do not understand where I'm wrong.

Thanks in advance for any help.

This is the complete code :

#target indesign

#targetengine Main

// ============================== V A R I A B L E S =================================//

var theName, theFolder;

var right_arr = [];

var left_arr = [];

main_win();

// ============================== M A I N ===========================================//

// -------------------- Creation of main window -------------------------------------//

function main_win() {

var dialog_win = new Window ("palette", "Book creator / Book modificator");

    dialog_win.alignChildren = ["fill", "fill"];

    var group_width =  450;

    var group_length = 100;

    var char_length = 45;

    var pm_width = 200; // placemark

    var pm_length = 300 // placemark

    var group_group_1 = dialog_win.add("group");

        group_group_1.alignChildren = ["fill", "fill"];

        var step_group_1 = group_group_1.add("panel");

            step_group_1.preferredSize = [Math.round(group_width / 2), group_length];

            step_group_1.alignChildren = "fill";

            var info_text_1 = step_group_1.add("statictext", undefined, "STEP 1\rSelect the option you are interested in, in order to activate its controls.\rWith no choice, only QUIT button is working.\r\r", {multiline: true});

                info_text_1.alignment = "fill";

                info_text_1.characters = Math.round(group_width / 20);

            var radio_group = step_group_1.add("group");

                radio_group.orientation = "column";

                radio_group.alignChildren = "fill";

                var radio1 = radio_group.add("radiobutton", undefined, " Create a new book");

                var radio2 = radio_group.add("radiobutton", undefined, " Open a book to edit");

        var step_group_2 = group_group_1.add("panel");

            step_group_2.alignChildren = "left";

            var info_text_2 = step_group_2.add("statictext", undefined, "STEP 2\r• Create a new book : first of all choose the destination folder, then type the desired name (max " + (char_length - 10) + " characters) without extension.\r• Open a book to edit : I think you don't need special instructions, right?.\r\r", {multiline: true});

                info_text_2.alignment = "fill";

                info_text_2.characters = Math.round(group_width / 8);

            var button_group = step_group_2.add("group");

                button_group.alignment = "center";

                button_group.alignChildren = "fill";

                var new_button = button_group.add("button", undefined, "Destination folder...");

                var old_button = button_group.add("button", undefined, "Open a book...");

                    new_button.enabled = false;

                    old_button.enabled = false;

            var dir_group = step_group_2.add("group");

                dir_group.add('statictext {text: "Book folder :", justify: "right"}');

                dir_group.alignChildren = "right";

                var book_dir = dir_group.add("statictext", undefined, theFolder);

                    book_dir.characters = char_length;

            var name_group = step_group_2.add("group");

                name_group.add('statictext {text: "Book name :", justify: "right"}');

                dir_group.alignChildren = "right";

                var book_name = name_group.add("edittext", undefined, theName);

                    book_name.characters = char_length - 10;

                    book_name.enabled = false;

    var group_group_2 = dialog_win.add("group");

        group_group_2.alignChildren = ["fill", "fill"];

        var step_group_3 = group_group_2.add("panel");

            step_group_3.preferredSize = [group_width, group_length * 4];

            var group_a = step_group_3.add("group");

                group_a.orientation = "row";

                var info_text_3 = group_a.add("statictext", undefined, "STEP 3\r• The left side shows the contents of the book to which you can add or remove documents, and / or order them as you like.\r• The right side shows the documents that are available in the selected folder (if checkbox is selected, the search is also done in the subfolders). Any documents already in the book are not listed. This list is sorted alphabetically by default.\r\r", {multiline: true});

                    info_text_3.alignment = ["left", "top"];

                    info_text_3.characters = Math.round(group_width / 7);

                var sub_group_a = group_a.add("group");

                    sub_group_a.orientation = "column";

                    sub_group_a.alignChildren = ["fill", "fill"];

                    var list_button = sub_group_a.add("button", undefined, "Files to add...");

                        list_button.enabled = false;

                    var check_sub = sub_group_a.add("checkbox", undefined, "Search in sub-folders");

                        check_sub.enabled = false;

                        check_sub.value = false;

            var group_b = step_group_3.add("group");

                var button_group_LS = group_b.add("group");

                    var move_group_LS = button_group_LS.add("group");

                        move_group_LS.orientation = "column";

                        move_group_LS.alignChildren = ["fill", "fill"];

                        var move_up = move_group_LS.add("button", undefined, "Move up");

                        var move_down = move_group_LS.add("button", undefined, "Move down");

                        button_group_LS.children[0].enabled = false;

                var list_group_LS = group_b.add("group");

                    var left_box = add_left (list_group_LS, left_arr);

                        left_box.preferredSize = [pm_width, pm_length];

                        function add_left (left_case, left_arr) {

                            var left_data = left_case.add("listbox", undefined, left_arr, {multiselect: true, showHeaders: true, columnTitles: [" > BOOK CONTENTS"]});

                            return left_data;

                        }

                        list_group_LS.children[0].enabled = false;

                var list_group_RS = group_b.add("group");

                    var right_box = add_right (list_group_RS, right_arr);

                        right_box.preferredSize = [pm_width, pm_length]

                        function add_right (right_case, right_arr) {

                            var right_data = right_case.add("listbox", undefined, right_arr, {multiselect: true, showHeaders: true, columnTitles: [" > AVAILABLE DOCUMENTS "]});

                            return right_data;

                        }

                        list_group_RS.children[0].enabled = false;

                var button_group_RS = group_b.add("group");

                    var move_group_RS = button_group_RS.add("group");

                        move_group_RS.orientation = "column";

                        move_group_RS.alignChildren = ["fill", "fill"];

                        var add_doc = move_group_RS.add("button", undefined, "Add to book");

                        var remove_doc = move_group_RS.add("button", undefined, "Remove from book");

                        button_group_RS.children[0].enabled = false;

    var button_dialog = dialog_win.add("group");

        button_dialog.alignment = "right";

        var quit_button = button_dialog.add("button", undefined, "QUIT");

        var doit_button = button_dialog.add("button", undefined, "DO IT");

            doit_button.enabled = false;

// -------------------- Evaluate choices --------------------------------------------//

    // --- STEP 1 ---//

    radio1.onClick = function() {

        check_open();

        new_button.enabled = true;

        old_button.enabled = false;

        new_button.active = true;

    };

    radio2.onClick = function() {

        check_open();

        new_button.enabled = false;

        old_button.enabled = true;

        old_button.active = true;

    };

    // --- STEP 2 ---//

    new_button.onClick = function() {

        book_name.text = "";

        new_book = Folder.selectDialog ("Choose the destination folder for the new book...");

        if (left_box.items.length > 0) {

            left_arr = [];

            upd_left(left_box);

        }

        if (new_book != null) {

            book_dir.text = path_trim(new_book.fsName);

        }

        book_name.enabled = true;

        book_name.active = true;

        list_button.enabled = true;

        check_sub.enabled = true;

    };

    book_name.onChanging = function() {

        max_char = book_name.text;

        if (max_char.length > book_name.characters) {

            book_name.text = "";

            book_name.textselection = max_char.slice(0, book_name.characters);

        }

    };

    old_button.onClick = function() {

        old_book = File.openDialog ("Select the book file to open...", let_me_see, true);

        if (left_box.items.length > 0) {

            left_arr = [];

            upd_left(left_box);

        }

        if (old_book != null) {

            book_dir.text = path_trim(old_book);

            book_split(book_dir.text);

            book_dir.text = the_folder;

            book_name.text = the_name;

        }

        get_Docs(old_book);

        clean(left_arr);

        list_group_LS.remove(list_group_LS.children[0]);

        left_box = add_left (list_group_LS, left_arr);

        left_box.preferredSize = [pm_width, pm_length];

        book_name.enabled = false;

        list_button.enabled = true;

        list_button.active = true;

        check_sub.enabled = true;

        dialog_win.layout.layout(true);

    };

    // --- STEP 3 ---//

    list_button.onClick = function() {

        var myFolder = Folder.selectDialog("Select a folder in which to search for documents...");

        if (right_box.items.length > 0) {

            right_arr = [];

            upd_right(right_box);

        }

        check_folder(myFolder, check_sub.value);

        right_arr.sort();                   // sorting the values of the array

        right_arr = decodeURI(right_arr);   // replacing %20 with space

        right_arr = right_arr.split(',');   // converting into array

        var the_right_arr = right_arr.slice();

            right_arr = [];

            getFileName(the_right_arr);

        list_group_RS.remove(list_group_RS.children[0]);

        right_box = add_right (list_group_RS, right_arr);

        right_box.preferredSize = [pm_width, pm_length];

        list_group_LS.children[0].enabled = true;

        list_group_RS.children[0].enabled = true;

        button_group_LS.children[0].enabled = true;

        button_group_RS.children[0].enabled = true;

        doit_button.enabled = true;

        dialog_win.layout.layout(true);

    };

    move_up.onClick = function () {

        var n = left_box.selection.index;

        if(n > 0) {

            swap (left_box.items[n - 1], left_box.items);

            left_box.selection = n - 1;

        }

    }

    move_down.onClick = function () {

        var n = left_box.selection.index;

        if (n < left_box.items.length - 1) {

            swap (left_box.items, left_box.items[n + 1]);

            left_box.selection = n + 1;

        }

    }

    add_doc.onClick = function() {

        // something ...

    }

    remove_doc.onClick = function() {

        left_arr.splice(left_box.selection.index, 1);

        upd_left(left_box);

    }

    // --- LAST STEP ---//

    quit_button.onClick = function() {

        dialog_win.close();

    }

    doit_button.onClick = function() {

        if (book_name.text != "") {

            check_book(new_book, book_name);

        }

        else {

            alert("The book name is missing.");

        }

    };

    check_open();

    dialog_win.show ();

}

// ============================== F U N C T I O N S =================================//

// --- BEGINNIG ---//

    // -------------------- Check for open book files -----------------------------------//

    function check_open() {

        if (app.books.length != 0) {

            var q = confirm("All book files must be closed before proceeding. If you press YES I will close them for you, otherwise press NO and close them manually.");

            if (q == true) {

                for (var x1 = 0; x1 < app.books.length; x1++) {

                    var open = app.books[x1];

                    open.close();

                    radio1.checked = false;

                    radio2.checked = false;

            }

            } else {

                exit(0);

            }

        }

    }

// --- STEP 2 NEW BOOK / OLD BOOK ---//

    // -------------------- Adapt directory text to max length of the static text ---//

    function path_trim(path) {

        var theFile = new File(path);

        var pathTrim = ".../" + theFile.fsName.split("/").splice(0).join("/");

        if ((pathTrim.length - 50) < 50) {

            pathTrim = ".../" + theFile.fsName.split("/").splice(-3).join("/");

        }

        else if ((pathTrim.length - 50) > 50) {

            pathTrim = ".../" + theFile.fsName.split("/").splice(-2).join("/");

        }

        return pathTrim;

    }

// --- STEP 2 OLD - LEFT SIDE ---//

    // -------------------- Selection of what can be shown in dialog window ---------//

    function let_me_see(bookPath){

        if (bookPath.constructor.name == "Folder") {return true}

        if (bookPath.name.slice(-5) == ".indb") {return true}

            return false;

    }

    // -------------------- Extraction of the book name and its path ----------------//

    function book_split(split_it) {

        var the_path = new File(split_it);

        var book_path = decodeURI(String(the_path));

        //  the_name.text = book_path.pop(); // file name with extension

            the_name = (book_path.split('/').pop().split('.'))[0];

            the_folder = book_path.split("/").slice(0, -1).join("/");

            while (the_folder.charAt(0)=='/') the_folder = the_folder.substring(1,the_folder.length);

            return [the_name, the_folder];

    }

    // -------------------- Left list update ----------------------------------------//

    function upd_left(left_data) {

        left_data.removeAll();

        var x2 = 0;

        while (left_data.items.length < left_arr.length) {

            left_data.add(left_arr[x2]);

            x2++;

        }

    }

    // -------------------- Extract document name from book -------------------------//

    function get_Docs(doc) {

        app.open(doc);

        var book_ref = app.activeBook;

        for (var x3 = 0; x3 < book_ref.bookContents.length; x3++){

            left_arr += book_ref.bookContents[x3].name;

        }

        book_ref.close();

        left_arr = left_arr.split('.indd'); // converting into array

        return doc;

    }

// --- STEP 3 RIGHT SIDE ---//

    // -------------------- Right list update ---------------------------------------//

    function upd_right(right_data) {

        right_data.removeAll();

        var x5 = 0;

        while (right_data.items.length < right_arr.length) {

            right_data.add(right_arr[x5]);

            x5++;

        }

    }

    // -------------------- Files search through folders ----------------------------//

    function check_folder(folder, sub_dir) {

        var myFilesList = folder.getFiles();

        for (var x6 = 0; x6 < myFilesList.length; x6++) {

            var myList = myFilesList[x6];

            if (myList instanceof File && myList.name.match(/\.indd$/i)) {

                right_arr.push(myList);

            }

            else if (myList instanceof Folder) {

                if (sub_dir == true) {

                    check_folder(myList);

                }

            }

        }

        return folder;

    }

    // -------------------- Extract document name from folders list -----------------//

    function getFileName(value) {

        for (var x7 = 0; x7 < value.length; x7++){

            var theFile = (value[x7].split('/').pop().split('.indd'))[0];

                right_arr.push(theFile);

        }

        right_arr.sort();

        return value;

    }

    // -------------------- Swap for move up and move down --------------------------//

    function swap (x, y) {

        var temp = x.text; x.text = y.text; y.text = temp;

    }

// --- LAST STEP ---//

    // -------------------- Check existance -----------------------------------------//

    function check_book(check_dir, check_name) {

        var check_path = check_dir + "/" + check_name.text + ".indb";

        if (File(check_path).exists == true) {

            alert("A book with the same name already exists, please change the name.");

        } else {

        // something

            alert("ALL DONE");

        }

    }

// ========== UTILIY ==========//

    // -------------------- Remove empty records ------------------------------------//

    function clean(what) {

        for(var i = what.length - 1; i >= 0; i--) {

            if(what == "") {

               what.splice(i, 1);

            }

        }

    }

// ========== THE END =========//

This topic has been closed for replies.
Correct answer cchimi

Both of your listboxes are multiselect, so selection returns an array. Change left_box.selection to left_box.selection[0] and you should get a result.

2 replies

Inspiring
April 7, 2015

Why do you think those variables are undefined? Are you getting a specific error? If so, where does debugger stop?

When I run your code, I get a dialog that looks like yours. If I complete step 1 and step 2 and then add files, I see files in the right box (called Available Documents). If I try to use Add to book, nothing happens - but that is expected because that piece of code is yet to be written:

    add_doc.onClick = function() {

        // something ...

    }

But if I set a breakpoint to that function and then query right_box and left_box from the console they seem fine. So, where exactly is your code breaking down?

AL3XIOAuthor
Known Participant
April 7, 2015

Hi cchimi,

I get no errors at all, simply Move up and Move down buttons don't work as expected.

By adding alert("selection.index = " + left_box.selection.index + "\r" + "selection.text = " + left_box.selection.text); at line 236 (under move_up.onClick) I get undefined as result, while I should receive the values referred to the choosen item on left side (under Book contents). Without these values I'm not able to interact with items (and I suppose will be the same on right side).

cchimiCorrect answer
Inspiring
April 7, 2015

Both of your listboxes are multiselect, so selection returns an array. Change left_box.selection to left_box.selection[0] and you should get a result.

Peter Kahrel
Community Expert
Community Expert
April 7, 2015

You can't really expect anyone to read that much code, without a sample to run the script against and see what happens. But by chance I noticed these lines:

right_arr.sort();                  // sorting the values of the array 

right_arr = decodeURI(right_arr);  // replacing %20 with space 

right_arr = right_arr.split(',');

which are probably the source of the problem. decodeURI() is a string function, not an array function. Unfortunately, instead of throwing an error, it converts an array to a string:

a = ['a%20b'];

$.writeln (a.constructor.name);  // Array

s = decodeURI(a);

$.writeln (s.constructor.name);  // String

You need to change %20 to a space in each individual array element. If this doesn't solve the problem you'll have to find the person who wrote the code and ask them to fix it.

Peter

AL3XIOAuthor
Known Participant
April 7, 2015

Hi Peter,

you're right, there are many lines of code, but how can I get help on a problem if I do not provide the necessary material? At least, with the complete code available, you can run it and test it in InDesign.

If it can be useful, I enclose a picture of how it looks.

As you can see I can populate both listboxes, but since objects that contain them are undefined, the buttons "Move up" and "Move down" do not work ("Add" and "Remove" are still with no code).

Without a solution to the problem I'm stuck.

Peter Kahrel
Community Expert
Community Expert
April 7, 2015

You said you found the code somewhere. Where did you find it? Can you not contact the person who wrote it?

And did you check the correctness of your use of decodeURI?