Painting big

I’ve been watching some youtube videos about painters who work outside on 9 x 12 or 12 x 16 inch boards. Then they return to the studio and upsize the painting to a larger size more suitable for hanging in a living room.

I prefer to work at 16 x 20 but I’m learning that my skills aren’t quite ready to create sellable work. So these large plein air paintings bomb, which means I spend a lot of time sanding them down and re applying the gesso for another go.

Another route many artists go is painting on gesso covered canvas which is merely taped to gatorboard. Then if the painting turns out, it can be glued to a board and framed, or, if the board is cradled, it’s ready to hang without a frame.

I have never painted large in oils…but for a number of reasons I wanted to try it. First I needed to learn how to cradle a large board. 24 x 36 x 0.25″ boards will sag, so they have to be supported by a cradle on the back…which can also act as the frame, making them ready for hanging.

https://www.youtube.com/watch?v=sfEdmw0pCik&t=100s

I borrowed my son’s miter saw, bought some high quality plywood and spent a few days out in my garage/shop learning how to be a carpenter. When I put the 24 x 36 inch oil gesso’d board on my carbon fiber easel, I realized it was too flimsy for a board that big.

I already have a heavy duty Bogen easel dating from my 4 x 5 large format camera days. But I had no way of mounting the board to the easel. Off to Lowes I went with only a rough idea of how I could build an easel from scratch. Man, I love inventing stuff from metal! I think inventing fits me better than painting.  There is a cool combination of sketching, thinking and working with drills, saws and screws that’s just really fun. It’s also neat to put stuff together that is better (and cheaper) than what you can buy in stores. I guess I like solving problems. I will post pictures later.

Should you have kids?

I saw this article about the decline in babies on the Washington Post website, to which I have a subscription and wrote this comment:

A topic close to my heart. We loved having our son and daughter 30 years ago. Kids forced us to cut back a little on rock climbing, but we still found ways to get out. Kids love to play outside! My wife did licensed home daycare during the 9 years they were young and not in school. Her daycare earned enough to pay our mortgage payment each month, and she was able to be their parent full time while I worked swing.

When they were both in school, she was able to return to her old job (COTA at a school), and that gave her the same summers off as the kids. This allowed her to be home when they got out of school. We never put our kids in day care. We also had two sets of grandparents within easy driving distance who would watch the kids on weekends to give us a break.

My blue collar income was never very much…but we lived frugally. I see so many young people now spending vast sums of money on really dumb stuff…like motorhomes, boats, hotels and exotic fly away vacations. We still car camp in little backpacking tents, as do our kids…it is possible to live cheaply…and make kids work.

They both got after school jobs in high school (dry cleaners, barista, planter nursery) which helped when they needed to buy their own transportation. They kept those jobs all the way through college. It was impossible for us to save money for college while raising two kids, paying our mortgage and keeping 3 old cars running.

Amazingly, our local community college had a scholarship program. It was called the “First Generation Grant”. If neither parent had a 4 year college degree, you could apply, and they granted about a dozen a year. We were surprised when they both qualified and were awarded the grants. They both work as nurses now and have money to burn, and zero college loans.

I don’t know if they will have kids…I know they kind of want them…but they are having so much fun they don’t want to slow down yet. I’m hoping they have them. My parents made sacrifices to have me and my siblings  I’d like to return the favor to the next generation. Kids are a bucket list thing….and besides, what could be more natural?

Old friends

Saw Ted today. We met in the 6th grade and have stayed friends ever since. Not counting my cousins, he is my oldest friend. He brought his daughter and we had a classic adventure getting lost at Point Defiance. We walked down to Owens Beach, then West along the water until we ran out of time. We saw a trail heading up the steep bank and started up. The trail petered out and we were lost. Not really lost…though that depends on how you define it. But it got interesting as we picked our way though the forest until a road showed up.

We are going to get together in a couple weeks to jam. We started playing together in high school when 4 of us started a garage band. I was the harp player and Ted played base. We had a rhythm, lead guitarist and a drummer. The drummer had a real job so he was in charge of renting the rehearsal garage. I remember pedaling my bicycle to band practice. We only played a few gigs, but it was lots of fun playing and practicing.

Later Ted and Bob formed a much better band that won a competition in Seattle.  They toured Eastern Europe on a fully funded one month concert tour. We all thought they were on their way to something big…but I think they broke up not long after that. We continued jamming for a decade after high school, but then drifted apart as old friends do. There were a few meetings over the decades that followed but they got farther and farther apart.  Anyway it was awesome to see my old buddy again and I hope we play some live music soon.

I stumbled across a Tedx talk online about a guy who says social media is bad for your career. This runs counter to current thinking, but his speech was so compelling I decided to take a break from Facebook and Instagram for a while. It’s only been two days but I like it already.

His main point was that social media is distracting and keeps you from doing what he calls: “Deep Work”. That is defined as long periods, like 4 or more hours where you are completely focused on one task. For a programmer it might be writing complex code. For a writer it would mean writing non-stop for hours with no distraction. For me as an artist, it means painting steadily for hours without any distraction…at all.

He also argues that a commonly held social media theory is a myth. The theory is that being on social media widens your networking audience and makes you more employable. He feels that getting off social media will make us much more marketable because we will be able to do deep work. And that deep work is so rare that it will overcome our lack of social media presence and bring employers. It makes sense. Multi tasking is a dog that won’t hunt. Deep work is something I’ve always loved. Running a printing press was all about deep work. We’d commonly work 12 hours or longer. Climbing is all about deep work and total focus. I never take my cell phone climbing, and I am happier for it.

Speaking of climbing, V. and I spent 3 days at Squish and discovered a new crag called the Papoose. I’d been there with Bud Miller decades ago but never went back after a runnout scare, until last weekend. There are two lovely 5.9 splitters at the base that we both on-sighted. They were both exceptional climbs and I’m so glad we decided to go exploring on a new crag.

Indian Creek 2018

We left Friday at 5PM. Arrived Saturday at Sand Creek Campground in Moab at 4PM. Easily got a site in the huge campground for $15 a night. Bought 3 nights planning on a Tuesday AM departure.

Hiked in light snow at Arches Sunday. Monday I painted Delicate Arch twice, morning and afternoon light. We’d planned on hiking the first half of the trip, then climbing the last few days. But the weather looked to be turning bad Thursday Friday. I was worried that if we hiked until Tuesday, we might only get one day of climbing on Wednesday, then the rain would come in. I texted Chad that he might want to come down a day early. Monday evening Chad showed up and we drove down to Indian Creek Tuesday morning where we did Generic Crack, Binou’s Crack and Chocolate Corner before camping at Super Bowl.

Wednesday we hiked up to Supercrack buttress, which is the same parking lot as Donnelly and did Twin Cracks 5.8+, Incredible Hand Crack 5.10 (12 yellows, 2 reds and a blue) and No Name (left of Twin Cracks) 5.10. Chad did a heck of a job getting half way up No Name before running out of steam. He has smaller hands, so it was miles of steeple jams, which, as he said: “Two moves takes everything I have.”

I was fresh from belaying, so I took over the lead and hung dog my way to the anchors. We used to call that yo yoing back in the day. It took 11 blues, 3 reds and maybe 8 yellows? Everything we did needs just one 60 to get off, as the anchors seem to be bolted right at 30 meters. I suspect the routes went in before 70’s became popular.Generic may be the exception at a little longer…but I’m not sure.

I think one would need at least 2 weeks down there to build up the muscle power to climb those cleanly. Or maybe it is something I need to do before going down. The guys I saw who were sending those hand cracks cleanly all had arms twice as thick as mine. At the very least I need to hit the pull ups hard, and make a couple trips up to Vertical World and run laps on the hand crack. Hand power is ultra critical down there.

Thursday we needed a rest day so we climbed the easier South Six Shooter. The approach was thought provokingly dangerous, and I backed off the 5.6 mantel move. I had a ton of rope drag, the wind was howling, and it didn’t feel like a rest day move. Plus the if you blew the mantel move you would very likely break something as  the gear was below your feet, and there were ledges to hit. Getting injured on top of  a mountain with a one hour approach is just plain stupid.

