If you want to do this without JS, you would generally use a form that submits with a variable for the category. It's always important to sanitize your inputs -- in your case this should be easy because you'd be passing an id (presumably an integer). Consider something like this in your HTML:
<form action="" method="get">
<option name="cid">
<select value="1">Category 1</select>
<select value="2">Category 2</select>
... etc ...
</option>
<input type="submit">Refresh</input>
</form>
Note that the "name" parameter is "cid", and in this example I used "get" -- you might prefer to use "post". Change $_GET and $_POST accordingly.
Then make your Snippet listen for the "cid" parameter:
$cid = null; // initialize
if (isset($_GET)) {
$cid = (int) $_GET['cid'];
}
if ($cid) {
$res = $modx->db->select("*", "learningmodx.products", "categoryid='" . $cid . "'" );
} else {
$res = $modx->db->select("*", "learningmodx.products");
}
// ... etc...
It's not as user-friendly because the page has to reload each time a new category is selected, but it should be much easier to code and debug.
Once you have that working, you could do the Ajax bit: make a separate MODX page that uses no template (i.e. blank). To test, paste in some static HTML -- maybe just start with "Hello world", but eventually you'll want to use HTML representing the output that your Snippet would normally kick out. Make a copy of your original page, and set it up so that it uses an Ajax request to that other MODX page. It's sorta like doing a "javascript include": it should send an Ajax request to the other page, then write it back to the original page. This is where those JQuery tutorials would come in. Once you have the Ajax working, then you can go back to the separate "Hello World" page and replace it with your Snippet to make it dynamically print out the HTML you require.
Hope that helps.