# Sorting Functionality Documentation

## Overview

This document describes the centralized sorting functionality implemented for table columns across the Django application.

## Files Created/Modified

### Created Files:
1. **`dbapp/mainapp/static/js/sorting.js`** - Main sorting JavaScript library
2. **`dbapp/mainapp/static/js/sorting-test.html`** - Test page for manual verification

### Modified Files:
1. **`dbapp/mainapp/templates/mainapp/base.html`** - Added sorting.js script include
2. **`dbapp/mainapp/templates/mainapp/components/_sort_header.html`** - Removed inline script, added data attributes

## Features

### 1. Sort Toggle Logic
- **First click**: Sort ascending (field)
- **Second click**: Sort descending (-field)
- **Third click**: Sort ascending again (cycles back)

### 2. URL Parameter Management
- Preserves all existing GET parameters (search, filters, etc.)
- Automatically resets page number to 1 when sorting changes
- Updates the `sort` parameter in the URL

### 3. Visual Indicators
- Shows up arrow (↑) for ascending sort
- Shows down arrow (↓) for descending sort
- Automatically initializes indicators on page load
- Adds `sort-active` class to currently sorted column

## Usage

### In Templates

Use the `_sort_header.html` component in your table headers:

```django
<thead class="table-dark sticky-top">
    <tr>
        <th>{% include 'mainapp/components/_sort_header.html' with field='id' label='ID' current_sort=sort %}</th>
        <th>{% include 'mainapp/components/_sort_header.html' with field='name' label='Название' current_sort=sort %}</th>
        <th>{% include 'mainapp/components/_sort_header.html' with field='created_at' label='Дата создания' current_sort=sort %}</th>
    </tr>
</thead>
```

### In Views

Pass the current sort parameter to the template context:

```python
def get(self, request):
    sort = request.GET.get('sort', '-id')  # Default sort
    
    # Validate allowed sorts
    allowed_sorts = ['id', '-id', 'name', '-name', 'created_at', '-created_at']
    if sort not in allowed_sorts:
        sort = '-id'
    
    # Apply sorting
    queryset = Model.objects.all().order_by(sort)
    
    context = {
        'sort': sort,
        'objects': queryset,
        # ... other context
    }
    return render(request, 'template.html', context)
```

## JavaScript API

### Functions

#### `updateSort(field)`
Updates the sort parameter and reloads the page.

**Parameters:**
- `field` (string): The field name to sort by

**Example:**
```javascript
updateSort('created_at');  // Sort by created_at ascending
```

#### `getCurrentSort()`
Gets the current sort field and direction from URL.

**Returns:**
- Object with `field` and `direction` properties
- `direction` can be 'asc', 'desc', or null

**Example:**
```javascript
const sort = getCurrentSort();
console.log(sort.field);      // 'created_at'
console.log(sort.direction);  // 'asc' or 'desc'
```

#### `initializeSortIndicators()`
Automatically called on page load to show current sort state.

## Requirements Satisfied

This implementation satisfies the following requirements from the specification:

- **5.1**: Supports ascending and descending order for sortable columns
- **5.2**: Toggles between ascending, descending when clicking column headers
- **5.3**: Displays visual indicators (arrow icons) showing sort direction
- **5.5**: Preserves sort state in URL parameters during navigation
- **5.6**: Preserves other active filters and resets pagination when sorting

## Testing

### Manual Testing

1. Open `dbapp/mainapp/static/js/sorting-test.html` in a browser
2. Click column headers to test sorting
3. Verify URL updates correctly
4. Add query parameters (e.g., ?page=5&search=test) and verify they're preserved

### Integration Testing

Test in actual Django views:
1. Navigate to any list view (sources, objitems, transponders)
2. Click column headers to sort
3. Verify data is sorted correctly
4. Apply filters and verify they're preserved when sorting
5. Navigate to page 2+, then sort - verify it resets to page 1

## Browser Compatibility

- Modern browsers supporting ES6 (URLSearchParams)
- Chrome 49+
- Firefox 44+
- Safari 10.1+
- Edge 17+

## Notes

- The sorting.js file is loaded with `defer` attribute for better performance
- All GET parameters are preserved except `page` which is reset to 1
- The function is globally available and can be called from any template
- Sort indicators are automatically initialized on page load