Chad owed me a finish from No Name, so he stepped up to the plate and sent the mantle nicely. Because it was a rest day, I also had trouble with a rounded 5.7 crack lower down on the second pitch. I hung 3 times. I think I was just tired. The creek is burly.

The summit views were lovely…climbing mountains is satisfying. We did the rap in two raps with our 60. One short one down to the chains 50 feet below the summit, and another 30 meter rap to the ground, passing the ugly slung block station.

Alex ran up while we were climbing but got there too late to join us, so he walked Sue down to the car. She was getting cold waiting. When we got down to the car I was ready to get serious about my rest day. But Alex was there…and I didn’t want to say no. When he offered to carry the pig up to the crag I caved and abandoned any thoughts of a rest day.  We hiked up and Alex led Supercrack. It took all 11 blues, plus 6 yellows. I would have brought a 5 for the last move to the chains, had I led it. It was Alex’s first creek lead, so he hung a lot but got up.

I hung twice on follow. The jams were great hands for my huge mitts. Plus I was wearing Ocuns over tape to be fatter. I’m not sure I will ever lead it though because the 10C start crack is super awkward. It starts good, then flares to a rounded #5 with a block in the way. You might be able to get a half inch cam in the block. Other than that I’m sure I could hang dog my way up the main crack. It’s a spectacular crack. Love to get some photos from either the anchors or the tower off right. It did have anchors for safely taking pictures of your leader.

Thursday night it poured, which matched the forecast from Monday. We drove up to Moab where I painted Double Arch while Sue did another Arches hike to Landscape Arch and beyond. And then the epic drive home. Left at 6PM, got home at 2PM Saturday.

Newspaper Rock

Newspaper Rock

 

North Six Shooter

North Six Shooter

 

South Six Shooter, Chad about to take over the lead at the mantle.

South Six Shooter, Chad about to take over the lead at the mantle.

 

 

North Six Shooter, from summit of South Six Shooter.

North Six Shooter, from summit of South Six Shooter.

 

Summit of South Six Shooter.

Summit of South Six Shooter.

 

Summit of South Six Shooter.

Summit of South Six Shooter

 

Petroglyph on first pitch of South Six Shooter.

Petroglyph on first pitch of South Six Shooter.

 

Incredible Hand Crack, all yellows

Incredible Hand Crack, all yellows

 

Incredible Hand Crack, all yellows. I found a rest!

Incredible Hand Crack, all yellows. I found a rest!

 

Chad on No Name crack

Chad on No Name crack

 

Generic Crack

Generic Crack

 

Binou's crack, got it clean this year

Binou’s crack, got it clean this year

 

Painting Delicate Arch, building on a blue monotone base

Painting Delicate Arch, building on a blue monotone base

 

Climbing season begins

I’m putting together some borrowed gear for climbing. It’s a big rack.  I’ve been playing a lot of ping pong for exercise. I’m a decent defensive player, able to dig for balls that appear to be hopeless. I have a couple pretty good serves, and can occasionally get in a good slam, though it’s not reliable yet.

So when I heard there was a ping pong tournament at the local climbing gym I got all excited. The prize was a $180 pass for 10 visits. Most young people are too busy playing video games and don’t pursue ball sports. And if they are athletic, I figured they’d focus on climbing, at the expense of ball sports.

The first young guy I played had a little talent but clearly didn’t spend a lot of time at pong. Then I sat out and watched 3 games with people who I thought I could beat…or at least equal.

When my turn came again I was matched with a 23 year old guy who held his paddle with the penhold grip. If that wasn’t scary enough, the way he was bouncing on his feet like a boxer sealed the deal. From the very first time his ball came over the net I knew I was in serious trouble. Every ball had a wicked spin. They’d float over the net headed south, but after the bounce they’d head east, or west, or any direction but the original vector.

