ExtJs 4 – click/drag to select/highlight
ExtJs4 has significant improvements over its class system, which is somewhat similar to a JavaScript framework named “Joose” that I used to make my JavaScript code more OO, they are both based on meta programming, both supports things like “singleton”, “traits”, “mixin” …
Just a quick experiment to create something that I might involve doing for a project.
The following bits of markup and code allows the user to click then drag over a set of boxes within an area, at the end of the drag, you are alerted which elements have been highlighted.
The Demo – See it in action!
Just click and drag from anywhere outside the the 10 smaller boxes and move mouse to highlight the boxes.
Get the code from http://jsfiddle.net/LFgzx/92/
The markup
<style> .element { width:20px; height:20px; border:1px solid #ccc; position:absolute; } .element-highlight { background-color:red; } #canvas { width:100px; height:200px; border:1px solid #ccc; position:relative; } #hightlightbox { border:1px dotted #ccc; position:absolute; left:0px; right:0px;display:none; } </style> <div id="canvas"> <div class="element" style="top:20px;left:20px;" id="e1"></div> <div class="element" style="top:40px;left:20px;" id="e2"></div> <div class="element" style="top:60px;left:20px;" id="e3"></div> <div class="element" style="top:80px;left:20px;" id="e4"></div> <div class="element" style="top:100px;left:20px;" id="e5"></div> </div> <div id="hightlightbox"></div>
Few things: elements are placed inside the canvas using relative/absolute positioning. div.hightlightbox is the dotted box that appear when you drag, it’s only shown when dragging.
The JavaScript
Ext.define('My.DragHighLight', { extend: 'Ext.util.Observable', constructor: function(){ this.addEvents({ "highlighted" : true }); // Call our superclass constructor to complete construction process. this.callParent(arguments); this.init(); }, init: function() { this.locationCache = []; this.canvasRegion = this.getLocation(Ext.get('canvas').dom); Ext.dd.DragDropManager.mode = 0; var canvasElements = Ext.select('div.element'); Ext.each(canvasElements.elements, function(el) { new Ext.dd.DragDrop(el); }); var THIS = this; //Ext.get('canvas').on('click', function() { // Ext.select('div.element').removeCls('element-highlight'); //}); dd = new Ext.dd.DragDrop("canvas"); dd.startDrag = function(x,y) { //activate the highlight box Ext.get('hightlightbox').setStyle('display','block'); } dd.onDrag = function(e) { var startX = Ext.dd.DragDropManager.startX, startY = Ext.dd.DragDropManager.startY, curX = e.getPageX(), curY = e.getPageY(); var topLeftXY, bottomRightXY; //4 possible directions //right if (startX < curX) { //up if (curY < startY) { topLeftXY = [startX, curY]; bottomRightXY = [curX, startY]; //down } else { topLeftXY = [startX , startY]; bottomRightXY = [curX, curY]; } //left } else { //up if (curY < startY) { topLeftXY = [curX, curY]; bottomRightXY = [startX, startY]; //down } else { topLeftXY = [curX, startY]; bottomRightXY = [startX, curY]; } } //avoid dragging outside the canvas if(topLeftXY[0] < THIS.canvasRegion.left) { topLeftXY[0] = THIS.canvasRegion.left; } if(topLeftXY[1] < THIS.canvasRegion.top) { topLeftXY[1] = THIS.canvasRegion.top; } if(bottomRightXY[0] > THIS.canvasRegion.right) { bottomRightXY[0] = THIS.canvasRegion.right; } if(bottomRightXY[1] > THIS.canvasRegion.bottom) { bottomRightXY[1] = THIS.canvasRegion.bottom; } var w = Math.abs(topLeftXY[0]- bottomRightXY[0]), h = Math.abs(topLeftXY[1]- bottomRightXY[1]); //create the highlight box var box = Ext.get('hightlightbox'); box.setXY(topLeftXY); box.setSize(w, h); var canvasElements = Ext.select('div.element'); Ext.each(canvasElements .elements, function(el) { //check for overlap if (THIS.isOverTarget(box, el)) { Ext.get(el).addCls('element-highlight'); } else { Ext.get(el).removeCls('element-highlight'); } }); return this; } dd.endDrag = function(x,y) { //deactivate the highlight box Ext.get('hightlightbox').setStyle('display','none'); var selectedEl = []; Ext.each(Ext.select('div.element').elements, function(el) { if (Ext.get(el).hasCls('element-highlight')) { selectedEl.push(el.id); } }); THIS.fireEvent('highlighted', selectedEl); } }, getLocation: function(oDD) { var el = oDD, pos, x1, x2, y1, y2, t, r, b, l; try { pos= Ext.core.Element.getXY(el); } catch (e) { } if (!pos) { return null; } x1 = pos[0]; x2 = x1 + Ext.fly(el).getWidth(true); y1 = pos[1]; y2 = y1 + Ext.fly(el).getHeight(true); t = y1; r = x2; b = y2; l = x1; return Ext.create('Ext.util.Region', t, r, b, l); }, isOverTarget: function(dragEl, targetEl) { // use cache if available var loc = this.locationCache[targetEl.id]; if (!loc || !this.useCache) { loc = this.getLocation(targetEl); this.locationCache[targetEl.id] = loc; } if (!loc) { return false; } var pos = {x: dragEl.getX(), y: dragEl.getY()}; var curRegion = Ext.create('Ext.util.Region', pos.y, pos.x + dragEl.getWidth(), pos.y + dragEl.getHeight(), pos.x ); var overlap = curRegion.intersect(loc); if (overlap) { return true; } else { return false; } } }); var h = new My.DragHighLight(); h.on('highlighted', function(els) { //console.log(els); })
Feel free to modify and extend to your needs …


