Skip to content

Instantly share code, notes, and snippets.

@OJ7
Created January 13, 2026 16:17
Show Gist options
  • Select an option

  • Save OJ7/4bf7084a1e8e3cae8d68b8a3f1ab9c0d to your computer and use it in GitHub Desktop.

Select an option

Save OJ7/4bf7084a1e8e3cae8d68b8a3f1ab9c0d to your computer and use it in GitHub Desktop.
Sort all listings by price on Swappa (instead of "featured" first)
// ==UserScript==
// @name Sort all listings by price on Swappa (instead of "featured" first)
// @namespace Violentmonkey Scripts
// @match https://swappa.com/listings/*
// @grant none
// @version 1.0
// @author -
// @description 1/13/2026, 10:30:33 AM
// ==/UserScript==
// Disclaimer: AI-generated script
// Sort table rows by price only (ignoring featured/non-featured status)
function sortTableByPrice() {
// Get the table and tbody
const table = document.getElementById("listings_table");
if (!table) {
console.error('Table with id "listings_table" not found');
return;
}
const tbody = table.querySelector("tbody");
if (!tbody) {
console.error("Table tbody not found");
return;
}
// Get all rows from tbody
const rows = Array.from(tbody.querySelectorAll("tr"));
// Extract price from each row and create sortable array
const rowsWithPrices = rows.map((row, index) => {
// Find the price span element
const priceSpan = row.querySelector('span[itemprop="price"]');
if (!priceSpan) {
console.warn(`Row ${index + 1} does not have a price span`);
return { row, price: Infinity }; // Put rows without prices at the end
}
// Extract price as number
const priceText = priceSpan.textContent.trim();
const price = parseFloat(priceText);
if (isNaN(price)) {
console.warn(`Row ${index + 1} has invalid price: "${priceText}"`);
return { row, price: Infinity };
}
return { row, price };
});
// Sort by price (ascending order)
rowsWithPrices.sort((a, b) => {
return a.price - b.price;
});
// Clear tbody
tbody.innerHTML = "";
// Re-insert rows in sorted order and update row numbers
rowsWithPrices.forEach((item, index) => {
const row = item.row;
// Update row number in the first td
const firstTd = row.querySelector("td:first-child");
if (firstTd) {
// Find the text node that contains the number
const metaTag = firstTd.querySelector("meta");
const textNodes = Array.from(firstTd.childNodes).filter(
(node) => node.nodeType === Node.TEXT_NODE
);
if (textNodes.length > 0) {
// Update the first text node (which should contain the number)
const numberTextNode = textNodes[0];
// Preserve the whitespace formatting
const whitespaceMatch =
numberTextNode.textContent.match(/^(\s*)\d+(\s*)$/);
if (whitespaceMatch) {
numberTextNode.textContent =
whitespaceMatch[1] + (index + 1) + whitespaceMatch[2];
} else {
numberTextNode.textContent = `\n ${
index + 1
}\n `;
}
} else if (metaTag) {
// If no text node exists, create one before the meta tag
const newTextNode = document.createTextNode(
`\n ${index + 1}\n `
);
firstTd.insertBefore(newTextNode, metaTag);
} else {
// Fallback: just set text content
firstTd.textContent = index + 1;
}
}
// Append row to tbody
tbody.appendChild(row);
});
console.log(`Sorted ${rowsWithPrices.length} rows by price`);
}
sortTableByPrice();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment