-1

I am firing up FancyBox2 with incoming HashTags. It all works... until you add a source code to the URL. How can I get this to work? Below is the code. I am assuming I need to say hash=everything up until a ? if a ? exist.

Jquery:

var thisHash = window.location.hash;
if(window.location.hash) {
$(thisHash).fancybox().trigger('click');
}

Links that need to work:

www.mysite.com/test/#test - this works

www.mysite.com/test/#test?source=blahblahblah - this does not

www.mysite.com/test/?source=blahblahblah#test - this works lol

RooksStrife
  • 1,647
  • 3
  • 22
  • 54

2 Answers2

2

Quick answer: The hash tags / named anchors / fragment identifiers (how ever you call them) must come after the query string to be parsed properly (at least as you expect them to be). So you need to build your URLs accordingly.

The following question on superuser.com has a full answer for your question (albeit your question is a bit different, the answer is the same) :

Does an anchor tag come before the query string or after?

Although http://www.example.com/test/#test?source=blahblahblah is a valid URL, what will be considered as the hash tag string is the whole test?source=blahblahblah part (with no query string being detected). Also, if you need to include the # char in the path, document or query string parts of the URL it must be endoded as %23.

So no, your second link will never work as you intend it to be, even if you need it to work like that.

EDIT - Bonus

If you're looking for an easy way to add a query string to an existing url in PHP, try url_add_query_params() from the following code:

 function build_query($query_data, $numeric_prefix = '', $arg_separator = '&', $inner_call = 0) {
    // Source: http://php.net/manual/en/function.http-build-query.php#112024
    if (!is_array($query_data)) return false;
    $result = array();
    foreach ((array)$query_data as $key => $value) {
        if ($inner_call) {
            if (is_numeric($key))
                $key = $numeric_prefix . "[]";
            else
                $key = $numeric_prefix . "[$key]";
        } else {
           if (is_int($key))
                $key = $numeric_prefix . $key;
        }

        if (is_array($value) || is_object($value)) {
            $result[] = build_query($value, $key, $arg_separator, 1);
                continue;
        }
        $result[] = urlencode($key) . "=" . urlencode($value);
    }
    return implode($arg_separator, $result);
}

function unparse_url($parsed_url) {
      // Source: http://php.net/manual/en/function.parse-url.php#106731
      $scheme   = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
      $host     = isset($parsed_url['host']) ? $parsed_url['host'] : '';
      $port     = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
      $user     = isset($parsed_url['user']) ? $parsed_url['user'] : '';
      $pass     = isset($parsed_url['pass']) ? ':' . $parsed_url['pass']  : '';
      $pass     = ($user || $pass) ? "$pass@" : '';
      $path     = isset($parsed_url['path']) ? $parsed_url['path'] : '';
      $query    = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
      $fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
      return "$scheme$user$pass$host$port$path$query$fragment";
}

function url_add_query_params($url, $new_params) {
    // parse url
    $url_components = parse_url($url);
    // return immediately if parsing failed
    if ($url_components === FALSE) { return $url; }
    // if $new_params is a query string, parse it
    if (!is_array($new_params)) {
        $new_params_str = $new_params;
        $new_params = array();
        parse_str($new_params_str, $new_params);
    }
    // parse query string from original url
    $params_str = isset($url_components['query']) ? $url_components['query'] : '';
    $params = array();
    parse_str($params_str, $params);
    // merge the two arrays, keeping later values for identical keys
    $params = array_merge($params, $new_params);
    // rebuild query string
    $url_components['query'] = build_query($params);
    // rebuild url
    return unparse_url($url_components);
}

Example:

$url = 'http://www.example.com/test/#test';
$new_url = url_add_query_params($url, 'source=blahblahblah');
echo $new_url; // output: http://www.example.com/test/?source=blahblahblah#test
echo "\n";

$url = 'http://www.example.com/test/?source=index&param=value#test';
$new_url = url_add_query_params($url, 'source=blahblahblah');
echo $new_url; // output: http://www.example.com/test/?source=blahblahblah&param=value#test

I only lightly tested it, but it should work as intended.

Community
  • 1
  • 1
johnwait
  • 1,135
  • 7
  • 17
  • Thanks for the post - I get what your saying and it being proper (which I will now follow), but I would imagine that you could write code to look for a #Hash and stop once you reach a ?mark. Then take that string and fire off the according FacnyBox. I would imagine you need to use RegEx with jQuery. Therefore treating the Hash a bit differently then just as a Hash. – RooksStrife Aug 15 '14 at 15:09
  • The problem with that is, even if you patch/fix jQuery, browsers and HTTP servers will style behave the same, i.e. any query parameters after the "#" will be stripped from requests (and be part of the fragment identifier instead). And I'm sure you don't want to write your own browser or server. – johnwait Aug 15 '14 at 17:32
2

The reason why this www.mysite.com/test/#test?source=blahblahblah link doesn't work is because the variable :

var thisHash = window.location.hash

... will return #test?source=blahblahblah.

Then you are trying to bind thisHash (#test?source=blahblahblah) to fancybox

$(thisHash).fancybox().trigger('click');

... which is an invalid selector.

You may need to write a function that validates window.location.hash and extracts the proper selector to be bound to fancybox like :

var _param;
function getSelector(thisHash) {
    if (thisHash.indexOf("?")) {
        _param = thisHash.split("?");
        return _param[0];
    } else {
        return thisHash;
    };
};

Check these jsfiddle links :

Then you could bind fancybox to the proper selector and add the trailing parameter "?source=" on the fly like :

var thisHash = window.location.hash;
jQuery(document).ready(function ($) {
    if (window.location.hash) {
        var selector = getSelector(thisHash);
        $(selector).fancybox({
            beforeLoad: function () {
                this.href = this.href + (typeof _param == "undefined" ? "" : "?" + _param[1])
            }
        }).trigger('click');
    }
}); // ready
JFK
  • 40,963
  • 31
  • 133
  • 306
  • what if the URL is www.mysite.com/?sourecode#HashTag. Won't the above code cause this not to work then? – RooksStrife Aug 15 '14 at 18:24
  • I answered for the none-working link, but I bet you pretty much got the idea what's going on and how to solve it, didn't you? (unless you want me to write the full recipe) – JFK Aug 15 '14 at 18:26