diff --git a/application/source/dom/util/init-options-from-attributes.mjs b/application/source/dom/util/init-options-from-attributes.mjs
new file mode 100644
index 0000000000000000000000000000000000000000..1c7e43813ec52a7448484d8bd0cf2dee2eaa7391
--- /dev/null
+++ b/application/source/dom/util/init-options-from-attributes.mjs
@@ -0,0 +1,78 @@
+/**
+ * Copyright schukai GmbH and contributors 2023. All Rights Reserved.
+ * Node module: @schukai/monster
+ * This file is licensed under the AGPLv3 License.
+ * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
+ */
+
+import {Pathfinder} from '../../data/pathfinder.mjs';
+import {isFunction} from '../../types/is.mjs';
+
+export {initOptionsFromAttributes };
+
+/**
+ * Initializes the given options object based on the attributes of the current DOM element.
+ * The function looks for attributes with the prefix 'data-monster-option-', and maps them to
+ * properties in the options object. It replaces the dashes with dots to form the property path.
+ * For example, the attribute 'data-monster-option-url' maps to the 'url' property in the options object.
+ * 
+ * With the mapping parameter, the attribute value can be mapped to a different value.
+ * For example, the attribute 'data-monster-option-foo' maps to the 'bar' property in the options object.
+ * 
+ * The mapping object would look like this:
+ * {
+ *    'foo': (value) => value + 'bar'
+ *    // the value of the attribute 'data-monster-option-foo' is appended with 'bar'
+ *    // and assigned to the 'bar' property in the options object.
+ *    // e.g. <div data-monster-option-foo="foo"></div>
+ *    'bar.baz': (value) => value + 'bar'
+ *    // the value of the attribute 'data-monster-option-bar-baz' is appended with 'bar'
+ *    // and assigned to the 'bar.baz' property in the options object.  
+ *    // e.g. <div data-monster-option-bar-baz="foo"></div>
+ * }
+ *
+ * @param {HTMLElement} element - The DOM element to be used as the source of the attributes.
+ * @param {Object} options - The options object to be initialized.
+ * @param {Object} mapping - A mapping between the attribute value and the property value.
+ * @param {string} prefix - The prefix of the attributes to be considered.
+ * @returns {Object} - The initialized options object.
+ * @this HTMLElement - The context of the DOM element.
+ */
+function initOptionsFromAttributes(element, options, mapping={},prefix = 'data-monster-option-') {
+    if (!(element instanceof HTMLElement)) return options;
+    if (!element.hasAttributes()) return options;
+
+    const finder = new Pathfinder(options);
+
+    element.getAttributeNames().forEach((name) => {
+        if (!name.startsWith(prefix)) return;
+
+        // check if the attribute name is a valid option. 
+        // the mapping between the attribute is simple. The dash is replaced by a dot.
+        // e.g. data-monster-url => url
+        const optionName = name.replace(prefix, '').replace(/-/g, '.');
+        if (!finder.exists(optionName)) return;
+
+        if (element.hasAttribute(name)) {
+            let value = element.getAttribute(name);
+            if (mapping.hasOwnProperty(optionName)&&isFunction(mapping[optionName])) {
+                value = mapping[optionName](value);
+            }
+            
+            const typeOfOptionValue = typeof finder.getVia(optionName);
+            if (typeOfOptionValue === 'boolean') {
+                value = value === 'true';
+            } else if (typeOfOptionValue === 'number') {
+                value = Number(value);
+            } else if (typeOfOptionValue === 'string') {
+                value = String(value);
+            } else if (typeOfOptionValue === 'object') {
+                value = JSON.parse(value);
+            }
+            
+            finder.setVia(optionName, value);
+        }
+    })
+
+    return options;
+}
\ No newline at end of file
diff --git a/development/pnpm-lock.yaml b/development/pnpm-lock.yaml
index de9815ee8909981f2e5332626d9f1d63913440e0..6d9d1a74f9b499ec728db0a342ad2ec11ff56b5e 100644
--- a/development/pnpm-lock.yaml
+++ b/development/pnpm-lock.yaml
@@ -1611,7 +1611,7 @@ packages:
       execa: 4.1.0
       polyfill-library: 3.111.0
       semver: 7.3.8
-      snyk: 1.1133.0
+      snyk: 1.1134.0
       yargs: 15.4.1
     transitivePeerDependencies:
       - supports-color
