Listing all the employees
Edit source\empcontrol.d and add this code:
void getAllEmployees()
{
Employee[] emps = empModel.getEmployees;
render!("emplistall.dt", emps);
}
Now, that’s a very simple method. Two lines!
But it is calling the empModel.getEmployees() method, which we haven’t written yet, and also needs the emplistall.dt file, which we haven’t created yet, so let’s resolve that.
First, let’s define the getEmployees() method at the end of source\empmodel.d:
Employee[] getEmployees()
{
Employee[] emps;
string sql = "select * from employees";
Row[] rows = conn.query(sql).array;
if(rows.length == 0) return emps;
return prepareEmployees(rows);
}
This method returns all the records in the table. But this method calls the prepareEmployees() method, so let’s define it.
Employee[] prepareEmployees(Row[] rows)
{
Employee[] emps;
foreach(row; rows)
{
Employee e = prepareEmployee(row);
emps ~= e;
}
return emps;
}
This method in turn calls the prepareEmployee() (singular, no ‘s’) method, so let’s define that too.
Employee prepareEmployee(Row row)
{
Employee e;
e.id = to!int(to!string(row[0]));
e.empid = to!string(row[1]);
e.deprt = to!string(row[2]);
e.paygd = to!string(row[3]);
e.email = to!string(row[4]);
e.pword = to!string(row[5]);
e.fname = to!string(row[6]);
e.lname = to!string(row[7]);
e.phone = to!string(row[8]);
e.photo = to!string(row[9]);
e.street = to!string(row[10]);
e.city = to!string(row[11]);
e.province = to!string(row[12]);
e.postcode = to!string(row[13]);
return e;
}
You should make sure the order of fields in prepareEmployee() follows the order of fields in the MySQL employees table. Sometimes MySQL does not save the fields in the same order as in your SQL CREATE TABLE statement. Check the Schemas view of MySQL Browser.

Now let’s create views\emplistall.dt.
extends layout
block maincontent
include csstable.dt
div.table-wrapper
table
tr
th Employee Id
th First name
th Last name
th Department
th Phone number
th Email address
th Street address
th City
th Province
th PostCode
th Action
-foreach(e; emps)
tr
td #{e.empid}
td #{e.fname}
td #{e.lname}
td #{e.deprt}
td #{e.phone}
td #{e.email}
td #{e.street}
td #{e.city}
td #{e.province}
td #{e.postcode}
td
form.form-hidden(method="get", action="edit_employee")
input(type="hidden", name="id", value="#{e.id}")
input(type="image", src="images/pencil.ico", height="15px")
|
form.form-hidden(method="get", action="delete_employee")
input(type="hidden", name="id", value="#{e.id}")
input(type="image", src="images/trash.ico", height="15px")
|
As mentioned before, we can mix D code inside a Diet template file with – (hyphen)
Remember that we passed an Employee array emps to the template views\emplistall.dt:
void getListEmployees()
{
Employee[] emps = empModel.getEmployees;
render!("emplistall.dt", emps);
}
Hence, we can inject this code:
-foreach(e; emps)
which will iterate through all of emps, which is an array of Employees, with e representing the current Employee record being processed inside the loop.
To display the value of a variable passed to the template, we use the construct #{variable}. This is equivalent to JSP’s <%= variable %> construct.
Hence the line
td #{e.deprt}
means display the value of e.deprt inside that table cell.
And here is views\csstable.dt which is needed by emplistall.dt.
:css
.table-wrapper
{
margin: 20px auto;
border-radius: 20px;
}
table
{
margin: 0 auto;
padding: 20px 0;
border-collapse: collapse;
background-color: #eff;
}
table td, table th
{
border: 1px solid black;
margin: 0;
padding: 0 5px;
}
.no-border
{
border: 0;
}
Compile and run the app and refresh the browser. Click on New employee again and add another employee, then click the Submit button.
And after adding some employees, you should see this:

I got the icons for the pencil and the trash bin by simply googling for ‘pencil icon’ and ‘trash bin icon’ and saving the icons into the \public\images\ folder.
In the views\emplistall.dt file, we have these lines
input(type="image", src="images/pencil.ico", height="15px")
input(type="image", src="images/trash.ico", height="15px")
so save and name the icon files in the \public\images\ folder with the same names.
Add more sample records by clicking on the Add employee link after each submission.
So here is the full source\empmodel.d so far:
module empmodel;
import mysql;
import std.conv;
import std.array;
struct Employee
{
int id; //row id or record id
string empid; //employee number
string deprt; //department
string paygd; //salary grade
string email; //email address
string pword; //password
string fname; //first name
string lname; //last name
string phone; //phone number
string photo; //ID photo
string street; //street address
string city; //city name
string province; //province name
string postcode; //postal code
}
struct Admin
{
string email; //email address
string pword; //passsword
}
string[] departments =
[
"Management and Admin",
"Accounting and Finance",
"Production",
"Maintenance",
"Shipping and Receiving",
"Purchasing and Supplies",
"IT Services",
"Human Resources",
"Marketing"
];
string[][] provinces =
[
["AB", "Alberta"],
["BC", "British Columbia"],
["MB", "Manitoba"],
["NB", "New Brunswick"],
["NL", "Newfoundland and Labrador"],
["NS", "Nova Scotia"],
["NT", "Northwest Territories"],
["NU", "Nunavut"],
["ON", "Ontario"],
["PE", "Prince Edward Island"],
["QC", "Quebec"],
["SK", "Saskatchewan"],
["YT", "Yukon Territory"]
];
string[] paygrades =
[
"A100", "A200", "A300", "A400",
"B100", "B200", "B300", "B400",
"C100", "C200", "C300", "C400",
"D100", "D200", "D300", "D400",
"E100", "E200", "E300", "E400",
"F100", "F200", "F300", "F400"
];
class EmployeeModel
{
Connection conn;
this()
{
string url = "host=localhost;port=3306;user=owner;pwd=qwerty;db=empdb";
conn = new Connection(url);
scope(exit) conn.close;
}
ulong addEmployee(Employee e)
{
string sql =
"insert into employees
(
empid,
deprt, paygd, email, pword,
fname, lname, phone, photo,
street, city, province, postcode
)
values(?,?,?,?,?,?,?,?,?,?,?,?,?)";
Prepared pstmt = conn.prepare(sql);
pstmt.setArgs
(
to!string(e.empid),
to!string(e.deprt),
to!string(e.paygd),
to!string(e.email),
to!string(e.pword),
to!string(e.fname),
to!string(e.lname),
to!string(e.phone),
to!string(e.photo),
to!string(e.street),
to!string(e.city),
to!string(e.province),
to!string(e.postcode)
);
return conn.exec(pstmt);
}
Employee[] getEmployees()
{
Employee[] emps;
string sql = "select * from employees";
Row[] rows = conn.query(sql).array;
if(rows.length == 0) return emps;
return prepareEmployees(rows);
}
Employee[] prepareEmployees(Row[] rows)
{
Employee[] emps;
foreach(row; rows)
{
Employee e = prepareEmployee(row);
emps ~= e;
}
return emps;
}
Employee prepareEmployee(Row row)
{
Employee e;
e.id = to!int(to!string(row[0]));
e.empid = to!string(row[1]);
e.deprt = to!string(row[2]);
e.paygd = to!string(row[3]);
e.email = to!string(row[4]);
e.pword = to!string(row[5]);
e.fname = to!string(row[6]);
e.lname = to!string(row[7]);
e.phone = to!string(row[8]);
e.photo = to!string(row[9]);
e.street = to!string(row[10]);
e.city = to!string(row[11]);
e.province = to!string(row[12]);
e.postcode = to!string(row[13]);
return e;
}
}
And here is the full source\empcontrol.d file so far:
module empcontrol;
import vibe.vibe;
import empmodel;
class EmployeeController
{
private EmployeeModel empModel;
private string realm = "The Lorem Ipsum Company";
this()
{
empModel = new EmployeeModel;
}
void index()
{
render!("index.dt");
}
void getAddEmployee()
{
render!("empadd.dt", departments, paygrades, provinces);
}
void postAddEmployee(Employee e)
{
import std.file;
import std.path;
import std.algorithm;
import vibe.http.auth.digest_auth;
auto pic = "picture" in request.files;
if(pic !is null)
{
string photopath = "none yet";
string ext = extension(pic.filename.name);
string[] exts = [".jpg", ".jpeg", ".png", ".gif"];
if(canFind(exts, ext))
{
photopath = "uploads/photos/" ~ e.fname ~ "_" ~ e.lname ~ ext;
string dir = "./public/uploads/photos/";
mkdirRecurse(dir);
string fullpath = dir ~ e.fname ~ "_" ~ e.lname ~ ext;
try moveFile(pic.tempPath, NativePath(fullpath));
catch (Exception ex) copyFile(pic.tempPath, NativePath(fullpath), true);
}
e.photo = photopath;
}
if(e.phone.length == 0) e.phone = "(123) 456 7890";
if(e.paygd.length == 0) e.paygd = "none yet";
if(e.postcode.length == 0) e.postcode = "A1A 1A1";
e.pword = createDigestPassword(realm, e.email, e.pword);
empModel.addEmployee(e);
redirect("all_employees");
}
void getAllEmployees()
{
Employee[] emps = empModel.getEmployees;
render!("emplistall.dt", emps);
}
}
Now let’s implement the editing of records to make the pencil icon functional.
Last updated