Question

How to add a extra field in todo application created using Play framework using Scala? I am using anorm DB... I am getting an error named "not found: value Task" in Application.scala at line 24. I have tried it out, please point out my mistake. Thanks in advance!

task.scala:

package models

import anorm._
import anorm.SqlParser._
import play.api.db._
import play.api.Play.current


case class Task(id: Long, label: String, name: String)

object Task {
  val task = {
    get[Long]("id") ~ 
    get[String]("label") ~ 
    get[String]("name") map {
      case label~name => Task(id, name)
      case id~label => Task(id, label)
    }
  }

  def all(): List[Task] = DB.withConnection { implicit c =>
    SQL("select * from task").as(task *)
  }
  def create(task: Task): Unit= {
    DB.withConnection { implicit c =>
      SQL("insert into task (label,name) values ({label},{name})").on(
        'label -> label,
        'name  -> name
      ).executeUpdate()
    }
  }

  def delete(id: Long) {
    DB.withConnection { implicit c =>
      SQL("delete from task where id = {id}").on(
        'id -> id
      ).executeUpdate()
    }
  }
}

application.scala (controller class):

package controllers

import play.api._
import play.api.mvc._
import play.api.data._
import play.api.data.Forms._

import play.api.data.Form
import play.api.data.Forms.{tuple,nonEmptyText}
import play.api.mvc.{Action, Controller}
import anorm.NotAssigned

import models.Task

object Application extends Controller {
  def index = Action {
    Redirect(routes.Application.tasks)
  }
  val taskForm = Form(
    tuple(
      "label" -> nonEmptyText,
      "name" -> nonEmptyText
    )
  )

  def tasks = Action {
    Ok(views.html.index(Task.all(), taskForm))
  }
  def showTask= Action {
    Ok(views.html.test(Task.all(), taskForm))
  }

  def newTask = Action { implicit request =>
    taskForm.bindFromRequest.fold(
      errors => BadRequest(views.html.index(Task.all(), errors)),
      {
        case (label, name) => {
          Task.create(Task(NotAssigned, label, name))
          Redirect(routes.Application.showTask)
        }
      }
    )
  }

  def deleteTask(id: Long) = Action {
    Task.delete(id)
    Redirect(routes.Application.showTask)
  }
}

Index (view file):

@(tasks: List[Task], taskForm: Form[(String, String)])

@import helper._

<h2>Add a new task</h2>

@form(routes.Application.newTask) {

  @inputText(taskForm("label")) 
  @inputText(taskForm("name"))

  <input type="submit" value="Create">
}

test.html (view file 2):

@(tasks: List[Task], taskForm: Form[(String,String)])

@import helper._

@main("Todo list") {
  <h1>@tasks.size task(s)</h1>

  <ul>
    @tasks.map { task =>
      <li>
        <b>@task.label</b>
        <b>@task.name</b>

        @form(routes.Application.deleteTask(task.id)) {
          <input type="submit" value="Delete">
        }
      </li>
    }
  </ul>  
}
Was it helpful?

Solution

Try to use :

(apply) and (unapply)

methods properly for form element.

(Task.apply)(Task.unapply)

OTHER TIPS

import models.Task._ imports all the methods on the companion object models.Task into the current scope, not the Task class and object themselves. So the current code would allow you to just call all and it would refer to Task.all

Change the import to import models.Task to instead get Task into the scope in your Application object and you will be able to use the task methods like you are trying to.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top