kendo.listview.js 27.6 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 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 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539
/** 
 * Kendo UI v2016.1.112 (http://www.telerik.com/kendo-ui)                                                                                                                                               
 * Copyright 2016 Telerik AD. All rights reserved.                                                                                                                                                      
 *                                                                                                                                                                                                      
 * Kendo UI commercial licenses may be obtained at                                                                                                                                                      
 * http://www.telerik.com/purchase/license-agreement/kendo-ui-complete                                                                                                                                  
 * If you do not own a commercial license, this file shall be governed by the trial license terms.                                                                                                      
                                                                                                                                                                                                       
                                                                                                                                                                                                       
                                                                                                                                                                                                       
                                                                                                                                                                                                       
                                                                                                                                                                                                       
                                                                                                                                                                                                       
                                                                                                                                                                                                       
                                                                                                                                                                                                       
                                                                                                                                                                                                       
                                                                                                                                                                                                       
                                                                                                                                                                                                       
                                                                                                                                                                                                       
                                                                                                                                                                                                       
                                                                                                                                                                                                       
                                                                                                                                                                                                       

*/
(function (f, define) {
    define('kendo.listview', [
        'kendo.data',
        'kendo.editable',
        'kendo.selectable'
    ], f);
}(function () {
    var __meta__ = {
        id: 'listview',
        name: 'ListView',
        category: 'web',
        description: 'The ListView widget offers rich support for interacting with data.',
        depends: ['data'],
        features: [
            {
                id: 'listview-editing',
                name: 'Editing',
                description: 'Support for record editing',
                depends: ['editable']
            },
            {
                id: 'listview-selection',
                name: 'Selection',
                description: 'Support for selection',
                depends: ['selectable']
            }
        ]
    };
    (function ($, undefined) {
        var kendo = window.kendo, CHANGE = 'change', CANCEL = 'cancel', DATABOUND = 'dataBound', DATABINDING = 'dataBinding', Widget = kendo.ui.Widget, keys = kendo.keys, FOCUSSELECTOR = '>*:not(.k-loading-mask)', PROGRESS = 'progress', ERROR = 'error', FOCUSED = 'k-state-focused', SELECTED = 'k-state-selected', KEDITITEM = 'k-edit-item', EDIT = 'edit', REMOVE = 'remove', SAVE = 'save', CLICK = 'click', NS = '.kendoListView', proxy = $.proxy, activeElement = kendo._activeElement, progress = kendo.ui.progress, DataSource = kendo.data.DataSource;
        var ListView = kendo.ui.DataBoundWidget.extend({
            init: function (element, options) {
                var that = this;
                options = $.isArray(options) ? { dataSource: options } : options;
                Widget.fn.init.call(that, element, options);
                options = that.options;
                that.wrapper = element = that.element;
                if (element[0].id) {
                    that._itemId = element[0].id + '_lv_active';
                }
                that._element();
                that._dataSource();
                that._templates();
                that._navigatable();
                that._selectable();
                that._pageable();
                that._crudHandlers();
                if (that.options.autoBind) {
                    that.dataSource.fetch();
                }
                kendo.notify(that);
            },
            events: [
                CHANGE,
                CANCEL,
                DATABINDING,
                DATABOUND,
                EDIT,
                REMOVE,
                SAVE
            ],
            options: {
                name: 'ListView',
                autoBind: true,
                selectable: false,
                navigatable: false,
                template: '',
                altTemplate: '',
                editTemplate: ''
            },
            setOptions: function (options) {
                Widget.fn.setOptions.call(this, options);
                this._templates();
                if (this.selectable) {
                    this.selectable.destroy();
                    this.selectable = null;
                }
                this._selectable();
            },
            _templates: function () {
                var options = this.options;
                this.template = kendo.template(options.template || '');
                this.altTemplate = kendo.template(options.altTemplate || options.template);
                this.editTemplate = kendo.template(options.editTemplate || '');
            },
            _item: function (action) {
                return this.element.children()[action]();
            },
            items: function () {
                return this.element.children();
            },
            dataItem: function (element) {
                var attr = kendo.attr('uid');
                var uid = $(element).closest('[' + attr + ']').attr(attr);
                return this.dataSource.getByUid(uid);
            },
            setDataSource: function (dataSource) {
                this.options.dataSource = dataSource;
                this._dataSource();
                if (this.options.autoBind) {
                    dataSource.fetch();
                }
            },
            _unbindDataSource: function () {
                var that = this;
                that.dataSource.unbind(CHANGE, that._refreshHandler).unbind(PROGRESS, that._progressHandler).unbind(ERROR, that._errorHandler);
            },
            _dataSource: function () {
                var that = this;
                if (that.dataSource && that._refreshHandler) {
                    that._unbindDataSource();
                } else {
                    that._refreshHandler = proxy(that.refresh, that);
                    that._progressHandler = proxy(that._progress, that);
                    that._errorHandler = proxy(that._error, that);
                }
                that.dataSource = DataSource.create(that.options.dataSource).bind(CHANGE, that._refreshHandler).bind(PROGRESS, that._progressHandler).bind(ERROR, that._errorHandler);
            },
            _progress: function () {
                progress(this.element, true);
            },
            _error: function () {
                progress(this.element, false);
            },
            _element: function () {
                this.element.addClass('k-widget k-listview').attr('role', 'listbox');
            },
            refresh: function (e) {
                var that = this, view = that.dataSource.view(), data, items, item, html = '', idx, length, template = that.template, altTemplate = that.altTemplate, active = activeElement();
                e = e || {};
                if (e.action === 'itemchange') {
                    if (!that._hasBindingTarget() && !that.editable) {
                        data = e.items[0];
                        item = that.items().filter('[' + kendo.attr('uid') + '=' + data.uid + ']');
                        if (item.length > 0) {
                            idx = item.index();
                            that.angular('cleanup', function () {
                                return { elements: [item] };
                            });
                            item.replaceWith(template(data));
                            item = that.items().eq(idx);
                            item.attr(kendo.attr('uid'), data.uid);
                            that.angular('compile', function () {
                                return {
                                    elements: [item],
                                    data: [{ dataItem: data }]
                                };
                            });
                            that.trigger('itemChange', {
                                item: item,
                                data: data
                            });
                        }
                    }
                    return;
                }
                if (that.trigger(DATABINDING, {
                        action: e.action || 'rebind',
                        items: e.items,
                        index: e.index
                    })) {
                    return;
                }
                that._angularItems('cleanup');
                that._destroyEditable();
                for (idx = 0, length = view.length; idx < length; idx++) {
                    if (idx % 2) {
                        html += altTemplate(view[idx]);
                    } else {
                        html += template(view[idx]);
                    }
                }
                that.element.html(html);
                items = that.items();
                for (idx = 0, length = view.length; idx < length; idx++) {
                    items.eq(idx).attr(kendo.attr('uid'), view[idx].uid).attr('role', 'option').attr('aria-selected', 'false');
                }
                if (that.element[0] === active && that.options.navigatable) {
                    that.current(items.eq(0));
                }
                that._angularItems('compile');
                that.trigger(DATABOUND);
            },
            _pageable: function () {
                var that = this, pageable = that.options.pageable, settings, pagerId;
                if ($.isPlainObject(pageable)) {
                    pagerId = pageable.pagerId;
                    settings = $.extend({}, pageable, {
                        dataSource: that.dataSource,
                        pagerId: null
                    });
                    that.pager = new kendo.ui.Pager($('#' + pagerId), settings);
                }
            },
            _selectable: function () {
                var that = this, multi, current, selectable = that.options.selectable, navigatable = that.options.navigatable;
                if (selectable) {
                    multi = kendo.ui.Selectable.parseOptions(selectable).multiple;
                    that.selectable = new kendo.ui.Selectable(that.element, {
                        aria: true,
                        multiple: multi,
                        filter: FOCUSSELECTOR,
                        change: function () {
                            that.trigger(CHANGE);
                        }
                    });
                    if (navigatable) {
                        that.element.on('keydown' + NS, function (e) {
                            if (e.keyCode === keys.SPACEBAR) {
                                current = that.current();
                                if (e.target == e.currentTarget) {
                                    e.preventDefault();
                                }
                                if (multi) {
                                    if (!e.ctrlKey) {
                                        that.selectable.clear();
                                    } else {
                                        if (current && current.hasClass(SELECTED)) {
                                            current.removeClass(SELECTED);
                                            return;
                                        }
                                    }
                                } else {
                                    that.selectable.clear();
                                }
                                that.selectable.value(current);
                            }
                        });
                    }
                }
            },
            current: function (candidate) {
                var that = this, element = that.element, current = that._current, id = that._itemId;
                if (candidate === undefined) {
                    return current;
                }
                if (current && current[0]) {
                    if (current[0].id === id) {
                        current.removeAttr('id');
                    }
                    current.removeClass(FOCUSED);
                    element.removeAttr('aria-activedescendant');
                }
                if (candidate && candidate[0]) {
                    id = candidate[0].id || id;
                    that._scrollTo(candidate[0]);
                    element.attr('aria-activedescendant', id);
                    candidate.addClass(FOCUSED).attr('id', id);
                }
                that._current = candidate;
            },
            _scrollTo: function (element) {
                var that = this, container, UseJQueryoffset = false, SCROLL = 'scroll';
                if (that.wrapper.css('overflow') == 'auto' || that.wrapper.css('overflow') == SCROLL) {
                    container = that.wrapper[0];
                } else {
                    container = window;
                    UseJQueryoffset = true;
                }
                var scrollDirectionFunc = function (direction, dimension) {
                    var elementOffset = UseJQueryoffset ? $(element).offset()[direction.toLowerCase()] : element['offset' + direction], elementDimension = element['client' + dimension], containerScrollAmount = $(container)[SCROLL + direction](), containerDimension = $(container)[dimension.toLowerCase()]();
                    if (elementOffset + elementDimension > containerScrollAmount + containerDimension) {
                        $(container)[SCROLL + direction](elementOffset + elementDimension - containerDimension);
                    } else if (elementOffset < containerScrollAmount) {
                        $(container)[SCROLL + direction](elementOffset);
                    }
                };
                scrollDirectionFunc('Top', 'Height');
                scrollDirectionFunc('Left', 'Width');
            },
            _navigatable: function () {
                var that = this, navigatable = that.options.navigatable, element = that.element, clickCallback = function (e) {
                        that.current($(e.currentTarget));
                        if (!$(e.target).is(':button,a,:input,a>.k-icon,textarea')) {
                            element.focus();
                        }
                    };
                if (navigatable) {
                    that._tabindex();
                    element.on('focus' + NS, function () {
                        var current = that._current;
                        if (!current || !current.is(':visible')) {
                            current = that._item('first');
                        }
                        that.current(current);
                    }).on('focusout' + NS, function () {
                        if (that._current) {
                            that._current.removeClass(FOCUSED);
                        }
                    }).on('keydown' + NS, function (e) {
                        var key = e.keyCode, current = that.current(), target = $(e.target), canHandle = !target.is(':button,textarea,a,a>.t-icon,input'), isTextBox = target.is(':text,:password'), preventDefault = kendo.preventDefault, editItem = element.find('.' + KEDITITEM), active = activeElement(), idx;
                        if (!canHandle && !isTextBox && keys.ESC != key || isTextBox && keys.ESC != key && keys.ENTER != key) {
                            return;
                        }
                        if (keys.UP === key || keys.LEFT === key) {
                            if (current) {
                                current = current.prev();
                            }
                            that.current(!current || !current[0] ? that._item('last') : current);
                            preventDefault(e);
                        } else if (keys.DOWN === key || keys.RIGHT === key) {
                            if (current) {
                                current = current.next();
                            }
                            that.current(!current || !current[0] ? that._item('first') : current);
                            preventDefault(e);
                        } else if (keys.PAGEUP === key) {
                            that.current(null);
                            that.dataSource.page(that.dataSource.page() - 1);
                            preventDefault(e);
                        } else if (keys.PAGEDOWN === key) {
                            that.current(null);
                            that.dataSource.page(that.dataSource.page() + 1);
                            preventDefault(e);
                        } else if (keys.HOME === key) {
                            that.current(that._item('first'));
                            preventDefault(e);
                        } else if (keys.END === key) {
                            that.current(that._item('last'));
                            preventDefault(e);
                        } else if (keys.ENTER === key) {
                            if (editItem.length !== 0 && (canHandle || isTextBox)) {
                                idx = that.items().index(editItem);
                                if (active) {
                                    active.blur();
                                }
                                that.save();
                                var focusAgain = function () {
                                    that.element.trigger('focus');
                                    that.current(that.items().eq(idx));
                                };
                                that.one('dataBound', focusAgain);
                            } else if (that.options.editTemplate !== '') {
                                that.edit(current);
                            }
                        } else if (keys.ESC === key) {
                            editItem = element.find('.' + KEDITITEM);
                            if (editItem.length === 0) {
                                return;
                            }
                            idx = that.items().index(editItem);
                            that.cancel();
                            that.element.trigger('focus');
                            that.current(that.items().eq(idx));
                        }
                    });
                    element.on('mousedown' + NS + ' touchstart' + NS, FOCUSSELECTOR, proxy(clickCallback, that));
                }
            },
            clearSelection: function () {
                var that = this;
                that.selectable.clear();
                that.trigger(CHANGE);
            },
            select: function (items) {
                var that = this, selectable = that.selectable;
                items = $(items);
                if (items.length) {
                    if (!selectable.options.multiple) {
                        selectable.clear();
                        items = items.first();
                    }
                    selectable.value(items);
                    return;
                }
                return selectable.value();
            },
            _destroyEditable: function () {
                var that = this;
                if (that.editable) {
                    that.editable.destroy();
                    delete that.editable;
                }
            },
            _modelFromElement: function (element) {
                var uid = element.attr(kendo.attr('uid'));
                return this.dataSource.getByUid(uid);
            },
            _closeEditable: function () {
                var that = this, editable = that.editable, data, item, index, template = that.template;
                if (editable) {
                    if (editable.element.index() % 2) {
                        template = that.altTemplate;
                    }
                    that.angular('cleanup', function () {
                        return { elements: [editable.element] };
                    });
                    data = that._modelFromElement(editable.element);
                    that._destroyEditable();
                    index = editable.element.index();
                    editable.element.replaceWith(template(data));
                    item = that.items().eq(index);
                    item.attr(kendo.attr('uid'), data.uid);
                    if (that._hasBindingTarget()) {
                        kendo.bind(item, data);
                    }
                    that.angular('compile', function () {
                        return {
                            elements: [item],
                            data: [{ dataItem: data }]
                        };
                    });
                }
                return true;
            },
            edit: function (item) {
                var that = this, data = that._modelFromElement(item), container, uid = data.uid, index;
                that.cancel();
                item = that.items().filter('[' + kendo.attr('uid') + '=' + uid + ']');
                index = item.index();
                item.replaceWith(that.editTemplate(data));
                container = that.items().eq(index).addClass(KEDITITEM).attr(kendo.attr('uid'), data.uid);
                that.editable = container.kendoEditable({
                    model: data,
                    clearContainer: false,
                    errorTemplate: false,
                    target: that
                }).data('kendoEditable');
                that.trigger(EDIT, {
                    model: data,
                    item: container
                });
            },
            save: function () {
                var that = this, editable = that.editable, model;
                if (!editable) {
                    return;
                }
                var container = editable.element;
                model = that._modelFromElement(container);
                if (editable.end() && !that.trigger(SAVE, {
                        model: model,
                        item: container
                    })) {
                    that._closeEditable();
                    that.dataSource.sync();
                }
            },
            remove: function (item) {
                var that = this, dataSource = that.dataSource, data = that._modelFromElement(item);
                if (that.editable) {
                    dataSource.cancelChanges(that._modelFromElement(that.editable.element));
                    that._closeEditable();
                }
                if (!that.trigger(REMOVE, {
                        model: data,
                        item: item
                    })) {
                    item.hide();
                    dataSource.remove(data);
                    dataSource.sync();
                }
            },
            add: function () {
                var that = this, dataItem, dataSource = that.dataSource, index = dataSource.indexOf((dataSource.view() || [])[0]);
                if (index < 0) {
                    index = 0;
                }
                that.cancel();
                dataItem = dataSource.insert(index, {});
                that.edit(that.element.find('[data-uid=\'' + dataItem.uid + '\']'));
            },
            cancel: function () {
                var that = this, dataSource = that.dataSource;
                if (that.editable) {
                    var container = that.editable.element;
                    var model = that._modelFromElement(container);
                    if (!that.trigger(CANCEL, {
                            model: model,
                            container: container
                        })) {
                        dataSource.cancelChanges(model);
                        that._closeEditable();
                    }
                }
            },
            _crudHandlers: function () {
                var that = this, clickNS = CLICK + NS;
                that.element.on(clickNS, '.k-edit-button', function (e) {
                    var item = $(this).closest('[' + kendo.attr('uid') + ']');
                    that.edit(item);
                    e.preventDefault();
                });
                that.element.on(clickNS, '.k-delete-button', function (e) {
                    var item = $(this).closest('[' + kendo.attr('uid') + ']');
                    that.remove(item);
                    e.preventDefault();
                });
                that.element.on(clickNS, '.k-update-button', function (e) {
                    that.save();
                    e.preventDefault();
                });
                that.element.on(clickNS, '.k-cancel-button', function (e) {
                    that.cancel();
                    e.preventDefault();
                });
            },
            destroy: function () {
                var that = this;
                Widget.fn.destroy.call(that);
                that._unbindDataSource();
                that._destroyEditable();
                that.element.off(NS);
                if (that.pager) {
                    that.pager.destroy();
                }
                kendo.destroy(that.element);
            }
        });
        kendo.ui.plugin(ListView);
    }(window.kendo.jQuery));
    return window.kendo;
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
    (a3 || a2)();
}));