Friday, 15 November 2019

Useful Docker commands

Start services listed in docker-compose.yml file for the first time

docker-compose up -d

Stop services listed in docker-compose.yml

docker-compose stop

Subsequently start services listed in docker-compose.yml file

docker-compose start

Clean up services listed in docker-compose.yml file

docker system prune

Bring up all services listed in docker-compose.yml file

docker-compose up

Bring up "node" service listed in docker-compose.yml file

docker-compose up node

Clean up all services listed in docker-compose.yml file

docker-compose rm -f

Rebuild your services on restart

docker-compose up -d --force-recreate --build

Log into a container named webserver

docker exec -it webserver /bin/bash

Provide information about the running container "ubuntu".

docker inspect ubuntu

Look for containers

docker container ls
This will give you a list of CONTAINER ID's.

Remove containers

docker container rm -f <CONTAINER ID>

Look for images

docker images
This will give you a list of IMAGE ID's.

Remove containers

docker rmi -f <IMAGE ID>

Look for volumes

docker volume ls
This will give you a list of VOLUME NAME's.

Remove volumes

docker volume rm -f <VOLUME NAME>

Thursday, 25 April 2019

Why use PhpStorm over Atom

I'm just about to do a lot more work with PHP and I will be using PhpStorm. What's so good about PhpStorm. Below are a few examples.

Working with scratch files

New->New scratch file : Creates a file without yet including it in your project.

Refactoring

Select the variable you want to refactor.
Right-click->Refactor->Rename.
All occurrences of the variable will be renamed.

Search everything in your project

Tap the Shift button twice.

Version control

If you already have a repository, one of the options on the PhpStorm welcome screen is 'Check out from version control'. Here you can select your repository type. You will then be asked for the repository location and PhpStorm will load with your repository.
Let's assume your project uses git or Bitbucket.
When you add code to your project a new tab appears at the bottom-left of PhpStorm titled 'Version Control'. This allows you to track, stage, and commit changes.

Databases

When you open up a project which contains a database connection you can work with the database.
A tab appears at the top-right of PhpStorm titled 'Databases'. From here you can click on the '+' button and add a new connection, if the connection has not already been made.
Once the connection has been established, the 'Databases' window shows the database structue, but you also have a console window into which you can add queries such as SELECT * FROM country.
When the query results are displayed in the console, it's possible to edit the data returned.

Vagrant

First set Vagrant up in your project
Tools->Vagrant->Init in Project Root
If Vagrant is not set up on your computer a dialogue box appears asking you for configuration details of Vagrant.
If Vagrant is set up on your computer a dialogue box appears asking you for your chose Vagrant instance.
Once Vagrant has been set up you can move 'Remote Host', find a file, right-click and select 'Edit remote file'.

REST

In your project you can test RESTful web API's for your project before you add the code.
Tools->HTTP Client->Test RESTful Web Service

Emmet built in

Type a tag name followed by TAB
e.g. html:5
e.g. html>head+body

Wednesday, 24 April 2019

Using Windoze for the first time in years

I'm having to use Microsoft Windows 10 for some work. I haven't touched Windows since XP. Here are some things which I thought would be useful.

The 'Start menu' is that ugly stuff at the bottom left which appears when you click on the Windows icon. It may look bad now, but when Microsoft brought out Vista etc, things looked so much worse.

Pin an application to the start menu

Left click on the Windows icon at the bottom left of the desktop. This shows the Windows 10 primary start menu ('Start menu').
Find your application shortcut by going through the alphabetically ordered list in the 'Start menu'.
Right click on your chosen shortcut.
Choose 'Pin to start menu'.

Remove an application from the start menu

Left click on the windows icon at the bottom left of the desktop. This shows the 'Start menu'.
Find your application shortcut icon within the 'Start menu' on the right.
Right click the icon and choose 'Unpin from start'.

Pin an application to the taskbar

Left click on the windows icon at the bottom left of the desktop. This shows the 'Start menu'.
Find your application shortcut by going through the alphabetically ordered list in the 'Start menu'.
Right click on your chosen shortcut.
Choose 'More' -> 'Pin to taskbar'.

