Calories? Steps? Heart rate? Sleep?
Find the right device for you with the Activity Tracker Showcase

How to get the database connection from a StatelessSession in Hibernate 4

by timvasil 1/22/2015 12:02:00 PM

In Hibernate 4, StatelessSession#connection is a deprecated method, but there's no suggested alternative.  StatelessSession does not have a "doWork" method like Session.  

The best way I've found to deal with the deprecation warnings is to get a connection from the connection provider directly, create StatelessSession with that connection explicitly, and then carry around references to both the session and connection.

Old (deprecated) approach:

StatelessSession session = sessionFactory.openStatelessSession(); // Example of using the underlying connection session.connection().setAutoCommit(true); // Now do work with session

New approach:

Connection connection = sessionFactory.getSessionFactoryOptions(). getServiceRegistry().getService(ConnectionProvider.class).getConnection(); StatelessSession session = sessionFactory.openStatelessSession(connection); // Example of using the underlying connection connection.setAutoCommit(true); // Now do work with session

 

Tags:

Hibernate | Java

Top 10 phone screen interview questions to assess jQuery competency

by timvasil 1/2/2015 9:32:00 PM

Here are my "top 10" jQuery questions that can be answered in 1-2 sentences over the phone--no whiteboard required.  These are not "gotcha" or "puzzler" questions.  They cover the basics, and any competent jQuery developer should know the answers.

1. What's the purpose of jQuery?

jQuery is a JavaScript library providing convenient abstractions and utilities to make DOM manipulation and event management consistent across browser vendors and versions.

2. How do CSS selectors related to jQuery?

CSS selectors are a common way of referencing DOM elements, i.e. via the $(selector) syntax.  A very common way of constructing a jQuery object is via a selector.

3. How would you define your own custom jQuery method (to extend jQuery)?

You'd write a statement like "jQuery.fn.pluginName = function() { ... }".  You could also use $.fn.extend(...);

4. How can you tell how many elements a jQuery selector has matched?

Use the "length" property of the jQuery object.

5. What's a Promise, and what's an example usage in the jQuery API?

A Promise is an interface (contract) providing for callbacks depending on success or failure of some asynchronous operation.  One such usage is $.ajax.

6. How is $.each() used, and what does the "this" keyword reference when the callback is executed?

The $.each() jQuery method iterates over all DOM elements of the invoked jQuery object by calling the provided callback once per element, in order.  The "this" keyword references each element in turn.

7. How can you bind to events on DOM elements that are not yet created?  (example: a "delete" button on rows that may be added to a table dynamically)

You can use the longer form of the $.on() method, binding to an ancestor that does exist, and specify a selector argument that matches the elements that will be created later.  (This is a performant replacement over the former $.live() method.)

8. What's the major difference between jQuery 1 and jQuery 2?

jQuery 2 does not support legacy browsers (IE6-8), making it lighter-weight.  The jQuery team is otherwise attempting to main API parity between versions 1 and 2.  More info here.

9. What's the difference between $.attr(), $.data(), and $.prop() methods?

The $.attr() method gets/sets HTML attributes directly on the DOM node, so the keys and values are strings. The $.data() method sets arbitrary data in a jQuery-managed dictionary associated with the DOM element(s), so the keys are strings but the values can be any type. The $.prop() attribute gets/sets properties of the DOM node, like whether it's currently checked.  

10. How would you use jQuery to determine whether a checkbox is checked?

Use $('checkbox-selector').prop('checked') or $('checkbox-selector').is(':checked')

Tags:

Interviewing | jQuery

Top 10 phone screen interview questions to assess JavaScript competency

by timvasil 12/31/2014 5:12:00 PM

Here are my "top 10" JavaScript (ECMAScript) questions that can be answered in 1-2 sentences over the phone--no whiteboard required.  These are not "gotcha" or "puzzler" questions.  They cover the basics, and any competent JavaScript developer should know the answers.

