Hey there
How it’s made

If you’re wondering how some thing on this webpage are made, no need to to inspect and gues what’s going on, I’ll explain it right here.

Click on the section you’re interested in and I’ll show you how it’s done!

Charles

A chat like form

Small disclaimer: this is not an actual AI, this script does not get smarter from more input. It’s merely a script that responds to user input in a conversational way.

Like on every design/developer portfolio out there I wanted a way for the visitors to contact me. But instead of the basic fill in form, I wanted to make it a little different. The idea was that the users has the feeling he or she has a converstation with a AI.

The first step in making this was to make sure what I wanted to know from the user. This came down to three points: name, message and away of getting back to them. This set the following states for Charles:

  • init
  • name
  • message
  • contact
  • done
close
minimize
fullscreen
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
switch( this.state ) { case 'name': returnMessage = this.lookForName(dataWordArray); break; case 'message': returnMessage = this.lookForMessage(dataWordArray); break; case 'contact': returnMessage = this.lookContact(dataWordArray); break; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
switch( this.state ) { case 'name': returnMessage = this.lookForName(dataWordArray); break; case 'message': returnMessage = this.lookForMessage(dataWordArray); break; case 'contact': returnMessage = this.lookContact(dataWordArray); break; }

Perfect, we only need to analyse what the user sends us and reply accordingly. So firsts things first, say hello to our user. In my case the conversation starts when the contact sections scrolls into view. We trigger a few messages from Charles and ask the user to introduce himself.

Now we need Charles to understand what the users replies. How do we do this?

close
minimize
fullscreen
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
const ui = { inputForm: document.querySelector('.js-form'), inputField: document.querySelector('.js-input'), outputField: document.querySelector('.js-output') } ui.inputForm.addEventlistener( 'submit', (e) => { e.preventDefault() const dataString = ui.inputField.value const dataArray = dataString.split(' ') ui.outputField.innerHTML = dataArray.join(' - ') } )
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
const ui = { inputForm: document.querySelector('.js-form'), inputField: document.querySelector('.js-input'), outputField: document.querySelector('.js-output') } ui.inputForm.addEventlistener( 'submit', (e) => { e.preventDefault() const dataString = ui.inputField.value const dataArray = dataString.split(' ') ui.outputField.innerHTML = dataArray.join(' - ') } )

In every state of the conversation we’re looking for different information. In the first state we try to get the users name from the message. And this is a tricky one, because a name can be anything. So every word in a greeting that’s not a greeting/introduction word I assume is part of the name.

Let’s take the following example:

'Hey I'm Mr T'

What we want are: “Mr” and “T” with a space in between. So what we do is we loop every word in the message and check the word if it’s present in one of our lists. “Hey” would be present in our list of greetings words and “I’m” would be our introduction list.

close
minimize
fullscreen
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
const dataString = 'Hey I'm Mr T' const dataArray = dataString.split(' ') // [ 'Hey', 'I'm', 'Mr', 'T' ] const checks = { cursing: false, } let name = '' dataArray.forEach( word => { if ( checks.cursing ) return checks.cursing = this.curseWords.includes( word ) if ( this.greetings.includes(word) || this.introduction.includes(word) ) return name = name ? `${name} ${word}` : word } )
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
const dataString = 'Hey I'm Mr T' const dataArray = dataString.split(' ') // [ 'Hey', 'I'm', 'Mr', 'T' ] const checks = { cursing: false, } let name = '' dataArray.forEach( word => { if ( checks.cursing ) return checks.cursing = this.curseWords.includes( word ) if ( this.greetings.includes(word) || this.introduction.includes(word) ) return name = name ? `${name} ${word}` : word } )

With the 'Hey I'm Mr T' example our loop would product the following name: 'Mr T', perfect!Now that we got the name of the user time to ask them for their message.

A message from a user can be multiple lines and can contain just about everything. The only thing we should check for is the swearing and submitting a message that’s to short. For swearing we can use the same check as before, explode the message and check each word.For the length we have to do something different, because the user can use multiple lines for their message, I decided to place a stop word. Once the users says: 'Thank you” we end the message. This way they can use multiple lines and I can append them to the total message. If the total message is to short we ask them elaborate a bit more.

The final state for the user is contact information. Here, like in the message, we give them a lot of freedom. If the user wants to leave a phone number or an email, that’s fine by me. So the only thing we check for is swearing. Now we have all the information we require from the user.

The last thing we need to do is thank the user for filling in the information and say our goodbyes.