Settings

Left click on the primary 'Start menu'.
To the far left are a small number of small icons.
Choose 'Settings'.

Notifications

Left click on the primary 'Start menu'.
To the far left are a small number of small icons.
Choose 'Settings'.
Choose 'Notifications & actions'.
Turn off some of those pesky apps which send you notifications when you're trying to work.

Keyboard shortcuts

Alt + Tab : Switch between open apps
Alt + F4 : Close the active item, or exit the active app
Windows logo key  + L : Lock your PC
F10 : Activate the Menu bar in the active app
Ctrl + Esc : Open Start
Ctrl + Shift + Esc : Open Task Manager
Esc : Stop or leave the current task
Windows logo key  + E : Open File Explorer
Windows logo key  + I : Open Settings

Wednesday, 10 April 2019

Vanilla JavaScript Grid navigation

I have created a Vanilla JavaScript Grid navigation. This has been built using https://github.com/guitarbeerchocolate/vanilla-js-component and resides at https://github.com/guitarbeerchocolate/vanilla-js-grid-navigation
It employs ES6, BEM and SASS.

logotext

This module offers 2 options:


  • A logo with text to the right.
  • A logo with text underneath

The module was created to make logo based header elements more SEO friendly. The logo is itself a background and the text resides in a H1 tag.

The SCSS uses the BEM approach and resides at https://github.com/guitarbeerchocolate/logotext

Forked from https://github.com/guitarbeerchocolate/vanilla-js-component

Friday, 29 March 2019

Yii use and namespace

use

Standard Yii

This is a keyword which is used to make functionality available to the current class.
E.g. If you add line below
use yii\db\ActiveRecord;
You will be able to create a new ActiveRecord such as
$ar = new ActiveRecord();
Or to create a class which is an extension of an ActiveRecord such as
class Customer extends ActiveRecord
{
}

Your Yii custom components

E.g. If you add line below
use app\models\Customer;
You will be able to add functionality which has been created for this application. In this case a model was created called 'Customer'. From here you can such functionality to your current class as
$query = Customer::find();

namespace

The namespace allows you to create a structured naming convention to retrieve the class you are currently working on.
E.g. If you add lines below
namespace app\models;
use yii\db\ActiveRecord;
class Customer extends ActiveRecord
{
}
This will allow you at a later date to 'use' this class thus
use app\models\Customer;

Thursday, 28 March 2019

Yii database model

This is partly based on the documentation found at https://www.yiiframework.com/doc/guide/2.0/en/start-databases

ActiveRecord

If you're going to work with records using Yii, it's helpful to make use of the ActiveRecord class. In this example, we're working with a database of country data.  Thankfully, this is a simple scenario which requires the creation of a simple class. Just add this as models/Country.php
<?php
namespace app\models;
use yii\db\ActiveRecord;
class Country extends ActiveRecord
{
}

Controller

Next we need to create a controller which we can use to pass data from the Country ActiveRecord model to a view. In this case, we're also going to add some pagination functionality, which we'll also pass to the view.

  1. First we create a $query object which will be used to retrieve the data.
  2. Next we create a $pagination object which will be used to control the display of that data.
  3. Next we get all the data we want.
  4. Finally we pass the data and pagination objects to the view.

We save this class as controllers/CountryController.php

<?php
namespace app\controllers;
use yii\web\Controller;
use yii\data\Pagination;
use app\models\Country;
class CountryController extends Controller
{
    public function actionIndex()
    {
        $query = Country::find();
        $pagination = new Pagination([
            'defaultPageSize' => 5,
            'totalCount' => $query->count(),
        ]);

        $countries = $query->orderBy('name')
            ->offset($pagination->offset)
            ->limit($pagination->limit)
            ->all();

        return $this->render('index', [
            'countries' => $countries,
            'pagination' => $pagination,
        ]);
    }
}

View

The view performs 3 tasks in this process:
Loops through the data, adding it to the page.
Adding the pagination object to that the data can be paged through.
Adding the LinkPager widget object to the pagination object to automatically create all those links, saving us a bunch of coding.
We'll put the view in the directory views/country/index.php

