Showing posts with label jQuery. Show all posts
Showing posts with label jQuery. Show all posts

Tuesday 28 November 2023

Revisit "How to make the entire page fade in on load" using Vue.js

 index.html

<!DOCTYPE html>

<html lang="en">

  <head>

    <meta charset="UTF-8" />

    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <title>Body Fade In</title>

    <link rel="stylesheet" href="./style.css" />

  </head>

  <body>

    <transition name="fade" appear>

      <h1>Hello World!</h1>

    </transition>

    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

    <script src="./app.js"></script>

  </body>

</html>

style.css

.fade-enter-active,

.fade-leave-active {

  transition: opacity 1s;

}

.fade-enter-from,

.fade-leave-to {

  opacity: 0;

}

app.js

const app = Vue.createApp({});

app.mount("body");

Revisit "Simple tab navigation using jQuery" using Vue.js

This is the first of a series in which I revisit old blog posts which made use of JavaScript and jQuery. I attempt to implement them, this time using Vue.js in order to improve my Vue.js skills.
First up is one from 2010 titled Simple tab navigation using jQuery.

index.html
<html lang="en">
  <head>
    <meta charset="UTF-8"></meta>
    <title>Tabbed Navigation</title>
    <style type="text/css">
      body {
        font-family: Sans-serif;
      }
      #subSystem {
        margin: 0 auto;
        width: 400px;
      }
      #subNav a.subMenu {
        display: block;
        text-decoration: none;
        float: left;
        text-align: center;
        width: 5rem;
        height: 2.5rem;
        padding-top: 1rem;
        border-top: 0.0625rem solid #ccc;
        border-left: 0.0625rem solid #ccc;
        border-right: 0.0625rem solid #ccc;
        color: #000;
      }
      #subNav a.subMenu:hover {
        background: #a3a3a3;
        color: #fff;
      }
      .menuSelected {
        background: #ccc;
        color: #fff;
      }
      #subContent {
        clear: left;
        min-height: 25rem;
        height: 25rem;
        border: 0.0625rem solid #ccc;
      }
    </style>
  </head>
  <body>
    <div id="subSystem">
      <div id="subNav">
        <a class="subMenu menuSelected" click="loadContent" href="./subPage1.html">First</a>
        <a class="subMenu" click="loadContent" href="./subPage2.html">Second</a>
        <a class="subMenu" click="loadContent" href="./subPage3.html">Third</a>
      </div>
      <div id="subContent"></div>
    </div>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <script src="./app.js"></script>
  </body>
</html>

app.js

const app = Vue.createApp({
  methods: {
    loadContent(event) {
      event.preventDefault();
      const href = event.target.getAttribute("href");
      fetch(href)
        .then((response) => response.text())
        .then((data) => {
          document.getElementById("subContent").innerHTML = data;
        })
        .catch((error) => {
          console.error("Error loading content:", error);
        });
    },
  },
  mounted() {
    // Simulate a click on the first tab when the page loads
    const firstTab = document.querySelector(".subMenu.menuSelected");
    if (firstTab) {
      firstTab.click();
    }
  },
});

app.mount("#subSystem");

Friday 11 May 2018

The 2018 Web Developer : JavaScript JSON processing without jQuery

Enter 'fetch'. The JavaScript API which performs HTTP requests.
First, I'll need to get fetch.
To add it to your project, change to your project directory:
cd myApp
Then use the following command:
npm install node-fetch --save

In this example, I have a simple .json file which contains a set of URLs and their types.

const fetch = require('node-fetch');
const url = 'feeds.json';
var myFetch = fetch(url);

myFetch.then(response=>response.json()).then(function(data) {
    showMyData(data);
  });

function showMyData(md)
{
  md.forEach((value) => {
    console.log(value.URL, value.TYPE);
  });
}

Thursday 10 May 2018

The 2018 Web Developer : Animating without jQuery

There's not much wrong with jQuery other than it's size. Sometimes when you want to keep your website very lean you may wish to rely on pure JavaScript. In this case, I use the excellent animate.css. Even better than that, you can use animate.scss.
To add it to your project, change to your project directory:
cd myApp/git
Then use the following command:
git clone https://github.com/geoffgraham/animate.scss
Here is an example page which, on page load brings in animate.css and runs the function doTheSlide, to animate the contents of the H1 tag.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Do the slide</title>
<link rel="stylesheet" href="scss/custom.css" />
</head>
<body>
  <h1>Hello world!</h1>
