Turning a list-based todo into a table-based version

Following on from my query around HTML5 forms and date attributes, I am looking for a few suggestions as to how the think through a small application to be used to manage SIM cards. The SIM cards have to be recorded as they are acquired and activated, allocated to end-users, and at some point when no longer required, they have to be de-allocated for re-issue, or cancelled with the supplying telco.

This is a real requirement, though what follows is not necessarily the answer to those questions. What I’m trying to do is use this more as a real world example, that I can base my own learning on.

I did a two day JS course last September, during which, we were guided through the creation of a todo list based on the use of jQuery. It’s quite a simple little app in every way, but I was wondered whether I could base this SIM card app on that general concept. I’ve taken that code and begun to make a few changes to it (extra input fields & a few minor CSS tweaks so far) - see Codepen

What I’d like to do to it is as follows:

  • Convert the list based display it currently has into a tabular form
  • Pickup the current date as new records are created
  • Create a pop-up for adding user details when the ‘Allocate SIM Card’ button is clicked
  • Look at some in-browser validation techniques to limit the amount of garbage making its way to the back-end
  • The list itself, needs to be sorted by oldest date first

For the purposes of this exercise, any data can be held either in local storage or arrays - it doesn’t matter which I don’t think.

I think what I’m after here is less about what the code has to look like, but more understanding the thought process of what I’d like it to do. The end-result just needs to come out looking as if it could be implemented. The code itself could be the worst piece of technical debt on the planet, so long as I can learn something from getting it to look and behave in an orderly fashion on screen.

On the off-chance any of this makes sense, I’m all ears.

Oh, and the Codepen only currently feeds of that date input field - none of the other inputs fields are linked to anything yet, though you can see what they’re intended for.

You might want to use es6 template strings for generating the html.

var makeRow = function(item) {
  return `
  <tr>
    <td>${ item.date }</td>
    <td>${ item.provider }</td>
  </tr>
  `
}

I’d suggest using the moment library if you’re dealing with dates, it really simplifies things. but to get the current date you can simply create a new Date()

For validation html5 input types and patterns should work, the <form> and inputs have a checkValidity method which will return true or false you can use.

The popup will be mostly styling the existing form you have, it’s a singular form in a div that you can hide/show appropriately.

use https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort for sorting an array

The most important thing to update is to get the data structure right

Replace var strings = []; with something more like this:

var todos = [{
  accountNumber: '1234567',
  mobileNumber: '0476123456',
  provider: 'AT&T',
  dateAdded: new Date(),
  completed: false
}]

The ideal is to be able to re-render the view based on that data at any time, from there it’s just a matter of updating the data when things change and responding to events.

2 Likes

Thanks for that @markbrown4

I’m good on the HTML5 validation side of things. I can sort that out once I know I can get data in/out of the array and present it on screen.

The ES6 template idea looks to be very relevant. Am I right in thinking it’s doing something similar to what little bits of HandlebarsJS & Moustache I’ve seen? From what I can see though, it should be straightforward enough to be able to replicate enough <td> cells to utilise what ends up in the array, on which subject…

Taking that as an example then, I could presumably create an empty array as my data structure something like this (I’ve added a couple of extra fields I’ll need.

var todos = [{
  accountNumber: '',
  mobileNumber: '',
  simId: '',
  provider: '',
  activatedDate: '',
  dateAdded: new Date(),
  completed: false
}]

Can I then take that as what effectively becomes a template for my data array, or do I need to do something a little different to set it up for reuse?

I ended up creating an array based around an object constructor. That seems to work well enough when viewed in the console. All except the boolean value which isn’t being reported back for some reason - it’s not causing any errors though.

Now to work out how to hook it up to the <td> template.

function SimCard(acct,mobNum,simId,telco,activated,added,completed) {
  this.acct = acct;
  this.mobNum = mobNum;
  this.simId = simId;
  this.telco = telco;
  this.activated = activated;
  this.added = added;
  this.completed = completed;
}

var sim = [];

sim[0] = new SimCard('xyz0001','503245001','att1234560','AT&T','2015-11-20','2015-11-21',false);
sim[1] = new SimCard('xyz0002','504245002','att1234561','AT&T','2015-12-25','2015-12-25',false);
sim[2] = new SimCard('xyz0003','506245003','att1234562','AT&T','2015-12-29','2016-01-01',false);
sim[3] = new SimCard('xyz0004','555245004','btx1234560','BT','2016-02-12','2016-02-14',false);
sim[4] = new SimCard('xyz0005','506245005','o2x4446661','O2','2016-03-18','2016-04-20',false);
sim[5] = new SimCard('xyz0006','505245006','ora3453452','Orange','2016-01-07','2016-03-28',false);

Yep, Handlebars and Moustache are more powerful but if you just need string interpolation template strings will do fine. It’s just joining strings together.

var makeRow = function(item) {
  return "<tr><td>" + item.dateAdded + "</td><td>" + item.mobileNumber  + "</td></tr>";
}

Assuming you have the makeRow function I provided earlier that’s the easy part. Put this in a render function that you can call whenever the data in the todos change.

$('#my-table').html(todos.map(makeRow).join(''));

Here’s a complete example

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title></title>
</head>
<body>
<table id="my-table"></table>
<script src="https://code.jquery.com/jquery-2.2.3.min.js" integrity="sha256-a23g1Nt4dtEYOj7bR+vTu7+T8VP13humZFBJNIYoEJo=" crossorigin="anonymous"></script>
<script type="text/javascript">
var todos = [{
  dateAdded: new Date(),
  mobileNumber: '0412 345 678'
},{
  dateAdded: new Date(),
  mobileNumber: '0487 654 321'
}];

var makeRow = function(item) {
  return `
  <tr>
    <td>${ item.dateAdded }</td>
    <td>${ item.mobileNumber }</td>
  </tr>
  `
}

var render = function() {
  var html = todos.map(makeRow).join('');
  $('#my-table').html(html);
}
render();
</script>
</body>
</html>

I don’t see a point of the constructor function to be honest, just add/edit literal objects in the array. Constructor functions are only useful when you have other functions on the prototype.

Thanks for all that - very useful. As ever though, I’m reading from the office, not in front of a code editor and the various files I have. I’ll get to looking at things in detail later in the day. :slight_smile:

This points heavily to my relatively low level of JS skills at this point in time. Right now, I’m don’t necessarily have enough experience to understand when one approach might be preferred to another.

In this instance, my understanding suggests that a literal object is a fairly singular thing - as in, if I need more than one row in my table, I’d need to create more than one literal object to be able to populate it, which didn’t seem very DRY. The constructor object looked like it would help me create an array, where each item within it would conform to a standard template, and could be iterated through.

Looking at this snippet of your code, I’ve got a better idea of what your were getting at in your initial response. It does look like it could get a little cumbersome quite quickly if I’m not careful, but I do need to keep in mind that what I’m doing this array is substituting for a database and the queries & back-end code that would go with it.

Thanks for the time you’ve spent on this so far, it’s much appreciated.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.