Welcome to the nuBuilder Forums!

Join our community by registering and logging in.
As a member, you'll get access to exclusive forums, resources, and content available only to registered users.

Make a URL a clickable link Topic is solved

Questions related to customising nuBuilder Forte with JavaScript or PHP.
Paul
Posts: 154
Joined: Mon Aug 25, 2025 6:03 am
Has thanked: 30 times
Been thanked: 3 times

Re: Make a URL a clickable link

Unread post by Paul »

Ok, I asked ChatGPT for help and here is what it said:

"We’ll:

Hide the URL text in the Browse form using CSS or JS (for non-print mode).

On Print mode, dynamically replace the URL text in those specific columns with clickable <a> tags.

Ensure blank column logic still works by checking column content before hiding.

How It Works

In Browse mode:

The script runs on afterbrowse event.

It finds the URL columns and makes their text invisible (color: transparent).

The cell still exists (so your hideBlankColumns() can still detect emptiness correctly).

In Print mode:

The script runs on beforeprint (nuBuilder event triggered before generating the print view).

It replaces plain text in URL cells with clickable <a href="..."> links.

So the printed/exported page shows live hyperlinks.


Full Implementation

Add this below your existing code in the Custom Code (JavaScript) of your Browse form:

Code: Select all

//---------------------------------------------------------------------
// Detect if we are in "Print" mode
//---------------------------------------------------------------------
nuOn('beforeprint', function() {

    // Columns that contain URLs
    const urlColumns = ['pk_audio_files', 'pk_video_files', 'pk_photo_files']; 

    // Get all cells in the Browse
    const cells = document.querySelectorAll('.nuCell[data-nu-column-name]');
    
    cells.forEach(cell => {
        const colName = cell.getAttribute('data-nu-column-name');
        const text = cell.textContent.trim();

        // Only transform if this is one of the URL columns and not empty
        if (urlColumns.includes(colName) && text !== '') {
            // Clear cell content
            cell.innerHTML = `<a href="${text}" target="_blank">${text}</a>`;
        }
    });
});

//---------------------------------------------------------------------
// Hide URL columns in Browse mode (not in print)
//---------------------------------------------------------------------

nuOn('afterbrowse', function() {

    const urlColumns = ['pk_audio_files', 'pk_video_files', 'pk_photo_files'];

    const cells = document.querySelectorAll('.nuCell[data-nu-column-name]');
    cells.forEach(cell => {
        const colName = cell.getAttribute('data-nu-column-name');
        if (urlColumns.includes(colName)) {
            // Hide text content visually (still available in DOM for print)
            cell.style.color = 'transparent';
            cell.style.pointerEvents = 'none';
        }
    });

    // Also hide headers for those columns
    const headers = document.querySelectorAll('.nuBrowseTitle[data-nu-column-name]');
    headers.forEach(header => {
        const colName = header.getAttribute('data-nu-column-name');
        if (urlColumns.includes(colName)) {
            header.style.color = 'transparent';
        }
    });
});

I entered the code at the end of my previous custom javascript code block in the Browse form as instructed by ChatGPT and this is the result of clicking on the Print button:

Code: Select all

VM5170:81 Uncaught ReferenceError: nuOn is not defined
    at <anonymous>:81:1
    at m (jquery-3.7.1.min.js:2:880)
    at $e (jquery-3.7.1.min.js:2:46274)
    at ce.fn.init.append (jquery-3.7.1.min.js:2:47633)
    at nuAddJavaScript (nuform.js?ts=20251009054910:6294:12)
    at nuBuildForm (nuform.js?ts=20251009054910:144:3)
    at Object.successCallback (nuajax.js?ts=20251009054910:193:4)
    at c (jquery-3.7.1.min.js:2:25304)
    at Object.fireWith [as resolveWith] (jquery-3.7.1.min.js:2:26053)
    at l (jquery-3.7.1.min.js:2:77782)

To be clear, this is the pre-existing code in the Browse form:

Code: Select all


if (!nuGlobalAccess()) {
    var columnIndex = 0;
    nuSetBrowseColumnSize(columnIndex, 0);
}


//if (!nuGlobalAccess()) //Un-comment this line so Admin users can see all blank columns

{
	// Get hidden columns from hideBlankColumns
	const hiddenColumns = hideBlankColumns();

	// Add the manually specified column index
       if (!nuGlobalAccess()) //This allows any admin user to still print the first column (userID)
       var columnIndex = 0;

	// Combine both arrays and remove duplicates
	const columnsToExclude = [...new Set([columnIndex, ...hiddenColumns])];

	// Exclude all columns
	nuPrintExcludeColumns(columnsToExclude);
}



function hideBlankColumns() {
    const hiddenColumns = [];
    
    // Find the browse container element using its ID
    const browseDiv = document.getElementById('nuRECORD');
    if (!browseDiv) {
        console.error(`Browse div with ID "${'nuRECORD'}" not found.`);
        return hiddenColumns;
    }
    
    // Get all browse title divs (headers)
    const headers = browseDiv.querySelectorAll('.nuBrowseTitle');
    if (headers.length === 0) {
        console.error('No browse title headers found.');
        return hiddenColumns;
    }
    
    const colCount = headers.length;
    const isColumnBlank = new Array(colCount).fill(true);
    
    // Get all data cells (excluding empty rows)
    const dataCells = browseDiv.querySelectorAll('.nuCell[data-nu-column]');
    
    // Check each data cell to see if the column has content
    dataCells.forEach(cell => {
        const colIndex = parseInt(cell.getAttribute('data-nu-column'));
        const content = cell.textContent.trim();
        // Mark column as not blank if it has content
        if (content !== '' && colIndex >= 0) {
            isColumnBlank[colIndex] = false;
        }
    });
    
    // Hide blank columns using nuBuilder's built-in function
    for (let j = 0; j < colCount; j++) {
        if (isColumnBlank[j]) {
            nuSetBrowseColumnSize(j, 0);
            hiddenColumns.push(j);
        }
    }
    
    return hiddenColumns;
}
kev1n
nuBuilder Team
Posts: 4591
Joined: Sun Oct 14, 2018 6:43 pm
Has thanked: 76 times
Been thanked: 539 times
Contact:

