Country Flag Profile Field

Cory's Avatar
Cory · in Themes & Extensions
4 replies 88 views

Preview #1 - Preview #2

Use the version below for v1 boards; use this version for v2 and above.

Create a new custom profile field:

Admin CP → Users & Groups → Profile Fields → Add field

Handle: flags
Label: Country
Show in mini profile: Enable

Admin CP → Themes → Board Templates → Below the board

<script>

const countryN = ['None', 'Afghanistan', 'Algeria', 'Argentina', 'Australia', 'Austria', 'Belgium', 'Brazil', 'Canada', 'Chile', 'China', 'Colombia', 'Denmark', 'Egypt', 'Ethiopia', 'France', 'Germany', 'Ghana', 'Greece', 'Hong Kong', 'India', 'Indonesia', 'Iran', 'Iraq', 'Ireland', 'Italy', 'Jamaica', 'Japan', 'Korea', 'Lebanon', 'Malaysia', 'Mexico', 'Morocco', 'Mozambique', 'Nepal', 'Netherlands', 'New Zealand', 'Nigeria', 'Norway', 'Pakistan', 'Peru', 'Philippines', 'Poland', 'Portugal', 'Russia', 'Saudi Arabia', 'South Africa', 'Spain', 'Sudan', 'Sweden', 'Switzerland', 'Taiwan', 'Thailand', 'Turkey', 'Uganda', 'Ukraine', 'United Kingdom', 'United States', 'Venezuela', 'Vietnam', 'Yemen'];
const countryI = ['https://files.jcink.net/uploads/cory//None.png', 'https://files.jcink.net/uploads/cory//Afghanistan.png', 'https://files.jcink.net/uploads/cory//Algeria.png', 'https://files.jcink.net/uploads/cory//Argentina_Flag_32.png', 'https://files.jcink.net/uploads/cory//Australia_Flag_32.png', 'https://files.jcink.net/uploads/cory//Austria_Flag_32.png', 'https://files.jcink.net/uploads/cory//Belgium_Flag_32.png', 'https://files.jcink.net/uploads/cory//Brazil_Flag_32.png', 'https://files.jcink.net/uploads/cory//Canada_Flag_32.png', 'https://files.jcink.net/uploads/cory//Chile_Flag_32.png', 'https://files.jcink.net/uploads/cory//China_Flag_32.png', 'https://files.jcink.net/uploads/cory//Colombia.png', 'https://files.jcink.net/uploads/cory//Denmark_Flag_32.png', 'https://files.jcink.net/uploads/cory//Egypt.png', 'https://files.jcink.net/uploads/cory//Ethiopia.png', 'https://files.jcink.net/uploads/cory//France_Flag_32.png', 'https://files.jcink.net/uploads/cory//Germany_Flag_32.png', 'https://files.jcink.net/uploads/cory//Ghana.png', 'https://files.jcink.net/uploads/cory//Greece_Flag_32.png', 'https://files.jcink.net/uploads/cory//Hong_Kong_Flag_32.png', 'https://files.jcink.net/uploads/cory//India_Flag_32.png', 'https://files.jcink.net/uploads/cory//Indonesia.png', 'https://files.jcink.net/uploads/cory//Iran.png', 'https://files.jcink.net/uploads/cory//Iraq.png', 'https://files.jcink.net/uploads/cory//Ireland_Flag_32.png', 'https://files.jcink.net/uploads/cory//Italy_Flag_32.png', 'https://files.jcink.net/uploads/cory//Jamaica_Flag_32.png', 'https://files.jcink.net/uploads/cory//Japan_Flag_32.png', 'https://files.jcink.net/uploads/cory//Korea_Flag_32.png', 'https://files.jcink.net/uploads/cory//Lebanon_Flag_32.png', 'https://files.jcink.net/uploads/cory//Malaysia_Flag_32.png', 'https://files.jcink.net/uploads/cory//Mexico_Flag_32.png', 'https://files.jcink.net/uploads/cory//Morocco.png', 'https://files.jcink.net/uploads/cory//Mozambique.png', 'https://files.jcink.net/uploads/cory//Nepal.png', 'https://files.jcink.net/uploads/cory//Netherlands_Flag_32.png', 'https://files.jcink.net/uploads/cory//New_Zealand_Flag_32.png', 'https://files.jcink.net/uploads/cory//Nigeria.png', 'https://files.jcink.net/uploads/cory//Norway_Flag_32.png', 'https://files.jcink.net/uploads/cory//Pakistan.png', 'https://files.jcink.net/uploads/cory//Peru.png', 'https://files.jcink.net/uploads/cory//Philippines_Flag_32.png', 'https://files.jcink.net/uploads/cory//Poland_Flag_32.png', 'https://files.jcink.net/uploads/cory//Portugal_Flag_32.png', 'https://files.jcink.net/uploads/cory//Russia_Flag_32.png', 'https://files.jcink.net/uploads/cory//Saudi_Arabia.png', 'https://files.jcink.net/uploads/cory//South_Africa.png', 'https://files.jcink.net/uploads/cory//Spain_Flag_32.png', 'https://files.jcink.net/uploads/cory//Sudan.png', 'https://files.jcink.net/uploads/cory//Sweden_Flag_32.png', 'https://files.jcink.net/uploads/cory//Switzerland_Flag_32.png', 'https://files.jcink.net/uploads/cory//Taiwan_Flag_32.png', 'https://files.jcink.net/uploads/cory//Thailand_Flag_32.png', 'https://files.jcink.net/uploads/cory//Turkey_Flag_32.png', 'https://files.jcink.net/uploads/cory//Uganda.png', 'https://files.jcink.net/uploads/cory//Ukraine.png', 'https://files.jcink.net/uploads/cory//United_Kingdom_flag_32.png', 'https://files.jcink.net/uploads/cory//United_States.png', 'https://files.jcink.net/uploads/cory//Venezuela_Flag_32.png', 'https://files.jcink.net/uploads/cory//Vietnam_Flag_32.png', 'https://files.jcink.net/uploads/cory//Yemen.png'];
const label = document.querySelectorAll('label.input-label');
let value;

