X-Git-Url: http://git.roojs.org/?a=blobdiff_plain;f=roojs-bootstrap-debug.js;h=c5e35d3fe01d2e9399a7d679416056257658912b;hb=bb4f20285cb0ce281099e1db5cb76e60175de50f;hp=c30b5b554cfcbd6ee1b57f12640bd0c61b40f1e8;hpb=267f6bc0ecf0897515863c3c91a8eea23388e273;p=roojs1 diff --git a/roojs-bootstrap-debug.js b/roojs-bootstrap-debug.js index c30b5b554c..c5e35d3fe0 100644 --- a/roojs-bootstrap-debug.js +++ b/roojs-bootstrap-debug.js @@ -1,18 +1,23 @@ -/** +Roo.bootstrap = {};/** * set the version of bootstrap based on the stylesheet... * */ -Roo.bootstrap.version = ( - function() { - var ret=3; - Roo.each(document.styleSheets, function(s) { - if ( s.href && s.href.match(/css-bootstrap4/)) { - ret=4; - } - }); - return ret; -})(); /* +Roo.bootstrap.version = ( function() { + var ret=3; + Roo.each(document.styleSheets, function(s) { + if ( s.href && s.href.match(/css-bootstrap4/)) { + ret=4; + } + }); + if (ret > 3) { + Roo.Element.prototype.visibilityMode = Roo.Element.DISPLAY; + } + return ret; +})(); Roo.bootstrap.menu = Roo.bootstrap.menu || {}; +Roo.bootstrap.nav = {}; + +Roo.bootstrap.form = {};Roo.bootstrap.panel = {};Roo.bootstrap.layout = {};/* * Based on: * Ext JS Library 1.1.1 * Copyright(c) 2006-2007, Ext JS, LLC. @@ -93,6 +98,7 @@ Roo.Shadow.prototype = { * frame: Shadow displays equally on all four sides
* drop: Traditional bottom-right drop shadow (default) */ + mode: false, /** * @cfg {String} offset * The number of pixels to offset the shadow from the element (defaults to 4) @@ -220,6 +226,8 @@ Roo.bootstrap = Roo.bootstrap || {}; /** * @class Roo.bootstrap.Component * @extends Roo.Component + * @abstract + * @children Roo.bootstrap.Component * Bootstrap Component base class * @cfg {String} cls css class * @cfg {String} style any extra css @@ -328,11 +336,11 @@ Roo.extend(Roo.bootstrap.Component, Roo.BoxComponent, { } if (this.cls) { - cfg.cls = (typeof(cfg.cls) == 'undefined') ? this.cls : cfg.cls + ' ' + this.cls; + cfg.cls = (typeof(cfg.cls) == 'undefined' ? this.cls : cfg.cls) + ' ' + this.cls; } if (this.style) { // fixme needs to support more complex style data. - cfg.style = this.style; + cfg.style = (typeof(cfg.style) == 'undefined' ? this.style : cfg.style) + '; ' + this.style; } if(this.name){ @@ -360,6 +368,11 @@ Roo.extend(Roo.bootstrap.Component, Roo.BoxComponent, { { return this.el; }, + getDocumentBody : function() // used by menus - as they are attached to the body so zIndexes work + { + return Roo.get(document.body); + }, + /** * Fetch the element to display the tooltip on. * @return {Roo.Element} defaults to this.el @@ -642,12 +655,16 @@ Roo.extend(Roo.bootstrap.Component, Roo.BoxComponent, { /** * @class Roo.bootstrap.Element * @extends Roo.bootstrap.Component - * Bootstrap Element class + * @children Roo.bootstrap.Component + * Bootstrap Element class (basically a DIV used to make random stuff ) + * * @cfg {String} html contents of the element * @cfg {String} tag tag of the element * @cfg {String} cls class of the element * @cfg {Boolean} preventDefault (true|false) default false * @cfg {Boolean} clickable (true|false) default false + * @cfg {String} role default blank - set to button to force cursor pointer + * * @constructor * Create a new Element @@ -665,7 +682,9 @@ Roo.bootstrap.Element = function(config){ * @param {Roo.bootstrap.Element} this * @param {Roo.EventObject} e */ - "click" : true + "click" : true + + }); }; @@ -676,6 +695,8 @@ Roo.extend(Roo.bootstrap.Element, Roo.bootstrap.Component, { html: '', preventDefault: false, clickable: false, + tapedTwice : false, + role : false, getAutoCreate : function(){ @@ -684,6 +705,9 @@ Roo.extend(Roo.bootstrap.Element, Roo.bootstrap.Component, { // cls: this.cls, double assign in parent class Component.js :: onRender html: this.html }; + if (this.role !== false) { + cfg.role = this.role; + } return cfg; }, @@ -696,6 +720,7 @@ Roo.extend(Roo.bootstrap.Element, Roo.bootstrap.Component, { this.el.on('click', this.onClick, this); } + }, onClick : function(e) @@ -704,9 +729,14 @@ Roo.extend(Roo.bootstrap.Element, Roo.bootstrap.Component, { e.preventDefault(); } - this.fireEvent('click', this, e); + this.fireEvent('click', this, e); // why was this double click before? }, + + + + + getValue : function() { return this.el.dom.innerHTML; @@ -825,6 +855,8 @@ Roo.extend(Roo.bootstrap.DropTarget, Roo.bootstrap.Element, { /** * @class Roo.bootstrap.Body * @extends Roo.bootstrap.Component + * @children Roo.bootstrap.Component + * @parent none builder * Bootstrap Body class * * @constructor @@ -876,6 +908,8 @@ Roo.extend(Roo.bootstrap.Body, Roo.bootstrap.Component, { * @class Roo.bootstrap.ButtonGroup * @extends Roo.bootstrap.Component * Bootstrap ButtonGroup class + * @children Roo.bootstrap.Button Roo.bootstrap.form.Form + * * @cfg {String} size lg | sm | xs (default empty normal) * @cfg {String} align vertical | justified (default none) * @cfg {String} direction up | down (default down) @@ -961,11 +995,11 @@ Roo.extend(Roo.bootstrap.ButtonGroup, Roo.bootstrap.Component, { * @extends Roo.bootstrap.Component * Bootstrap Button class * @cfg {String} html The button content - * @cfg {String} weight (default | primary | secondary | success | info | warning | danger | link ) default - * @cfg {String} badge_weight (default | primary | secondary | success | info | warning | danger | link ) default (same as button) + * @cfg {String} weight (default|primary|secondary|success|info|warning|danger|link|light|dark) default + * @cfg {String} badge_weight (default|primary|secondary|success|info|warning|danger|link|light|dark) default (same as button) * @cfg {Boolean} outline default false (except for weight=default which emulates old behaveiour with an outline) - * @cfg {String} size ( lg | sm | xs) - * @cfg {String} tag ( a | input | submit) + * @cfg {String} size (lg|sm|xs) + * @cfg {String} tag (a|input|submit) * @cfg {String} href empty or href * @cfg {Boolean} disabled default false; * @cfg {Boolean} isClose default false; @@ -975,13 +1009,15 @@ Roo.extend(Roo.bootstrap.ButtonGroup, Roo.bootstrap.Component, { * @cfg {String} theme (default|glow) * @cfg {Boolean} inverse dark themed version * @cfg {Boolean} toggle is it a slidy toggle button - * @cfg {Boolean} pressed (true|false) default null - if the button ahs active state + * @cfg {Boolean} pressed  default null - if the button ahs active state * @cfg {String} ontext text for on slidy toggle state * @cfg {String} offtext text for off slidy toggle state * @cfg {Boolean} preventDefault default true (stop click event triggering the URL if it's a link.) * @cfg {Boolean} removeClass remove the standard class.. - * @cfg {String} target target for a href. (_self|_blank|_parent|_top| other) - * + * @cfg {String} target (_self|_blank|_parent|_top|other) target for a href. + * @cfg {Boolean} grpup if parent is a btn group - then it turns it into a toogleGroup. + * @cfg {Roo.bootstrap.menu.Menu} menu a Menu + * @constructor * Create a new button * @param {Object} config The config object @@ -990,23 +1026,23 @@ Roo.extend(Roo.bootstrap.ButtonGroup, Roo.bootstrap.Component, { Roo.bootstrap.Button = function(config){ Roo.bootstrap.Button.superclass.constructor.call(this, config); - this.weightClass = ["btn-default btn-outline-secondary", - "btn-primary", - "btn-success", - "btn-info", - "btn-warning", - "btn-danger", - "btn-link" - ], + this.addEvents({ // raw events /** * @event click - * When a butotn is pressed + * When a button is pressed * @param {Roo.bootstrap.Button} btn * @param {Roo.EventObject} e */ "click" : true, + /** + * @event dblclick + * When a button is double clicked + * @param {Roo.bootstrap.Button} btn + * @param {Roo.EventObject} e + */ + "dblclick" : true, /** * @event toggle * After the button has been toggles @@ -1043,6 +1079,7 @@ Roo.extend(Roo.bootstrap.Button, Roo.bootstrap.Component, { removeClass: false, name: false, target: false, + group : false, pressed : null, @@ -1077,9 +1114,9 @@ Roo.extend(Roo.bootstrap.Button, Roo.bootstrap.Component, { } ] }; - - if (['default', 'secondary' , 'primary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) { - cfg.cls += ' '+this.weight; + // why are we validating the weights? + if (Roo.bootstrap.Button.weights.indexOf(this.weight) > -1) { + cfg.cls += ' ' + this.weight; } return cfg; @@ -1094,15 +1131,15 @@ Roo.extend(Roo.bootstrap.Button, Roo.bootstrap.Component, { return cfg; } + - if (this.theme==='default') { cfg.cls = 'btn roo-button'; //if (this.parentType != 'Navbar') { this.weight = this.weight.length ? this.weight : 'default'; //} - if (['default', 'primary', 'secondary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) { + if (Roo.bootstrap.Button.weights.indexOf(this.weight) > -1) { var outline = this.outline || this.weight == 'default' ? 'outline-' : ''; var weight = this.weight == 'default' ? 'secondary' : this.weight; @@ -1117,7 +1154,7 @@ Roo.extend(Roo.bootstrap.Button, Roo.bootstrap.Component, { cfg.tag = 'a'; cfg.cls = 'btn-glow roo-button'; - if (['default', 'primary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) { + if (Roo.bootstrap.Button.weights.indexOf(this.weight) > -1) { cfg.cls += ' ' + this.weight; } @@ -1270,17 +1307,30 @@ Roo.extend(Roo.bootstrap.Button, Roo.bootstrap.Component, { } - if (this.el.hasClass('roo-button')) { + if (this.el.hasClass('roo-button')) { + this.el.on('click', this.onClick, this); + this.el.on('dblclick', this.onDblClick, this); + } else { + this.el.select('.roo-button').on('click', this.onClick, this); + this.el.select('.roo-button').on('dblclick', this.onDblClick, this); + + } + // why? + if(this.removeClass){ this.el.on('click', this.onClick, this); - } else { - this.el.select('.roo-button').on('click', this.onClick, this); - } - - if(this.removeClass){ - this.el.on('click', this.onClick, this); - } - - this.el.enableDisplayMode(); + } + + if (this.group === true) { + if (this.pressed === false || this.pressed === true) { + // nothing + } else { + this.pressed = false; + this.setActive(this.pressed); + } + + } + + this.el.enableDisplayMode(); }, onClick : function(e) @@ -1290,10 +1340,29 @@ Roo.extend(Roo.bootstrap.Button, Roo.bootstrap.Component, { } Roo.log('button on click '); - if(this.preventDefault){ + if(this.href === '' || this.preventDefault){ e.preventDefault(); } + if (this.group) { + if (this.pressed) { + // do nothing - + return; + } + this.setActive(true); + var pi = this.parent().items; + for (var i = 0;i < pi.length;i++) { + if (this == pi[i]) { + continue; + } + if (pi[i].el.hasClass('roo-button')) { + pi[i].setActive(false); + } + } + this.fireEvent('click', this, e); + return; + } + if (this.pressed === true || this.pressed === false) { this.toggleActive(e); } @@ -1301,7 +1370,16 @@ Roo.extend(Roo.bootstrap.Button, Roo.bootstrap.Component, { this.fireEvent('click', this, e); }, - + onDblClick: function(e) + { + if (this.disabled) { + return; + } + if(this.preventDefault){ + e.preventDefault(); + } + this.fireEvent('dblclick', this, e); + }, /** * Enables this button */ @@ -1309,6 +1387,7 @@ Roo.extend(Roo.bootstrap.Button, Roo.bootstrap.Component, { { this.disabled = false; this.el.removeClass('disabled'); + this.el.dom.removeAttribute("disabled"); }, /** @@ -1318,6 +1397,7 @@ Roo.extend(Roo.bootstrap.Button, Roo.bootstrap.Component, { { this.disabled = true; this.el.addClass('disabled'); + this.el.attr("disabled", "disabled") }, /** * sets the active state on/off, @@ -1333,8 +1413,8 @@ Roo.extend(Roo.bootstrap.Button, Roo.bootstrap.Component, { */ toggleActive : function(e) { - this.setActive(!this.pressed); - this.fireEvent('toggle', this, e, !this.pressed); + this.setActive(!this.pressed); // this modifies pressed... + this.fireEvent('toggle', this, e, this.pressed); }, /** * get the current active state @@ -1361,7 +1441,8 @@ Roo.extend(Roo.bootstrap.Button, Roo.bootstrap.Component, { setWeight : function(str) { - this.el.removeClass(this.weightClass); + this.el.removeClass(Roo.bootstrap.Button.weights.map(function(w) { return 'btn-' + w; } ) ); + this.el.removeClass(Roo.bootstrap.Button.weights.map(function(w) { return 'btn-outline-' + w; } ) ); this.weight = str; var outline = this.outline ? 'outline-' : ''; if (str == 'default') { @@ -1373,8 +1454,21 @@ Roo.extend(Roo.bootstrap.Button, Roo.bootstrap.Component, { }); - - /* +// fixme - this is probably generic bootstrap - should go in some kind of enum file.. - like sizes. + +Roo.bootstrap.Button.weights = [ + 'default', + 'secondary' , + 'primary', + 'success', + 'info', + 'warning', + 'danger', + 'link', + 'light', + 'dark' + +];/* * - LGPL * * column @@ -1384,6 +1478,7 @@ Roo.extend(Roo.bootstrap.Button, Roo.bootstrap.Component, { /** * @class Roo.bootstrap.Column * @extends Roo.bootstrap.Component + * @children Roo.bootstrap.Component * Bootstrap Column class * @cfg {Number} xs colspan out of 12 for mobile-sized screens or 0 for hidden * @cfg {Number} sm colspan out of 12 for tablet-sized screens or 0 for hidden @@ -1511,6 +1606,8 @@ Roo.extend(Roo.bootstrap.Column, Roo.bootstrap.Component, { /** * @class Roo.bootstrap.Container * @extends Roo.bootstrap.Component + * @children Roo.bootstrap.Component + * @parent builder * Bootstrap Container class * @cfg {Boolean} jumbotron is it a jumbotron element * @cfg {String} html content of element @@ -1874,26 +1971,23 @@ Roo.extend(Roo.bootstrap.Container, Roo.bootstrap.Component, { } }); - /* - * - LGPL - * - * This is BS4's Card element.. - similar to our containers probably.. - * - */ -/** + /** * @class Roo.bootstrap.Card * @extends Roo.bootstrap.Component - * Bootstrap Card class + * @children Roo.bootstrap.Component + * @licence LGPL + * Bootstrap Card class - note this has children as CardHeader/ImageTop/Footer.. - which should really be listed properties? * * * possible... may not be implemented.. * @cfg {String} header_image src url of image. * @cfg {String|Object} header * @cfg {Number} header_size (0|1|2|3|4|5) H1 or H2 etc.. 0 indicates default + * @cfg {Number} header_weight (primary|secondary|success|info|warning|danger|light|dark) * * @cfg {String} title * @cfg {String} subtitle - * @cfg {String} html -- html contents - or just use children.. + * @cfg {String|Boolean} html -- html contents - or just use children.. use false to hide it.. * @cfg {String} footer * @cfg {String} weight (primary|warning|info|danger|secondary|success|light|dark) @@ -1907,7 +2001,7 @@ Roo.extend(Roo.bootstrap.Container, Roo.bootstrap.Component, { * @cfg {String} margin_y (0|1|2|3|4|5|auto) * * @cfg {String} padding (0|1|2|3|4|5) - * @cfg {String} padding_top (0|1|2|3|4|5) + * @cfg {String} padding_top (0|1|2|3|4|5)next_to_card * @cfg {String} padding_bottom (0|1|2|3|4|5) * @cfg {String} padding_left (0|1|2|3|4|5) * @cfg {String} padding_right (0|1|2|3|4|5) @@ -1927,6 +2021,9 @@ Roo.extend(Roo.bootstrap.Container, Roo.bootstrap.Component, { * * @config {Boolean} collapsable can the body be collapsed. * @config {Boolean} collapsed is the body collapsed when rendered... + * @config {Boolean} rotateable can the body be rotated by clicking on it.. + * @config {Boolean} rotated is the body rotated when rendered... + * * @constructor * Create a new Container * @param {Object} config The config object @@ -1940,14 +2037,31 @@ Roo.bootstrap.Card = function(config){ /** * @event drop * When a element a card is dropped - * @param {Roo.bootstrap.Element} this + * @param {Roo.bootstrap.Card} this + * + * + * @param {Roo.bootstrap.Card} move_card the card being dropped? + * @param {String} position 'above' or 'below' + * @param {Roo.bootstrap.Card} next_to_card What card position is relative to of 'false' for empty list. + + */ + 'drop' : true, + /** + * @event rotate + * When a element a card is rotate + * @param {Roo.bootstrap.Card} this * @param {Roo.Element} n the node being dropped? - * @param {Object} dd Drag and drop data - * @param {Roo.EventObject} e - * @param {Roo.EventObject} data the data passed via getDragData + * @param {Boolean} rotate status */ - 'drop' : true - + 'rotate' : true, + /** + * @event cardover + * When a card element is dragged over ready to drop (return false to block dropable) + * @param {Roo.bootstrap.Card} this + * @param {Object} data from dragdrop + */ + 'cardover' : true + }); }; @@ -1989,6 +2103,8 @@ Roo.extend(Roo.bootstrap.Card, Roo.bootstrap.Component, { collapsable : false, collapsed : false, + rotateable : false, + rotated : false, dragable : false, drag_group : false, @@ -1996,6 +2112,12 @@ Roo.extend(Roo.bootstrap.Card, Roo.bootstrap.Component, { drop_group : false, childContainer : false, dropEl : false, /// the dom placeholde element that indicates drop location. + containerEl: false, // body container + bodyEl: false, // card-body + headerContainerEl : false, // + headerEl : false, + header_imageEl : false, + layoutCls : function() { @@ -2015,7 +2137,7 @@ Roo.extend(Roo.bootstrap.Card, Roo.bootstrap.Component, { ['', 'xs', 'sm', 'lg', 'xl'].forEach(function(v) { if (('' + t['display' + (v.length ? '_' : '') + v]).length) { - cls += ' d' + (v.length ? '-' : '') + v + '-' + t['margin' + (v.length ? '_' : '') + v] + cls += ' d' + (v.length ? '-' : '') + v + '-' + t['display' + (v.length ? '_' : '') + v] } }); @@ -2068,47 +2190,49 @@ Roo.extend(Roo.bootstrap.Card, Roo.bootstrap.Component, { cfg.cls += ' bg-' + this.weight; } - cfg.cls += this.layoutCls(); + cfg.cls += ' ' + this.layoutCls(); - var hdr = false; + var hdr = false; + var hdr_ctr = false; if (this.header.length) { hdr = { tag : this.header_size > 0 ? 'h' + this.header_size : 'div', - cls : 'card-header', - cn : [] + cls : 'card-header ' + (this.header_weight ? 'bg-' + this.header_weight : ''), + cn : [] }; - cfg.cn.push(hdr); - hdr_ctr = hdr; + cfg.cn.push(hdr); + hdr_ctr = hdr; } else { - hdr = { + hdr = { tag : 'div', - cls : 'card-header d-none', - cn : [] + cls : 'card-header d-none ' + (this.header_weight ? 'bg-' + this.header_weight : ''), + cn : [] }; - cfg.cn.push(hdr); - } - if (this.collapsable) { - hdr_ctr = { - tag : 'a', - cls : 'd-block user-select-none', - cn: [ - { - tag: 'i', - cls : 'roo-collapse-toggle fa fa-chevron-down float-right' - } - - ] - }; - hdr.cn.push(hdr_ctr); - } - if (this.header.length) { + cfg.cn.push(hdr); + hdr_ctr = hdr; + } + if (this.collapsable) { + hdr_ctr = { + tag : 'a', + cls : 'd-block user-select-none', + cn: [ + { + tag: 'i', + cls : 'roo-collapse-toggle fa fa-chevron-down float-right ' + (this.collapsed ? 'collapsed' : '') + } + + ] + }; + hdr.cn.push(hdr_ctr); + } + hdr_ctr.cn.push( { - tag: 'span', - cls: 'roo-card-header-ctr', - html : this.header - }) - } - + tag: 'span', + cls: 'roo-card-header-ctr' + ( this.header.length ? '' : ' d-none'), + html : this.header + }); + + if (this.header_image.length) { cfg.cn.push({ tag : 'img', @@ -2116,26 +2240,26 @@ Roo.extend(Roo.bootstrap.Card, Roo.bootstrap.Component, { src: this.header_image // escape? }); } else { - cfg.cn.push({ - tag : 'div', - cls : 'card-img-top d-none' - }); - } - + cfg.cn.push({ + tag : 'div', + cls : 'card-img-top d-none' + }); + } + var body = { tag : 'div', - cls : 'card-body', + cls : 'card-body' + (this.html === false ? ' d-none' : ''), cn : [] }; - var obody = body; - if (this.collapsable) { - obody = { - tag: 'div', - cls : 'roo-collapsable collapse ' + (this.collapsed ? '' : 'show'), - cn : [ body ] - }; - } - + var obody = body; + if (this.collapsable || this.rotateable) { + obody = { + tag: 'div', + cls : 'roo-collapsable collapse ' + (this.collapsed || this.rotated ? '' : 'show'), + cn : [ body ] + }; + } + cfg.cn.push(obody); if (this.title.length) { @@ -2144,7 +2268,7 @@ Roo.extend(Roo.bootstrap.Card, Roo.bootstrap.Component, { cls : 'card-title', src: this.title // escape? }); - } + } if (this.subtitle.length) { body.cn.push({ @@ -2166,13 +2290,18 @@ Roo.extend(Roo.bootstrap.Card, Roo.bootstrap.Component, { }); } // fixme ? handle objects? + if (this.footer.length) { + cfg.cn.push({ - tag : 'div', - cls : 'card-footer', - html: this.footer // escape? + cls : 'card-footer ' + (this.rotated ? 'd-none' : ''), + html : this.footer }); + + } else { + cfg.cn.push({cls : 'card-footer d-none'}); } + // footer... return cfg; @@ -2182,22 +2311,30 @@ Roo.extend(Roo.bootstrap.Card, Roo.bootstrap.Component, { getCardHeader : function() { var ret = this.el.select('.card-header',true).first(); - if (ret.hasClass('d-none')) { - ret.removeClass('d-none'); - } + if (ret.hasClass('d-none')) { + ret.removeClass('d-none'); + } return ret; }, - - getCardImageTop : function() + getCardFooter : function() { - var ret = this.el.select('.card-img-top',true).first(); - if (ret.hasClass('d-none')) { - ret.removeClass('d-none'); - } + var ret = this.el.select('.card-footer',true).first(); + if (ret.hasClass('d-none')) { + ret.removeClass('d-none'); + } return ret; }, + getCardImageTop : function() + { + var ret = this.header_imageEl; + if (ret.hasClass('d-none')) { + ret.removeClass('d-none'); + } + + return ret; + }, getChildContainer : function() { @@ -2210,9 +2347,9 @@ Roo.extend(Roo.bootstrap.Card, Roo.bootstrap.Component, { initEvents: function() { - - this.bodyEl = this.getChildContainer(); - if(this.dragable){ + this.bodyEl = this.el.select('.card-body',true).first(); + this.containerEl = this.getChildContainer(); + if(this.dragable){ this.dragZone = new Roo.dd.DragZone(this.getEl(), { containerScroll: true, ddGroup: this.drag_group || 'default_card_drag_group' @@ -2220,20 +2357,37 @@ Roo.extend(Roo.bootstrap.Card, Roo.bootstrap.Component, { this.dragZone.getDragData = this.getDragData.createDelegate(this); } if (this.dropable) { - this.dropZone = new Roo.dd.DropZone(this.el.select('.card-body',true).first() , { - containerScroll: true, - ddGroup: this.drop_group || 'default_card_drag_group' - }); - this.dropZone.getTargetFromEvent = this.getTargetFromEvent.createDelegate(this); - this.dropZone.onNodeEnter = this.onNodeEnter.createDelegate(this); - this.dropZone.onNodeOver = this.onNodeOver.createDelegate(this); - this.dropZone.onNodeOut = this.onNodeOut.createDelegate(this); - this.dropZone.onNodeDrop = this.onNodeDrop.createDelegate(this); - } + this.dropZone = new Roo.dd.DropZone(this.el.select('.card-body',true).first() , { + containerScroll: true, + ddGroup: this.drop_group || 'default_card_drag_group' + }); + this.dropZone.getTargetFromEvent = this.getTargetFromEvent.createDelegate(this); + this.dropZone.onNodeEnter = this.onNodeEnter.createDelegate(this); + this.dropZone.onNodeOver = this.onNodeOver.createDelegate(this); + this.dropZone.onNodeOut = this.onNodeOut.createDelegate(this); + this.dropZone.onNodeDrop = this.onNodeDrop.createDelegate(this); + } if (this.collapsable) { - this.el.select('.card-header',true).on('click', this.onToggleCollapse, this); - } + this.el.select('.card-header',true).on('click', this.onToggleCollapse, this); + } + if (this.rotateable) { + this.el.select('.card-header',true).on('click', this.onToggleRotate, this); + } + this.collapsableEl = this.el.select('.roo-collapsable',true).first(); + + this.footerEl = this.el.select('.card-footer',true).first(); + this.collapsableToggleEl = this.el.select('.roo-collapse-toggle',true).first(); + this.headerContainerEl = this.el.select('.roo-card-header-ctr',true).first(); + this.headerEl = this.el.select('.card-header',true).first(); + + if (this.rotated) { + this.el.addClass('roo-card-rotated'); + this.fireEvent('rotate', this, true); + } + this.header_imageEl = this.el.select('.card-img-top',true).first(); + this.header_imageEl.on('load', this.onHeaderImageLoad, this ); + }, getDragData : function(e) { @@ -2258,21 +2412,44 @@ Roo.extend(Roo.bootstrap.Card, Roo.bootstrap.Component, { return false; }, /** - * Part of the Roo.dd.DropZone interface. If no target node is found, the - * whole Element becomes the target, and this causes the drop gesture to append. - */ + * Part of the Roo.dd.DropZone interface. If no target node is found, the + * whole Element becomes the target, and this causes the drop gesture to append. + * + * Returns an object: + * { + + position : 'below' or 'above' + card : relateive to card OBJECT (or true for no cards listed) + items_n : relative to nth item in list + card_n : relative to nth card in list + } + * + * + */ getTargetFromEvent : function(e, dragged_card_el) { var target = e.getTarget(); - while ((target !== null) && (target.parentNode != this.bodyEl.dom)) { + while ((target !== null) && (target.parentNode != this.containerEl.dom)) { target = target.parentNode; } + + var ret = { + position: '', + cards : [], + card_n : -1, + items_n : -1, + card : false + }; + //Roo.log([ 'target' , target ? target.id : '--nothing--']); // see if target is one of the 'cards'... - var ctarget = -1; - var cards = []; + + //Roo.log(this.items.length); - var lpos = pos = cpos = false; + var pos = false; + + var last_card_n = 0; + var cards_len = 0; for (var i = 0;i< this.items.length;i++) { if (!this.items[i].el.hasClass('card')) { @@ -2280,48 +2457,52 @@ Roo.extend(Roo.bootstrap.Card, Roo.bootstrap.Component, { } pos = this.getDropPoint(e, this.items[i].el.dom); + cards_len = ret.cards.length; //Roo.log(this.items[i].el.dom.id); - var ii = cards.length; - cards.push(this.items[i]); - - if (ctarget < 0 && pos == 'above') { - ctarget = ii > 0 ? ii - 1 : 0; - cpos = ii > 0 ? 'below' : pos; - } + ret.cards.push(this.items[i]); + last_card_n = i; + if (ret.card_n < 0 && pos == 'above') { + ret.position = cards_len > 0 ? 'below' : pos; + ret.items_n = i > 0 ? i - 1 : 0; + ret.card_n = cards_len > 0 ? cards_len - 1 : 0; + ret.card = ret.cards[ret.card_n]; + } + } + if (!ret.cards.length) { + ret.card = true; + ret.position = 'below'; + ret.items_n; + return ret; } - if (!cards.length) { - return [ true, 'below' ]; + // could not find a card.. stick it at the end.. + if (ret.card_n < 0) { + ret.card_n = last_card_n; + ret.card = ret.cards[last_card_n]; + ret.items_n = this.items.indexOf(ret.cards[last_card_n]); + ret.position = 'below'; } - if (ctarget < 0) { - ctarget = cards.length -1; - cpos = 'below'; - } - if (cards[ctarget].el == dragged_card_el) { + if (this.items[ret.items_n].el == dragged_card_el) { return false; } - if (cpos == 'below') { - var card_after = ctarget+1 == cards.length ? false : cards[ctarget+1]; - - // then above should not be dragged_card_el. - // and ctarget sho + if (ret.position == 'below') { + var card_after = ret.card_n+1 == ret.cards.length ? false : ret.cards[ret.card_n+1]; if (card_after && card_after.el == dragged_card_el) { return false; } - return [ cards[ctarget], cpos ]; + return ret; } // its's after .. - var card_before = ctarget > 0 ? cards[ctarget-1] : false; + var card_before = ret.card_n > 0 ? ret.cards[ret.card_n-1] : false; - if (card_before && card_before.el == dragged_card_el) { return false; } - return [ cards[ctarget], cpos, cards, ctarget ]; + return ret; }, onNodeEnter : function(n, dd, e, data){ @@ -2335,9 +2516,13 @@ Roo.extend(Roo.bootstrap.Card, Roo.bootstrap.Component, { this.dropPlaceHolder('hide'); return false; } - Roo.log(['getTargetFromEvent', target_info[0].el.dom.id,target_info[1]]); + Roo.log(['getTargetFromEvent', target_info ]); + + + if (this.fireEvent('cardover', this, [ data ]) === false) { + return false; + } - this.dropPlaceHolder('show', target_info,data); return false; @@ -2349,39 +2534,110 @@ Roo.extend(Roo.bootstrap.Card, Roo.bootstrap.Component, { onNodeDrop : function(n, dd, e, data) { - // call drop - return false if - if (this.fireEvent("drop", this, n, dd, e, data) === false) { + // call drop - return false if + + // this could actually fail - if the Network drops.. + // we will ignore this at present..- client should probably reload + // the whole set of cards if stuff like that fails. + + + var info = this.getTargetFromEvent(e,data.source.el); + if (info === false) { return false; } - - var target_info = this.getTargetFromEvent(e,data.source.el); - if (target_info === false) { + this.dropPlaceHolder('hide'); + + + + this.acceptCard(data.source, info.position, info.card, info.items_n); + return true; + + }, + firstChildCard : function() + { + for (var i = 0;i< this.items.length;i++) { + + if (!this.items[i].el.hasClass('card')) { + continue; + } + return this.items[i]; + } + return this.items.length ? this.items[this.items.length-1] : false; // don't try and put stuff after the cards... + }, + /** + * accept card + * + * - card.acceptCard(move_card, info.position, info.card, info.items_n); + */ + acceptCard : function(move_card, position, next_to_card ) + { + if (this.fireEvent("drop", this, move_card, position, next_to_card) === false) { return false; } - var pt = this.getDropPoint(e, n, dd); - var insertAt = (n == this.bodyEl.dom) ? this.items.length : n.nodeIndex; - if (pt == "below") { - insertAt++; - } - for (var i = 0; i < this.items.length; i++) { - var r = this.items[i]; - //var dup = this.store.getById(r.id); - if (dup && (dd != this.dragZone)) { - Roo.fly(this.getNode(this.store.indexOf(dup))).frame("red", 1); - } else { - if (data.copy) { - this.store.insert(insertAt++, r.copy()); + var to_items_n = next_to_card ? this.items.indexOf(next_to_card) : 0; + + move_card.parent().removeCard(move_card); + + + var dom = move_card.el.dom; + dom.style.width = ''; // clear with - which is set by drag. + + if (next_to_card !== false && next_to_card !== true && next_to_card.el.dom.parentNode) { + var cardel = next_to_card.el.dom; + + if (position == 'above' ) { + cardel.parentNode.insertBefore(dom, cardel); + } else if (cardel.nextSibling) { + cardel.parentNode.insertBefore(dom,cardel.nextSibling); } else { - data.source.isDirtyFlag = true; - r.store.remove(r); - this.store.insert(insertAt++, r); + cardel.parentNode.append(dom); } - this.isDirtyFlag = true; + } else { + // card container??? + this.containerEl.dom.append(dom); + } + + //FIXME HANDLE card = true + + // add this to the correct place in items. + + // remove Card from items. + + + if (this.items.length) { + var nitems = []; + //Roo.log([info.items_n, info.position, this.items.length]); + for (var i =0; i < this.items.length; i++) { + if (i == to_items_n && position == 'above') { + nitems.push(move_card); + } + nitems.push(this.items[i]); + if (i == to_items_n && position == 'below') { + nitems.push(move_card); + } } + this.items = nitems; + Roo.log(this.items); + } else { + this.items.push(move_card); } - this.dragZone.cachedTarget = null; + + move_card.parentId = this.id; + return true; + + + }, + removeCard : function(c) + { + this.items = this.items.filter(function(e) { return e != c }); + + var dom = c.el.dom; + dom.parentNode.removeChild(dom); + dom.style.width = ''; // clear with - which is set by drag. + c.parentId = false; + }, /** Decide whether to drop above or below a View node. */ @@ -2390,7 +2646,7 @@ Roo.extend(Roo.bootstrap.Card, Roo.bootstrap.Component, { if (dd) { return false; } - if (n == this.bodyEl.dom) { + if (n == this.containerEl.dom) { return "above"; } var t = Roo.lib.Dom.getY(n), b = t + n.offsetHeight; @@ -2406,20 +2662,43 @@ Roo.extend(Roo.bootstrap.Card, Roo.bootstrap.Component, { { if (this.collapsed) { this.el.select('.roo-collapse-toggle').removeClass('collapsed'); - this.el.select('.roo-collapsable').addClass('show'); + this.collapsableEl.addClass('show'); this.collapsed = false; return; } this.el.select('.roo-collapse-toggle').addClass('collapsed'); - this.el.select('.roo-collapsable').removeClass('show'); + this.collapsableEl.removeClass('show'); this.collapsed = true; }, - dropPlaceHolder: function (action, where_ar, data) + + onToggleRotate : function(e) + { + this.collapsableEl.removeClass('show'); + this.footerEl.removeClass('d-none'); + this.el.removeClass('roo-card-rotated'); + this.el.removeClass('d-none'); + if (this.rotated) { + + this.collapsableEl.addClass('show'); + this.rotated = false; + this.fireEvent('rotate', this, this.rotated); + return; + } + this.el.addClass('roo-card-rotated'); + this.footerEl.addClass('d-none'); + this.el.select('.roo-collapsable').removeClass('show'); + + this.rotated = true; + this.fireEvent('rotate', this, this.rotated); + + }, + + dropPlaceHolder: function (action, info, data) { if (this.dropEl === false) { - this.dropEl = Roo.DomHelper.append(this.bodyEl, { + this.dropEl = Roo.DomHelper.append(this.containerEl, { cls : 'd-none' },true); } @@ -2429,16 +2708,24 @@ Roo.extend(Roo.bootstrap.Card, Roo.bootstrap.Component, { this.dropEl.addClass('d-none'); return; } - var cardel = where_ar[0].el.dom; - + // FIXME - info.card == true!!! this.dropEl.dom.parentNode.removeChild(this.dropEl.dom); - if (where_ar[1] == 'above') { - cardel.parentNode.insertBefore(this.dropEl.dom, cardel); - } else if (cardel.nextSibling) { - cardel.parentNode.insertBefore(this.dropEl.dom,cardel.nextSibling); + + if (info.card !== true) { + var cardel = info.card.el.dom; + + if (info.position == 'above') { + cardel.parentNode.insertBefore(this.dropEl.dom, cardel); + } else if (cardel.nextSibling) { + cardel.parentNode.insertBefore(this.dropEl.dom,cardel.nextSibling); + } else { + cardel.parentNode.append(this.dropEl.dom); + } } else { - cardel.parentNode.append(this.dropEl.dom); + // card container??? + this.containerEl.dom.append(this.dropEl.dom); } + this.dropEl.addClass('d-block roo-card-dropzone'); this.dropEl.setHeight( Roo.get(data.ddel).getHeight() ); @@ -2447,6 +2734,34 @@ Roo.extend(Roo.bootstrap.Card, Roo.bootstrap.Component, { + }, + setHeaderText: function(html) + { + this.header = html; + if (this.headerContainerEl) { + this.headerContainerEl.dom.innerHTML = html; + } + }, + onHeaderImageLoad : function(ev, he) + { + if (!this.header_image_fit_square) { + return; + } + + var hw = he.naturalHeight / he.naturalWidth; + // wide image = < 0 + // tall image = > 1 + //var w = he.dom.naturalWidth; + var ww = he.width; + he.style.left = 0; + he.style.position = 'relative'; + if (hw > 1) { + var nw = (ww * (1/hw)); + Roo.get(he).setSize( ww * (1/hw), ww); + he.style.left = ((ww - nw)/ 2) + 'px'; + he.style.position = 'relative'; + } + } @@ -2462,6 +2777,8 @@ Roo.extend(Roo.bootstrap.Card, Roo.bootstrap.Component, { /** * @class Roo.bootstrap.CardHeader * @extends Roo.bootstrap.Element + * @parent Roo.bootstrap.Card + * @children Roo.bootstrap.Component * Bootstrap CardHeader class * @constructor * Create a new Card Header - that you can embed children into @@ -2481,6 +2798,42 @@ Roo.extend(Roo.bootstrap.CardHeader, Roo.bootstrap.Element, { +}); + + + + /* + * - LGPL + * + * Card footer - holder for the card footer elements. + * + */ + +/** + * @class Roo.bootstrap.CardFooter + * @extends Roo.bootstrap.Element + * @parent Roo.bootstrap.Card + * @children Roo.bootstrap.Component + * Bootstrap CardFooter class + * + * @constructor + * Create a new Card Footer - that you can embed children into + * @param {Object} config The config object + */ + +Roo.bootstrap.CardFooter = function(config){ + Roo.bootstrap.CardFooter.superclass.constructor.call(this, config); +}; + +Roo.extend(Roo.bootstrap.CardFooter, Roo.bootstrap.Element, { + + + container_method : 'getCardFooter' + + + + + }); @@ -2495,7 +2848,10 @@ Roo.extend(Roo.bootstrap.CardHeader, Roo.bootstrap.Element, { /** * @class Roo.bootstrap.CardImageTop * @extends Roo.bootstrap.Element + * @parent Roo.bootstrap.Card + * @children Roo.bootstrap.Component * Bootstrap CardImageTop class + * * @constructor * Create a new Card Image Top container * @param {Object} config The config object @@ -2517,6 +2873,172 @@ Roo.extend(Roo.bootstrap.CardImageTop, Roo.bootstrap.Element, { + +/* +* Licence: LGPL +*/ + +/** + * @class Roo.bootstrap.ButtonUploader + * @extends Roo.bootstrap.Button + * Bootstrap Button Uploader class - it's a button which when you add files to it + * + * + * @cfg {Number} errorTimeout default 3000 + * @cfg {Array} images an array of ?? Img objects ??? when loading existing files.. + * @cfg {Array} html The button text. + * @cfg {Boolean} multiple (default true) Should the upload allow multiple files to be uploaded. + * + * @constructor + * Create a new CardUploader + * @param {Object} config The config object + */ + +Roo.bootstrap.ButtonUploader = function(config){ + + + + Roo.bootstrap.ButtonUploader.superclass.constructor.call(this, config); + + + this.addEvents({ + // raw events + /** + * @event beforeselect + * When button is pressed, before show upload files dialog is shown + * @param {Roo.bootstrap.UploaderButton} this + * + */ + 'beforeselect' : true, + /** + * @event fired when files have been selected, + * When a the download link is clicked + * @param {Roo.bootstrap.UploaderButton} this + * @param {Array} Array of files that have been uploaded + */ + 'uploaded' : true + + }); +}; + +Roo.extend(Roo.bootstrap.ButtonUploader, Roo.bootstrap.Button, { + + + errorTimeout : 3000, + + images : false, + + fileCollection : false, + allowBlank : true, + + multiple : true, + + getAutoCreate : function() + { + + + return { + cls :'div' , + cn : [ + Roo.bootstrap.Button.prototype.getAutoCreate.call(this) + ] + }; + + + }, + + + initEvents : function() + { + + Roo.bootstrap.Button.prototype.initEvents.call(this); + + + + + + this.urlAPI = (window.createObjectURL && window) || + (window.URL && URL.revokeObjectURL && URL) || + (window.webkitURL && webkitURL); + + var im = { + tag: 'input', + type : 'file', + cls : 'd-none roo-card-upload-selector' + + }; + if (this.multiple) { + im.multiple = 'multiple'; + } + this.selectorEl = Roo.get(document.body).createChild(im); // so it does not capture click event for navitem. + + //this.selectorEl = this.el.select('.roo-card-upload-selector', true).first(); + + this.selectorEl.on('change', this.onFileSelected, this); + + + + }, + + + onClick : function(e) + { + e.preventDefault(); + + if ( this.fireEvent('beforeselect', this) === false) { + return; + } + + this.selectorEl.dom.click(); + + }, + + onFileSelected : function(e) + { + e.preventDefault(); + + if(typeof(this.selectorEl.dom.files) == 'undefined' || !this.selectorEl.dom.files.length){ + return; + } + var files = Array.prototype.slice.call(this.selectorEl.dom.files); + this.selectorEl.dom.value = '';// hopefully reset.. + + this.fireEvent('uploaded', this, files ); + + }, + + + + + /** + * addCard - add an Attachment to the uploader + * @param data - the data about the image to upload + * + * { + id : 123 + title : "Title of file", + is_uploaded : false, + src : "http://.....", + srcfile : { the File upload object }, + mimetype : file.type, + preview : false, + is_deleted : 0 + .. any other data... + } + * + * + */ + + reset: function() + { + + this.selectorEl + } + + + + +}); /* * - LGPL * @@ -2539,6 +3061,7 @@ Roo.extend(Roo.bootstrap.CardImageTop, Roo.bootstrap.Element, { * @cfg {String} smUrl sm image source * @cfg {String} mdUrl md image source * @cfg {String} lgUrl lg image source + * @cfg {Boolean} backgroundContain (use style background and contain image in content) * * @constructor * Create a new Input @@ -2555,7 +3078,13 @@ Roo.bootstrap.Img = function(config){ * The img click event for the img. * @param {Roo.EventObject} e */ - "click" : true + "click" : true, + /** + * @event load + * The when any image loads + * @param {Roo.EventObject} e + */ + "load" : true }); }; @@ -2570,6 +3099,7 @@ Roo.extend(Roo.bootstrap.Img, Roo.bootstrap.Component, { smUrl: '', mdUrl: '', lgUrl: '', + backgroundContain : false, getAutoCreate : function() { @@ -2642,12 +3172,20 @@ Roo.extend(Roo.bootstrap.Img, Roo.bootstrap.Component, { tag: 'img', cls: (this.imgResponsive) ? 'img-responsive' : '', html : null, - src : 'about:blank' // just incase src get's set to undefined?!? + src : Roo.BLANK_IMAGE_URL // just incase src get's set to undefined?!? }; + if (this.backgroundContain) { + cfg.cls += ' background-contain'; + } + cfg.html = this.html || cfg.html; - cfg.src = this.src || cfg.src; + if (this.backgroundContain) { + cfg.style="background-image: url(" + this.src + ')'; + } else { + cfg.src = this.src || cfg.src; + } if (['rounded','circle','thumbnail'].indexOf(this.border)>-1) { cfg.cls += ' img-' + this.border; @@ -2680,6 +3218,12 @@ Roo.extend(Roo.bootstrap.Img, Roo.bootstrap.Component, { if(!this.href){ this.el.on('click', this.onClick, this); } + if(this.src || (!this.xsUrl && !this.smUrl && !this.mdUrl && !this.lgUrl)){ + this.el.on('load', this.onImageLoad, this); + } else { + // not sure if this works.. not tested + this.el.select('img', true).on('load', this.onImageLoad, this); + } }, @@ -2688,6 +3232,12 @@ Roo.extend(Roo.bootstrap.Img, Roo.bootstrap.Component, { Roo.log('img onclick'); this.fireEvent('click', this, e); }, + onImageLoad: function(e) + { + Roo.log('img load'); + this.fireEvent('load', this, e); + }, + /** * Sets the url of the image - used to update it * @param {String} url the url of the image @@ -2698,7 +3248,11 @@ Roo.extend(Roo.bootstrap.Img, Roo.bootstrap.Component, { this.src = url; if(this.src || (!this.xsUrl && !this.smUrl && !this.mdUrl && !this.lgUrl)){ - this.el.dom.src = url; + if (this.backgroundContain) { + this.el.dom.style.backgroundImage = 'url(' + url + ')'; + } else { + this.el.dom.src = url; + } return; } @@ -2720,7 +3274,9 @@ Roo.extend(Roo.bootstrap.Img, Roo.bootstrap.Component, { /** * @class Roo.bootstrap.Link * @extends Roo.bootstrap.Component - * Bootstrap Link Class + * @children Roo.bootstrap.Component + * Bootstrap Link Class (eg. '') + * @cfg {String} alt image alternative text * @cfg {String} href a tag href * @cfg {String} target (_self|_blank|_parent|_top) target for a href. @@ -2824,7 +3380,10 @@ Roo.extend(Roo.bootstrap.Link, Roo.bootstrap.Component, { /** * @class Roo.bootstrap.Header * @extends Roo.bootstrap.Component + * @children Roo.bootstrap.Component * Bootstrap Header class + * + * * @cfg {String} html content of header * @cfg {Number} level (1|2|3|4|5|6) default 1 * @@ -2862,23 +3421,13 @@ Roo.extend(Roo.bootstrap.Header, Roo.bootstrap.Component, { - /* - * Based on: - * Ext JS Library 1.1.1 - * Copyright(c) 2006-2007, Ext JS, LLC. - * - * Originally Released Under LGPL - original licence link has changed is not relivant. - * - * Fork - LGPL - *