aksjhdk asj

InK - Interface Kit

Ink JS UI

Beautiful js components to go with your project.

Ink UI Javacscript components

Ink offers a great set of Javascript components to enrich your user interface, which are easy to implement, powerful and responsive. We made these components thinking of people who don't know JS but still need to include certain features on their web pages without help from a programmer, but there is also a deep core of JS code to explore, if you're so inclined.

Next, we'll detail each component, explain it as simply as we can, provide you with all the configuration details and also provide you with links to the deeper technical docs, in case you are a developer, looking for more power under the hood.

To get started, you need to include certain scripts which will make your components work. We suggest you place these in your document's <head> and keep them all neatly organised. You will need to include:

  • ink.js which is the core code that makes everything else work
  • the modules you need (eg. ink.modal.js, if you need a modal window)
  • autoload.js, which initializes all modules, so you don't have to

You can load these components from Ink's CDN or from your local host, here's how you do it.

Code for loading from CDN

<script type="text/javascript" src="http://js.sapo.pt/js/ink.js"></script>
<script type="text/javascript" src="http://js.sapo.pt/js/ink.myModule.js"></script>
<script type="text/javascript" src="http://js.sapo.pt/js/autoload.js"></script>

Code for loading from your local host

<script type="text/javascript" src="./js/ink.js"></script>
<script type="text/javascript" src="./js/ink.myModule.js"></script>
<script type="text/javascript" src="./js/autoload.js"></script>

We'll remind you to load the correct modules for each component, using the local host method, in the documentation below. Just replace the given local host examples with the CDN URL above, if you prefer it.

If you have a better grasp of JS and do not want all components intitialized off the bat, then do not inclue autoload.js, and, instead, initialize each component by hand. You can refer to the technical documentation to see how each initialization is made.

Table

Skip to the code

The table component adds powerful features to a native HTML table, such as sorting and pagination, that will offer improved interactivity with tabular data.

All you need is a table and some simple data-attributes and you're set.

Necessary JS Modules

Before you begin, make sure you're including the necessary Javascript inside your <head>, you'll need ink.js, ink.table.js and autoload.js.

Code

<script type="text/javascript" src="./js/ink.js"></script>
<script type="text/javascript" src="./js/ink.table.js"></script>
<script type="text/javascript" src="./js/autoload.js"></script>

If you opted for not using the autoload feature, then you'll need to initialize the Table component by hand. Simply include the following code, at the end of your page, before the closing <body>

<script type="text/javascript">
    var t = new SAPO.Ink.Table('myTable');
</script>

Setting up sorting

To make your table columns sortable, you need to add the data-sortable attribute to your <th> elements. The value must be either "true" or "false" and Ink will just look a the column, figure out what kind of content it contains and then sort it, either alphabetically or numerically, depending on that content.

So, if you have a table with names and ages and you want both columns to be sortable, you simply add the data-attribute in both headers, like this:

Code

<thead>
  <th data-sortable="true">Name</th>
  <th data-sortable="true">Age</th>
</thead>

Setting up pagination

Sometimes, your tables are just too long and you need to split them up by pages, without forcing your user to skip to a different page and load an entirely new table. With Ink, all you need is to specify how many rows per page you want your table to have. If your table grows to more than the specified number of rows, then it will create a new page within the table, which you can access via a pagination-style menu. Check out the Navigation section, under pagination menus to see how they work.

To have pagination, you also need to provide an empty <nav> with an empty <ul> element for Ink to write the page navigation into. They need the .ink-navigation and .pagination classes, respectivelly. Furthermore, you can configure said pagination by adding classes to the <ul> just as detailed in the Navigation section linked above. So, you'll need this:

Code

<table data-page-size="10"> <!--tells your table to break at every 10 rows-->
  ... <!--your table content here-->
</table>
<nav class="ink-navigation"><ul class="pagination"></ul></nav> <!--pagination will be written here, automatically-->

As you can see, it's pretty easy to setup. We suggest you read our Tables section in order to create your Ink tables and then add the JS to make them work better for your users. Here's an example of a sortable and paginated table, just hit the show source code button to copy the code.