label.forEach(element => {
if (element && element.innerText.includes('Country')) {
element.parentElement.nextElementSibling.querySelector('input').style.display = 'none';
const div = document.createElement('div');
div.style.display = 'flex';
div.style.flexWrap = 'wrap';
div.style.gap = '10px';

for (let i = 0; i < countryN.length; i++) {
const img = document.createElement('img');
img.src = countryI[i];
img.alt = countryN[i];
img.title = countryN[i];
img.className = 'country-flag';
img.width = '32';
img.height = '32';
img.style.cursor = 'pointer';
img.style.opacity = '0.5';
element.parentElement.nextElementSibling.appendChild(div);
div.appendChild(img);
}

value = element.parentElement.nextElementSibling.querySelector('input').value;
}
});

const flag = document.querySelectorAll('img.country-flag');

flag.forEach(element => {
if (element.title === value) {
element.style.opacity = '1';
}

element.addEventListener('click', function() {
flag.forEach(allElements => {
allElements.style.opacity = '0.5';
});

const title = element.title;
element.parentElement.parentElement.querySelector('input').value = title;
element.style.opacity = '1';
});
});

const about = document.querySelectorAll('div.profile-about__item');

about.forEach(element => {
if (element.querySelector('dt').innerText === 'Country') {
const myCountry = element.querySelector('dd').innerText;

for (let i = 0; i < countryN.length; i++) {
if (myCountry === countryN[i]) {
element.querySelector('dd').innerHTML = `<img src="${countryI[i]}" title="${countryN[i]}" alt="${countryN[i]}">`;
}
}
}
});

const mini = document.querySelectorAll('div.mini-profile--custom dt');

mini.forEach(element => {
if (element.innerText === 'Country') {
const myCountry = element.nextElementSibling.innerText;

for (let i = 0; i < countryN.length; i++) {
if (myCountry === countryN[i]) {
element.nextElementSibling.innerHTML = `<img src="${countryI[i]}" title="${countryN[i]}" alt="${countryN[i]}">`;
}
}
}
});
</script>

Last edited by Cory

👍 1

Noce, I had to put it "Top of the page" as all my other input boxes are maxed out LOL

"Please remain seated. The captain has absolutely no idea what he’s doing."

Hello everyone, just a quick update regarding the flags 🙂

I managed to get them working on ForumSpark 2.0, at least so far! You can select your country flag through Edit Profile and it will then display on your profile. I haven't managed to get it showing in the post profile/mini profile yet, so that's still a work in progress.

The code below also includes some CSS adjustments to fit my current theme. If you decide to use it you may want to tweak the CSS to match your own forum.

One other thing that you'll need to find:

[name="custom_field[7]"]

and change the 7 to the number of your own Country (or whatever name) custom profile field.

Code:

