Beutelevision

by Thomas Beutel

Adding special options to select using Vue.js

I get some interesting requests from my clients and some of them are head-scratchers. The beauty of Vue.js is that you can implement almost any behavior and do it fairly simply.

In this case, the client wanted to swap in a different Act-On form via an iframe if a certain option was selected. Since the original options were being populated from an API (via axios) I had to add the special option separately.

Here is what I did in the select component:


Vue.component('course-selector2',{
props: ['courses','value'],
template: '<select class="custom-select" v-model="course"><option value="">Select date and location</option><option v-for="option in options" v-bind:value="option.value">{{ option.label }}</option></select>',
computed: {
options: function() {
var type = this.courses.type;
var list = this.courses.list.map(
function(obj){
var label = obj.start_date_formatted+' | '+obj.location;
return {'value':obj.event_internal_id,'label':label};
}
);
list.push({'value':'-1','label':'I\'m not sure yet. Please have someone call me.'}); // this will show a different form
return list;
}
},
data: function() {
return {
course: ''
}
},
watch: {
course: function() {
this.$emit('input',this.course);
}
}
});

In the computed options above, note how I push the extra option onto the list. Obviously I could have just added the option in the template itself but I find this to be a cleaner and easier to read implementation.

Later in the main app code below, I implemented a watch to do the swapping. Whenever the Please have someone call me option is selected, the registration form is hidden and the contact me form is shown instead.


window.onload = function(){
var app = new Vue({
el: '#app',
data: {
courses: [ ], // populated via axios, not shown
course1: '',
display_reg: true,
display_call: false,
internal_event_id: 0
},
watch: {
course1: function() {
this.event_internal_id = this.course1;
if(this.event_internal_id == -1){
this.display_reg = false;
this.display_call = true;
}
else {
this.display_reg = true;
this.display_call = false;
}
},
template: '<form v-show="display_reg" id="myform" method="post" action="/path/to/cart">' +
'<div style="margin-top:10px;"><label style="display:block;color:#ffffff;">Course Date and Location</label><course-selector2 v-model="course1" v-bind:courses="{type:\'Course Listings\',list:courses}"></course-selector2></div>' +
'<div style="margin-top:24px;"><img style="cursor:pointer;" id="add-reg-btn" v-on:click="onSubmit" type="image" src="/images/acton/continue.png" border="0"/></div>' +
'<p style="color:#ffffff;" v-show="display_cart_text">You will be directed to an online cart to complete your purchase and confirm registration.</p>' +
'</form>' +
'<div class="wrapper"><iframe class="custom-iframe" v-on:load="hideCallHeader" v-show="display_call" src="path/to/act-on-form" style="border: 0; min-height: 565px;margin-left:-10px;"></iframe></div>'
});

Please note that the above is just a rough sketch. I have not tested the above example and major portions of the app are missing. My purpose here is just to give you an idea of what I did.

Prevent default in Vue.js after checking value

Here is what I did to prevent a form submit based on a value. In this case, I’m checking to make sure a value is not blank.

 <form id="myform" method="post" v-on:submit="onSubmit" action="/path/to/form-handler">
 methods: {
        onSubmit: function(e) {
            if(this.some_value == ''){
                e.preventDefault();
                return false;
            }
           return true;
        }
 },

One Month of Blog Posts

I managed to post one post per day for a month. I’m really happy with this milestone. I can’t say that each post was long or weighty, but that wasn’t the point for me. My goal was just to post something each day, either an observation, an assertion or a prediction.

The purpose of this was simply to do get my thoughts out and to do it every day. What I found is that the first 20 or so posts just came out. At one point I was a couple of posts ahead so I wrote them in my personal notebook (I use Scrivener for that) and then posted them the day after I wrote them.

The more recent posts came more reluctantly. I was blocked for a bit but then I just opened up WordPress and started writing. And once a few words came out, the rest were right there. I guess that is my biggest learning. Just start, and the rest of the post will almost write itself.

Athletic Socks Apparently Like Chrome Lures

I fished high tide again today at Ocean Beach. It was just as windy as yesterday but I dressed for it and was comfortable for the 2-1/2 hours I was there. There were fewer anglers today than there were yesterday and I didn’t see anyone catch anything.

The only bite I got was on a chrome lure. A healthy size large athletic sock slammed the lure, and it weighed well over a pound. This was a first for me. Needless to say I was surprised if not exactly elated. I let it go and for a split second I considered fishing for the other sock but I was satisfied with just the one.

One thing I like about fishing is that every time I’m out, I expect the unexpected and I learn something new.

Ocean Beach Striper Fishing – Part 1

I fished for a little over an hour at Ocean Beach around high tide. It was my first time using a fish finder rig and sand crabs, so it was mostly a learning mission. I saw about 20 other anglers fishing bait, presumably sand crabs as well and one of them pulled out a dandy of striper. It must have been at least 10 pounds.

What I did learn was: 1) casting into the wind is a challenge; 2) standing in the wind is more of a challenge; and 3) bring a container for sand crabs. Finding the sand crabs was easy enough. I have a small bait net that use the surf to scoop them up. I even found a couple softshell crabs among them.

I’ll give it another try tomorrow. I’m going to wear another layer to stay warm and also bring something for my ears.