Example

Scoville Rating of Peppers

Pepper Scoville Rating
Trinidad Moruga Scorpion 1500000
Bhut Jolokia 1000000
Naga Viper 1463700
Red Savina Habanero 580000
Habanero 350000
Scotch Bonnet 180000
Malagueta 50000
Tabasco 35000
Serrano Chili 27000
JalapeƱo 8000
Poblano 1500
Peperoncino 500

<table class="ink-table alternating" data-page-size="6">
    <thead>
        <tr>
            <th data-sortable="true" width="75%">Pepper</th>
            <th data-sortable="true" width="25%">Scoville Rating</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Trinidad Moruga Scorpion</td>
            <td>1500000</td>
        </tr>
        <tr>
            <td>Bhut Jolokia</td>
            <td>1000000</td>
        </tr>
        <tr>
            <td>Naga Viper</td>
            <td>1463700</td>
        </tr>
        <tr>
            <td>Red Savina Habanero</td>
            <td>580000</td>
        </tr>
        <tr>
            <td>Habanero</td>
            <td>350000</td>
        </tr>
        <tr>
            <td>Scotch Bonnet</td>
            <td>180000</td>
        </tr>
        <tr>
            <td>Malagueta</td>
            <td>50000</td>
        </tr>
        <tr>
            <td>Tabasco</td>
            <td>35000</td>
        </tr>
        <tr>
            <td>Serrano Chili</td>
            <td>27000</td>
        </tr>
        <tr>
            <td>Jalapeño</td>
            <td>8000</td>
        </tr>
        <tr>
            <td>Poblano</td>
            <td>1500</td>
        </tr>
        <tr>
            <td>Peperoncino</td>
            <td>500</td>
        </tr>
    </tbody>
</table>
<nav class="ink-navigation"><ul class="pagination"></ul></nav>

Configurable data attributes

Here's a list of the data-attributes you can use to manage your table components.

  • data-page-size defines how many rows per page (not counting headers) your table shows, must be a numeric value. Must be applied to <table> element. Example: data-page-size="20"
  • data-sortable makes a column sortable (toggles between not sorted, ascending and descending), value must be "true" or "false" (default). Must be applied to a <th> element. Example: data-sortable="true"

For more examples, like remote data loading via AJAX, and a list of all supported options, check our technical documentation.

Tree View

Skip to the code

The Tree View component takes a structure of nested lists and transforms it into an interactive tree with expandable and collapsible branches.

Although we recommend you use primarily unordered or ordered lists, this component can be applied to any structured group of DOM elements.

Necessary JS modules

Before you begin, make sure you're including the necessary Javascript inside your <head>, you'll need ink.js, ink.treeview.js and autoload.js if you want your module to be initialized with no hassle.

Code

<script type="text/javascript" src="./js/ink.js"></script>
<script type="text/javascript" src="./js/ink.treeview.js"></script>
<script type="text/javascript" src="./js/autoload.js"></script>

If you opted for not using the autoload feature, then you'll need to initialize the Modal component by hand. Simply include the following code, at the end of your page, before the closing <body>

Code

<script>
    var treeView = new SAPO.Ink.TreeView('.ink-tree-view');
</script>

Building a tree view

To make a tree view, you need to create a list, with sub lists and make sure your first parent list has the .ink-tree-view class.

To add a small state icon, indicating if a node is opened or closed, you need to add an empty <span> in the corresponding list element. The Javascript will write the correct icon into that <span> as required.

To make your lists expand and collapse, make sure you envelop each interactive node in and anchor element with an empty href, like so: <a href="">.

Finally, you can indicate whether each node starts out closed, which is the default, or open, for which you need to simply add the .open class in the corresponding <li>.

If you check the example below, you'll see how the lists are nested, with the first branch being open by defult, then, hit the view source code button to get it. Keep reading below for more details and configurations.

Example