1. What data types does JavaScript support?

Based on unique return values of the typeof operator, there are 7:  undefined, object (which includes arrays), boolean, number, string, function, and object.  (ECMAScript 6 supports an additional type, symbol.)

2. What's the difference between "==" and "==="?

The double-equals operator (==) tests for equity after coercing the operands to matching types, whereas the triple-equals operator (===) tests for both type and equailty without doing any type conversion.  Therefore an expression like 1=='1' evaluates to true, whereas 1==='1' evaluates to false.

3. What's "undefined"?

Undefined is a special value used with unitialized variables, missing function arguments, and functions that do not return a value explicitly.  It's distinct from null, which is assigned explicitly. (It's also a global property set to this value.)

4. What does the "use strict" statement do?

The "use strict" statement, introduced in ECMAScript 5, changes the semantics of JavaScript to eliminate silent errors, improve performance, and prohibit certain reserved syntax.

5. What does the "this" keyword refer to?

It's tricky, but the "this" keyword basically provides object context:  global context (window object) outside of a function, object reference inside a function, or DOM reference in an event handler.  You can use call and apply to set a function's context explicitly.  More details here.

6. What's the difference between "call" and "apply"?

While both are methods of the Function prototype used to call a function, taking a context as the first argument, call also takes a comma-separated list of arguments to pass to the target function, whereas apply takes a single array of packed arguments to pass to the target function.

7. What are the possible scopes for declaring variables?

A variable can be scoped globally or at a function level.  While a variable can be declared with a block ({ ... }) it's still scoped to the outer function.

8. What's a closure, and how can you create one?

A closure is a function that references variables from outside its definition, and an easy way to create one is to define an anonymous function within a function, and refers to variables from the outer function's declared variables or arguments.

9. What's "prototype" used for?

Each object has a "prototype" property, defining an object hierarchy through its "prototype chain" for inheritance.  When referencing a property of an object, if the property does not exist, the JavaScript interpreter looks up the prototype hierarchy for a match. 

10. How would you execute a JavaScript statement asynchronously?

