Isaac Harned – Here for forms with javascript

  • Isaac Harned – Here for forms with javascript

    Posted by Isaac Harned on September 23, 2022 at 12:37 pm

    Thank you for the opportunity to join the group, I see a couple faces from XCon floating around!

    Attached is the project I am currently working on. This is for a new type of State Certified testing we are getting into for Hood Certifications. We want the form to be customizable in the field based on the amount and layout of equipment. My issues are two fold:

    1. The drop down in the top right that selects the number of terminal units is buggy and will occasionally crash the document with no pattern seen.

    2. This document does not work very well on systems with low resources, looking for ideas on consolidating code, or any other ideas to make this form usable on any system.

    Thank you guys, I know there are way bigger brains than me in this forum, and I appreciate the help. Learning as I go has been a struggle.

    Liz Larsen replied 1 year, 4 months ago 5 Members · 38 Replies
  • 38 Replies
  • David Cutler

    Member
    October 6, 2022 at 8:02 am
    Points: 23,092
    Rank: UC2 Brainery Brown Belt III UC2 Brainery Brown Belt III

    Quite the process you have going there @isaac-harned !

    Unfortunately I’m not one to help with JavaScript. Perhaps @lizlarsen or @Doug McLean could provide some thoughts on this?

    • Isaac Harned

      Member
      October 6, 2022 at 9:42 am
      Points: 6,049
      Rank: UC2 Brainery Purple Belt I UC2 Brainery Purple Belt I

      I am actually making progress, once I get everything positioned right on the reduced page size and flatten the boxes, I am hopeful that will reduce a lot of the strain. Did a small test with the larger page size and it loaded pretty quick. I think the dropdown issue is not necessarily a coding problem, but hopefully the Engineering team can get back to me with some kind of answer.

      I am now having a separate issue with form fields created in Revu 21. It seems the Auto text size is broken, and doesn’t fix itself when opened in Revu 20. Support tried telling me it only adjusts vertically NOT horizontally. Was pretty thrown off by that response, so I’m escalating.

      • David Cutler

        Member
        October 6, 2022 at 10:01 am
        Points: 23,092
        Rank: UC2 Brainery Brown Belt III UC2 Brainery Brown Belt III

        Glad to hear that you are making progress @isaac-harned . I’ve been planning an upgrade to my takeoff tools for a while, but I haven’t made the time to get it done…

        Hope that Bluebeam can get the auto size issue resolved for you. Autoformat features are great when they work the way you want them too, and frustrating when they don’t!

        Welcome to the Brainery BTW!

        • Isaac Harned

          Member
          October 10, 2022 at 8:28 am
          Points: 6,049
          Rank: UC2 Brainery Purple Belt I UC2 Brainery Purple Belt I

          Thank you David, and I will keep you guys posted on the Autosize!

      • Isaac Harned

        Member
        October 28, 2022 at 5:03 pm
        Points: 6,049
        Rank: UC2 Brainery Purple Belt I UC2 Brainery Purple Belt I

        The solution to this was simply the page size. 11 x 17 does not give the font enough of a lower size range to adjust. I had to tell Bluebeam support why this was happening, and that their text boxes DO adjust vertically AND horizontally. 36 x 24 works just fine.

        🙄

        • David Cutler

          Member
          October 30, 2022 at 10:34 am
          Points: 23,092
          Rank: UC2 Brainery Brown Belt III UC2 Brainery Brown Belt III

          Thank you for the update on one of the original questions @isaac-harned

          Always interesting when you can stump the support folks! At the same time, no matter how much training they have I’m sure customers like us find ways to bend and break the software that their developers never imagined. 🙂

          Now that you’ve posted this perhaps the solution will pop up in some tech support person’s internet search…

          Nice job figuring the auto size issue out. Thank you for sharing the solution with us all.

    • Doug McLean

      Member
      October 27, 2022 at 1:32 pm
      Points: 12,350
      Rank: UC2 Brainery Blue Belt II UC2 Brainery Blue Belt II

      Oh don’t rely on me for JavaScript.
      I’m too busy learning M code to learn Javascript

  • Troy DeGroot

    Organizer
    October 6, 2022 at 10:05 am
    Points: 20,764
    Rank: UC2 Brainery Brown Belt UC2 Brainery Advanced Brown Belt Rank

    Awesome post @isaac-harned

    JavaScript is not my expertise either, but I’m hear to learn. Thanks for being part of the community here.

    • Isaac Harned

      Member
      October 10, 2022 at 8:28 am
      Points: 6,049
      Rank: UC2 Brainery Purple Belt I UC2 Brainery Purple Belt I

      Thank you Troy!

  • Liz Larsen

    Member
    October 6, 2022 at 7:01 pm
    Points: 4,629
    Rank: UC2 Brainery Orange Belt IIII UC2 Brainery Orange Belt IIII

    First of all, this is a really clever system.

    Next, for the dropdowns, I noticed the trigger was set to “on blur” rather than the standard “mouse up”. Can you explain your reasoning? I never use it in Bluebeam forms and am genuinely curious as to when/why I might want to.

    I ask because for the “on blur” to trigger, you actually have to click outside of the dropdown. So, for example, I can change one of the dropdowns from 3 to 4, and you won’t see the update of an additional line until I, the user, actively click outside of the dropdown box (or tab, or hit enter). Whereas if you use “mouse up”, the change happens immediately.

    I suspect (but have no way of knowing for certain) that the lag issue is caused by so many “global scripts” rather than storing the scripts within the individual form fields’ JavaScript.

    Also, if I were you, I would perhaps find a way to use regex to reduce the need for the verbosity that currently exists. There is a coding principal that I’m quite fond of called DRY (Don’t Repeat Yourself). I think you could reduce the number of scripts (Set Taps Box 1, Set Taps Box 2, etc…) and reduce the length of the scripts themselves (FindOCG(“6-1”), FindOCG(“6-2”), etc…) by using regular expressions to loop through these, thereby reducing the amount of code you have.

    Again, really clever use of forms and JavaScript here. I only spent about 15 minutes looking over your sheet, so I’m probably missing some intricacies of how everything works. Feel free to reach out for further discussion. I love what you’ve accomplished so far.

    • Isaac Harned

      Member
      October 10, 2022 at 8:27 am
      Points: 6,049
      Rank: UC2 Brainery Purple Belt I UC2 Brainery Purple Belt I

      Thank you so much for taking time Liz, You may just save the day on this one.

      The “On blur” was actually a work around to make iPad feasible (no mouse, no mouse up), but that may not even be possible with the amount of layers. Testing to come on this.

      I am going to add the scripts to the dropdowns today, will post back and let you know.

      Regex in java may take me a bit to learn, but maybe some progress here by the end of week.

      • Liz Larsen

        Member
        October 10, 2022 at 4:44 pm
        Points: 4,629
        Rank: UC2 Brainery Orange Belt IIII UC2 Brainery Orange Belt IIII

        I used regex in this game I made within Bluebeam.

        See the attached PDF and screenshot.

        The screenshot was taken from the code attached to any of the Square buttons (Square1, Square2, etc…)

        Basically, the code that uses the regex loops through all the gray/cyan buttons to see if any of them are cyan to test for a win/lose condition. Since there are a couple other buttons, I wanted this particular for loop to ignore those. That’s why all the buttons have a consistent naming scheme. The regex looks for form fields with the word “Square” followed by 1 or 2 digits, and ignores everything else.

        If you’d like a free, interactive place to learn and practice some regular expressions, I recommend Free Code Camp. They have a course called JavaScript Algorithms and Data Structures (https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/). The Regular Expressions are the 3rd section when you scroll down.

        I also just found this site 5 seconds ago that seems like it would be very helpful (and free): https://regexlearn.com/learn/regex101

        Hopefully this gets your brain thinking about methods to condense some of your functions and how you can then combine some of your functions into a single function. Good luck and let me know if you need anymore help!

        • David Cutler

          Member
          October 11, 2022 at 5:53 am
          Points: 23,092
          Rank: UC2 Brainery Brown Belt III UC2 Brainery Brown Belt III

          A game made in Revu? That takes the cake for most creative use of Revu that I’ve seen (so far at least) @lizlarsen !

          🙂

        • Liz Larsen

          Member
          October 27, 2022 at 6:57 am
          Points: 4,629
          Rank: UC2 Brainery Orange Belt IIII UC2 Brainery Orange Belt IIII

          To help explain regular expressions and how they work with JavaScript in Bluebeam, I made a video.

          Regular expressions lend themselves really well to writing code in JavaScript. It’ll vastly cut down on code bloat due to hard-coding form field or layer names, plus it’ll make your code more versatile in the future since the regular expression will take care of any new form fields that follow the naming convention you’ve already set.

          Not sure if that makes sense, but the video will help with that.

          https://youtu.be/LoG4BnefDRo

          • David Cutler

            Member
            October 27, 2022 at 7:52 am
            Points: 23,092
            Rank: UC2 Brainery Brown Belt III UC2 Brainery Brown Belt III

            Great video @lizlarsen ! This Java Script stuff is all Greek to me, but I think I might understand a word or two of it after watching your video. The tools that you showed for checking code and such look very useful.

            You are also either an amazing editor or just really good at getting everything recorded in 1 take!

            • Liz Larsen

              Member
              October 27, 2022 at 9:40 am
              Points: 4,629
              Rank: UC2 Brainery Orange Belt IIII UC2 Brainery Orange Belt IIII

              I recorded everything in one take, first try 😂 I didn’t like how the sound quality came out, so I contemplated re-recording but decided against it. I hope people give me some grace for my first ever video.

            • David Cutler

              Member
              October 27, 2022 at 9:47 am
              Points: 23,092
              Rank: UC2 Brainery Brown Belt III UC2 Brainery Brown Belt III

              You did amazing @lizlarsen especially for your first video!🙂

  • Troy DeGroot

    Organizer
    October 10, 2022 at 2:35 pm
    Points: 20,764
    Rank: UC2 Brainery Brown Belt UC2 Brainery Advanced Brown Belt Rank

    Love this collaboration. Thanks to both of you.

  • Isaac Harned

    Member
    October 24, 2022 at 1:28 pm
    Points: 6,049
    Rank: UC2 Brainery Purple Belt I UC2 Brainery Purple Belt I

    Here is the latest update to the code and the file. Major thanks to Liz for all the help!

    • David Cutler

      Member
      October 24, 2022 at 2:52 pm
      Points: 23,092
      Rank: UC2 Brainery Brown Belt III UC2 Brainery Brown Belt III

      Great to hear that you are making progress @isaac-harned . If anyone can help you with these types of functions it’s @lizlarsen !

      Looking forward to seeing where you take this.

      Dave

  • Isaac Harned

    Member
    October 26, 2022 at 5:00 pm
    Points: 6,049
    Rank: UC2 Brainery Purple Belt I UC2 Brainery Purple Belt I

    The struggle continues, Children layers do not want to activate and deactivate.

    I have tried switching tactics by using substrings to try and match some of these values, using the dash as a placeholder for values before and after. I attempt to grab before the dash to match with the parent, and after the dash to determine if the applicable “NumberOfTaps” dropdown signals the layer to be on or off. Nothing seems to be working on this front

    Now also having an issue where layers print settings turn off when I change the initState, even though these are set to “Use Default”. tried submitting this issue to Bluebeam, however they tell me they cannot provide assistance with custom code. I guess I must find a way to change the print setting for the layer as well. I have tried modifying the code so that it ONLY targets the initState, but this does not help.

    There is also now a third array of OCGs, this is to turn off all children of parents that have been deactivated. This one is also having the same difficulty as the other loop targeting children layers.

    I am getting no specific errors, except for the console displaying a single “false”

    • Isaac Harned

      Member
      October 26, 2022 at 7:02 pm
      Points: 6,049
      Rank: UC2 Brainery Purple Belt I UC2 Brainery Purple Belt I

      Here is the latest file with the dropdown coded, sorry for not getting this in earlier

      • Liz Larsen

        Member
        October 26, 2022 at 10:21 pm
        Points: 4,629
        Rank: UC2 Brainery Orange Belt IIII UC2 Brainery Orange Belt IIII

        Ok, so, I wasn’t sure why it wasn’t working.

        I ended up writing the NumberOfTerminals dropdown box code from scratch to better learn how everything works. I like to do this piece by piece in the console first to make sure my code is doing what I expect. If it’s not, I troubleshoot until I get an expected result. Then I add that code to my overall code. Rinse and repeat until I have something that works.

        This process has two benefits:

        1. I don’t have to search a huge block of code for errors since I’m basically testing one thing at a time.
        2. I learn more about how JavaScript itself works and how to get it to effectively “talk” to Bluebeam.

        I did get something that works (attached) and even though it works, I still get some “false” and “undefined” stuff showing up in the console, not sure why that’s appearing or if it’ll be troublesome later.

        I must go to bed now because it’s late, but take a look at what I wrote and let me know what you think.

      • Liz Larsen

        Member
        October 26, 2022 at 10:23 pm
        Points: 4,629
        Rank: UC2 Brainery Orange Belt IIII UC2 Brainery Orange Belt IIII

        Additionally, since I went through the process on my own and learned a lot, I’m going to look through your code tomorrow and see if I can figure out why it wasn’t working.

        • Isaac Harned

          Member
          October 27, 2022 at 9:28 am
          Points: 6,049
          Rank: UC2 Brainery Purple Belt I UC2 Brainery Purple Belt I

          Oh my goodness Liz, you are amazing. It works for sure!!

          I am still having the issue of the print setting for the layer toggling off and not back on, will test some more with that.

          I am going to work today to modify all the individual dropdowns so that expressions can be applied to all, but this is so fantastic!!

          Couple of small questions on the code:

          1. The regex variable tapsMask, is this to filter out all layers that are not associated with the terminal and tap dropdowns (i.e. RACH layers)?

          2. The double vertical bars, is this an OR statement? Seems like you are testing either the full fname OR the substring prior to the dash.

          I have attached a screenshot of the code with some detailed notes for anyone hoping to follow along, please feel free to correct me @lizlarsen if I misinterpret anything! The file below is the latest with the new code loaded into dropdown. Sub dropdowns have not been 100% coded yet, but check out how fast this file moves now!!!

          • Liz Larsen

            Member
            October 27, 2022 at 5:57 pm
            Points: 4,629
            Rank: UC2 Brainery Orange Belt IIII UC2 Brainery Orange Belt IIII

            The tapsMask will match either parent or child layers for all the terminal layers. So it’ll match standalone digits up to 99 and it’ll match any of those with child layers, ie 1-1, 1-2, etc… up to 99-99. I did this because I knew all parent or child layers greater than the number of terminals should be off and it was easy to just turn them all off.

            Then the next else if looks for just parent terminal layers (ie 1 or 2 digits only) less than or equal to the number of terminals and turns those on.

            Then the last else if looks for children terminal layers that are less than or equal to the number of taps for that particular parent layer and turns those on, if that fails, turn the rest for that tap off.

            —————————————————————————————-

            The double vertical lines || are indeed an OR test. That first if statement only cares if the first two digits are greater than the number of terminals, so the OR is looking for up to 2 digits only OR 2 digits that come before a “-” dash.

            —————————————————————————————-

            Thank you for commenting the code better than I did. I started to, and then kinda stopped… I make an attempt, but not a very good attempt when it comes to that.

            • Isaac Harned

              Member
              October 28, 2022 at 9:11 am
              Points: 6,049
              Rank: UC2 Brainery Purple Belt I UC2 Brainery Purple Belt I

              Thank you Liz, super helpful!!!!!!

  • Isaac Harned

    Member
    October 27, 2022 at 5:12 pm
    Points: 6,049
    Rank: UC2 Brainery Purple Belt I UC2 Brainery Purple Belt I

    Form is 100% working, not crashing, and is fast as all get out.

    Attached is the working file, all code is placed inside of each dropdown.

    Still a little confused on how the layers turn off their print setting, but the issue there is probably not code related.

    Can’t thank you enough @lizlarsen , let me know what you think of the modifications I made for the individual dropdown code!

    • Liz Larsen

      Member
      October 27, 2022 at 8:02 pm
      Points: 4,629
      Rank: UC2 Brainery Orange Belt IIII UC2 Brainery Orange Belt IIII

      My last little tiny piece of advice would be to move the primary code from the dropdown boxes (ie the NumberOfTaps_ form field local code) into one single function within the global JavaScript. Then in each dropdown box local code, you would set a variable like var numberOfTaps = this.getField(“NumberOfTaps2”); then call the global function using that variable.

      This means if you need to update the primary code, you only have to update the global function rather than every single dropdown box.

      I did not do this for my game that I made (and posted earlier in this thread) and I should have. At some point I’ll go update it to fix that. Cuz let me tell you, it was a PAIN to update the virtually identical code in every single square for some silly little mistake when I was in the process of creating it. Oof.

      I hope that makes sense. If you need additional explanation or help, let me know.

      • Liz Larsen

        Member
        October 27, 2022 at 9:29 pm
        Points: 4,629
        Rank: UC2 Brainery Orange Belt IIII UC2 Brainery Orange Belt IIII

        I actually started working on this and it’s more difficult than initially anticipated. However, I think I’m onto something and I’ll update you when I figure it out. Stay tuned!

        • Liz Larsen

          Member
          October 27, 2022 at 10:00 pm
          Points: 4,629
          Rank: UC2 Brainery Orange Belt IIII UC2 Brainery Orange Belt IIII

          YAAAASSSS! I got it. Man, nothing like the adrenaline rush of successful code at almost 11pm on a school night.

          Ok, I wrote some code so that all your NumberOfTaps__ dropdowns will have the same code verbatim. No need to specify what terminal it is or manually update this in any way. See the attached local code text file.

          Then, that dropdown code calls a global function that does all the work. See the attached global code.

          This means that if you add more terminals in the future, there’s no manually updating the code. Just copy the local code into the dropdown, label your layers and form fields correctly, and the code takes care of the rest.

          • Liz Larsen

            Member
            October 27, 2022 at 10:15 pm
            Points: 4,629
            Rank: UC2 Brainery Orange Belt IIII UC2 Brainery Orange Belt IIII

            It would help if I actually attached the text files…. It’s late. I’m tired.

            • Isaac Harned

              Member
              October 28, 2022 at 8:57 am
              Points: 6,049
              Rank: UC2 Brainery Purple Belt I UC2 Brainery Purple Belt I

              So in the local code, the line:

              var tap = dropDownName.match(/\d{1,2}$/)

              Does this only store what is matched? I.e. it looks at NumberOfTaps1, and only stores the “1” since it matches the search for 1 or 2 digits at the end of the string?

            • Isaac Harned

              Member
              October 28, 2022 at 9:10 am
              Points: 6,049
              Rank: UC2 Brainery Purple Belt I UC2 Brainery Purple Belt I

              Also the line:

              let childMask = new RegExp(“^” + tap + “-[\\d]{1,2}$”);

              when I plug this into regex101, I get some weird search parameters. Never worked with the RegEx constructor, so please bear with me here =)

              So if the previous tap variable only stores the number at the end of the string (Let’s say NumberOfTaps1), then this would be constructed as such:

              /^1-[\\d]{1,2}$/

              The part that is tripping me up is the double slashes I think, what does this do to the digit search?

            • Isaac Harned

              Member
              October 31, 2022 at 8:45 am
              Points: 6,049
              Rank: UC2 Brainery Purple Belt I UC2 Brainery Purple Belt I

              Liz let me know that since this is not a pre-constructed regex, and the part being built to look for a digit is in quotations, JavaScript sees this as an escape character. In order to keep the expression intact, a second backslash was added to the digit search.

            • Liz Larsen

              Member
              October 31, 2022 at 6:41 pm
              Points: 4,629
              Rank: UC2 Brainery Orange Belt IIII UC2 Brainery Orange Belt IIII

              @isaac-harned

              Also the line:

              let childMask = new RegExp(“^” + tap + “-[\\d]{1,2}$”);

              when I plug this into regex101, I get some weird search parameters. Never worked with the RegEx constructor, so please bear with me here =)

              So if the previous tap variable only stores the number at the end of the string (Let’s say NumberOfTaps1), then this would be constructed as such:

              /^1-[\\d]{1,2}$/

              The part that is tripping me up is the double slashes I think, what does this do to the digit search?

              You can’t plug that particular regular expression into regex101. That website is meant for only regular expressions, not for any other code (ie JavaScript).

              The new RegExp(“string”) is JavaScript, therefore regex101 doesn’t know what to do with it.

              new RegExp(“string”) allows you to take a string and let JavaScript know to turn it into a regular expression. Just like any other string, we can add variables.

              var name = "Liz";
              console.println("Hello, my name is " + name + ".");

              The code above will print “Hello, my name is Liz.” to the console. This is basically what we’re doing, except with a regular expression as the end result.

              To answer your original question, we use the double slashes because new RegExp is a string and the \ is an escape character in JavaScript. To escape an escape character, we have to add an additional \. The first \ is the escape character, letting JavaScript know that the second \ is to be interpreted as a string character.

              To test that this code works, I went to codepen.io. You can see in the attached photo how heavily I have to edit the global code to test the functionality. But it was enough proof of concept for me to know that the tap variable in my childMask regular expression was working.

              I hope that makes sense.

            • Liz Larsen

              Member
              October 31, 2022 at 6:03 pm
              Points: 4,629
              Rank: UC2 Brainery Orange Belt IIII UC2 Brainery Orange Belt IIII

              @isaac-harned

              So in the local code, the line:

              var tap = dropDownName.match(/\d{1,2}$/)

              Does this only store what is matched? I.e. it looks at NumberOfTaps1, and only stores the “1” since it matches the search for 1 or 2 digits at the end of the string?

              Yes, you got it. The tap variable stores the number of taps for that particular terminal. (I always hope that I’m using the correct terminology for your PDF)

              var dropDownName = event.target.name stores the name of the dropdown box

              var tap = dropDownName.match(/\d{1,2}$/) stores the digit on the end of the dropDownName, thereby effectively finding the layer it’s on.

              That tap variable is then passed to the global code, which turns the appropriate layers on or off.

  • David Cutler

    Member
    October 27, 2022 at 6:40 pm
    Points: 23,092
    Rank: UC2 Brainery Brown Belt III UC2 Brainery Brown Belt III

    Awesome collaboration @isaac-harned and @lizlarsen ! Glad that you were able to help each other figure this out and give us a bit of a look “behind the code”. 🙂

Log in to reply.