<ul class="ink-tree-view">
  <li class="open"><span></span><a href="#">root</a>
    <ul>
      <li><a href="">child 1</a></li>
      <li><span></span><a href="">child 2</a>
        <ul>
          <li><a href="">grandchild 2a</a></li>
          <li><span></span><a href="">grandchild 2b</a>
            <ul>
              <li><a href="">grandgrandchild 1bA</a></li>
              <li><a href="">grandgrandchild 1bB</a></li>
            </ul>
          </li>
        </ul>
      </li>
      <li><a href="">child 3</a></li>
    </ul>
  </li>
</ul>

Configurable data attributes

If by any chance you need the functionality of a tree view, with expandable and collapsible branches, but can't use a list, you can still create a functioning structure by using two data-attributes that will define which are the trigger elements and which are the interactive children.

  • data-node Identifies which of your elements are considered nodes, that can be expanded and collapsed. Value must be a valid CSS selector. The default value is li, meaning you don't need this attribute if you're using a nested list. Example: data-node=".myNode"
  • data-child Identifies which of your elements are condidered children elements within your structure. value must be a valid CSS selector. The default value is ul, meaning you don't need this attribute if you're using a nested list. Example: data-node=".myChild"

Note If you need to build a tree view with elements other than lists, then you will not benefit from Ink's defaul styling for this component and you'll have to add your own style.

Specifications and other examples, available in the technical documentation.

Sortable List

Skip to the code

The Sortable List component allows the user to reorder items on a list, by dragging and dropping.

Necessary JS modules

Before you begin, make sure you're including the necessary Javascript inside your <head>, you'll need ink.js, ink.modal.js and autoload.js to initialize the module automatically.

Code

<script type="text/javascript" src="./js/ink.js"></script>
<script type="text/javascript" src="./js/ink.sortablelist.js"></script>
<script type="text/javascript" src="./js/autoload.js"></script>

If you opted for not using the autoload feature, then you'll need to initialize the Modal component by hand. Simply include the following code, at the end of your page, before the closing <body>

Code

<script>
  var sortableList = new SAPO.Ink.SortableList('#slist');
</script>

Building a sortable list

Making a sortable list is as easy as using a class. Build a <ul> with the .ink-sortable-list class, and you're set. By default, your <li> elements can be dragged and their order changed by the user.

If you need your sortable list to work differently, check the configurable attributes after the example. Click the view source code button to get a functional snippet.

Example

  • drag hereFirst element
  • drag hereSecond element
  • drag hereThird element

<ul class="unstyled ink-sortable-list" id="slist" data-instance="sortableList9">
    <li><span class="ink-label info"><i class="icon-reorder"></i>drag here</span>primeiro</li>
    <li><span class="ink-label info"><i class="icon-reorder"></i>drag here</span>segundo</li>
    <li><span class="ink-label info"><i class="icon-reorder"></i>drag here</span>terceiro</li>
</ul>

Configurable data attributes

  • data-drag-object Allows you to set which element is draggable. Default is <li>, can be set to any CSS selector. Example: data-drag-object=".myClass".

If you check the example code above, you'll see we created a "drag here" label and made that the draggable element with data-drag-object=".ink-label"

Check our technical documentation for further configuration.

Date Picker

Skip to the code

The date picker component adds a flyout calendar to a textbox, within a form, so your users can just click the box and pick a date, visually, instead of having to guess the date format or you having to print specific instructions to explain that format.

Using the date picker also guarantees that you get your dates in the format you need, without extra form validation.

Necessary JS modules

Before you begin, make sure you're including the necessary Javascript inside your <head>, you'll need ink.js, ink.datepicker.js and autoload.js.

Code

<script type="text/javascript" src="./js/ink.js"></script>
<script type="text/javascript" src="./js/ink.datepicker.js"></script>
<script type="text/javascript" src="./js/autoload.js"></script>

If you opted for not using the autoload feature, then you'll need to initialize the component by hand. Simply include the following code, at the end of your page, before the closing <body>

<script type="text/javascript">
    var picker = new SAPO.Ink.DatePicker('#myDatePicker');
</script>

Getting started

Creating a date picker couldn't be easier. All you need is a text input in your form, tagged with the .ink-datepicker class. And that is all.

Like other Ink Javascript components, the date picker is configurable by using data-attributes, which we will detail below. For now, let's see what your code should look like. Remember, you are within a form, so go read up on Ink forms, if you need to.