<?php
use yii\helpers\Html;
use yii\widgets\LinkPager;
?>
<h1>Countries</h1>
<ul>
<?php foreach ($countries as $country): ?>
    <li>
        <?php echo Html::encode("{$country->code} ({$country->name})"); ?>:
        <?php echo $country->population; ?>
    </li>
<?php endforeach; ?>
</ul>
<?php echo LinkPager::widget(['pagination' => $pagination]); ?>

Yii first models and forms

This is partly based on the documentation found at https://www.yiiframework.com/doc/guide/2.0/en/start-forms

Model

In building a form interaction it's often best to begin with a model; a place where the data will be sent for checking, and or converting and putting into a source. A model is therefore also required far all CRUD operations.

rules and validate

The model below handles an entry form post. It doesn't do much with the data, but it does contain a method with a reserved word, rules(). This method will be called later from the controller using the term validate()

The rules method return to the validate call within the controller validation of 2 expectations:

  1. That the name and emailAddress fields are required.
  2. That the emailAddress is a valid email field.

<?php
namespace app\models;
use Yii;
use yii\base\Model;
class EntryForm extends Model
{
    public $name;
    public $emailAddress;
    public function rules()
    {
        return [
            [
              ['name', 'emailAddress'], 'required'
            ],
            [
              'emailAddress', 'email'
            ]
        ];
    }
}

Controller

The controller makes our newly created model available to us through the line
use app\models\EntryForm;
A method is created called actionEntry() is created which will be called from the form (contained in a view) using the view file name of entry.php
and a new instance of the model is created through the line
$model = new EntryForm();
The POSTed data is sent to the model using the
Yii::$app->request->post() method. A list of other request options can be found at
https://www.yiiframework.com/doc/api/2.0/yii-web-request
At the same time, the model validates the data using
$model->validate() which as mentioned previously makes use of the rules() method.
Once these tests have been passed and you've done something useful with the data, you can render the confirmation view, entry-confirm.php.
If something went wrong you can take the user back to the form view entry.php.
In both cases, though it may seem a little confusing, $model is passed as 'model' to the views. This means that 'model' becomes $model within the views.
<?php
namespace app\controllers;
use Yii;
use yii\web\Controller;
use yii\web\Request;
use app\models\EntryForm;
class SiteController extends Controller
{
    // actionIndex(), actionSay() etc.
    public function actionEntry()
    {
        $model = new EntryForm();
        $request = new Request();
        if ($model->load($request->post()) && $model->validate()) {
            // valid data received in $model do something meaningful here
            return $this->render('entry-confirm', ['model' => $model]);
        } else {
            // either the page is initially displayed or there is some validation error
            return $this->render('entry', ['model' => $model]);
        }
    }
}

Views

As mentioned in the controller section above, there are 2 views; entry.php and entry-confirm.php.

entry-confirm.php

Residing at views/site/entry-confirm.php is fairly easy to understand.
<?php
use yii\helpers\Html;
?>
<p>You have entered the following information:</p>
<ul>
    <li><label>Name</label>: <?php echo Html::encode($model->name); ?></li>
    <li><label>Email</label>: <?php echo Html::encode($model->emailAddress); ?></li>
</ul>

entry.php

Residing at views/site/entry.php requires a little more explanation.
The ActiveForm::begin() method creates form tag. This tag has an action field into which the ActiveForm::begin() method the filename of the form. This action field is used to make a request to the actionEntry() method in the controller.
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
?>
<?php $form = ActiveForm::begin(); ?>
    <?php echo $form->field($model, 'name'); ?>
    <?php echo $form->field($model, 'emailAddress'); ?>
    <div class="form-group">
        <?php echo Html::submitButton('Submit', ['class' => 'btn btn-primary']); ?>
    </div>
<?php ActiveForm::end(); ?>

Tuesday, 26 March 2019

Yii first controller and URLs

