The forum of the forums
Would you like to react to this message? Create an account in a few clicks or log in to continue.

Custom quote buttons logic

2 posters

Go down

Custom quote buttons logic Empty Custom quote buttons logic

Post by Wizzard May 18th 2024, 7:47 pm

Version: phpBB2, phpBB3, punBB, Invision
How it works?
This functionality has two quote buttons. First one is "Add to quoted" and the second one is "Quote". These two work in a different way. What is the point of this functionality actually? Well, currently if you click on quote button you would be redirected and you can't see other messages on the forum. With current quote button you can't select specific part of the message you want to quote but the whole message.
When it comes to multi quote, the situation is the same, you can quote only full messages but to do so you need to select them and quick on reply button. Then you would be redirected and yet again, you can't see messages from people before. Pretty annoying, is it not?

This code will enable you to select text you want to quote and when you click quote, it will add it in textarea (reply area). When you select text and click "Add to quoted", the text won't be added instantly but will be saved in localstorage. So you can go down and down until you select all messages you want to quote and then click on a button to add all those quotes.

When you select the text:
Custom quote buttons logic Screen13

When you click on the "Add to quoted" you get a bubble:
Custom quote buttons logic Screen14

Downsides of code is that you can't quote images and you can't maintain the styles from lists, centered text, etc. It only takes text in it's raw form.

Oh yes, when you go down to reply area, if you want to add all selected quotes, click on this:

Custom quote buttons logic Screen16


How to implement:
1. AP - Display - Pictures and colors - Colors & CSS - CSS Stylesheet
There place this code and save afterwards:
Code:
#quote-buttons {
    display: flex;
    gap: 5px;
}

#quote-buttons button {
    background-color: #007bff;
    color: white;
    border: none;
    padding: 5px 10px;
    cursor: pointer;
    border-radius: 3px;
}

#quote-buttons button:hover {
    background-color: #0056b3;
}

2. AP - Modules - HTML & JAVASCRIPT - Javascript codes management
Click on: Custom quote buttons logic Screen15

And then for name put whatever you want, placement in the topics, and code for different versions is:

