Gettin’ Sass-y with CSS

Cascading Style Sheets came into the world 19 years ago, which is coincidentally about the time I realized I could build my own websites and put them online. Since my formative years were largely dedicated to messing around on the internet, I put in a lot of practice writing CSS in junior high and high school. Like, a lot of practice. However–still, to this very day, when I write CSS and need to figure out why something doesn’t work, it often ends with my banging my head into the desk and reminding myself that “they’re called Cascading Style Sheets because they cascade.”

Here’s what’s up: the CSS I’ve been writing hasn’t really been much different than the CSS I was writing in high school. Sure, I knew of the existance of those fancy extensions/preprocessors, but I wasn’t about to actually use them. It’s just CSS. How fancy does it need to get?

Well, I was working on my little group management app, CoLeadr–remember that? And as I was writing up the CSS for the main dashboard view, it occurred to me that it would, in fact, be really awesome if I could use variables in my stylesheet. I tend to develop in black and white and add a color scheme in later, and I was starting to see that particular stylesheet becoming a pain in the butt. So I decided to check out a CSS preprocessor.

I chose Sass (Syntactically Awesome Stylesheets), for the very grown-up and professional reason that “sass” sounds a lot more fun than “less”. So I typed “sass” into Google, and Google knew exactly what I meant because Google is magic. One line in the terminal later, and I was up and running.

There’s actually two different types of Sass file: the original indented syntax .sass, and the more recent .scss, which is similar to CSS. Both get interpreted to CSS with a simple terminal command, or you can set it up to watch individual files or entire directories for changes, and Sass will automagically interpret to CSS whenever there’s an update. I’ve been writing .scss, so I don’t have to teach myself very many new syntactical tricks. I also keep a terminal window open specifically for being able to repeat this command:

toribrenneison$ sass sass/marketing_sassy.scss marketing.css

Using variables is super easy. Sass recognizes colors, numbers, booleans and strings as variable values. Variables are declared with a dollar sign (or–someone introduced me to this and I have been in love with it since–a bling) at the start of your Sass file, and can then be used anywhere in the rest of the file. When the file is processed to CSS, Sass will fill in the variable values for whatever CSS is being compiled, so this:

$body-background-color: #ffffff;
body { background-color: $body-background-color; }

Turns into this:

body { background-color: #ffffff; }

You can see how that would make a massive CSS file a lot more manageable when it comes to changing the values for things like colors, margins/padding, borders, and the like. Speaking of massive CSS files, Sass has some handy methods for splitting your Sass into manageable chunks. A partial Sass file _starts _with _an _underscore, and although they’re not generated into CSS files with the same magic, Sass was also kind enough to give us an @import command to bring those partials in and add them to the CSS file it compiles.

Sass also gives us mixins, which are like reuseable chunks of code. Let’s snag the example from Sass’s own website and say, for example, that you want to declare a border-radius value that will appear in several different places. Since it’s best practice to declare styles with several vendor prefixes (Google webkit, Mozilla, Microsoft, Opera) so that your code has the best chance of working in all browsers, typing can get tedious pretty quickly. With a Sass mixin, you can declare once (their example uses a variable for good measure):

@mixin border-radius($radius) {
-webkit-border-radius: $radius;
-moz-border-radius: $radius;
-ms-border-radius: $radius;
border-radius: $radius;
}

And use it anywhere:

.box { @include border-radius(10px); }

Which compiles to:

.box {
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
-ms-border-radius: 10px;
border-radius: 10px;
}

Something else that is totally amazing about Sass? Inheritance. Sass will let you nest your declarations, although you should beware of going too deep, which will lead to over-qualified CSS (I’m looking at you, Bootstrap). So you can nest a declaration for a line item or a link inside of the declaration for your navigation class, which keeps the Sass file easy to read. Straight-up inheritance also works: just use the @extend command, and you’ll be able to add on to already-existing declarations. To once again steal from Sass’s website, you can build “success” and “error” off of an existing “message” class:

.message {
border: 1px solid #ccc;
padding: 10px;
color: #333;
}
.success {
@extend .message;
border-color: green;
}
.error {
@extend .message;
border-color: red;
}

Will turn into:

.message, .success, .error {
border: 1px solid #cccccc;
padding: 10px;
color: #333;
}
.success {
border-color: green;
}
.error {
border-color: red;
}

Sass will also do some math for you, but since I’m terrible at math, I’ve left that alone. I like to use a grid system like Bootstrap/Foundation/Skeleton to do my layouts, so I don’t really need Sass to do crazy layout calculations for me, anyway–I can see the value in it, of course, but it’s not something I’m ready to try and use myself.

Would I recommend Sass to a friend? I certainly would, and I’m doing it right now. Perhaps, at some point, I’ll try and play around with Less. But for now, I’m getting Sass-y, and loving it.

You can find documentation and read more about Sass by visiting the official website: sass-lang.com.

So, I’m Building a Web App (Part Three: CheckBoxList(For) the Best)

After dealing with the dropdown fiasco in part two of my struggle to build a working ASP.NET MVC app, I worked on getting project functionality in place instead of continuing with the unsatisfactory method of adding and removing people from subgroups.

The thing is, though, that I knew the dropdown wasn’t a good fix.  Using the dropdown meant that a person could only be added or removed from one group at a time, and I had slung it together so that different views were needed for addition and removal.  It was pretty much the epitome of bad UX–clunky, frustrating, and there was absolutely no need for it to be as difficult as it was.

I got projects and stuff working, but the problem I ran into after that was that my code was super ugly.  It’d turned into spaghetti all over the place, tons of logic in the controllers, everything was a mess.  I wanted to go back and turn the dropdowns into checkboxes, but I was afraid to touch anything because I’d cobbled everything together in such a delicate fashion.  (That’s what happens when you’re learning and don’t really know what you’re doing, I guess.)

So, naturally, I decided I’d just start over again.  Open up a new project in Visual Studio and just start over.  Y’know.  I only have to present this project to potential employers in a week and a half, no big deal.

This was the third time that I’d written up the add/remove functionality and it went so much easier this time.  MVC has a lot of HTML helpers, but it lacks one to make model-based checkbox lists.  So some absolute angels wrote an extension called CheckBoxList(For), which you can find at http://mvccbl.com/ or, y’know, just install through NuGet Package Manager in Visual Studio, like a normal person.  It makes checkbox lists almost stupid easy, and I had my functionality up and running in a couple hours.  The first time I attempted to make it work, it took me a couple weeks.

I can’t stop playing with it.  The checkboxes are such a better experience than the dropdown, and since I need another checkbox list to add groups and members to projects, I’m actually looking forward to using CheckBoxList(For) again.  That’s right, a MVC extension has actually got me excited about checkboxes!

…in other, unrelated news, I had a dream about jQuery last night.  Sometimes I wonder what I’m doing with my life.

 

So, I’m Building A Web App (Part Two: Dropdown Fiasco)

In Part One, I introduced you guys to my personal project, a web app for leaders of small groups.  Now I want to provide you with gruesome details of how I snottily cried over attempting to make a dropdown list.

If you google “DropDownListFor MVC” or some variant thereof, you will actually get a half-billion search results from Stack Overflow, etc where people are wondering why their dropdown menu doesn’t work.  It turns out that making effective dropdown lists in ASP.NET MVC is really tough!  Like, really tough.  When I set out to change my text box to a dropdown, I thought, how hard can it actually be?  I’ve made dropdowns in HTML like, at least a dozen times. 

I don’t even remember what all I tried before blinding grasping the solution, but to be honest, I struggled with it for over a week.  Here’s my final word on how to make it work:

Step One:  Use a viewmodel.

Using a viewmodel makes life with dropdowns so much easier.  Actually, they make life in MVC much easier all over, because you can easily deal with “extra” data that you know you’ll need to include in your view, plus you won’t have superfluous data hanging around.  For me, this meant a viewmodel class that looks like this:
public class PersonGroupingViewModel
{
[Key]
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set;}
public virtual IList Memberships { get; set; }
public SelectList AllGroups { get; set; }
public int SelectedGroupId { get; set; }
}

I needed the ID of my Person object, the person’s first and last name, the list of groups they were a member of, and finally–here’s the important part for the dropdown–a SelectList of all the groups in the database and an int to store the ID of the selected group.

Step Two: Create a view that is strongly-typed to your viewmodel. 

You need your view to be strongly-typed to your viewmodel so that you can easily access the data fields in the viewmodel.  This part is kind of a no-brainer.

Step Three:  Populate your viewmodel in your controller and pass it off to the view.

Step three involved spinning up up a new instance of my viewmodel class and passing it off to the view instead of the domain model.  I also had to spin up a new SelectList with all of the groups available and make sure it was included in the viewmodel so that the dropdown would work.  I did it in the controller it shouldn’t matter if you do it in the default constructor for the viewmodel class:

