lift autocomplete change page content - autocomplete

im using an auto complete widget to show required inputs to the user in a liftScreen. i need to change the content of the page with the selected option of the autocomplete.
Is it possible with autocomplete widget?
If it is please post an example.

Here is an example of Autocomplete and Ajax:
/*Create a ValueCell to update*/
val cell = ValueCell("")
/* Do a basic ajaxText */
val nameAjax = SHtml.ajaxText(cell.get, s=>{ cell.set(s); Noop})
/* Make attributes out of it */
val attrs: Seq[(String,String)] = nameAjax.attributes.toList.map{md => (md.key,md.value.text)}
/* Do the basic autocomplete with your attibutes */
def query(s:String):List[String] /*Do the query to get the desired autocomplete values */
def buildQueryName(current: String, limit: Int): Seq[String] = {
if (current.length == 0) Nil
else query(current).take(limit) /*query representing
}
private def processResult(s : String) {}
/* Function to render the autocomplete box */
def autoCompleteBox = AutoComplete("", buildQueryName _, processResult _ , attrs:_* )
/* function to render the dynamic part */
def dynamicPart = WiringUI.apply(cell)(createDynamicPart)
def createDynamicPart(value:String)(ns:NodeSeq):NodeSeq ={
<h3> value selected: {value} </h3>
}

Related

Writing error code and its string message: Scala

I am storing error code and its string message in this way:
object Error {
def FileNotFound(filename: String) = Error("ERR01", s"${filename} not found")
def UserNotExist(userName: String) = Error("ERR02", s"${userName} not exist")
}
case class Error(code: String, value: String) {}
Benefit of keeping it like this is that I can pass string value to error message.
And I am creating it like
def validate(data: SomeType): List[Error] = {
var errors = ListBuffer[Error]()
if (validation1("abc") == false) {
errors+= Error.FileNotFound("abc")
}
if (validation2("lmn") == false) {
errors+= Error.UserNotExist("lmn")
}
errors.toList
}
I am new to Scala and functional programming.
Is it right way to write error code like this?
Is it following functional programming paradigm?
Scala: 2.11
Here are my two cents with a full example.
I assume you want to do this in nice-and-easy functional style, so let's remove the mutable ListBuffer and see how to deal with it. The description of the steps are after the code.
UPDATE: I want to note that, in your code, the usage of ListBuffer is acceptable because it doesn't break rerefential transparency. This is because you don't expose its mutable nature outside the function and the output of the function depends only on its inputs.
Nonetheless I usually prefer to avoid using mutable data if not for specific reasons, like compactness or performance.
object StackOverflowAnswer {
/* Base type with some common fields */
class MyError( val code: String, val msg: String )
/* FileNotFound type, subtype of MyError, with its specific fields */
case class FileNotFound( filename: String ) extends MyError(
"ERR01", s"$filename not found"
)
/* UserDoesntExist type, subtype of MyError, with its specific fields */
case class UserDoesntExist( userName: String ) extends MyError(
"ERR01", s"$userName doesn't exist"
)
/*
* Validates the file. If it finds an error it returns a Some(MyError) with
* the error that's been found
* */
def checkForBadFile( data: String ): Option[MyError] =
if( data.contains("bad_file.txt") )
Some(FileNotFound("bad_file.txt"))
else
None
/*
* Validates the user. If it finds an error it returns a Some(MyError) with
* the error that's been found
* */
def checkForMissingUser( data: String ): Option[MyError] =
if( data.contains("bad_username") )
Some(UserDoesntExist("bad_username"))
else
None
/*
* Performs all the validations and returns a list with the errors.
*/
def validate( data: String ): List[MyError] = {
val fileCheck = checkForBadFile( data )
val userCheck = checkForMissingUser( data )
List( fileCheck, userCheck ).flatten
}
/* Run and test! */
def main( args: Array[String] ): Unit = {
val goodData = "This is a text"
val goodDataResult = validate( goodData ).map( _.msg )
println(s"The checks for '$goodData' returned: $goodDataResult")
val badFile = "This is a text with bad_file.txt"
val badFileResult = validate( badFile ).map( _.msg )
println(s"The checks for '$badFile' returned: $badFileResult")
val badUser = "This is a text with bad_username"
val badUserResult = validate( badUser ).map( _.msg )
println(s"The checks for '$badUser' returned: $badUserResult")
val badBoth = "This is a text with bad_file.txt and bad_username"
val badBothResult = validate( badBoth ).map( _.msg )
println(s"The checks for '$badBoth' returned: $badBothResult")
}
}
I start defining the type structure for the error, similar to your.
Then I have two functions that performs validations for each check you want. When they find an error, they return it using the Option type of Scala. If you're not familiar with Option, you can have a look at this link or do some googling.
Then I have the validation function that calls and store each the above single checks. The last bit is the use of flatten (doc here) that "flattens" List[Option[MyError]] into List[MyError], removing the middle Option.
Then there is the actual code that shows you some examples.

Scala Factory Design Pattern,what is "loose" coupling?

I am studying about the Factory Design Pattern in Scala.One of the benefits of this method is Loose Coupling between Object Creation logic and Client (from http://www.journaldev.com/10350/factory-design-pattern-in-scala). How can we achieve this and why we need loose coupling at all? Can someone give some examples and explain this?
As I understood you are looking for an example on Factory Pattern in Scala, you can find the usecase with some simple examples here
Factory pattern is more useful when creating API library classes (classes which can be used by other classes). Hope the below example will explain it clearly,
trait ContentAPI {
def getContentById(id : Int) : String
def getContentByTitle(title: String) : String
def getAllContent(title: String) : String }
object ContentAPI {
protected class ContentAPI(config: APIConfig) extends PageContentAPI {
/**
* get all content of a page parsing the page title
*
* #param query title parsed
* #return all content as a String
*/
override def getAllContent(query: String) : String = {
var pageContent: String = " Some text"
pageContent
}
/**
* get only the content body text parsing the page title
*
* #param query title parsed
* #return content as a String
*/
override def getContentByTitle(query: String) : String = {
var pageContent: String = " Some String "
pageContent
}
/**
* get only the content body text parsing the page id
*
* #param query id parsed
* #return content as a string
*/
override def getContentById(query: Int) : String
var pageContent: String = "some string"
pageContent
}
}
class APIConfig(path: String) {
val inputPath = path
}
/** Configuration object for the Content API */
object APIConfig {
protected class APIConfigBuilder(dataPath: String) {
def setDataPath(path: String): APIConfigBuilder = {
new APIConfigBuilder(path)
}
def getOrCreate(): APIConfig = {
new APIConfig(dataPath)
}
}
def withBuilder(): APIConfigBuilder = {
new APIConfigBuilder("")
}
}
def apply(config: APIConfig): ContentAPI = {
new ContentAPI(config)
}
}
/** Client Object */
object APIClient{
def main(args: Array[String]): Unit = {
import Arguments.WIKI_DUMP_BASE
val dataPath = "path"
val contentAPI = ContentAPI(APIConfig.withBuilder().setDataPath(dataPath).getOrCreate())
contentAPI.getAllContent("Anarchism").show()
contentAPI.getContentByTitle("Anarchism").show()
contentAPI.getContentById(12).show()
}
}

too many arguments for method apply: (car: play.api.data.Form[models.CarroFormData])

I have this error bellow and can't find the solution or how to debug what's being passed to apply.
Can anyone help?
too many arguments for method apply: (car:
play.api.data.Form[models.CarroFormData])(implicit messages:
play.api.i18n.Messages)play.twirl.api.HtmlFormat.Appendable in class
index
Controller Form
def add = Action { implicit request =>
CarroForm.form.bindFromRequest.fold(
// if any error in submitted data
errorForm => Ok(views.html.admin.index(errorForm, Seq.empty[Carro])),
data => repo.create(carro.name, carro.description, carro.img, carro.keywords).map { _ =>
// If successful, we simply redirect to the index page.
Redirect(routes.application.index)
})
}
This is the Model
package dal
import javax.inject.{ Inject, Singleton }
import play.api.db.slick.DatabaseConfigProvider
import slick.driver.JdbcProfile
import models._
import scala.concurrent.{ Future, ExecutionContext }
/**
* A repository for people.
*
* #param dbConfigProvider The Play db config provider. Play will inject this for you.
*/
#Singleton
class CarroRepository #Inject() (dbConfigProvider: DatabaseConfigProvider)(implicit ec: ExecutionContext) {
// We want the JdbcProfile for this provider
private val dbConfig = dbConfigProvider.get[JdbcProfile]
// These imports are important, the first one brings db into scope, which will let you do the actual db operations.
// The second one brings the Slick DSL into scope, which lets you define the table and other queries.
import dbConfig._
import driver.api._
/**
* Here we define the table. It will have a name of people
*/
private class CarroTable(tag: Tag) extends Table[Carro](tag, "carro") {
/** The ID column, which is the primary key, and auto incremented */
def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
/** The name column */
def name = column[String]("name")
/** The description column */
def description = column[String]("description")
/** The img column */
def img = column[String]("img")
/** The keywords column */
def keywords = column[String]("keywords")
/**
* This is the tables default "projection".
*
* It defines how the columns are converted to and from the Person object.
*
* In this case, we are simply passing the id, name and page parameters to the Person case classes
* apply and unapply methods.
*/
def * = (id, name, description, img, keywords) <> ((Carro.apply _).tupled, Carro.unapply)
}
/**
* The starting point for all queries on the people table.
*/
private val carro = TableQuery[CarroTable]
/**
* Create a person with the given name and age.
*
* This is an asynchronous operation, it will return a future of the created person, which can be used to obtain the
* id for that person.
*/
def create(name: String, description: String, img:String, keywords: String): Future[Carro] = db.run {
// We create a projection of just the name and age columns, since we're not inserting a value for the id column
(carro.map(p => (p.name, p.description, p.img, p.keywords))
// Now define it to return the id, because we want to know what id was generated for the person
returning carro.map(_.id)
// And we define a transformation for the returned value, which combines our original parameters with the
// returned id
into ((nameAge, id) => Carro(id, nameAge._1, nameAge._2, nameAge._3, nameAge._4))
// And finally, insert the person into the database
) += (name, description, img, keywords)
}
/**
* List all the people in the database.
*/
def list(): Future[Seq[Carro]] = db.run {
carro.result
}
}
package models
import play.api.data.Form
import play.api.data.Forms._
import play.api.libs.json._
case class Carro(id: Long, name:String, description:String, img:String, keywords:String)
case class CarroFormData(name: String, description: String, img: String, keywords: String)
object CarroForm {
val form = Form(
mapping(
"name" -> nonEmptyText,
"description" -> nonEmptyText,
"img" -> nonEmptyText,
"keywords" -> nonEmptyText
)(CarroFormData.apply)(CarroFormData.unapply)
)
}
object Carros {
var carros: Seq[Carro] = Seq()
def add(carros: Carro): String = {
carros = carros :+ carro.copy(id = carro.length) // manual id increment
"User successfully added"
}
def delete(id: Long): Option[Int] = {
val originalSize = carro.length
carro = carro.filterNot(_.id == id)
Some(originalSize - carro.length) // returning the number of deleted users
}
def get(id: Long): Option[Carro] = carro.find(_.id == id)
def listAll: Seq[Carro] = carro
implicit val carroFormat = Json.format[Carro]
}
View Code
#(car: Form[CarroFormData])(implicit messages: Messages)
#import helper._
#main(new Main("Car Dealers", "Compra e venda de carros", "logo.png", "carro, compra, venda")) {
<div class="container">
<h1>Hello</h1>
#form(routes.AdminCarro.add()) {
#inputText(person("name"))
#inputText(person("description"))
#inputText(person("img"))
#inputText(person("keywords"))
)
<div class="buttons">
<input type="submit" value="Add Car"/>
</div>
}
</div>
}
At your controller code:
def add = Action { implicit request =>
CarroForm.form.bindFromRequest.fold(
// if any error in submitted data
errorForm => Ok(views.html.admin.index(errorForm, Seq.empty[Carro])),
data => repo.create(carro.name, carro.description, carro.img, carro.keywords).map { _ =>
// If successful, we simply redirect to the index page.
Redirect(routes.application.index)
}
)
}
At the errorForm, you are calling the index view with two arguments:
Ok(views.html.admin.index(errorForm, Seq.empty[Carro]))
But your view declares just one argument:
#(car: Form[CarroFormData])(implicit messages: Messages)
Just remove the Seq.empty[Carro] from the call in your controller and everything should work as expected. If you still getting the same error, see if there are other places where this view is called the same wrong way (with two arguments) or try to sbt clean your project before sbt run.