Code

<input type="text" id="date" class="ink-datepicker">

That is the basic of basics for getting a date picker, but there is a more complete example below, grab the code by hitting the view code button. Then, you can read up on all the ways you can configure your date picker, using data-attributes.

<div class="control-group">
    <label for="dPicker">A date field:</label>
    <div class="control">
        <input id="dPicker" class="ink-datepicker" type="text"></input>
    </div>
</div>

Using the calendar

The calendar has some really useful features you might want to be aware of. On the top left corner you have a link to clear the input box, in case you've entered a wrong date, and on the top right, you can click to close the calendar.

On the next line, you have navigation chevrons on either side, that will allow you to navigate by month and in the center, you can click either the month name to directly pick another month, or the year, to pick a different year, without having to navigate by hand to those dates. When you click a day, the date gets written into the input field. Just click the above example and try it out.

Configurable data attributes

To further configure your date picker, just add data-attributes to your text input field. Here's a comprehensive list of all the attributes you can use on the date picker.

  • data-format sets the date format which will be written into the text input and submitted with the form. The default value is data-format="yyyy-mm-dd" but there are many different options as you can see below:

    • yyyy-mm-dd - Ex: 2013-05-27 (default)
    • yyyy/mm/dd - Ex: 2013/05/27
    • yy-mm-dd Ex: 13-05-27
    • yy/mm/dd Ex: 13/05/27
    • dd-mm-yyyy - Ex: 27-05-2013
    • dd/mm/yyyy - Ex: 27/05/2013
    • dd-mm-yy Ex: 27-05-13
    • dd/mm/yy Ex: 27/05/13
    • mm-dd-yyyy - Ex: 05-27-2013
    • mm/dd/yyyy - Ex: 05/27/2013

  • data-position specifies where the calendar will appear, relative to the input field. Example: data-position="bottom". Possible values are:

    • bottom
    • left

  • data-css-class sets a class for the calendar. The default value is data-css-class="sapo_component_datepicker", but you can change it to any class you need to use in your project to style the calendar.

  • data-start-date sets a start date, that will be selected when you open the calendar. It must be defined in the following format: yyyy-mm-dd. Example: data-start-date="2013-01-01"

There are other configurations, some specific for Javascript, available on the technical documentation.

Tabs

Skip to the code

The Tabs Component offers a simple way to build a tab-separated layout, allowing you to offer multiple content in the same space with intuitive navigation.

Necessary JS modules

Before you begin, make sure you're including the necessary Javascript inside your <head>, you'll need ink.js, ink.tabs.js and autoload.js to initialize the module automatically.

Code

<script type="text/javascript" src="./js/ink.js"></script>
<script type="text/javascript" src="./js/ink.modal.js"></script>
<script type="text/javascript" src="./js/autoload.js"></script>

If you opted for not using the autoload feature, then you'll need to initialize the Tabs component by hand. Simply include the following code, at the end of your page, before the closing <body>

Notice that, in this particular case, when initializing the module, you'll have to declare which tab is active on load and which aren't, by using their respective indexes.

Code

<script type="text/javascript">
var tabs = new SAPO.Ink.Tabs('.ink-tabs', {
        disabled: ['#stuff', '#more_stuff'], 
        active: '#news',
        onBeforeChange: function(tab){
            console.log('beforeChange', tab);
        }, 
        onChange: function(tab){
            console.log('Changed', tab);
        }
    });
</script>

Building tabs

To make a tabbed view, you'll need a block element with the .ink-tabs class, such as a <div>, within which you'll have a <ul> for your tabbed navigation and a set of <div> elements to hold the content of each tab. Your .ink-tabs element should also have a class to determine where the navigation will be in relation to the content: .top, .bottom, .left or .right

The <ul> must have the .tabs-nav class and each list element must be wrapped in an anchor pointing to a valid ID in the content of the tabs.

Each of the <div> holding the content, must have the .tabs-content class and an ID that matches the navigation anchors.

