Adding copy to clipboard button to every google code prettify pre blocks in blogger

It's a 2 part process:
  • The script part to find all the pre blocks having code in it and append a copy button to it dynamically.
  • The style part to place our copy button at the specified location(on top right of every code block in this case)
The script part:
<script>
var pre = document.getElementsByTagName('pre');
for (var i = 0; i < pre.length; i++) {
            var button = document.createElement('button');
                    button.className = 'copy-button';
                    button.textContent = 'Copy';
                    var s = pre[i].innerText;
                    button.setAttribute("data-clipboard-text",s); 
                    pre[i].appendChild(button);        

}

var clipboard = new Clipboard('.copy-button');
    clipboard.on('success', function(e) {
    console.info('Action:', e.action);
    console.info('Text:', e.text);
    console.info('Trigger:', e.trigger);
    e.trigger.textContent = 'Copied';
    window.setTimeout(function() {
        e.trigger.textContent = 'Copy';
    }, 2000);
    e.clearSelection();

});
    clipboard.on('error', function(e) {
    console.error('Action:', e.action);
    console.error('Trigger:', e.trigger);
});
</script>
<script src="https://cdn.rawgit.com/zenorocha/clipboard.js/v1.7.1/dist/clipboard.min.js"> 
</script>
Note:Before this version was 1.7.1 also as rawgit will shutdown in sometime above code will be replaced with:
<script src="https://cdn.jsdelivr.net/gh/zenorocha/clipboard.js@v1.7.1/dist/clipboard.min.js"> 
</script>
The style part (You might want to clean this part a bit,I will update it in free time):
<style>
.copy-button {
    cursor: pointer;
    border: 0;
    font-size: 10px;
    text-transform: uppercase;
    font-weight: 500;
    padding: 6px 10px 10px;
    color: #795548;
    background-color: transparent;
    position: absolute;
    top: 0;
    right: 0;
}

.copy-button, ::before, ::after {
    box-sizing: inherit;
}

.copy-button {
    font-family: 'HELEVETICA',sans-serif;
    font-size: 12px;
    font-weight: normal;
    text-align: center;
    text-decoration: none;
    text-indent: 0;      
}

pre[class*="prettyprint"] {
    -moz-tab-size: 4;
    -moz-hyphens: none;
     hyphens: none;
}


.copy-button::backdrop {
    background-color: rgba(0, 0, 0, 0.5);
}

.copy-button::before {
    content: '';
    display: inline-block;
    width: 16px;
    height: 16px;
    margin-right: 3px;
    background-size: contain;
    background-image: url('http://www.YourWebsiteName.com/favicon.ico');
    background-repeat: no-repeat;
    position: relative;
    top: 3px;

}

.copy-button {
    cursor: pointer;
    border: 0;
    font-size: 10px;
    text-transform: uppercase;
    font-weight: 500;
    padding: 6px 10px 10px;
    color: #795548;
    background-color: transparent;
    position: absolute;
    top: 0;
    right: 0;

}

pre[class*="prettyprint"] {
    -moz-tab-size: 4;
    -moz-hyphens: none;
    hyphens: none;
    position: relative;}

.copy-button{border-radius: 0;
    min-width:55px;
    background: none repeat scroll 0 0 transparent;
    border: 1px solid #bbb;
    color: #26589F;
    font-family: 'HELEVETICA',sans-serif;
    font-size: 12px;
    font-weight: normal;
    line-height: 1.42rem;
    margin: 0;
    padding: 0px 5px;
    text-align: center;
    text-decoration: none;
    text-indent: 0;
    position:absolute;
    background:#ccc;   

}

.pre{max-width: 30px;
    overflow: hidden;
    position: absolute;}

ol.linenums {
    overflow: auto;
}
</style>

