Simple HTML form to pass values to URL

Viewed 109

I have a simple HTML form with a select element. The purpose is this is to use Wordpress's built in query parameters to allow users to sort the posts in an archive. Date Added, Title, etc.

<form action="" method="GET">
    <label id="sortLabel" for="orderby">Sort Songs:</label>
        <select name="orderby" id="sortbox">
            <option disabled selected>Sort by:</option>
            <option value="date&order=asc">Oldest First</option>
            <option value="date&order=dsc">Newest First</option>
            <option value="title&order=asc">Alphabetical (A-Z)</option>
            <option value="title&order=dsc">Alphabetical (Z-A</option>
        </select>
    <input type="submit" value="Filter" />
</form>

The option values are being passed through to the URL fine, but the URLs are encoding, causing the URL to look like this:

www.example.com/songs/?orderby=date%26order%3Dasc

Instead of this:

www.example.com/songs/?orderby=date&order=asc

1 Answers

This is simply how HTML forms work.

The value attributes are arbitrary text. The browser is sending the form request to www.example.com/songs/?orderby=<value>, where you happen to be setting the <value> to "date&order=asc", "date&order=dsc", etc.

The orderby's value has to make it to the server intact. & and = are reserved characters in a URL's query component, so that is why they are being percent-encoded when the orderby field is added to the URL query, thus allowing the server to properly receive the <value> that the user selected for orderby in the HTML.

To do what you want, you need to treat orderby and order separately in the HTML. I would add a separate <select> for order, eg:

<form action="" method="GET">
    <label id="sortLabel" for="orderby">Sort Songs:</label>
    <select name="orderby" id="sortbox">
        <option disabled selected>Sort by:</option>
        <option value="date">Date</option>
        <option value="title">Title</option>
    </select>
    <select name="order" id="sortbox">
        <option disabled selected>Order by:</option>
        <option value="asc">Oldest First, Alphabetical (A-Z)</option>
        <option value="dsc">Newest First, Alphabetical (Z-A)</option>
    </select>
    <input type="submit" value="Filter" />
</form>

If you wanted to make the order list a little cleaner, you could use client-side scripting to manipulate the display texts of the order options whenever the user selects a different orderby option.

Related