By filling out this form, your request will be shared directly with our experts. We will reply as soon as possible.
(function () {
const SPARE_PARTS_TEXT = ‘spareparts’;
function log(){ try{ console.debug(‘[AC-IMO]’, …arguments); }catch(e){} }
function textContainsIMO(txt){return (txt||”).toLowerCase().includes(‘imo’);}
function isSparePartsSelected(selectEl){
const val = String(selectEl.value||selectEl.options[selectEl.selectedIndex]?.text||”)
.trim().toLowerCase();
return val === SPARE_PARTS_TEXT;
}
function nearestRow(el){
return el.closest(‘.form-row, ._form_element, .ac-field, .field, .row, ._field-wrapper, .form-group’) || el.parentElement;
}
function findLinkedLabel(form, input){
const id = input.id && input.id.trim();
if (id) {
const lab = form.querySelector(`label[for=”${CSS.escape(id)}”]`);
if (lab) return lab;
}
const wrap = input.closest(‘label’); if (wrap) return wrap;
const row = nearestRow(input); if (row){ const inRow = row.querySelector(‘label’); if (inRow) return inRow; }
return null;
}
function findHeadingNear(input){
const row = nearestRow(input);
if (!row) return null;
return row.querySelector(‘legend, .label, .control-label, ._form-label, .field > .label’) ||
(row.previousElementSibling && /label|legend|title|heading/i.test(row.previousElementSibling.className||”) ? row.previousElementSibling : null);
}
function ensureError(el,msg){
const r=nearestRow(el); if(!r) return;
let e=r.querySelector(‘.imo-error’);
if(!e){ e=document.createElement(‘div’); e.className=’imo-error’; e.style.fontSize=’0.9rem’; e.style.marginTop=’0.25rem’; e.style.color=’#d00′; r.appendChild(e); }
e.textContent=msg;
}
function clearError(el){
const r=nearestRow(el); const e=r&&r.querySelector(‘.imo-error’); if(e) e.remove();
}
function parseIMODigits(raw){const m=String(raw||”).trim().match(/^(?:IMO\s*)?(\d{7})$/i); return m?m[1]:null;}
function validIMONumber(d){if(!d) return false; const a=d.split(”).map(Number); if(a.length!==7||a.some(n=>Number.isNaN(n))) return false; const w=[7,6,5,4,3,2,1]; const s=a.reduce((x,n,i)=>x+n*w[i],0); return s%10===0;}
function findSubjectSelect(root){
const form = root.form || root; // accepter input eller form
const custom=form.getAttribute && form.getAttribute(‘data-ac-subject’); if(custom) return form.querySelector(custom);
for(const sel of form.querySelectorAll(‘select’)){
const has=[…sel.options].some(opt => String(opt.text||opt.value).trim().toLowerCase()===SPARE_PARTS_TEXT);
if(has) return sel;
}
return null;
}
function findIMOInput(form){
const custom=form.getAttribute(‘data-ac-imo’); if(custom) return form.querySelector(custom);
const cand=[…form.querySelectorAll(‘input[type=”text”], input[type=”tel”], input[type=”number”]’)];
for(const el of cand){
const ph=el.getAttribute(‘placeholder’)||”; if(textContainsIMO(ph)) return el;
const id=el.id&&el.id.trim(); const lab=id?form.querySelector(`label[for=”${CSS.escape(id)}”]`):null; if(lab&&textContainsIMO(lab.textContent)) return el;
const wrap=el.closest(‘label’); if(wrap&&textContainsIMO(wrap.textContent)) return el;
const row=nearestRow(el); const inRow=row&&row.querySelector(‘label’); if(inRow&&textContainsIMO(inRow.textContent)) return el;
}
return null;
}
function setBlockVisibility(form, input, visible){
const rowSel = form.getAttribute(‘data-ac-imo-row’);
const row = rowSel ? form.querySelector(rowSel) : nearestRow(input);
const label = findLinkedLabel(form, input);
const heading = findHeadingNear(input);
const display = visible ? ” : ‘none’;
if (row) row.style.display = display;
if (label && !row?.contains(label)) label.style.display = display;
if (heading && !row?.contains(heading)) heading.style.display = display;
if (!visible) clearError(input);
}
function updateIMOVisibility(form, subjectEl, imoEl){
const show = isSparePartsSelected(subjectEl);
setBlockVisibility(form, imoEl, show);
if (show){
imoEl.setAttribute(‘required’,’required’);
imoEl.setAttribute(‘inputmode’,’numeric’);
imoEl.setAttribute(‘pattern’,'(?:IMO\\s*)?\\d{7}’);
if(!imoEl.placeholder) imoEl.placeholder=’IMO 1234567′;
} else {
imoEl.removeAttribute(‘required’);
imoEl.removeAttribute(‘pattern’);
}
}
function attachToForm(form){
const isAC=form.classList.contains(‘_form’) || /activehosted\.com|activecampaign/i.test(form.getAttribute(‘action’)||”);
if(!isAC) return;
const subjectEl=findSubjectSelect(form);
const imoEl=findIMOInput(form);
if(!subjectEl||!imoEl){ log(‘Form fundet men mangler subject/IMO’, form); return; }
updateIMOVisibility(form, subjectEl, imoEl);
subjectEl.addEventListener(‘change’,()=>updateIMOVisibility(form, subjectEl, imoEl));
imoEl.addEventListener(‘input’,()=>clearError(imoEl));
form.addEventListener(‘submit’,function(e){
if(!isSparePartsSelected(subjectEl)) return;
const digits=parseIMODigits(imoEl.value);
if(!validIMONumber(digits)){ e.preventDefault(); ensureError(imoEl,’Angiv et gyldigt IMO-nummer på 7 cifre (fx “IMO 1234567”).’); imoEl.focus(); }
else { clearError(imoEl); }
});
}
function scanDoc(doc){
doc.querySelectorAll(‘form’).forEach(attachToForm);
}
function tryScanIframes(){
document.querySelectorAll(‘iframe’).forEach(ifr=>{
try{
const doc = ifr.contentDocument;
if (doc && doc.domain === document.domain) scanDoc(doc); // kun samme origin
}catch(e){ /* cross-origin: ignorer */ }
});
}
function scanAll(){ scanDoc(document); tryScanIframes(); }
if(document.readyState===’loading’){ document.addEventListener(‘DOMContentLoaded’,scanAll); } else { scanAll(); }
window.addEventListener(‘load’, scanAll);
const mo=new MutationObserver(()=>scanAll());
mo.observe(document.documentElement,{childList:true,subtree:true});
})();
Work with us!
Send us your application
Even when there are no open positions, we are often searching to expand our team, and take on new colleagues. Send us your CV through the form above, and one of our team will contact you if there is a possible position matching your expertise.
Please remember to explain the purpose of your letter and identify your skills. You can also email for extra information at: jobBREAKER!@BREAKER!g-o.dk