Comments

  1. Thanks for the code. I had a problem using this with the bootstrap. I had to modify slightly. I had to pass the modal container id.

    Instead of:

    var clipboard = new Clipboard('.copy-button');

    I have done:

    var clipboard = new Clipboard('.copy-button', {
    container: document.getElementById('rep')
    });

    ReplyDelete
    Replies
    1. I have used the set attribute thing and simple class selector as it works in blogger default themes and yes for bootstrap what you have done is exactly what is required "For use in Bootstrap Modals or with any other library that changes the focus you'll want to set the focused element as the container value." as stated in advanced usage section of clipboardjs site, thanks for mentioning it here.

      Delete
  2. Thank you bro!! it was really helpful for me.

    ReplyDelete
  3. Hi Shivam, It works fine. But some times the C# formatting is copied properly. All the content appear in a single line while pasting the content without their line formatting and indentation like displayed in the webpage. Is there anything that can be done.?

    ReplyDelete
    Replies
    1. Hi,
      I will need a example of problematic code to test things out before suggesting anything, is it loosing indentation only when you are using copy button to copy code or also when you are selecting code manually and copying pasting it using ctrl+c and ctrl+v, which text editor are you pasting the code into ? Is this behavior specific to browser?

      Delete
    2. Hi Shivam, Yes, its loosing indentation when using the copy code button only. But, the problem is the indentation is retained for languages like XAML. But only C# codes does not retain the indentation. And it is not browser specific it does not retain the indentation in all the browsers. And i am using notepad++ to paste the content.

      Delete
    3. Hi,
      I am not sure why its happening as we are already using "data-clipboard-text" and not "data-clipboard-target" I will check it and let you know if I find something, meanwhile I have updated the code to make use of latest version of clipboardjs which is 2.0.4 earlier it was using 1.7.1 may be with new version it might have got fixed, thanks.

      Delete
    4. Updated version 2.0.4 does not seem to work at all. Copy to clipboard success event does not fire at all.

      Delete
    5. Also forgot to mention, that this happens in the Navigation tab bar, where code snippets for various languages are provided for the same concept.

      Delete
    6. I noticed it today in console on opera anything above version 2.0.1 was throwing uncaught exceptions so reverted back to using 2.0.1 which seems to me working fine.Try inspect element and switch to console tab then click copy button and see if correct code is getting logged with formatting or not.

      Delete
  4. sir i add this code in blogger it's not working its show a xml error

    ReplyDelete
    Replies
    1. Hi Gohel,
      Where did you add this code ...the easiest place to add it is in a widget try clicking on add widget from layout section choose JavaScript widget from the newly opened window and then paste it there ....I am using the same code on tcbin and it's working fine.

      Delete
  5. Replies
    1. Hi Morsalin,
      I would really appreciate if you could give me the details of the error you are receiving...like I said in one of my comments above add the code in a Javascript widget and make sure you check the box which says Visible show javascript/html...I will add a video if I get some free time in near future but cant commit anything for now thanks.

      Delete
  6. Hi Shivam, can you please help me on the following error:

    org.xml.sax.SAXParseException; lineNumber: 3207; columnNumber: 20; The content of elements must consist of well-formed character data or markup.

    The error message is talking about the below:

    for (var i = 0; i < pre.length; i++) {

    Thanks.

    ReplyDelete
    Replies
    1. Thanks for the suggestion bro but what I need is a copy code button to automatically copy the codes within code box. I have already solved it. Thanks

      Check the outcome here: https://vandeweybalao.blogspot.com/2020/04/how-to-add-blinking-notification-bar-in-blogger-blogspot.html

      Delete
  7. Hi Van ,

    Glad that you solved your issue, I have been busy lately in my day job so wasn't able to reply sooner, I have been notified about invalid traffic coming to my site and thus I request you to please refrain from adding links to similar posts while commenting as it encourages others do to the same.
    Thank you for understanding.

    ReplyDelete
  8. I have to use it in a post. how to implement?

    ReplyDelete

Post a Comment

Note:Please be gentle while commenting and avoid spamming as comment are anyways moderated thank you.

Popular posts from this blog

Enabling fixed Sidebar for blogger Contempo template for screen sizes smaller than 1440px

Adding Home Older Newer Post Buttons in new Blogger templates such as Contempo