</body>
</html>
Nothing happens until you create your scss file. custom.css is created thus:
cd myApp/scss
node-sass -w custom.scss custom.css
Now let's put some clever stuff in the custom.scss file.
@import "../git/animate.scss/animate.scss";
h1 {
  @include slideInLeft();
}
Refresh the browser and, hey presto! Now we're animating.

Tuesday 24 April 2018

Live data to your page using EventSource

In the following example I deliver live data to a web page. It's possible to do this quite easily using node.js and socket.io. However most of the websites I create are delivered through a shared server and the providers won't let me install node.js, so here I provide an alternative.
In this instance I use a combination of HTML, JavaScript and PHP. It would also be possible to use jQuery instead of straight JavaScript and PHP with something like python or indeed any other language. I also use a JSON file which could be replaced by any other data source.

Let's begin with data source tester.json
[
{
"name": "Aragorn",
"race": "Human"
},
{
"name": "Gimli",
"race": "Dwarf"
}
]

Now, the HTML file (index.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Live data connectivity</title>
</head>
<body>
<table id="myTable">
  <thead>
    <tr>
      <th>Name</th>
      <th>Race</th>
    </tr>
  </thead>
  <tbody></tbody>
</table>
<script src="updatetables.js"></script>
<script src="run.js"></script>
</body>
</html>

Basically we need to check if the HTML table has any data inside. if it doesn't we take data from the data source. If the HTML table does contain data, it will be updated with the contents of the data source. To achieve this we'll use a function inside updatetables.js.
function updateTable(jd, id)
{
  var tbody = document.getElementById(id).tBodies[0];
  for (var i = 0; i < jd.length; i++)
  {
    if(tbody.rows[i] == null)
    {
      /* No data in HTML table */
      var row = tbody.insertRow(i);
      var x = row.insertCell(0);
      x.innerHTML = jd[i].name;
      x = row.insertCell(1);
      x.innerHTML = jd[i].race;
    }
    else
    {
      /* Data in HTML table. Needs updating. */
      var row = tbody.rows[i];
      tbody.rows[i].cells[0].innerHTML = jd[i].name;
      tbody.rows[i].cells[1].innerHTML = jd[i].race;
    }
  }
}

Now that we have a means of updating the table, we need to get the data using stream.php
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$JSON = file_get_contents('tester.json');
echo 'data: '.json_encode($JSON).PHP_EOL.PHP_EOL;
flush();
?>

Finally we can use the JavaScript EventSource object to call stream.php and get our data. Once we have our data, we can pass it to updatetables.js. This is done through run.js
var source = new EventSource('stream.php');
var tableid = 'myTable';
source.onmessage = function(event)
{
  var jsonData = JSON.parse(event.data);
  jsonData = JSON.parse(jsonData);
  updateTable(jsonData, tableid);
};

If you have recreated these files, to test it all works, try changing the values of items in tester.json and see the updates on your page without refresh.




Tuesday 28 March 2017

jQuery media queries plugin

Media queries are really useful in CSS, but what if you could use them to control page events and content using jQuery. I have created the beginnings of a solution below.

Here we have 2 files:
  • index.html
  • mediaquery.plugin.js

index.html is a very basic page which passes the window object to mediaquery.plugin.js.

mediaquery.plugin.js listens for changes in the window width and reacts accordingly.

In this case it simply changes the background colour of the body which calls the plugin, but of course, this is only the start. In place of changing the page colour, you could do all sorts of useful things. For example, you could pass the identifier of a div the plugin and add external content to it. The list is endless. Have fun!


index.html

<!DOCTYPE html>
<html lang="en">
<head>
<title>jQuery media queries</title>
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="mediaquery.plugin.js"></script>
<script>
(function()
{
    $(window).mediaquery();
})();
</script>
</body>
</html>

mediaquery.plugin.js

(function($)
{
    $.fn.mediaquery = function(options)
    {
        var defaults =
        {
            phone:'blue',
            tablet:'red',
            desktop:'green'
        };
        options = $.extend(defaults, options);

        $(this).handleWidths(options);
        $(this).resize(function()
        {
            $(this).handleWidths(options);
        });
    }
})(jQuery);

$.fn.handleWidths = function(opt)
{
    if($(this).width() < 481)
    {
        $(this).phoneFunc(opt.phone);
    }
    else if($(this).width() < 769)
    {
        $(this).tabletFunc(opt.tablet);
    }
    else
    {
        $(this).desktopFunc(opt.desktop);
    }
}

$.fn.phoneFunc = function(str)
{
    $('body').css('background-color', str);
};

$.fn.tabletFunc = function(str)
{
    $('body').css('background-color', str);
};

$.fn.desktopFunc = function(str)
{
    $('body').css('background-color', str);
};


Wednesday 10 August 2016

Using jQuery FormData to include files when making POST request

In this example I create a form, with a text, and file input field. When I submit the form, contents from all input fields are submitted through the 'FormData' class. The results from the called script are returned to a div. Finally, the fields are then cleared.
<html>
<head>
    <title>jQuery File Upload</title>
</head>
<body>
    <form action="upload.php" method="POST" enctype="multipart/form-data">
        <input type="text" name="myname" />
        <input type="file" name="fileinfo" multiple="" />
        <button type="submit">Submit</button>
    </form>
    <div id="result"></div>
    <script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
    <script>  
    (function()
    {
        $('form').on('submit', function(e)
        {
            var theDiv = $('div#result');
            var thisForm = $(this);
            var action = thisForm.attr('action');
            var method = thisForm.attr('method');
            $.ajax(
            {
                url: action,
                type: method,
                data: new FormData(this),
                processData: false,
                contentType: false
            }).done(function(datareceived)
            {
                thisForm.find('input, textarea').val('');
                theDiv.html(datareceived);
            });
            e.preventDefault();
        });
    })();
    </script>
</body>
</html>

To test if it works I use upload.php. See
<?php
$str = NULL;
foreach($_FILES as $file)
{
    if(move_uploaded_file($file['tmp_name'], $file['name']) == FALSE)
    {
        $str .= $file['name'].' not uploaded<br />';
    }
}
$str .= '<br />POST items include : <br />';
foreach($_POST as $postitem => $value)
{
    $str .= 'Name : '.$postitem.' Value : '.$value.'<br />';
}
echo $str;
?>

Monday 25 July 2016

Ratings field within Bootstrap using Font Awesome stars

I looked around for a nice easy rating field using stars. Just like the ones you find on tripAdvisor. All the solutions looked a little CSS or JS heavy and needed images which are more HTTP connections.
So my solution uses only a little CSS, a small amount of jQuery and font-awesome. You'll have to get font-awesome for it to work.
See below.
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <title>Font awesome stars</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
    <link rel="stylesheet" href="font-awesome/css/font-awesome.min.css" />
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
    <style>
    .star-selected
    {
      color:pink;
    }
    </style>

  </head>
  <body>
<form method="POST" action="someaction.php">
      <div class="form-group">
        <input type="hidden" name="stars">
        <i class="fa fa-star" aria-hidden="true" value="1"></i>
        <i class="fa fa-star" aria-hidden="true" value="2"></i>
        <i class="fa fa-star" aria-hidden="true" value="3"></i>
        <i class="fa fa-star" aria-hidden="true" value="4"></i>
        <i class="fa fa-star" aria-hidden="true" value="5"></i>
      </div>
      <button type="submit">Submit</button>
    </form>

   
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
    <script>
    (function()
    {
      var theStars = $('form').find('i');
      $('i').on('click', function()
      {
        theStars.removeClass('star-selected');
        var theStarIclicked = $(this);
        var highVal = theStarIclicked.attr('value');
        theStarIclicked.addClass('star-selected');
        $("input[name='stars']").attr('value',highVal);
        theStars.each(function(i)
        {
          if($(this).attr('value') < highVal)
          {
            $(this).addClass('star-selected');
          }
        });       
        console.log('Star selected '+$("input[name='stars']").attr('value'));
      });
    })();
    </script>

  </body>
</html>

Wednesday 6 April 2016

jQuery plugin to insert external content

This jQuery plugin takes 2 parameters:
  1. The location of an external website
  2. The element within that location which contains content you would like to insert in yours
See the code here

Wednesday 23 March 2016

jQuery plugin which takes and receives form data

This jQuery plugin to take all form data, pass it to a named script and return a message to a named HTML element. Particularly good with Twitter Bootstrap.
See the code here.

Use jQuery to handle GET requests in a Twitter Bootstrap page

Today, I created a jQuery plugin. It takes GET requests via apage URL and passes the content to declared HTML elements.
See the code here.

HTML includes like PHP using jQuery

Here I have created a jQuery plugin to perform HTML includes (sub pages)  similar to method possible in PHP.
Find the code here.

Dynamically make items active in Twitter Bootstrap navigation using jQuery

Here, I have created a jQuery plugin. It takes as its parameter the elements containing navigation items from a Twitter Bootstrap page. The plugin then matches the page URL with a navigation item and makes it active.
Find the code here.

Monday 21 March 2016

H1 shows window width

I'm often trying understand which media queries to add to my CSS in order to control changes in the display of content. For this I need to see the window width as it resizes. There are other ways, but I find it more convenient if the page title show the window width.
To enable this, I add the following jQuery code, which is also available as a public gist here.
$(window).resize(function()
{
  $('h1').text($(window).width());
});

Golden ratio

I've been reading this article recently on use of the golden ratio within web design.
As a result I've developed a jQuery plugin to help in its implementation within my pages. You can find it here on my github page. It also include an index.html and custom.css to help demonstrate its use.
There are 2 implementations:
  1. Creating a rectangle where the golden ratio width is derived from the height
  2. Creating 2 rectangles based on their container height
Hope they help.

Tuesday 16 June 2015

Change content using select menu in a Bootstrap page with the help of jQuery

I recently delivered the solution to a stackoverflow question. The question was around using a select menu to display different content contained in divs using jQuery.
Below is the solution, but the only difference is that I've contained it in a Bootstrap page. The important bit are highlighted in red.
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">  
    <title>Bootstrap select content</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
    <style>
    body
    {
      padding-top:2em;
    }
    </style>
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
    <div class="row">
      <div class="container">
        <div class="col-md-12">
          <select name="type" id="type" class="form-control">
            <option>Select some content</option>
            <option value="bar">Bar</option>
            <option value="restaurant">Restaurant</option>
            <option value="hotel">Hotel</option>
          </select>
          <hr />
          <div id="bar" class="type well">Bar</div>
          <div id="restaurant" class="type well">Restaurant</div>
          <div id="hotel" class="type well">Hotel</div>
        </div>
      </div>
    </div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
    <script>
    (function()
    {
      $('div.type').hide();
      $('#type').change(function()
      {
          $('div.type').hide();
          $('#'+$(this).val()).toggle();
      });
    })();
    </script>
  </body>
</html>

Wednesday 10 June 2015

Bootstrap formhandler calling class methods with JSON returned and processed

This entry offers a number of techniques through 4 files.

  • index.php contains a message alert which will only be displayed when there is a message to put in it. The forms use an action which contains the name of a class and method which will be used to process the results. There is also a call to custom.js
  • custom.js handles the form submissions and delivers the data returned to the page. It passes the form action and field content to formhandler.php. It receives JSON which then is either passed to a message alert or a data table.
  • formhandler.php receives the call from custom.js. This contains the form action and field content. It takes the form action and uses them to create calls to classes and methods named in the form action. For example and action of myclass/mymethod would be used to create calls similar to those below. The inclusion of the $_POST array allows the form field content to be passed to the class. The data returned is then passed back to custom.js for processing.
$myclass = new myclass($_POST);
$myclass->mymethod;

  • myclassname.class.php contains the example class and methods. The class receives the $_POST array and processes its content. There are 3 methods which demonstrate how to return a string, an array and an object.

This approach is a quick way of utilising many classes. It does not require a .htaccess file to simplify form actions and is flexible in its handling of returned data through JSON.
Have fun.

index.php

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Form handler for many PHP classes using jQuery</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
    <style>
    body
    {
      margin-top:2em;
    }
    #message, #data-table
    {
      display:none;
    }
    </style>
  </head>
  <body>
    <div class="row">
      <div class="container">
        <div class="col-md-12">
          <div id="message" class="alert alert-success" role="alert"></div>
          <!-- <form action="myclassname/myclassmethod_string" method="POST"> -->
          <!-- <form action="myclassname/myclassmethod_array" method="POST"> -->
          <form action="myclassname/myclassmethod_object" method="POST">
            <div class="form-group">
              <label for="name"></label>
              <input type="text" name="name" class="form-control" />
            </div>
            <button type="submit" class="btn btn-default">Submit</button>
          </form>
          <table id="data-table" class="table table-striped">
            <thead>
              <tr>
                <th>Name</th>
                <th>Age</th>
              </tr>
            </thead>
            <tbody>
            </tbody>
          </table>
        </div>
      </div>
    </div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
    <script src="custom.js"></script>
  </body>
</html>

custom.js

(function()
{
  $('form').on('submit', function(event)
  {
    $.post('formhandler.php?action='+$(this).attr('action'), $(this).serialize(), function(data)
    {
      var json_obj = JSON.parse(data);
      if(json_obj.hasOwnProperty('message'))
      {
        $('#message').text(json_obj.message);
        $('#message').show();
        $('#message').fadeOut(3000);
      }
      else
      {
        $.each(json_obj, function(name,age)
        {
          $('#data-table > tbody').appendRow(name,age);            
        });
        $('#data-table').show();
      }
    });
    event.preventDefault();
  });
})();

$.fn.appendRow = function()
{
  var s = '<tr>';
  for (var i = 0; i < arguments.length; i++)
  {
    s += '<td>'+arguments[i]+'</td>';
  }
  s += '</tr>';
  return $(this).append(s);
}

formhandler.php

<?php
if(isset($_GET['action']))
{
$arr = split('/', $_GET['action']);
$class = $arr[0];
$method = $arr[1];
require_once $class.'.class.php';
if(class_exists($class))
{
$evalStr = '$'.$class.' = new '.$class.'($_POST);';
eval($evalStr);
if(method_exists($class, $method))
{
$evalStr = '$returnValue = $'.$class.'->'.$method.'();';
eval($evalStr);
}
else
{
$returnValue = 'Method does not exist';
}
}
else
{
$returnValue = 'Class does not exist';
}
}
else
{
$returnValue = 'No action given';
}

if(is_object($returnValue) || is_array($returnValue))
{
echo json_encode($returnValue);
}
else
{
$returnArr = array('message'=>$returnValue);
echo json_encode($returnArr);
}
?>

myclassname.class.php

<?php
class myclassname
{
private $pa;
function __construct($postArray = array())
{
$this->pa = $postArray;
}

function myclassmethod_string()
{
return 'Your name is '.$this->pa['name'];
}

function myclassmethod_array()
{
$myArr = array('Peter'=>'35', 'Ben'=>'37', 'Joe'=>'43');
return $myArr;
}

function myclassmethod_object()
{
$myObj = (object) array('Peter'=>'35', 'Ben'=>'37', 'Joe'=>'43');
return $myObj;
}

function __destruct()
{

}
}
?>

Monday 30 March 2015

Simple Twitter Bootstrap with Knockout

The code below demonstrates some simple features of Knockout (or knockout.js) within a Twitter Bootstrap page. The funny thing is, you need jQuery for Twitter Bootstrap, so you're forced to get the best of both worlds, at the cost of your page loading speed.

The page does 3 things:
As you put text into the input box, the text is synchronised with the H1 tag
When you're happy, you can click the "I'm happy" button
Clicking the button adds the text to the list group below

I've put the Knockout items in red.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">  
    <title>Bootstrap with Knockout</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
    <div class="row">
      <div class="container">
        <div class="col-md-6">
          <!-- This is used for adding text from the input box to the title -->
          <h1 data-bind="text:title"></h1>
          <form class="form-inline">
            <input type="text" class="form-control" data-bind="value:title, valueUpdate:'afterkeydown'">
            <!-- This is used to kick off the 'addOlEntry' function when the button is clicked -->
            <button type="submit" class="btn btn-primary" data-bind="click:addOlEntry">I'm happy</button>
          </form>
          <hr />
          <!-- Loop through the olArray -->
          <ol class="list-group" data-bind="foreach:olArray">
            <!-- Add a list item for each entry in the olArray -->
            <li class="list-group-item" data-bind="text:$data"></li>
          </ol>
        </div>
      </div>
    </div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>  
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
    <script>
   /* Create a title variable and make it observable. This becomes synced to the input box within the      HTML.
Create an array and make that also observable.
Create a function which is called when the button is clicked and adds the title text to the array.#
Bind it all together. */
    var vm = 
    {
      title:ko.observable(),
      olArray:ko.observableArray(),
      addOlEntry:function()
      {
        this.olArray.push(this.title());
      }
    }    
    ko.applyBindings(vm);
    </script>
  </body>
</html>

Wednesday 11 March 2015

Twitter Bootstrap carousel gallery with thumbnails and modals using jQuery

The challenge is to create a Twitter Bootstrap carousel with the following attributes:

  • Thumbnails of each image as the indicators.
  • Hovering over images highlights the fact that you can click on them.
  • Clicking on an image will display them in a modal window.

The solution lies below with areas of interest highlighted in red.
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bootstrap thumbnail gallery</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
    <style>
    img
    {
      width:6em;
    }
    img:hover
    {
      opacity: 0.4;
      filter: alpha(opacity=40);
    }
    #exampleModal > div.modal-dialog > div > div.modal-body > img, #carousel-example-generic > div.carousel-inner > div.item > img
    {
      width:100%;
    }
    #carousel-example-generic > ol.carousel-indicators > img, #carousel-example-generic > ol.carousel-indicators > img.active
    {
      width:2em;
    }
    #carousel-example-generic > ol.carousel-indicators > img.active
    {
      height:3em;
    }
    </style>
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
    <div class="row">
      <div class="container">
        <div class="col-md-4">
          <div id="carousel-example-generic" class="carousel slide" data-ride="carousel">

            <!-- Start of Indicators -->
            <ol class="carousel-indicators">
              <img src="derek.jpg" data-target="#carousel-example-generic" data-slide-to="0" class="active">
              <img src="jimmy.jpg" data-target="#carousel-example-generic" data-slide-to="1">
              <img src="peter.jpg" data-target="#carousel-example-generic" data-slide-to="2">
              <img src="johnnie.jpg" data-target="#carousel-example-generic" data-slide-to="3">
              <img src="steve.jpg" data-target="#carousel-example-generic" data-slide-to="4">
              <img src="mick.jpg" data-target="#carousel-example-generic" data-slide-to="5">
            </ol>
            <!-- End of Indicators -->

            <!-- Start of Wrapper for slides -->
            <div class="carousel-inner" role="listbox">
              <div class="item active">
                <img src="derek.jpg" alt="Derek" data-toggle="modal" data-target="#exampleModal">          
              </div><!-- .item -->
              <div class="item">
                <img src="jimmy.jpg" alt="Jimmy" data-toggle="modal" data-target="#exampleModal">          
              </div><!-- .item -->
              <div class="item">
                <img src="peter.jpg" alt="Peter" data-toggle="modal" data-target="#exampleModal">          
              </div><!-- .item -->
              <div class="item">
                <img src="johnnie.jpg" alt="Johnnie" data-toggle="modal" data-target="#exampleModal">          
              </div><!-- .item -->
              <div class="item">
                <img src="steve.jpg" alt="Steve" data-toggle="modal" data-target="#exampleModal">          
              </div><!-- .item -->
              <div class="item">
                <img src="mick.jpg" alt="Mick" data-toggle="modal" data-target="#exampleModal">          
              </div><!-- .item -->        
            </div><!-- .carousel-inner -->
            <!-- End of Wrapper for slides -->

            <!-- Start of Controls -->
            <a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
            <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
            <span class="sr-only">Previous</span>
            </a>
            <a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
            <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
            <span class="sr-only">Next</span>
            </a>
            <!-- end of Controls -->
          </div><!-- #carousel-example-generic -->    
        </div>
        <aside class="col-md-8">
         
        </aside>
      </div>
    </div>

    <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
            <h4 class="modal-title"></h4>
          </div>
          <div class="modal-body"></div>
        <div class="modal-footer"></div>
        </div><!-- /.modal-content -->
      </div><!-- /.modal-dialog -->
    </div><!-- /.modal -->

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
    <script>
    (function()
    {
      $('#exampleModal').on('show.bs.modal', function (event)
      {
        var img = $(event.relatedTarget);
        var alt = img.attr('alt');
        var src = img.attr('src');
        var modal = $(this);
        modal.find('.modal-title').text(alt);
        modal.find('.modal-body').html('<img src="'+src+'" />');
      });
    })();
    </script>
  </body>
</html>