If you're making a tabbed view with tabs on top, on the left or on the right, put the navigation first in your markup, if you need the tabs at the bottom, then, put the content first and the navigation after.

Examples of each and a full code snippet will follow, but for now, let's look at an example code, just to clarify everything.

Example Code

<div class="ink-tabs top"> <!-- Creates a tabbed view with top nav -->
  <ul class="tabs-nav">
    <li><a href="#item1">Item 1</a></li> <!-- Points to item 1 below -->
    <li><a href="#item2">Item 2</a></li> <!-- Points to item 2 below -->
    ...
  </ul>
  <div id="item1" class="tabs-content"> <!-- Item 1 -->
    ... <!-- Your tab content here -->
  </div>
  <div id="item2" class="tabs-content"> <!-- Item 2 -->
    ... <!-- Your tab content here -->
  </div>
  ...
</div>

Example With top navigation

Shotgun

The shotgun fires once every 500ms. It fires 6 pellets per attack, and each pellet does 4 damage, making for a maximum possible damage of 24. Pellets are arranged in a random pattern around the crosshair.

Range is 2048 units.

The shotgun is a hitscan weapon; when the attacker fires, traces are performed to see what the player is aiming at, in that very same frame. There are no moving projectiles.

Nailgun

The nailgun is a projectile weapon; projectile weapons fire actual objects with a finite speed.

The nailgun may fire every 100ms. Nails travel at 1000ups, and dissappear after 6 seconds if they haven't hit anything.

Nails do 9 damage per hit, and are fired alternatively from 5u left of the crosshair, then 5u right of the crosshair. Nails are a point.

Rocket Launcher

The rocket launcher may fire every 800ms. Like nails, rockets travel at 1000ups, and are not affected by gravity. A direct hit by a rocket does a random amount of damage between 100 and 120 (or fixed 110 in KTX).

All hits, direct or not, do 120 splash damage (over a 160u radius, like the grenade launcher), however objects that are hit directly are immune to this splash damage.

This avoids making the rocket launcher too destructive.

Lightning Gun

The lightning gun fires every 100ms. It has a range of 600u, and is a hitscan weapon. It does 30 damage per hit, and may damage up to 3 damagable objects in that 600u range per hit.

When fired underwater in deathmatch mode 3, the lightning gun does (35 x number of cells in gun) splash damage, with the firer as the centre. The radius is the damage (35 x cells), plus 40.

A few rules change in DMM4. Discharging only works a random 50% of the time, the rest of the time you do 4000 damage to yourself only. Additionally, the lightning gun is disabled when you obtain Quad.

Example With bottom navigation

Shotgun

The shotgun fires once every 500ms. It fires 6 pellets per attack, and each pellet does 4 damage, making for a maximum possible damage of 24. Pellets are arranged in a random pattern around the crosshair.

Range is 2048 units.

The shotgun is a hitscan weapon; when the attacker fires, traces are performed to see what the player is aiming at, in that very same frame. There are no moving projectiles.

Nailgun

The nailgun is a projectile weapon; projectile weapons fire actual objects with a finite speed.

The nailgun may fire every 100ms. Nails travel at 1000ups, and dissappear after 6 seconds if they haven't hit anything.

Nails do 9 damage per hit, and are fired alternatively from 5u left of the crosshair, then 5u right of the crosshair. Nails are a point.

Rocket Launcher

The rocket launcher may fire every 800ms. Like nails, rockets travel at 1000ups, and are not affected by gravity. A direct hit by a rocket does a random amount of damage between 100 and 120 (or fixed 110 in KTX).

All hits, direct or not, do 120 splash damage (over a 160u radius, like the grenade launcher), however objects that are hit directly are immune to this splash damage.

This avoids making the rocket launcher too destructive.

Lightning Gun

The lightning gun fires every 100ms. It has a range of 600u, and is a hitscan weapon. It does 30 damage per hit, and may damage up to 3 damagable objects in that 600u range per hit.

When fired underwater in deathmatch mode 3, the lightning gun does (35 x number of cells in gun) splash damage, with the firer as the centre. The radius is the damage (35 x cells), plus 40.