I lost 8 to 11 and went home in a bad mood. I mean, really, what was I thinking? I’m 64 and I went to tournament in  a climbing gym full of people in their 20’s. It was inevitable that I would loose. Pick any activity, and no matter how good you are, there is always going to be someone better. Add in the factor of age, and it just happens more often.

While I was stewing in my bad mood I got to thinking about all the things at which I am mediocre. Here is my list. I have mediocre skill at the following:

  • rock climbing
  • backcountry skiing
  • downhill skiing
  • ping pong
  • guitar
  • chromatic harmonica
  • landscape, still-life, seascape painting
  • photography
  • operating an industrial sewing machine
  • operating a printing press
  • programming JavaScript
  • filmmaking
  • studio lighting
  • electrical wiring

And here is my list of things at which I  consider myself to be talented:

  • parenting…kids turned out great!
  • blues harp
  • teaching ( I was awarded tenure…until my program closed)
  • HTML5, CSS3, JavaScript Animation
  • Photoshop and Illustrator
  • WordPress
  • portrait painting
  • life planning (our house and cars are paid off)
  • marriage…though Sue might disagree?
  • inventing, designing and trouble shooting…I make things
  • social skills, I can get along with anyone.

After a couple days of thinking about it I came around to the realization that being a jack of all trades, master of none means I am quite good at one thing that isn’t on either list:

I am really good at having fun! The fact that I am mediocre at an activity doesn’t stop me from enjoying it. That long list of things at which I am mediocre represents a lot of time…a lifetime really…of trying different things…and focusing in on the fun ones.

I’ll be working three days a week again in April. That will be fun to get a pay check again. I sort of miss those. In late June I’ll be off again for the summer…which might be really sweet. I plan to keep studying JavaScript. I decided to give up Python…I think that was a wrong turn. I realized there was much more to learn in JavaScript so I got a new book called Eloquent Javascript that looks fun.

 

Skied up Mount St. Helens

Clint, Craig and I skied up Mt. St. Helens yesterday.  I ate steak and potatoes the night before but it wasn’t enough. At the halfway point we could see figures on the summit, but my endurance was very low. I could skin up about 100 feet, then I’d have to pause for a while to catch my breath, and repeat. The distances between pauses got shorter the higher I got.

I apologized to Clint for going so slow, and he said he wasn’t in any hurry, that I should take my time. My son and Craig are both superb skiers, while I am mediocre at best. I was the oldest guy on the mountain by at least 20 years. Most of them were between 25 and 35. Most of the 100 people we saw were on snowshoes or on foot. It’s weird that only about 1 in 5 were on skis. Skis made the trip down a lot faster, and in spots the skiing was excellent, feeling like  the steep section of a blue run at Crystal i.e. the Forest Queen chair lift. The skiing down Worm Flow couloir was fairly easy in spring corn, though it had some cement snow in places.

Down lower on the main hiking route there were tons of post hole tracks which made for choppy skiing. I was so tired by then (10 mile round trip, 4500 feet gain) that all I could do was shaky snow plow turns. We were racing the light, as getting caught in the dark on icy snow was not an attractive option.

 

# # Example file for parsing and processing JSON # import urllib import json def printResults(data): # Use the json module to load the string data into a dictionary theJSON = json.loads(data) # now we can access the contents of the JSON like any other Python object if "title" in theJSON["metadata"]: print(theJSON["metadata"]["title"]) # output the number of events, plus the magnitude and each event name count = theJSON["metadata"]["count"] print (str(count) + " events recorded") # for each event, print the place where it occurred for i in theJSON["features"]: print(i["properties"]["place"]) print("-----------------\n")#this runs after the for loops is done # print the events that only have a magnitude greater than 4 for i in theJSON["features"]: if i["properties"]["mag"] >= 4.0: print "%2.1f" % i["properties"]["mag"], i["properties"]["place"] print("-----------------\n")#this runs after the for loops is done # print only the events where at least 1 person reported feeling something print("Events that were felt: ") for i in theJSON["features"]: feltReports = i["properties"]["felt"] if feltReports != None: if feltReports > 0: print "%2.1f" % i["properties"]["mag"], i["properties"]["place"], " reported " + str(feltReports) + " times" def main(): # define a variable to hold the source URL # In this case we'll use the free data feed from the USGS # This feed lists all earthquakes for the last day larger than Mag 2.5 urlData = "http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.geojson" # Open the URL and read the data webUrl = urllib.urlopen(urlData) print ("result code: " + str(webUrl.getcode()))#returns: 200 = true, it got data if (webUrl.getcode() == 200): data = webUrl.read() printResults(data) else: print("Received error, cannot parse results") if __name__ == "__main__": main()

