draggables.js 12.2 KB
Newer Older
1
(function (requirejs, require, define) {
2
define(['js/capa/drag_and_drop/draggable_events', 'js/capa/drag_and_drop/draggable_logic'], function (draggableEvents, draggableLogic) {
3 4 5
    return {
        'init': init
    };
6

7
    function init(state) {
8 9 10 11 12
        state.config.draggables.every(function (draggable) {
            processDraggable(state, draggable);

            return true;
        });
13
    }
14

15
    function makeDraggableCopy(callbackFunc) {
16
        var draggableObj, property;
17

18 19 20 21 22 23 24 25 26 27 28 29 30
        // Make a full proper copy of the draggable object, with some modifications.
        draggableObj = {};
        for (property in this) {
            if (this.hasOwnProperty(property) === true) {
                draggableObj[property] = this[property];
            }
        }
        // The modifications to the draggable copy.
        draggableObj.isOriginal = false; // This new draggable is a copy.
        draggableObj.uniqueId = draggableObj.state.getUniqueId(); // Is newly set.
        draggableObj.stateDraggablesIndex = null; // Will be set.
        draggableObj.containerEl = null; // Not needed, since a copy will never return to a container element.
        draggableObj.iconEl = null; // Will be created.
31
        draggableObj.iconImgEl = null; // Will be created.
32
        draggableObj.labelEl = null; // Will be created.
33
        draggableObj.targetField = []; // Will be populated.
34 35 36

        // Create DOM elements and attach events.
        if (draggableObj.originalConfigObj.icon.length > 0) {
37 38 39 40 41 42

            draggableObj.iconEl = $('<div></div>');
            draggableObj.iconImgEl = $('<img />');
            draggableObj.iconImgEl.attr('src', draggableObj.originalConfigObj.icon);
            draggableObj.iconImgEl.load(function () {

43 44 45 46 47 48 49
                draggableObj.iconEl.css({
                    'position': 'absolute',
                    'width': draggableObj.iconWidthSmall,
                    'height': draggableObj.iconHeightSmall,
                    'left': 50 - draggableObj.iconWidthSmall * 0.5,
                    'top': ((draggableObj.originalConfigObj.label.length > 0) ? 5 : 50 - draggableObj.iconHeightSmall * 0.5)
                });
50 51 52 53 54 55 56 57
                draggableObj.iconImgEl.css({
                    'position': 'absolute',
                    'width': draggableObj.iconWidthSmall,
                    'height': draggableObj.iconHeightSmall,
                    'left': 0,
                    'top': 0
                });
                draggableObj.iconImgEl.appendTo(draggableObj.iconEl);
58

59
                if (draggableObj.originalConfigObj.label.length > 0) {
60 61 62 63 64 65 66 67
                    draggableObj.labelEl = $(
                        '<div ' +
                            'style=" ' +
                                'position: absolute; ' +
                                'color: black; ' +
                                'font-size: 0.95em; ' +
                            '" ' +
                        '>' +
68
                            draggableObj.originalConfigObj.label +
69 70
                        '</div>'
                    );
71 72 73
                    draggableObj.labelEl.css({
                        'left': 50 - draggableObj.labelWidth * 0.5,
                        'top': 5 + draggableObj.iconHeightSmall + 5
74
                    });
75 76

                    draggableObj.attachMouseEventsTo('labelEl');
77
                }
78

79
                draggableObj.attachMouseEventsTo('iconEl');
80

81
                draggableObj.stateDraggablesIndex = draggableObj.state.draggables.push(draggableObj) - 1;
82 83 84 85

                setTimeout(function () {
                    callbackFunc(draggableObj);
                }, 0);
86
            });
87 88

            return;
89
        } else {
90
            if (draggableObj.originalConfigObj.label.length > 0) {
91 92 93 94 95 96 97 98
                draggableObj.iconEl = $(
                    '<div ' +
                        'style=" ' +
                            'position: absolute; ' +
                            'color: black; ' +
                            'font-size: 0.95em; ' +
                        '" ' +
                    '>' +
99
                        draggableObj.originalConfigObj.label +
100 101
                    '</div>'
                );
102 103 104 105
                draggableObj.iconEl.css({
                    'left': 50 - draggableObj.iconWidthSmall * 0.5,
                    'top': 50 - draggableObj.iconHeightSmall * 0.5
                });
106

107
                draggableObj.attachMouseEventsTo('iconEl');
108

109
                draggableObj.stateDraggablesIndex = draggableObj.state.draggables.push(draggableObj) - 1;
110

111 112 113
                setTimeout(function () {
                    callbackFunc(draggableObj);
                }, 0);
114

115
                return;
116
            }
117
        }
118
    }
119

120
    function processDraggable(state, obj) {
121
        var draggableObj;
122 123

        draggableObj = {
124
            'uniqueId': state.getUniqueId(),
125 126
            'originalConfigObj': obj,
            'stateDraggablesIndex': null,
Valera Rozuvan committed
127 128
            'id': obj.id,
            'isReusable': obj.can_reuse,
129
            'isOriginal': true,
Valera Rozuvan committed
130 131
            'x': -1,
            'y': -1,
132 133 134
            'zIndex': 1,
            'containerEl': null,
            'iconEl': null,
135
            'iconImgEl': null,
136 137 138 139 140 141 142 143
            'iconElBGColor': null,
            'iconElPadding': null,
            'iconElBorder': null,
            'iconElLeftOffset': null,
            'iconWidth': null,
            'iconHeight': null,
            'iconWidthSmall': null,
            'iconHeightSmall': null,
144
            'labelEl': null,
145
            'labelWidth': null,
146 147 148 149
            'hasLoaded': false,
            'inContainer': true,
            'mousePressed': false,
            'onTarget': null,
150
            'onTargetIndex': null,
151 152
            'state': state,

153 154 155 156 157 158 159 160 161 162 163
            'mouseDown': draggableEvents.mouseDown,
            'mouseUp': draggableEvents.mouseUp,
            'mouseMove': draggableEvents.mouseMove,

            'checkLandingElement': draggableLogic.checkLandingElement,
            'checkIfOnTarget': draggableLogic.checkIfOnTarget,
            'snapToTarget': draggableLogic.snapToTarget,
            'correctZIndexes': draggableLogic.correctZIndexes,
            'moveBackToSlider': draggableLogic.moveBackToSlider,
            'moveDraggableTo': draggableLogic.moveDraggableTo,

164
            'makeDraggableCopy': makeDraggableCopy,
165 166 167 168 169

            'attachMouseEventsTo': draggableEvents.attachMouseEventsTo,

            'targetField': [],
            'numDraggablesOnMe': 0
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
        };

        draggableObj.containerEl = $(
            '<div ' +
                'style=" ' +
                    'width: 100px; ' +
                    'height: 100px; ' +
                    'display: inline; ' +
                    'float: left; ' +
                    'overflow: hidden; ' +
                    'border-left: 1px solid #CCC; ' +
                    'border-right: 1px solid #CCC; ' +
                    'text-align: center; ' +
                    'position: relative; ' +
                '" ' +
                '></div>'
        );

        draggableObj.containerEl.appendTo(state.sliderEl);

        if (obj.icon.length > 0) {
            draggableObj.iconElBGColor = 'transparent';
            draggableObj.iconElPadding = 0;
            draggableObj.iconElBorder = 'none';
            draggableObj.iconElLeftOffset = 0;

196 197 198 199 200
            draggableObj.iconEl = $('<div></div>');

            draggableObj.iconImgEl = $('<img />');
            draggableObj.iconImgEl.attr('src', obj.icon);
            draggableObj.iconImgEl.load(function () {
201 202 203 204 205
                draggableObj.iconWidth = this.width;
                draggableObj.iconHeight = this.height;

                if (draggableObj.iconWidth >= draggableObj.iconHeight) {
                    draggableObj.iconWidthSmall = 60;
206
                    draggableObj.iconHeightSmall = draggableObj.iconWidthSmall * (draggableObj.iconHeight / draggableObj.iconWidth);
207 208
                } else {
                    draggableObj.iconHeightSmall = 60;
209
                    draggableObj.iconWidthSmall = draggableObj.iconHeightSmall * (draggableObj.iconWidth / draggableObj.iconHeight);
210
                }
211

212 213 214 215 216
                draggableObj.iconEl.css({
                    'position': 'absolute',
                    'width': draggableObj.iconWidthSmall,
                    'height': draggableObj.iconHeightSmall,
                    'left': 50 - draggableObj.iconWidthSmall * 0.5,
217 218 219 220 221

                    // Before:
                    // 'top': ((obj.label.length > 0) ? (100 - draggableObj.iconHeightSmall - 25) * 0.5 : 50 - draggableObj.iconHeightSmall * 0.5)
                    // After:
                    'top': ((obj.label.length > 0) ? 37.5 : 50.0) - 0.5 * draggableObj.iconHeightSmall
222
                });
223 224 225 226 227 228 229 230
                draggableObj.iconImgEl.css({
                    'position': 'absolute',
                    'width': draggableObj.iconWidthSmall,
                    'height': draggableObj.iconHeightSmall,
                    'left': 0,
                    'top': 0
                });
                draggableObj.iconImgEl.appendTo(draggableObj.iconEl);
231
                draggableObj.iconEl.appendTo(draggableObj.containerEl);
232 233

                if (obj.label.length > 0) {
234
                    draggableObj.labelEl = $(
235 236 237
                        '<div ' +
                            'style=" ' +
                                'position: absolute; ' +
Valera Rozuvan committed
238 239
                                'color: black; ' +
                                'font-size: 0.95em; ' +
240 241 242 243 244 245
                            '" ' +
                        '>' +
                            obj.label +
                        '</div>'
                    );

246
                    draggableObj.labelEl.appendTo(draggableObj.containerEl);
247
                    draggableObj.labelWidth = draggableObj.labelEl.width();
248 249
                    draggableObj.labelEl.css({
                        'left': 50 - draggableObj.labelWidth * 0.5,
250 251 252 253 254

                        // Before:
                        // 'top': (100 - this.iconHeightSmall - 25) * 0.5 + this.iconHeightSmall + 5
                        // After:
                        'top': 42.5 + 0.5 * draggableObj.iconHeightSmall
255
                    });
256 257

                    draggableObj.attachMouseEventsTo('labelEl');
258
                }
259 260

                draggableObj.hasLoaded = true;
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
            });
        } else {
            // To make life easier, if there is no icon, but there is a
            // label, we will create a label and store it as if it was an
            // icon. All the existing code will work, and the user will
            // see a label instead of an icon.
            if (obj.label.length > 0) {
                draggableObj.iconElBGColor = state.config.labelBgColor;
                draggableObj.iconElPadding = 8;
                draggableObj.iconElBorder = '1px solid black';
                draggableObj.iconElLeftOffset = 9;

                draggableObj.iconEl = $(
                    '<div ' +
                        'style=" ' +
                            'position: absolute; ' +
                            'color: black; ' +
                            'font-size: 0.95em; ' +
                        '" ' +
                    '>' +
                        obj.label +
                    '</div>'
                );
284

285
                draggableObj.iconEl.appendTo(draggableObj.containerEl);
286

287 288 289 290
                draggableObj.iconWidth = draggableObj.iconEl.width();
                draggableObj.iconHeight = draggableObj.iconEl.height();
                draggableObj.iconWidthSmall = draggableObj.iconWidth;
                draggableObj.iconHeightSmall = draggableObj.iconHeight;
291

292 293 294 295
                draggableObj.iconEl.css({
                    'left': 50 - draggableObj.iconWidthSmall * 0.5,
                    'top': 50 - draggableObj.iconHeightSmall * 0.5
                });
Valera Rozuvan committed
296 297

                draggableObj.hasLoaded = true;
298 299 300 301 302
            } else {
                // If no icon and no label, don't create a draggable.
                return;
            }
        }
303

304 305
        draggableObj.attachMouseEventsTo('iconEl');
        draggableObj.attachMouseEventsTo('containerEl');
306

307
        state.numDraggablesInSlider += 1;
308
        draggableObj.stateDraggablesIndex = state.draggables.push(draggableObj) - 1;
309
    }
310
}); // End-of: define(['draggable_events', 'draggable_logic'], function (draggableEvents, draggableLogic) {
311
}(RequireJS.requirejs, RequireJS.require, RequireJS.define)); // End-of: (function (requirejs, require, define) {