Friday, July 21, 2017

Colorful serialization

I was writing some code to serialize a C# class to JSON and needed to export a System.Drawing.Color field as a hex string. Thankfully it's easy to customize the output using Json.NET. I created the following custom converter to save colors as hex strings (like #FFF0B6)

public class ColorHexConverter : JsonConverter {
 
 public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
  var color = (Color)value;
  var hexString = color.IsEmpty ? string.Empty : string.Concat("#", (color.ToArgb() & 0x00FFFFFF).ToString("X6");
  writer.WriteValue(hexString);
 }
 
 public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
  var hexString = reader.Value.ToString();
  if (hexString == null || !hexString.StartsWith("#")) return Color.Empty;
  return ColorTranslator.FromHtml(hexString);
 }
 
 public override bool CanConvert(Type objectType) {
  return objectType == typeof(Color);
 }
}

And example usage:

[JsonConverter(typeof(ColorHexConverter))]
public Color BackgroundColor;

Monday, March 13, 2017

Exclusive checkbox column

We had a customer that had a checkbox grid and wanted the checkboxes in one of the rows to be exclusive (e.g. when checked no other items in that column are checked). Most survey platforms have this functionality for a multiple choice checkbox question but not for columns in a checkbox grid. Some quick jQuery and JavaScript coding I had the following mostly generic function working.

$(function() {
  // Get the row with None or None of the above.
  var row = $('.sg-table tbody th:contains("None")').parent();
   
  // Find all of the checkboxes in that row and add a click event handler to them
  row.find(":input").each(function() {
    $(this).click(function() {
      // Get the index of the checkbox so you can change the other checkboxes in the same column.
      var index = $(this).parent().index() + 1;
      var selector = ".sg-table tbody tr td:nth-child("+index+") input:checkbox";
       
      // If the None of the above is being checked clear and disable the other checkboxes in the col.
      // Otherwise just re-enable them.
      if (this.checked) {
        $(selector).not(this).each(function() {
          this.checked = false;
          this.disabled = true;
        });
      } else {
        $(selector).not(this).each(function() {
          this.disabled = false;
        });
      }
    });
  });
});
Working demo: JSFiddle