phpBB2
Code:
$(document).ready(function() {
    let pendingQuotes = [];

    // Function to populate textarea with quotes from local storage
    function populateTextareaWithQuotes() {
        const textarea = $('.sceditor-container textarea');
        if (textarea.length > 0) {
            const quotes = JSON.parse(localStorage.getItem('pendingQuotes')) || [];
            quotes.forEach(quote => {
                textarea.val(textarea.val() + `[quote="${quote.username}"]${quote.text}[/quote]\n`);
            });
        }
    }
             
    $(function(){
        $('<a class="sceditor-button sceditor-button-add-quotes" unselectable="on"><div unselectable="on" style="background-image:url(https://i.ibb.co/mCggBTP/quote.png)">a</div></a>').insertAfter('.sceditor-button-source');
    });

    // Add Quotes button click event listener
    $(document).on('click', '.sceditor-button-add-quotes', function() {
        populateTextareaWithQuotes();
    });

    // Event listener for selecting text
    $(document).on('mouseup', function(e) {
        if ($(e.target).closest('#quote-buttons').length > 0 || $(e.target).closest('.sceditor-toolbar').length > 0) {
            return;
        }

        const selection = window.getSelection();
        const selectedText = selection.toString().trim();
        const postElement = $(e.target).closest('.post');

        if (selectedText.length > 0 && postElement.length > 0) {
            const username = postElement.find('.name strong a').text().trim();

            $('#quote-buttons').remove();

            const quoteButtons = $('<div id="quote-buttons"></div>').css({
                position: 'absolute',
                top: `${e.pageY}px`,
                left: `${e.pageX}px`,
                backgroundColor: 'white',
                border: '1px solid #ccc',
                padding: '5px',
                zIndex: '1000'
            });

            const addToQuotedButton = $('<button id="add-to-quoted">Add to quoted</button>').data('selectedText', selectedText).data('username', username);
            quoteButtons.append(addToQuotedButton);

            const quoteNowButton = $('<button id="quote-now">Quote</button>').data('selectedText', selectedText).data('username', username);
            quoteButtons.append(quoteNowButton);

            $('body').append(quoteButtons);
        } else {
            $('#quote-buttons').remove();
        }
    });

    // Event listener for adding selected text to pending quotes
    $(document).on('click', '#add-to-quoted', function(e) {
        e.stopPropagation();
        const text = $(this).data('selectedText');
        const username = $(this).data('username');
       
        pendingQuotes.push({ text: text, username: username });
        localStorage.setItem('pendingQuotes', JSON.stringify(pendingQuotes));

        $('#quote-buttons').remove();
       
        // Show bubble notification
        const bubble = $('<div class="quote-added-bubble">Quote added</div>').css({
            position: 'fixed',
            top: '50%',
            left: '50%',
            transform: 'translate(-50%, -50%)',
            backgroundColor: '#4CAF50',
            color: 'white',
            padding: '15px',
            borderRadius: '10px',
            zIndex: '9999'
        });
        $('body').append(bubble);
       
        // Remove bubble after 3 seconds
        setTimeout(function() {
            bubble.remove();
        }, 3000);
    });

    // Event listener for quoting selected text immediately
    $(document).on('click', '#quote-now', function(e) {
        e.stopPropagation();
        const text = $(this).data('selectedText');
        const username = $(this).data('username');
        const textarea = $('.sceditor-container textarea');
        if (textarea.length > 0) {
            textarea.val(textarea.val() + `[quote="${username}"]${text}[/quote]\n`);
        }
        $('#quote-buttons').remove();
    });

    // Event listener to remove quote buttons if clicked outside
    $(document).on('mousedown', function(e) {
        const quoteButtons = $('#quote-buttons');
        if (quoteButtons.length > 0 && !quoteButtons.is(e.target) && quoteButtons.has(e.target).length === 0) {
            quoteButtons.remove();
        }
    });
});

phpBB3
Code:
$(document).ready(function() {
    let pendingQuotes = [];

    // Function to populate textarea with quotes from local storage
    function populateTextareaWithQuotes() {
        const textarea = $('.sceditor-container textarea');
        if (textarea.length > 0) {
            const quotes = JSON.parse(localStorage.getItem('pendingQuotes')) || [];
            quotes.forEach(quote => {
                textarea.val(textarea.val() + `[quote="${quote.username}"]${quote.text}[/quote]\n`);
            });
        }
    }

    $(function(){
        $('<a class="sceditor-button sceditor-button-add-quotes" unselectable="on"><div unselectable="on" style="background-image:url(https://i.ibb.co/mCggBTP/quote.png)">a</div></a>').insertAfter('.sceditor-button-source');
    });

    // Add Quotes button click event listener
    $(document).on('click', '.sceditor-button-add-quotes', function() {
        populateTextareaWithQuotes();
    });

    $(document).on('mouseup', function(e) {
        if ($(e.target).closest('#quote-buttons').length > 0 || $(e.target).closest('.sceditor-toolbar').length > 0) {
            return;
        }

        const selection = window.getSelection();
        const selectedText = selection.toString().trim();
        const postEntry = $(e.target).closest('.post');

        if (selectedText.length > 0 && postEntry.length > 0) {
            const postBody = postEntry.find('.content');
            const username = postEntry.find('.postprofile a').text().trim();

            $('#quote-buttons').remove();

            const quoteButtons = $('<div id="quote-buttons"></div>').css({
                position: 'absolute',
                top: `${postBody.offset().top}px`,
                left: `${postBody.offset().left + postBody.width() + 10}px`,
                backgroundColor: 'white',
                border: '1px solid #ccc',
                padding: '5px',
                zIndex: '1000'
            });

            const addToQuotedButton = $('<button id="add-to-quoted">Add to quoted</button>').data('selectedText', selectedText).data('username', username);
            quoteButtons.append(addToQuotedButton);

            const quoteNowButton = $('<button id="quote-now">Quote</button>').data('selectedText', selectedText).data('username', username);
            quoteButtons.append(quoteNowButton);

            $('body').append(quoteButtons);
        } else {
            $('#quote-buttons').remove();
        }
    });

    $(document).on('click', '#add-to-quoted', function(e) {
        e.stopPropagation();
        console.log("Add to quoted button clicked");
        const text = $(this).data('selectedText');
        const username = $(this).data('username');

        pendingQuotes.push({ text: text, username: username });
        localStorage.setItem('pendingQuotes', JSON.stringify(pendingQuotes));

        $('#quote-buttons').remove();

        // Show bubble notification
        const bubble = $('<div class="quote-added-bubble">Quote added</div>').css({
            position: 'fixed',
            top: '50%',
            left: '50%',
            transform: 'translate(-50%, -50%)',
            backgroundColor: '#4CAF50',
            color: 'white',
            padding: '15px',
            borderRadius: '10px',
            zIndex: '9999'
        });
        $('body').append(bubble);

        // Remove bubble after 3 seconds
        setTimeout(function() {
            bubble.remove();
        }, 3000);
    });

    $(document).on('click', '#quote-now', function(e) {
        e.stopPropagation();
        console.log("Quote button clicked");
        const text = $(this).data('selectedText');
        const username = $(this).data('username');
        const textarea = $('.sceditor-container textarea');
        if (textarea.length > 0) {
            textarea.val(textarea.val() + `[quote="${username}"]${text}[/quote]\n`);
        }
        $('#quote-buttons').remove();
    });

    $(document).on('mousedown', function(e) {
        const quoteButtons = $('#quote-buttons');
        if (quoteButtons.length > 0 && !quoteButtons.is(e.target) && quoteButtons.has(e.target).length === 0) {
            quoteButtons.remove();
        }
    });

    // Remove pending quotes from localStorage on page reload
    $(window).on('beforeunload', function() {
        localStorage.removeItem('pendingQuotes');
    });
});