SelectList allthegroups = new SelectList(db.Groups, "GroupId", "Name");

There are about eleven million constructors for SelectList objects, but the one I’m using here is SelectList(IEnumerable, String, String), which specifies list items and also assigns the data value field (GroupId) and data text field (Name).  This allows me to display the group names in the dropdown, but post the group ID back to the controller.  Set it to the appropriate property in the viewmodel (viewmodel.AllGroups = allthegroups;)  and off you go!

Step Four: Actually put that dropdown sucker in the view.

Now for the fun part!  This is where the magic happens:

<div class="form-group">
<label>Choose Group:</label>
@Html.DropDownListFor(model => model.SelectedGroupId, Model.AllGroups, "Select A Group")
</div>

DropDownListFor is an HTML helper than can be used with a strongly-typed model (in this case, the viewmodel).  What’s happening here is that the selected group will post back the value as SelectedGroupId, the dropdown will populate from the model SelectList named AllGroups, and the default selected value will just be a string called “Select A Group”.

Step Five: In the POST action, grab that sweet ID you got back from the dropdown and get to work.

I just grabbed the entire viewmodel back in the controller POST action and processed out the individual bits. Here’s the code to look up the person and group in the database, and perform the necessary person-into-group finagling:

int PersonId = viewmodel.PersonId;
int GroupId = viewmodel.SelectedGroupId;
Person person = db.People.Find(PersonId);
Group group = db.Groups.Find(GroupId);

group.Members.Add(person);
db.SaveChanges();

I cast off my viewmodel and spin a new one to pass back to the view, because in my app, a person can belong to more than one group.  This makes the group we just added show up on that view under a section called “Memberships”, and the person can then be added to another group.  It’s not the prettiest thing in the world and also not the best UX, but it’s good enough for now and will be revisited later.  The important part is that it works!

Stay tuned for part three, in which I tackle checkbox lists and cry about UX design.

So, I’m Building A Web App (Part One)

About three weeks ago, I started an ASP.NET MVC project.  What I’m attempting to do is build a web app that helps leaders of very small organizations (like a church small group or a scout troop) keep track of their members and projects.  For someone with a grand total of 4 weeks experience in C# and no real experience with model-view-controller architecture (I don’t think RailsBridge really counts), it was… not unambitious, I suppose.

Step one: get CRUD functionality for people and groups, and then functionality to add and remove people from groups.

At least, that was what step one was supposed to be.  I’m using Entity Framework (code-first) and the magic that was supposed to happen to set up my database + tables (pretty simple–Groups, People, join table for the many-to-many relationship between Groups and People) was just… not happening.  The entire first week and a half of my project time was dedicated to uninstalling and reinstalling SQL Server Express and trying to figure out a) why I could create databases in SQL Server Management Studio but did not have permissions to read/write to/from them anywhere else and b) why EF was refusing to cooperate with anything even vaguely related to data management.  Finally, I took my laptop to a friend who is an (ex) SQL DBA and, after futzing with it for over an hour, he finally hit upon that I was missing the SQLClient installer that allows SQL Server Express and everything else ever to talk to one another.  For some reason, it hadn’t downloaded and installed… still no clue what happened there, but hooray!  I finally had a working database and could do things!

Setting up CRUD actions with Entity Framework is stupid easy, so getting part one of step one ready to go went by fairly quickly.  I could create, read, update and delete (just in case you missed the acronym) people and groups, but now I had to somehow convince my app to put people into groups and take them out again.  Actually, to break down step one even further, I just had to get the people into groups.

Working with the MVC pattern when you only have a shaky grasp of what it actually is can be a little daunting (okay, a lot daunting).  I knew that I had a Person object, and a Group object, and the Person object had an ICollection<Group> called “Memberships” and the Group object had an ICollection<Person> called “Members”.  Now how did I get them to play nice?  I got it working (admittedly with some help from the prior-mentioned friend) so that the primary key (PersonId) of the Person into the view and inserted a text box so that the user could put in the primary key for the Group (GroupId) in.  This then passed back to the controller, which looked up the Person in the database and added them to the Group’s member list.  So, it worked, but it wasn’t nice.  No real user would remember the IDs of all their groups and use a text box, so I decided to do it with a dropdown menu.  Dropdown menus are easy, right?  Select a group, press a button, and off you go!

Not so much.  More on the dropdown fiasco  to come in Part Two…