I’ve been getting a ton of emails lately about the persistent issues with Bootstrap.js dropdowns, accordions, or other JavaScript based Bootstrap components in Fuji. This is caused by Prototype.js (not really a big surprise). This issue has existed as long a CMS has been around, however what is specific to Fuji is that all the usual tricks and workarounds have stopped working. Previously I released a couple workaround but they were not complete and issues remained.
I think I finally have a solution that seems to work and I have yet to find a case where it does not. The solution is to replace Bootstrap.js (which relies on jQuery) with “Bootstrap Prototype” which is available here: https://github.com/jwestbrook/bootstrap-prototype
You can still include jQuery (with noConflict()) and use as needed, but this will get all your drop down menus and Bootstrap components working with Prototype.
HTML:
1 2 3 4 5 6 7 | <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/> <nav>Bootstrap menu goes here</nav> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> <script> var $j = jQuery.noConflict(); </script> <script src="/prototype-bootstrap.jsdbx"></script> |
UI Script: (name: “prototype-bootstrap”)
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 | /* =========================================================== * bootstrap_prototype.js v2.3.2 * http://twitter.github.com/bootstrap/javascript.html * =========================================================== * Copyright 2012 Twitter, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ========================================================== */ /* Modified for use with PrototypeJS http://github.com/jwestbrook/bootstrap-prototype */ /* BUILD TIME Sat May 03 2014 08:07:36 GMT-0700 (PDT) */ "use strict"; var BootStrap={transitionendevent:null,handleeffects:null},transEndEventNames=$H({WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"}),el=new Element("bootstrap");transEndEventNames.each(function(a){void 0!==el.style[a.key]&&(BootStrap.transitionendevent=a.value,BootStrap.handleeffects="css")});null===BootStrap.handleeffects&&"undefined"!==typeof Effect&&(BootStrap.handleeffects="effect"); BootStrap.Affix=Class.create({initialize:function(a,b){this.$element=$(a);this.$element.store("bootstrap:affix",this);this.options={offset:0};Object.extend(this.options,b);Event.observe(window,"scroll",this.checkPosition.bind(this));Event.observe(window,"click",function(){setTimeout(this.checkPosition.bind(this),1)}.bind(this));this.checkPosition()},checkPosition:function(){if(this.$element.visible()){var a=document.height,b=window.pageYOffset||document.documentElement.scrollTop,c=this.$element.positionedOffset(), d=this.options.offset,e=d.bottom,f=d.top;"object"!=typeof d&&(e=f=d);"function"==typeof f&&(f=d.top());"function"==typeof e&&(e=d.bottom());a=null!=this.unpin&&b+this.unpin<=c.top?!1:null!=e&&c.top+this.$element.getHeight()>=a-e?"bottom":null!=f&&b<=f?"top":!1;this.affixed!==a&&(this.affixed=a,this.unpin="bottom"==a?c.top-b:null,this.$element.removeClassName("affix affix-top affix-bottom").addClassName("affix"+(a?"-"+a:"")))}}}); Event.observe(window,"load",function(){$$('[data-spy="affix"]').each(function(a){var b={};b.offset=a.hasAttribute("data-offset")?a.readAttribute("data-offset"):{};a.hasAttribute("data-offset-bottom")?b.offset.bottom=a.readAttribute("data-offset-bottom"):"";a.hasAttribute("data-offset-top")?b.offset.top=a.readAttribute("data-offset-top"):"";new BootStrap.Affix(a,b)})}); BootStrap.Alert=Class.create({initialize:function(a){a.store("bootstrap:alert",this);$(a).observe("click",this.close)},close:function(a){function b(){d.fire("bootstrap:closed");d.remove()}a=$(this);var c=a.readAttribute("data-target"),d;c||(c=(c=a.href)&&c.replace(/.*(?=#[^\s]*$)/,"").replace("#",""));void 0!==c&&0<c.length?d=$(c):"";void 0!==d&&d.length||(d=a.hasClassName("alert")?a:a.up());d.fire("bootstrap:close").defaultPrevented||("css"===BootStrap.handleeffects&&d.hasClassName("fade")?(d.observe(BootStrap.transitionendevent, function(){b()}),d.removeClassName("in")):"effect"===BootStrap.handleeffects&&d.hasClassName("fade")?new Effect.Fade(d,{duration:0.3,from:1*d.getOpacity(),afterFinish:function(){d.removeClassName("in");b()}}):b())}}); BootStrap.Button=Class.create({initialize:function(a,b){a.store("bootstrap:button",this);this.$element=$(a);"object"==typeof b?(this.options=b,this.options.loadingText="undefined"!=typeof this.options.loadingText?b.loadingText:""):"undefined"!=typeof b&&"toggle"==b?this.toggle():"undefined"!=typeof b&&this.setState(b)},setState:function(a){var b=this.$element,c="input"==b.readAttribute("type")?"value":"innerHTML";a+="Text";b.readAttribute("data-reset-text")||b.writeAttribute("data-reset-text",b[c]); b[c]=b.readAttribute("data-"+a.underscore().dasherize())||this.options&&this.options[a]||"";setTimeout(function(){"loadingText"==a?b.addClassName("disabled").writeAttribute("disabled",!0):b.removeClassName("disabled").writeAttribute("disabled",!1)},0)},toggle:function(){var a=this.$element.up('[data-toggle="buttons-radio"]');a&&a.select(".active").invoke("removeClassName","active");this.$element.toggleClassName("active")}}); BootStrap.Carousel=Class.create({initialize:function(a,b){this.options={interval:5E3,pause:"hover"};this.$element=$(a);this.options.interval=this.$element.hasAttribute("data-interval")?this.$element.readAttribute("data-interval"):this.options.interval;a.store("bootstrap:carousel",this);this.$indicators=this.$element.down(".carousel-indicators");Object.extend(this.options,b);this.options.slide&&this.slide(this.options.slide);"hover"==this.options.pause&&this.$element.on("mouseenter",this.pause.bind(this))&& this.$element.on("mouseleave",this.cycle.bind(this));this.options.interval&&this.cycle()},cycle:function(a){a||(this.paused=!1);this.options.interval&&!this.paused&&(this.interval=setInterval(this.next.bind(this),this.options.interval));return this},getActiveIndex:function(){this.$active=this.$element.down(".item.active");this.$items=this.$active.up().childElements();return this.$items.indexOf(this.$active)},to:function(a){var b=this.$element.down(".item.active"),c=b.up().childElements(),b=c.indexOf(b); if(!(a>c.length-1||0>a))return this.sliding?this.$element.on("bootstrap:slid",function(){this.to(a)}.bind(this)):b==a?this.pause().cycle():this.slide(a>b?"next":"previous",$(c[a]))},pause:function(a){a||(this.paused=!0);this.$element.select(".next, .prev").length&&"css"==BootStrap.handleeffects&&(this.$element.fire(BootStrap.transitionendevent),this.cycle());clearInterval(this.interval);this.interval=null;return this},next:function(){if(!this.sliding)return this.slide("next")},prev:function(){if(!this.sliding)return this.slide("previous")}, slide:function(a,b){var c=this.$element.down(".item.active"),d=b||c[a](),e=this.interval,f="next"==a?"left":"right",g="next"==a?"first":"last";this.sliding=!0;e&&this.pause();d=void 0!==d?d:this.$element.select(".item")[g]();a="previous"==a?"prev":a;if(!d.hasClassName("active")){this.$indicators&&(this.$indicators.down(".active").removeClassName("active"),this.$element.on("bootstrap:slid",function(){var a=$(this.$indicators.childElements()[this.getActiveIndex()]);a&&a.addClassName("active");this.$element.stopObserving("bootstrap:slid")}.bind(this))); if("css"==BootStrap.handleeffects&&this.$element.hasClassName("slide")){g=this.$element.fire("bootstrap:slide");if(g.defaultPrevented)return;this.$element.on(BootStrap.transitionendevent,function(b){d.removeClassName([a,f].join(" ")).addClassName("active");c.removeClassName(["active",f].join(" "));this.sliding=!1;setTimeout(function(){this.$element.fire("bootstrap:slid")}.bind(this),0);e&&this.cycle();this.$element.stopObserving(BootStrap.transitionendevent)}.bind(this));d.addClassName(a);d.offsetWidth; c.addClassName(f);d.addClassName(f)}else if("effect"==BootStrap.handleeffects&&"undefined"!==typeof Effect&&"undefined"!==typeof Effect.Morph)new Effect.Parallel([new Effect.Morph(d,{sync:!0,style:"left:0%;"}),new Effect.Morph(c,{sync:!0,style:"left:"+("left"==f?"-":"")+"100%;"})],{duration:0.6,beforeSetup:function(b){d.addClassName(a);this.sliding=!0}.bind(this),afterFinish:function(b){d.removeClassName(a).addClassName("active");c.removeClassName("active");d.style[f]=null;c.style[f]=null;this.sliding= !1;this.$element.fire("bootstrap:slid");e&&this.cycle()}.bind(this)});else{g=this.$element.fire("bootstrap:slide");if(g.defaultPrevented)return;c.removeClassName("active");d.addClassName("active");this.sliding=!1;this.$element.fire("bootstrap:slid");e&&this.cycle()}return this}}}); BootStrap.Collapse=Class.create({initialize:function(a,b){this.$element=$(a);a.store("bootstrap:collapse",this);this.options={toggle:!0};Object.extend(this.options,b);this.options.parent&&(this.$parent=$(this.options.parent));var c=this.dimension();"auto"===this.$element.style[c]&&(c=["scroll",c].join("-").camelize(),this.reset(this.$element[c]+"px"));this.options.toggle&&this.toggle()},dimension:function(){return this.$element.hasClassName("width")?"width":"height"},show:function(){var a,b,c;if(!this.transitioning){a= this.dimension();b=["scroll",a].join("-").camelize();(c=this.$parent&&this.$parent.select("> .accordion-group > .in"))&&c.length&&c.each(function(a){(a=a.retrieve("bootstrap:collapse"))&&a.transitioning||a.hide()});var d={};d[a]="0px";this.$element.setStyle(d);this.transition("addClassName","show","bootstrap:shown");"css"==BootStrap.handleeffects?(d={},d[a]=this.$element[b]+"px",this.$element.setStyle(d)):"effect"==BootStrap.handleeffects&&("undefined"!==typeof Effect&&"undefined"!==typeof Effect.BlindDown)&& this.$element.blindDown({duration:0.5,afterFinish:function(c){d={};d[a]=this.$element[b]+"px";this.$element.setStyle(d)}.bind(this)})}},hide:function(){var a;if(!this.transitioning&&(a=this.dimension(),this.reset(this.$element.getStyle(a)),this.transition("removeClassName","hide","bootstrap:hidden"),this.reset("0px"),"effect"==BootStrap.handleeffects&&"undefined"!==typeof Effect&&0===Effect.Queues.get("global").effects.length)){var b={};b[a]="0px";this.$element.setStyle(b)}},reset:function(a){var b= this.dimension();this.$element.removeClassName("collapse");var c={};c[b]=a;this.$element.setStyle(c);this.$element[null!==a?"addClassName":"removeClassName"]("collapse");return this},transition:function(a,b,c){var d=function(){"show"==b&&this.reset();this.transitioning=0;this.$element.fire(c)}.bind(this);this.$element.fire("bootstrap:"+b).defaultPrevented||(this.transitioning=1,"css"==BootStrap.handleeffects&&this.$element.hasClassName("collapse")?(this.$element.observe(BootStrap.transitionendevent, d),this.$element[a]("in")):"hide"==b&&"effect"==BootStrap.handleeffects&&"undefined"!==typeof Effect&&"undefined"!==typeof Effect.BlindUp?this.$element.blindUp({duration:0.5,afterFinish:function(b){var c=this.dimension();b.element[a]("in");b={};b[c]="0px";this.$element.setStyle(b);d()}.bind(this)}):"show"==b&&"effect"==BootStrap.handleeffects&&"undefined"!==typeof Effect&&"undefined"!==typeof Effect.BlindUp?this.$element.blindDown({duration:0.5,beforeStart:function(b){var c=this.dimension();b.element[a]("in"); var d={};d[c]="auto";this.$element.setStyle(d);b.element.hide()}.bind(this),afterFinish:function(a){d()}.bind(this)}):(d(),this.$element[a]("in")))},toggle:function(){this[this.$element.hasClassName("in")?"hide":"show"]()}}); BootStrap.Dropdown=Class.create({initialize:function(a){a.store("bootstrap:dropdown",this);var b=$(a).on("click",this.toggle);$$("html")[0].on("click",function(){b.up().removeClassName("open")})},toggle:function(a){var b=$(this),c,d;b.hasClassName("disabled")||"disabled"==b.readAttribute("disabled")||(c=BootStrap.Dropdown.prototype.getParent(b),d=c.hasClassName("open"),BootStrap.Dropdown.prototype.clearMenus(),d||("ontouchstart"in document.documentElement&&(d=new Element("div",{"class":"dropdown-backdrop"}), d.observe("click",BootStrap.Dropdown.prototype.clearMenus),b.insert({before:d})),c.toggleClassName("open")),b.focus(),a.stop())},keydown:function(a){var b,c,d,e;if(/(38|40|27)/.test(a.keyCode)&&(b=$(this),a.preventDefault(),a.stopPropagation(),!b.hasClassName("disabled")&&"disabled"!=b.readAttribute("disabled"))){c=BootStrap.Dropdown.prototype.getParent(b);d=c.hasClassName("open");if(!d||d&&a.keyCode==Event.KEY_ESC)return a.which==Event.KEY_ESC&&c.select("[data-toggle=dropdown]")[0].focus(),b.click(); b=c.select("[role=menu] li:not(.divider) a");b.length&&(e=-1,b.each(function(a,b){a.match(":focus")?e=b:""}),a.keyCode==Event.KEY_UP&&0<e&&e--,a.keyCode==Event.KEY_DOWN&&e<b.length-1&&e++,~e||(e=0),b[e].focus())}},clearMenus:function(){$$(".dropdown-backdrop").invoke("remove");$$("[data-toggle=dropdown]").each(function(a){BootStrap.Dropdown.prototype.getParent(a).removeClassName("open")})},getParent:function(a){var b=a.readAttribute("data-target");b||(b=(b=a.readAttribute("href"))&&/#/.test(b)&&b.replace(/.*(?=#[^\s]*$)/, "")&&"#"!=b);(b=b&&$$(b))&&b.length||(b=a.up());return b}}); BootStrap.Modal=Class.create({initialize:function(a,b){a.store("bootstrap:modal",this);this.$element=$(a);this.options=void 0!==b?b:{};this.options.backdrop=void 0!==this.options.backdrop?b.backdrop:!0;this.options.keyboard=void 0!==this.options.keyboard?b.keyboard:!0;this.options.show=void 0!==this.options.show?b.show:!0;this.options.show&&this.show();$$("[data-dismiss='modal']").invoke("observe","click",function(){this.hide()}.bind(this));this.options.remote&&this.$element.select(".modal-body")&& new Ajax.Updater(this.$element.select(".modal-body")[0],this.options.remote)},toggle:function(){return this[this.isShown?"hide":"show"]()},show:function(a){var b=this;this.$element.setStyle({display:"block"});a=this.$element.fire("bootstrap:show");this.isShown||a.defaultPrevented||(this.isShown=!0,this.escape(),this.backdrop(function(){var a=("css"==BootStrap.handleeffects||"effect"==BootStrap.handleeffects&&"undefined"!==typeof Effect&&"undefined"!==typeof Effect.Fade)&&b.$element.hasClassName("fade"); void 0===b.$element.up("body")&&$$("body")[0].insert(b.$element);b.$element.setStyle({display:"block"});a&&"css"==BootStrap.handleeffects?(b.$element.observe(BootStrap.transitionendevent,function(){b.$element.fire("bootstrap:shown")}),setTimeout(function(){b.$element.addClassName("in").writeAttribute("aria-hidden",!1)},1)):a&&"effect"==BootStrap.handleeffects?new Effect.Parallel([new Effect.Morph(b.$element,{sync:!0,style:"top:10%"}),new Effect.Opacity(b.$element,{sync:!0,from:0,to:1})],{duration:0.3, afterFinish:function(){b.$element.addClassName("in").writeAttribute("aria-hidden",!1);b.$element.fire("bootstrap:shown")}}):b.$element.addClassName("in").writeAttribute("aria-hidden",!1).fire("bootstrap:shown");b.enforceFocus()}))},hide:function(a){a=this.$element.fire("bootstrap:hide");this.isShown&&!a.defaultPrevented&&(this.isShown=!1,this.escape(),"css"==BootStrap.handleeffects&&this.$element.hasClassName("fade")?this.hideWithTransition():"effect"==BootStrap.handleeffects&&"undefined"!==typeof Effect&& "undefined"!==typeof Effect.Fade&&this.$element.hasClassName("fade")?this.hideWithTransition():(this.hideModal(),this.$element.setStyle({display:""})))},enforceFocus:function(){var a=this;$(document).on("focus",function(b){a.$element[0]===b.target||a.$element.has(b.target).length||a.$element.focus()})},escape:function(){var a=this;if(this.isShown&&this.options.keyboard)$(document).on("keyup",function(b){b.which==Event.KEY_ESC&&a.hide()});else this.isShown||$(document).stopObserving("keyup")},hideWithTransition:function(){var a= this;"css"==BootStrap.handleeffects?(this.$element.observe(BootStrap.transitionendevent,function(){this.setStyle({display:""});this.setStyle({top:""});a.hideModal();this.stopObserving(BootStrap.transitionendevent)}),setTimeout(function(){this.$element.removeClassName("in").writeAttribute("aria-hidden",!0)}.bind(this))):new Effect.Morph(this.$element,{duration:0.3,style:"top:-25%;",afterFinish:function(b){b.element.removeClassName("in").writeAttribute("aria-hidden",!0);b.element.setStyle({display:""}); b.element.setStyle({top:""});a.hideModal()}})},hideModal:function(){this.$element.hide();this.backdrop(function(){this.removeBackdrop();this.$element.fire("bootstrap:hidden")}.bind(this))},removeBackdrop:function(){this.$backdrop&&this.$backdrop.remove();this.$backdrop=null},backdrop:function(a){var b=this,c=this.$element.hasClassName("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var d=("css"==BootStrap.handleeffects||"effect"==BootStrap.handleeffects&&"undefined"!==typeof Effect&&"undefined"!== typeof Effect.Fade)&&c;this.$backdrop=new Element("div",{"class":"modal-backdrop "+c});d&&"css"==BootStrap.handleeffects?this.$backdrop.observe(BootStrap.transitionendevent,function(){a();this.stopObserving(BootStrap.transitionendevent)}):d&&"effect"==BootStrap.handleeffects&&this.$backdrop.setOpacity(0);this.$backdrop.observe("click",function(){"static"==b.options.backdrop?"":b.hide()});$$("body")[0].insert(this.$backdrop);d&&"effect"==BootStrap.handleeffects?new Effect.Appear(this.$backdrop,{from:0, to:0.8,duration:0.3,afterFinish:a}):a();setTimeout(function(){$$("modal-backdrop").invoke("addClassName","in")},1)}else!this.isShown&&this.$backdrop?c&&"css"==BootStrap.handleeffects?(b.$backdrop.observe(BootStrap.transitionendevent,function(){a()}),setTimeout(function(){b.$backdrop.removeClassName("in")},1)):c&&"effect"==BootStrap.handleeffects&&"undefined"!==typeof Effect&&"undefined"!==typeof Effect.Fade?new Effect.Fade(b.$backdrop,{duration:0.3,from:1*b.$backdrop.getOpacity(),afterFinish:function(){b.$backdrop.removeClassName("in"); a()}}):(b.$backdrop.removeClassName("in"),a()):a&&a()}}); BootStrap.Tooltip=Class.create({initialize:function(a,b){a.store("bootstrap:tooltip",this);this.options={animation:!0,placement:a.hasAttribute("data-placement")?a.readAttribute("data-placement"):"top",selector:!1,template:(new Element("div",{"class":"tooltip"})).insert(new Element("div",{"class":"tooltip-arrow"})).insert(new Element("div",{"class":"tooltip-inner"})),trigger:"hover focus",title:"",delay:0,html:!1,container:!1};Object.extend(this.options,b);"string"==typeof this.options.container&& (this.options.container=$$(this.options.container).first());"string"==typeof this.options.template&&(this.options.template=(new Element("div")).update(this.options.template).down());this.options.delay&&"number"==typeof this.options.delay&&(this.options.delay={show:b.delay,hide:b.delay});void 0===this.options.subclass&&this.init("tooltip",a)},init:function(a,b){var c,d;this.type=a;this.$element=$(b);this.enabled=!0;this.options.trigger.split(" ").each(function(a){if("click"==a&&this.options.selector)this.$element.on("click", this.options.selector,this.toggle.bind(this));else"click"==a?this.$element.observe("click",this.toggle.bind(this)):"manual"!=a&&(c="hover"==a?"mouseenter":"focus",d="hover"==a?"mouseleave":"blur",this.$element.observe(c,this.enter.bind(this)),this.$element.observe(d,this.leave.bind(this)))},this);this.options.selector&&(this.$element=this.$element.down(this.options.selector),this.$element.store("bootstrap:tooltip",this));this.fixTitle()},enter:function(a){var b;this._options&&$H(this._options).each(function(a){}.bind(this)); b=this;if(!b.options.delay||!b.options.delay.show)return b.show();clearTimeout(this.timeout);b.hoverState="in";this.timeout=setTimeout(function(){"in"==b.hoverState&&b.show()},b.options.delay.show)},leave:function(a){var b=this;this.timeout&&clearTimeout(this.timeout);if(!b.options.delay||!b.options.delay.hide)return b.hide();b.hoverState="out";this.timeout=setTimeout(function(){"out"==b.hoverState&&b.hide()},b.options.delay.hide)},show:function(){var a,b,c,d,e;if(this.hasContent()&&this.enabled&& !this.$element.fire("bootstrap:show").defaultPrevented){a=this.tip();this.setContent();this.options.animation&&a.addClassName("fade");d="function"==typeof this.options.placement?this.options.placement.call(this,a[0],this.$element[0]):this.options.placement;a.setStyle({top:0,left:0,display:"block"});this.options.container?this.options.container.insert(a):this.$element.insert({after:a});b=this.getPosition();c=a.offsetWidth;a=a.offsetHeight;switch(d){case "bottom":e={top:b.top+b.height,left:b.left+b.width/ 2-c/2};break;case "top":e={top:b.top-a,left:b.left+b.width/2-c/2};break;case "left":e={top:b.top+b.height/2-a/2,left:b.left-c};break;case "right":e={top:b.top+b.height/2-a/2,left:b.left+b.width}}e.top+="px";e.left+="px";this.applyPlacement(e,d);this.$element.fire("bootstrap:shown")}},applyPlacement:function(a,b){var c=this.tip(),d=c.offsetWidth,e=c.offsetHeight,f,g,h;c.setStyle(a).addClassName(b).addClassName("in");a.top=1*a.top.replace("px","");a.left=1*a.left.replace("px","");f=c.offsetWidth;g= c.offsetHeight;"top"==b&&g!=e&&(a.top=a.top+e-g,h=!0);"bottom"==b||"top"==b?(e=0,0>a.left&&(e=-2*a.left,a.left=0,a.top+="px",a.left+="px",c.setStyle(a),f=c.offsetWidth),this.replaceArrow(e-d+f,f,"left")):this.replaceArrow(g-e,g,"top");"string"!==typeof a.top||a.top.match(/px/)||(a.top+="px",a.left+="px");h&&c.setStyle(a)},replaceArrow:function(a,b,c){this.arrow().length?this.arrow()[0].setStyle({position:a?50*(1-a/b)+"%":""}):""},setContent:function(){var a=this.tip(),b=this.getTitle();this.options.html|| (b=b.escapeHTML());a.down(".tooltip-inner").update(b);a.removeClassName("fade in top bottom left right")},hide:function(){var a=this,b=this.tip();if(!this.$element.fire("bootstrap:hide").defaultPrevented){if("css"==BootStrap.handleeffects&&this.$tip.hasClassName("fade")){var c=setTimeout(function(){b.stopObserving(BootStrap.transitionendevent);b?b.remove():""},500);b.observe(BootStrap.transitionendevent,function(){clearTimeout(c);b?b.remove():"";this.stopObserving(BootStrap.transitionendevent);a.$element.fire("bootstrap:hidden")}); b.removeClassName("in")}else"effect"==BootStrap.handleeffects&&this.$tip.hasClassName("fade")?new Effect.Fade(b,{duration:0.3,from:1*b.getOpacity(),afterFinish:function(){b.removeClassName("in");b.remove();a.$element.fire("bootstrap:hidden")}}):(b.removeClassName("in"),void 0!==b.up("body")?b.remove():"",this.$element.fire("bootstrap:hidden"));return this}},fixTitle:function(){var a=this.$element;(a.readAttribute("title")||"string"!=typeof a.readAttribute("data-original-title"))&&a.writeAttribute("data-original-title", a.readAttribute("title")||"").writeAttribute("title",null)},hasContent:function(){return this.getTitle()},getPosition:function(){var a=this.$element,b={};"function"==typeof a.getBoundingClientRect?Object.extend(b,a.getBoundingClientRect()):Object.extend(b,{width:a.offsetWidth,height:a.offsetHeight});return Object.extend(b,a.positionedOffset())},getTitle:function(){var a=this.$element,b=this.options;return a.readAttribute("data-original-title")||("function"==typeof b.title?b.title.call(a):b.title)}, tip:function(){return this.$tip=this.$tip||this.options.template},arrow:function(){return this.$arrow=this.$arrow||this.tip().select(".tooltip-arrow")},validate:function(){this.$element[0].parentNode||(this.hide(),this.options=this.$element=null)},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled},toggle:function(a){this.tip().hasClassName("in")?this.hide():this.show()},destroy:function(){this.hide();var a,b;this.options.trigger.split(" ").each(function(c){"click"== c?this.$element.stopObserving("click"):"manual"!=c&&(a="hover"==c?"mouseenter":"focus",b="hover"==c?"mouseleave":"blur",this.$element.stopObserving(a),this.$element.stopObserving(b))},this)}}); BootStrap.Popover=Class.create(BootStrap.Tooltip,{initialize:function($super,b,c){b.store("bootstrap:popover",this);$super(b,{subclass:!0});Object.extend(this.options,{placement:"right",trigger:"click",content:"",template:(new Element("div",{"class":"popover"})).insert(new Element("div",{"class":"arrow"})).insert(new Element("h3",{"class":"popover-title"})).insert(new Element("div",{"class":"popover-content"}))});if(c&&c.template&&Object.isString(c.template)){var d=(new Element("div")).update(c.template); c.template=d.down()}Object.extend(this.options,c);this.init("popover",b,this.options)},setContent:function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();0<a.select(".popover-title").length?a.select(".popover-title")[0].update(b):"";0<a.select(".popover-content").length?a.select(".popover-content")[0].update(c):"";a.removeClassName("fade top bottom left right in")},hasContent:function(){return this.getTitle()||this.getContent()},getContent:function(){var a=this.$element,b=this.options;return("function"== typeof b.content?b.content.call(a[0]):b.content)||a.readAttribute("data-content")},tip:function(){this.$tip||(this.$tip=this.options.template);return this.$tip},destroy:function($super){$super();this.hide();this.$element.stopObserving(this.options.trigger)}}); BootStrap.ScrollSpy=Class.create({initialize:function(a,b){a=$(a);a.store("bootstrap:scrollspy",this);this.options={offset:30};a.hasAttribute("data-target")&&(this.options.target=a.readAttribute("data-target"));var c=a.match("body")?window:a,d;Object.extend(this.options,b);this.$scrollElement=c.observe("scroll",this.process.bind(this));this.selector=(this.options.target||(d=a.readAttribute("href"))&&d.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a";this.$body=$$("body").first();this.refresh();this.process()}, refresh:function(){this.offsets=[];this.targets=[];this.$body.select(this.selector).map(function(a){a=a.readAttribute("data-target")||a.readAttribute("href");var b=/^#\w/.test(a)&&$$(a).first();return b&&[b.viewportOffset().top-b.getHeight()+(this.$scrollElement!=window&&this.$scrollElement.cumulativeScrollOffset().top),a]||null},this).without(!1,null).sort(function(a,b){return a-b}).each(function(a){this.offsets.push(a[0]);this.targets.push(a[1])},this)},process:function(){var a=this.$scrollElement.cumulativeScrollOffset().top+ this.options.offset,b=(this.$scrollElement.scrollHeight||this.$body.scrollHeight)-this.$scrollElement.getHeight(),c=this.offsets,d=this.targets,e=this.activeTarget,f;if(a>=b)return e!=(f=d.last())&&this.activate(f);for(f=c.length;f--;)e!=d[f]&&a>=c[f]&&(!c[f+1]||a<=c[f+1])&&this.activate(d[f])},activate:function(a){this.activeTarget=a;0<$$(this.options.target).length?$$(this.options.target).first().select(".active").invoke("removeClassName","active"):"";a=$$(this.selector+'[data-target="'+a+'"],'+ this.selector+'[href="'+a+'"]').first().up("li").addClassName("active");void 0!==a.up(".dropdown-menu")&&(a=a.up("li.dropdown").addClassName("active"));a.fire("bootstrap:activate")}});Event.observe(window,"load",function(){$$('[data-spy="scroll"]').each(function(a){new BootStrap.ScrollSpy(a)})}); BootStrap.Tab=Class.create({initialize:function(a){a.store("bootstrap:tab",this);this.element=$(a)},show:function(){var a=this.element,b=a.up("ul:not(.dropdown-menu)"),c=a.readAttribute("data-target"),d;c||(c=(c=a.readAttribute("href"))&&c.replace(/.*(?=#[^\s]*$)/,""));void 0!==a.up("li")&&a.up("li").hasClassName("active")||(d=void 0!==b?b.select(".active:last a")[0]:null,a.fire("bootstrap:show",{relatedTarget:d}).defaultPrevented||(c=$$(c)[0],this.activate(a.up("li"),b),this.activate(c,void 0!== c?c.up():void 0,function(){a.fire("bootstrap:shown",{relatedTarget:d})})))},activate:function(a,b,c){function d(){void 0!==e?e.removeClassName("active").select("> .dropdown-menu > .active").invoke("removeClassName","active"):"";void 0!==a?a.addClassName("active"):"";f?(a.offsetWidth,a.addClassName("in")):g?new Effect.Appear(a,{duration:0.3,afterFinish:function(){a.addClassName("in")}}):void 0!==a?a.removeClassName("fade"):"";void 0!==a&&a.up(".dropdown-menu")&&a.up("li.dropdown").addClassName("active"); c&&c()}var e=void 0!==b?b.select("> .active")[0]:void 0,f=c&&"css"==BootStrap.handleeffects&&void 0!==e&&e.hasClassName("fade"),g="effect"==BootStrap.handleeffects&&"undefined"!==typeof Effect&&"undefined"!==typeof Effect.Fade;f?(e.observe(BootStrap.transitionendevent,function(a){d(a);this.stopObserving(BootStrap.transitionendevent)}),void 0!==e?e.removeClassName("in"):""):g?void 0!==e&&e.hasClassName("in")&&e.hasClassName("fade")?new Effect.Fade(e,{duration:0.3,afterFinish:function(){e.removeClassName("in"); d()}}):d():(d(),void 0!==e?e.removeClassName("in"):"")}}); BootStrap.Typeahead=Class.create({initialize:function(a,b){this.$element=$(a);this.$element.store("bootstrap:typeahead",this);this.options={source:[],items:8,menu:new Element("ul",{"class":"typeahead dropdown-menu"}),item:(new Element("li")).update(new Element("a",{href:"#"})),minLength:1};this.options.items=this.$element.readAttribute("data-items")?this.$element.readAttribute("data-items"):this.options.items;this.options.source=this.$element.readAttribute("data-source")?this.$element.readAttribute("data-source").evalJSON(!0): this.options.source;Object.extend(this.options,b);this.matcher=this.options.matcher||this.matcher;this.sorter=this.options.sorter||this.sorter;this.highlighter=this.options.highlighter||this.highlighter;this.updater=this.options.updater||this.updater;this.source=this.options.source;this.$menu=this.options.menu;this.shown=!1;this.listen()},select:function(){var a=this.$menu.down(".active").readAttribute("data-value");this.$element.setValue(this.updater(a));this.$element.fire("bootstrap:change");return this.hide()}, updater:function(a){return a},show:function(){var a=Object.extend({},this.$element.positionedOffset());Object.extend(a,{height:this.$element.offsetHeight});this.$menu.setStyle({top:a.top+a.height+"px",left:a.left+"px",display:"block"});this.$element.insert({after:this.$menu});this.shown=!0;return this},hide:function(){this.$menu.hide();this.shown=!1;return this},lookup:function(a){this.query=this.$element.getValue();return!this.query||this.query.length<this.options.minLength?this.shown?this.hide(): this:(a=Object.isFunction(this.source)?this.source(this.query,this.process.bind(this)):this.source)?this.process(a):this},process:function(a){a=a.findAll(this.matcher,this);a=this.sorter(a);return a.length?this.render(a.slice(0,this.options.items)).show():this.shown?this.hide():this},matcher:function(a){return~a.toLowerCase().indexOf(this.query.toLowerCase())},sorter:function(a){for(var b=[],c=[],d=[],e;e=a.shift();)e.toLowerCase().indexOf(this.query.toLowerCase())?~e.indexOf(this.query)?c.push(e): d.push(e):b.push(e);return b.concat(c,d)},highlighter:function(a){var b=this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&");return a.replace(RegExp("("+b+")","ig"),function(a,b){return"<strong>"+b+"</strong>"})},render:function(a){a=a.map(function(a){var c=this.options.item.clone(!0).writeAttribute("data-value",a);c.down("a").update(this.highlighter(a));return c},this);a.first().addClassName("active");this.$menu.update();a.each(function(a){this.$menu.insert(a)},this);return this},next:function(a){a= this.$menu.down(".active").removeClassName("active").next();void 0===a&&(a=this.$menu.down("li"));a.addClassName("active")},prev:function(a){a=this.$menu.down(".active").removeClassName("active").previous();void 0===a&&(a=this.$menu.select("li").last());a.addClassName("active")},listen:function(){this.$element.observe("focus",this.focus.bind(this)).observe("blur",this.blur.bind(this)).observe("keypress",this.keypress.bind(this)).observe("keyup",this.keyup.bind(this));this.eventSupported("keydown")&& this.$element.observe("keydown",this.keydown.bind(this));this.$menu.observe("click",this.click.bind(this));this.$menu.on("mouseover","li",this.mouseenter.bind(this));this.$menu.on("mouseout","li",this.mouseleave.bind(this))},eventSupported:function(a){var b="on"+a in this.$element;b||(this.$element.writeAttribute(a,"return;"),b="function"===typeof this.$element[a]);return b},move:function(a){if(this.shown){switch(a.keyCode){case Event.KEY_TAB:case Event.KEY_RETURN:case Event.KEY_ESC:a.preventDefault(); break;case Event.KEY_UP:a.preventDefault();this.prev();break;case Event.KEY_DOWN:a.preventDefault(),this.next()}a.stopPropagation()}},keydown:function(a){this.suppressKeyPressRepeat=~[40,38,9,13,27].indexOf(a.keyCode);this.move(a)},keypress:function(a){this.suppressKeyPressRepeat||this.move(a)},keyup:function(a){switch(a.keyCode){case Event.KEY_DOWN:case Event.KEY_UP:case 16:case 17:case 18:break;case Event.KEY_TAB:case Event.KEY_RETURN:if(!this.shown)return;this.select();break;case Event.KEY_ESC:if(!this.shown)return; this.hide();break;default:this.lookup()}a.stopPropagation();a.preventDefault()},focus:function(a){this.focused=!0},blur:function(a){this.focused=!1;!this.mousedover&&this.shown&&this.hide()},click:function(a){a.stopPropagation();a.preventDefault();this.select();this.$element.focus()},mouseenter:function(a){this.mousedover=!0;this.$menu.select(".active").invoke("removeClassName","active");a.findElement("li").addClassName("active");a.stopPropagation()},mouseleave:function(a){this.mousedover=!1;!this.focused&& this.shown&&this.hide();a.stopPropagation()}}); document.observe("dom:loaded",function(){$$('.alert [data-dismiss="alert"]').each(function(a){new BootStrap.Alert(a)});$$("[data-toggle^=button]").invoke("observe","click",function(a){a=a.findElement();a.hasClassName("btn")||(a=a.up(".btn"));new BootStrap.Button(a,"toggle")});document.on("click","[data-slide], [data-slide-to]",function(a){var b=a.findElement(),c,d=$$(b.readAttribute("data-target")||(c=b.readAttribute("href"))&&c.replace(/.*(?=#[^\s]+$)/,"")).first();Object.extend({});(c=b.readAttribute("data-slide"))? d.retrieve("bootstrap:carousel")[c]():"";b.hasAttribute("data-slide-to")&&(b=b.readAttribute("data-slide-to"),d.retrieve("bootstrap:carousel").pause().to(b).cycle());a.stop()});$$('[data-toggle="collapse"]').each(function(a){var b=a.readAttribute("href"),b=a.hasAttribute("href")?b.replace(/.*(?=#[^\s]+$)/,""):null,b=a.readAttribute("data-target")||b,c={toggle:!1};a.hasAttribute("data-parent")&&(c.parent=a.readAttribute("data-parent").replace("#",""));b=$$(b).first();b.hasClassName("in")?a.addClassName("collapsed"): a.removeClassName("collapsed");new BootStrap.Collapse(b,c)});document.on("click",'[data-toggle="collapse"]',function(a,b){var c=b.readAttribute("href"),c=b.hasAttribute("href")?c.replace(/.*(?=#[^\s]+$)/,""):null,c=b.readAttribute("data-target")||a.preventDefault()||c;$$(c).first().retrieve("bootstrap:collapse").toggle()});document.observe("click",BootStrap.Dropdown.prototype.clearMenus);$$(".dropdown form").invoke("observe","click",function(a){a.stop()});$$("[data-toggle=dropdown]").invoke("observe", "click",BootStrap.Dropdown.prototype.toggle);$$("[data-toggle=dropdown], [role=menu]").invoke("observe","keydown",BootStrap.Dropdown.prototype.keydown);$$("[data-toggle='modal']").invoke("observe","click",function(a){var b=this.readAttribute("data-target")||this.href&&this.href.replace(/.*(?=#[^\s]+$)/,"").replace(/#/,""),c={};void 0!==$(b)&&(b=$(b),/#/.test(this.href)||(c.remote=this.href),new BootStrap.Modal($(b),c));a.stop()});$$('[data-toggle="tab"], [data-toggle="pill"]').invoke("observe","click", function(a){a.preventDefault();(new BootStrap.Tab(this)).show()});$$('[data-provide="typeahead"]').each(function(a){new BootStrap.Typeahead(a)})}); |
Hi Nathan,
Thanks for this! I had just run into this issue with bootstrap dropdowns and the mobile accordion menu not working in a fuji instance and this solution was really helpful.
Brad, great to hear 🙂
Thanks for this. It appears like it also requires your other fix or else the dropdown disappears after selecting an option in the dropdown.
http://servicenowcms.com/bootstrap-dropdowns-in-fuji/
Are you still including the bootstrap.js file? The drop downs should not disappear when using this file instead of bootstrap.js. I tested it and it worked fine for me.
I am also having this issue. I’ve created the UI Script and I’ve also added the HTML provided above to my layouts for our CMS site, however, my menu drop-downs still disappear when clicked. Is there a specific place that I need to include the provided HTML posted above?
Thanks,
Jacob Laux
I have tried using this an implementing popovers and a collapse menu and I keep getting errors, have you been able to implement them? Everything else works fine
Martin, I tested all the main elements and everything seemed to work for me. I’m pretty sure I tested the collapse menu. But I’m out of the country rest of this week so won’t have an opportunity to check it.
Yeah so basically I just grabbed a sample collapse from the bootstrap site and when I load the page the menu is expanded, clicking on it will collapse it but then it won’t expand again.
Hi, can get everything working except for the collapse menu, can collapse the menu, but not back again. It just stays toggled. Any ideas?
This seems like a good solution as well which worked in Fuji for me.
http://jsfiddle.net/dgervalle/hhBc6/
Hi Nathan,
I used this solution, it works great but it seems there is an issue with this solution. When using this solution to Bootstrap v3, than it is having some styling issues. Like I tried it with bootstrap v2 tabs and it works fine but once i used it with Bootstrap v3 than it is having some styling issues.
Akash, I did a quick test of all the main components with this script and I did not see any issues. The CSS should still be the original CSS that ships with Bootstrap, this should just replace the javascript. Thanks for brining this to my attention though, if I find time I’ll take a closer look. Thanks.
Hi Nathan,
Plz check https://dev12277.service-now.com/bt-test2.do link, It is having issues, I used the same code..See the tab behavior when clicked