How to make an a responsive table grid with alphabetical ordered columns

I’ve been able to get the letters on the page like this. Still working on getting the terms for each letter. Everything I try is undefined.

letterGroups: computed("terms.[]", function() {

  let groups = [];

  console.log(groups)
  // "a" is ascii code 97. "z" is 122.
  for (let letterIndex = 97; letterIndex < 123; letterIndex++) {
    let letter = String.fromCharCode(letterIndex);

    groups.push({
      letter,
      terms: this.terms === letter
    });
  }
  return groups;
})
});

Got it.

letterGroups: computed("terms.[]", function() {
  let groups = [];

  // "a" is ascii code 97. "z" is 122.
  for (let letterIndex = 97; letterIndex < 123; letterIndex++) {
    let letter = String.fromCharCode(letterIndex);
    const match = letter.toLowerCase();
    groups.push({
      letter,
      terms: this.terms.filter(t => t.term.toLowerCase()[0] === match)
    });
  }
  return groups;
})
});

For anyone that finds this in the future, the final code ended up looking like this (using pods and TailwindCSS)…

// app/pods/components/alpha-grid/component.js

import Component from "@ember/component";
import { computed } from "@ember/object";

export default Component.extend({

  rows: computed("terms.[]", function() {
    let terms = this.terms;
    let columns = Math.floor(this.element.getBoundingClientRect().width / 175 );
    let itemsPerColumn = Math.ceil(terms.length / columns);

    let rows = [];
    for (let rowNumber = 0; rowNumber < itemsPerColumn; rowNumber++) {
      let row = [];
      for (let i = rowNumber; i < terms.length; i+= itemsPerColumn) {
        row.push(terms.objectAt(i));
      }
      rows.push(row);
    }
    return rows;
  }),

  handleResize() {
    this.notifyPropertyChange("rows");
  },
  didInsertElement() {
    this.handleResize = this.handleResize.bind(this);
    window.addEventListener("resize", this.handleResize);
  },
  willDestroyElement() {
    window.removeEventListener("resize", this.handleResize);
  }
});
{{!-- app/pods/components/alpha-grid/template.js }}
{{#each rows as |row|}}
	<div class="alpha-grid">
		{{#each row as |item|}}
			<div class="alpha-item"><a class="text-blue-light text-sm no-underline" href="{{href-to "terms.letter.term_id" item.letter item.id}}">{{item.term}}</a></div>
		{{/each}}
	</div>
{{/each}}
// app/pods/components/letter-groups/component.js

import Component from "@ember/component";
import { computed } from "@ember/object";

export default Component.extend({

letterGroups: computed("terms.[]", function() {
  let groups = [];

  // "a" is ascii code 97. "z" is 122.
  for (let letterIndex = 97; letterIndex < 123; letterIndex++) {
    let letter = String.fromCharCode(letterIndex);
    const match = letter.toLowerCase();
    groups.push({
      letter,
      terms: this.terms.filter(t => t.term.toLowerCase()[0] === match)
    });
  }
  return groups;
})
});
{{!-- app/pods/components/letter-groups/template.hbs }}

{{#each letterGroups as |group|}}
  <h2 class="capitalize">{{group.letter}}</h2>
  {{alpha-grid terms=group.terms}}
{{/each}}
{{!-- app/pods/disciplines/template.hbs }}

{{letter-groups terms=model.terms}}
// app/tailwind/utilities/your-utility.css

.alpha-grid {
  display: flex;
}

.alpha-item {
  min-width: 175px;
  max-width: 175px;
  padding: 8px;
}

Hope this helps somebody out there :slight_smile:

2 Likes