Me and my son Clint

Summit shot, me, Craig & Clint

Summit shot, me, Craig & Clint

 

St. Helens crater

St. Helens crater

 

Clint and Craig lunch break, Mt. Adams in the background

Clint and Craig lunch break, Mt. Adams in the background

I’ve been studying Python. My Django studies got weird because Django runs in Python and I’d never done Python. Sometimes I feel like I’m trying to learn Japanese, French, Russian and Spanish all at the same time.

This was my latest exercise. This is the Python code for pulling JSON data from the USGS Earthquake website. It formats the data and then spits it back out as a list of recent earthquakes with information about strength, location and whether it was felt.

# 
# Example file for parsing and processing JSON
#
import urllib 
import json

def printResults(data):
  # Use the json module to load the string data into a dictionary
  theJSON = json.loads(data)
  
  # now we can access the contents of the JSON like any other Python object
  if "title" in theJSON["metadata"]:
    print(theJSON["metadata"]["title"])
    
  
  # output the number of events, plus the magnitude and each event name  
  count = theJSON["metadata"]["count"]
  print (str(count) + " events recorded")

  # for each event, print the place where it occurred
  for i in theJSON["features"]:
    print(i["properties"]["place"])
  print("-----------------\n")#this runs after the for loops is done

  # print the events that only have a magnitude greater than 4
  for i in theJSON["features"]:
    if i["properties"]["mag"] >= 4.0:
      print "%2.1f" % i["properties"]["mag"], i["properties"]["place"]
  print("-----------------\n")#this runs after the for loops is done   
  
  # print only the events where at least 1 person reported feeling something
  print("Events that were felt: ")
  for i in theJSON["features"]:
    feltReports = i["properties"]["felt"]
    if feltReports != None:
      if feltReports > 0:
        print "%2.1f" % i["properties"]["mag"], i["properties"]["place"], " reported " + str(feltReports) + " times"
  
def main():
  # define a variable to hold the source URL
  # In this case we'll use the free data feed from the USGS
  # This feed lists all earthquakes for the last day larger than Mag 2.5
  urlData = "http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.geojson"

  # Open the URL and read the data
  webUrl = urllib.urlopen(urlData)
  print ("result code: " + str(webUrl.getcode()))#returns: 200 = true, it got data
  if (webUrl.getcode() == 200):
    data = webUrl.read()
    printResults(data)
  else:
    print("Received error, cannot parse results")

if __name__ == "__main__":
  main()

 

Recent Songs

I’ve been playing guitar and or harmonica about an hour a day recently. Along with regular exercise, it helps me stay balanced. Music is a wonderful gift I got from my parents, who were also both amateur musicians. Dad sang into his 90’s, and mom played the piano.

Here are my recent songs. Finding the  sheet music and chords for any given song is a challenge. The two websites linked here seem to be the current best choice. Both of them allow you to transpose the key. Transposing is essential if you are a beginner, as I am on the harp. I need as few flats and sharps as possible. Plus the key needs to fit my voice and the guitar chords need to be easy. It’s a lot to ask, but those websites make it happen. And for $5.50, the sheet music is nicely priced and instantly downloadable.

Once I get the chords, I copy them into Word and massage them so they are correct, and so they fit on one page. Here are 4 of my most recent songs.

 

bobby-mcgee

bobby-mcgee

 

save-best4-last

save-best4-last

 

candle-in-wind

candle-in-wind

 

my-father-chords

my-father-chords

 

Sitting on the dock of the bay

