I am very familiar with JavaScript and OOP, but I am very uninterested in developing JS classes that are used for programming UI (HTML). I searched a bit, but did not come across any common patterns.
Suppose I wanted to dynamically create panel objects (similar to Microsoft Windows panels). Each object needs a container, a header area that can include a text label, and a close button that has a click event handler. In addition to the DOM (HTML) representation, the object will also have a JavaScript object representation (variables and methods). Here is one of the ways I tried:
// // Window class // var Window = function(params) { this.testMethod = function() { console.log('test'); // just an example } this.windowDiv = document.createElement('div'); this.windowDiv.style.width = params.width + 'px'; this.windowDiv.style.height = params.height + 'px'; this.windowDiv.style.position = 'absolute'; this.windowDiv.style.top = '30px'; this.windowDiv.style.left = '30px'; this.windowDiv.style.border = '1px solid #000'; this.headerDiv = document.createElement('div'); this.headerDiv.style.width = '100%'; this.headerDiv.style.height = '30px'; this.headerDiv.style.background = '#bbb'; this.headerDiv.style.borderBottom = '1px solid #000'; this.headerDiv.innerHTML = params.title; this.buttonDiv = document.createElement('div'); this.buttonDiv.style.width = '30px'; this.buttonDiv.style.height = '18px'; this.buttonDiv.style.position = 'absolute'; this.buttonDiv.style.top = '0px'; this.buttonDiv.style.right = '5px'; this.buttonDiv.style.textAlign = 'center'; this.buttonDiv.style.background = 'red'; this.buttonDiv.style.border = '0px 1px 1px 1px solid #000'; this.buttonDiv.innerHTML = 'x'; this.buttonDiv.addEventListener('click', function(e) { document.body.removeChild(e.target.parentNode.parentNode); }, false); this.headerDiv.appendChild(this.buttonDiv); this.windowDiv.appendChild(this.headerDiv); document.body.appendChild(this.windowDiv); } // Initialize var myWindow = new Window({ width: 400, height: 200, title: 'My Window' }); myWindow.testMethod();
This does not seem "right." Another approach might be to have a render () method and use it to highlight the HTML generation code. It seems uncomfortable that the JS object contains several nested HTML objects inside it. Should I just enter nested tags through innerHTML?
So I'm curious ... what's the best approach here? What is the best way to develop classes with DOM code (HTML objects and style) and traditional variables and methods? Is there a way to use Prototypes for these HTML objects? In this example, you can even imagine that there is also a WindowManager class that contains Window instance objects, helps manage them, and creates new ones. And that too may have HTML representation.
Some of the above can be processed with static CSS and use identifiers / classes to clear some of the code, but let me say that positioning and size must be done programmatically (to handle resizing, dragging, etc.).
I'm not interested in the framework-level solutions that ExtJS, jQuery, etc. can provide. I want to know what works best for home code. In fact, I would be interested to know how the engineers of these frameworks develop their user interface classes.