🌏 About Bangladesh

General Information

  • Official Name: People’s Republic of Bangladesh
  • Capital: Dhaka
  • Language: Bangla
  • Currency: Bangladeshi Taka (BDT)
  • Government: Parliamentary Republic
  • Location: South Asia

History

  • Ancient Maurya, Gupta, Pala empires
  • Mughal Empire influence
  • British colonial rule till 1947
  • East Pakistan era (1947–1971)
  • Liberation War → Independent in 1971

Quick Summary Table

Feature Detail
Independence Day March 26, 1971
Victory Day Dec 16, 1971
Area 147,570 km²
Population ~172 million
Districts 64
Capital Dhaka

👥 Population of Bangladesh

District wise Population

Filter by District

🌍 Area-wise Population

Area

Filter by Type

🍛 Famous Food of Bangladesh

Famous Food District wise

Filter by District

🏰 Historical Places

Distric-wise historical places

Filter by District 🏛️

Rivers of Bangladesh

Rivers

Rivers of Bangladesh

Major Rivers

Major Rivers of Bangladesh

Health Facilities

Hospitals in Bangladesh

Filter Healthcare Facilities

Fire Service Facilities

Fire service

Fire Stations of Bangladesh

School & Colleges

District Wise School & Colleges

Schools & Colleges of Bangladesh

University List

Public University

Private University

---
title: "Explore Bangladesh"
output:
  flexdashboard::flex_dashboard:
    orientation: rows
    vertical_layout: fill
    theme: cosmo
    source_code: embed
---



```{r setup, include=FALSE}
library(DT)
library(dplyr)
library(htmltools)
library(jsonlite)
```

# 🌏 About Bangladesh

### General Information
- **Official Name:** People's Republic of Bangladesh  
- **Capital:** Dhaka  
- **Language:** Bangla  
- **Currency:** Bangladeshi Taka (BDT)  
- **Government:** Parliamentary Republic  
- **Location:** South Asia  

### History
- Ancient Maurya, Gupta, Pala empires  
- Mughal Empire influence  
- British colonial rule till 1947  
- East Pakistan era (1947–1971)  
- Liberation War → **Independent in 1971**  

### Quick Summary Table  
| Feature           | Detail            |
|------------------|------------------|
| Independence Day | March 26, 1971   |
| Victory Day      | Dec 16, 1971     |
| Area             | 147,570 km²      |
| Population       | ~172 million     |
| Districts        | 64               |
| Capital          | Dhaka            |

---

# 👥 Population of Bangladesh

### District wise Population

```{r }
# ---------------------------
# Load & Clean Data
# ---------------------------
pop_data <- read.csv("~/Documents/Explore-Bangladesh/Datasets/bangladesh_district_population_area.csv",
                     stringsAsFactors = FALSE, check.names = FALSE)

# Remove unnamed columns
pop_data <- pop_data[, colnames(pop_data) != "" & !is.na(colnames(pop_data))]

colnames(pop_data) <- c(
  "Name","Abbr","Status","Native","Area_km2",
  "Pop_1991","Pop_2001","Pop_2011","Pop_2022"
)

# Convert numeric columns
pop_data <- pop_data %>%
  mutate(across(starts_with("Pop"), ~as.numeric(gsub(",", "", .))),
         Area_km2 = as.numeric(gsub(",", "", Area_km2)))

districts <- sort(unique(pop_data$Name))

# ---------------------------
# Cleaner Dropdown + CSS
# ---------------------------
dropdown <- tagList(
  tags$style("
    #districtFilter_pop {
      width: 180px;
      padding: 4px 6px;
      font-size: 14px;
      height: 32px !important;
      line-height: 20px !important;
      background-color: white;
      border: 1px solid #ccc;
      border-radius: 4px;
    }
  "),
  tags$select(
    id = "districtFilter_pop",
    tags$option(value = "", "All Districts"),
    lapply(districts, function(x) tags$option(value = x, x))
  )
)

# ---------------------------
# Render dropdown + DataTable
# ---------------------------
browsable(
  tagList(
    tags$h3("Filter by District", style = "margin-bottom:5px;"),
    dropdown,
    datatable(
      pop_data,
      rownames = FALSE,
      filter = "none",
      options = list(
        pageLength = 10,
        scrollX = TRUE,
        autoWidth = TRUE,
        initComplete = JS("
          function(settings, json) {
            var table_pop = this.api();
            
            $('#districtFilter_pop').on('change', function() {
              var val = $(this).val();

              if (val && val.length > 0) {
                table_pop.column(0).search('^' + val + '$', true, false).draw();
              } else {
                table_pop.column(0).search('').draw();
              }
            });
          }
        ")
      )
    )
  )
)
```


