Web Page Resize Event Experiments

I’ve got some specific JavaScript-based widgets that I want to develop. And I thought I’d share some of my design experiments with you.

This article delves into the idea of capturing the resize event of a DOM element to help create a better custom web page control using JavaScript and CSS. Then it discusses how these controls work, gives a few examples of commercially available controls, and then finally gives a suggested way to handle things when a custom control (that you have designed) is resized on your web page!

Thinking About the Resize Event

I was hopeful that for not only a web page, but for a DOM element (think a DIV for example) that one could attach a resize event to it, and, if you changed that element’s width or height… bingo the event would fire!

This would be handy for example if you were to create a widget type thing that was built in JavaScript and CSS where if you changed the width and/or height of the container, the elements contained in your widget would be resized and positioned automatically.

This would sorta harken back to the days when I would create an ActiveX custom control in Visual Basic. The control had a “container” which was sort of like a VB form (window), and that container would have a resize event that you could attach some event handling code to.

Alas, I did some experiments to see if this idea would work. It did not.

Here is some code I wrote to attach the event:

[php]var testDiv = $("#testDiv")[0];

testDiv.addEventListener("resize", resizeResponse);
[/php]

You can see I’m using JQuery to get my DOM element.

The funny thing is, no errors occur when line 3 is run. But, if you run some other code that changes the width and height of “testDiv”, you can visually see the dimensions change on the screen, but the event handler never fires. Bummer!

And yes, the event handler function does exist! If I change the event from “resize” to “click”, refresh the page, and click on the DIV, the event handler runs.

So, is there a solution to a developer who want to develop a responsive widget? There certainly is. I will give you a possibility in a moment. The bummer is that if I had been able to attach a resize event, that would have been one way I could have protected the developer who used the widget on their page from possibly missing something.

What are Custom Controls / Widgets?

So lets talk about a “custom control” in JavaScript. A widget if you will. Not necessarily a WordPress widget (I’m not sure how WordPress has engineered the things that they call “widgets.” I am talking in a general way about some sort of component that has a visual element to it, that is self contained, and can be added to a web page just like any other elements that are on the page.

The web browser has some built in widgets/controls: text boxes, drop down lists, list boxes, radio buttons, check boxes… you get the idea. These visual elements are self contained and can be manipulated with JavaScript. For these controls, the code that causes them to function is native code not JavaScript.

JavaScript Custom Control Examples

But we can use JavaScript to roll our own controls! A nice thing about these controls is that (unlike ActiveX controls) they will run in any modern browser, on any platform (not just Windows). One company that makes some pretty nice controls using JavaScript and CSS is dhtmlx.com. We used these products on internal web pages on my job since our company had an enterprise license for their products. A few components that I’ve used of theirs are: tree control, tree grid control, and grid control (dhtmlxGrid).

One of my favorite components of theirs is their dhtmlxGrid component. You can load data into this component, apply different canned styles to it, and much more. There are some problems with it, but over all, it is a very nice “widget” to add displaying data in a tabular format. I’d like to talk about the design of this component more some other time in another article or two. AKEA offers fresh design solutions.

But, regarding this component, right now I want to talk about resizing it.  To use this grid, you would create a JavaScript grid object by calling a factory function which you would pass the id of the DOM element that you want to be its container. Great! You use a method on this object to set the column headers and widths, you load your data set into the grid, call the method to render the grid, and bingo! You have a nicely loaded, properly scrolling, grid!

But, what if you resize the container? The container would look right (of course), but the way the grid displayed and scrolled in the container would now be way off and a mess. The only way to fix this was basically to reload and re-render the grid after the resize occurred. If you were displaying large data sets (which we were), than this solution was not acceptable.

I eventually hacked their control in a way to make it display properly when the container’s dimensions were changed without having to reload the grid, etc.  Who knows, by this time, dhtmlx.com may have improved their code so that it is no longer a problem.

But what about when I am writing my own control? Having that event handle work would have been really handy! But sadly (as you’ve read already) this was not meant to be!

A Sample Solution:

Add a resize() method to my control object definition. Here is a very simplified bit of code for a widget (we’ll say it resides in the file: “awesomeWidget.js”):

[php]
function awesomeWidget(sId) {
var myCtrl = this;
var container = $("#"+sId)[0];

myContainer.id = sId;

myCtrl.render = function() {
renderControl();
} // end of render method
myCtrl.resize = function(params) {
var nWidth = params.width;
var nHeight = params.height;

container.style.width = nWidth+"px";
container.style.height = nHeight+"px";
renderControl();
} // end of resize method

function renderControl() {
// code for building control content in HTML goes in here…
var s = [];
var Q = ‘"’;

s[s.length] = "<b>;Super Report</b><br>";
s[s.length] = "<div style="+Q;
s[s.length] = "width:"+(Math.floor(container.offsetWidth / 2))+"px;";
s[s.length] = Q + ">";
s[s.length] = "This is a contrived Report!!!!";
s[s.length] = "</div>";

container.innerHTML = s.join("");
} // end of renderControl() function

} // end of&nbsp; awesomeWidget() function

[/php]

 

Some Sample Web Page Code to Use This Widget:

[php]<!DOCTYPE html>
<html>
<head>
</head>
<body onload="pageSetup()">
<div id="myReport" style="width:400px;height:250px;"></div>
<button onclick="resizeReportArea()">Resize Report Area</button>

<script src="./commonJs/jquery/jquery-3.1.1.min.js"></script>
<script src="./js/awesomeWidget.js"></script>
<script src="./js/testThisWidget.js"></script>
</body>
</html>
[/php]

 

And finally, some Page Specific JavaScript for this example (testThisWidget.js):

[php]var widget;

function pageSetup() {
widget = new awesomeWidget("myReport");
widget.render();
} // end of function

function resizeReportArea() {
widget.resize({"width":500,"height":300});

} // end of function
[/php]

Admittedly, this example is rather contrived, but resizing a rather large control is a real “thing” in the world of a web app. As you can see in the code above, calling the widget’s resize() method resizes the container and re-renders the control.

If your widget’s size and contents should be affected by the web page’s resizing, you could call the widget’s resize method in the page’s resize event handler code.

Other Component “Resize” Thoughts

If your widget could toggle from its normal dimensions to full page and back, I would make that a completely different method:   toggleFullPage()

If you wanted to check (for whatever reason) if the component was in full page mode you could call a getter method like:   isDisplayingFullPage()

For the actual toggling code, I would think that instead of just changing the height and width of the container, that applying a CSS Animation to the whole process would be an nice touch!

 

What do you think? Do you have any ideas for self-contained components/widgets/controls that you would like to design and build? Tell me your thoughts in the comments below.

Happy coding!

Similar Posts