This is partly based on the documentation found at https://www.yiiframework.com/doc/guide/2.0/en/start-hello
Within the controllers directory I have a file called SiteController.php. I'll explain a few things about it.

site is the default route for Yii applications and therefore SiteController.php would be (by default) the first controller a user interaction would access. So if I access my application through the URL http://localhost/test/yii-apps/basic/web/ then (by default) the SiteController would be called, and (by deafult) the actionIndex method would be called within that controller.

actionIndex renders the view views/site/index.php within the default layout views/layouts/main.php

In order to create a controller we need to make use of the controller classes declared at the top.

The method actionSay can be called from the URL http://localhost/test/yii-apps/basic/web/index.php
?r=site%2Fsay and within this URL, the r stands for route. route's format is ControllerID/ActionID. This would render the view views/site/say.php within the default layout views/layouts/main.php showing the content 'Hello' since this is the default value of the variable message.

The %2F is the URL encoded version of /

views/site/say.php looks like this:

<?php
use yii\helpers\Html;
echo Html::encode($message);
?>

To extend this approach the URL http://localhost/test/yii-apps/basic/web/index.php?r=site%2Fsay&message=Hello+Mick would pass a string Hello+Mick to the value of the variable message and the resulting page would display the string 'Hello Mick'.

Thus SiteController.php looks like this.

<?php
namespace app\controllers;
use yii\web\Controller;
class SiteController extends Controller
{
    public function actionIndex()
    {
        return $this->render('index');
    }

    public function actionSay($message = 'Hello')
    {
        return $this->render('say', ['message' => $message]);
    }
}
?>

Thursday, 21 March 2019

Yii views and layouts

Within Yii we have the concept of views and layouts. This can get a little confusing for 2 reasons:

  1. They both reside within the views directory
  2. The higher level is the layout, which lies within a sub directory if views i.e views/layouts

That aside once you strip the garbage found in most tutorial the concept is straight forward.
Let's take a layout as our starting position. In this case views/layouts/main.php
This contains 3 elements which are particular to Yii.

  1. The declaration of a variable from config/web.php to set the language
  2. The declaration of a variable which resides in the view for the title tag
  3. The all important echo of the $content variable which displays the contents of the view

<!DOCTYPE html>
<html lang="<?php echo Yii::$app->language ?>">
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title><?php echo $this->title ?></title>
</head>
<body>
<?php echo $content; ?>
</body>
</html>

Now let's look at the views/site/index.php
This view passes the title variable which is used in the <title> tag. of the layout above. "Hello world!" is displayed where $content is echo'd from the layout above.
<?php
$this->title = 'My Yii Application';
?>
Hello world!

Introduction to Yii

Yii is a PHP, MVC framework which has been built with performance in mind.

Creating a new project

Let's imagine I've created a yii-apps directory to put all my Yii tests in.
cd yii-apps
If I run the following :
composer create-project --prefer-dist yiisoft/yii2-app-basic basic
I'm doing a number of things:

  • Using composer with the create-project command.
  • Adding the --prefer-dist option to the create-project command which will install packages from dist directory when available.
  • Adding the --stability=dev option, so that the app will be created as a piece of development rather than production. That can come later.
  • Creating the app using the 'Yii 2.0 Basic Application Template'. There are many application templates you can use. Some of them are written by 'yiisoft', the organisation which develops Yii itself.

Once installed, you can use the following command to see you application.
php yii serve
This would give you a URL such as http://localhost:8080/
Alternatively, if you already have a LAMP server running, you can use a URL like this in your browser:
http://localhost/test/yii-apps/basic/web/

How is it structured?

Yii applications are loaded using the following hierarchy:
Entry script -> Controller -> Actions

Yii Views are HTML with PHP. You can use helpers such as yii\helpers\Html and widgets such as yii\widgets\ActiveForm to create views

Yii models use the "active record pattern (methods)" to pull and push data, so in most cases you won't need to write queries.

You can use composer to perform tasks on your application such as create it, or add components.

composer.json handles all the components

config/web.php handles all the routing. Here, you can uncomment the urlManager section to handle pretty URLs.