# 🌍 Area-wise Population

### Area

```{r }
pop_area <- read.csv("~/Documents/Explore-Bangladesh/Datasets/bangladesh_area_wise_population_area.csv")

colnames(pop_area) <- c("Name","Abbr","Status","Native","Area_km2",
                        "Pop_1991","Pop_2001","Pop_2011","Pop_2022","X")

pop_area <- pop_area %>% 
  select(-X)

area_filter <- unique(pop_area$Abbr)

dropdown_area <- tagList(
  tags$style("
    #districtFilter_area {
      width: 180px;
      padding: 4px 6px;
      font-size: 14px;
      height: 32px !important;
      line-height: 20px !important;
      background-color: white;
      border: 1px solid #ccc;
      border-radius: 4px;
    }
  "),
  tags$select(
    id = "districtFilter_area",
    tags$option(value = "", "All Type"),
    lapply(area_filter, function(x) tags$option(value = x, x))
  )
)

# ---------------------------
# Render dropdown + DataTable
# ---------------------------
browsable(
  tagList(
    tags$h3("Filter by Type", style = "margin-bottom:5px;"),
    dropdown_area,
    datatable(
      pop_area,
      rownames = FALSE,
      filter = "none",
      options = list(
        pageLength = 10,
        scrollX = TRUE,
        autoWidth = FALSE,
        initComplete = JS("
          function(settings, json) {
            var table_area = this.api();

            $('#districtFilter_area').on('change', function() {
              var val = $(this).val();

              if (val && val.length > 0) {
                table_area.column(1).search('^' + val + '$', true, false).draw();
              } else {
                table_area.column(1).search('').draw();
              }
            });
          }
        ")
      )
    )
  )
)
```

# 🍛 Famous Food of Bangladesh

## Famous Food District wise

```{r }
food_data <- read.csv("~/Documents/Explore-Bangladesh/Datasets/Famous_food - Sheet1.csv")
colnames(food_data) <- c("District", "Bangla_Name", "English_Name")

food_districts <- sort(unique(food_data$District))

dropdown_food <- tagList(
  tags$style("
    #districtFilter_food {
      width: 180px;
      padding: 4px 6px;
      font-size: 14px;
      height: 32px !important;
      line-height: 20px !important;
      background-color: white;
      border: 1px solid #ccc;
      border-radius: 4px;
    }
  "),
  tags$select(
    id = "districtFilter_food",
    tags$option(value = "", "All Districts"),
    lapply(food_districts, function(x) tags$option(value = x, x))
  )
)

browsable(
  tagList(
    tags$h3("Filter by District", style = "margin-bottom:5px;"),
    dropdown_food,
    datatable(
      food_data,
      rownames = FALSE,
      filter = "none",
      options = list(
        pageLength = 15,
        scrollX = TRUE,
        autoWidth = FALSE,
        initComplete = JS("
          function(settings, json) {
            var table_food = this.api();

            $('#districtFilter_food').on('change', function() {
              var val = $(this).val();

              if (val && val.length > 0) {
                table_food.column(0).search('^' + val + '$', true, false).draw();
              } else {
                table_food.column(0).search('').draw();
              }
            });
          }
        ")
      )
    )
  )
)

```