@@ -4091,8 +4091,8 @@ packages:
       supports-color: 7.2.0
     dev: true
 
-  /snyk@1.1133.0:
-    resolution: {integrity: sha512-op/OCcfZZcR1nZDwKS4sVYB51Dqc327/t47a0nyzVTtB8qVQJyujnIcsWaOeY4uEoaJnUNxp1Mp5kgN6jhwJFA==}
+  /snyk@1.1134.0:
+    resolution: {integrity: sha512-gy+Aas1F10AEkAH40f8ewPavFCVjUW/izTv1RJNRwuOt52wqFgb4mkW3F0U6xq4HCNiEzmWCkz8BN21uzdMPUA==}
     engines: {node: '>=12'}
     hasBin: true
     requiresBuild: true
diff --git a/development/test/cases/dom/events.mjs b/development/test/cases/dom/events.mjs
index 9abf85cd72f866f25418846ce638d582a1bdf77e..e255fd5178a4400577f20ffe256cfe3ce3be0fc4 100644
--- a/development/test/cases/dom/events.mjs
+++ b/development/test/cases/dom/events.mjs
@@ -8,7 +8,7 @@ import {initJSDOM} from "../../util/jsdom.mjs";
 describe('Events', function () {
 
     before(async function () {
-        initJSDOM();
+        await initJSDOM();
     })
 
     describe('findTargetElementFromEvent()', function () {
@@ -23,10 +23,10 @@ describe('Events', function () {
                 expect(e.getAttribute('data-monster')).to.be.equal('hello')
                 done();
             })
-            setTimeout(()=>{
+            setTimeout(() => {
                 fireEvent(div, 'click');
-            },0)
-            
+            }, 0)
+
         });
 
     });