Bedtime Reading

I tend to read non-fiction more than fiction, especially late in the evening, and one of my favorite reading topics is seismology. There are many good books about it on my bookshelf and one of my favorites is Cascadia’s Fault by Jerry Thompson. It chronicles the research conducted in the 1980s that uncovered the true nature of the Cascadia subduction zone. Prior to that time the subduction zone had not been considered a threat for large earthquakes. A lot of interesting fieldwork was done to show just the opposite.

My favorite story is on the fieldwork done by Brian Atwater and his colleagues to show that a grove of of dead cedars had all drowned in an earthquake in the year 1700. I think the reason I find this story so compelling is that it was not at all intuitive that the dead trees would be at all related to an earthquake. The trees were easy to overlook and although some locals had known about them, it was Atwater who made the connection. And when he did find them, it still took much work to uncover their actual date of death. The outer layers of bark had rotted away, and it was a while before a solution was found using tree-ring analysis of the roots. The date was later corroborated with an orphan tsumani record from Japan.

I have probably read this account four or five times and I’m still in awe of all the connections that had to be made to make this story complete. So many opportunities to miss clues and yet it all came together to tell a compelling story of a massive earthquake over 300 years ago.

Multiple Open Graph Images in Act-On Landing Page

A client asked me today if there is any way to have multiple Open Graph (og:image) images in an Act-On landing page, as Act-On only specifies one image in their SEO section. I searched around a bit, but then I realized that it’s actually quite straightforward. Simply add the additional meta tags in the Javascript section, since this section is placed in the head element of the page.

We tested it in Facebook and it worked well. We did find out that when you post in Facebook, it only allows you to select from the first 5 images.

Karl the Fog, Fishing Buddy

I go fishing twice a week, either at Crissy Field or Ocean Beach and I experience all varieties of weather. The other day it was just gorgeous! Not a cloud in sight, and the few wisps of fog disappeared as soon as the sun was up. It was warm, meaning that with all my layers and neoprene waders on, I wouldn’t have minded at all if a there was a breeze to moderate the low 60s temperature. It was nice to feel the warm sun reflecting off the water.

But I’ll admit something. I really prefer fog. A foggy morning at the beach is what I connect with good fishing. Everything seems a bit calmer, and at least in my mind, I seem to get more bites. Maybe the fish are a bit less wary when it’s overcast? I haven’t kept a record of sunny vs. foggy, so it’s just a feeling. But I think this is especially true when the water is gin clear, which it has been of late, especially during moderate tides.

I grew up on the west side of San Francisco. Karl the Fog was my constant companion during school vacation time, and I remember resenting him a bit. Why couldn’t be here during school days but gone in the summer? But that’s not the way our weather works. But now that I’m much older he’s a good friend and fishing buddy. I look forward to waking up and hearing the fog horns sounding in the Golden Gate. It means to me that a good morning of fishing it about to begin.

Dunked

There always a first for everything. This morning I was fishing at Crissy Field for halibut, trying my best to get that bite which is ever so rare. It takes a bit of concentration. At first I fished a large 5-1/2 inch swimbait. I wasn’t getting any bites but it was casting real well and the lure has quite a presence. Unfortunately after about 2 hours of casting it I got snagged and lost it. That was partly my fault. I whipped the rod and snapped the monofilament leader. Next time I’ll be a bit more patient and see if I can loosen it by trying different angles.

Losing lures is all part of fishing, although it’s been rare that I’ve lost lures at Crissy. It is almost all sand after all. But it does happen.

So I decided to put on a chrome spoon. A few days ago I caught some small surfperch on it, both at Crissy and Ocean Beach. But I know that halibut will strike it as well. And sure enough I got a couple of strikes. I’m guessing they were surfperch but you just never know.

I made my way over to the tide station in the small area between the station and the weir that protects it. I was standing in about 2 feet of water. Being in a wave-protected area, the water is particularly calm. I cast the spoon out and just moments later saw a jacksmelt jump not to far from where I was reeling it in. Hmm, I thought, a jumping smelt? Could it be being chased by a halibut? I’m ever the optimist. Then as I reeled in some more, I felt a really good deep strike. Wow, that felt like a bigger fish. But somehow I missed it.

Now I was even more determined. Next time I would really try to set the hook. So I cast a couple more times. And sure enough I got a good strike, so I reared back… and then I promptly slipped and fell backwards into the water! I got my backpack wet and probably a couple of gallons of saltwater in my waders. I was soaked down to my undies.

But in those milliseconds before I fell I also knew that I had hooked the fish. So I scrambled out of the water, dripping, and reeled in a… jacksmelt.

It was just one of those moments when you know it’s time to pack it in and go home.

Act III

I don’t watch a lot of TV these days. I spend a lot of time working, writing and creating Yes, I have been watching the NBA Finals and I do watch the occasional Giants game. But other than that, my media consumption consists primarily of podcasts and short fishing videos on youtube.

But once in a while I want to rewatch a favorite movie. My guilty pleasure these days is popping in a Star Wars or Pixar DVD and just watching Act III. It feels a little bit like cheating. But I’ve seen all of these movies plenty of times before, so why not? However, I do watch a New Hope from the beginning, always!