A few rules change in DMM4. Discharging only works a random 50% of the time, the rest of the time you do 4000 damage to yourself only. Additionally, the lightning gun is disabled when you obtain Quad.

Example With left navigation

Shotgun

The shotgun fires once every 500ms. It fires 6 pellets per attack, and each pellet does 4 damage, making for a maximum possible damage of 24. Pellets are arranged in a random pattern around the crosshair.

Range is 2048 units.

The shotgun is a hitscan weapon; when the attacker fires, traces are performed to see what the player is aiming at, in that very same frame. There are no moving projectiles.

Nailgun

The nailgun is a projectile weapon; projectile weapons fire actual objects with a finite speed.

The nailgun may fire every 100ms. Nails travel at 1000ups, and dissappear after 6 seconds if they haven't hit anything.

Nails do 9 damage per hit, and are fired alternatively from 5u left of the crosshair, then 5u right of the crosshair. Nails are a point.

Rocket Launcher

The rocket launcher may fire every 800ms. Like nails, rockets travel at 1000ups, and are not affected by gravity. A direct hit by a rocket does a random amount of damage between 100 and 120 (or fixed 110 in KTX).

All hits, direct or not, do 120 splash damage (over a 160u radius, like the grenade launcher), however objects that are hit directly are immune to this splash damage.

This avoids making the rocket launcher too destructive.

Lightning Gun

The lightning gun fires every 100ms. It has a range of 600u, and is a hitscan weapon. It does 30 damage per hit, and may damage up to 3 damagable objects in that 600u range per hit.

When fired underwater in deathmatch mode 3, the lightning gun does (35 x number of cells in gun) splash damage, with the firer as the centre. The radius is the damage (35 x cells), plus 40.

A few rules change in DMM4. Discharging only works a random 50% of the time, the rest of the time you do 4000 damage to yourself only. Additionally, the lightning gun is disabled when you obtain Quad.

Example With right navigation

Shotgun

The shotgun fires once every 500ms. It fires 6 pellets per attack, and each pellet does 4 damage, making for a maximum possible damage of 24. Pellets are arranged in a random pattern around the crosshair.

Range is 2048 units.

The shotgun is a hitscan weapon; when the attacker fires, traces are performed to see what the player is aiming at, in that very same frame. There are no moving projectiles.

Nailgun

The nailgun is a projectile weapon; projectile weapons fire actual objects with a finite speed.

The nailgun may fire every 100ms. Nails travel at 1000ups, and dissappear after 6 seconds if they haven't hit anything.

Nails do 9 damage per hit, and are fired alternatively from 5u left of the crosshair, then 5u right of the crosshair. Nails are a point.

Rocket Launcher

The rocket launcher may fire every 800ms. Like nails, rockets travel at 1000ups, and are not affected by gravity. A direct hit by a rocket does a random amount of damage between 100 and 120 (or fixed 110 in KTX).

All hits, direct or not, do 120 splash damage (over a 160u radius, like the grenade launcher), however objects that are hit directly are immune to this splash damage.

This avoids making the rocket launcher too destructive.

Lightning Gun

The lightning gun fires every 100ms. It has a range of 600u, and is a hitscan weapon. It does 30 damage per hit, and may damage up to 3 damagable objects in that 600u range per hit.

When fired underwater in deathmatch mode 3, the lightning gun does (35 x number of cells in gun) splash damage, with the firer as the centre. The radius is the damage (35 x cells), plus 40.

A few rules change in DMM4. Discharging only works a random 50% of the time, the rest of the time you do 4000 damage to yourself only. Additionally, the lightning gun is disabled when you obtain Quad.

<div class="ink-tabs top"> <!-- replace 'top' with 'bottom', 'left' or 'right' to place navigation -->
    
    <!-- put navigation first if using top, left or right positioning -->
    <ul class="tabs-nav">
        <li><a href="#home">Home</a></li>
        <li><a href="#news">News</a></li>
        <li><a href="#description">Description</a></li>
        <li><a href="#stuff">Stuff</a></li>
        <li><a href="#more_stuff">More stuff</a></li>
    </ul>
    
    <!-- Put your content second if using top, left or right navigation -->
    <div id="home" class="tabs-content"><p>Content</p></div>
    <div id="news" class="tabs-content"><p>Content</p></div>
    <div id="description" class="tabs-content"><p>Content</p></div>
    <div id="stuff" class="tabs-content"><p>Content</p></div>
    <div id="more_stuff" class="tabs-content"><p>Content</p></div>
    <!-- If you're using bottom navigation, switch the nav block with the content blocks -->

