Tuesday, 29 April 2014

jQuery equalise selector widths

Now for making the width of selectors the same. This gets slightly more complicated on 4 counts:
1. Firefox can't turn null values into zero, so you have to force it.
2. You also need to get margin, border and padding values to make your calculations. Including parent padding.
3. You have to handle the browser being resized.
4. You have to add a little contingency for browser rendering differences.
Let's start with the HTML:
<!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>equalise width</title>
    <link rel="stylesheet" type="text/css" href="style.css">  
    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
      <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
    <article>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliud igitur esse censet gaudere, aliud non dolere. Ad eos igitur converte te, quaeso. Atqui iste locus est, Piso, tibi etiam atque etiam confirmandus, inquam; Cum autem in quo sapienter dicimus, id a primo rectissime dicitur. Ut optime, secundum naturam affectum esse possit. Videsne quam sit magna dissensio? Duo Reges: constructio interrete. Sed quanta sit alias, nunc tantum possitne esse tanta. At enim hic etiam dolore. Facile est hoc cernere in primis puerorum aetatulis.</p>
    </article>
    <article>
      <p>Summus dolor plures dies manere non potest? At ego quem huic anteponam non audeo dicere; Nemo nostrum istius generis asotos iucunde putat vivere. Pugnant Stoici cum Peripateticis. Istam voluptatem perpetuam quis potest praestare sapienti? Quid sequatur, quid repugnet, vident.</p>
    </article>
    <article>
      <p>Nihil opus est exemplis hoc facere longius. Quam illa ardentis amores excitaret sui! Cur tandem? Sic enim censent, oportunitatis esse beate vivere.</p>
    </article>
    <footer>
      <p>footer</p>
    </footer>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>  
    <script src="equalisewidth.plugin.js"></script>
    <script>
    (function()
    {
      $('article').equalisewidth();
      $(window).resize(function()
      {
        $('article').equalisewidth();
      });
    })();
    </script>
  </body>
</html>
Now for the CSS (style.css):
body
{
  font: 90%/1.618 sans-serif;
  padding-top:2em;
}
article
{
float:left;
margin:1em;
padding:1em;
background:red;
color:white;
}
footer
{
clear:left;
}
And finally the jQuery plugin (equalisewidth.plugin.js):
(function($)
{
  $.fn.equalisewidth = function()
  {
    var thisMargin = parseInt($(this).css('margin-left').replace(/px/,'')) + parseInt($(this).css('margin-right').replace(/px/,''));
    if(isNaN(thisMargin)) thisMargin = 0;
    var thisBorder = parseInt($(this).css('border-left').replace(/px/,'')) + parseInt($(this).css('border-right').replace(/px/,''));
    if(isNaN(thisBorder)) thisBorder = 0;
    var thisPadding = parseInt($(this).css('padding-left').replace(/px/,'')) + parseInt($(this).css('padding-right').replace(/px/,''));
    if(isNaN(thisPadding)) thisPadding = 0;
    var thisParentPadding = parseInt($(this).parent().css('padding-left').replace(/px/,'')) + parseInt($(this).parent().css('padding-right').replace(/px/,''));
    if(isNaN(thisParentPadding)) thisParentPadding = 0;
    var equalWidth = $(this).parent().width() / $(this).length;
    var spacing = (thisMargin + thisParentPadding) + (thisBorder + thisPadding) + 2;
    var widthResize = equalWidth - spacing;  
    $(this).each(function()
    {
      $(this).width(widthResize);    
    });
  }
})(jQuery);
Enjoy!

jQuery equalise height plugin

Sometimes we just want a group of element to be the same height. It's more visually pleasing. This plugin is designed to do just that.
First the HTML:
<!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>equalise height</title>
    <link rel="stylesheet" type="text/css" href="style.css">  
    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
      <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
    <article>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliud igitur esse censet gaudere, aliud non dolere. Ad eos igitur converte te, quaeso. Atqui iste locus est, Piso, tibi etiam atque etiam confirmandus, inquam; Cum autem in quo sapienter dicimus, id a primo rectissime dicitur. Ut optime, secundum naturam affectum esse possit. Videsne quam sit magna dissensio? Duo Reges: constructio interrete. Sed quanta sit alias, nunc tantum possitne esse tanta. At enim hic etiam dolore. Facile est hoc cernere in primis puerorum aetatulis.</p>
    </article>
    <article>
      <p>Summus dolor plures dies manere non potest? At ego quem huic anteponam non audeo dicere; Nemo nostrum istius generis asotos iucunde putat vivere. Pugnant Stoici cum Peripateticis. Istam voluptatem perpetuam quis potest praestare sapienti? Quid sequatur, quid repugnet, vident.</p>
    </article>
    <article>
      <p>Nihil opus est exemplis hoc facere longius. Quam illa ardentis amores excitaret sui! Cur tandem? Sic enim censent, oportunitatis esse beate vivere.</p>
    </article>
    <footer>
      <p>footer</p>
    </footer>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <script src="equaliseheight.plugin.js"></script>
    <script>
    (function()
    {
      $('article').equaliseheight();
    })();
    </script>
  </body>