Sitting on the dock of the bay

Skiing and climbing in one weekend

Saturday Sue, Lisa and I skinned up to Pebble Creek above Panorama Pt. Then we dropped into the bowl above the top of Mazama Ridge, where a cloud rose up to meet us just as we got to the best snow. We skied blindly for half an hour, trusting in our previous trips there to know we weren’t skiing off cliffs. That was nerve wracking. Lisa is the best skier and was boldly leading out ahead. She’d do a few turns into the white out, holler up that it was ok and we’d follow.

Eventually we came out of the cloud but by then we were in the flats on top of Mazama. Another half hour brought us to Clints snowcave. He, Craig, Tony and Mike had skied up with overnight gear and were well into a 4 man snow palace.

It was getting on toward 4 PM by then and we couldn’t stay long as the car was several miles down and away in deep cement snow. It was a lovely day with the family, but we were very glad to get to the car. Sue and I were exhausted but Lisa could have probably done it all again.

I got up early Sunday and drove to Vantage with Vitaliy, Christine and Julia. We met Vladi and a few other gym friends there. I got up Air Guitar and Pony Keg cleanly, but had to hang on Whipsaw and Sunshine Buttress. My absence from the climbing gym has made my fingers weak. It was great hanging out with so many good climbing friends. Even Chad was there and we talked about Indian Creek.

When we got to Ellensburg there was a roadblock on I-90. The pass had shut down due to snow. It took us a total of 8 hours to drive home from Vantage, including waiting at a restaurant for an hour. We took 97 over Bluit Swauk Pass, then Stevens Pass, and 203 down through Carnation to Julias car at North Bend.

Lisa's 30th birthday. From right, me, Clint, a nurse, nurse, Lisa, Bonnie

Lisa’s 30th birthday. From right, me, Clint, a nurse, nurse, Lisa, Bonnie

 

Vitaliy, me, Christine, Julia, ?, AJ, ?, Christian

Vitaliy, me, Christine, Julia, ?, AJ, ?, Christian at Vantage

 

Lisa and Clint top of Mazama Ridge

Lisa and Clint top of Mazama Ridge

 

Looking up above Pan

Looking up above Pan

 

Lisa and Sue top of pan

 

to do app in html5

I spent a full day trying to debug an indexedDB JavaScript lesson. It would work on my iPhone, and on codepen, but nowhere else. It wouldn’t  work at all on my MacBook, except for codepen.com. I knew my code was clean because typing errors are always the first thing I check. And the way it was behaving, I could tell it was some kind of security blockage either on the hosting servers or in the browsers.

While searching for an answer I came across another free online tutorial, and this one worked. I don’t know why it worked because it was structured much the same, though with subtle differences. Anyway I was able to combine stuff I’d learned in both tutorials to make a pretty sweet little  pure  HTML5 and vanilla JavaScript  note taking app.

Once I had it running I realized it was missing the drag and drop functionality I’ve come to expect in apps like wunderlist. After a quick google search, I found a tutorial that built a drag and drop list. Sadly, that one has a problem on mobile devices. You can drag the list items on a computer, but not on a phone. Phones have a different set of responses and the  eventListeners are set up completely different from computers.

But more searching led me to this cool tutorial page with links out to the slip.js library.

And finally I had a very nice little “todo” note taker app. It’s still not hooked up to a database…that may be coming. But it’s actually quite useable. There are 400 lines of code, not counting the slip javascript library. I prettied it up with some style sheets, and tried to make it mobile friendly.

It’s tricky to embed it in WordPress. There are conflicts with classes and ID’s. So instead, here is a direct link on my server.. It remembers your list items as long as you don’t clear your browsers cache. It does not sync with your computer though… You need wunderlist for that.

Just for practice, I’ve also posted it up on codepen so that you can tinker with it, if you should so desire.

There are two js files that run it. This is the one that hooks it up to the indexedDB database.