# 🏰 Historical Places

### Distric-wise historical places

```{r }
# Load data
historic <- read.csv("~/Documents/Explore-Bangladesh/Datasets/historical_places.csv",
                     stringsAsFactors = FALSE, check.names = FALSE)
colnames(historic) <- c("District", "Place")

# Unique districts for dropdown
history_filter <- sort(unique(historic$District))

# Create dropdown with CSS
dropdown_history <- tags$div(
  tags$style("
    #districtFilter_history {
      width: 200px;
      padding: 4px 6px;
      font-size: 14px;
      height: 32px !important;
      line-height: 20px !important;
      background-color: white;
      border: 1px solid #ccc;
      border-radius: 4px;
      margin-bottom: 10px;
    }
  "),
  tags$select(
    id = "districtFilter_history",
    tags$option(value = "", "All Districts"),
    lapply(history_filter, function(x) tags$option(value = x, x))
  )
)

# Render the table
browsable(
  tagList(
    tags$h3("Filter by District 🏛️", style = "margin-bottom:5px;"),
    dropdown_history,
    datatable(
      historic,
      rownames = FALSE,
      filter = "none",
      options = list(
        pageLength = 15,
        scrollX = TRUE,
        autoWidth = FALSE,
        initComplete = JS("
          function(settings, json) {
            var table_history = this.api();

            // Bind dropdown change event
            $('#districtFilter_history').on('change', function() {
              var val = $(this).val();

              if(val) {
                // Filter only the first column (District)
                table_history.column(0).search('^' + val + '$', true, false).draw();
              } else {
                table_history.column(0).search('').draw();
              }
            });
          }
        ")
      )
    )
  )
)
```

# Rivers of Bangladesh

### Rivers 

```{r }
rivers <- read.csv("~/Documents/Explore-Bangladesh/Datasets/rivers.csv",
                   stringsAsFactors = FALSE, check.names = FALSE)
colnames(rivers) <- c("List", "Name", "District", "Thana", "Latitude", "Longitude")
rivers <- rivers %>% select(-List)

# Prepare unique lists
all_districts <- sort(unique(rivers$District))
all_thanas    <- sort(unique(rivers$Thana))

# Create district → thanas mapping for JS
district_thana_map <- rivers %>%
  select(District, Thana) %>%
  distinct() %>%
  arrange(District, Thana) %>%
  split(.$District) %>%
  lapply(function(x) sort(unique(x$Thana)))

# HTML dropdowns
dropdowns_rivers <- tagList(
  tags$div(
    style = "margin-bottom: 15px; padding: 10px; background:#f8f9fa; border-radius: 6px;",
    tags$label("Filter by: ", style = "font-weight:bold; margin-right:10px;"),
    tags$select(
      id = "districtFilter_rivers",
      style = "width:200px; padding:6px; margin-right:12px;",
      tags$option(value = "", "All Districts"),
      lapply(all_districts, function(d) tags$option(value = d, d))
    ),
    tags$select(
      id = "thanaFilter_rivers",
      style = "width:200px; padding:6px;",
      tags$option(value = "", "All Thanas")
    )
  )
)

# JavaScript for interdependent dropdowns + filtering
js_code <- sprintf("
  function(settings, json) {
    var table = this.api();
    
    // Full district-thana mapping from R
    var districtThanaMap = %s;
    
    var $districtSelect = $('#districtFilter_rivers');
    var $thanaSelect    = $('#thanaFilter_rivers');
    
    // Helper: redraw table based on current dropdown values
    function applyFilters() {
      var dist = $districtSelect.val();
      var thana = $thanaSelect.val();
      
      if (dist) {
        table.column(1).search('^' + dist + '$', true, false);
      } else {
        table.column(1).search('');
      }
      
      if (thana) {
        table.column(2).search('^' + thana + '$', true, false);
      } else {
        table.column(2).search('');
      }
      
      table.draw();
    }
    
    // District change
    $districtSelect.on('change', function() {
      var selectedDist = $(this).val();
      $thanaSelect.empty().append('<option value=\"\">All Thanas</option>');
      
      if (selectedDist && districtThanaMap[selectedDist]) {
        districtThanaMap[selectedDist].forEach(function(thana) {
          $thanaSelect.append('<option value=\"' + thana + '\">' + thana + '</option>');
        });
      } else {
        // All thanas when no district selected
        Object.values(districtThanaMap).flat().sort().forEach(function(thana) {
          if (!$thanaSelect.find(\"option[value='\" + thana + \"']\").length) {
            $thanaSelect.append('<option value=\"' + thana + '\">' + thana + '</option>');
          }
        });
      }
      
      // Reset thana selection when district changes
      $thanaSelect.val('');
      applyFilters();
    });
    
    // Thana change
    $thanaSelect.on('change', function() {
      applyFilters();
    });
    
    // Initial population of thana dropdown
    Object.values(districtThanaMap).flat()
      .filter((v,i,a) => a.indexOf(v) === i)
      .sort()
      .forEach(function(thana) {
        $thanaSelect.append('<option value=\"' + thana + '\">' + thana + '</option>');
      });
  }
", toJSON(district_thana_map, auto_unbox = TRUE))

# Render interactive table
browsable(
  tagList(
    tags$h3("Rivers of Bangladesh", style = "color:#2c3e50; margin-bottom:10px;"),
    dropdowns_rivers,
    datatable(
      rivers,
      rownames = FALSE,
      escape = FALSE,
      options = list(
        pageLength = 15,
        scrollX = TRUE,
        dom = 'tip',
        initComplete = JS(js_code)
      ),
      selection = 'none'
    )
  )
)
```


