0

I have page displayed using cards which shows threaddump information. Threaddump information are shown using v-for, the problem is when I copy , it copies only single loop of data with my current copyThreadInfoToClipboard method. So, my requests are,

  1. How can I copy the entire loop of data?
  2. How can I escape sub-element tags in the copied selection text like in this example <span> and <pre> tag. I don't want my copied text to contain <!----><!----><code data-v-ea65a43e="">, I can put id on each individual element and try to copy but is there a way we can copy with a single id which would-be parent and skip /remove the sub-element tags in the copied text but it should contain the sub-element inner text though, I just want my copied text to not include sun elements HTML tags.

code sandbox is here : click

    <template>
  <b-row>
    <b-col>
      <b-card class="shadow border-0">
        <b-button
          size="sm"
          @click.prevent="copyThreadInfoToClipboard('thread-id')"
          >Copy to clipboard</b-button
        >
        <b-card-text
          id="thread-id"
          class="text-monospace"
          v-for="thread in allThreads"
          :key="thread.threadName"
        >
          "{{ thread.threadName }}" #{{ thread.id }} state:{{
            thread.threadState
          }}
          cpu-time:{{ thread.cpuTime }} user-time:{{ thread.userTime }}
          <span v-if="thread.lockName != null"
            >Lock-name: {{ thread.lockName }} </span
          ><span v-if="thread.getLockOwnerName != null"
            >Lock-owner-name: {{ thread.getLockOwnerName }}</span
          >
          <br />
          <code id="line-break"> {{ thread.stacktrace }}</code>
        </b-card-text>
      </b-card>
    </b-col>
  </b-row>
</template>

<script>
export default {
  data(){
    return{
      allThreads:[{
            "isThreadCpuTimeSupported": "true",
            "getLockOwnerName": null,
            "isSuspended": "false",
            "stacktrace": "[email protected]/java.net.PlainSocketImpl.accept0(Native Method)\[email protected]/java.net.PlainSocketImpl.socketAccept(PlainSocketImpl.java:159)\[email protected]/java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:458)\[email protected]/java.net.ServerSocket.implAccept(ServerSocket.java:551)\[email protected]/java.net.ServerSocket.accept(ServerSocket.java:519)\norg.apache.catalina.core.StandardServer.await(StandardServer.java:609)\norg.apache.catalina.startup.Catalina.await(Catalina.java:721)\norg.apache.catalina.startup.Catalina.start(Catalina.java:667)\[email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\[email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\[email protected]/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\[email protected]/java.lang.reflect.Method.invoke(Method.java:566)\napp//org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:343)\napp//org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:474)\n",
            "cpuTime": "16312.5",
            "userTime": "11515.625",
            "threadState": "RUNNABLE",
            "id": "1",
            "lockName": null,
            "threadName": "main",
            "isNative": "true"
        },
        {
            "isThreadCpuTimeSupported": "true",
            "getLockOwnerName": null,
            "isSuspended": "false",
            "stacktrace": "[email protected]/java.lang.ref.Reference.waitForReferencePendingList(Native Method)\[email protected]/java.lang.ref.Reference.processPendingReferences(Reference.java:241)\[email protected]/java.lang.ref.Reference$ReferenceHandler.run(Reference.java:213)\n",
            "cpuTime": "0.0",
            "userTime": "0.0",
            "threadState": "RUNNABLE",
            "id": "2",
            "lockName": null,
            "threadName": "Reference Handler",
            "isNative": "false"
        },
        {
            "isThreadCpuTimeSupported": "true",
            "getLockOwnerName": null,
            "isSuspended": "false",
            "stacktrace": "[email protected]/java.lang.Object.wait(Native Method)\[email protected]/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:155)\[email protected]/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:176)\[email protected]/java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:170)\n",
            "cpuTime": "0.0",
            "userTime": "0.0",
            "threadState": "WAITING",
            "id": "3",
            "lockName": "java.lang.ref.ReferenceQueue$Lock@4f01e5fa",
            "threadName": "Finalizer",
            "isNative": "false"
        }]
    }
  }
  ,
  methods: {
    copyThreadInfoToClipboard(id) {
      var copyText = document.getElementById(id).innerHTML;
      var input_temp = document.createElement('textarea');
      input_temp.innerHTML = copyText;
      document.body.appendChild(input_temp);
      input_temp.select();
      input_temp.setSelectionRange(0, 99999); /*For mobile devices*/
      document.execCommand('copy');
      alert(input_temp.value);
    },
  },
};
</script>

2 Answers 2

2

For question #1, you can use:

//Copied from @hiws answer
//this will have the benefit of having a unique parent div 
//from which copy the entire content 

<div id="thread-id">
  <b-card-text v-for="...">
    <!-- Content to copy -->
  </b-card-text>
</div>

For question #2: Use innerText instead of innerHtml, this won't give you the markup.

var copyText = document.getElementById(id).innerText;
Sign up to request clarification or add additional context in comments.

8 Comments

InnerText works perfectly but HTMLInputElement.select() doesn't work.
So we have just a problem now :). How you are using it? Can you put the lines of code?
you can access the running code here : codesandbox.io/s/smoosh-resonance-vuecm?file=/src/App.vue
it does copies but only first loop of data means if you see there are three threads "main","Reference Handler" and "Finalizer" and it always copy the first thread which which is "main". It does not copy the entire data shown on the right side of sandbox .
I see the reason why. You are iterating elements with v-for, but you set a string ID, that get iterated, so it generate three divs with the same ID, thats why when you copy the innerHtml from the selected div you have just the content of the first. Look this part: ` <b-card-text id="thread-id" class="text-monospace" v-for="thread in allThreads"`
|
1

You're almost there. The issue is you're generating 3 divs with the same id. and document.getElementById(id) will only retrieve the first one. Instead wrap your v-for in another div and place the id on that element.

<div id="thread-id">
  <b-card-text v-for="...">
    <!-- Content to copy -->
  </b-card-text>
</div>

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.