.NET MVC: Finding default Bootsrap JavaScripts - javascript

In an out-of-the-box implementation of an MVC app using Bootstrap in Visual Studio 2013, there seems to be some javasvript that works on this element:
<li role="presentation" class="dropdown">
....
</li>
When that element is clicked, there is, somewhere, some JavaScript that changes the class in this element to:
<li role="presentation" class="dropdown open">
....
</li>
I want to augment/alter whatever script this is, but I can't find it. Or, I could also just create my own that works along side the existing script, but I can't figure out how to reference this element when it doesn't have an id. I'd rather not add my own id, as this list of li's is generated dynamically and I don't want to deal with referencing all the id's in the JavaScript.
How would I find the existing script that is making this change? OR How would I create my own script to handle the on-click?
Thanks!

You can reference the open li using css class selector '.':
$(".dropdown.open")
this will give you the currently open dropdown.
Explanation:
'CSS selectors' allow you to select elements using CSS syntax. For example:
'#id' where the '#' indicates the following text is the id of the element.
'.class' allows you to select all elements by class, eg $(".dropdown") gives you all elements with class "dropdown". These can be combined ".dropdown.open" - all elements with both class dropdown and open
Never change the library directly, there's an event you can hook into:
$('#id_of_ul').on('shown.bs.dropdown', function () {
// do something...
})
http://getbootstrap.com/javascript/#dropdowns
Explanation:
.on is the jquery event hook to provide your own handler when something happens, eg: $("#id").on('click', function....
In this case, the event is called shown.bs.dropdown and is provided / raised by the twitter-bootstrap dropdown functionality.
To answer the explicit question of where to find the scripts, you can download from getbootstrap.com or, they'll be in your MVC project under Scripts\

Related

Can I respond to a menu item housed in a List Item via its click event?

To set a Session variable in response to the selection of a menu item, should a list item click event replace an anchor tag?
In my Meteor app, I originally intended to use iron router routing in response to menu item selections, like so:
<li>Open Existing</li>
...but now am thinking I would rather use dynamic templates, and use the value of a Session variable to replace the Template in the body (SPA-style). So is this the way to go about that:
html:
<li name="mniOpenExisting" id="mniOpenExisting">Open Existing</li>
Javascript:
"click mniOpenExisting": function (event) {
return 'openExistingTemplate';
// In actuality, I will use:
//Session.set('curTemplate', 'openExistingTemplate');
}
?
IOW, I can just do away with the anchor tag and respond to the click of the menu items?
Yes that is correct, the <a> is not required.
"click #mniOpenExisting": function (event) {
// take action here when element with id 'mniOpenExisting' is clicked
}
I like the coding style set out here, with the separation between ids and classes used for presentation and the data- tags for event handlers.
Iron:router is still 'SPA-style', however the additional functionality it has already built in may save you time and keep your code cleaner that reimplementing this functionality yourself, though that depends on how complex your app will be.
Also see Meteor UI Pattern: Keeping App State on the URL. This is generally a much better option than having Session variables for the same task.

The data-toggle attributes in Twitter Bootstrap

What does data-toggle attributes do in Twitter Bootstrap? I couldn't find an answer in Bootstrap API.
I have seen a similar question before as well, link.
But it didn't help me much.
It is a Bootstrap data attribute that automatically hooks up the element to the type of widget it is. Data-* is part of the html5 spec, and data-toggle is specific to Bootstrap.
Some Examples:
data-toggle="modal"
data-toggle="collapse"
data-toggle="dropdown"
data-toggle="tab"
Go through the Bootstrap JavaScript docs and search for data-toggle and you will see it used in the code examples.
One working example:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Dropdown trigger</a>
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
<li>Item</li>
</ul>
</div>
Any attribute that starts with data- is the prefix for custom attributes used for some specific purpose (that purpose depends on the application). It was added as a semantic remedy to people's heavy use of rel and other attributes for purposes other than their original intended purposes (rel was often used to hold data for things like advanced tooltips).
In the case of Bootstrap, I'm not familiar with its inner workings, but judging from the name, I'd guess it's a hook to allow toggling of the visibility or perhaps a mode of the element it's attached to (such as the collapsable side bar on Octopress.org).
html5doctor has a good article on the data- attribute.
Cycle 2 is another example of extensive use of the data- attribute.
For example, say you were creating a web application to list and display recipes. You might want your customers to be able to sort the list, display features of the recipes, and so on before they choose the recipe to open. In order to do this, you need to associate things like cooking time, primary ingredient, meal position, and so on right inside the list elements for the recipes.
<li>Borscht</li>
<li>Chocolate Mousse</li>
<li>Almond Radiccio Salad</li>
<li>Deviled Eggs</li>
In order to get that information into the page, you could do many different things. You could add comments to each LI element, you could add rel attributes to the list items, you could place all the recipes in separate folders based on time, meal, and ingredient (i.e. ). The solution that most developers took was to use class attributes to store information about the current element. This has several advantages:
You can store multiple classes on an element
The class names can be human readable
It’s easy to access classes with JavaScript (className)
The class is associated with the element it’s on
But there are some major drawbacks to this method:
You have to remember what the classes do. If you forget or a new developer takes over the project, the classes might be removed or changed without realizing that that affects how the application runs.
Classes are also used for styling with CSS, and you might duplicate CSS classes with data classes by mistake, ending up with strange styles on your live pages.
It’s more difficult to add on multiple data elements. If you have multiple data elements, you need to access them in some way with your JavaScript, either by the name of the class or the position in the class list. But it’s easy to mess up.
All the other methods I suggested had these problems as well as others. But since it was the only way to quickly and easily include data, that’s what we did.
HTML5 Data Attributes to the Rescue
HTML5 added a new type of attribute to any element—the custom data element (data-*). These are custom (denoted by the *) attributes that you can add to your HTML elements to define any type of data you want. They consist of two parts:
Attribute Name
This is the name of the attribute. It must be at least one lowercase character and have the prefix data-. For example: data-main-ingredient, data-cooking-time, data-meal. This is the name of your data.
Attribute Vaule
Like any other HTML attribute, you include the data itself in quotes separated by an equal sign. This data can be any string that is valid on a web page. For example: data-main-ingredient="chocolate".
You can then apply these data attributes to any HTML element you want. For example, you could define the information in the example list above:
<li data-main-ingredient="beets" data-cooking-time="1 hour" data-meal="dinner">Borscht</li>
<li data-main-ingredient="chocolate" data-cooking-time="30 minutes" data-meal="dessert">Chocolate Mousse</li>
<li data-main-ingredient="radiccio" data-cooking-time="20 minutes" data-meal="dinner">Almond Radiccio Salad</li>
<li data-main-ingredient="eggs" data-cooking-time="15 minutes" data-meal="appetizer">Deviled Eggs</li>
Once you have that information in your HTML, you will be able to access it with JavaScript and manipulate the page based on that data.
From the Bootstrap Docs:
<!--Activate a modal without writing JavaScript. Set data-toggle="modal" on a
controller element, like a button, along with a data-target="#foo" or href="#foo"
to target a specific modal to toggle.-->
<button type="button" data-toggle="modal" data-target="#myModal">Launch modal</button>
So many answers have been given, but they don't get to the point. Let's fix this.
http://www.w3schools.com/bootstrap/bootstrap_ref_js_collapse.asp
To the point
Any attribute starting with data- is not parsed by the HTML5 parser.
Bootstrap uses the data-toggle attribute to create collapse functionality.
How to use: Only 2 Steps
Add class="collapse" to the element #A you want to collapse.
Add data-target="#A" and data-toggle="collapse".
Purpose: the data-toggle attribute allows us to create a control to collapse/expand a div (block) if we use Bootstrap.
The presence of this data-attribute tells Bootstrap to switch between visual or a logical states of another element on user interaction.
It is used to show modals, tab content, tooltips and popover menus as well as setting a pressed-state for a toggle-button. It is used in multiple ways without a clear documentation.
The purpose of data-toggle in bootstrap is so you can use jQuery to find all tags of a certain type. For example, you put data-toggle="popover" in all popover tags and then you can use a JQuery selector to find all those tags and run the popover() function to initialize them. You could just as well put class="myPopover" on the tag and use the .myPopover selector to do the same thing. The documentation is confusing, because it makes it appear that something special is going on with that attribute.
This
<div class="container">
<h3>Popover Example</h3>
Toggle popover1
Toggle popover2
</div>
<script>
$(document).ready(function(){
$('.myPop').popover();
});
</script>
works just fine.
It is a Bootstrap defined HTML5 data attribute. It binds a button to an event.
Here you can also find more examples for values that data-toggle can have assigned. Just visit the page and then CTRL+F to search for data-toggle.
Bootstrap leverages HTML5 standards in order to access DOM element attributes easily within javascript.
data-*
Forms a class of attributes, called custom data attributes, that allow proprietary information to be exchanged between the HTML and its DOM representation that may be used by scripts. All such custom data are available via the HTMLElement interface of the element the attribute is set on. The HTMLElement.dataset property gives access to them.
Reference

Inside of a event registered by NodeList.connect(), how to get a reference to the triggered node?

Short-form question
I'm executing dojo.query() and applying an event handler to all of the returned nodes, using the NodeList.onmouseenter() function. However, when one of those nodes triggers the event, I need to know which one it was, so I can traverse the DOM from that particular node's location. How can I get a reference that particular node at trigger-time?
Long-form question with full context
I am trying to adapt a jQuery-powered navigation menu (see overview and complete source) to work in a Dojo environment. In a nutshell, the HTML looks like this:
<ul class="topnav">
<li>Home</li>
<li>
Tutorials
<ul class="subnav"> <!-- This CSS class hides the <ul> on page load -->
<li>Sub Nav Link</li>
<li>Sub Nav Link</li>
</ul>
<span></span> <!-- CSS fills the <span> with an image -->
</li>
...
The outermost <ul> tag represents the navigation menu as a whole... and the nested <ul> tags are where a menu item has a drop-down submenu. Such menu items also have an <span> tag in there, to display an arrow image and make things easier to identify during DOM-traversing.
So, the jQuery code adds an event handler to all those <span> tags. The tutorial link above uses an "onClick", but I plan to change that to a hover (i.e. "onmouseenter" and "onmouseleave"). Either way, the event trigger causes the hidden submenu to be diplayed with a jQuery "slideDown" effect (equivalent to Dojo's "wipeIn").
$("ul.topnav li span").click(function() {
$(this).parent().find("ul.subnav").slideDown('fast').show();
});
To get from the <span> to the nested <ul>, the event handler crawls the DOM one level up and then one level back down... starting from $(this). This is the part that is killing me in Dojo! I've tried dozens of variations, but here is my current (broken) code:
dojo.require("dojo.fx");
dojo.require("dojo.NodeList-traverse");
dojo.require("dojo.NodeList-manipulate");
dojo.ready(function(){
dojo.query("ul.topnav li span").onmouseenter(function(node) {
node.siblings("ul.subnav").wipeIn().play();
});
}
Inside of Dojo's NodeList event connection functions (e.g. onmouseenter), I can't figure out how to get a trigger-time reference to the node that was triggered. The anonymous function I'm passing to "onmouseenter" takes a parameter called "node", but that's just my wishful thinking. Dojo doesn't really pass such a reference.
What I need is an equivalent to the $(this) on the second line of the above jQuery snippet. A reference to the particular node that was event-triggered, so that I can traverse the DOM from that particular node's location. Is there an easy way to do this with Dojo's NodeList that I'm just missing?
IIRC, the onmouseenter callback doesn't receive a node as a parameter but receives an event object instead. If this is the case you can try to:
Get the node through other means, (evt.currTarget or something like that, I always get confused with these...)
Use a forEach instead, get the references to the nodes, and do the event connection manually:
dojo.query('blabla').forEach(function(node){
dojo.connect(node, 'onmouseenter', function(evt){
//node should point to wat you want now
node.siblings("ul.subnav").wipeIn().play();
});
});
The best reference you can get to a node, is the node itself including its id.
At trigger time "this" is the node and with it you can get everything in particular its id with: this.id.
dojo.query(".anyClass").connect(Mouse.enter, function(evt){
var xId=this.id;
console.log("You entered element "+xId);
});

How to remove a JavaScript initialisation?

What I am trying to achieve is a second dropdown list to be populated with values based on the selection of the first dropdown list.
I've got it to work using the following:
http://jsfiddle.net/ydPfH/6/
The problem is that an external plug in that I am using to display images in a drop down list somehow stops this code from working properly.
The code that initalises this plug-in is $("body select").msDropDown(); and what I have below the simple search form that uses this plug-in is a jquery expandable div so you click Advanced Search to expand the form with the dynamic dropdowns.
<a href="#" rel="toggle[advancedsearch]" data-openimage="images/collapse.png" data-
closedimage="images/expand.png">Advanced Search<img id="expand"
src="images/collapse.png"/> </a>
<div id="advancedsearch">
<p>Document Properties:</p>
<form>
<select id="tags" name="tags" class="tags">
etc....
What I'm hoping for is some kind of onclick or something even easier to call to another JS method to somehow remove the $("body select").msDropDown(); initialisation or to even initialise something silly that in turn removes it.
Full source of the page can be seen here if it helps: http://jsfiddle.net/pQ9LT/
Thanks,
Martin
If I'm getting this right, here is the answer:
You should add class attributes to the <select> elements that are going to be using your msDropDown plugin. Then initialize the plugin like this $('select.yourClass').msDropDown();
where yourClass is the class name you assigned these <select> elements.
The body part in your selector is superflous.
This way, jQuery will only apply the plugin to the <select> elements "marked" with you class name and not all of them so you can use the other "normal" <select> elements without interference.
Hope I helped you out.
I'm not completely clear on what your overall requirements are and what may or may not be acceptable so where are a few thoughts that I have.
Give the select elements you do not want styled as image combo boxes a class or an id. Then use the :not() selector in combination with your msDropdown initialization
$("body select:not('.nostyle')").msDropDown(); //using the class 'nostyle' to filter out the elements that should get the image combobox
Use a more specific selector in the initialization call; this is kinda the opposite of the above
$("body select.classOfSelectsTobeStyled").msDropDown(); //using the class 'classOfSelectsTobeStyled' on elements that should get the image combobox

How can I apply prototype's toggle to content loaded via JSON, IE problem only

I use PHP and javascript via prototype.
i have a threaded comments page that on open
by default via javascript call to a PHP file data returned via JSON, only parent comments are retrieved in the db. (in short only parent comments are fetched from db and displayed)
then the parents are loaded and formatted to be shown on the page with a link to get and display its child comments, link example:
<span id="moreparent8351" onclick="insertChildDiv('parent8351')">1 Replies and more</span>
the span link above calls the javascript function "insertChildDiv()" that basically gets comments whose parent_id=parent8351, also using a PHP file that returns data via JSON to the javascript that dynamically inserts this child comments nested under its parent comment.
then the span link above using prototype transforms into:
<span id="moreparent8351" onclick="$('childparent8351').toggle()">1 Replies and more</span>
now here is the problem, this inserted content inside this div with id=childparent8351 wont respond to the hide/show toggle ONLY in IE v6,v7 and v8. other browsers work fine.
it looks like IE cannot apply the hide/show toggle to a dynamically inserted content.
I tried hardcoding the inserted content that i see in fogbugz to the page and testing it again on IE, guess what? toggle works!
I dont want to fetch all the comments both parent and child and then hide the child comments, that is a waste of resources on something that we are not sure is important or to be read by the users.
Is there a workaround? if there is none, then i hope this post will help others on their design stage for something similar.
Element.toggle() should work fine with dynamically generated content. Your problem most likely lies within the method you use to generate this content.
You stated:
then the span link above using
prototype transforms into:
<span id="moreparent8351" onclick="$('childparent8351').toggle()">1 Replies and more</span>
How exactly are you changing the onclick attribute of the span element?
First of all, I definately would not recommend changing an onclick event on-the-fly. It is probably better to use one function that checks the current state of what you are trying to do and executes the appropriate code.
Be sure not to "transform" your span element, including the onclick attribute using innerHTML. Chances are the DOM is still trying to reference a function that you have just removed. If updating your onclick attribute at all, do it like this:
var element = $('moreparent8351');
// this automatically removes previous onclick handlers set in this manner
element.onclick = function() { // do stuff };
...or, when you want to it the Prototype way:
var element = $('moreparent8351');
// OPTIONAL: remove previous handler, if set
element.stopObserving('click', my_cool_function());
// attach new handler
element.observe('click', function() { // do stuff });

Categories