</html>
Now the CSS (style.css):
body
{
  font: 90%/1.618 sans-serif;
  padding-top:2em;
}
article
{
float:left;
margin:1em;
padding:1em;
width:15em;
background:red;
color:white;
}
footer
{
clear:left;
}
And finally the jQuery plugin (equaliseheight.plugin.js):
(function($)
{
  $.fn.equaliseheight = function()
  {
    var maxHeight = 0;
    $(this).each(function()
    {
      if($(this).height() > maxHeight)
      {
        maxHeight = $(this).height();
      }
    });
    $(this).height(maxHeight);
  }
})(jQuery);

Monday, 28 April 2014

jQuery second word plugin

You've seen those fancy titles where the second word is a different colour from the first. To achieve this, you really don't want to have to put span tags all around your code. Below I've created a plugin which allows you to decide which elements have their second word looking different from the first. You can use it with any framework. Please excuse the separate CSS file, but I've been using LiveStyle with Sublime Text 2. It really speeds development up.
First the HTML:
<!DOCTYPE html>
<html lang="en">
  <head>  
    <title>Second word</title>  
    <link href='style.css' rel='stylesheet' type='text/css'>  
  </head>
  <body>
    <header>
      <h1>Second word</h1>
    </header>
    <section>
      <article>
        <h2>Sub header</h2>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sin tantum modo ad indicia veteris memoriae cognoscenda, curiosorum. Si verbum sequimur, primum longius verbum praepositum quam bonum. Duo Reges: constructio interrete. Falli igitur possumus. Egone non intellego, quid sit don Graece, Latine voluptas? Sed virtutem ipsam inchoavit, nihil amplius. Sed eum qui audiebant, quoad poterant, defendebant sententiam suam.</p>
      </article>
      <article>
        <h2>Sub heading</h2>
        <p>Quis est, qui non oderit libidinosam, protervam adolescentiam? Nam si amitti vita beata potest, beata esse non potest. Recte, inquit, intellegis. Idemne potest esse dies saepius, qui semel fuit? Venit enim mihi Platonis in mentem, quem accepimus primum hic disputare solitum; Aliter enim explicari, quod quaeritur, non potest. Profectus in exilium Tubulus statim nec respondere ausus; Nos vero, inquit ille;</p>
      </article>        
    </section>
    <footer><p>&copy; Second word 2014</p></footer>  
    <script src="https://code.jquery.com/jquery.js"></script>
    <script src="secondword.plugin.js"></script>
    <script>
    (function()
    {
        $('header > h1, article > h2').secondword();
    })();
    </script>
  </body>
</html>

Now the style.css:
body
{
padding:1em;
font-family:Sans-serif;
}
header, footer, article > h2
{
font-family:Serif;
color:red;
font-style:italic;
}
section > article
{
text-align:justify;
line-height:1.7;
}
body, header > h1 span.secondword, article > h2 span.secondword
{
color:#777;
}

And finally, the jQuery plugin, secondword.plugin.js:
(function($)
{
  $.fn.secondword = function()
  {
    $(this).each(function()
    {
      var text = $(this).text().split(' ');
      if(text.length < 2) return;
      text[1] = '<span class="secondword">'+text[1]+'</span>';
      $(this).html(text.join(' '));
    });
  }
})(jQuery);

Friday, 25 April 2014

Get .htaccess files working on Ubuntu after LAMP installation

Step 1. Configure Apache mod_rewrite
sudo a2enmod rewrite

Step 2. Within the file /etc/apache2/apache2.conf
Under the section labelled <Directory /var/www/>
Change the line
AllowOverride None
to
AllowOverride All

Step 3. Restart apache
sudo /etc/init.d/apache2 restart

jQuery accordion plugin you can style how you like

The jQuery accordion plugins I have come across also come with some complex CSS. They rely on the CSS to hide elements and you have to dig your way through complex CSS elements in order to adapt the look for your own purposes. On of the the worst culprits for this is the one which comes with the jQuery UI library.
So I devised my own plugin which operates without any CSS, is easy to style, is lightweight, does not require anchors to open items, and provides flexibility to the item headers.
First the HTML.
<!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>Accordion</title>  
    <style>
    body
    {
      font: 90%/1.618 sans-serif;
      padding-top:2em;
    }
    </style>
    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
      <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
    <div id="micksaccordion">
      <section>
        <header>
          <h1>Header 1</h1>
        </header>
        <article>
          <p>This is from article 1</p>
        </article>
      </section>
      <section>
        <header>
          <h2>Header 2</h2>
        </header>
        <article>
          <p>This is from article 2</p>
        </article>
      </section>
      <section>
        <header>
          <h3>Header 3</h3>
        </header>
        <article>
          <p>This is from article 3</p>
        </article>
      </section>
      <section>
        <header>
          <h4>Header 4</h4>
        </header>
        <article>
          <p>This is from article 4</p>
        </article>
      </section>
    </div><!-- micksaccordion -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <script src="accordion.plugin.js"></script>
    <script>
    (function()
    {
      /* Easy version
      $('#micksaccordion').accordion();
      */
      $('#micksaccordion').accordion(
      {
        /* 'first', 'last', false */
        show:'last'
      });
    })();
    </script>
  </body>