# Major Rivers 

### Major Rivers of Bangladesh 

```{r }
major_rivers <- read.csv("~/Documents/Explore-Bangladesh/Datasets/bangladesh_rivers.csv",
                   stringsAsFactors = FALSE, check.names = FALSE)
colnames(major_rivers) <- c("River Name", "Districts", "Length")

datatable(
  major_rivers,
  rownames = FALSE,
  options = list(
    pageLength = 10,
    scrollX = TRUE,
    autoWidth = FALSE
  )
)

```

# Health Facilities 

## Hospitals in Bangladesh 

```{r }
# Load data
hospital <- read.csv("~/Documents/Explore-Bangladesh/Datasets/healthcare_facilities_full.csv",
                     stringsAsFactors = FALSE, check.names = FALSE)

# Rename columns (adjust based on actual data)
colnames(hospital)[1:min(8, ncol(hospital))] <- c("List", "Name", "Registration_Code", 
                                                   "Type", "Category", "District", "Thana", "Address")[1:min(8, ncol(hospital))]

hospital <- hospital %>%
  select(-List) %>%
  mutate(across(everything(), ~ trimws(.))) %>%
  mutate(across(everything(), ~ na_if(., ""))) %>% 
  mutate(Category = ifelse(Type == "Blood Bank", "Blood Bank",Category )) # Convert empty strings to NA

# Clean dataset for filters
hospital_clean <- hospital %>%
  filter(!is.na(Type), !is.na(Category), !is.na(District), !is.na(Thana))

# Unique values
all_types <- sort(unique(hospital_clean$Type))
all_categories <- sort(unique(hospital_clean$Category))
all_districts <- sort(unique(hospital_clean$District))
all_thanas <- sort(unique(hospital_clean$Thana))

# Dropdowns
dropdowns <- tags$div(
  style = "background:#f8f9fa; padding:15px; border-radius:10px; margin-bottom:20px;",
  tags$h4("Filter Healthcare Facilities", style = "margin:0 0 10px 0; color:#1e40af;"),
  tags$div(
    style = "display:flex; flex-wrap: wrap; gap: 12px;",
    tags$select(id = "typeSel", style = "min-width:180px; padding:6px;",
                tags$option(value="", "All Types"),
                lapply(all_types, function(x) tags$option(value=x, x))),
    tags$select(id = "categorySel", style = "min-width:180px; padding:6px;",
                tags$option(value="", "All Categories")),
    tags$select(id = "districtSel", style = "min-width:180px; padding:6px;",
                tags$option(value="", "All Districts")),
    tags$select(id = "thanaSel", style = "min-width:180px; padding:6px;",
                tags$option(value="", "All Thanas")),
    tags$button(id="clearBtn", "Clear Filters",
                style="padding:6px 12px; background-color:#dc3545; color:white; border:none; border-radius:4px; cursor:pointer;")
  )
)

# JavaScript for hierarchical filters
js <- JS("
function(settings, json) {
  var table = this.api();
  var allData = table.rows().data().toArray();
  
  // Helper to populate dropdown
  function populateDropdown($select, items, placeholder) {
    $select.empty();
    $select.append('<option value=\"\">' + placeholder + '</option>');
    items.forEach(function(item){ $select.append('<option value=\"'+item+'\">'+item+'</option>'); });
  }

  var $type = $('#typeSel');
  var $category = $('#categorySel');
  var $district = $('#districtSel');
  var $thana = $('#thanaSel');

  // Maps
  var typeMap = {}, categoryMap = {}, districtMap = {};
  allData.forEach(function(row){
    var type=row[2], cat=row[3], dist=row[4], thana=row[5];
    if(type){ if(!typeMap[type]) typeMap[type]=[]; if(cat && typeMap[type].indexOf(cat)===-1) typeMap[type].push(cat);}
    if(cat){ if(!categoryMap[cat]) categoryMap[cat]=[]; if(dist && categoryMap[cat].indexOf(dist)===-1) categoryMap[cat].push(dist);}
    if(dist){ if(!districtMap[dist]) districtMap[dist]=[]; if(thana && districtMap[dist].indexOf(thana)===-1) districtMap[dist].push(thana);}
  });

  function getAllUnique(index){
    var unique=[]; allData.forEach(function(row){if(row[index] && unique.indexOf(row[index])===-1) unique.push(row[index]);}); return unique.sort();
  }

  function applyFilters(){
    var t=$type.val(), c=$category.val(), d=$district.val(), th=$thana.val();
    table.columns().search('');
    if(t) table.column(2).search('^'+t+'$',true,false);
    if(c) table.column(3).search('^'+c+'$',true,false);
    if(d) table.column(4).search('^'+d+'$',true,false);
    if(th) table.column(5).search('^'+th+'$',true,false);
    table.draw();
  }

  $type.on('change', function(){
    var val=$(this).val();
    populateDropdown($category, val ? typeMap[val] : getAllUnique(3), 'All Categories');
    $category.val(''); $district.val(''); $thana.val('');
    populateDropdown($district, [], 'All Districts');
    populateDropdown($thana, [], 'All Thanas');
    applyFilters();
  });

  $category.on('change', function(){
    var val=$(this).val();
    populateDropdown($district, val ? categoryMap[val] : getAllUnique(4), 'All Districts');
    $district.val(''); $thana.val('');
    populateDropdown($thana, [], 'All Thanas');
    applyFilters();
  });

  $district.on('change', function(){
    var val=$(this).val();
    populateDropdown($thana, val ? districtMap[val] : getAllUnique(5), 'All Thanas');
    $thana.val('');
    applyFilters();
  });

  $thana.on('change', applyFilters);

  $('#clearBtn').on('click', function(){
    $type.val(''); $category.val(''); $district.val(''); $thana.val('');
    populateDropdown($category, getAllUnique(3), 'All Categories');
    populateDropdown($district, getAllUnique(4), 'All Districts');
    populateDropdown($thana, getAllUnique(5), 'All Thanas');
    table.columns().search('').draw();
  });

  // Init dropdowns
  populateDropdown($category, getAllUnique(3), 'All Categories');
  populateDropdown($district, getAllUnique(4), 'All Districts');
  populateDropdown($thana, getAllUnique(5), 'All Thanas');
}
")

# Render
browsable(
  tagList(
    dropdowns,
    datatable(
      hospital,
      rownames = FALSE,
      escape = FALSE,
      options = list(
        pageLength = 15,
        scrollX = TRUE,
        lengthMenu = c(10,25,50,100),
        dom='lfrtip',
        initComplete = js
      ),
      class='compact stripe hover cell-border'
    )
  )
)

```