How to override implicit Action val into Play framework 2

I need to override implicited values befor it pass to the template, but dont have idea how.
Something like this:
/* This Session User and City setup */
case class MySession(user: Option[User] = None, city: Option[City] = None) {}
/* Trait for Controllers */
trait CMySession {
implicit def mySession[A](implicit request: Request[A]) : MySession = {
val userOpt = /*... get from session user here ...*/
val cityOpt = /*... get from session city here ...*/
MySession(user = userOpt, city = cityOpt)
}
}
/* Controller */
def showCity(city_name: String) = Action { implicit request =>
// Get city
val cityOpt = { for (c <- mySession.city) yield Some(c) } getOrElse Cities.getByName(city_name)
// Check if NO City in session, but we get it from request
if (mySession.city != cityOpt) {
// NEED some how override implicited mySession value here for template?!
}
Ok(views.html.showCity())
}}
Thank you for any clues!
The great thing about implicit values in Scala is that you can override them, either by declaring your own implicit value in scope (in your case in the if block) or by passing it explicitly (in your case the template, e.g. views.html.showCity(session = myOtherSession)).

How to make a field READONLY in lift crudify

I have a field that I would like to be read-only and have a default value.
here what I have till now:
object passwd extends MappedString(this, 20)
{
override def defaultValue = "XXX" + Random.alphanumeric.take(12).mkString // some default value
// readOnly = true // Or something similar???
}
I tried overriding toHtml, asHtml, toForm, displayHtml but they all change the view or the label or something else.
I just want the defaultValue to be automatically generated (which works) but the users not to be able to edit that field when create/editing the entity.
Any advice would be very much appreciated
Got it,
Just override _toForm and disable the input element:
import net.liftweb.http.S
override def _toForm =
S.fmapFunc({s: List[String] => this.setFromAny(s)}){name =>
Full(<input disabled='disabled' type='text' id={fieldId} maxlength={maxLen.toString}
name={name}
value={is match {case null => "" case s => s.toString}}/>)}
The trait MappedField defines the methods writePermission_? and readPermission_?:
/**
* Given the current execution state, can the field be written?
*/
def writePermission_? = false
/**
* Given the current execution state, can the field be read?
*/
def readPermission_? = false
So you could just override these with
object passwd extends MappedString(this, 20) {
override def defaultValue = "XXX" + Random.alphanumeric.take(12).mkString // some default value
override writePermission_? = false
override readPermission_? = true
}
Is that what you're looking for?