</html>

And now the jQuery plugin:
(function($)
{
  $.fn.extend(
  {
    accordion:function(options)
    {
      var defaults =
      {
          show:false
      }

      var options = $.extend(defaults, options);

      return this.each(function()
      {
        var o = options;              

        var articles = $(this).find('article');

        var firstSection = $(this).children().first();      
        var firstArticle = firstSection.find('article');

        var lastSection = $(this).children().last();      
        var lastArticle = lastSection.find('article');

        articles.hide();

        if(o.show == 'first')
        {
          firstArticle.show();
        }
       
        if(o.show == 'last')
        {
          lastArticle.show();
        }

        var sections = $(this).find('section');

        $(sections).on('click','header', function()
        {
          thesection = $(this).parent();
          thearticle = thesection.find('article');        
          if (thearticle.css('paddingTop') == '0px') thearticle.css({paddingTop: '1px'});
          if (thearticle.css('paddingBottom') == '0px') thearticle.css({paddingBottom: '1px'});        
          thearticle.slideToggle('slow');
        });

      });
    }
  });
})(jQuery);

Enjoy!

Monday, 14 April 2014

HTML Entities jQuery plugin for the code tag

Try presenting HTML in a web page. It's a pain in the neck. Even in between the code tag, you have to create HTML Entities for greater than and less than symbols etc.
Not wanting to go through that pain ever again, I have created a small JavaScript plugin which helps.
First, here is the HTML page important differences 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>Convert to HTML Entities</title>  
  </head>
  <body>
    <code>Hello, <h1>world!</h1></code>
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <script src="htmlentities.plugin.js"></script>
    <script>
    (function()
    {
      $('code').htmlentities();
    })();
    </script>
  </body>
</html>
Now, htmlentities.plugin.js:
(function($)
{
  $.fn.htmlentities = function()
  {
 
    beforeString = $(this).html();  
    afterString = beforeString.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
    $(this).html(afterString);
  }
})(jQuery);

Happy coding!

Wednesday, 9 April 2014

Twitter Bootstrap Progress Bar example using jQuery and PHP

So you'd like to see Twitter Bootstrap Progress Bar actually work. Not too many examples out there are there. For this, after you've downloaded Twitter Bootstrap, you will need 3 more files:

  • Your demo file, index.html
  • Your post handler, posthandler.php
  • Your empty data file, datafile.dat which is writeable

So let's start with index.html. Get the basic template from http://getbootstrap.com/getting-started/
and make the following additions (in red). This file:

  • Creates a progress bar
  • Kicks off the post handler using the submit button
  • Checks the value contained in the data file
  • Uses the data gathered to increase the width of the progress bar

<!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 101 Template</title>

    <!-- Bootstrap -->
    <link href="css/bootstrap.min.css" rel="stylesheet">  
    <style>
    body
    {
      padding-top:2em;
    }  
    </style>
    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
      <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
    <div class="row">
      <div class="container">
        <div class="col-md-12">
          <form role="form">
            <button type="submit" class="btn btn-default">Submit</button>
          </form><br />
          <div class="progress progress-striped active">
            <div class="progress-bar" role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100" style="width:0%">
            </div>
          </div>
        </div>
      </div>
    </div>    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="js/bootstrap.min.js"></script>
    <script>
    (function()
    {
      $('form').submit(function()
      {
        $.post('posthandler.php', function(data1)
        {
          console.log(data1)
        });

        var refreshId = setInterval(function()
        {
          $.get('datafile.dat', function(data2)
          {
            $('.progress-bar').css('width',data2+'%');
            if(data2 >= 100)
            {
              console.log('finished');
              $('.progress').removeClass('active');
              $('.progress').removeClass('progress-striped');
              $('.progress-bar').text('Complete');
              clearInterval(refreshId);
            }
          });
        }, 100);
        return false;
      });      
    })();
    </script>
  </body>
</html>

Now for the posthandler.php
This script:

  • Clears the data file
  • Every so often, updates the data file contents

<?php
file_put_contents('datafile.dat', '');
for($i = 1; $i <= 100; $i++)
{
usleep(200000);
file_put_contents('datafile.dat', $i);
}
?>

Enjoy!