You can use flood filling to color clicked areas bounded by your user-defined lines.
Let the user draw their lines on the canvas.
 
When the user clicks on a region bounded by lines, floodfill that region with a color.
 
Note: you must draw your gridlines underneath the canvas or else those gridlines will act as boundaries for the floodfill algorithm and you will just fill a grid cell.  You can use CSS to layer an image under your canvas or use a separate canvas to draw the gridlines.

Here's starting example code and a Demo:  http://jsfiddle.net/m1erickson/aY4Xs/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
    body{ background-color: ivory; }
    #canvas{border:1px solid red;}
</style>
<script>
$(function(){
    // canvas and mousedown related variables
    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var $canvas=$("#canvas");
    var canvasOffset=$canvas.offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;
    var scrollX=$canvas.scrollLeft();
    var scrollY=$canvas.scrollTop();
    // save canvas size to vars b/ they're used often
    var canvasWidth=canvas.width;
    var canvasHeight=canvas.height;
    // define the grid area
    // lines can extend beyond grid but
    // floodfill wont happen outside beyond the grid
    var gridRect={x:50,y:50,width:200,height:200}
    drawGridAndLines();
    // draw some test gridlines
    function drawGridAndLines(){
        ctx.clearRect(0,0,canvas.width,canvas.height)
        // Important: the lineWidth must be at least 5
        // or the floodfill algorithm will "jump" over lines
        ctx.lineWidth=5;
        ctx.strokeRect(gridRect.x,gridRect.y,gridRect.width,gridRect.height);
        ctx.beginPath();
        ctx.moveTo(75,25);
        ctx.lineTo(175,275);
        ctx.moveTo(25,100);
        ctx.lineTo(275,175);
        ctx.stroke();
    }
    // save the original (unfilled) canvas
    // so we can reference where the black bounding lines are
    var strokeData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);
    // fillData contains the floodfilled canvas data
    var fillData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);
    // Thank you William Malone for this great floodFill algorithm!
    // http://www.williammalone.com/articles/html5-canvas-javascript-paint-bucket-tool/
    //////////////////////////////////////////////
    function floodFill(startX, startY, startR, startG, startB) {
      var newPos;
      var x;
      var y;
      var   pixelPos;
      var   neighborLeft;
      var   neighborRight;
      var   pixelStack = [[startX, startY]];
      while (pixelStack.length) {
        newPos = pixelStack.pop();
        x = newPos[0];
        y = newPos[1];
        // Get current pixel position
        pixelPos = (y * canvasWidth + x) * 4;
        // Go up as long as the color matches and are inside the canvas
        while (y >= 0 && matchStartColor(pixelPos, startR, startG, startB)) {
          y -= 1;
          pixelPos -= canvasWidth * 4;
        }
        pixelPos += canvasWidth * 4;
        y += 1;
        neighborLeft = false;
        neighborRight = false;
        // Go down as long as the color matches and in inside the canvas
        while (y <= (canvasHeight-1) && matchStartColor(pixelPos, startR, startG, startB)) {
          y += 1;
          fillData.data[pixelPos]     = fillColor.r;
          fillData.data[pixelPos + 1] = fillColor.g;
          fillData.data[pixelPos + 2] = fillColor.b;
          fillData.data[pixelPos + 3] = 255;
          if (x > 0) {
            if (matchStartColor(pixelPos - 4, startR, startG, startB)) {
              if (!neighborLeft) {
                // Add pixel to stack
                pixelStack.push([x - 1, y]);
                neighborLeft = true;
              }
            } else if (neighborLeft) {
              neighborLeft = false;
            }
          }
          if (x < (canvasWidth-1)) {
            if (matchStartColor(pixelPos + 4, startR, startG, startB)) {
              if (!neighborRight) {
                // Add pixel to stack
                pixelStack.push([x + 1, y]);
                neighborRight = true;
              }
            } else if (neighborRight) {
              neighborRight = false;
            }
          }
          pixelPos += canvasWidth * 4;
        }
      }
    }
    function matchStartColor(pixelPos, startR, startG, startB) {
      // get the color to be matched
      var r = strokeData.data[pixelPos],
        g = strokeData.data[pixelPos + 1],
        b = strokeData.data[pixelPos + 2],
        a = strokeData.data[pixelPos + 3];
      // If current pixel of the outline image is black-ish
      if (matchstrokeColor(r, g, b, a)) {
        return false;
      }
      // get the potential replacement color
      r = fillData.data[pixelPos];
      g = fillData.data[pixelPos + 1];
      b = fillData.data[pixelPos + 2];
      // If the current pixel matches the clicked color
      if (r === startR && g === startG && b === startB) {
        return true;
      }
      // If current pixel matches the new color
      if (r === fillColor.r && g === fillColor.g && b === fillColor.b) {
        return false;
      }
      return true;
    }
    function matchstrokeColor(r, g, b, a) {
      // never recolor the initial black divider strokes
      // must check for near black because of anti-aliasing
      return (r + g + b < 100 && a === 255);  
    }
    // Start a floodfill
    // 1. Get the color under the mouseclick
    // 2. Replace all of that color with the new color
    // 3. But respect bounding areas! Replace only contiguous color.
    function paintAt(startX, startY) {
      // get the clicked pixel's [r,g,b,a] color data
      var pixelPos = (startY * canvasWidth + startX) * 4,
        r = fillData.data[pixelPos],
        g = fillData.data[pixelPos + 1],
        b = fillData.data[pixelPos + 2],
        a = fillData.data[pixelPos + 3];
      // this pixel's already filled
      if (r === fillColor.r && g === fillColor.g && b === fillColor.b) {
        return;
      }
      // this pixel is part of the original black image--don't fill
      if (matchstrokeColor(r, g, b, a)) {
        return;
      }
      // execute the floodfill
      floodFill(startX, startY, r, g, b);
      // put the colorized data back on the canvas
      ctx.putImageData(fillData, 0, 0);
    }
    // end floodFill algorithm
    //////////////////////////////////////////////
    // get the pixel colors under x,y
    function getColors(x,y){
        var data=ctx.getImageData(x,y,1,1).data;
        return({r:data[0], g:data[1], b:data[2], a:data[3] });
    }
    // create a random color object {red,green,blue}
    function randomColorRGB(){
        var hex=Math.floor(Math.random()*16777215).toString(16);
        var r=parseInt(hex.substring(0,2),16);
        var g=parseInt(hex.substring(2,4),16);
        var b=parseInt(hex.substring(4,6),16);
        return({r:r,g:g,b:b});    
    }
    function handleMouseDown(e){
      e.preventDefault();
      // get the mouse position
      x=parseInt(e.clientX-offsetX);
      y=parseInt(e.clientY-offsetY);
      // don't floodfill outside the gridRect
      if(
          x<gridRect.x+5 || 
          x>gridRect.x+gridRect.width ||
          y<gridRect.y+5 ||
          y>gridRect.y+gridRect.height
      ){return;}
      // get the pixel color under the mouse
      var px=getColors(x,y);
      // get a random color to fill the region with
      fillColor=randomColorRGB();
      // floodfill the region bounded by black lines
      paintAt(x,y,px.r,px.g,px.b);
    }
    $("#canvas").mousedown(function(e){handleMouseDown(e);});
}); // end $(function(){});
</script>
</head>
<body>
    <h4>Click in a region within the grid square.</h4>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
[ Info about getImageData and the pixel array ]
context.getImageData().data gets an array representing r,g,b & a values of the specified area of the canvas (in our case we selected the whole canvas).  The top-left pixel (0,0) is the first element(s) in the array.
Each pixel is represented by 4 sequential elements in the array.
The first array element holds the red component (0-255), the next element holds blue, the next holds green and the next holds the alpha (opacity).
// pixel 0,0
red00=data[0];
green00=data[1];
blue00=data[2];
alpha00=data[3];
// pixel 1,0
red10=data[4];
green10=data[5];
blue10=data[6];
alpha10=data[7];
Therefore, you jump to the red element of any pixel under the mouse like this:
// pixelPos is the position in the array of the first of 4 elements for pixel (mouseX,mouseY)
var pixelPos = (mouseY * canvasWidth + mouseX) * 4  
And you can get all 4 r,g,b,a values by getting the next 4 pixel array elements
var r = fillData.data[pixelPos];
var g = fillData.data[pixelPos + 1];
var b = fillData.data[pixelPos + 2];
var a = fillData.data[pixelPos + 3];