I am trying to understand how the show/hide logic of a dropdown in twitter bootstrap works.
I can declare a dropdown menu in a navbar purely with HTML, and yet it seems that Javascript is involved with showing/hiding the dropdown. Also the dropdown disappears if I focus out by clicking on an unrelated area on the page.
Question part 1: Where can I find the Javascript code that is involved with Dropdowns in bootstrap?
Question part 2: Is it somehow possible to tap into the event logic and execute some custom Javascript code when a certain dropdown receives a focus out event? For example so that I can hide another (unrelated) element on the page when the dropdown looses focus?
To be more precise:
Lets say I declare a bootstrap dropdown purely in HTML (this would be inside a ul.nav.navbar-nav):
<li role="presentation" class="dropdown">
<a id="mainmenu" class="dropdown-toggle" data-toggle="dropdown"
role="button" aria-haspopup="true" aria-expanded="false">
Lectures <span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li>Action</li>
</ul>
</li>
Now somewhere else on the page I have the following HTML:
<div id="#background" style="display: none">
<img src="...">
</div>
When I click on the dropdown button bootstrap will show the dropdown, but want two additional things to happen:
The div#background should be shown
Assuming I click somewhere outside the dropdown (which will cause bootstrap to close it), I want the div#background to be hidden again.
I think it should somehow be possible to register my own callback function on some bootstrap event and show/hide my div from that callback, like so:
/* just to illustrate my idea */
hide = function(element) {
element.style.display = "none"
}
show = function(element) {
element.style.display = "block"
}
}
So how and where could I register the hide and show functions such that they get called when I open/close the dropdown and also when I click on an unrelated area on the screen, which will cause the dropdown to close.
If this is possible to achieve purely in HTML by attaching some data-* elements to my div#background then I would like to know about that too.
First:
Do you think about something like this?
$('.dropdown-toggle').dropdown();
Got it from w3schools.com
Second:
You can do call the dropdown link
$('#element').click( function(){
$('#dropdownElement').dropdown();
});
Is that what you are looking for?
Related
I am trying to automate the assignment for toggle button on the below link :
http://way2automation.com/way2auto_jquery/accordion.php
where the icons will go on and off based on the toggle button.
The HTML code snippet for the buttons are :
<h3 class="ui-accordion-header ui-state-default ui-accordion-icons ui-corner-all" role="tab" id="ui-id-1" aria-controls="ui-id-2" aria-selected="false" aria-expanded="false" tabindex="-1"><span class="ui-accordion-header-icon ui-icon ui-icon-circle-arrow-e"></span>Section 1</h3>
I have switched to the frame already and trying to check the element using :
chromeDriver.findElement(By.xpath("//*[#id=\"ui-id-1\"]/span")).isEnabled()
however after clicking on toggel buttons the icon gets disappeared and the element is not visible at all. Hence I am getting error for the above line. Is there any way to check the icons are there or not?
I have an issue with using a linked template with JSViews and Materialize Dropdown Button.
The first time, the view is rendered, it works fine, however as soon as I observably update the status of the button, the ul tag which is linked to the button is deleted from the DOM.
I have created a test case on JSFiddle: here
<script id="test_template" type="text/x-jsrender">
{^{for tasks}}
<div class="dropdown change-state" style="display: block">
{^{if Status == 0}}
<a href="#" class="completed-state-box dropdown-button btn btn-flat red" data-constrainwidth="false" data-activates='review_status_dropdown-{{:Id}}'>NOT COMPLETE</a>
{{/if}}
{^{if Status == 1}}
<a href="#" class="completed-state-box dropdown-button btn btn-flat green" data-constrainwidth="false" data-activates='review_status_dropdown-{{:Id}}'>COMPLETE</a>
{{/if}}
<ul id="review_status_dropdown-{{:Id}}" class="dropdown-content">
<li><a class="state-change-button" href="#" data-value="0">NOT COMPLETE</a></li>
<li><a class="state-change-button" href="#" data-value="1">COMPLETE</a></li>
</ul>
</div>
{{/for}}
If you click on a button after running, it opens the drop down just fine. If you select an option that is not set (ie set the COMPLETED button to NOT COMPLETE), it updates the UI, but as the ul is removed from the DOM, clicking on it again does not reveal the drop down. Only the button that is updated is affected.
Can anyone see where I am going wrong?
It looks like Materialize clones the ul and inserts a copy after each activator. Initially there is only one activator (since the other {^{if}} expression is false so its content is empty) - and the cloned ul is placed next to it inside the {^{if}} block.
When you click to toggle the status, the contents of that {^{if}} get removed, and the other {^{if}} contents get rendered. But the second activator (<a> tag) has not been 'activated' and so does not have an associated <ul>.
If you are going to use Materialize alongside JsViews, then you have to deal with Materialize potentially doing DOM manipulation, which can break the JsViews data linking. Having two frameworks which both manipulate the same DOM can lead to collisions or conflicts.
In this case you can resolve the problem by using the visible binding, rather than {^{if}}:
<div class="dropdown change-state" style="display: block">
<a href="#" data-link="visible{:Status==0}" class="completed-state-box dropdown-button btn btn-flat red" data-constrainwidth="false" data-activates='review_status_dropdown-{{:Id}}'>NOT COMPLETE</a>
<a href="#" data-link="visible{:Status==1}" class="completed-state-box dropdown-button btn btn-flat green" data-constrainwidth="false" data-activates='review_status_dropdown-{{:Id}}'>COMPLETE</a>
<ul id="review_status_dropdown-{{:Id}}" class="dropdown-content">
<li><a class="state-change-button" href="#" data-value="0">NOT COMPLETE</a></li>
<li><a class="state-change-button" href="#" data-value="1">COMPLETE</a></li>
</ul>
</div>
Update:
In response to grayson's Materialize-related issues of 'inline-block' vs 'block',
here are a couple of alternatives:
You can data-link directly to the CSS display attribute, and specify the values you want to toggle:
<a data-link="css-display{:Status==1?'inline-block':'none'}" ...>
Or you can create a custom tag that does what you want:
$.views.tags("show", {
render: function(val) {
return val ? "inline-block" : "none"
},
attr: "css-display"
});
and then write:
<a data-link="{show Status==0}" ...>
You can even do:
$.views.tags("show", {
render: function(val, type) {
return val ? type||"inline-block" : "none"
},
attr: "css-display"
});
and write
<a data-link="{show Status==0}" ...>
or
<foo data-link="{show Status==0 'block'}" ...>
Boris' Answer is the correct answer to this question as you would obviously expect, however, I wanted to add a little something which may help anyone in the situation.
JSViews is very clever and using the visible binding, it appears to try and identify the type of element, so in the case of an anchor tag it uses display:inline, whereas for a div it uses display:block
In the case of materialize (and bootstrap), the btn class sets the display to inline-block, so using visible binding doesn't work as intended in all cases.
In my case, because this truly was a button rather than a link, I changed the anchor tag to a button tag and as this is a block element it worked just fine.
It is not an ideal solution, as in my case, I might have 30 buttons, with 5 options which means flooding the DOM with lots of extra hidden tags, but until I can come up with a better solution, using the {^{if..., it works.
I am using bootstrap popover with vuejs.
How can I trigger vue functionality?
In below code when I am clicking on add break link, it opens bootstrap popover, with click me button. Now here vuejs doesn't work, if I click on click me, it is not prompting alert.
<a data-toggle="popover" data-placement="top" v-d2d-popover data-content='<button v-on:click="alert(6)">click me</button>' href="javascript:void(0)" class="btn btn-link popover-notitle">
<i class="ace-icon fa fa-plus-circle bigger-120 green"></i>add break
</a>
Can anybody help me?
Since the button is just written in a string, it isn't being compiled by Vue. Here are a couple of ideas to try:
Use Vue for popover as well: https://yuche.github.io/vue-strap/#popover
Create popover content in a separate div (in your component so Vue will compile it) and then fetch the content for the popover:
{
content: $('#myPopoverContent').html(),
html: true
}
I was wondering how I would go about changing the background color of the selected tab (not the contents of the tab, the tab heading itself, when I hover over it it turns grey but then goes back to normal once I click the tab, I want it to stay grey). I was also wondering how to change the font and font color of the tab heading once selected.
Please let me know if you need any other information, I'm not really sure how much more specific I can get without taking screenshots but I will if needed.
You can set css class for selected tab header. For example, if you have html like this,
<div class="menu">
<ul>
<li><a class="menuLink active" href="#">Home</a></li>
<li> <a class="menuLink" href="#">Page1</a></li>
<li><a class="menuLink" href="#">Page2</a></li>
<li><a class="menuLink" href="#">Page3</a></li>
</ul>
</div>
then using jQuery,
$('.menuLink').click(function(){
$('a').removeClass('active');
$(this).addClass('active');
});
Demo: http://jsfiddle.net/PYW35/
P.S.: this question should be tagged for jQuery, css.
I am using Durandal, hottowel. Want to change the view dynamically, hide some div depending upon a cookie value. However, if I write the code in "activate" as such
$("#box1").hide();
$("#box2").show();
both the boxes are shown, hide does not work. But if I wire the same code to a click event then everything works. Is "activate" is not the right place to do such a thing? What's the best way to do such a thing.
My view is simply as follows:
<section>
<div id="box1">
box1
</div>
<div id="box2">
box2
</div>
</section>
A better approach is to use the knockout bindings that ship with durandal to do this declaratively in the view.
<section>
<div data-bind="visible: box1Visible">
box1
</div>
<div data-bind="visible: box2Visible">
box2
</div>
</section>
VM:
return {
activate: activate,
box1Visible: ko.observable(false),
box2Visible: ko.observable(true)
}
Then all you have to do to show or hide the boxes is set the values of those observables from the view model. The view model then doesn't need to be aware of the structure or the names of elements in the view.
I think I got the answer by using ViewAttached in my model. This method is called after view is bound. read more about it here http://durandaljs.com/documentation/Composition/
and here