Back to feed
ForumSpark Support Themes & Extensions Join

Country Flag Profile Field

Cory · 7 months ago · 4 replies · 45

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>
4 replies
Empire · 7 months ago

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

Empire · 1 month ago

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>

Cedric · 1 month ago

Nice work!

Empire · 1 month ago

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

Create a free account to join the conversation.
Sign up free
ForumSpark © 2023 - 2026 · ForumSpark.net · Terms