controllers/SiteController.php is the default controller and contains a method call actionIndex(). This takes users to the index view residing at views/site/index.php. This is where the naming convention becomes obvious. Our controller is called SiteController.php and it corresponds to views/site.

web is the directory containing all the CSS and images etc.

vendor is the directory containing all the libraries.

A full description of the directory structure can be found at https://www.yiiframework.com/doc/guide/2.0/en/start-workflow

One final tip

Since PHP 7 came out you can require multiple namespace items as below:
use some\namespace\{ClassA, ClassB, ClassC as C};
use function some\namespace\{fn_a, fn_b, fn_c};
use const some\namespace\{ConstA, ConstB, ConstC};

Friday, 15 March 2019

JIRA, briefly

JIRA Project

JIRA 'Project' is the highest level container, and can be created from the JIRA homepage.
In JIRA the SCRUM workflow template is the default option when creating a new project.

Issues

An 'Issue' in JIRA is a single work item within a project. An issue can be created from the '+' button on the left of the screen from within a project.
An issue should take at least a few hours, but not more than 3 days.
Issue types are :

  • Stories
  • Tasks
  • Epics
  • Bugs

Stories

Stories are planned work for a specific feature, e.g. as a user I need to delete any element of a list.

Tasks

Tasks any other planned non-story work, e.g. create the new custom module table.
Unplanned work, e.g. Put '+44' at the beginning of UK phone numbers.

Epics

An epic is a collection of stories and tasks to achieve a noteworthy outcome. Sometimes it's a good idea to think of epics at the beginning of a project and fill them with stories and tasks as you get into the detail of a project.

Labels & Components

Labels and Components are tags applied to issues which allow you to filter issues.

Labels

Labels e.g. Front-end, back-end, red-team, blue-team.

Components

Components e.g. User profile module, machine learning engine.

Backlog

'Backlog' refers to the product backlog document in SCRUM. There is a Backlog link on the left of the JIRA screen within each project.
The backlog list in JIRA contains stories and tasks. You can use this list to priortise the work into sprint size blocks.
The backlog also contains epics which you can drag and drop into priority order. You can also then drag stories and tasks into those epics.
The backlog also contains an 'All issues' section from which you can see all stories and tasks which are colour coded by the epics you have prioritised them to.
The All issues list within the backlog also contains a list of sprints. You can drag and drop stories and tasks into sprints by priority order. At the bottom of each spint list is an estimate of how long the combined issues should take. This should help you stay within sprint period i.e. normally 2 weeks.

Story points

Story points are a relative measure of complexity, e.g. 13 is harder than 5. Perhaps early on, it's a good idea to give a 2-3 hour issue a story point of 1, whereas an issue taking 3 days could get a story point of 13.

Starting a sprint

Click the 'Start sprint' button at the top of the Backlog. You should add a start and end date in the dialog box.
Click the 'Active sprints' link to the left of the project screen. This will show you what's called the 'boards'. As you work through the sprint, you will drag issues from the TO DO, to the IN PROGRESS, to the DONE boards.

Thursday, 14 March 2019

SCRUM, briefly

Product backlog

Product backlog (document) is created by product owner, It's a prioritised list of stuff which needs to be done from a business standpoint to realise the vision. It may have list items added or taken away.
People, users, stakeholders outside the project often want to know what's going on. The product backlog is their only interface to the project. They don't have access to the internal Scrum activity.

Sprint planning

The product owner and Scrum master sit down and look at the product backlog to agree the small collection of priority items which, when complete resemble a visible & quantifiable element of the project. This subset should take no more than 4 weeks (better less). When complete is added to an empty sprint backlog.

Separation of backlogs

Once the sprint backlog is full it will not be touched until the sprint is completed. No items which come into the product backlog will update the sprint backlog. If something needs adding the people requesting will only have to wait until the end of the sprint.

Sprint begins

Each day a called a stand-up meeting takes place with the scrum master and the people doing the work.
In stand-up meetings the workers say:

  • Here is what I did yesterday
  • Here is what I'm going to do today
  • Here is what is in my way