PunBB
Code:
$(document).ready(function() {
    let pendingQuotes = [];

    // Function to populate textarea with quotes from local storage
    function populateTextareaWithQuotes() {
        const textarea = $('.sceditor-container textarea');
        if (textarea.length > 0) {
            const quotes = JSON.parse(localStorage.getItem('pendingQuotes')) || [];
            quotes.forEach(quote => {
                textarea.val(textarea.val() + `[quote="${quote.username}"]${quote.text}[/quote]\n`);
            });
        }
    }

    $(function(){
        $('<a class="sceditor-button sceditor-button-add-quotes" unselectable="on"><div unselectable="on" style="background-image:url(https://i.ibb.co/mCggBTP/quote.png)">a</div></a>').insertAfter('.sceditor-button-source');
    });

    // Add Quotes button click event listener
    $(document).on('click', '.sceditor-button-add-quotes', function() {
        populateTextareaWithQuotes();
    });

    $(document).on('mouseup', function(e) {
        if ($(e.target).closest('#quote-buttons').length > 0 || $(e.target).closest('.sceditor-toolbar').length > 0) {
            return;
        }

        const selection = window.getSelection();
        const selectedText = selection.toString().trim();
        const postEntry = $(e.target).closest('.post');

        if (selectedText.length > 0 && postEntry.length > 0) {
            const postBody = postEntry.find('.post-entry');
            const username = postEntry.find('.username a').text().trim();

            $('#quote-buttons').remove();

            const quoteButtons = $('<div id="quote-buttons"></div>').css({
                position: 'absolute',
                top: `${postBody.offset().top}px`,
                left: `${postBody.offset().left + postBody.width() + 10}px`,
                backgroundColor: 'white',
                border: '1px solid #ccc',
                padding: '5px',
                zIndex: '1000'
            });

            const addToQuotedButton = $('<button id="add-to-quoted">Add to quoted</button>').data('selectedText', selectedText).data('username', username);
            quoteButtons.append(addToQuotedButton);

            const quoteNowButton = $('<button id="quote-now">Quote</button>').data('selectedText', selectedText).data('username', username);
            quoteButtons.append(quoteNowButton);

            $('body').append(quoteButtons);
        } else {
            $('#quote-buttons').remove();
        }
    });

    $(document).on('click', '#add-to-quoted', function(e) {
        e.stopPropagation();
        console.log("Add to quoted button clicked");
        const text = $(this).data('selectedText');
        const username = $(this).data('username');

        pendingQuotes.push({ text: text, username: username });
        localStorage.setItem('pendingQuotes', JSON.stringify(pendingQuotes));

        $('#quote-buttons').remove();

        // Show bubble notification
        const bubble = $('<div class="quote-added-bubble">Quote added</div>').css({
            position: 'fixed',
            top: '50%',
            left: '50%',
            transform: 'translate(-50%, -50%)',
            backgroundColor: '#4CAF50',
            color: 'white',
            padding: '15px',
            borderRadius: '10px',
            zIndex: '9999'
        });
        $('body').append(bubble);

        // Remove bubble after 3 seconds
        setTimeout(function() {
            bubble.remove();
        }, 3000);
    });

    $(document).on('click', '#quote-now', function(e) {
        e.stopPropagation();
        console.log("Quote button clicked");
        const text = $(this).data('selectedText');
        const username = $(this).data('username');
        const textarea = $('.sceditor-container textarea');
        if (textarea.length > 0) {
            textarea.val(textarea.val() + `[quote="${username}"]${text}[/quote]\n`);
        }
        $('#quote-buttons').remove();
    });

    $(document).on('mousedown', function(e) {
        const quoteButtons = $('#quote-buttons');
        if (quoteButtons.length > 0 && !quoteButtons.is(e.target) && quoteButtons.has(e.target).length === 0) {
            quoteButtons.remove();
        }
    });

    // Remove pending quotes from localStorage on page reload
    $(window).on('beforeunload', function() {
        localStorage.removeItem('pendingQuotes');
    });
});

