11 Replies Latest reply on Apr 7, 2015 4:15 PM by AL3XIO

    object is undefined : why?

    AL3XIO

      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[n]);
                  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[n], 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[i] == "") {
                     what.splice(i, 1);
                  }
              }
          }
      // ========== THE END =========//
      
        • 1. Re: object is undefined : why?
          Peter Kahrel Adobe Community Professional & MVP

          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

          • 2. Re: object is undefined : why?
            AL3XIO Level 1

            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.

            Book project.jpg

             

            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.

            • 3. Re: object is undefined : why?
              Peter Kahrel Adobe Community Professional & MVP

              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?

              • 4. Re: object is undefined : why?
                AL3XIO Level 1

                Peter, this piece of code is one of those written by me, so there's no one to ask directly for help.

                You make me notice that decodeURI transforms the array into string, however, with array.split () the string is transformed back into array, right? So, at least in theory, this should not lead to any problems.

                Before opening this post I have spent many hours after dinner to try to figure out where I was wrong. By my reasoning there is no reason why the two objects are undefined, but obviously I'm wrong.

                Tonight I will check the correctness of my use of decodeURI.

                • 5. Re: object is undefined : why?
                  cchimi Level 2

                  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?

                  • 6. Re: object is undefined : why?
                    AL3XIO Level 1

                    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).

                    • 7. Re: object is undefined : why?
                      cchimi Level 2

                      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.

                      • 8. Re: object is undefined : why?
                        Marc Autret Level 4

                        Hi AL3XIO,

                         

                        Since left_data and right_data are multi-selection ListBoxes (due to multiselect: true) the selection property does not return a ListItem, but an Array of ListItem(s). Hence left_box.selection.index is undefined, as any other ListItem property that you wrongly assign to left_box.selection.

                         

                        So you probably have to check various things before you implement your MoveUp / MoveDown routines.

                        First, check that (left_box.selection!==null) as this happens if no item is selected.

                        Then, use left_box.selection.length in order to count and/or explore the selected items.

                         

                        @+

                        Marc

                        • 9. Re: object is undefined : why?
                          Marc Autret Level 4

                          @ cchimi

                           

                          You won ;-)

                          (Am I being too slow or too verbose? probably both!)

                           

                          @+

                          Marc

                          • 10. Re: object is undefined : why?
                            AL3XIO Level 1

                            @ cchimi, you are right !!! I had completely forgotten that I had set the listboxes as multiselection. Now I get the much longed values.

                             

                            @ Marc, it's true, I have to check many things before continuing with the development.

                             

                            Thank you both for the help, I had lost my way.

                            • 11. Re: object is undefined : why?
                              AL3XIO Level 1

                              @ Marc, provide the answer to the question is important, but not all. You add suggestions and supplemental information to help those who, like me, are trying to learn, and this takes time.