0

I have adapted some code to populate drop-down selection boxes via MySQL queries, and my final 'result' needs to be appended to a new "search" URL.

var result = $("select#model option:selected").html();
$.post (location.href="advanced_search.php?" + "keywords=" + result, function(data){;

My problem is result includes spaces that I need to convert to +, so:

/advanced_search.php?keywords=2001-2004 Honda Civic TypeR

needs to read:

/advanced_search.php?keywords=2001-2004+Honda+Civic+TypeR

I've spent all evening looking for a solution, but I am having a very hard time finding something I can implement with my limited skills!

Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
  • This seems to be what you are looking for, since other values which are not ASCII may cause problems as well I guess: http://stackoverflow.com/questions/332872/how-to-encode-a-url-in-javascript – bjarneh Oct 16 '12 at 23:32
  • why are you setting `location.href` at the same time as trying to post to it? – Alnitak Oct 16 '12 at 23:36
  • What I don't understand is why you'd use `$.post` instead of `$.get`. – zzzzBov Oct 16 '12 at 23:40
  • Methinks this is an [XY Problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). – zzzzBov Oct 16 '12 at 23:43
  • 2
    FYI, `location.href = ...` will blow away your POST data, so while you may think you are POSTing these parameters to the server, you are actually just redirecting and using GET parameters. – Mike Samuel Oct 16 '12 at 23:44

5 Answers5

5

Use the data parameters of jQuery's AJAX methods and you won't need to escape anything - it'll all be done for you by jQuery.

Furthermore, this query is probably supposed to be a GET, rather than a POST. When you assign to location.href you cause a page reload of the new URL, rather than a true AJAX request.

var result = $("select#model option:selected").html();
$.get("advanced_search.php", {
     keywords: result
}, function() { ... });

IMHO there is almost never a good reason to create POST or GET parameters by hand - it's far simpler to use an object of key / value pairs.

Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • That's why I'm an amateur, I guess?! Thank you for your input anyway. Andy. – user1742819 Oct 16 '12 at 23:49
  • Sorry, @Alnitak, your answer is much better than mine, but I can still give you a +1. – Niet the Dark Absol Oct 16 '12 at 23:57
  • @Kolink no worries, you just have to figure how to answer the question the OP really needed answering, and not the one he actually asked ;-) Heck, you still got accepted... – Alnitak Oct 16 '12 at 23:59
  • Sorry if I've sparked something off with my inadequate knowledge. It's kind of why I've muddled through it up to this point without posting on a technical forum in the first place! I have changed my snipped to 'get' now, but I am clueless as to why! This is my first attempt at anything like this, and I'm trying to learn. I don't know why everyone is so harsh on each other over 2 lines of code though! $.get (location.href="advanced_search_result.php?keywords=" + result.replace(/ /g,'+'), function(data){; Works perfectly for what I want to do. Andy. – user1742819 Oct 17 '12 at 00:09
  • To illustrate why there's a debate, see what happens if you search for `This#breaks` – Niet the Dark Absol Oct 17 '12 at 00:46
  • But is that relevant to my question? All I needed was a way to convert a string from (ex) 2001-2004 Honda Civic TypeR to 2001-2004+Honda+Civic+TypeR. I don't have any instances of # in my item descriptions. – user1742819 Oct 17 '12 at 01:18
  • Don't get me wrong, I would like to understand *why* I am so wrong, but one poster has me down as "stupid" for using jQuery, and feeling rather unwelcome as a bad coder by others! Frankly, Kolink answered my question exactly as it was posed, and I think members castigating him for offering a solution that works *exactly* as I asked for, and me for limited knowledge, is rather harsh. We all have to start somewhere. Were all the members here born knowing code, or just freed from the Matrix over the last 10 years?! – user1742819 Oct 17 '12 at 01:23
  • @user1742819, you do realize that Kolink is the only poster that used the word "stupid" (not at you directly either), and that you've accepted his answer? – zzzzBov Oct 17 '12 at 03:53
  • @user1742819 remove the `location.href=` bit - it doesn't do what you think it does. As for the debate, every answer here _apart_ from the accepted one gives you a solution that will work regardless of the format of your entries, and many are offering advice on why your `$.post` is wrong, and why you shouldn't be altering `location.href`. This knowledge is freely offered by programmers with many decades of experience between them. It should not be ignored. – Alnitak Oct 17 '12 at 07:07
1
location.href="advanced_search.php?" + "keywords=" + result

should probably be

location.href="advanced_search.php?keywords=" + encodeURIComponent(result)

since if result contains a # then that will become part of the fragment instead of part of a query parameter. encodeURIComponent will properly escape a string so that your server returns result when you ask for the value of the "keywords" GET parameter.

As Mozilla's docs explain

To avoid unexpected requests to the server, you should call encodeURIComponent on any user-entered parameters that will be passed as part of a URI. For example, a user could type "Thyme &time=again" for a variable comment. Not using encodeURIComponent on this variable will give comment=Thyme%20&time=again. Note that the ampersand and the equal sign mark a new key and value pair.


If you have an already constructed URL, then

encodeURI('/advanced_search.php?keywords=2001-2004 Honda Civic TypeR')

== '/advanced_search.php?keywords=2001-2004%20Honda%20Civic%20TypeR'

The builtin encodeURI function takes a string and replaces all characters that can't appear in a URL with the %-encoded equivalent.

Encodes a Uniform Resource Identifier (URI) by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character (will only be four escape sequences for characters composed of two "surrogate" characters).

Any server should treat %20 in a URL as equivalent to + except that %20 works outside the path part of the URL.

If for some reason, you really need +, then after encodeURI it should be safe to replace %20 with + thus.

var myUrl = '/advanced_search.php?keywords=2001-2004 Honda Civic TypeR';
encodeURI(myUrl).replace(/%20/g, '+')
Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
  • @cwolves, I edited my post to make it clear when `encodeURI` is appropriate and when `encodeURIComponent`. – Mike Samuel Oct 16 '12 at 23:40
  • 1
    this is all unnecessarily complicated - `$.post` has a means to _automatically_ escape parameters - the OP should use it! – Alnitak Oct 16 '12 at 23:40
  • @Alnitak, If you write an answer that explains `$.post`, I'll be happy to upvote. If the user is posting, they shouldn't be passing GET parameters. – Mike Samuel Oct 16 '12 at 23:43
  • @MikeSamuel in my answer I've left the script using `$.post`, but the parameters will end up in the message body, not at GET parameters. – Alnitak Oct 16 '12 at 23:44
  • @Alnitak, Apologies. I didn't see your answer earlier. I'm still unclear as to whether the user wants to GET or POST so I'll leave this answer here in the meantime. – Mike Samuel Oct 16 '12 at 23:46
  • @MikeSamuel I think you hit the nail on the head with your comment about writing to `location.href` - he's causing an actual redirect to a GET-based script, and the AJAX call never happens. – Alnitak Oct 16 '12 at 23:48
1

You want encodeURIComponent which not only replaces spaces but anything else that may cause issues.

..."keywords=" + encodeURIComponent( result )
1

I would suggest you revisit your code just slightly, as POSTing data but just sending the information over the QueryString (everything after the ? in the URL) is missing the point just a little.

You should be sending your keywords in an object, like so:

var result = $("select#model option:selected").html();
$.post("advanced_search.php", { keywords: result }, function(data){
    // success callback code goes here
});

If your PHP looks for the $_POST['keywords'], you should find your data in there when the $post is executed by jQuery.

Sending it across the QueryString is not undoable, but in that case you really should be doing something along the lines of:

var result = $("select#model option:selected").html();
$.get("advanced_search.php", 
    { keywords: result }, 
    function(data){
        // success callback code goes here
    });

However, you should get used to POSTing data properly, as sending data over the querystring is both unsecure and prone to issues due to encoding and URL length limits.

Also, this begs the question: Why are you encoding the HTML from within the tag? Why are you not simply putting a simple key in your , like this:

<select id="model">
    <option value="key1">2001-2004 Honda Civic TypeR</option>
    <option value="key2">2005-2008 Honda Civic TypeR</option>
    <option value="key3">2009-2012 Honda Civic TypeR</option>
    <option value="key4">2013-2015 Honda Civic TypeR</option>
</select>

var result = $("select#model option:selected").val();
$.post("advanced_search.php", { keywords: result }, function(data){
    // success callback code goes here
});

Should be simpler to run the query, as well, considering you can have your values shortened and not require any mucking around with encoding/decoding values, unless you don't have keys for each select option, in which case, I guess I understand the approach you're taking.

Jason M. Batchelor
  • 2,951
  • 16
  • 25
  • 1
    even with `$.get()` he should use a key/value object instead of a manually constructed query string. – Alnitak Oct 16 '12 at 23:42
  • The part is not hard coded. (Is that the correct term?) The option tags are populated according to the data queried from the database. The next drop-down section box is then dependant on the parent category of the previous box. The last box lists all my items by their "item description" in the database table. I am using that text description to append to the search result page. Very crude, I am sure. But it works, and that's what I need! I have all the time in the world to work on it and refine it, but I just need it working for now. Thank you for your input. Andy. – user1742819 Oct 17 '12 at 00:18
-3

Just .replace(/ /g,'+') it, although I must admit I'm confused as to what your code is doing exactly.

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
  • 1
    Although that will change `' '` to `'+'`, it will not correctly escape the value to be used within a query-string, as is shown in the question. – zzzzBov Oct 16 '12 at 23:39
  • +1 to return this to 0 vote. This shouldn't be down-voted. It does _exactly_ what the OP asked for, it's just not the best answer –  Oct 16 '12 at 23:40
  • 2
    @cwolves, there's a difference between doing what's right, and doing what the OP asks for. See the [XY Problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) as a good example of when *not* to answer the question. – zzzzBov Oct 16 '12 at 23:42
  • @Kolink I didn't downvote, but I agree with zzzzBov - answering the question exactly as written does the OP no favours at all. – Alnitak Oct 16 '12 at 23:43
  • @zzzzBov -- Agreed, but answers that actually answer the question correctly should not be down-voted into negative votes. They should just calmly sit around not being accepted. I believe negative votes should be reserved for answers that are actually _wrong_, not just ones that "can be better". This answer actually would solve the OP's problem –  Oct 16 '12 at 23:43
  • 2
    @cwolves, "this answer is not useful" (as per the `[title]` on the down arrow). I think an answer such as this one that doesn't fix the problem, but only the symptoms is not useful. Obviously you feel differently. – zzzzBov Oct 16 '12 at 23:46
  • 3
    This answer will only send the OP further down the wrong path. It only takes a little insight to recognize the actual problem presented here, this does not fix it... and now it's been accepted (shakes head...). – Wesley Murch Oct 16 '12 at 23:47
  • This did *exactly* what I wanted to do! Thank you very much, zzzzBov! :) – user1742819 Oct 16 '12 at 23:48
  • 3
    @user1742819 it didn't fix your problem - it merely masked the symptoms. – Alnitak Oct 16 '12 at 23:48
  • Sorry, guys, but I've always maintained that jQuery makes people stupid and I guess this is proof. I mean, what's the point of sending a `$.post` request and putting the form data in the `get` variable? – Niet the Dark Absol Oct 16 '12 at 23:51
  • 2
    In agreement with all the others, here. This is the worst sort of monkeypatching. @user1742819, you need to take a hard look at all the other suggestions, as getting it wrong now will only cause you hours of rework in the future if you don't learn better practices, now. – Jason M. Batchelor Oct 16 '12 at 23:51
  • Sorry, as I said, new here! Thanks actually go to Kolink for the solution to my issue! I seem to have caused a bit of debate here, and what I have implemented is probably "wrong" in professional circles. I don't know how to elaborate on my post so anyone can comment further, if they wanted to. Sorry for the fuss I may have caused. Andy. – user1742819 Oct 16 '12 at 23:59
  • 1
    @user1742819, I recommend reviewing all of the answers and spend time reading the material presented. If you're new to [url-encoding](http://en.wikipedia.org/wiki/Percent-encoding), it will take some time investment on your part to learn and understand it. Copy-pasting the first bit of code that seems to do what you want is only going to hurt you down the road. – zzzzBov Oct 17 '12 at 01:40