labs.steveottenad.com

test

test

result1588

test

test

jService.io

Screenshot 2014-02-12 19.14.01

I just wanted to show everyone jService.io, a set of services I just made to help surface the over 108,000 jeopardy clues scraped into a DB. The technology stack is as follows:

  • Ruby on rails
    • Nokogiri
    • Chronic
    • Bootstrap 4
  • Coffeescript
  • Postgresql
  • Heroku

Check it out on github as well at http://github.com/sottenad/jservice

 

result277

1

Popcorn.js Custom Plugin

I took on a custom Popcorn.js plugin for a client of ours who needed to display certain metadata about a video at certain points throughout the video. Initially, this process was shaping up to be a bear, requiring hacky delays to show/hide the information. This method also wasnt synced to the video, so if the client was at full CPU load, the content would routinely get out of sync with the video.

Popcorn.js

Luckily, Mozilla put out the Popcorn.js framework a few weeks ago to deal almost exclusively with these types of problems. However, the included plugins, while super useful, weren’t doing what I needed. Below is a quick walkthrough of my thought process and code samples to create this demo

Existing plugin

Popcorn does supply a couple of design patterns for authoring plugins, but after a few attempts, these werent’ yeilding results as fast as I wanted. I chose to alter an existing plugin that Popcorn ships with, the “Subtitle” plugin [source, extracted from the complete popcorn source].