# Fire Service Facilities 

### Fire service 

```{r }
fire_service <- read.csv("~/Documents/Explore-Bangladesh/Datasets/Fire-station - Sheet1.csv",
                         stringsAsFactors = FALSE,
                         check.names = FALSE,
                         fileEncoding = "UTF-8")

# Clean column names (removes extra spaces, etc.)
colnames(fire_service) <- trimws(colnames(fire_service))

# ------------------- 2. FIND EXACT COLUMNS -------------------
# This works no matter the exact spelling or order
division_col_idx <- which(tolower(colnames(fire_service)) %in% c("division", "divisions"))
district_col_idx <- which(tolower(colnames(fire_service)) %in% c("district", "districts"))

if(length(division_col_idx) == 0) stop("Column 'Division' not found!")
if(length(district_col_idx) == 0) stop("Column 'District' not found!")

# ------------------- 3. BUILD MAPPING (NO deframe!) -------------------
map_df <- fire_service %>%
  select(all_of(c(division_col_idx, district_col_idx))) %>%
  setNames(c("Division", "District")) %>%
  filter(!is.na(Division), !is.na(District), Division != "", District != "") %>%
  distinct() %>%
  group_by(Division) %>%
  summarise(Districts = list(sort(unique(District))), .groups = "drop")

# Convert to named list manually (no deframe needed)
division_district_map <- map_df$Districts
names(division_district_map) <- map_df$Division

all_divisions <- sort(unique(map_df$Division))

# ------------------- 4. DROPDOWNS -------------------
dropdowns <- tags$div(
  style = "text-align:center; margin:25px 0; padding:18px; background:#f8f9fa; border-radius:12px;",
  tags$label("Filter Fire Stations:", 
              style = "font-weight:bold; font-size:18px; margin-right:15px; color:#2c3e50;"),
  tags$select(id = "divFilter",
              style = "width:270px; padding:10px; font-size:16px; border-radius:6px; border:1px solid #3498db; margin-right:15px;",
              tags$option(value = "", "All Divisions"),
              lapply(all_divisions, function(x) tags$option(value = x, x))
  ),
  tags$select(id = "distFilter",
              style = "width:270px; padding:10px; font-size:16px; border-radius:6px; border:1px solid #3498db;",
              tags$option(value = "", "All Districts"))
)

# ------------------- 5. JAVASCRIPT (PERFECT) -------------------
js_code <- sprintf("
  function(settings, json) {
    var table = this.api();
    var map = %s;
    
    var $div = $('#divFilter');
    var $dist = $('#distFilter');
    
    function apply() {
      var div  = $div.val();
      var dist = $dist.val();
      
      // These indices are now 100%% correct (0-based for DataTables)
      table.column(%d).search(div  ? '^' + $.fn.dataTable.util.escapeRegex(div)  + '$' : '', true, false);
      table.column(%d).search(dist ? '^' + $.fn.dataTable.util.escapeRegex(dist) + '$' : '', true, false);
      table.draw();
    }
    
    $div.on('change', function() {
      var selected = $(this).val();
      $dist.empty().append('<option value=\"\">All Districts</option>');
      
      if (selected && map[selected]) {
        map[selected].forEach(d => $dist.append('<option value=\"' + d + '\">' + d + '</option>'));
      } else {
        var all = Object.values(map).flat()
          .filter((v,i,a) => a.indexOf(v) === i)
          .sort();
        all.forEach(d => $dist.append('<option value=\"' + d + '\">' + d + '</option>'));
      }
      $dist.val('');
      apply();
    });
    
    $dist.on('change', apply);
    
    // Initial districts
    (function() {
      var all = Object.values(map).flat()
        .filter((v,i,a) => a.indexOf(v) === i)
        .sort();
      all.forEach(d => $dist.append('<option value=\"' + d + '\">' + d + '</option>'));
    })();
    
    apply();
  }
", toJSON(division_district_map, auto_unbox = TRUE),
   division_col_idx - 1,   # 0-based index for JS
   district_col_idx - 1
)

# ------------------- 6. SHOW TABLE -------------------
browsable(
  tagList(
    tags$head(tags$style(HTML("
      body {font-family: 'Segoe UI', sans-serif; background:#f5f7fa; padding:20px;}
      h3 {color:#e74c3c; text-align:center; font-size:32px; margin:20px;}
      .dataTables_wrapper {background:white; border-radius:12px; padding:20px; box-shadow:0 4px 20px rgba(0,0,0,0.1);}
    "))),
    tags$h3("Fire Stations of Bangladesh"),
    dropdowns,
    datatable(
      fire_service,
      rownames = FALSE,
      escape = FALSE,
      options = list(
        pageLength = 20,
        lengthMenu = c(10, 20, 50, 100),
        scrollX = TRUE,
        dom = 'ltip',
        order = list(division_col_idx - 1, 'asc'),
        initComplete = JS(js_code)
      ),
      class = "cell-border stripe hover compact"
    )
  )
)
```