<script>
(function () {

    'use strict';

    const COUNTRIES = [
        'AF','AL','DZ','AS','AD','AO','AI','AQ','AG','AR',
        'AM','AW','AU','AT','AZ','BS','BH','BD','BB','BY',
        'BE','BZ','BJ','BM','BT','BO','BA','BW','BR','BN',
        'BG','BF','BI','CV','KH','CM','CA','KY','CF','TD',
        'CL','CN','CX','CC','CO','KM','CG','CD','CK','CR',
        'CI','HR','CU','CY','CZ','DK','DJ','DM','DO','EC',
        'EG','SV','GQ','ER','EE','ET','FK','FO','FJ','FI',
        'FR','GF','PF','GA','GM','GE','DE','GH','GI','GR',
        'GL','GD','GP','GU','GT','GG','GN','GW','GY','HT',
        'HN','HK','HU','IS','IN','ID','IR','IQ','IE','IM',
        'IL','IT','JM','JP','JE','JO','KZ','KE','KI','KP',
        'KR','KW','KG','LA','LV','LB','LS','LR','LY','LI',
        'LT','LU','MO','MK','MG','MW','MY','MV','ML','MT',
        'MH','MQ','MR','MU','YT','MX','FM','MD','MC','MN',
        'ME','MS','MA','MZ','MM','NA','NR','NP','NL','NC',
        'NZ','NI','NE','NG','NU','NF','MP','NO','OM','PK',
        'PW','PS','PA','PG','PY','PE','PH','PN','PL','PT',
        'PR','QA','RE','RO','RU','RW','BL','SH','KN','LC',
        'MF','PM','VC','WS','SM','ST','SA','SN','RS','SC',
        'SL','SG','SX','SK','SI','SB','SO','ZA','GS','SS',
        'ES','LK','SD','SR','SJ','SE','CH','SY','TW','TJ',
        'TZ','TH','TL','TG','TK','TO','TT','TN','TR','TM',
        'TC','TV','UG','UA','AE','GB','US','UY','UZ','VU',
        'VA','VE','VN','VG','VI','WF','EH','YE','ZM','ZW'
    ];

    /*
     * Country flag images
     * Uses the two-letter country code.
     */

    function getFlagURL(code) {

        return 'https://flagcdn.com/w40/' +
            code.toLowerCase() +
            '.png';

    }

    function addStyles() {

        if (
            document.getElementById(
                'ek-country-style'
            )
        ) {
            return;
        }

        const style =
            document.createElement('style');

        style.id =
            'ek-country-style';

        style.textContent = `

            .ek-country-picker {
                display: grid;
                grid-template-columns: repeat(20, 38px);
                gap: 4px;
                width: fit-content;
                max-width: 100%;
                margin-top: 8px;
                padding: 5px;
                box-sizing: border-box;
                border-radius: 6px;
                background: rgba(0,0,0,.12);
            }

            .ek-country-picker button {
                appearance: none;
                display: flex;
                align-items: center;
                justify-content: center;
                width: 38px;
                height: 30px;
                padding: 3px;
                margin: 0;
                border: 1px solid rgba(255,255,255,.10);
                border-radius: 4px;
                background: rgba(255,255,255,.035);
                cursor: pointer;
                box-sizing: border-box;
                transition:
                    background .15s ease,
                    border-color .15s ease,
                    transform .15s ease;
            }

            .ek-country-picker button:hover {
                background: rgba(255,255,255,.10);
                border-color: rgba(255,255,255,.28);
                transform: translateY(-1px);
            }

            .ek-country-picker button.ek-country-selected {
                background: rgba(255,255,255,.12);
                border-color: rgba(255,255,255,.60);
                box-shadow:
                    0 0 0 1px rgba(255,255,255,.08),
                    0 2px 6px rgba(0,0,0,.20);
            }

            .ek-country-picker img {
                display: block;
                width: auto;
                height: 17px;
                max-width: 29px;
                object-fit: contain;
                pointer-events: none;
            }

            .ek-profile-country-flag {
                display: inline-block;
                width: auto;
                height: 20px;
                max-width: 32px;
                object-fit: contain;
                vertical-align: middle;
            }

            @media (max-width: 900px) {

                .ek-country-picker {
                    grid-template-columns:
                        repeat(15, 38px);
                }

            }

            @media (max-width: 700px) {

                .ek-country-picker {
                    grid-template-columns:
                        repeat(10, 38px);
                }

            }

            @media (max-width: 500px) {

                .ek-country-picker {
                    grid-template-columns:
                        repeat(7, 38px);
                }

            }

        `;

        document.head.appendChild(style);
    }

    function addCountryPicker() {

        const input =
            document.querySelector(
                'input[name="custom_field[7]"]'
            );

        if (!input) {
            return;
        }

        if (
            document.querySelector(
                '.ek-country-picker'
            )
        ) {
            return;
        }

        input.style.display =
            'none';

        const picker =
            document.createElement('div');

        picker.className =
            'ek-country-picker';

        const currentCountry =
            input.value
                .trim()
                .toUpperCase();

        COUNTRIES.forEach(
            function (code) {

                const button =
                    document.createElement(
                        'button'
                    );

                button.type =
                    'button';

                button.title =
                    code;

                button.setAttribute(
                    'aria-label',
                    code
                );

                const image =
                    document.createElement(
                        'img'
                    );

                image.src =
                    getFlagURL(code);

                image.alt =
                    code;

                image.loading =
                    'lazy';

                button.appendChild(
                    image
                );

                if (
                    currentCountry ===
                    code
                ) {

                    button.classList.add(
                        'ek-country-selected'
                    );

                }

                button.addEventListener(
                    'click',
                    function () {

                        input.value =
                            code;

                        input.dispatchEvent(
                            new Event(
                                'input',
                                {
                                    bubbles: true
                                }
                            )
                        );

                        input.dispatchEvent(
                            new Event(
                                'change',
                                {
                                    bubbles: true
                                }
                            )
                        );

                        picker
                            .querySelectorAll(
                                'button'
                            )
                            .forEach(
                                function (item) {

                                    item.classList.remove(
                                        'ek-country-selected'
                                    );

                                }
                            );

                        button.classList.add(
                            'ek-country-selected'
                        );

                    }
                );

                picker.appendChild(
                    button
                );

            }
        );

        input.parentElement.appendChild(
            picker
        );
    }

    /*
     * Public profile:
     *
     * <div class="profile-about__item">
     *     <dt>Country</dt>
     *     <dd>
     *         <a href="https://GB">GB</a>
     *     </dd>
     * </div>
     */

    function displayCountryFlag() {

        document
            .querySelectorAll(
                'div.profile-about__item'
            )
            .forEach(
                function (item) {

                    const label =
                        item.querySelector(
                            'dt'
                        );

                    const value =
                        item.querySelector(
                            'dd'
                        );

                    if (
                        !label ||
                        !value
                    ) {
                        return;
                    }

                    if (
                        label.textContent
                            .trim()
                            .toLowerCase() !==
                        'country'
                    ) {
                        return;
                    }

                    if (
                        value.querySelector(
                            '.ek-profile-country-flag'
                        )
                    ) {
                        return;
                    }

                    const link =
                        value.querySelector(
                            'a'
                        );

                    if (!link) {
                        return;
                    }

                    const code =
                        link.textContent
                            .trim()
                            .toUpperCase();

                    if (
                        !COUNTRIES.includes(
                            code
                        )
                    ) {
                        return;
                    }

                    const flag =
                        document.createElement(
                            'img'
                        );

                    flag.className =
                        'ek-profile-country-flag';

                    flag.src =
                        getFlagURL(code);

                    flag.alt =
                        code;

                    flag.title =
                        code;

                    flag.loading =
                        'lazy';

                    flag.decoding =
                        'async';

                    value.replaceChildren(
                        flag
                    );

                }
            );
    }

    /*
     * Older profile layout
     */

    function displayOldCountryFlag() {

        document
            .querySelectorAll('p')
            .forEach(
                function (row) {

                    const label =
                        row.querySelector(
                            ':scope > span'
                        );

                    const value =
                        row.querySelector(
                            ':scope > b'
                        );

                    if (
                        !label ||
                        !value
                    ) {
                        return;
                    }

                    if (
                        label.textContent
                            .trim()
                            .toLowerCase() !==
                        'country'
                    ) {
                        return;
                    }

                    if (
                        value.querySelector(
                            '.ek-profile-country-flag'
                        )
                    ) {
                        return;
                    }

                    const code =
                        value.textContent
                            .trim()
                            .toUpperCase();

                    if (
                        !COUNTRIES.includes(
                            code
                        )
                    ) {
                        return;
                    }

                    const flag =
                        document.createElement(
                            'img'
                        );

                    flag.className =
                        'ek-profile-country-flag';

                    flag.src =
                        getFlagURL(code);

                    flag.alt =
                        code;

                    flag.title =
                        code;

                    flag.loading =
                        'lazy';

                    flag.decoding =
                        'async';

                    value.replaceChildren(
                        flag
                    );

                }
            );
    }

    function updateCountryDisplay() {

        displayCountryFlag();

        displayOldCountryFlag();

    }

    function run() {

        addStyles();

        addCountryPicker();

        updateCountryDisplay();

        const observer =
            new MutationObserver(
                function () {

                    updateCountryDisplay();

                }
            );

        observer.observe(
            document.body,
            {
                childList: true,
                subtree: true
            }
        );
    }

    if (
        document.readyState ===
        'loading'
    ) {

        document.addEventListener(
            'DOMContentLoaded',
            run
        );

    } else {

        run();

    }

})();
</script>

Last edited by empire

👍 1 ❤️ 1

"Please remain seated. The captain has absolutely no idea what he’s doing."

Nice work!

Updated code to also show flag on the about me tab on profile that I did not even realise that I forgot about XD

👍 1

"Please remain seated. The captain has absolutely no idea what he’s doing."

Theme: FS 2.0
Create Your Community with ForumSpark

ForumSpark is a modern community platform built on custom software. It combines the familiar feel of classic forums with a fast, simple experience designed for today’s communities.