Code Walkthrough

  Popcorn.plugin( "subtitle" , {
      manifest: {

This section is defining the title of your plugin, in this case “subtitle”, and preparing the plugin to take stock of what arguments it will expect and what type each of those arguments are

manifest: {
        about: {
          name: "Popcorn Pop Plugin",
          version: "0.1",
          author: "Steve Ottenad",
          website: "http://labs.steveottenad.com/"
        },
        options: {
          start: {
            elem: "input",
            type: "text",
            label: "In"
          },
          end: {
            elem: "input",
            type: "text",
            label: "Out"
          },
          target: "subtitle-container",
          text: {
            elem: "input",
            type: "text",
            label: "Text"
          }
        }
      },

This “manifest” section defines each of the arguments that the plugin can accept, as well as what type of objects the arguments are. Note that these manifest arguments are only necessary if you want to use the plugin you are building with Butter, Mozillas WYSIWYG editor that utilizes Popcorn.js

 _setup: function( options ) {
      var c = document.getElementById(f.target);
      f._container = document.createElement("div");
      c.style.width ='0px';
      if (!c && n.plugin.debug) throw Error("target container doesn't exist");
      c && c.appendChild(f._container);
}

Guess what this does? Ya, it is fired at the moment you call your plugin, NOT the moment it is called using the “Start” attribute. Make sure you are scoping your plugin correctly, this was the toughest part for me. The problem is that the plugin can/will create multiple instances of itself, so proper closure is important. In my finished code, I am using the “f” variable to store all instantiation variables and elements (I’m creating a div), and then reference that later in the start/end functions through the “C” variable. You can see the assignment of the f._container to the ‘c’ variable at the end of this function

start: function (f, c) {
	var outer = document.getElementById(c.target);
	c._container.innerHTML = c.text+'<br /><br /><a href="#" class="play button">Play</a>';
	var ref = this;
	ref.pause();
	animateItem(outer, c.width);
	$('.play').live('click', function(){
		toggleState(ref,this,false)
	});
	$('.pause').live('click', function(){
		toggleState(ref,this,true)
	});
 
},

The start function is what fires when your video gets to the point (in seconds) you defined in the plugin call. Each instance you create will have this function assigned to it, so again, its important to scope all your variables and pass in the reference to the function itself, which contains all your _setup variables. Another option would be to do most of your heavy lifting here in the start function if it wont slow down the video and/or doesnt need to be instantaneous

We start be referencing the target we passed in when calling the plugin, then insert some html into the container we created in the _setup function. We can reference all the options we passed into the plugin by using “c.” then the option name. Next, I’m assigning “this” to a variable, since we will need the reference to the actual element we are working on later in the game with some click handlers. The “animateItem” is handling the animation of the element we’ve created and then we’re assigning play/pause click handlers to allow for toggling of the video

end: function (f, c) {
	var outer = document.getElementById(c.target);
	c._container.innerHTML = 'All Done.';
	c._container.style.display="none";
	animateItem(outer, '0px');
},

Any functions you need to fire on the ‘end’ option (in seconds), but before the video actually reaches its end should go here in the “end” function. Im just using it to print out a message, then immediately hide the box, to make room for another instance of the plugin.

Type Mismatch on wpadder.js

I encountered an odd error today working on a SharePoint 2010 Publishing site. After adding all my usual scripts, I was no longer able to use any Web Part adding functionality. Clicking “add a web part” in the web part zones did nothing. Trying to insert a webpart via the ribbon brought up the web part adder, but the majority of it was blank and just kinda busted.

I did however get this error

SCRIPT5: Type mismatch.
wpadder.js?rev=hnGJJEMcU5XH%2BCq7PlSxJw%3D%3D, line 2 character 13993

in the IE debugger under the Script tab error console.

Solution

Sharepoint (and possibly IE in general) has issues with any plugins/scripts that try to extend the Array Prototype. It appears that it breaks quite a few functions and generally is a good idea not to extend it if you dont have to.

So, to wrap it up. If you run into this problem, search through all your javascript for the string “Array.prototype”, or even “Array.” and you should come up with a hit (hopefully), comment that out or find a workaround for that piece of code and you’re good to go

Addition

We (mainly Adam Toth) found that less.js also causes an issue, due to the fact that it redefines all the prototype functions for Arrays. The same root problem, but it was a bit tricker to find. Make sure to do a full-text search on your entire project for the best results. I like Astrogrep to do this. It’s fast, thorough, and free.

More Offenders

Thanks to Bryan Gulley

Using jQuery to parse YouTube/Vimeo URL’s

Here is a handy script to help parse a url and determine if it contains a vimeo/youtube link, then if it does, return the iframe object to play it. It should be handy for any type of user-generated link field where you would rather display the video inline than link off to it.

The Function

Updated July 11 with better Vimeo regex

function getEmbeddedPlayer(url, height, width){
	var output = '';
	var youtubeUrl = url.match(/watch\?v=([a-zA-Z0-9\-_]+)/);
	var vimeoUrl = url.match(/^http:\/\/(www\.)?vimeo\.com\/(clip\:)?(\d+).*$/);
	if( youtubeUrl ){
		output = '<iframe src="http://www.youtube.com/embed/'+youtubeUrl[1]+'?rel=0" height="240" width="320" allowfullscreen="" frameborder="0"></iframe>

How to call it

Note: this uses jquery to grab the value of a text field, but the getEmbeddedPlayer() function does not rely on jquery to work

var width = 640;
var height = 360;
var url = $('#url').val();
var output = getEmbeddedPlayer(url,height,width);
$('#results').html(output);

Try It


Find Video

Adding Javascript to SharePoint 2010 Master Page

Including Javascript In SharePoint 2010

Adding scripts in a Sharepoint 2010 Master Page can be accomplished in a couple of different ways. I’d like to focus on what I consider to be both the easiest (once learned) and the most beneficial method, the tag. Keep in mind I am writing this article from the place of a (primarily) front-end developer. This is not geared at back end developers looking to use all of the functionality of the ScriptManager Tag.

Read the rest of this entry »

HTML Compressor

After hours (ok, minutes) of looking for a decent HTML compressor, I decided to write my own. This strips out ALL whitespace. Its perfect for compressing a document for production, or packing down all those super long .NET controls that often eat up 80-100 lines of code. Read the rest of this entry »

Reskin/Restyle the Sharepoint 2010 Advanced Search Box

Sharepoint Advanced Search Control After CSS Styling

This post is in continuation to my previous post “Reskin/Restyle the Standard Sharepoint 2010 Search Box“, and covers how to create, and style with CSS, an out of the box (OOB) Sharepoint 2010 Advanced Seach box.

Read the rest of this entry »