# School & Colleges

### District Wise School & Colleges 

```{r }
# ------------------- 1. READ DATA -------------------
school_service <- read.csv("~/Documents/Explore-Bangladesh/Datasets/bangladesh_school_colleges.csv",
                           stringsAsFactors = FALSE,
                           check.names = FALSE,
                           fileEncoding = "UTF-8")

# Fix column names as per your data
colnames(school_service) <- c("EIN", "Name", "District", "Area", "Link")
school_service <- school_service %>% select(-Link)
colnames(school_service) <- trimws(colnames(school_service))

# ------------------- 2. FIND EXACT COLUMNS -------------------
district_col_idx <- which(colnames(school_service) == "District")
area_col_idx     <- which(colnames(school_service) == "Area")

if(length(district_col_idx) == 0) stop("Column 'District' not found!")
if(length(area_col_idx) == 0)     stop("Column 'Area' not found!")

# ------------------- 3. BUILD MAPPING: District → Areas -------------------
district_area_map <- school_service %>%
  select(District, Area) %>%
  filter(!is.na(District), !is.na(Area), District != "", Area != "") %>%
  distinct() %>%
  group_by(District) %>%
  summarise(Areas = list(sort(unique(Area))), .groups = "drop")

# Convert to named list (no deframe needed)
district_area_map_list <- district_area_map$Areas
names(district_area_map_list) <- district_area_map$District

all_districts <- sort(unique(school_service$District))

# ------------------- 4. DROPDOWNS -------------------
dropdowns <- tags$div(
  style = "text-align:center; margin:25px 0; padding:18px; background:#f8f9fa; border-radius:12px;",
  tags$label("Filter Schools & Colleges:",
              style = "font-weight:bold; font-size:18px; margin-right:15px; color:#2c3e50;"),
  tags$select(id = "districtFilter",
              style = "width:280px; padding:10px; font-size:16px; border-radius:6px; border:1px solid #3498db; margin-right:15px;",
              tags$option(value = "", "All Districts"),
              lapply(all_districts, function(x) tags$option(value = x, x))
  ),
  tags$select(id = "areaFilter",
              style = "width:280px; padding:10px; font-size:16px; border-radius:6px; border:1px solid #3498db;",
              tags$option(value = "", "All Areas"))
)

# ------------------- 5. JAVASCRIPT (100% WORKING) -------------------
js_code <- sprintf("
  function(settings, json) {
    var table = this.api();
    var map = %s;  // District → [Areas]

    var $dist = $('#districtFilter');
    var $area = $('#areaFilter');

    function apply() {
      var selectedDist = $dist.val();
      var selectedArea = $area.val();

      // Column indices (0-based): District = 2, Area = 3
      table.column(2).search(selectedDist ? '^' + $.fn.dataTable.util.escapeRegex(selectedDist) + '$' : '', true, false);
      table.column(3).search(selectedArea ? '^' + $.fn.dataTable.util.escapeRegex(selectedArea) + '$' : '', true, false);
      table.draw();
    }

    $dist.on('change', function() {
      var dist = $(this).val();
      $area.empty().append('<option value=\"\">All Areas</option>');

      if (dist && map[dist]) {
        map[dist].forEach(a => $area.append('<option value=\"' + a + '\">' + a + '</option>'));
      } else {
        var all = Object.values(map).flat()
          .filter((v,i,a) => a.indexOf(v) === i)
          .sort();
        all.forEach(a => $area.append('<option value=\"' + a + '\">' + a + '</option>'));
      }
      $area.val('');
      apply();
    });

    $area.on('change', apply);

    // Initial fill
    (function() {
      var all = Object.values(map).flat()
        .filter((v,i,a) => a.indexOf(v) === i)
        .sort();
      all.forEach(a => $area.append('<option value=\"' + a + '\">' + a + '</option>'));
    })();

    apply();
  }
", toJSON(district_area_map_list, auto_unbox = TRUE))

# ------------------- 6. SHOW TABLE -------------------
browsable(
  tagList(
    tags$head(tags$style(HTML("
      body {font-family: 'Segoe UI', sans-serif; background:#f5f7fa; padding:20px;}
      h3 {color:#27ae60; text-align:center; font-size:32px; margin:20px;}
      .dataTables_wrapper {background:white; border-radius:12px; padding:20px; box-shadow:0 4px 20px rgba(0,0,0,0.1);}
    "))),
    tags$h3("Schools & Colleges of Bangladesh"),
    dropdowns,
    datatable(
      school_service,
      rownames = FALSE,
      escape = FALSE,
      options = list(
        pageLength = 15,
        lengthMenu = c(10, 15, 25, 50, 100),
        scrollX = TRUE,
        scrollY = "600px",           # Beautiful vertical scrolling
        scrollCollapse = TRUE,
        dom = 'l<"sep">tip',         # l = length menu, t = table, i = info, p = pagination
        order = list(2, 'asc'),
        initComplete = JS(js_code)
      ),
      class = "cell-border stripe hover compact",
      selection = "none"
    )
  )
)
```

# University List 

### Public University 

```{r }
public_university <- read.csv("~/Documents/Explore-Bangladesh/Datasets/public_universities.csv",
                   stringsAsFactors = FALSE, check.names = FALSE)
colnames(public_university) <- c("SL", "s", "University", "Website")
public_university <- public_university %>% 
  select(-c(SL,s))

datatable(
  public_university,
  rownames = FALSE,
  options = list(
    pageLength = 10,
    scrollX = TRUE,
    autoWidth = FALSE
  )
)

```
### Private University 

```{r }
private_university <- read.csv("~/Documents/Explore-Bangladesh/Datasets/private_university.csv",
                   stringsAsFactors = FALSE, check.names = FALSE)
colnames(private_university) <- c("SL", "s", "University", "Website")
private_university <- private_university %>% 
  select(-c(SL,s))

datatable(
  private_university,
  rownames = FALSE,
  options = list(
    pageLength = 10,
    scrollX = TRUE,
    autoWidth = FALSE
  )
)

```