var todoDB = (function(){
  var tDB = {};
  var datastore = null;

  //todo: add methods for interacting with db here
  //open connection to the datastore

  tDB.open = function(callback){
    //database version
    var version = 1;

    //open connection to db
    var request = indexedDB.open('todos', version);

    //handle upgrades to datastore
    request.onupgradeneeded = function(e) {
      var db = e.target.result;

      e.target.transaction.onerror = tDB.onerror;

      //delete old datastore
      if(db.objectStoreNames.contains('todo')) {
        db.deleteObjectStore('todo');
      }

      //create a new datastore
      var store = db.createObjectStore('todo', {
        keyPath: 'timestamp'
      });

    };//end request.onupgradeneeded function

    //handle success datastore access
    request.onsuccess = function(e) {
      //get a reference to the DB
      datastore = e.target.result;

      //execute callback
      callback();
    };
    //handlerrors opening datastore
    request.onerror = tDB.onerror;

  };//end tDB.open = function

  //fetch all the todo items in the datastore
  tDB.fetchTodos = function(callback) {
    var db = datastore;
    var transaction = db.transaction(['todo'], 'readwrite');
    var objStore = transaction.objectStore('todo');

    var keyRange = IDBKeyRange.lowerBound(0);
    var cursorRequest = objStore.openCursor(keyRange);

    var todos = [];

    transaction.oncomplete = function(e) {
      //execute callback
      callback(todos);
    };

    cursorRequest.onsuccess = function(e){
      var result = e.target.result;

      if(!!result == false) {
        return;
      }

      todos.push(result.value);

      result.continue();
    };

    cursorRequest.onerror = tDB.onerror;
  };

  /**
  * create new todo item
  */
  tDB.createTodo = function(text, callback){
    // get reference to db
    var db = datastore;

    //intiate new transaction
    var transaction = db.transaction(['todo'], 'readwrite');

    //get the datastore
    var objStore = transaction.objectStore('todo');

    //create a timestamp for todo item
    var timestamp = new Date().getTime();

    //create an object for the todo itemsv
    var todo = {
      'text': text,
      'timestamp': timestamp
    };

    //create the datastore cursorRequest
    var request = objStore.put(todo);

    //handle the success put
    request.onsuccess = function(e) {
      //execute callback
      callback(todo);
    };

    //handle handlerrors
    request.onerror = tDB.onerror;
  };//end tDB.createTodo function

  /**
  * delete a todo item
  */
  tDB.deleteTodo = function(id, callback){
    var db = datastore;
    var transaction = db.transaction(['todo'], 'readwrite');
    var objStore = transaction.objectStore('todo');

    var request = objStore.delete(id);

    request.onsuccess = function(e) {
      callback();
    }
    //writes errors to the console
    request.onerror = function(e){
      console.log(e);
    }
  };//end tDB.deleteTodo function
  //export the tDB object
  return tDB;
}());

And here is the one where I did quite a bit of customization, you can see the drag and drop “slip” references at the bottom.

