Trying to avoid imperative code

In that case I would generalize a bit and consider an arbitrary list of fields and work with that. You could have a data type that keeps track of the field that is being edited with an integer:

data Node = Node (Maybe Int) [Field]

Then you can write a draw function something like this:

drawNode :: Node -> IO ()
drawNode (Node Nothing fields) = mapM_ drawField fields
drawNode (Node (Just n) fields) = do
  mapM_ drawField before
  drawEditField x
  mapM_ drawField after
  where
    (before, x : after) = Data.List.splitAt n fields

drawField :: Field -> IO ()
drawField = _

drawEditField :: Field -> IO ()
drawEditField = _