bootstrap

All posts tagged bootstrap

bootstraplogo

If you’ve spent any time looking at the Bootstrap docs you’ll notice their nav bar on the right.  Very slick example of both Scrollspy and Affix.  I have written blog posts about both of these topics in conjunction with each other titled Bootstrap ScrollSpy Pitfalls and Fixes.  In my example I use a very simple styling for my nav using nav-pills.  This works out alright but what if we want to get exactly what Bootstrap is doing?  Well, let’s figure out just how they do it.

They are using very similar code to what I had in the pitfalls and tricks post so I’ll bring that in here.

Now that we have a simple navigation let’s style it to have sub menus not be shown until the item is in view of the user, just like Bootstrap.

We’ve added some sub menu items to a few of the nav elements.  At this point if you were to render the page it would show all of the items in the list regardless of it being a sub menu or not.  We want to change that so we only see specific sub menus when they are active.  To do this we just need to add a little bit of CSS that will trigger the display of the sub menus.  When the menu item is not active the sub menus are hidden.  When the menu item is activated it displays the sub menus below.

That’s all there is to it! No tricky JavaScript required, it’s all CSS.   Now just adjust the padding, change the color, and add sub menus to your heart’s content.  You now have a side nav that looks and acts just like Bootstrap’s does in their docs.

One of the most commonly used features of Bootstrap is their Modal component.  If you don’t know what a modal is it is like a pop up except it can contain HTML.  This means you can put any sort of information you’d like in it, a common example is a modal that contains a login form.  This post will show you how to create your own modals and even load in the content dynamically using AJAX.

Modal Basics

Let’s start with the most basic modal that contains static content.  You’ll need two things.  The first is a button or link to trigger the modal.  Secondly, you’ll need to put the modal div somewhere on your page.  Below is some example code with the button and the modal div.

This code was taken from Bootstrap’s example for modals.  Let’s break it down a bit starting with the button.  You’ll see that the button is styled with some standard Bootstrap classes to make it large and blue.  After that you’ll notice two HTML5 data tags, data-toggle and data-target.  Bootstrap uses these to know that you are planning on using this to open a modal and with content in the id contained in data-target.

Our modal div is labeled with the id of the data-target from the button.  In that .modal there are a lot of other elements listed in their example.  The class .modal makes Bootstrap know this is a modal and .fade refers to how the animation will work when it needs to be shown.  The tabindex is set to -1 to avoid any unforeseen issues with tabbing through your page.  The next three are for accessibility purposes like screen readers and can be omitted if you are not supporting screen reading technologies.

The modal is broken down into sections represented as various divs.  Each div needs to have a corresponding modal class to ensure that Bootstrap can display it correctly.  It is a good idea to have all of these divs in place even if you don’t put content in all of them.  The first is the .modal-dialog.  This is where everything that is the modal will be contained.  The next div is .modal-content.  This is where all of your content like text and buttons will eventually be placed.  There are three sections to a modal, the header, the body, and the footer.  They are labeled with the classes .modal-header, .modal-body, and .modal-footer.

bootstrap modal

The .modal-header is where you place your title and close button.  You’ll notice in the example that the button in the .modal-header contains an HTML5 data element called data-dismiss=”modal”.  This tells Bootstrap to close the modal when this button is clicked.

Inside of the .modal-body is where you’ll place your form and whatever other content you need.  Essentially this acts just like a smaller web page.  You can use all of the Bootstrap formatting and styling and place any JavaScript and content you’d like in here.  Later we will see how to put dynamically loaded content in here.

Finally, there is the .modal-footer.  Most of the time you’ll put another close button down here because a lot of users are used to having both an ‘x’ in the upper right corner and a close button at the bottom.  You can also put any text or maybe a Submit button for your form in here as well.

Loading Content with AJAX

Sometimes you’ll want to load in the content of the modal using AJAX.  There are a couple of ways to do this but using jQuery but here we will use the Bootstrap data elements to make Bootstrap do the leg work for us.  Taking the above example we just need to make a few minor changes.

Main.html

Changing the button to an a tag allows us to give a URL in the href parameter.  Bootstrap interprets this as the content to be loaded and the data-target to be where the content is to be loaded.

ModalContent.html

You’ll notice that I’ve moved everything except the .modal to a separate page. From our testing and experience this was the most consistent way to load content into the modal without any weird CSS or loading issues.

That’s all there is to it.  Modals are powerful and wonderful.  Gathering information from the user or displaying a small bit of information without making the user leave the page is a wonderful thing to add to any webpage.  Let me know how you are using modals below in the comments.
})();
// ]]>