window.onload = function(){
  //todo: app code goes here
  //display todo items by passing in the refreshTodos function as a parameter?
  todoDB.open(refreshTodos);

  //get references to html elements
  var newTodoForm = document.getElementById('new-todo-form');
  var newTodoInput = document.getElementById('new-todo');
  var submitBtn = document.querySelector('.submitBtn');
  //my form submitter addEventListener
  newTodoForm.addEventListener('submit', triggerForm);

  submitBtn.addEventListener('click', triggerForm);

  //handle the form sumissions
function triggerForm() {
    //get text
    var text = newTodoInput.value;

    //check tomake sure test is not blank or just spaces
    if(text.replace(/ /g,'') != ''){
      //create the todo item
      todoDB.createTodo(text, function(todo) {
        refreshTodos();
      });
    }

    //reset input field
    newTodoInput.value = '';

    //don't send the form
    return false;
  };//end triggerForm function

  //update the list of todo items.
  function refreshTodos(){
    todoDB.fetchTodos(function(todos){
      var todoList = document.getElementById('todo-items');
      todoList.innerHTML = '';

      for(var i = 0; i < todos.length; i++){
        //read the todo items backwards-most recent first
        var todo = todos[(todos.length - 1 - i)];

        var li = document.createElement('li');
        li.id = 'todo-' + todo.timestamp;
        //li.setAttribute('draggable', 'true');
        var checkbox = document.createElement('button');
        checkbox.textContent = 'X';
        checkbox.className = 'todo-checkbox';//""
        checkbox.setAttribute('data-id', todo.timestamp);//""



        var span = document.createElement('span');
        span.innerHTML = todo.text;

        li.appendChild(span);
        li.appendChild(checkbox);
        todoList.appendChild(li);

        //set up listener checkbox
        checkbox.addEventListener('click', function(e){
          var id = parseInt(e.target.getAttribute('data-id'));

          todoDB.deleteTodo(id, refreshTodos);
        });
      }//end for i < todos.length
//my non mobile dragger function used to be here.

    });//end todoDB.fetchTodos
    newTodoInput.focus();

  }//end function refreshTodos
//begin slippery functions
//slideThem = <ul id="todo-items">
var slideThem = document.querySelector('#todo-items');
new Slip(slideThem);//apply slip library to <ul>
slideThem.addEventListener('slip:reorder', function(e){
  e.target.parentNode.insertBefore(e.target, e.detail.insertBefore);
});
//end slipper function
};//end window.onload

The style sheet got fairly long  because…well…I’m sort of artsy and I wanted it to be pretty.

* {
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}

body, html {
  padding: 0;
  margin: 0;
}

body {

  color: #545454;
  background: #f7f7f7;
}
#page-wrapper {
    font: 2em Verdana, Helvetica, sans-serif;
  width: 100%;
  max-width: 750px;
  margin: 0.2em auto;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0,0,0,0.2);
  border-radius: 12px;
}
#page-wrapper footer {
border-top: 2px solid #0088cc;
padding: 0.5em;
background-color: rgb(207, 240, 245);
border-bottom-left-radius: 12px;
border-bottom-right-radius: 12px;
}
#page-wrapper footer h3 {
  font-size: 1.2em;
  color: #61bfee;
  margin:0;
  padding: 0;
  text-align: center;
}
#new-todo-form {
  padding: 0.5em;
  background: #0088cc;
  border-top-left-radius: 12px;
  border-top-right-radius: 12px;
}

#new-todo {
  width: 100%;
  padding: 0.5em;
  font-size: 1em;
  border-radius: 3px;
  border: 0;
}

#todo-items {
  list-style: none;
  padding: 0.3em 0.3em;
  margin: 0;
}

#todo-items li {
  margin: 0.5em 0 0 0;
  padding: 0;
  background-color: rgb(246, 232, 161);
  border: 1px solid rgb(153, 129, 67);
  display: flex;
  justify-content: space-between;
/* cursor: move; */
}
#todo-items li.dragElem {
  opacity: 0.6;
}
#todo-items li.over {
  border-top: 4px solid red;
}
#todo-items li span {
  margin: 0.7em 0.2em;

}
#page-wrapper button:hover {
  background-color: #0088cc;
  color: white;
}
.submitBtn {
      color: white;
      font-size: 1em;
      padding: 0.5em;
      margin: 0.5em 0 0 0;
      background-color: rgb(255, 162, 4);
}

.todo-checkbox {
  color: white;
  background-color: rgb(213, 119, 21);
  font-size: 1.2em;
  padding: 0.5em;
}

 

HTML5 To Do shopping list app

I’ve been using both Evernote and Wunderlist for years. I’ve built a ToDo list before in jQuery that came close to Wunderlist. It had draggable list items, and delete item checkboxes. But when studying JavaScript, jQuery is considered cheating.

So I was pleased to see this one show up in my latest online lesson. I prettied it up with some style sheets. I’m waiting until later in my studies to figure out how to connect it to a database, hopefully with something like Node.js. For now though, it just works in the browser session memory. It’s cool to make useful things that actually work. This one embedded in WordPress has some extra padding related to WordPress styles, but the direct link outside of WordPress works as intended.

Shopping list


You can also access it here as a direct link outside of WordPress.