@@ -76,10 +76,10 @@ describe('Events', function () {
 
         it('should throw error', function () {
             expect(() => fireEvent({}, 'touch')).to.throw(Error);
-            
+
         });
-    });   
-    
+    });
+
     describe('fireCustomEvent()', function () {
         it('should fire a click event', function (done) {
             let div = document.createElement('div');
@@ -100,8 +100,8 @@ describe('Events', function () {
         it('should fire a touch event on collection1', function (done) {
             let div = document.createElement('div');
             div.addEventListener('touch', (e) => {
-                if(e.detail.detail!=='hello world') {
-                    done('error');    
+                if (e.detail.detail !== 'hello world') {
+                    done('error');
                 }
                 done();
             })
@@ -111,12 +111,12 @@ describe('Events', function () {
 
             fireCustomEvent(collection, 'touch', "hello world");
         });
-        
+
         it('should fire a touch event on collection2', function (done) {
             let div = document.createElement('div');
             div.addEventListener('touch', (e) => {
-                if(e.detail.a!=='hello world') {
-                    done('error');    
+                if (e.detail.a !== 'hello world') {
+                    done('error');
                 }
                 done();
             })
@@ -124,7 +124,7 @@ describe('Events', function () {
             div.appendChild(document.createElement('div'));
             let collection = div.querySelectorAll('div');
 
-            fireCustomEvent(collection, 'touch', {a:"hello world"});
+            fireCustomEvent(collection, 'touch', {a: "hello world"});
         });
 
         it('should fire a touch event', function (done) {
diff --git a/development/test/cases/dom/util/init-options-from-attributes.mjs b/development/test/cases/dom/util/init-options-from-attributes.mjs
new file mode 100644
index 0000000000000000000000000000000000000000..2e030d9dc8c6e67247a1f9ab3335314712af9cd9
--- /dev/null
+++ b/development/test/cases/dom/util/init-options-from-attributes.mjs
@@ -0,0 +1,155 @@
+import {expect} from "chai"
+
+import {initOptionsFromAttributes} from "../../../../..//application/source/dom/util/init-options-from-attributes.mjs";
+import {initJSDOM} from "../../../util/jsdom.mjs";
+
+describe('initOptionsFromAttributes', () => {
+    let element;
+    let options;
+
+    before(async function () {
+        await initJSDOM();
+    })    
+
+    beforeEach(() => {
+        options = { url: "", key: { subkey: "" } };
+        element = document.createElement('div');
+    });
+
+    it('should initialize options with matching attributes', () => {
+        element.setAttribute('data-monster-option-url', 'https://example.com');
+        element.setAttribute('data-monster-option-key.subkey', 'test');
+
+        const result = initOptionsFromAttributes(element, options);
+
+        expect(result.url).to.equal('https://example.com');
+        expect(result.key.subkey).to.equal('test');
+    });
+
+    it('should not modify options without matching attributes', () => {
+        const result = initOptionsFromAttributes(element, options);
+
+        expect(result.url).to.equal('');
+        expect(result.key.subkey).to.equal('');
+    });
+
+    it('should ignore attributes without the correct prefix', () => {
+        element.setAttribute('data-some-option-url', 'https://example.com');
+
+        const result = initOptionsFromAttributes(element, options);
+
+        expect(result.url).to.equal('');
+    });
+
+    it('should ignore attributes with invalid option paths', () => {
+        element.setAttribute('data-monster-option-nonexistent', 'value');
+
+        const result = initOptionsFromAttributes(element, options);
+
+        expect(result).to.deep.equal(options);
+    });
+
+    it('should apply mapping for a single attribute', () => {
+        element.setAttribute('data-monster-option-url', 'example');
+        const mapping = {
+            'url': (value) => 'https://' + value + '.com'
+        };
+
+        const result = initOptionsFromAttributes(element, options, mapping);
+
+        expect(result.url).to.equal('https://example.com');
+    });
+
+    it('should apply mapping for a nested attribute', () => {
+        element.setAttribute('data-monster-option-key-subkey', '123');
+        const mapping = {
+            'key.subkey': (value) => parseInt(value, 10) * 2
+        };
+
+        const result = initOptionsFromAttributes(element, options, mapping);
+
+        expect(result.key.subkey).to.equal("246");
+    });
+
+    it('should apply multiple mappings', () => {
+        element.setAttribute('data-monster-option-url', 'example');
+        element.setAttribute('data-monster-option-key.subkey', '123');
+        const mapping = {
+            'url': (value) => 'https://' + value + '.com',
+            'key.subkey': (value) => parseInt(value, 10) * 2
+        };
+
+        const result = initOptionsFromAttributes(element, options, mapping);
+
+        expect(result.url).to.equal('https://example.com');
+        expect(result.key.subkey).to.equal("246");
+    });
+
+    it('should ignore mappings for non-existing attributes', () => {
+        const mapping = {
+            'url': (value) => 'https://' + value + '.com'
+        };
+
+        const result = initOptionsFromAttributes(element, options, mapping);
+
+        expect(result.url).to.equal('');
+    });
+
+    it('should ignore mappings for invalid option paths', () => {
+        element.setAttribute('data-monster-option-nonexistent', 'value');
+        const mapping = {
+            'nonexistent': (value) => value + 'bar'
+        };
+
+        const result = initOptionsFromAttributes(element, options, mapping);
+
+        expect(result).to.deep.equal(options);
+    });
+
+    it('should apply mapping only to specified attributes', () => {
+        element.setAttribute('data-monster-option-url', 'example');
+        element.setAttribute('data-monster-option-key.subkey', '123');
+        const mapping = {
+            'url': (value) => 'https://' + value + '.com'
+        };
+
+        const result = initOptionsFromAttributes(element, options, mapping);
+
+        expect(result.url).to.equal('https://example.com');
+        expect(result.key.subkey).to.equal('123');
+    });
+
+    it('should not apply mapping if not a function', () => {
+        element.setAttribute('data-monster-option-url', 'example');
+        const mapping = {
+            'url': 'https://example.com'
+        };
+
+        const result = initOptionsFromAttributes(element, options, mapping);
+
+        expect(result.url).to.equal('example');
+    });
+
+    it('should apply mapping with custom prefix', () => {
+        element.setAttribute('data-custom-option-url', 'example');
+        const mapping = {
+            'url': (value) => 'https://' + value + '.com'
+        };
+
+        const result = initOptionsFromAttributes(element, options, mapping, 'data-custom-option-');
+
+        expect(result.url).to.equal('https://example.com');
+    });
+
+    it('should not apply mapping with incorrect custom prefix', () => {
+        element.setAttribute('data-custom-option-url', 'example');
+        const mapping = {
+            'url': (value) => 'https://' + value + '.com'
+        };
+
+        const result = initOptionsFromAttributes(element, options, mapping);
+
+        expect(result.url).to.equal('');
+    });    
+    
+});