Invision
Code:
$(window).on('load', function() {
    // Clear localStorage when the page loads
    localStorage.removeItem('pendingQuotes');
});

$(document).ready(function() {
    let pendingQuotes = [];

    // Function to populate textarea with quotes from local storage
    function populateTextareaWithQuotes() {
        const textarea = $('.sceditor-container textarea');
        if (textarea.length > 0) {
            const quotes = JSON.parse(localStorage.getItem('pendingQuotes')) || [];
            quotes.forEach(quote => {
                textarea.val(textarea.val() + `[quote="${quote.username}"]${quote.text}[/quote]\n`);
            });
        }
    }
             
    $(function(){
        $('<a class="sceditor-button sceditor-button-add-quotes" unselectable="on"><div unselectable="on" style="background-image:url(https://i.ibb.co/mCggBTP/quote.png)">a</div></a>').insertAfter('.sceditor-button-source');
    });

    // Add Quotes button click event listener
    $(document).on('click', '.sceditor-button-add-quotes', function() {
        populateTextareaWithQuotes();
    });

    $(document).on('mouseup', function(e) {
        if ($(e.target).closest('#quote-buttons').length > 0 || $(e.target).closest('.sceditor-toolbar').length > 0) {
            return;
        }

        const selection = window.getSelection();
        const selectedText = selection.toString().trim();
        const postEntry = $(e.target).closest('.post-entry');

        if (selectedText.length > 0 && postEntry.length > 0) {
            const range = selection.getRangeAt(0);
            const rect = range.getBoundingClientRect();

            const postContainer = postEntry.closest('.post-container');
            const username = postContainer.find('.postprofile-head strong').text();

            $('#quote-buttons').remove();

            const quoteButtons = $('<div id="quote-buttons"></div>').css({
                position: 'absolute',
                top: `${rect.bottom + window.scrollY}px`,
                left: `${rect.left + window.scrollX}px`,
                backgroundColor: 'white',
                border: '1px solid #ccc',
                padding: '5px',
                zIndex: '1000'
            });

            const addToQuotedButton = $('<button id="add-to-quoted">Add to quoted</button>').data('selectedText', selectedText).data('username', username);
            quoteButtons.append(addToQuotedButton);

            const quoteNowButton = $('<button id="quote-now">Quote</button>').data('selectedText', selectedText).data('username', username);
            quoteButtons.append(quoteNowButton);

            $('body').append(quoteButtons);
        } else {
            $('#quote-buttons').remove();
        }
    });

    $(document).on('click', '#add-to-quoted', function(e) {
        e.stopPropagation();
        console.log("Add to quoted button clicked");
        const text = $(this).data('selectedText');
        const username = $(this).data('username');
       
        pendingQuotes.push({ text: text, username: username });
        localStorage.setItem('pendingQuotes', JSON.stringify(pendingQuotes));

        $('#quote-buttons').remove();
       
        // Show bubble notification
        const bubble = $('<div class="quote-added-bubble">Quote added</div>').css({
            position: 'fixed',
            top: '50%',
            left: '50%',
            transform: 'translate(-50%, -50%)',
            backgroundColor: '#4CAF50',
            color: 'white',
            padding: '15px',
            borderRadius: '10px',
            zIndex: '9999'
        });
        $('body').append(bubble);
       
        // Remove bubble after 3 seconds
        setTimeout(function() {
            bubble.remove();
        }, 1500);
    });

    $(document).on('click', '#quote-now', function(e) {
        e.stopPropagation();
        console.log("Quote button clicked");
        const text = $(this).data('selectedText');
        const username = $(this).data('username');
        const textarea = $('.sceditor-container textarea');
        if (textarea.length > 0) {
            textarea.val(textarea.val() + `[quote="${username}"]${text}[/quote]\n`);
        }
        $('#quote-buttons').remove();
    });

    $(document).on('mousedown', function(e) {
        const quoteButtons = $('#quote-buttons');
        if (quoteButtons.length > 0 && !quoteButtons.is(e.target) && quoteButtons.has(e.target).length === 0) {
            quoteButtons.remove();
        }
    });
});