</div>

Configurable Data Attributes

As with most Ink JS components, you can add extra features to the tabs via data attributes. Check the following list for attributes you can add to your .ink-tabs <div>

  • data-prevent-url-change Prevents the URL from being changed when navigating between tabs. Value must be boolean, "true" (default) or "false". Example: data-prevent-url-change="false"
  • data-active Allows specifying which of the tabs is open by default. Value must be an ID present in the markup structure of the tabs. Example: data-active="#secondItem"

You can see several examples in the technical documentation.

Form Validator

The Form Validator component provides an easy way to validate forms before submitting them. It can:

  • Detect required fields
  • Validate some field types
  • Detect match with password and confirmation password
  • Use custom field types

Necessary JS modules

Before you begin, make sure you're including the necessary Javascript inside your <head>, you'll need ink.js and ink.formvalidator.js.

Code

<script type="text/javascript" src="./js/ink.js"></script>
<script type="text/javascript" src="./js/ink.formvalidator.js"></script>

Notice that, contrary to other modules, you don't really need to initialize the Form Validator, as the validation request is made on form submission.

Validating

There are two components that you need to use in order to validate a form using Ink. You'll have to request validation on form submission and you'll have to tag the input elements with certain classes to tell Ink what to validate.

So, start by building your form (make sure you read the sction on forms), and add the bit of Javascript that tells Ink to do the validation in your <form>, like this:

<form class="ink-form" method="post" action="#" onsubmit="return SAPO.Ink.FormValidator.validate(this);">

Once you have the onsubmit attribute set, you need to 'tag' each of your input elements (text, radio buttons, select boxes, etc), with one or more validation classes. Refer to the following list to see what they do:

  • .ink-fv-required - Checks if the form field has been filled/set.
  • .ink-fv-email - Checks if the form field value is a valid e-mail address.
  • .ink-fv-url - Checks if the form field value is a valid URL.
  • .ink-fv-number - Checks if the form field value is a number.
  • .ink-fv-phone_pt - Checks if the form field value is a valid Portuguese telephone.
  • .ink-fv-phone_cv - Checks if the form field value is a valid Cabo Verde's telephone.
  • .ink-fv-phone_mz - Checks if the form field value is a valid Mozambique's telephone.
  • .ink-fv-phone_ao - Checks if the form field value is a valid Angola's telephone.
  • .ink-fv-date - Checks if the form field value is a valid date.
  • .ink-fv-confirm - A pair of form fields with this class will be checked if they're value match each other.
  • .ink-fv-custom - Through JavaScript is possible to define a custom function that will be used to check if the field is valid or not.

More examples and detailed configurations, in the technical documentation.

Please select one option

<form id="myform" class="ink-form" method="post" action="#" onsubmit="return SAPO.Ink.FormValidator.validate(this);">
    <fieldset>
        <div class="control-group required">
            <label for="name">Name:</label>
            <div class="control">
                <input type="text" name="name" id="name" class="ink-fv-required" />
            </div>
        </div>
        
        <div class="control-group required">
            <label for="mail">Email:</label>
            <div class="control">
                <input type="text" name="mail" id="mail" class="ink-fv-required ink-fv-email" />
            </div>
        </div>
        
        <div class="control-group required">
            <label for="pass">Password: </label>
            <div class="control">
                <input type="password" name="pass" id="pass" class="ink-fv-required ink-fv-confirm" />
            </div>
        </div>
        
        <div class="control-group required">
            <label for="confpass">Confirm Password:</label>
            <div class="control">
                <input type="password" name="confpass" id="confpass" class="ink-fv-required ink-fv-confirm" />
            </div>
        </div>
        
        <div class="control-group required">
            <p class="label">Please select one option</p>
            <ul class="control unstyled">
                <li><input type="radio" name="radio1" id="radio1_g" value="1" class="ink-fv-required" /> <label for="radio1_g">radio 1</label> </li>
                <li><input type="radio" name="radio1" id="radio2_g" value="2" class="ink-fv-required" /> <label for="radio2_g">radio 2</label> </li>
                <li><input type="radio" name="radio1" id="radio3_g" value="3" class="ink-fv-required" /> <label for="radio3_g">radio 3</label> </li>
            </ul>
        </div>
    </fieldset>
    <div>
        <input type="submit" name="sub" value="Submit" class="ink-button success" />
    </div>