While JavaScript execution is single-threaded, you can defer a particular statement using setTimeout with a timeout argument of 0 ms.  (In newer web browsers, if the statement isn't accessing the DOM you could also use web workers.)

Tags:

Interviewing | JavaScript

Build a unique selector for any DOM element using jQuery

by timvasil 2/24/2014 7:19:00 PM

If you need a selector that uniquely identifies a DOM element and is robust to some changes to the page structure over time, your best bet is to keep the selector as concise as possible.  I've seen jQuery plugins that attempt to build a selector by navigating the entire DOM hierarchy, and adding some unique bits for each ancestor encountered along the way.  This can be overkill -- especially if any element has an ID along the way.  Since ID is unique, there's no need to keep going.

Here's a custom jQuery function called "getSelector" to provide a concise selector for any element on the page.

$.fn.getSelector = function() {
  var el = this[0];
  if (!el.tagName) {
    return '';
  }

  // If we have an ID, we're done; that uniquely identifies this element
  var el$ = $(el);
  var id = el$.attr('id');
  if (id) {
    return '#' + id;
  }

  var classNames = el$.attr('class');
  var classSelector;
  if (classNames) {
    classSelector = '.' + $.trim(classNames).replace(/\s/gi, '.');
  }

  var selector;
  var parent$ = el$.parent();
  var siblings$ = parent$.children();
  var needParent = false;
  if (classSelector && siblings$.filter(classSelector).length == 1) {
     // Classes are unique among siblings; use that
     selector = classSelector;
  } else if (siblings$.filter(el.tagName).length == 1) {
     // Tag name is unique among siblings; use that
     selector = el.tagName;
  } else {
     // Default to saying "nth child"
     selector = ':nth(' + $(this).index() + ')';
     needParent = true;
  }

  // Bypass ancestors that don't matter
  if (!needParent) {
    for (ancestor$ = parent$.parent();
         ancestor$.length == 1 && ancestor$.find(selector).length == 1;
         parent$ = ancestor$, ancestor$ = ancestor$.parent());
    if (ancestor$.length == 0) {
       return selector;
    }
  }

  return parent$.getSelector() + ' > ' + selector;
}

To test this on your page, you can try out this code -- it'll write the selector to the console wherever you click.

$("*").click(function() {
        var selector = $(this).getSelector();
        console.log(selector + ' --> matches ' + $(selector).length + ' element');
        return false;
      });

Here's some example output (notice that many DOM elements, including HTML and BODY, are excluded because they are not necessary):

#recentPosts > :nth(0) > A --> matches 1 element

Tags:

JavaScript | jQuery

How to convert an SVG image into a static image with only JavaScript

by timvasil 2/6/2014 1:15:00 AM

Recently I was trying to convert a Highcharts SVG-based chart into a static image that I could copy and paste into a document.  Highcharts provides a mechanism to do this on with a server-side roundtrip, but for modern browsers (and, no, not any flavor of IE), it's possible to do this completely on the client side -- and even inline replace the SVG element with a pixel-perfect matching <img> element.

Here's the code (written as a jQuery extension):

    /**
     * Converts an SVG element to an IMG element with the same dimensions
     * and same visual content. The IMG src will have a temporary blob URL.
     * Works in Webkit and Firefox and IE10+.
     */
    $.fn.toImage = function() {
        $(this).each(function() {
            var svg$ = $(this);
            var width = svg$.width();
            var height = svg$.height();

            // Create a blob from the SVG data
            var svgData = new XMLSerializer().serializeToString(this);
            var blob = new Blob([svgData], { type: "image/svg+xml;charset=utf-8" });

            // Get the blob's URL
            var blobUrl = (self.URL || self.webkitURL || self).createObjectURL(blob);

            // Load the blob into an image
            $('<img />')
                .width(width)
                .height(height)
                .on('load', function() {
                    // Overwrite the SVG tag with the img tag
                    svg$.replaceWith(this);
                })
                .attr('src', blobUrl);
        });
    };

If you'd like the destination tag to have Base64-encoded data rather than a temporary blob URL and/or want to manipulate the image (e.g. set the background color), add an intermediate step of rendering the image on a canvas first. Unfortunately this step doesn't work in IE, whose security model marks the canvas as "write only" once SVG data is written to it, regardless of where it came from.

    /**
     * Converts an SVG element to an IMG element with the same dimensions
     * and same visual content. The IMG src will be a base64-encoded image.
     * Works in Webkit and Firefox (not IE).  
     */
    $.fn.toImage = function() {
        $(this).each(function() {
            var svg$ = $(this);
            var width = svg$.width();
            var height = svg$.height();

            // Create a blob from the SVG data
            var svgData = new XMLSerializer().serializeToString(this);
            var blob = new Blob([svgData], { type: "image/svg+xml;charset=utf-8" });

            // Get the blob's URL
            var domUrl = self.URL || self.webkitURL || self;
            var blobUrl = domUrl.createObjectURL(blob);

            // Load the blob into a temporary image
            $('<img />')
                .width(width)
                .height(height)
                .on('load', function() {
                    try {
                        var canvas = document.createElement('canvas');
                        canvas.width = width;
                        canvas.height = height;
                        var ctx = canvas.getContext('2d');

                        // Start with white background (optional; transparent otherwise)
                        ctx.fillStyle = '#fff';
                        ctx.fillRect(0, 0, width, height);

                        // Draw SVG image on canvas
                        ctx.drawImage(this, 0, 0);

                        // Replace SVG tag with the canvas' image
                        svg$.replaceWith($('<img />').attr({
                            src: canvas.toDataURL(),
                            width: width,
                            height: height
                        }));
                    } finally {
                        domUrl.revokeObjectURL(blobUrl);
                    }
                })
                .attr('src', blobUrl); 
        });
    };

Usage is straightforward. For example, to convert all the SVG images on a page to static images, do this:

$('svg').toImage();

Tags:

Highcharts | JavaScript | jQuery | SVG

Workaround for WebKit bug rendering with "text-transform: uppercase"

by timvasil 1/30/2014 12:11:00 AM

There's a longstanding WebKit bug whereby DOM elements styled with "text-transform: uppercase" don't have their metrics (height, width) updated when manipulated dynamically, e.g., $('selector').html('new content');

The problem is documented here:  https://bugs.webkit.org/show_bug.cgi?id=99606

The simple fix I've found is to do this:  $('selector').hide().show();

Tags:

JavaScript | jQuery | WebKit

Fixing bad behaviors with IIS's reverse proxy: it's all about the pipeline mode

by timvasil 11/20/2013 11:53:00 AM

I noticed an "gotcha" when using the IIS reverse proxy feature (ARR -- attribute request routing):  it won't work well if the app pool doing the URL rewriting is using Integrated pipeline mode.  

Bad behaviors I saw in integrated mode included:

  1. "502.3 - Bad Gateway The operation timed out" errors after the proxy timeout period expired (2 minutes by default).  This typically happened with a subset of POST requests and 302 (redirect) responses. 
  2. "Unexpected end of MIME multipart stream. MIME multipart message is not complete".  This happened for POST requests with multipart/form-data content (i.e. file uploads).
  3. Increased latency.

The fix is to change the app pool's pipleine mode to Classic.

Tags:

ASP.NET | IIS | ARR

jQuery extension method to parse a query string

by timvasil 3/21/2013 9:49:00 PM

This code automatically trims a leading "?" (if present) and accomodates multiple params with the same key by stuffing them into an array.  (You can also find it on Gist.)

(function($) {
    var re = /([^&=]+)=?([^&]*)/g;
    var decode = function(str) {
        return decodeURIComponent(str.replace(/\+/g, ' '));
    };
    $.parseParams = function(query) {
        var params = {}, e;
        if (query) {
            if (query.substr(0, 1) == '?') {
                query = query.substr(1);
            }

            while (e = re.exec(query)) {
                var k = decode(e[1]);
                var v = decode(e[2]);
                if (params[k] !== undefined) {
                    if (!$.isArray(params[k])) {
                        params[k] = [params[k]];
                    }
                    params[k].push(v);
                } else {
                    params[k] = v;
                }
            }
        }
        return params;
    };

Example usage:


  $.parseParams(document.location.search)
 

Tags:

JavaScript | jQuery

Pagination JavaScript

by timvasil 3/20/2013 8:25:00 PM

Before I settled on an "infinite scrolling" solution to a pagination problem, I was using Twitter Bootstrap's "pagination" CSS class and a bunch of page links, including the usual next/previous.  I wrote the script to meet these requirements:

  1. First and previous page links must always be available
  2. Next and last page links must always be available
  3. The current page must be highlighted and non-clickable
  4. Up to X additional links must be visible for interstitial pages before and after the current page.  
  5. Each link must consume the same amount of horizontal space so next/previous/first/last links don't change position.  This prevents accidental clicks if the user were to click multiple times and the elements jumped around.

Here are some examples of how this looks for various pages:

This is the code:

var html = [];
var maxBlocks = 11;  // specify the max <li> elements you want rendered
var currentPage = 1; // specify current page here
var numPages = Math.ceil(totalItems / pageSize);

if (numPages > 0) {
    addPageLink = function(page, label, tooltip) {
        var cls = (page == currentPage || page === null) ? 'disabled' : '';
        if (label == currentPage) {
            cls += ' active';
        }
        html.push('<li title="', tooltip, '" data-page="', page, '" class="', cls, 
             '"><a href="#">', label, '</a></li>');
    }
    
    html.push('<ul>');
    addPageLink(Math.max(1, currentPage - 1), '&laquo;', 'Previous page');
    addPageLink(1, 1, 'First page');

    var maxPivotPages = Math.round((maxBlocks - 5) / 2);
    var minPage = Math.max(2, currentPage - maxPivotPages);
    var maxPage = Math.min(numPages - 1, 
                           currentPage + maxPivotPages * 2 - (currentPage - minPage));
    minPage = Math.max(2, minPage - (maxPivotPages * 2 - (maxPage - minPage)));

    for (var i = minPage; i <= maxPage; i++) {
        var isMore = (i == minPage && i != 2) || (i == maxPage && i != numPages - 1);
        if (isMore) {
            addPageLink(null, '&hellip;');
        } else {
            addPageLink(i, i, 'Page ' + i);
        }
    }
            
    addPageLink(numPages, numPages, 'Last page');
    addPageLink(Math.min(numPages, currentPage + 1), '&raquo;', 'Next page');
    html.push('</ul>');
}

$('.pagination').html(html.join(''));

And here are the Bootstrap CSS tweaks to get fixed width and the highlighted state (in Less syntax):

.pagination {
    li a {
        min-width: 20px;
    }
    
    li.active {
        a, a:hover, a:active {
            background-color: #005580;
            color: #fff;
        }
    }
}

Tags:

CSS | JavaScript | jQuery | Twitter Bootstrap

Options for a multi-app large-screen kiosk

by timvasil 3/19/2013 6:05:00 PM

I've been looking for a way to build a large-screen kiosk capable of running multiple apps and websites, but still run in a 'locked down" mode so kiosk users can't escape the sandbox and do something malicious.  The iPad now has a kiosk mode, but it limits you to a single app.  Android has kiosk apps, like SureLock, that do support multiple apps and websites, however there's no Android device quite large enough for what I'm trying to do (the 24" ViewSonic is the largest I've seen).  That leaves a custom solution:  probably built on top of Windows so Windows apps + Android apps (in an emulator like BlueStacks).

Here's a summary of the options I've evaluated to date to get a ~40" multi-app exhibit/kiosk experience:

 

Option 1 

Option 2 

Option 3

Concept

10 iPads + Mac Mini

Android all-in-one device

Large touchscreen + PC

Screen size

9.7" x 10 devices

24" x 2 devices

40" x 1 screen

Relative size

Max dimensions
(w × h)

40" × 26"

21" × 28"

40" × 26"

Multi-touch capabilities

11 touch points
(per device)

2 touch points

2 to 32 touch points
(varies by model)

Apps supported

Web sites + iPad apps
(max 1 app per device)

Web sites + Android apps

  

Web sites + some Android apps + some Windows apps

Restricted web site browsing

Yes

Yes

Yes

Lock portions of applications

No

Yes

Yes

Trailer-capable

Limited
(backgrounds only)

Limited
(backgrounds and logo)

Yes

Usage data collection

No

No

Yes

Remote admin

Limited (iTunes)

Yes

Yes

Risks

1.    Lead time for vendor to frame iPads

 

1.    Hardware not shipping until April (22" version available now)

1.    Multi-touch not currently available for Android apps

2.    Requires unproven custom software

Hardware

Touchscreens

$5,300
($3,500 with 10 iPad Minis)

$600

$2,500

PC

$650

$0

$650

Software & labor 

Kiosk software

$100

$60

75 hours
(custom development)

Configuration & testing

20 hours

20 hours

20 hours

Remote management

50 hours

20 hours

0 hours

Metric collection & reporting

40 hours
(requires “jailbreaking” iPads)

20 hours

7 hours

 

Can you think of better configurations?  Please let me know!

Tags:

Hardware | Windows | Android | iOS

Search

Calendar

«  February 2015  »
SuMoTuWeThFrSa
25262728293031
1234567
891011121314
15161718192021
22232425262728
1234567

View posts in large calendar

Recent comments

Archive