One of the biggest features of Bootstrap is their responsive grid.  It helps developers and designers easily space out content on a page without having to worry about margins and screen sizes.  I’ve done some posts in the past talking about the best way to use the various screen size related tags.  Today I wanted to focus on taking all of that to the next level.  The grid system works at every level as far down as you want to go.  Below is a catalog I created which quickly informs of a moisture test.  There is a lot of information to display and doing so in a clean format is hard.  Using Bootstrap’s grid system at every step has helped to create what you see below.

catalog

This is the final result that we will be breaking down.  You can see that there is a test number on the left without anything underneath it, a larger section with text followed by smaller sections and even a table.  Let’s break down every layer and div.

catalog-outer-row

The outer div of the entire thing is given the class row.  The row class keeps everything tight to the 12-column Bootstrap design and doesn’t let things roll over unexpectedly.  If you forcefully go over the 12-columns it will obviously bump it but sticking the row class on an outer div will help keep everything together.  This is also useful for printing as I don’t want a row to ever be cut between two pages.  You can either add @media print{ .row{page-break-inside:avoid; } or give that outer div an extra class that you give the CSS to so that it won’t split between two pages.

catalog-section-divs

Here you see how I did the test number on the left with nothing underneath while having a lot of content on the right.  I give one column to the number and eleven to the content.

catalog-inner-divs

Looking inside of the larger div there is a lot more going on.  To start off with I use header tags which give breaks after each header and then a <p> tag around the description.  After that I create a brand new row, yup a row within a row (rowception! OK, I’ll stop), which holds even more information that we will break down next.  Last we have a simple header and table.  This table does not have a normal thead/tbody since I put the th tags and td tags on the same line.  To have consistent spacing on th/td cells across all tables I have added the CSS table { table-layout: fixed;}.

catalog-row-divs

The final piece goes even deeper as we have already been dissecting a row let’s break apart this new row.  Still using the twelve column system of Bootstrap I have given every column a spacing of 2 except the last one which is size 4 with an offset of two.  Notice how using the row on the outside gives us a fresh twelve column grid to work within inside of an already created component.  Inside of each of those grid elements you can add whatever you’d like, including more rows!  The first and second contain unformatted lists, the third is a paragraph, and the fourth contains a Bootstrap alert.

That’s all there is to it!  Bootstrap gives you everything you need to create perfectly spaced content at every level on the page.  If twelve columns isn’t right for you they even allow you to customize how big you want your columns.  I hope this was informative and demonstrated how to use Bootstrap above and beyond their simple examples on their page.  If you have any great tips when using Bootstrap please leave a comment below.

One of the biggest things I’ve run into with Bootstrap are their tables which are dynamic and grow and shrink depending on content size.  For the most part this is completely desired.  Every now and then you want a bit more control over your table column widths.  This is a very simple trick that I wanted to document for those who have run into the problem of wanting more control than Bootstrap gives initially.

Say you’ve created your table as shown below.

Let’s say once you render this table the description for the test is way too big and is pushing the other columns away and making them smaller than you think they should be.  The quickest way to fix this is to simply give column sizes to your table headers.  Whatever the width of your table headers your table data will conform to that size.  Knowing this we can alter the above example to make description take up less space and give a little bit more to other columns.

Super simple.  Works great.  Give it a try.  The biggest request I’ve had, that I have yet to find an answer for, is how to stop the overflow for a table data and show ellipsis instead using Bootstrap.  It’s a simple enough procedure in HTML but Bootstrap is doing something else that doesn’t allow the overflow.  If anyone knows how to keep a table data on one line and have it show ellipsis please leave a comment.

Bootstrap comes with a lot of different JavaScript tools to make your website more user friendly.  Today I’m going to cover Tabs and then give a more advanced example for making your tabs have dynamic content using AJAX.  We all know what tabs look like and in a website they can be very useful to group similar content without having to create a new page for each chunk of data.  Below is an example of the basic Bootstrap tabs.

You’ll notice that there are two sections to the tabs. The first is the nav-bar ul. This is where you give each tab a title. You can even do drop downs here because they are normal Bootstrap nav items.  That’s all there is to the basic Bootstrap tabs.  They work wonders and you can see the live demo on their site here.

To make each tab load in data via AJAX you’ll need to tap into Bootstrap’s triggers.  Here’s what I did using the same example as above and the JQuery below.

The trigger is fired when the tab is changed and the e.target is the event target, or in our case the newly activated tab.  Since the tab’s href points to the id of the element we want to change data we can use that to point our data to when it comes.  I’ve added a check to make sure we are only making the AJAX call if that tab is empty to help on load times of large data sets but you can remove that if you’d like.

That’s all there is to it.  Nothing too difficult but useful when you need tabs and need to change that data without reloading the page.  Let me know how you are using tabs below in the comments.

map-title

There’s just something about having a map of an address that is appealing to people.  Why just list the address like a mailing label when you can place a nice marker on an interactive Google Map?  That’s what I thought too when I was adding content to our customer profiles.  I’d never done this before but knew that Google has a great API for accessing their data as well as some pretty good examples to follow.  The API covers how to use Google Maps on any device but for the purposes of this post I will be focusing solely on web.

Let’s go over some ground rules for using Google Maps API and then move on to a very simple example and build upon it slightly.  To start off with, you can only make a limited number of requests to Google for maps data before you have to start paying.  For a small company or webpage this limit will not be a problem.

For-profit web sites are permitted to generate up to 25 000 map loads per day using the Google Maps JavaScript API v3. A map load is counted when a map is initialized on a web page. User interaction with a map after it has loaded (eg. panning the map, zooming the map, or changing from roadmap to satellite map) does not have any impact on usage limits.

That’s a lot of requests, 25,000, and I know I won’t ever get to that point but if you do Google’s got your back.  Say one day your site becomes an overnight success.  You’re serving tons of traffic and your host is demanding money for the increased CPU usage and storage and you have complaints piling up about site downtimes and slow server times the last thing you want is one more person, Google, coming to complain to you.

In order to ensure that sites which experience short term spikes in usage are not adversely affected by the Maps API usage limits, only sites that exceed the limits for more than 90 consecutive days are subject to the limits.

Nice.  Thanks Google.  After that you better apply for a Google Maps API Business License or purchase additional quota or deal with your high traffic problem and make it go away.  Now, onto our map example.  Google uses straight vanilla JavaScript and in my later example I change a few things to leverage JQuery.

Simple Map

simplemap

This is the example given by Google and it is fairly straight forward.  We have some basic HTML5 page with a map-canvas div.  Since div’s have an initial height of 0 the style is set to give it a height.  I had some issues when I tried this exact code and needed to modify it to use specific pixel height.  The specific pixel height is nice because it gives you straight control over how tall it will be.  Applying this with Bootstrap columns will give you a nice width and in my case a widescreen looking map.

The map has a number of options shown above.  Zoom is how zoomed in the map is, the higher the number the closer you are.  Center tells the map where to be centered and uses latitude and longitude, this can be changed dynamically and is what I will show in a second.  MapTypeId refers to the type of map and you can do ROADMAP, SATTELITE, HYBRID, or TERRAIN.  After that we create the map in the DOM and add it to our div.  That’s it!  Now this map is kind of simple and boring, right?  It only shows a specific location, no markers, and is hard-coded.  Let’s change a bit of that and make, still a basic map, but a geolocating map.

I wanted to create a map that would update to the address of the customer.  I have the address on the screen I was just going to pull it and make a request to Google to center the map on that location and place a marker.  Simple enough.

Simple Geolocating Map

newmap

JavaScript

HTML

I have used a little bit of JQuery to get the text from my address section and a little bit of Bootstrap to make everything look nice.  I also set the map-canvas to have a height of 150px, but that was personal preference.  It does need a height though or you will not see it.  Going through the JavaScript, I have set an initial starting location as well as set the zoom all the way out.  If the address is not found I want to just show a map of the world.  Create the map and then we need to geolocate the customer’s address.  Using Google’s geocoder this is easy because they have a variable named address and you can enter anything in there that you would normally enter into a Google Map’s search bar.  I simply grab all of the address, including the customer name, and go for the search.  If Google returns with an OK response we focus the map on that location, zoom in a bit, and add a marker to look nice.  I also created a URL to link to Google maps itself when the marker is clicked.  This was a request from some users that wanted to go to a larger map.

I also added a button that lets the user change the address if the customer is not found.  Google will make the attempt and if they can’t find it we let the user know that that address may be invalid and to check on it.  If it is right then they can just ignore this problem or report it to Google with the link at the bottom right of the map.

That’s it.  There are a lot of different things you can do with the Google Maps API including directions, custom markers, adding more markers, etc.  Take a look at all of the API documentation if you have further needs.  For us this was sufficient and a lot of people like it even if it is just a visually pleasing item and no one will actually use.  Comment below on how you are using the Maps API or if you have any questions on what I’ve done here.

UPDATE:  If you’d like to read more about Bootstrap compatability with Google Maps check out their Third party support page.

Bootstrap 3 Released

Just a quick note for everyone, Bootstrap has officially released version 3.0.0 as of Monday.  If you have been following along with the blog so far you’ll already be familiar with the major changes to Bootstrap.  This final release fixes a lot of those bugs that I’ve brought up here.  It is now stable and ready for production.  The biggest complaint I’ve seen from people is the move to the flat theme by default where the 2.3.2 version was polished and looked nice.  The good news is that Bootstrap allows you to use the new version with the old look, problem solved!  We are going to continue with the flat look because we like it but it’s totally up to you how you use Bootstrap.  Full release notes here.  Good luck!

menu-title

Designing our new internal marketing tools has been a pet project of mine for a couple of weeks now.  I spend a little time here and there adding information and tools for our employees to better understand our relationship with our clients.  I’m displaying basic contact information, some information on the kind of business we do with them, a log of notes we take, past business, and company information.  All of that equates to a rather long page of information.  All of the information is relevant and displayed in an attractive compact manner the problem is it is just so much information that it can be overwhelming.  I showed it to a coworker and he wanted tabs to flip between the various bits of information because he found it overwhelming.  I didn’t want to go to tabs because of the increased difficulty that would be added when they wanted to print off the marketing information and I didn’t feel that tabs were the right way to go here.  With that in mind I needed another solution for a large page of information that could be easily navigable…enter Bootstrap ScrollSpy.

Anyone who has looked at the Bootstrap documentation will immediately notice that has exactly the same problem I’m having; long page with lots of information.  On the left they have a static menu that follows you and highlights what section you are currently in.  Clicking on any one of those links will bring you to that portion of the page.  If it’s good enough for them it’s good enough for me so I set about recreating their side menu style.

ScrollSpy can be used with any .nav menu whether it is one your create with a ul or if it is the main nav-bar at the top of the screen.  ScrollSpy works by checking what element is currently at the top of the visible screen and adding making that nav element active.  This is great but there are a few quirks and tweeks that took me a while to figure out.

At the most basic level you want to add the HTML 5 data-spy attribute to your body because that is what we are going to spy on.  Here is the example code from Bootstrap’s documentation.

The data-target attribute needs to point to the parent element of your nav.  So if you have a nav-bar you’ll need to have an outer div or element with the id that you will use in your ScrollSpy.

Now all of your elements in your nav will need to have an href pointing to the id of the element you will be spying on.  These will need to be valid elements in your DOM.  If you are adding things dynamically and need to update your ScrollSpy use

That’s it for the simple example.  Set the data-spy and data-target on your body tag and you should be all set assuming your nav is set up properly.  One issue you may run into is not spying on the body.  When I originally started this I wasn’t spying on the body tag because I was loading in a template using Django’s block tags.  Granted it was within the body tag at one point but not specifically and I wanted to only watch my div.  ScrollSpy will only work correctly on non-body tag elements if they have a fixed height and a scroll bar.  If you do not have a scroll bar on the element you are spying on it will not work.  Your nav-bar will always have the last element as active.  To fix this just give the element you are spying on a fixed height and you should be good.  In my case instead of using the HTML 5 tags on the body I used JavaScript.  The body tag is used in every page and I didn’t want the ScrollSpy loaded on every single page.  In my JavaScript for my marketing page I have the line $("body").scrollspy({target: "#side-nav", offset:50});.  The offset tells ScrollSpy by how many pixels to offset the scroll before we are actually “in” the element.  I added some padding so when you see the header near the top we are now in the section.

To mimic the fixed sidebar used on the Bootstrap documentation use either the Affix JavaScript from Bootstrap or the affix class on your nav.  Below I have my full example and how it all works.

HTML

 JavaScript

I hide the side nav on smaller resolutions to give more screen real estate. The a tags have both a name and an id because the id is used by ScrollSpy and the name is used as a normal locator on a page.  Let me know what you think and if there are any questions or comments.

As Bootstrap nears releasing their final version of Bootstrap 3 they will continue to roll out Release Candidates for bug fixing and testing.  We have elected to keep as up to date with them as we can under the assumption that release candidates are fairly stable and shouldn’t change too much between now and release.  Tuesday they released their next release candidate, RC2.  You can read about the full changes at their blog but I’m going to highlight a few of the main things that changed for us.

Default Col is Gone

In RC1 we were using col- to be the default size for all devices.  RC2 has removed this default class.  Instead they have added a new -xs size for really small phones and a -md, though I think this was in RC1 we just never used it.  The best way to do a default size for most devices is now to use to col-sm-.  Use the small version because it works for devices with a screen resolution  of ≥768px.  This is what most modern devices are using.  Anything lower than that will default your spans to be like a col-12.  If you need to make changes for screens smaller than that use col-xs-.

Navbar Changes

Some little things changed with the navbar.  Just quick changes to classes.  You’ll need to wrap the mobile navbar header in a div with the class navbar-header.  Change nav-collapse to navbar-collapse.

Large and Small or lg and sm?

To keep consistency throughout Bootstrap they have changed many of the button classes from button-large to button-lg and button-small to button-sm. Form groups is also affected by this change.

Those are some of the main things we found.  I’m sure there are plenty of things that are affecting other people.  Head over to their blog to read all about it.  I’ll update this post if I come across anything else.

EDIT Aug 16 12:06PM

It seems we’ve stumbled upon a bug in their Modal.  When a modal is opened and then closed when you reopen it you can’t close it with the x or the close button. They are aware of the issue.  Our modals are actually all out of whack and we are looking into that right now which is how we found that bug.

EDIT Aug 16 12:20PM

Modals loaded remotely are being loaded into the modal and not the modal-body.  To fix this just move all of the divs below the modal into your remote document and that should work for now.  It’s an issue they are discussing.

EDIT Aug 19 1:01PM

When you print it uses the col-xs tag.  Make sure to update accordingly.

typeaheadjs

 

New Version – Twitter Typehead.js v0.10

Bootstrap dropped support for their bootstrap-typeahead.js and suggested we all use Twitter’s Typeahead.js.  This was a pretty big change for us and we encountered a bit of a learning curve because the documentation wasn’t exactly what we had hoped it would be.  Typeahead.js is incredible and can do some amazing things though and we are happy to be using it.

The first issue is that right out of the box it will not work with Bootstrap 3.  Support is still being looked at but in the mean time there are some fixes.  Here is a thread about the issue on their GitHub page with some helpful people posting solutions for the interim.  Below is the code we are using for ours which I’m sure will change in the coming days.

Once we got the formatting and could create our typeahead inputs we needed data for them.  We were using AJAX calls to our server to get the list as the user typed.  This worked but was a little slow.  Typeahead now has a few different ways of populating data into the input field.

Local

Local is a list of hard coded values right in your JavaScript

Prefetch

When the page is loaded the ajax call is made and stored in the browser’s local storage so the next time you visit the page it does not need to make another request unless the time-to-live has expired.  The ttl is defaulted to one day but you can change that in the options you pass.  One thing to note is that your browser has a limited amount of storage for this type of thing.  When we tried to pull our contacts list all in one go it would crash typeahead because the browser ran out of memory for local storage.  Our fix for this was that the prefetch URL would only return a limited number of entries, for example, the last 1000 updated contacts.

Remote

If the user starts to try and type something that isn’t immediately available through prefetch or local it falls back to your remote URL.  Just place the %QUERY tag in your URL and it will take what the user has entered and make a call to your server for a list using that query.

Full Example:

Templates

Typeahead supports your own custom templates for the drop down.  In our case we are just making the customer number bold and displaying their name but you could do everything from changing fonts, making inline lists, or even displaying images inline with your results.  Very cool.

Datums

We learned the hard way about a few different things when formatting results for your typeahead.  Typeahead expects a list of dictionaries with certain values, these are called datums.  Only two keys are required by typeahead, value and tokens.  After that you can add your own keys to be used by the typeahead for whatever purpose you’d like, whether it’s changing what happens on click or an image to be placed inline.  The value is the actual value of the typeahead, what the user is trying to get to.  Tokens are a list of strings that help the user get to where they want to go.  One very important note, the tokens must be single word strings — no spaces.   Spaces come across as %20 and when the user enters a normal space the typeahead doesn’t recognize that correctly.  So what we did was split the name of the company/contact into a list of separate strings for each word and that worked great.

Onward

Still playing around with it but I feel like we have a pretty good grasp on it.  Here is a list of their examples just to help drive the point home a bit further. Just waiting on the Bootstrap 3 support but overall we are happy with the new typeahead after we spent a long time trying to figure out all of the quirks we were having with it.

Hope this is helpful to others out there.

EDIT 16 September 2013

Some people were complaining about the dropdown not dynamically scaling.  Git user karimlahlou has posted this to fix that problem.

Thank you @ashleydw, finally i got it working. for those need to adjust the list width, use this function:

Hope this helps a few people.