Location (of browser)

var
Locations              = {}
Locations.SearchValues = GetSearchValues
Locations.SearchValue  = GetSearchValue
Locations.Up           = Up
Locations.TwoUp        = TwoUp
Locations.CreateDownFn = CreateDownFn
Locations.Down         = Down
Locations.Reload       = Reload

Search values

Locations.SearchValues( parameter_names )

function GetSearchValues()
{
    return GetSearchValues.CreateDictionary( window.location.search );
}

GetSearchValues.CreateDictionary
=
function( url_search_parameters )
{
    var object = new Object;

    if ( 0 < url_search_parameters.length )
    {
        var bits = ('?' == url_search_parameters[0])
                 ? url_search_parameters.substring( 1 ).split( "&" )
                 : url_search_parameters.substring( 0 ).split( "&" );

        var n    = bits.length;
        
        for ( var i=0; i < n; i++ )
        {
            var keyvalue = bits[i].split( "=" );

            if ( 2 == keyvalue.length )
            {
                var key = "";
                var val = "";

                try
                {
                    key = decodeURIComponent( keyvalue[0] );
                    val = decodeURIComponent( keyvalue[1] );
                }
                catch ( err )
                {}

                if ( (null != key) && (null != val) ) object[key] = val;
            }
        }
    }
    return object;
}

Search value

Locations.SearchValue( parameter_name )

function GetSearchValue( name )
{
	var parameters = GetSearchValues();
	
	return parameters[name] ? parameters[name] : "";
}

Up

Locations.Up( parameter_names )

The Up function navigates the browser to the parent page. The argument 'parameter_names' is an array of strings that name search parameters that should be kept. Up is usually called when a form on a page has sucessfully completed, and the expected action is to return to a parent page.

function Up( search_parameters )
{
	var loc  = location.protocol + "//" + location.host;
	var bits = location.pathname.split( "/" );
	var path = "";

	switch ( bits.length )
	{
	case 0: // ""
	case 1: // Can't happen
		path = "/";
		break;
	
	case 2: // "/"
		path = "/";
		break;
	
	default:
		bits = ("" == bits[bits.length - 1]) ? bits.slice( 0, -2 ) : bits.slice( 0, -1 );
		path = bits.join( "/" ) + "/";
	}

	loc += path;

    if ( null == search_parameters )
    {
        loc += location.search;
    }
    else
    {
        loc += "?";

        for ( const key in search_parameters )
        {
            loc += search_parameters[key] + "=" + Recode( GetSearchValue( search_parameters[key] ) ) + "&";
        }
        loc = loc.substring( 0, loc.length - 1 );
    }

	location.assign( loc );
}

TwoUp

Locations.TwoUp( parameter_names )

The TwoUp function navigates the browser to the parent of the parent page. The argument 'parameter_names' is an array of strings that name search parameters that should be kept. Up is usually called when a form on a page has sucessfully completed, and the expected action is to return to a parent page.

function TwoUp( search_parameters )
{
    var loc  = location.protocol + "//" + location.host;
    var bits = location.pathname.split( "/" );
    var path = "";

    switch ( bits.length )
    {
    case 0: // ""
    case 1: // Can't happen
        path = "/";
        break;
    
    case 2: // "/"
        path = "/";
        break;
    
    default:
        bits = ("" == bits[bits.length - 1]) ? bits.slice( 0, -3 ) : bits.slice( 0, -2 );
        path = bits.join( "/" ) + "/";
    }

    loc += path;

    if ( null == search_parameters )
    {
        loc += location.search;
    }
    else
    {
        loc += "?";

        for ( const key in search_parameters )
        {
            loc += search_parameters[key] + "=" + Recode( GetSearchValue( search_parameters[key] ) ) + "&";
        }
        loc = loc.substring( 0, loc.length - 1 );
    }

    location.assign( loc );
}

Create Down Function

Locations.CreateDownFn( pathname, search )

Returns a function suitable for assigning as an 'onclick' handler, that will keep a copy of pathname and search (as it is in the scope of a function). The function calls Down.

function CreateDownFn( pathname, search )
{
    return function()
    {
        Down( pathname, search );
    }
}

Down

Locations.Down( pathname, search )

function Down( pathname, search )
{
    var loc  = location.protocol + "//" + location.host + location.pathname + pathname + search;

    if ( -1 !== loc.indexOf( '=%' ) )
    {
        var parameters = Locations.SearchValues();
    
        loc = Replace( loc, parameters );
    }

    location.assign( loc );
}

Reload

Locations.Reload( ignored )

function Reload( ignored )
{
    location.reload();
}