Sprint ends

There should be a potentially shippable product. The sprint backlog may now be cleared and not be revisited.
The sprint review takes place, which is a show and tell of the potentially shippable product created during the sprint.
The sprint review informs external users that progress has been made.

Product retrospective

After the sprint is over a product retrospective meeting takes place which includes the workers and and the Scrum master. It contains:

  • Lessons learned with a purpose
  • How they will continue to work

The Product retrospective feeds back to the process of taking the product backlog and adding entries to the sprint backlog.

Wednesday, 13 March 2019

Interacting with a vagrant box

SSH

The most common way of interacting with a vagrant box is through ssh. Once the box is up you can connect to it from your local terminal. Remember to be in the directory of you virtual box before doing anything. In my case it's ~/vagrant/centos65i686. Just type:
vagrant ssh

Synced Folders

The folder you used to launch your vagrant session, the one which contains Vagrantfile, can be accessed from you box after you have begun your ssh session as /vagrant. E.g.
vagrant ssh
ls /vagrant
would return Vagrantfile
During the next section titled 'Provisioning' we'll add a line to the Vagrant file to sync folders which enable the process of developing web content.

Provisioning

Vagrant can automatically install software when you vagrant up so that the guest machine can be repeatably created and ready-to-use. E.g.
Create bootstrap.sh in the same directory as your Vagrantfile with these contents.
#!/usr/bin/env bash
apt-get update
apt-get install -y apache2
Next, add these line to your Vagrantfile:
config.vm.synced_folder '.', "/var/www"
config.vm.provision :shell, path: "bootstrap.sh"
Once this is done, you'll need to reload the vagrant session and make sure that the provisioning is used thus:
vagrant reload --provision
If you're starting a session from scratch:
vagrant up --provision
will do.

Port Forwarding

During the provisioning stage we installed an Apache server. We also set up a synced folder so that whatever we had in our /vagrant folder could be served.
Port forwarding allows you to access a port on your own machine, but actually have all the network traffic forwarded to a specific port on the guest machine.
To achieve this add the following line to your Vagrantfile:
config.vm.network :forwarded_port, guest: 80, host: 4567
Then reload your session:
vagrant reload --provision
Now you should be able to access your box directory through your browser using the following URL
http://localhost:4567

When you want to finish your ssh session, just type
logout
If I mess up
If you make a bunch of changes which mess things up, don't worry. You can return the box to its original state by typing
vagrant destroy

Thursday, 7 March 2019

Using the Vanilla JS Component template with LAMP

I use the Vanilla JS Component at https://github.com/guitarbeerchocolate/vanilla-js-component, and you have LAMP server on my box. However, when I want to call PHP scripts which are on the LAMP server such as, in a POST request using fetch or XHR within JavaScript I get the following errors in my browser:
Access to XMLHttpRequest at 'http://localhost/test/vanilla-js-POST-JSON/login.php' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

postjson_xhr.js:19 Cross-Origin Read Blocking (CORB) blocked cross-origin response http://localhost/test/vanilla-js-POST-JSON/login.php with MIME type text/html. See https://www.chromestatus.com/feature/5629709824032768 for more details.

Obviously, it's treating the LAMP server like another domain.

The way to fix this is to put a line at the top of your PHP script thus:
header('Access-Control-Allow-Origin: *');
Happy coding.

Monday, 4 March 2019

Vagrant Virtual boxes (machines) on my old laptop

So, I've been playing around with Vagrant. It's been good, but I had a little pain early on because I have an old laptop. If you're a GNU/Linux user like me, you can get away with having an old laptop. I do most Vagrant things on the command-line, so the instructions below assume you're on GNU/Linux command and using the CLI.

How to install Vagrant

sudo apt update && sudo apt upgrade
sudo apt install virtualbox
sudo apt install vagrant -y

How to test the install has worked

vagrant --version

Create a sub-directory

I create a directory into which I will put all my boxes (virtual machines)
mkdir ~/vagrant
cd ~/vagrant

i686 example

Installing the box