Maybe in the future I might improve the script to be more interesting, but for now it is what it is. If any bugs are found, let me know.
Wizzard
Wizzard
Forumember

Male Posts : 30
Reputation : 6
Language : English

Ape, Shek, SarkZKalie, poesia-verses and كونان2000 like this post

Back to top Go down

Custom quote buttons logic Empty Re: Custom quote buttons logic

Post by Shek June 3rd 2024, 1:15 pm

Nice work! I have a two suggestion for this code also.
Spoiler:
The difference is that this one has the option to copy the selected section. Wink
Shek
Shek
Active Poster

Male Posts : 1691
Reputation : 61
Language : Portuguese (Brazil) and English
Location : Brazil

https://publipos.net

poesia-verses likes this post

Back to top Go down

Custom quote buttons logic Empty Re: Custom quote buttons logic

Post by Wizzard June 3rd 2024, 1:21 pm

Shek wrote:Nice work! I have a two suggestion for this code also.
Spoiler:
The difference is that this one has the option to copy the selected section. Wink

And mine code doesn't copy the selected section? XD
I bet you didn't even try the code. I even have add to quoted feature as a bonus.
Wizzard
Wizzard
Forumember

Male Posts : 30
Reputation : 6
Language : English

Back to top Go down

Custom quote buttons logic Empty Re: Custom quote buttons logic

Post by Shek June 3rd 2024, 1:25 pm

Yes, it has been tested in all versions. But I don't think I'm interested only in contributing, but in discussing who did the best. The important thing is that everyone can enjoy it, whatever it is. Congratulations! cheers Your code is much more polished, by the way.
Shek
Shek
Active Poster

Male Posts : 1691
Reputation : 61
Language : Portuguese (Brazil) and English
Location : Brazil

https://publipos.net

Back to top Go down

Back to top

- Similar topics

 
Permissions in this forum:
You cannot reply to topics in this forum