4
\$\begingroup\$

Trying to implement this API in a way that works pre and post jQuery UI 1.9:

I have a subtle feeling that there should be a more elegant way.

/** Prefix number with '+'/'-' or return empty string for 0. */
function offsetString(n){
    return n === 0 ? "" :(( n > 0 ) ? ("+" + n) : ("" + n)); 
}

var posOpts = {
    at: "left top",
    of: $target
};

if( isVersionAtLeast($.ui.version, 1, 9) ){
    posOpts.my = "left" + offsetString(markerOffsetX) +
       " top" + offsetString(markerOffsetY);
} else {
    posOpts.my = "left top";
    posOpts.offset = "" + markerOffsetX + " " + markerOffsetY;
}
$dropMarker.position(posOpts);
\$\endgroup\$
1
  • \$\begingroup\$ I recommend that you put the relevant information from that link into this post in case the link ever goes dead. \$\endgroup\$ Commented Aug 26, 2014 at 15:12

2 Answers 2

2
\$\begingroup\$

Interesting question,

have you tried passing +0 as an offset, that should work and make your code a little easier to read.

/** Prefix number with '+'/'-' or return empty string for 0. */
function offsetString(n){
    return '' + ( n < 0 ? n : '+' + n );
}

As for the isVersionAtLeast($.ui.version, 1, 9) I would only check this once.

function generateCompatibleOffsetFunction(){

  if( isVersionAtLeast($.ui.version, 1, 9) ){
    return function setOffset( options , offsetX , offsetY ){
      options.my = "left" + offsetString(offsetX ) + " top" + offsetString(offsetY );
    }
  } else {
    return function setOffset( options , offsetX , offsetY ){
      options.my = "left top";
      options.offset = "" + offsetX + " " + offsetY;
    }
  }
}

var setOffset = generateCompatibleOffsetFunction();

/** Prefix number with '+'/'-' or return empty string for 0. */
function offsetString(n){
    return '' + ( n < 0 ? n : '+' + n );
}

var posOpts = {
    at: "left top",
    of: $target
};

setOffset( posOpts, markerOffsetX, markerOffsetY );

$dropMarker.position(posOpts);
\$\endgroup\$
0
\$\begingroup\$

I came up with this approach (barely tested): the idea is to use the new syntax, but convert to the old syntax when a legacy jQuery UI is included (i.e. version <= 1.8).

This could be used like so:

$("#source").position(fixPositionOptions({
    my: "left+30 center",
    at: "center bottom+30",
    of: $("#target")
}));

(See also this fiddle: http://jsfiddle.net/mar10/6xtu9a4e/)

var uiVersion = $.ui.version.match(/^(\d)\.(\d+)/);

/** Make jQuery.position() arguments backwards compatible,i.e. if 
 * jQuery UI version <= 1.8, convert 
 *   { my: "left+3 center", at: "left bottom", of: $target }
 * to
 *   { my: "left center", at: "left bottom", of: $target, offset: "3  0" }
 *
 * See http://jqueryui.com/upgrade-guide/1.9/#deprecated-offset-option-merged-into-my-and-at
 * and http://jsfiddle.net/mar10/6xtu9a4e/
 */
function fixPositionOptions(opts) {
    if( opts.offset || ("" + opts.my + opts.at ).indexOf("%") >= 0 ) {
        $.error("expected new position syntax (but '%' is not supported)");
    }
    if( uiVersion[1] < 2 && uiVersion[2] <= 8 ) {
        var // parse 'left+3 center' into ['left+3 center', 'left', '+3', 'center', undefined]
            myParts = /(\w+)([+-]?\d+)?\s+(\w+)([+-]?\d+)?/.exec(opts.my),
            atParts = /(\w+)([+-]?\d+)?\s+(\w+)([+-]?\d+)?/.exec(opts.at),
            // convert to numbers
            dx = (myParts[2] ? (+myParts[2]) : 0) + (atParts[2] ? (+atParts[2]) : 0),
            dy = (myParts[4] ? (+myParts[4]) : 0) + (atParts[4] ? (+atParts[4]) : 0);

        opts = $.extend({}, opts, { // make a copy and overwrite
            my: myParts[1] + " " + myParts[3],
            at: atParts[1] + " " + atParts[3]
        });
        if( dx || dy ) {
            opts.offset = "" + dx + " " + dy;
        }
    }
    return opts;
}
\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.