Re: Make a URL a clickable link

Unread post by kev1n »

The AI-generated code is complete rubbish. Just give the AI the code you already have and clearly explain what you want it to do — basically what I wrote above.
Paul
Posts: 154
Joined: Mon Aug 25, 2025 6:03 am
Has thanked: 30 times
Been thanked: 3 times

Re: Make a URL a clickable link

Unread post by Paul »

I did exactly as you stated above. I took the time to 1. explained what code I already had 2. explained the desired outcome in detail. The above is the result of that.

I suppose AI is not as 'intelligent' as the human brain. After all, it IS artificial.
Paul
Posts: 154
Joined: Mon Aug 25, 2025 6:03 am
Has thanked: 30 times
Been thanked: 3 times

Re: Make a URL a clickable link

Unread post by Paul »

Ok, I gave ChatGPT another chance and it finally came up with some working code!
(Sort of...)

I used your suggestion:

Code: Select all

CONCAT('<a href="', pk_audio_files, '" target="_blank">Download All Audio Files</a>')

CONCAT('<a href="', pk_video_files, '" target="_blank">Download All Video Files</a>')

CONCAT('<a href="', pk_photo_files, '" target="_blank">Download All Photo Files</a>')

together with the new ChatGPT code:

Code: Select all

// ==============================
// Hide specific columns normally,
// but show them during nuPrint().
// ==============================

// Columns with hyperlinks (replace with correct column indexes!)
const hyperlinkColumns = [4, 5, 6]; // example: 1=audio, 2=video, 3=photo

// Function to hide columns
function hideColumns(cols) {
    cols.forEach(i => nuSetBrowseColumnSize(i, 0));
}

// Function to show columns (auto size)
function showColumns(cols) {
    cols.forEach(i => nuSetBrowseColumnSize(i, 'auto'));
}

// Hide columns by default (non-admins only)
if (!nuGlobalAccess()) {
    hideColumns(hyperlinkColumns);
}


// ==============================
// Hook into nuPrint()
// ==============================

(function() {
    // Keep a reference to the original nuPrint
    const originalNuPrint = window.nuPrint;

    window.nuPrint = function() {
        // Before print: show the hyperlink columns
        showColumns(hyperlinkColumns);

        // Call the original nuPrint function
        originalNuPrint();

        // After short delay, re-hide the columns (so Browse view looks normal again)
        setTimeout(() => {
            if (!nuGlobalAccess()) hideColumns(hyperlinkColumns);
        }, 2000);
    };
})();


// ==============================
// Your existing blank column logic
// ==============================

if (!nuGlobalAccess()) {
    var columnIndex = 0;
    nuSetBrowseColumnSize(columnIndex, 0);
}

{
    const hiddenColumns = hideBlankColumns();

    if (!nuGlobalAccess()) var columnIndex = 0;

    const columnsToExclude = [...new Set([columnIndex, ...hiddenColumns])];
    nuPrintExcludeColumns(columnsToExclude);
}

function hideBlankColumns() {
    const hiddenColumns = [];
    const browseDiv = document.getElementById('nuRECORD');
    if (!browseDiv) return hiddenColumns;

    const headers = browseDiv.querySelectorAll('.nuBrowseTitle');
    if (headers.length === 0) return hiddenColumns;

    const colCount = headers.length;
    const isColumnBlank = new Array(colCount).fill(true);
    const dataCells = browseDiv.querySelectorAll('.nuCell[data-nu-column]');

    dataCells.forEach(cell => {
        const colIndex = parseInt(cell.getAttribute('data-nu-column'));
        const content = cell.textContent.trim();
        if (content !== '' && colIndex >= 0) isColumnBlank[colIndex] = false;
    });

    for (let j = 0; j < colCount; j++) {
        if (isColumnBlank[j]) {
            nuSetBrowseColumnSize(j, 0);
            hiddenColumns.push(j);
        }
    }
    return hiddenColumns;
}

Last edited by Paul on Thu Oct 09, 2025 6:41 pm, edited 1 time in total.
Paul
Posts: 154
Joined: Mon Aug 25, 2025 6:03 am
Has thanked: 30 times
Been thanked: 3 times

Re: Make a URL a clickable link

Unread post by Paul »

But then I get
Uncaught SyntaxError: Failed to execute 'appendChild' on 'Node': Identifier 'hyperlinkColumns' has already been declared

Uncaught SyntaxError: Failed to execute 'appendChild' on 'Node': Identifier 'hyperlinkColumns' has already been declared
at m (jquery-3.7.1.min.js:2:880)
at $e (jquery-3.7.1.min.js:2:46274)
at ce.fn.init.append (jquery-3.7.1.min.js:2:47633)
at nuAddJavaScript (nuform.js?ts=20251009182102:6294:12)
at nuBuildForm (nuform.js?ts=20251009182102:144:3)
at Object.successCallback (nuajax.js?ts=20251009182102:193:4)
at c (jquery-3.7.1.min.js:2:25304)
at Object.fireWith [as resolveWith] (jquery-3.7.1.min.js:2:26053)
at l (jquery-3.7.1.min.js:2:77782)
at XMLHttpRequest.<anonymous> (jquery-3.7.1.min.js:2:80265)

Help?
Post Reply