{"id":8237011,"date":"2025-03-12T15:11:24","date_gmt":"2025-03-12T15:11:24","guid":{"rendered":"https:\/\/www.aese.pt\/form-page\/"},"modified":"2026-05-13T14:31:27","modified_gmt":"2026-05-13T14:31:27","slug":"form-page","status":"publish","type":"page","link":"https:\/\/www.aese.pt\/en\/form-page\/","title":{"rendered":"Form Page"},"content":{"rendered":"\n<section id=\"\" class=\"container_rf\">\n            <div class=\"container_rf__form\">\n            <h1 class=\"container_rf__title\">\n                <svg width=\"28\" height=\"2\" viewBox=\"0 0 28 2\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                    <path d=\"M0.8 1.98566V0.385659H27.2V1.98566H0.8Z\" fill=\"#D83F00\" \/>\n                <\/svg>\n\n                Candidatura ao AESE Executive MBA            <\/h1>\n            Form not found or invalid ID. Please select a valid form ID.        <\/div>\n    <\/section>\n<script>\n    document.addEventListener('DOMContentLoaded', function() {\n        \/**\n         * Creates progress bar elements for the form steps\n         *\/\n        const createProgressBars = () => {\n            const progressContainer = document.querySelector('.ff-el-progress');\n            if (!progressContainer) {\n                console.warn('Progress container not found');\n                return;\n            }\n\n            \/\/ Create progress bar if it doesn't exist\n            let progressBar = progressContainer.querySelector('.ff-el-progress-bar');\n            if (!progressBar) {\n                progressBar = document.createElement('div');\n                progressBar.className = 'ff-el-progress-bar';\n                progressContainer.appendChild(progressBar);\n            }\n\n            \/\/ Clear and create the 3 progress items\n            progressBar.innerHTML = '';\n            const TOTAL_STEPS = 3;\n            for (let i = 0; i < TOTAL_STEPS; i++) {\n                const item = document.createElement('div');\n                item.className = 'ff-el-progress-item';\n                progressBar.appendChild(item);\n            }\n        };\n\n        \/**\n         * Updates progress bar based on current form step\n         *\/\n        let updateProgressTimeout;\n        const updateProgress = () => {\n            const progressStatus = document.querySelector('.ff-el-progress-status');\n            if (!progressStatus) {\n                console.warn('Progress status not found');\n                return;\n            }\n\n            \/\/ Extract current step from the status text - look for any number\n            const match = progressStatus.textContent.match(\/(\\d+)\/);\n            if (!match) return;\n            \n            const currentStep = parseInt(match[1]);\n            \n            \/\/ Update the text to Portuguese format\n            progressStatus.textContent = `STEP ${currentStep}\/3 `;\n\n            \/\/ Handle all step navigations\n            const stepNavs = document.querySelectorAll('.step-nav');\n            stepNavs.forEach(stepNav => {\n                \/\/ Add mobile required fields text (full width, appears first)\n                let mobileRequiredText = stepNav.querySelector('.required-fields-text-mobile');\n                if (!mobileRequiredText) {\n                    mobileRequiredText = document.createElement('div');\n                    mobileRequiredText.className = 'required-fields-text-mobile';\n                    mobileRequiredText.textContent = `* Required fields`;\n                    stepNav.insertBefore(mobileRequiredText, stepNav.firstChild);\n                }\n\n                \/\/ Add spacing div if it doesn't exist\n                let spacingDiv = stepNav.querySelector('.step-nav-spacing');\n                if (!spacingDiv) {\n                    spacingDiv = document.createElement('div');\n                    spacingDiv.className = 'step-nav-spacing';\n                    spacingDiv.style.flexBasis = '33.33%';\n                    \/\/ Insert after mobile text\n                    if (mobileRequiredText.nextSibling) {\n                        stepNav.insertBefore(spacingDiv, mobileRequiredText.nextSibling);\n                    } else {\n                        stepNav.appendChild(spacingDiv);\n                    }\n                }\n\n                \/\/ Add required fields text to the first space (desktop only)\n                let requiredFieldsText = spacingDiv.querySelector('.required-fields-text');\n                if (!requiredFieldsText) {\n                    requiredFieldsText = document.createElement('div');\n                    requiredFieldsText.className = 'required-fields-text';\n                    requiredFieldsText.textContent = `* Required fields`;\n                    spacingDiv.appendChild(requiredFieldsText);\n                }\n\n                \/\/ Create or get navigation elements container\n                let navElementsContainer = stepNav.querySelector('.nav-elements-container');\n                if (!navElementsContainer) {\n                    navElementsContainer = document.createElement('div');\n                    navElementsContainer.className = 'nav-elements-container';\n                    navElementsContainer.style.display = 'flex';\n                    navElementsContainer.style.justifyContent = 'space-between';\n                    navElementsContainer.style.alignItems = 'center';\n\n                    const updateFlexBasis = () => {\n                        const isMobile = window.matchMedia('(max-width: 1024px)').matches;\n                        navElementsContainer.style.flexBasis = isMobile ? '100%' : '66.67%';\n                    };\n\n                    \/\/ Set initial flex basis\n                    updateFlexBasis();\n\n                    \/\/ Add debounced resize listener\n                    let resizeTimeout;\n                    window.addEventListener('resize', () => {\n                        if (resizeTimeout) {\n                            clearTimeout(resizeTimeout);\n                        }\n                        resizeTimeout = setTimeout(updateFlexBasis, 250);\n                    });\n                    \n                    \/\/ Move existing elements into the container (skip mobile text and spacing div)\n                    const elementsToMove = Array.from(stepNav.children).filter(\n                        child => !child.classList.contains('required-fields-text-mobile') && \n                                !child.classList.contains('step-nav-spacing')\n                    );\n                    elementsToMove.forEach(element => {\n                        navElementsContainer.appendChild(element);\n                    });\n                    stepNav.appendChild(navElementsContainer);\n                }\n\n                \/\/ Handle progress status element\n                const prevButton = stepNav.querySelector('.ff-btn-prev');\n                let stepStatus = stepNav.querySelector('.ff-el-progress-status');\n\n                if (!stepStatus) {\n                    stepStatus = progressStatus.cloneNode(true);\n                    if (prevButton && prevButton.style.visibility !== 'hidden') {\n                        prevButton.insertAdjacentElement('afterend', stepStatus);\n                    } else {\n                        navElementsContainer.insertBefore(stepStatus, navElementsContainer.firstChild);\n                    }\n                }\n                stepStatus.textContent = `STEP ${currentStep}\/3 `;\n                \n                \/\/ Add is-last-step class only when on step 3\n                if (currentStep === 3) {\n                    stepStatus.classList.add('is-last-step');\n                } else {\n                    stepStatus.classList.remove('is-last-step');\n                }\n\n           \n                \n                \/\/ Apply flex distribution to main container\n                stepNav.style.display = 'flex';\n                stepNav.style.width = '100%';\n            });\n\n            const items = document.querySelectorAll('.ff-el-progress-item');\n            items.forEach((item, index) => {\n                \/\/ Add both active and completed classes for current and previous steps\n                if (index < currentStep) {\n                    item.classList.add('active', 'completed');\n                } else {\n                    item.classList.remove('active', 'completed');\n                }\n            });\n        };\n\n        \/**\n         * Initializes form step tracking and observers\n         *\/\n        const initializeFormSteps = () => {\n            createProgressBars();\n            updateProgress();\n\n            const formSteps = document.querySelector('.ff-step-container');\n            if (!formSteps) {\n                console.warn('Form steps container not found');\n                return;\n            }\n\n            let isUpdating = false;\n            const observer = new MutationObserver(() => {\n                if (!isUpdating) {\n                    isUpdating = true;\n                    clearTimeout(updateProgressTimeout);\n                    updateProgressTimeout = setTimeout(() => {\n                        updateProgress();\n                        isUpdating = false;\n                    }, 100);\n                }\n            });\n            \n            observer.observe(formSteps, {\n                attributes: true,\n                attributeFilter: ['class'],\n                subtree: true,\n                childList: false\n            });\n        };\n\n        \/**\n         * Enhances select elements with custom wrapper and rotation functionality\n         *\/\n        const enhanceSelectElements = () => {\n            const selects = document.querySelectorAll('.ff-default select.ff-el-form-control');\n            \n            selects.forEach(select => {\n                const wrapper = document.createElement('div');\n                wrapper.className = 'select-wrapper';\n                select.parentNode.insertBefore(wrapper, select);\n                wrapper.appendChild(select);\n\n                let isOpen = false;\n\n                const handleSelectOpen = () => {\n                    if (!isOpen) {\n                        isOpen = true;\n                        wrapper.classList.add('open');\n                    }\n                };\n\n                const handleSelectClose = () => {\n                    isOpen = false;\n                    wrapper.classList.remove('open');\n                };\n\n                \/\/ Event listeners\n                select.addEventListener('mousedown', handleSelectOpen);\n                select.addEventListener('mouseup', (e) => {\n                    setTimeout(() => {\n                        if (isOpen && !e.target.value) handleSelectClose();\n                    }, 50);\n                });\n                select.addEventListener('change', handleSelectClose);\n\n                \/\/ Modified blur handler to ensure arrow rotation\n                select.addEventListener('blur', () => {\n                    handleSelectClose();\n                });\n\n                \/\/ Add click outside listener\n                document.addEventListener('click', (e) => {\n                    if (!wrapper.contains(e.target) && isOpen) {\n                        handleSelectClose();\n                    }\n                });\n            });\n        };\n\n        \/**\n         * Customizes the file upload button with additional information\n         *\/\n        const customizeFileUpload = () => {\n            const uploadBtns = document.querySelectorAll('.ff_upload_btn.ff-btn');\n            uploadBtns.forEach(btn => {\n                \/\/ Add drag and drop event listeners\n                btn.addEventListener('dragover', (e) => {\n                    e.preventDefault();\n                    btn.classList.add('dragover');\n                });\n\n                btn.addEventListener('dragleave', (e) => {\n                    e.preventDefault();\n                    btn.classList.remove('dragover');\n                });\n\n                btn.addEventListener('drop', (e) => {\n                    btn.classList.remove('dragover');\n                });\n\n                \/\/ Existing code for button customization\n                const span = document.createElement('span');\n                span.textContent = 'choose on the computer';\n                btn.textContent = 'Drag the file here or ';\n                btn.appendChild(span);\n\n                \/\/ Add file information element\n                const fileInfo = document.createElement('div');\n                fileInfo.className = 'file-info';\n                fileInfo.innerHTML = `\n                    <span>Supported File Types: jpeg, pdf, png<\/span>\n                    <span>Maximum Size: 10 MB<\/span>\n                `;\n                btn.parentNode.insertBefore(fileInfo, btn.nextSibling);\n            });\n        };\n\n        \/**\n         * Manages uploaded files list label visibility\n         *\/\n        const addUploadedLabel = () => {\n            const formContainer = document.querySelector('.fluentform');\n            if (!formContainer) return;\n\n            const updateLabel = () => {\n                const uploadedList = document.querySelector('.ff-uploaded-list');\n                const existingLabel = document.querySelector('.uploaded-files-label');\n                \n                \/\/ Remove label if list doesn't exist or is not visible\n                if (!uploadedList || uploadedList.offsetHeight === 0 || window.getComputedStyle(uploadedList).display === 'none') {\n                    if (existingLabel) {\n                        existingLabel.remove();\n                    }\n                    return;\n                }\n\n                \/\/ Check for files in the list (excluding the label itself)\n                const hasFiles = Array.from(uploadedList.children).some(child => !child.classList.contains('uploaded-files-label'));\n                \n                if (hasFiles) {\n                    if (!existingLabel) {\n                        const label = document.createElement('div');\n                        label.className = 'uploaded-files-label';\n                        label.textContent = 'Loaded';\n                        uploadedList.insertBefore(label, uploadedList.firstChild);\n                    }\n                } else if (existingLabel) {\n                    existingLabel.remove();\n                }\n            };\n\n            \/\/ Setup mutation observer for dynamic changes\n            let isLabelUpdating = false;\n            let updateLabelTimeout;\n            const observer = new MutationObserver(() => {\n                if (!isLabelUpdating) {\n                    isLabelUpdating = true;\n                    clearTimeout(updateLabelTimeout);\n                    updateLabelTimeout = setTimeout(() => {\n                        updateLabel();\n                        isLabelUpdating = false;\n                    }, 100);\n                }\n            });\n\n            observer.observe(formContainer, {\n                childList: true,\n                subtree: true,\n                attributes: true\n            });\n\n            updateLabel();\n        };\n\n        \/**\n         * Removes the default submit button content\n         *\/\n        const cleanSubmitButtonWrapper = () => {\n            const submitWrapper = document.querySelector('.ff_submit_btn_wrapper');\n            if (submitWrapper) {\n                \/\/ Preserve btn-custom elements\n                const customButtons = submitWrapper.querySelectorAll('.btn-custom');\n                submitWrapper.innerHTML = ''; \/\/ Clear the content\n                \/\/ Re-add custom buttons if any\n                customButtons.forEach(btn => submitWrapper.appendChild(btn));\n            }\n        };\n\n        \/**\n         * Adjusts form spacing based on title height\n         *\/\n        const adjustFormSpacing = () => {\n            const titleElement = document.querySelector('.container_rf__title');\n            const formContainer = document.querySelector('.frm-fluent-form .ff-t-container:has(.fvb_form)');\n            \n            if (titleElement && formContainer) {\n                const titleHeight = titleElement.offsetHeight;\n                const threshold = 60; \/\/ 60px threshold\n                \n                if (titleHeight > threshold) {\n                    formContainer.style.marginTop = '8rem';\n                } else {\n                    formContainer.style.marginTop = '6rem';\n                }\n            }\n        };\n\n        \/**\n         * Sets the program selection based on URL parameter\n         *\/\n        const setProgramFromParams = () => {\n            const urlParams = new URLSearchParams(window.location.search);\n            const programName = urlParams.get('programName');\n            if (!programName) return;\n\n            const decodedProgram = decodeURIComponent(programName)\n                .replace(\/\\+\/g, ' ')\n                .toLowerCase()\n                .trim();\n            \n            \n            const waitForForm = () => {\n                const form = document.querySelector('.fluentform');\n                if (!form) {\n                    setTimeout(waitForForm, 500);\n                    return;\n                }\n\n                let isProgramUpdating = false;\n                const observer = new MutationObserver(() => {\n                    if (!isProgramUpdating) {\n                        isProgramUpdating = true;\n                        const programSelect = form.querySelector('select.fr_program-inscrition');\n                        \n                        if (programSelect) {\n                            observer.disconnect();\n                            \n                            const options = Array.from(programSelect.options);\n                            \n                            const matchingOption = options.find(option => {\n                                const optionText = option.text.toLowerCase().trim();\n                                \n                                \/\/ Skip empty or \"select\" options\n                                if (!option.value || optionText === 'selecione') return false;\n                                \n                                \n                                \/\/ Try exact match\n                                if (optionText === decodedProgram) return true;\n                                \n                                \/\/ Try includes match\n                                if (optionText.includes(decodedProgram) || decodedProgram.includes(optionText)) return true;\n                                \n                                return false;\n                            });\n\n                            if (matchingOption) {\n                                programSelect.value = matchingOption.value;\n                                \n                                \/\/ Trigger both change and input events\n                                const events = ['change', 'input'];\n                                events.forEach(eventType => {\n                                    const event = new Event(eventType, { bubbles: true });\n                                    programSelect.dispatchEvent(event);\n                                });\n                            }\n                        }\n                        isProgramUpdating = false;\n                    }\n                });\n\n                observer.observe(form, {\n                    childList: true,\n                    subtree: true,\n                    attributes: true\n                });\n            };\n\n            waitForForm();\n        };\n\n        \/**\n         * Monitors title height changes and adjusts spacing\n         *\/\n        const monitorTitleHeight = () => {\n            const titleElement = document.querySelector('.container_rf__title');\n            if (!titleElement) {\n                setTimeout(monitorTitleHeight, 500);\n                return;\n            }\n\n            \/\/ Initial adjustment\n            adjustFormSpacing();\n\n            \/\/ Monitor for changes\n            const observer = new ResizeObserver(() => {\n                adjustFormSpacing();\n            });\n\n            observer.observe(titleElement);\n        };\n\n        \/**\n         * Adds required fields text for forms without steps\n         *\/\n        const addRequiredFieldsTextForNonStepForms = () => {\n            \/\/ Check if there are step navigations\n            const stepNavs = document.querySelectorAll('.step-nav:not(.no-steps-form)');\n            \n            \/\/ If no original step navigation found, this is likely a single-step form\n            if (stepNavs.length === 0) {\n                \/\/ Don't add if we already added it\n                if (document.querySelector('.step-nav.no-steps-form')) {\n                    return;\n                }\n                \n                \/\/ Look for submit button wrapper or form buttons area\n                const submitWrapper = document.querySelector('.ff_submit_btn_wrapper');\n                const formContainer = document.querySelector('.fluentform');\n                \n                if (formContainer) {\n                    \/\/ Look for FluentForm's table structure with ff-t-cell\n                    const allCells = formContainer.querySelectorAll('.ff-t-cell.ff-t-column-1');\n                    let targetCell = null;\n                    \n                    \/\/ First, try to find the very last row that has a submit button\n                    const allRows = formContainer.querySelectorAll('.ff-t-row');\n                    let lastRowWithSubmit = null;\n                    \n                    for (let i = allRows.length - 1; i >= 0; i--) {\n                        const row = allRows[i];\n                        if (row.querySelector('.ff-btn-submit, button[type=\"submit\"], input[type=\"submit\"]')) {\n                            lastRowWithSubmit = row;\n                            break;\n                        }\n                    }\n                    \n                    if (lastRowWithSubmit) {\n                        \/\/ Look for the left cell in this row\n                        const leftCell = lastRowWithSubmit.querySelector('.ff-t-cell.ff-t-column-1');\n                        if (leftCell && (!leftCell.querySelector('input, select, textarea, button') || leftCell.textContent.trim() === '')) {\n                            targetCell = leftCell;\n                        }\n                    }\n                    \n                    \/\/ If we didn't find it that way, try the simpler approach\n                    if (!targetCell) {\n                        for (let cell of allCells) {\n                            if (cell.textContent.trim() === '' && !cell.querySelector('input, select, textarea')) {\n                                \/\/ Check if next cell has submit button\n                                const nextCell = cell.nextElementSibling;\n                                if (nextCell && nextCell.querySelector('.ff-btn-submit, button[type=\"submit\"], input[type=\"submit\"]')) {\n                                    targetCell = cell;\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                    \n                    if (targetCell) {\n                        \/\/ Use the empty left cell to place our required text\n                        const requiredFieldsText = document.createElement('div');\n                        requiredFieldsText.className = 'required-fields-text';\n                        requiredFieldsText.textContent = `* Required fields`;\n                        \n                        targetCell.appendChild(requiredFieldsText);\n                        return; \/\/ Exit early since we found and used the FluentForm structure\n                    }\n                    \n                    \/\/ Fallback to our original method if FluentForm structure is different\n                    let targetInsertionPoint = null;\n                    let submitElement = null;\n                    \n                    \/\/ Look for submit button wrapper first\n                    if (submitWrapper) {\n                        targetInsertionPoint = submitWrapper.parentNode;\n                        submitElement = submitWrapper;\n                    } else {\n                        \/\/ Look for any submit button\n                        const submitBtn = formContainer.querySelector('.ff-btn-submit, button[type=\"submit\"], input[type=\"submit\"]');\n                        if (submitBtn) {\n                            targetInsertionPoint = submitBtn.parentNode;\n                            submitElement = submitBtn;\n                        } else {\n                            \/\/ Last resort: append to form container\n                            targetInsertionPoint = formContainer;\n                        }\n                    }\n                    \n                    if (targetInsertionPoint) {\n                        \/\/ Create a container that mimics the step-nav structure for bottom positioning\n                        const requiredFieldsContainer = document.createElement('div');\n                        requiredFieldsContainer.className = 'step-nav no-steps-form';\n                        \n                        \/\/ Add mobile required fields text (full width, appears first)\n                        const mobileRequiredText = document.createElement('div');\n                        mobileRequiredText.className = 'required-fields-text-mobile';\n                        mobileRequiredText.textContent = `* Required fields`;\n                        requiredFieldsContainer.appendChild(mobileRequiredText);\n\n                        \/\/ Add left spacing div (33.33% for required text)\n                        const spacingDiv = document.createElement('div');\n                        spacingDiv.className = 'step-nav-spacing';\n                        requiredFieldsContainer.appendChild(spacingDiv);\n\n                        \/\/ Add required fields text to the left space (desktop only)\n                        const requiredFieldsText = document.createElement('div');\n                        requiredFieldsText.className = 'required-fields-text';\n                        requiredFieldsText.textContent = `* Required fields`;\n                        spacingDiv.appendChild(requiredFieldsText);\n\n                        \/\/ Create navigation elements container for the submit button (66.67% for button)\n                        const navElementsContainer = document.createElement('div');\n                        navElementsContainer.className = 'nav-elements-container';\n\n                        \/\/ Add nav elements container first to our main container\n                        requiredFieldsContainer.appendChild(navElementsContainer);\n                        \n                        \/\/ Handle submit button placement\n                        if (submitElement && submitElement.parentNode) {\n                            \/\/ Insert our container before the submit element, then move it to our nav container\n                            targetInsertionPoint.insertBefore(requiredFieldsContainer, submitElement);\n                            navElementsContainer.appendChild(submitElement);\n                        } else {\n                            \/\/ No submit button found, just append our container\n                            targetInsertionPoint.appendChild(requiredFieldsContainer);\n                        }\n                    }\n                }\n            }\n        };\n\n        \/\/ Initialize all form components\n        initializeFormSteps();\n        enhanceSelectElements();\n        customizeFileUpload();\n        addUploadedLabel();\n        setProgramFromParams();\n        monitorTitleHeight();\n        \n        \/\/ Add required fields text for forms without steps\n        const waitForFormAndAddRequiredText = () => {\n            const formContainer = document.querySelector('.fluentform');\n            if (formContainer) {\n                addRequiredFieldsTextForNonStepForms();\n            } else {\n                setTimeout(waitForFormAndAddRequiredText, 500);\n            }\n        };\n        \n        waitForFormAndAddRequiredText();\n        \n    });\n<\/script>\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"page-form.php","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-8237011","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.aese.pt\/en\/wp-json\/wp\/v2\/pages\/8237011","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.aese.pt\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.aese.pt\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.aese.pt\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.aese.pt\/en\/wp-json\/wp\/v2\/comments?post=8237011"}],"version-history":[{"count":0,"href":"https:\/\/www.aese.pt\/en\/wp-json\/wp\/v2\/pages\/8237011\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.aese.pt\/en\/wp-json\/wp\/v2\/media?parent=8237011"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}