0

Copy to clipboard: Multi-line referenced table

Hi Folks, 

Here's a doozy (well, hopefully not). I'd like to add a 'Copy' button below a referenced table "Project Details". Within that table, I'd like to copy a couple of fields: "Item Detail" and "Item Total".

I'd like for them to paste like this:

Item Detail #1 ..........$Item Total #1
Item Detail #2 ..........$Item Total #2
Item Detail #3 ..........$Item Total #3
and so on...

I've come to figure out that there's not a way to do that with an actual button, so by combing through other Ninox threads and questions I've figured out how to style a button using a formula field.

Additionally, I've been working with AI to try and put some code together to get the formatting I've outlined above. 

I'm getting there, but pretty hung up on adding the paragraph returns (line breaks) after each line.

As it stands the current code (copied below) returns something like this:

Item Detail #1Item Detail #2Item Detail #3..........$

Item Total #1Item Total #2Item Total #3
So, the <br> is working, but not doing it for every line, nor is it in the correct order. Here's the code I have currently:
 

let outputList := "";
let details := 'Project Details';
for r in details do
    outputList := outputList + r.'Item Details' + " ...............$ " + r.'Item Total' + "<br>"
end;

html("
<style>
    .customButton {
        height: 25px;
        width: 105px;
        background-color: #5e6e9c;
        border: none;
        color: #fff;
        font-weight: bold;
        padding: 5px;
    }
</style>

<button class='customButton' onclick='CopyEstimate(getDetails())'>Copy Estimate</button>

<script>
function getDetails() {
    return '" +
if 'Project Details' then
    'Project Details'.'Item Details' + " ...............$ " +
    'Project Details'.'Item Total'
else
    "No Project Details Found"
end +
"';
}

function CopyEstimate(str) {
    var el = document.createElement('textarea');
    el.value = str;
    el.setAttribute('readonly', '');
    el.style.position = 'absolute';
    el.style.left = '-9999px';
    document.body.appendChild(el);
    el.select();
    document.execCommand('copy');
    document.body.removeChild(el);
}
</script>")


Any ideas? Thank you in advance!

10 replies

null
    • Fred
    • 6 mths ago
    • Reported - view

    There are two ways to do a paragraph return/line break/carriage return.

    1) just add a paragraph return:

    let outputList := "";
    let details := 'Project Details';
    for r in details do
        outputList := outputList + r.'Item Details' + " ...............$ " + r.'Item Total' + "
    "
    end;
    

    Notice at the end of line 4, I just hit the enter key.

    The big problem I have with this method is that is messes up the display of the code for my eyes.

    I like using a variable:

    let pmark := urlDecode("%0A");
    let outputList := "";
    let details := 'Project Details';
    for r in details do
        outputList := outputList + r.'Item Details' + " ...............$ " + r.'Item Total' + pmark
    end;
    

    Here we use the urlDecode() function to convert ASCII code for a line feed into a paragraph mark.

      • Taylor_Hanson
      • 6 mths ago
      • Reported - view

       thank you! Any ideas about how to get things to order like this (with the paragraph returns)?

      Item Detail #1 ..........$Item Total #1
      Item Detail #2 ..........$Item Total #2
      Item Detail #3 ..........$Item Total #3 

    • Fred
    • 6 mths ago
    • Reported - view
     said:
     thank you! Any ideas about how to get things to order like this (with the paragraph returns)?
    Item Detail #1 ..........$Item Total #1 Item Detail #2 ..........$Item Total #2 Item Detail #3 ..........$Item Total #3 

    You can try:

    let pmark := urlDecode("%0A");
    let details := 'Project Details';
    let outputList := for r in details do
        r.'Item Details' + " ...............$ " + r.'Item Total'
    end;
    join(outputList, pmark)
    

    Here we use the join() command to take the array created in line 3 and add a paragraph mark in between array items. This way does not add a paragraph mark after the last array item, like it would if you hard coded the paragraph mark into the text line.

      • Taylor_Hanson
      • 6 mths ago
      • Reported - view

       I'm not sure what I'm getting wrong... below is all of my current code. When I 'click the button' (formula) and paste it, this is what I'm getting:

      Registration Sign Design: 24x36in, updated SAP branding + “Golf Tournament Registration”, 1 versionReception Sign Design: 24x36in, updated SAP branding + “Golf Tournament Reception”, 1 versionMemorial Sign Design: 24x36in, updated SAP branding + text and photo, additional Photoshop, 1 versionReception Sign Print: x4qty, 24x36in, single sided, foam coreRegistration Sign Print: x4qty, 24x36in, single sided, foam coreMemorial Sign Print: x2qty, 24x36in, single sided, foam coreArrows Print: x8 arrows, printer template, black ...............$ $75.00$75.00$200.00$168.62$189.26$84.31$57.91

      As opposed to:

      Registration Sign Design: 24x36in, updated SAP branding + “Golf Tournament Registration”, 1 version...............$75.00

      Reception Sign Design: 24x36in, updated SAP branding + “Golf Tournament Reception”, 1 version...............$75.00

      Memorial Sign Design: 24x36in, updated SAP branding + text and photo, additional Photoshop, 1 version...............$200.00

      Reception Sign Print: x4qty, 24x36in, single sided, foam core...............$168.62

      Registration Sign Print: x4qty, 24x36in, single sided, foam core...............$189.26

      Memorial Sign Print: x2qty, 24x36in, single sided, foam core...............$84.31

      Arrows Print: x8 arrows, printer template, black...............$57.91

      Here's my current code. Any ideas? Thank you so much for your help!

      let pmark := urlDecode("%0A");
      let details := 'Project Details';
      let outputList := for r in details do
              r.'Item Details' + " ...............$ " + r.'Item Total'
          end;
      join(outputList, pmark);
      html("
      <style>
          .customButton {
              height: 35px;
              width: 110px;
              background-color: #5e6e9c;
              border: none;
              color: #fff;
              font-weight: bold;
              font-size: 11px;
              padding: 5px;
          }
      </style>
      <button class='customButton' onclick='CopyEstimate(getDetails())'>Copy Estimate</button>

      <script>
      function getDetails() {
          return '" +
      if 'Project Details' then
          'Project Details'.Id + 'Project Details'.'Item Details' + "..............." +
          'Project Details'.'Item Total' +
          "
          "
      else
          "No Project Details Found"
      end +
      "';
      }

      function CopyEstimate(str) {
          var el = document.createElement('textarea');
          el.value = str;
          el.setAttribute('readonly', '');
          el.style.position = 'absolute';
          el.style.left = '-9999px';
          document.body.appendChild(el);
          el.select();
          document.execCommand('copy');
          document.body.removeChild(el);
      }
      </script>")

    • Fred
    • 6 mths ago
    • Reported - view
     said:
    I'm not sure what I'm getting wrong... below is all of my current code. When I 'click the button' (formula) and paste it, this is what I'm getting:

     I think it has something to do with this part of your code:

    <button class='customButton' onclick='CopyEstimate(getDetails())'>Copy Estimate</button>
    <script>
    function getDetails() {
        return '" +
    if 'Project Details' then
        'Project Details'.Id + 'Project Details'.'Item Details' + "..............." +
        'Project Details'.'Item Total' +
        "
        "
    else
        "No Project Details Found"
    end +
    "';
    }
    

    Why do you have the first part of your code when it looks like this part of the code does all of the heavy lifting. Lines 5 - 9, is the code that creates the text for the clipboard

    I'm guessing you can move the first part of the code into the if statement:

    <button class='customButton' onclick='CopyEstimate(getDetails())'>Copy Estimate</button>
    <script>
    function getDetails() {
        return '" +
    if 'Project Details' then
    let pmark := urlDecode("%0A");
    let details := 'Project Details';
    let outputList := for r in details do
        r.'Item Details' + " ...............$ " + r.'Item Total'
    end;
    join(outputList, pmark)
    else
        "No Project Details Found"
    end +
    "';
    }
    

    But I don't work with function() at all so I can't be sure if it will work.

      • Taylor_Hanson
      • 6 mths ago
      • Reported - view

       Oof this is a toughie. I was hoping it would be pretty straight forward, even if clearly beyond my skill level...

      I'm essentially asking it to copy a referenced table (specific fields) formatted in the rows as shown.

      I'm open to another approach if there is one. I've been digging into these forms and so far haven't had any luck...

      I've updated the code as you've suggested, but still getting the same results. Attached is a test Ninox file so you (or anyone who might have an idea) can see the button and setup, if that's helpful.

      Thank you!

      let pmark := urlDecode("%0A");
      let details := 'Project Details';
      let outputList := for r in details do
              r.'Item Details' + " ...............$ " + r.'Item Total'
          end;
      join(outputList, pmark);
      html("
      <style>
          .customButton {
              height: 35px;
              width: 110px;
              background-color: #5e6e9c;
              border: none;
              color: #fff;
              font-weight: bold;
              font-size: 11px;
              padding: 5px;
          }
      </style>
      
      <button class='customButton' onclick='CopyEstimate(getDetails())'>Copy Estimate</button>
      <script>
      function getDetails() {
          return '" +
      if 'Project Details' then
          let pmark := urlDecode("%0A");
          let details := 'Project Details';
          let outputList := for r in details do
                  r.'Item Details' + " ...............$ " + r.'Item Total'
              end;
          join(outputList, pmark)
      else
          "No Project Details Found"
      end +
      "';
      }
      
      </script>")
      
      • Fred
      • 6 mths ago
      • Reported - view

      The copy estimate button in the Job Status Log table doesn't do anything for me. Is that the right button. I click on it and when I paste nothing happens.

      If you just put this in the formula field:

      let pmark := urlDecode("%0A");
      let details := 'Project Details';
      let outputList := for r in details do
              r.'Item Details' + " ...............$ " + r.'Item Total'
          end;
      join(outputList, pmark)
      

      And change the style color back to black and make the field much bigger you will see the data come out like:

      Design: Update Text on Existing Card Art, 1 Version ...............$ $50.00

      Print: 1000qty (x2 versions of 500), Classic Crest Solar White 130# Card Stock, Double Sided ...............$ $310.45

      The text is wrapped by the forum.

      I don't use html() much so I'm no help figuring out what is going on there. I'm sure there are others who can help out here.

      • Taylor_Hanson
      • 6 mths ago
      • Reported - view

       Ugh, you're right. It's no longer functioning on my end either...

      Sorry this seems to be working less and less. I've placed your code above into the formula window. Am I supposed to keep the styling, or any other code? 

      Below is what I've placed in, but now, it doest seem like anything is working...

      let pmark := urlDecode("%0A");
      let details := 'Project Details';
      let outputList := for r in details do
              r.'Item Details' + " ...............$ " + r.'Item Total'
          end;
      join(outputList, pmark);
      html("
      <style>
          .customButton {
              height: 35px;
              width: 110px;
              background-color: #5e6e9c;
              border: none;
              color: #fff;
              font-weight: bold;
              font-size: 11px;
              padding: 5px;
          }
      </style>
      
      <button class='customButton' onclick='CopyEstimate(getDetails())'>Copy Estimate</button>
      <script>
      function getDetails() {
          return '" +
      if 'Project Details' then
          let pmark := urlDecode("%0A");
          let details := 'Project Details';
          let outputList := for r in details do
                  r.'Item Details' + " ...............$ " + r.'Item Total'
              end;
          join(outputList, pmark)
      else
          "No Project Details Found"
      end +
      "';
      }
      
      </script>")
      

      I'm beyond confused...

    • Fred
    • 6 mths ago
    • Reported - view
     said:
    Below is what I've placed in, but now, it doest seem like anything is working...

    You are still putting in all the code.

    Let us make this a bit simpler.

    Create a new formula field and put this code in it:

    let pmark := urlDecode("%0A");
    let details := 'Project Details';
    let outputList := for r in details do
            r.'Item Details' + " ...............$ " + r.'Item Total'
        end;
    join(outputList, pmark);
    

    Just the code above. Nothing below or above it.

      • Taylor_Hanson
      • 6 mths ago
      • Reported - view

       Thank you for clarifying. I get it now. I was picturing this be more of a button that gets that result (as opposed to it automatically showing up in that field). But now, maybe I can make a button that has an 'on click' function to reveal this window. Thank you!

Content aside

  • 6 mths agoLast active
  • 10Replies
  • 164Views
  • 2 Following