8

I have a select dropdown with id's mapped to values. On the onChange event I want to redirect to the same url but with 'id=value' appended to the querystring.

How do I check that this 'id' option isn't already in the querystring (I don't want multiple values) and replace / append as necessary.

How do I check if '?' is already in the querystring and append to the url if its not.

Is there an easy way with jquery to do this?

It must do something similar under the hood for $().ajax(url, {options}) calls. I was hoping I could just do $().redirect( url, { id : $(this).val() }) or somesuch.

Thanks in advance.

Note: This page may or may not have a few different query options passed in (which set defaults on other form options) so replacing the whole querystring is not an option.

<html>
<head><script type="text/javascript" src="/jquery-1.3.2.min.js"></script></head>
<body>
  <script>
    $(function(){                                                                                                                                         
        $('#selector').change(function(){                                                                                                                 
            // problem if 'id' option already exists
            var url = location.href + '?;id=' + $(this).val();                                                                                            
            location.assign( url );
        });                                                                                                                                               
    });                                                                                                                                                   
  </script>

  <a href="#" onclick="location.assign( location.pathname )">reset</a>                                                                                      
  <form>                                                                                                                                                    
    <select id='selector' name='id'>                                                                                                                      
        <option value='1'>one</option>                                                                                                                    
        <option value='2'>two</option>                                                                                                                    
        <option value='3'>three</option>                                                                                                                  
    </select>                                                                                                                                             
  </form>
</body>
</html>
1

6 Answers 6

10

I ended up going with a RegExp match to override the options. jQuery.param takes a hash and serialises it to a query_string but it doesn't provide the inverse (breaking up a query_string).

// put function into jQuery namespace
jQuery.redirect = function(url, params) {

    url = url || window.location.href || '';
    url =  url.match(/\?/) ? url : url + '?';

    for ( var key in params ) {
        var re = RegExp( ';?' + key + '=?[^&;]*', 'g' );
        url = url.replace( re, '');
        url += ';' + key + '=' + params[key]; 
    }  
    // cleanup url 
    url = url.replace(/[;&]$/, '');
    url = url.replace(/\?[;&]/, '?'); 
    url = url.replace(/[;&]{2}/g, ';');
    // $(location).attr('href', url);
    window.location.replace( url ); 
};

Then in the html

$('#selector').change(function(){ 
   $.redirect( location.href, { id : $(this).val() })
})

Thanks to everyone that responded.

Sign up to request clarification or add additional context in comments.

Comments

7

setting window.location.search will update the url's query string (and overwrite a value if it already exits)

$('#selector').change(function(){  
  window.location.search = "id=" + $(this).val();
}); 

2 Comments

What browser? Whats your HTML and JS look like?
Sorry, I was mistaking .search for a 'search' querystring parameter. Really search means the entire querystring in the DOM's location object.
7

Based on CoffeeMonster's answer:

There is a problem when the location.href contains a hash part:

www.example.com#hash becomes www.example.com#hash?id=whatever which results in ?id=whatever not being interpreted by the server.

Fixed it by removing the hash part of the url: url.split("#")[0];

// put function into jQuery namespace
jQuery.redirect = function(url, params) {

    url = url || window.location.href || '';
    url = url.split("#")[0];
    url =  url.match(/\?/) ? url : url + '?';

    for ( var key in params ) {
        var re = RegExp( ';?' + key + '=?[^&;]*', 'g' );
        url = url.replace( re, '');
        url += ';' + key + '=' + params[key]; 
    }  
    // cleanup url 
    url = url.replace(/[;&]$/, '');
    url = url.replace(/\?[;&]/, '?'); 
    url = url.replace(/[;&]{2}/g, ';');
    // $(location).attr('href', url);
    window.location.replace( url ); 
};

Now www.example.com#hash becomes www.example.com?id=whatever

1 Comment

Now, for bonus points, re-attach the hash to the end of the url. :-)
2

This works like a charm:

jQuery.redirect = function( url ) {
   window.location.replace( url );  
};
$( "#selector" ).change( function() {
    var href = window.location.href.substring( 0, window.location.href.indexOf( '?' ) );
    $.redirect( href + '?id=' + $( this ).val() );
} );

Comments

1

Try using the split function:

var url = location.href.split('?')[0] + '?;id=' + $(this).val();

split returns a list made up of the string split up by the string (like '?'), with that string removed.

Comments

0

I suspect the alleged solution is not working with specific variable names. Especially the line:

RegExp( ';?' + key + '=?[^&;]*', 'g' )

If key is a character sequence present elsewhere within the querystring, that occurrence will be mistakenly replaced also (try one letter, e.g. 'a'). This is because the regex leaves the string boundaries open (leading ';' and trailing '=' are both optional). Maybe the epxression better be something like:

RegExp( '[;&]' + key + '=?[^&;]*', 'g' )

Though I haven't tested it yet.

1 Comment

Nice bug find! Just checked my code and I'm passing in client_id=12;project_id=45; etc. but I see how easily it would break with just id= I think I'll go with something like RegExp( '[;&]?\b' ... ) Will test when I get to work. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.