You can have your forms and tables on a html page and dynamically load your components.
In the example below the components are on a component.html page, I’m fetching the components using two javascript modules
the ComponentLoader return a Promise so you can have a .then(…) if you need to dynamically add javascript or css
classes/classes.mjs
export class ComponentLoader {
constructor(clearCache = false) {
this.componentCache = '';
this.clearCache = clearCache;
}
static clearCache() {
ComponentLoader.componentCache = '';
}
static async fetchContent(baseUrl) {
if (ComponentLoader.componentCache === '') {
try {
const response = await fetch(baseUrl);
return (ComponentLoader.componentCache = await response.text());
} catch (error) {
throw new Error(`Error fetching content: ${error.message}`);
}
}
return ComponentLoader.componentCache;
}
static async injectComponent(selector, target, baseUrl, clearCache) {
try {
if (clearCache) {
this.clearCache();
}
const content = await this.fetchContent(baseUrl);
const targetNode = document.querySelector(target);
if (targetNode) {
const parser = new DOMParser();
const parsedDocument = parser.parseFromString(content, 'text/html');
const clonedNode = parsedDocument
.querySelector(selector)
.cloneNode(true);
targetNode.parentNode.replaceChild(clonedNode, targetNode);
console.log('Component injected successfully.');
} else {
throw new Error(`Target node with selector "${selector}" not found.`);
}
} catch (error) {
console.error('Error injecting component:', error);
throw error;
}
}
static loadComponentWithSelector(selector, target, baseUrl, clearCache) {
return new Promise(async (resolve, reject) => {
try {
if (clearCache) {
this.clearCache();
}
await this.injectComponent(selector, target, baseUrl, clearCache);
resolve();
} catch (error) {
reject(error);
}
});
}
}
How to use it
app.mjs
import {
ComponentLoader,
ParallaxBackground,
} from './classes/classes.mjs';
ComponentLoader.loadComponentWithSelector(
'[data-hero]',
'[data-hero]',
'component.html',
true
)
.then(() => {
new ParallaxBackground();
console.log('Component loaded successfully.');
})
.catch((error) => {
console.error('Error:', error);
});
const formSelector = document.getElementById('formselector');
formSelector.addEventListener('change', () => {
if (formSelector.value === '1') {
ComponentLoader.loadComponentWithSelector(
'[data-contactus]',
'[data-form]',
'component.html',
false
)
.then(() => {
// here you can add css or javascript if needed
console.log('Component loaded successfully.');
})
.catch((error) => {
console.error('Error:', error);
});
}
if (formSelector.value === '2') {
ComponentLoader.loadComponentWithSelector(
'[data-table]',
'[data-form]',
'component.html',
false
)
.then(() => {
// here you can add css or javascript if needed
console.log('Component loaded successfully.');
})
.catch((error) => {
console.error('Error:', error);
});
}
if (formSelector.value === '3') {
ComponentLoader.loadComponentWithSelector(
'[data-record2]',
'[data-form]',
'component.html',
false
)
.then(() => {
// here you can add css or javascript if needed
console.log('Component loaded successfully.');
})
.catch((error) => {
console.error('Error:', error);
});
}
if (formSelector.value === '4') {
ComponentLoader.loadComponentWithSelector(
'[data-record3]',
'[data-form]',
'component.html',
false
)
.then(() => {
// here you can add css or javascript if needed
console.log('Component loaded successfully.');
})
.catch((error) => {
console.error('Error:', error);
});
}
});
Here is an example of the ComponentLoader
have a look