</form>

Progress bar

The Progress Bar component gives the .ink-progress-bar markup it's animated behavior.

It also allows the user to set the progress in runtime.

This component has the following configurable data-attributes:

  • Start Value (data-start-value) - This attribute holds an integer, from 0 to 100, that will specify the initial progress of the component. Default value is 0.
I am a grey progress bar
I am a green progress bar
I am a blue progress bar
I am a red progress bar
I am a orange progress bar
I am a black progress bar
    <div class="ink-progress-bar grey" data-start-value="70%">
        <span class="caption">I am a grey progress bar</span>
        <div class="bar grey"></div>
    </div>
    <div class="ink-progress-bar green" data-start-value="60%">
        <span class="caption">I am a green progress bar</span>
        <div class="bar green"></div>
    </div>
    <div class="ink-progress-bar blue" data-start-value="50%">
        <span class="caption">I am a blue progress bar</span>
        <div class="bar blue" style="width: 50%"></div>
    </div>
    <div class="ink-progress-bar red" data-start-value="40%">
        <span class="caption">I am a red progress bar</span>
        <div class="bar red"></div>
    </div>
    <div class="ink-progress-bar orange" data-start-value="30%">
        <span class="caption">I am a orange progress bar</span>
        <div class="bar orange"></div>
    </div>
    <div class="ink-progress-bar black" data-start-value="20%">
        <span class="caption">I am a black progress bar</span>
        <div class="bar black"></div>
    </div>
    <script>
        var 
            progressBarsElms = SAPO.Dom.Selector.select('.ink-progress-bar'),
            progressBars = [],
            i
        ;
        for(i = 0; i < progressBarsElms.length; i += 1){
            progressBars.push(new SAPO.Ink.ProgressBar( progressBarsElms[i] ));
        }
    </script>

Image Query

The Image Query component allows you to load different image sources, depending on the viewport width. It has the following features:

  • Template-system-like source - This allows you to set how the src attribute will change depending on the settings defined.
  • Retina-aware - If you have images specially crafted for retina displays, you only need to provide a specific source (via the retina key) and the component will load them instead of the regular ones

More specifications and other examples, available in the technical documentation.

<div class="imageQueryExample large-100 medium-100 small-100 content-center clearfix vspace">
    <img src="/assets/imgs/imagequery/small/image.jpg" />
</div>
<script type="text/javascript">
    var tv1 = new SAPO.Ink.ImageQuery('.imageQueryExample img',{
        src: '/assets/imgs/imagequery/{:label}/{:file}',
        queries: [
            {
                label: 'small',
                width: 480
            },
            {
                label: 'medium',
                width: 640
            },
            {
                label: 'large',
                width: 1024
            }
        ]
    });
</script>

Behaviors

Sticky

Sticky keeps an element "stuck" as you scroll the rest of the page. The best example is the side menu on this website. To use it, add the .sticky class to a block-level element in your layout.

Check the technical documentation for more details.

Toggle

Collapsible turns your horizontal menus into vertical ones depending on the screen width. It gives you the possibility to collapse/expand your menus.

Activate it by using the ink-collapsible class. A working example of collapsible is the top most menu.

Check the technical documentation for more details.

Dismiss

When clicking an element with the ink-close class, the first ink-alert or ink-alert-block ancestor is removed from the document.

Activate it by using the ink-close class inside of an element with one of the previously mentioned classes.

Check the technical documentation for more details.