As mentioned, I have an old laptop and therefore I can only run i686 boxes on it. You can find lots of boxes at https://app.vagrantup.com/boxes/search It was here that I searched for the term 'i686' and came up with the box 'herroffizier/centos-6.5-i686' which will be used in the example below. Still in the '~/vagrant' directory, create another sub-directory and change to it.
mkdir centos65i686
cd centos65i686
Now let's install the box.
vagrant init herroffizier/centos-6.5-i686
The installation takes place and a file called Vagrantfile is created. I like to make a few changes to this file for my own purposes. Here is my example Vagrant file below.
Vagrant.configure("2") do |config|
  config.vm.boot_timeout = 600
  config.vm.box = "herroffizier/centos-6.5-i686"
  config.vm.provider "virtualbox" do |vb|
    vb.gui = true
    vb.memory = "1024"
  end
end
I extended the timeout because I have an old laptop. I also load the GUI and give it a decent amount of memory.
Running the box
Now I'm ready to run my box. Still in the 'centos65i686' directory type the following.
vagrant up
A new window starts up and the box loads within it.
Once the loading process has completed you are presented with a login screen. Use the following credentials:
username : vagrant
password : vagrant
Now you should be in.

Tidying up

If you've finished with your box, you can close it down with the following command.
vagrant halt

Tuesday, 26 February 2019

Vanilla JavaScript Login form POST handler using XHR

I did a similar post to this called Vanilla JavaScript Login form POST handler using fetch. Fetch returns a JavaScript Promise, which can be a bit of a pain so I've also done a version using XHR, see below:

var postJSON = function(url, method, data, callback) {
  var xhr = new XMLHttpRequest();
  xhr.open(method, url, true);
  xhr.responseType = 'json';
  xhr.onload = function() {
    var status = xhr.status;
    if (status === 200) {
      callback(null, xhr.response);
    } else {
      callback(status, xhr.response);
    }
  };
  xhr.send(data);
};

Here's how to call it:
const form = document.querySelector('form');
form.addEventListener('submit', function(ev) {
  ev.preventDefault();
  const url = this.getAttribute('action');
  const method = this.getAttribute('method');

  postJSON(url, method, new FormData(form), function(error, json) {
    if (error !== null) {
      console.log('parsing failed', error);
    } else {
      console.log('json.username', json.username);
      console.log('json.password', json.password);
    }
  });
});

Tuesday, 12 February 2019

Vanilla JS Bind

I have created a Vanilla JavaScript bind class. This has been built using https://github.com/guitarbeerchocolate/vanilla-js-component and resides at https://github.com/guitarbeerchocolate/JS_Bind
It employs :


  • HTML5
  • ES6

Vanilla JS carousel

I have created a Vanilla JavaScript carousel. This has been built using https://github.com/guitarbeerchocolate/vanilla-js-component and resides at https://github.com/guitarbeerchocolate/vanilla-js-carousel
It employs :

  • HTML5
  • SASS
  • BEM
  • ES6

Vanilla JS component

I'm creating a number of elements using Vanilla JavaScript. They will use :

  • HTML5
  • SASS
  • CSS grid
  • BEM
  • Media queries
  • ES6

In order to put these elements together more efficiently, I have put together a small framework, from which I will fork.
It lies at https://github.com/guitarbeerchocolate/vanilla-js-component

Wednesday, 6 February 2019

Vanilla JavaScript Login form POST handler using fetch

I've been updating my gists lately because I'm now in position to leave jQuery behind. See https://gist.github.com/guitarbeerchocolate
So, here's how to pass login form data to some middleware and accept JSON in return using fetch.

const form = document.querySelector('form');
form.addEventListener('submit', function(ev) {
  ev.preventDefault();
  const url = this.getAttribute('action');
  const method = this.getAttribute('method');

  fetch(url, {
    method: method,
    body: new FormData(form)
  }).then(function(response) {
    return response.json()
  }).then(function(json) {
    console.log('json.username', json.username)
    console.log('json.password', json.password)
  }).catch(function(error) {
    console.log('parsing failed', error)
  })
});