diff --git a/combo/example/.gitignore b/combo/example/.gitignore
new file mode 100644
index 0000000..eeea5d1
--- /dev/null
+++ b/combo/example/.gitignore
@@ -0,0 +1,3 @@
+.ensime_cache
+ensime-langserver.log
+pc.stdout.log
\ No newline at end of file
diff --git a/combo/example/build.sbt b/combo/example/build.sbt
new file mode 100644
index 0000000..7b9618a
--- /dev/null
+++ b/combo/example/build.sbt
@@ -0,0 +1,87 @@
+//##################################################################
+//##
+//## Build settings
+//##
+//##############
+
+lazy val projectSettings = Seq(
+ organization := "net.liftweb",
+ version := "0.9.4-SNAPSHOT",
+ name := "demo",
+ scalaVersion := "2.12.7",
+ scalacOptions ++= Seq("-unchecked", "-deprecation"),
+ autoAPIMappings := true
+)
+
+lazy val meta = (project in file("."))
+ .enablePlugins(JettyPlugin)
+ .enablePlugins(BuildInfoPlugin)
+ .settings(projectSettings: _*)
+ .settings(
+ buildInfoKeys := Seq[BuildInfoKey](name, version, scalaVersion, sbtVersion),
+ buildInfoKeys ++= Seq[BuildInfoKey](
+ BuildInfoKey.action("buildTime") {
+ System.currentTimeMillis
+ } // re-computed each time at compile
+ ),
+ buildInfoPackage := "net.liftweb.example.lib"
+ )
+
+//##
+//##
+//##################################################################
+
+//##################################################################
+//##
+//## Resolvers
+//##
+//##############
+
+
+resolvers ++= Seq("snapshots" at "https://oss.sonatype.org/content/repositories/snapshots",
+ "staging" at "https://oss.sonatype.org/content/repositories/staging",
+ "releases" at "https://oss.sonatype.org/content/repositories/releases"
+)
+
+//##
+//##
+//##################################################################
+
+//##################################################################
+//##
+//## Dependencies
+//##
+//##############
+
+libraryDependencies ++= {
+ val liftVersion = "3.3.0"
+ Seq(
+ "net.liftweb" %% "lift-webkit" % liftVersion,
+ "net.liftweb" %% "lift-json" % liftVersion,
+ "net.liftweb" %% "lift-db" % liftVersion,
+ "net.liftweb" %% "lift-mapper" % liftVersion,
+
+ "net.liftmodules" %% "fobo-twbs-bootstrap4-api_3.3" % "2.1.1",
+ "net.liftmodules" %% "widgets_3.1" % "1.6.0-SNAPSHOT",
+ "net.liftmodules" %% "textile_3.1" % "1.4-SNAPSHOT",
+
+ "org.webjars" % "bootstrap" % "4.2.1",
+ "org.webjars" % "jquery" % "3.3.1",
+ "org.webjars" % "jquery-migrate" % "1.4.1",
+ "org.webjars" % "popper.js" % "1.14.6",
+ "org.webjars" % "font-awesome" % "5.6.1",
+ "org.webjars" % "highlightjs" % "9.6.0",
+
+ "org.eclipse.jetty" % "jetty-webapp" % "8.1.7.v20120910" % "test",
+ "junit" % "junit" % "4.10" % "test",
+ "ch.qos.logback" % "logback-classic" % "1.2.3",
+ "org.specs2" %% "specs2-core" % "3.8.6" % "test",
+ "org.specs2" %% "specs2-matcher-extra" % "3.8.6" % "test",
+ "org.specs2" %% "specs2-junit" % "3.8.6" % "test",
+ "com.h2database" % "h2" % "1.3.167"
+ )
+}
+
+//##
+//##
+//##################################################################
\ No newline at end of file
diff --git a/combo/example/project/build.properties b/combo/example/project/build.properties
new file mode 100644
index 0000000..c46277f
--- /dev/null
+++ b/combo/example/project/build.properties
@@ -0,0 +1 @@
+sbt.version=1.2.7
\ No newline at end of file
diff --git a/combo/example/project/plugins.sbt b/combo/example/project/plugins.sbt
new file mode 100644
index 0000000..6cc81ca
--- /dev/null
+++ b/combo/example/project/plugins.sbt
@@ -0,0 +1,4 @@
+addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.0.1")
+addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "5.2.2")
+addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.9.0")
+addSbtPlugin("org.ensime" % "sbt-ensime" % "2.5.1")
diff --git a/combo/example/src/main/scala/bootstrap/liftweb/Boot.scala b/combo/example/src/main/scala/bootstrap/liftweb/Boot.scala
index 1637964..6c4485e 100644
--- a/combo/example/src/main/scala/bootstrap/liftweb/Boot.scala
+++ b/combo/example/src/main/scala/bootstrap/liftweb/Boot.scala
@@ -16,40 +16,49 @@
package bootstrap.liftweb
import net.liftweb._
-import common.{Box, Full, Empty, Failure, Loggable}
+import common.{Box, Empty, Failure, Full, Loggable}
import util.{Helpers, NamedPF, Props}
import http._
import actor._
import provider._
import sitemap._
import Helpers._
-
import example._
import net.liftmodules.widgets.autocomplete._
+import net.liftmodules.{fobobs4api => fobo}
import comet._
import model._
import lib._
-import net.liftweb.mapper.{DB, ConnectionManager, Schemifier, DefaultConnectionIdentifier, ConnectionIdentifier}
+import net.liftweb.mapper.{
+ ConnectionIdentifier,
+ ConnectionManager,
+ DB,
+ DefaultConnectionIdentifier,
+ Schemifier
+}
+import scala.xml.Text
import _root_.java.sql.{Connection, DriverManager}
-import snippet._
+import snippet._
/**
- * A class that's instantiated early and run. It allows the application
- * to modify lift's environment
- */
+ * A class that's instantiated early and run. It allows the application
+ * to modify lift's environment
+ */
class Boot {
def boot {
DB.defineConnectionManager(DefaultConnectionIdentifier, DBVendor)
LiftRules.addToPackages("net.liftweb.example")
/**
- * We're doing this as HTML5
- */
- LiftRules.htmlProperties.default.set((r: Req) => new Html5Properties(r.userAgent))
+ * We're doing this as HTML5
+ */
+ LiftRules.htmlProperties.default.set((r: Req) =>
+ new Html5Properties(r.userAgent))
- LiftRules.localeCalculator = r => definedLocale.openOr(LiftRules.defaultLocaleCalculator(r))
+ LiftRules.localeCalculator = r =>
+ definedLocale.openOr(LiftRules.defaultLocaleCalculator(r))
if (!Props.inGAE) {
// No DB stuff in GAE
@@ -65,29 +74,19 @@ class Boot {
XmlServer.init()
LiftRules.statelessDispatch.append {
- case r@Req("stateless" :: _, "", GetRequest) => StatelessHtml.render(r) _
+ case r @ Req("stateless" :: _, "", GetRequest) =>
+ StatelessHtml.render(r) _
}
LiftRules.dispatch.prepend(NamedPF("Login Validation") {
case Req("login" :: page, "", _)
- if !LoginStuff.is && page.head != "validate" =>
- () => Full(RedirectResponse("/login/validate"))
+ if !LoginStuff.is && page.head != "validate" =>
+ () =>
+ Full(RedirectResponse("/login/validate"))
})
- LiftRules.snippetDispatch.append(NamedPF("Template")
- (Map("Template" -> Template,
- "AllJson" -> AllJson)))
-
- /*
- LiftRules.snippetDispatch.append {
- case "MyWizard" => MyWizard
- case "WizardChallenge" => WizardChallenge
- case "ScreenForm" => PersonScreen
- }
- */
-
SessionMaster.sessionCheckFuncs = SessionMaster.sessionCheckFuncs :::
- List(SessionChecker)
+ List(SessionChecker)
// Uncomment the lines below to see how
// a Lift app looks when it's stateless
@@ -99,37 +98,53 @@ class Boot {
LiftRules.snippetDispatch.append(Map("runtime_stats" -> RuntimeStats))
/*
- * Show the spinny image when an Ajax call starts
- */
- LiftRules.ajaxStart =
- Full(() => LiftRules.jsArtifacts.show("ajax-loader").cmd)
+ * Show the spinny image when an Ajax call starts
+ */
+ LiftRules.ajaxStart = Full(
+ () => LiftRules.jsArtifacts.show("ajax-loader").cmd)
/*
- * Make the spinny image go away when it ends
- */
- LiftRules.ajaxEnd =
- Full(() => LiftRules.jsArtifacts.hide("ajax-loader").cmd)
+ * Make the spinny image go away when it ends
+ */
+ LiftRules.ajaxEnd = Full(
+ () => LiftRules.jsArtifacts.hide("ajax-loader").cmd)
LiftRules.early.append(makeUtf8)
LiftRules.cometCreation.append {
- case CometCreationInfo("Clock",
- name,
- defaultXml,
- attributes,
- session) =>
- new ExampleClock(session, Full("Clock"),
- name, defaultXml, attributes)
-
+ case CometCreationInfo("Clock", name, defaultXml, attributes, session) =>
+ new ExampleClock(session, Full("Clock"), name, defaultXml, attributes)
+
}
+ LiftRules.noticesAutoFadeOut.default.set((notices: NoticeType.Value) => {
+ notices match {
+ case NoticeType.Notice => Full((8 seconds, 4 seconds))
+ case _ => Empty
+ }
+ })
+
LiftSession.onBeginServicing = RequestLogger.beginServicing _ ::
- LiftSession.onBeginServicing
+ LiftSession.onBeginServicing
LiftSession.onEndServicing = RequestLogger.endServicing _ ::
- LiftSession.onEndServicing
+ LiftSession.onEndServicing
+
+ LiftRules.setSiteMapFunc(() => MenuInfo.sitemap())
+ LiftRules.securityRules = () => {
+ SecurityRules(
+ content = Some(
+ ContentSecurityPolicy(
+ scriptSources = List(ContentSourceRestriction.UnsafeEval,
+ ContentSourceRestriction.UnsafeInline,
+ ContentSourceRestriction.Self),
+ styleSources = List(ContentSourceRestriction.UnsafeInline,
+ ContentSourceRestriction.Self)
+ )))
+ }
- LiftRules.setSiteMapFunc(MenuInfo.sitemap)
+ // FoBo init
+ fobo.API.init = fobo.API.Bootstrap4
ThingBuilder.boot()
@@ -137,14 +152,16 @@ class Boot {
// Dump information about session every 10 minutes
SessionMaster.sessionWatchers = SessionInfoDumper ::
- SessionMaster.sessionWatchers
+ SessionMaster.sessionWatchers
// Dump browser information each time a new connection is made
LiftSession.onBeginServicing = BrowserLogger.haveSeenYou _ :: LiftSession.onBeginServicing
}
- private def makeUtf8(req: HTTPRequest): Unit = {req.setCharacterEncoding("UTF-8")}
+ private def makeUtf8(req: HTTPRequest): Unit = {
+ req.setCharacterEncoding("UTF-8")
+ }
}
object RequestLogger extends Loggable {
@@ -154,37 +171,50 @@ object RequestLogger extends Loggable {
startTime(millis)
}
- def endServicing(session: LiftSession, req: Req,
+ def endServicing(session: LiftSession,
+ req: Req,
response: Box[LiftResponse]) {
val delta = millis - startTime.is
- logger.info("At " + (timeNow) + " Serviced " + req.uri + " in " + (delta) + "ms " + (
- response.map(r => " Headers: " + r.toResponse.headers) openOr ""
- ))
+ logger.info(
+ "At " + (now) + " Serviced " + req.uri + " in " + (delta) + "ms " + (
+ response.map(r => " Headers: " + r.toResponse.headers) openOr ""
+ ))
}
}
object MenuInfo {
import Loc._
+ import net.liftmodules.fobobs4.lib.BSLocInfo
- lazy val noGAE = Unless(() => Props.inGAE, "Disabled for GAE")
+ private lazy val noGAE = Unless(() => Props.inGAE, "Disabled for GAE")
+ private val topNavLG = LocGroup("topNav")
- def sitemap() = SiteMap(
- Menu("Home") / "index",
- Menu("Interactive Stuff") / "interactive" submenus(
+ private val siteMapList = List(
+ Menu.i("Home") / "index" >> topNavLG,
+ TopNav.interactiveMenuPart,
+ Menu.i("Interactive Stuff") / "interactive" submenus (
Menu("Comet Chat") / "chat" >> noGAE,
Menu("Ajax Samples") / "ajax",
Menu("Ajax Form") / "ajax-form",
Menu("Modal Dialog") / "rhodeisland",
Menu("JSON Messaging") / "json",
Menu("Stateless JSON Messaging") / "stateless_json",
- Menu("More JSON") / "json_more",
- Menu("Ajax and Forms") / "form_ajax") ,
- Menu("Persistence") / "persistence" >> noGAE submenus (
+ // Menu("More JSON") / "json_more",
+ Menu("Ajax and Forms") / "form_ajax"
+ ),
+ TopNav.persistenceMenuPart,
+ Menu.i("Persistence") / "persistence" >> noGAE submenus (
Menu("XML Fun") / "xml_fun" >> noGAE,
Menu("Database") / "database" >> noGAE,
- Menu(Loc("simple", Link(List("simple"), true, "/simple/index"), "Simple Forms", noGAE)),
- Menu("Templates") / "template" >> noGAE),
- Menu("Templating") / "templating" / "index" submenus(
+ Menu(
+ Loc("simple",
+ Link(List("simple"), true, "/simple/index"),
+ "Simple Forms",
+ noGAE)) //,
+ // Menu("Templates") / "template" >> noGAE
+ ),
+ TopNav.templatingMenuPart,
+ Menu.i("Templating") / "templating" / "index" submenus (
Menu("Surround") / "templating" / "surround",
Menu("Embed") / "templating" / "embed",
Menu("Evalutation Order") / "templating" / "eval_order",
@@ -192,18 +222,23 @@ object MenuInfo {
Menu("Simple Wizard") / "simple_wizard",
Menu("Lazy Loading") / "lazy",
Menu("Parallel Snippets") / "parallel",
- Menu("
tag") / "templating"/ "head"),
- Menu("Web Services") / "ws" >> noGAE,
- Menu("Localization") / "lang",
- Menu("Menus") / "menu" / "index" submenus(
+ Menu("
tag") / "templating" / "head"
+ ),
+ Menu.i("Web Services") / "ws" >> noGAE >> topNavLG,
+ Menu.i("Localization") / "lang" >> topNavLG,
+ TopNav.menusMenuPart,
+ Menu.i("Menus") / "menu" / "index" submenus (
Menu("First Submenu") / "menu" / "one",
- Menu("Second Submenu (has more)") / "menu" / "two" submenus(
+ Menu("Second Submenu (has more)") / "menu" / "two" submenus (
Menu("First (2) Submenu") / "menu" / "two_one",
- Menu("Second (2) Submenu") / "menu" / "two_two"),
+ Menu("Second (2) Submenu") / "menu" / "two_two"
+ ),
Menu("Third Submenu") / "menu" / "three",
- Menu("Forth Submenu") / "menu" / "four"),
+ Menu("Forth Submenu") / "menu" / "four"
+ ),
Menu(WikiStuff),
- Menu("Misc code") / "misc" submenus(
+ TopNav.miscMenuPart,
+ Menu.i("Misc code") / "misc" submenus (
Menu("Long Time") / "longtime",
Menu("Number Guessing") / "guess",
Menu("Wizard") / "wiz",
@@ -215,18 +250,320 @@ object MenuInfo {
Menu("Wiring Invoice") / "invoice_wiring",
Menu("File Upload") / "file_upload",
Menu("Async REST") / "async_rest",
- Menu(Loc("login", Link(List("login"), true, "/login/index"),
- Requiring LoginSiteMap )),
- Menu("Counting") / "count"),
- Menu(Loc("lift", ExtLink("http://liftweb.net"),
- Lift project home )),
- Menu(Loc("src", ExtLink("https://github.com/lift/examples/tree/master/combo/example"),
- "Source code for this site")))
+ Menu(
+ Loc("login",
+ Link(List("login"), true, "/login/index"),
+ Requiring LoginSiteMap )),
+ Menu("Counting") / "count"
+ ),
+ Menu(
+ Loc("lift",
+ ExtLink("http://liftweb.net"),
+ S.loc("lift", Lift project home ),
+ topNavLG, BSLocInfo.LinkTargetBlank)),
+ Menu(
+ Loc("src",
+ ExtLink("https://github.com/lift/examples/tree/master/combo/example"),
+ S.loc("src", Text("Source code for this site")),
+ topNavLG, BSLocInfo.LinkTargetBlank))
+ )
+
+ private object TopNav {
+ // Interactive stuff
+ private val interactiveLoc = Loc(
+ "topNavInteractive",
+ Link(List("topNavInteractive"), true, "/interactive"),
+ S.loc("topNavInteractive", Text("Interactive Stuff")))
+ private val cometChatLoc = Loc("topNavCometChat",
+ Link(List("topNavCometChat"), true, "/chat"),
+ S.loc("topNavCometChat", Text("Comet Chat")),
+ noGAE)
+ private val ajaxSamplesLoc = Loc(
+ "topNavAjaxSamples",
+ Link(List("topNavAjaxSamples"), true, "/ajax"),
+ S.loc("topNavAjaxSamples", Text("Ajax Samples")))
+ private val ajaxFormLoc = Loc(
+ "topNavAjaxForm",
+ Link(List("topNavAjaxForm"), true, "/ajax-form"),
+ S.loc("topNavAjaxForm", Text("Ajax Form")))
+ private val modalDialogLoc = Loc(
+ "topNavModalDialog",
+ Link(List("topNavModalDialog"), true, "/rhodeisland"),
+ S.loc("topNavModalDialog", Text("Modal Dialog")))
+ private val jSONMessagingLoc = Loc(
+ "topNavJSONMessaging",
+ Link(List("topNavJSONMessaging"), true, "/json"),
+ S.loc("topNavJSONMessaging", Text("JSON Messaging")))
+ private val statelessJSONMessagingLoc = Loc(
+ "topNavStatelessJSONMessaging",
+ Link(List("topNavStatelessJSONMessaging"), true, "/stateless_json"),
+ S.loc("topNavStatelessJSONMessaging", Text("Stateless JSON Messaging"))
+ )
+ private val AjaxAndFormsLoc = Loc(
+ "topNavAjaxAndForms",
+ Link(List("topNavAjaxAndForms"), true, "/form_ajax"),
+ S.loc("topNavAjaxAndForms", Text("Ajax and Forms")))
+ private val interactiveDD = Menu.i("topNavInteractiveDD") / "/dddlabel2"
+ private val interactiveDivider1 = Menu("interactiveDivider1") / "interactiveDivider1"
+ private val interactive = Menu(interactiveLoc)
+ private val cometChat = Menu(cometChatLoc)
+ private val ajaxSamples = Menu(ajaxSamplesLoc)
+ private val ajaxForm = Menu(ajaxFormLoc)
+ private val modalDialog = Menu(modalDialogLoc)
+ private val jSONMessaging = Menu(jSONMessagingLoc)
+ private val statelessJSONMessaging = Menu(statelessJSONMessagingLoc)
+ private val ajaxAndForms = Menu(AjaxAndFormsLoc)
+
+ // Persistence
+ private val persistenceLoc = Loc(
+ "topNavPersistence",
+ Link(List("topNavPersistence"), true, "/persistence"),
+ S.loc("topNavPersistence", Text("Persistence")),
+ noGAE)
+ private val xMLFunLoc = Loc("topNavXMLFun",
+ Link(List("topNavXMLFun"), true, "/xml_fun"),
+ S.loc("topNavXMLFun", Text("XML Fun")),
+ noGAE)
+ private val databaseLoc = Loc(
+ "topNavDatabase",
+ Link(List("topNavDatabase"), true, "/database"),
+ S.loc("topNavDatabase", Text("Database")),
+ noGAE)
+ private val simpleLoc = Loc(
+ "topNavSimple",
+ Link(List("topNavSimple"), true, "/simple/index"),
+ S.loc("topNavSimple", Text("Simple Forms")),
+ noGAE)
+ private val persistenceDD = Menu.i("topNavPersistenceDD") / "/ddlabel3" >> noGAE
+ private val persistenceDivider1 = Menu("persistenceDivider1") / "persistenceDivider1"
+ private val persistence = Menu(persistenceLoc)
+ private val xMLFun = Menu(xMLFunLoc)
+ private val database = Menu(databaseLoc)
+ private val simple = Menu(simpleLoc)
+
+ // Templating
+ private val teplatingLoc = Loc(
+ "topNavTeplating",
+ Link(List("topNavTeplating"), true, "/templating/index"),
+ S.loc("topNavTeplating", Text("Templating"))
+ )
+ private val surroundLoc = Loc(
+ "topNavSurround",
+ Link(List("topNavSurround"), true, "/templating/surround"),
+ S.loc("topNavSurround", Text("Surround"))
+ )
+ private val embedLoc = Loc(
+ "topNavEmbed",
+ Link(List("topNavEmbed"), true, "/templating/embed"),
+ S.loc("topNavEmbed", Text("Embed"))
+ )
+ private val evaluationOrderLoc = Loc(
+ "topNavEvaluationOrder",
+ Link(List("topNavEvaluationOrder"), true, "/templating/eval_order"),
+ S.loc("topNavEvaluationOrder", Text("Evalutation Order"))
+ )
+ private val selectDivsLoc = Loc(
+ "tomNavSelectDivs",
+ Link(List("tomNavSelectDivs"), true, "/templating/selectomatic"),
+ S.loc("tomNavSelectDivs", Text("Select
s"))
+ )
+ private val simpleWizardLoc = Loc(
+ "topNavSimpleWizard",
+ Link(List("topNavSimpleWizard"), true, "/simple_wizard"),
+ S.loc("topNavSimpleWizard", Text("Simple Wizard"))
+ )
+ private val lazyLoadingLoc = Loc(
+ "topNavLazyLoading",
+ Link(List("topNavLazyLoading"), true, "/lazy"),
+ S.loc("topNavLazyLoading", Text("Lazy Loading"))
+ )
+ private val parallelSnippetsLoc = Loc(
+ "topNavParallelSnippets",
+ Link(List("topNavParallelSnippets"), true, "/parallel"),
+ S.loc("topNavParallelSnippets", Text("Parallel Snippets"))
+ )
+ //
tag
+ private val headTagLoc = Loc(
+ "topNavHeadTagLoc",
+ Link(List("topNavHeadTagLoc"), true, "/templating/head"),
+ S.loc("topNavHeadTagLoc", Text("
tag"))
+ )
+ private val templatingDD = Menu.i("topNavTemplatingDD") / "/ddlabel4"
+ private val templatingDivider1 = Menu("templatingDivider1") / "templatingDivider1"
+ private val templating = Menu(teplatingLoc)
+ private val surround = Menu(surroundLoc)
+ private val embed = Menu(embedLoc)
+ private val evaluationOrder = Menu(evaluationOrderLoc)
+ private val selectDivs = Menu(selectDivsLoc)
+ private val simpleWizard = Menu(simpleWizardLoc)
+ private val lazyLoading = Menu(lazyLoadingLoc)
+ private val parallelSnippets = Menu(parallelSnippetsLoc)
+ private val headTag = Menu(headTagLoc)
+
+ // Menu
+ private val menusLoc = Loc(
+ "topNavMenus",
+ Link(List("topNavMenus"), true, "/menu/index"),
+ S.loc("topNavMenus", Text("Menus"))
+ )
+ private val firstSubmenuLoc = Loc(
+ "topNavFirstSubmenu",
+ Link(List("topNavFirstSubmenu"), true, "/menu/one"),
+ S.loc("topNavFirstSubmenu", Text("First Submenu"))
+ )
+ private val secondSubmenuLoc = Loc(
+ "topNavSecondSubmenu",
+ Link(List("topNavSecondSubmenu"), true, "/menu/two"),
+ S.loc("topNavSecondSubmenu", Text("Second Submenu (has more)"))
+ )
+ private val first2SubmenuLoc = Loc(
+ "topNavFirst2Submenu",
+ Link(List("topNavFirst2Submenu"), true, "/menu/two_one"),
+ S.loc("topNavFirst2Submenu", Text("First (2) Submenu"))
+ )
+ private val second2SubmenuLoc = Loc(
+ "topNavSecond2Submenu",
+ Link(List("topNavSecond2Submenu"), true, "/menu/two_two"),
+ S.loc("topNavSecond2Submenu", Text("Second (2) Submenu"))
+ )
+ private val thirdSubmenuLoc = Loc(
+ "topNavThirdSubmenu",
+ Link(List("topNavThirdSubmenu"), true, "/menu/three"),
+ S.loc("topNavThirdSubmenu", Text("Third Submenu"))
+ )
+ private val forthSubmenuLoc = Loc(
+ "topNavForthSubmenu",
+ Link(List("topNavForthSubmenu"), true, "/menu/four"),
+ S.loc("topNavForthSubmenu", Text("Forth Submenu"))
+ )
+ private val menusDD = Menu.i("topNavMenusDD") / "/ddlabel5"
+ private val menusDivider1 = Menu("menusDivider1") / "menusDivider1"
+ private val menus = Menu(menusLoc)
+ private val firstSubmenu = Menu(firstSubmenuLoc)
+ private val secondSubmenu = Menu(secondSubmenuLoc)
+ private val first2Submenu = Menu(first2SubmenuLoc)
+ private val second2Submenu = Menu(second2SubmenuLoc)
+ private val thirdSubmenu = Menu(thirdSubmenuLoc)
+ private val forthSubmenu = Menu(forthSubmenuLoc)
+
+ // Misc
+ private val miscLoc = Loc(
+ "topNavMisc",
+ Link(List("topNavMisc"), true, "/misc"),
+ S.loc("topNavMisc", Text("Misc code"))
+ )
+ private val longTimeLoc = Loc(
+ "topNavLongTime",
+ Link(List("topNavLongTime"), true, "/longtime"),
+ S.loc("topNavLongTime", Text("Long Time"))
+ )
+ private val numberGuessingLoc = Loc(
+ "topNavNumberGuessing",
+ Link(List("topNavNumberGuessing"), true, "/guess"),
+ S.loc("topNavNumberGuessing", Text("Number Guessing"))
+ )
+ private val wizardLoc = Loc(
+ "topNavWizard",
+ Link(List("topNavWizard"), true, "/wiz"),
+ S.loc("topNavWizard", Text("Wizard"))
+ )
+ private val wizardChallengeLoc = Loc(
+ "topNavWizardChallenge",
+ Link(List("topNavWizardChallenge"), true, "/wiz2"),
+ S.loc("topNavWizardChallenge", Text("Wizard Challenge"))
+ )
+ private val simpleScreenLoc = Loc(
+ "topNavSimpleScreen",
+ Link(List("topNavSimpleScreen"), true, "/simple_screen"),
+ S.loc("topNavSimpleScreen", Text("Simple Screen"))
+ )
+ private val variableScreenLoc = Loc(
+ "topNavVariableScreen",
+ Link(List("topNavVariableScreen"), true, "/variable_screen"),
+ S.loc("topNavVariableScreen", Text("Variable Screen"))
+ )
+ private val arcChallenge1Loc = Loc(
+ "topNavArcChallenge1",
+ Link(List("topNavArcChallenge1"), true, "/arc"),
+ S.loc("topNavArcChallenge1", Text("Arc Challenge #1"))
+ )
+ private val simpleWiringLoc = Loc(
+ "topNavSimpleWiring",
+ Link(List("topNavSimpleWiring"), true, "/simple_wiring"),
+ S.loc("topNavSimpleWiring", Text("Simple Wiring"))
+ )
+ private val wiringInvoiceLoc = Loc(
+ "topNavWiringInvoice",
+ Link(List("topNavWiringInvoice"), true, "/invoice_wiring"),
+ S.loc("topNavWiringInvoice", Text("Wiring Invoice"))
+ )
+ private val fileUploadLoc = Loc(
+ "topNavFileUpload",
+ Link(List("topNavFileUpload"), true, "/file_upload"),
+ S.loc("topNavFileUpload", Text("File Upload"))
+ )
+ private val asyncRESTLoc = Loc(
+ "topNavAsyncREST",
+ Link(List("topNavAsyncREST"), true, "/async_rest"),
+ S.loc("topNavAsyncREST", Text("Async REST"))
+ )
+ private val loginLoc = Loc(
+ "topNavLogin",
+ Link(List("topNavLogin"), true, "/login/index"),
+ S.loc("topNavLogin", Requiring LoginSiteMap )
+ )
+ private val countingLoc = Loc(
+ "topNavCounting",
+ Link(List("topNavCounting"), true, "/count"),
+ S.loc("topNavCounting", Text("Counting"))
+ )
+ private val miscDD = Menu.i("topNavMiscDD") / "/ddlabel6"
+ private val miscDivider1 =Menu("miscDivider1") / "miscDivider1"
+ private val misc = Menu(miscLoc)
+
+ private val longTime = Menu(longTimeLoc)
+ private val numberGuessing = Menu(numberGuessingLoc)
+ private val wizard = Menu(wizardLoc)
+ private val simpleScreen = Menu(simpleScreenLoc)
+ private val variableScreen = Menu(variableScreenLoc)
+ private val arcChallenge = Menu(arcChallenge1Loc)
+ private val simpleWiring = Menu(simpleWiringLoc)
+ private val wiringInvoice = Menu(wiringInvoiceLoc)
+ private val fileUpload = Menu(fileUploadLoc)
+ private val asyncRest = Menu(asyncRESTLoc)
+ private val login = Menu(loginLoc)
+ private val counting = Menu(countingLoc)
+
+ // Public stuff
+ val interactiveMenuPart = interactiveDD >> topNavLG >> PlaceHolder submenus (interactive,
+ interactiveDivider1 >> topNavLG >> BSLocInfo.Divider,
+ cometChat, ajaxSamples, ajaxForm, modalDialog, jSONMessaging, statelessJSONMessaging, ajaxAndForms)
+
+ val persistenceMenuPart = persistenceDD >> topNavLG >> PlaceHolder submenus (persistence,
+ persistenceDivider1 >> topNavLG >> BSLocInfo.Divider,
+ xMLFun, database, simple)
+
+ val templatingMenuPart = templatingDD >> topNavLG >> PlaceHolder submenus (templating,
+ templatingDivider1 >> topNavLG >> BSLocInfo.Divider,
+ surround, embed, evaluationOrder, selectDivs, simpleWizard, lazyLoading, parallelSnippets, headTag)
+
+ // Note: The bootstrap navigator dose only handle one level of sub-menus
+ val menusMenuPart = menusDD >> topNavLG >> PlaceHolder submenus (menus,
+ menusDivider1 >> topNavLG >> BSLocInfo.Divider,
+ firstSubmenu, secondSubmenu, first2Submenu, second2Submenu, thirdSubmenu, forthSubmenu)
+
+ val miscMenuPart = miscDD >> topNavLG >> PlaceHolder submenus (misc,
+ miscDivider1 >> BSLocInfo.Divider,
+ longTime, numberGuessing, wizard, simpleScreen, variableScreen, arcChallenge, simpleWiring,
+ wiringInvoice, fileUpload, asyncRest, login, counting)
+ }
+
+ def sitemap() = SiteMap(siteMapList: _*)
}
/**
-* Database connection calculation
-*/
+ * Database connection calculation
+ */
object DBVendor extends ConnectionManager {
private var pool: List[Connection] = Nil
private var poolSize = 0
@@ -234,60 +571,58 @@ object DBVendor extends ConnectionManager {
private lazy val chooseDriver = Props.mode match {
case Props.RunModes.Production => "org.apache.derby.jdbc.EmbeddedDriver"
- case _ => "org.h2.Driver"
+ case _ => "org.h2.Driver"
}
-
private lazy val chooseURL = Props.mode match {
case Props.RunModes.Production => "jdbc:derby:lift_example;create=true"
- case _ => "jdbc:h2:mem:lift;DB_CLOSE_DELAY=-1"
+ case _ => "jdbc:h2:mem:lift;DB_CLOSE_DELAY=-1"
}
+ private def createOne: Box[Connection] =
+ try {
+ val driverName: String = Props.get("db.driver") openOr chooseDriver
+ val dbUrl: String = Props.get("db.url") openOr chooseURL
- private def createOne: Box[Connection] = try {
- val driverName: String = Props.get("db.driver") openOr chooseDriver
+ Class.forName(driverName)
+ val dm = (Props.get("db.user"), Props.get("db.password")) match {
+ case (Full(user), Full(pwd)) =>
+ DriverManager.getConnection(dbUrl, user, pwd)
- val dbUrl: String = Props.get("db.url") openOr chooseURL
-
-
- Class.forName(driverName)
-
- val dm = (Props.get("db.user"), Props.get("db.password")) match {
- case (Full(user), Full(pwd)) =>
- DriverManager.getConnection(dbUrl, user, pwd)
+ case _ => DriverManager.getConnection(dbUrl)
+ }
- case _ => DriverManager.getConnection(dbUrl)
+ Full(dm)
+ } catch {
+ case e: Exception => e.printStackTrace; Empty
}
- Full(dm)
- } catch {
- case e: Exception => e.printStackTrace; Empty
- }
-
def newConnection(name: ConnectionIdentifier): Box[Connection] =
synchronized {
pool match {
case Nil if poolSize < maxPoolSize =>
val ret = createOne
- poolSize = poolSize + 1
- ret.foreach(c => pool = c :: pool)
- ret
+ poolSize = poolSize + 1
+ ret.foreach(c => pool = c :: pool)
+ ret
case Nil => wait(1000L); newConnection(name)
- case x :: xs => try {
- x.setAutoCommit(false)
- Full(x)
- } catch {
- case e => try {
- pool = xs
- poolSize = poolSize - 1
- x.close
- newConnection(name)
+ case x :: xs =>
+ try {
+ x.setAutoCommit(false)
+ Full(x)
} catch {
- case e => newConnection(name)
+ case e =>
+ try {
+ pool = xs
+ poolSize = poolSize - 1
+ x.close
+ newConnection(name)
+ } catch {
+ case e => newConnection(name)
+ }
}
- }
}
}
@@ -302,7 +637,9 @@ object BrowserLogger extends Loggable {
def haveSeenYou(session: LiftSession, request: Req) {
if (!HaveSeenYou.is) {
- logger.info("Created session " + session.uniqueId + " IP: {" + request.request.remoteAddress + "} UserAgent: {{" + request.userAgent.openOr("N/A") + "}}")
+ logger.info(
+ "Created session " + session.uniqueId + " IP: {" + request.request.remoteAddress + "} UserAgent: {{" + request.userAgent
+ .openOr("N/A") + "}}")
HaveSeenYou(true)
}
}
@@ -311,50 +648,50 @@ object BrowserLogger extends Loggable {
object SessionInfoDumper extends LiftActor with Loggable {
private var lastTime = millis
- private def cyclePeriod = 1 minute
+ private def cyclePeriod = 10 minute
import net.liftweb.example.lib.SessionChecker
- protected def messageHandler =
- {
- case SessionWatcherInfo(sessions) =>
- if ((millis - cyclePeriod) > lastTime) {
- lastTime = millis
- val rt = Runtime.getRuntime
- rt.gc
-
- RuntimeStats.lastUpdate = timeNow
- RuntimeStats.totalMem = rt.totalMemory
- RuntimeStats.freeMem = rt.freeMemory
- RuntimeStats.sessions = sessions.size
-
- val percent = (RuntimeStats.freeMem * 100L) / RuntimeStats.totalMem
-
- // get more aggressive about purging if we're
- // at less than 35% free memory
- if (percent < 35L) {
- SessionChecker.killWhen /= 2L
- if (SessionChecker.killWhen < 5000L)
- SessionChecker.killWhen = 5000L
- SessionChecker.killCnt *= 2
- } else {
- SessionChecker.killWhen *= 2L
- if (SessionChecker.killWhen >
+ protected def messageHandler = {
+ case SessionWatcherInfo(sessions) =>
+ if ((millis - cyclePeriod) > lastTime) {
+ lastTime = millis
+ val rt = Runtime.getRuntime
+ rt.gc
+
+ RuntimeStats.lastUpdate = now
+ RuntimeStats.totalMem = rt.totalMemory
+ RuntimeStats.freeMem = rt.freeMemory
+ RuntimeStats.sessions = sessions.size
+
+ val percent = (RuntimeStats.freeMem * 100L) / RuntimeStats.totalMem
+
+ // get more aggressive about purging if we're
+ // at less than 35% free memory
+ if (percent < 35L) {
+ SessionChecker.killWhen /= 2L
+ if (SessionChecker.killWhen < 5000L)
+ SessionChecker.killWhen = 5000L
+ SessionChecker.killCnt *= 2
+ } else {
+ SessionChecker.killWhen *= 2L
+ if (SessionChecker.killWhen >
SessionChecker.defaultKillWhen)
- SessionChecker.killWhen = SessionChecker.defaultKillWhen
- val newKillCnt = SessionChecker.killCnt / 2
- if (newKillCnt > 0) SessionChecker.killCnt = newKillCnt
- }
-
- val dateStr: String = timeNow.toString
- logger.info("[MEMDEBUG] At " + dateStr + " Number of open sessions: " + sessions.size)
- logger.info("[MEMDEBUG] Free Memory: " + pretty(RuntimeStats.freeMem))
- logger.info("[MEMDEBUG] Total Memory: " + pretty(RuntimeStats.totalMem))
- logger.info("[MEMDEBUG] Kill Interval: " + (SessionChecker.killWhen / 1000L))
- logger.info("[MEMDEBUG] Kill Count: " + (SessionChecker.killCnt))
+ SessionChecker.killWhen = SessionChecker.defaultKillWhen
+ val newKillCnt = SessionChecker.killCnt / 2
+ if (newKillCnt > 0) SessionChecker.killCnt = newKillCnt
}
- }
+ val dateStr: String = now.toString
+ logger.info(
+ "[MEMDEBUG] At " + dateStr + " Number of open sessions: " + sessions.size)
+ logger.info("[MEMDEBUG] Free Memory: " + pretty(RuntimeStats.freeMem))
+ logger.info("[MEMDEBUG] Total Memory: " + pretty(RuntimeStats.totalMem))
+ logger.info(
+ "[MEMDEBUG] Kill Interval: " + (SessionChecker.killWhen / 1000L))
+ logger.info("[MEMDEBUG] Kill Count: " + (SessionChecker.killCnt))
+ }
+ }
private def pretty(in: Long): String =
if (in > 1000L) pretty(in / 1000L) + "," + (in % 1000L)
diff --git a/combo/example/src/main/scala/net/liftweb/example/comet/AskName.scala b/combo/example/src/main/scala/net/liftweb/example/comet/AskName.scala
index 4692da4..1681050 100644
--- a/combo/example/src/main/scala/net/liftweb/example/comet/AskName.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/comet/AskName.scala
@@ -14,24 +14,20 @@
* limitations under the License.
*/
-package net.liftweb {
-package example {
-package comet {
+package net.liftweb.example.comet
-import _root_.net.liftweb.http._
-import S._
+import net.liftweb.http._
import SHtml._
-import _root_.net.liftweb.common._
-import _root_.net.liftweb.util._
-import _root_.scala.xml._
class AskName extends CometActor {
def render =
ajaxForm(
What is your username?
++
- text("",name => answer(name.trim)) ++
- )
-}
-
-}
-}
+
)
}
diff --git a/combo/example/src/main/scala/net/liftweb/example/comet/Chat.scala b/combo/example/src/main/scala/net/liftweb/example/comet/Chat.scala
index 723f884..e49b94f 100644
--- a/combo/example/src/main/scala/net/liftweb/example/comet/Chat.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/comet/Chat.scala
@@ -15,106 +15,101 @@
*/
package net.liftweb {
-package example {
-package comet {
-
-import _root_.net.liftweb._
-import http._
-import common._
-import actor._
-import util._
-import Helpers._
-import _root_.scala.xml._
-import S._
-import SHtml._
-import js._
-import JsCmds._
-import JE._
-import net.liftweb.http.js.jquery.JqJsCmds.{AppendHtml}
-
-class Chat extends CometActor with CometListener {
- private var userName = ""
- private var chats: List[ChatLine] = Nil
-
- /* need these vals to be set eagerly, within the scope
- * of Comet component constructor
- */
- private val ulId = S.attr("ul_id") openOr "some_ul_id"
-
- private val liId = S.attr("li_id")
-
- private lazy val li = liId.
- flatMap{ Helpers.findId(defaultHtml, _) } openOr NodeSeq.Empty
-
- private val inputId = Helpers.nextFuncName
-
- // handle an update to the chat lists
- // by diffing the lists and then sending a partial update
- // to the browser
- override def lowPriority = {
- case ChatServerUpdate(value) => {
- val update = (value filterNot (chats contains)).reverse.
- map(b => AppendHtml(ulId, line(b)))
-
- partialUpdate(update)
- chats = value
- }
- }
-
- // render the input area by binding the
- // appropriate dynamically generated code to the
- // view supplied by the template
- override lazy val fixedRender: Box[NodeSeq] =
- S.runTemplate("_chat_fixed" :: Nil,
- "postit" -> Helpers.evalElemWithId {
- (id, elem) =>
- SHtml.onSubmit((s: String) => {
- ChatServer ! ChatServerMsg(userName, s.trim)
- SetValById(id, "")
- })(elem)
- } _)
-
- // display a line
- private def line(c: ChatLine) = {
- ("name=when" #> hourFormat(c.when) &
- "name=who" #> c.user &
- "name=body" #> c.msg)(li)
- }
-
- // display a list of chats
- private def displayList: NodeSeq = chats.reverse.flatMap(line)
-
- // render the whole list of chats
- override def render = {
- "name=chat_name" #> userName &
- ("#"+ulId+" *") #> displayList
- }
-
- // setup the component
- override def localSetup {
- askForName
- super.localSetup
- }
-
- // register as a listener
- def registerWith = ChatServer
-
- // ask for the user's name
- private def askForName {
- if (userName.length == 0) {
- ask(new AskName, "what's your username") {
- case s: String if (s.trim.length > 2) =>
- userName = s.trim
- reRender(true)
-
- case _ =>
+ package example {
+ package comet {
+
+ import http._
+ import common._
+ import util._
+ import Helpers._
+ import _root_.scala.xml._
+ import js._
+ import JsCmds._
+ import net.liftweb.http.js.jquery.JqJsCmds.{AppendHtml}
+
+ class Chat extends CometActor with CometListener {
+ private var userName = ""
+ private var chats: List[ChatLine] = Nil
+
+ /* need these vals to be set eagerly, within the scope
+ * of Comet component constructor
+ */
+ private val ulId = S.attr("ul_id") openOr "some_ul_id"
+
+ private val liId = S.attr("li_id")
+
+ private lazy val li = liId.flatMap { Helpers.findId(defaultHtml, _) } openOr NodeSeq.Empty
+
+ private val inputId = Helpers.nextFuncName
+
+ // handle an update to the chat lists
+ // by diffing the lists and then sending a partial update
+ // to the browser
+ override def lowPriority = {
+ case ChatServerUpdate(value) => {
+ val update = (value filterNot (chats contains)).reverse.map(b =>
+ AppendHtml(ulId, line(b)))
+
+ partialUpdate(update)
+ chats = value
+ }
+ }
+
+ // render the input area by binding the
+ // appropriate dynamically generated code to the
+ // view supplied by the template
+ override lazy val fixedRender: Box[NodeSeq] =
+ S.runTemplate(
+ "_chat_fixed" :: Nil,
+ "postit" -> Helpers.evalElemWithId { (id, elem) =>
+ SHtml.onSubmit((s: String) => {
+ ChatServer ! ChatServerMsg(userName, s.trim)
+ SetValById(id, "")
+ })(elem)
+ } _
+ )
+
+ // display a line
+ private def line(c: ChatLine): NodeSeq = {
+ ("name=when" #> hourFormat(c.when) &
+ "name=who" #> c.user &
+ "name=body" #> c.msg)(li)
+ }
+
+ // display a list of chats
+ private def displayList: NodeSeq = chats.reverse.flatMap(line)
+
+ // render the whole list of chats
+ override def render = {
+ "name=chat_name" #> userName &
+ ("#" + ulId + " *") #> displayList
+ }
+
+ // setup the component
+ override def localSetup {
askForName
- reRender(false)
+ super.localSetup
+ }
+
+ // register as a listener
+ def registerWith = ChatServer
+
+ // ask for the user's name
+ private def askForName {
+ if (userName.length == 0) {
+ ask(new AskName, "what's your username") {
+ case s: String if (s.trim.length > 2) =>
+ userName = s.trim
+ reRender(true)
+
+ case _ =>
+ askForName
+ reRender(false)
+ }
+ }
+ }
+
}
}
}
-
-}
-}
-}
}
diff --git a/combo/example/src/main/scala/net/liftweb/example/comet/ChatServer.scala b/combo/example/src/main/scala/net/liftweb/example/comet/ChatServer.scala
index af68a88..7073433 100644
--- a/combo/example/src/main/scala/net/liftweb/example/comet/ChatServer.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/comet/ChatServer.scala
@@ -15,52 +15,51 @@
*/
package net.liftweb {
-package example {
-package comet {
+ package example {
+ package comet {
-import _root_.net.liftweb._
-import http._
-import common._
-import actor._
-import util._
-import Helpers._
-import _root_.scala.xml.{NodeSeq, Text}
-import net.liftmodules.textile.TextileParser
-import _root_.java.util.Date
+ import http._
+ import common._
+ import actor._
+ import util._
+ import Helpers._
+ import _root_.scala.xml.{NodeSeq, Text}
+ import net.liftmodules.textile.TextileParser
+ import _root_.java.util.Date
-/**
- * A chat server. It gets messages and returns them
- */
-
-object ChatServer extends LiftActor with ListenerManager {
- private var chats: List[ChatLine] = List(ChatLine("System", Text("Welcome"), now))
+ /**
+ * A chat server. It gets messages and returns them
+ */
+ object ChatServer extends LiftActor with ListenerManager {
+ private var chats: List[ChatLine] = List(
+ ChatLine("System", Text("Welcome"), now))
- override def lowPriority = {
- case ChatServerMsg(user, msg) if msg.length > 0 =>
- chats ::= ChatLine(user, toHtml(msg), timeNow)
- chats = chats.take(50)
- updateListeners()
+ override def lowPriority = {
+ case ChatServerMsg(user, msg) if msg.length > 0 =>
+ chats ::= ChatLine(user, toHtml(msg), now)
+ chats = chats.take(50)
+ updateListeners()
- case _ =>
- }
+ case _ =>
+ }
- def createUpdate = ChatServerUpdate(chats.take(15))
+ def createUpdate = ChatServerUpdate(chats.take(15))
- /**
- * Convert an incoming string into XHTML using Textile Markup
- *
- * @param msg the incoming string
- *
- * @return textile markup for the incoming string
- */
- def toHtml(msg: String): NodeSeq = TextileParser.paraFixer(TextileParser.toHtml(msg, Empty))
+ /**
+ * Convert an incoming string into XHTML using Textile Markup
+ *
+ * @param msg the incoming string
+ *
+ * @return textile markup for the incoming string
+ */
+ def toHtml(msg: String): NodeSeq =
+ TextileParser.paraFixer(TextileParser.toHtml(msg, Empty))
-}
+ }
-case class ChatLine(user: String, msg: NodeSeq, when: Date)
-case class ChatServerMsg(user: String, msg: String)
-case class ChatServerUpdate(msgs: List[ChatLine])
-}
-}
+ case class ChatLine(user: String, msg: NodeSeq, when: Date)
+ case class ChatServerMsg(user: String, msg: String)
+ case class ChatServerUpdate(msgs: List[ChatLine])
+ }
+ }
}
-
diff --git a/combo/example/src/main/scala/net/liftweb/example/comet/Clock.scala b/combo/example/src/main/scala/net/liftweb/example/comet/Clock.scala
index ab798f1..bd1f584 100644
--- a/combo/example/src/main/scala/net/liftweb/example/comet/Clock.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/comet/Clock.scala
@@ -18,7 +18,6 @@ package net.liftweb
package example
package comet
-import _root_.net.liftweb._
import http._
import common._
import util._
@@ -27,22 +26,30 @@ import js._
import JsCmds._
import _root_.scala.xml.{Text, NodeSeq}
-class ExampleClock (initSession: LiftSession,
+class ExampleClock(initSession: LiftSession,
initType: Box[String],
initName: Box[String],
initDefaultXml: NodeSeq,
- initAttributes: Map[String, String]) extends CometActor {
+ initAttributes: Map[String, String])
+ extends CometActor {
// schedule a ping every 10 seconds so we redraw
Schedule.schedule(this, Tick, 10 seconds)
- def render = "#clock_time *" replaceWith timeNow.toString
+ def render = "#clock_time *" #> Text(now.toString)
override def lowPriority = {
case Tick =>
- partialUpdate(SetHtml("clock_time", Text(timeNow.toString)))
+ partialUpdate(SetHtml("clock_time", Text(now.toString)))
Schedule.schedule(this, Tick, 10 seconds)
}
- initCometActor(initSession, initType, initName, initDefaultXml, initAttributes)
+
+ val creationInfo = new CometCreationInfo(initType.orNull,
+ initName,
+ initDefaultXml,
+ initAttributes,
+ initSession)
+
+ initCometActor(creationInfo)
}
case object Tick
diff --git a/combo/example/src/main/scala/net/liftweb/example/comet/LongTime.scala b/combo/example/src/main/scala/net/liftweb/example/comet/LongTime.scala
index 662be22..220e671 100644
--- a/combo/example/src/main/scala/net/liftweb/example/comet/LongTime.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/comet/LongTime.scala
@@ -14,9 +14,7 @@
* limitations under the License.
*/
-package net.liftweb
-package example
-package comet
+package net.liftweb.example.comet
import net.liftweb.actor._
import scala.xml.{NodeSeq, Text}
@@ -90,9 +88,9 @@ class LongTime extends CometActor {
def render =
url match {
case Full(where) =>
- Your job is complete. Click Me
+
case _ =>
- We're working on your job... it's {progress}% complete
+
We're working on your job... it's {progress}% complete
}
}
diff --git a/combo/example/src/main/scala/net/liftweb/example/lib/AsyncRest.scala b/combo/example/src/main/scala/net/liftweb/example/lib/AsyncRest.scala
index 8795fb9..3a9e436 100644
--- a/combo/example/src/main/scala/net/liftweb/example/lib/AsyncRest.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/lib/AsyncRest.scala
@@ -18,9 +18,7 @@ package net.liftweb
package example
package lib
-import net.liftweb._
import http._
-import common._
import rest._
/**
diff --git a/combo/example/src/main/scala/net/liftweb/example/lib/LoginStuff.scala b/combo/example/src/main/scala/net/liftweb/example/lib/LoginStuff.scala
index 2b04e8c..1a28ff1 100644
--- a/combo/example/src/main/scala/net/liftweb/example/lib/LoginStuff.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/lib/LoginStuff.scala
@@ -15,14 +15,13 @@
*/
package net.liftweb {
-package example {
-package lib {
+ package example {
+ package lib {
-import _root_.net.liftweb._
-import http._
+ import http._
-object LoginStuff extends SessionVar(false)
+ object LoginStuff extends SessionVar(false)
-}
-}
+ }
+ }
}
diff --git a/combo/example/src/main/scala/net/liftweb/example/lib/SessionChecker.scala b/combo/example/src/main/scala/net/liftweb/example/lib/SessionChecker.scala
index a37b45b..45834e6 100644
--- a/combo/example/src/main/scala/net/liftweb/example/lib/SessionChecker.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/lib/SessionChecker.scala
@@ -15,38 +15,37 @@
*/
package net.liftweb {
-package example {
-package lib {
+ package example {
+ package lib {
-import _root_.net.liftweb._
-import http._
-import util._
-import Helpers._
-import common._
+ import http._
+ import util._
+ import Helpers._
+ import common._
-object SessionChecker extends Function2[Map[String, SessionInfo],
- SessionInfo => Unit, Unit] with Logger
-{
- def defaultKillWhen = 180000L
- // how long do we wait to kill single browsers
- @volatile var killWhen = defaultKillWhen
+ object SessionChecker
+ extends Function2[Map[String, SessionInfo], SessionInfo => Unit, Unit]
+ with Logger {
+ def defaultKillWhen = 180000L
+ // how long do we wait to kill single browsers
+ @volatile var killWhen = defaultKillWhen
- @volatile var killCnt = 1
+ @volatile var killCnt = 1
- def apply(sessions: Map[String, SessionInfo],
- destroyer: SessionInfo => Unit): Unit = {
- val cutoff = millis - 180000L
-
- sessions.foreach {
- case (name, si @ SessionInfo(session, agent, _, cnt, lastAccess)) =>
- if (cnt <= killCnt && lastAccess < cutoff) {
- info("Purging "+agent)
- destroyer(si)
+ def apply(sessions: Map[String, SessionInfo],
+ destroyer: SessionInfo => Unit): Unit = {
+ val cutoff = millis - 180000L
+
+ sessions.foreach {
+ case (name, si @ SessionInfo(session, agent, _, cnt, lastAccess)) =>
+ if (cnt <= killCnt && lastAccess < cutoff) {
+ info("Purging " + agent)
+ destroyer(si)
+ }
+ }
}
+ }
+
}
}
}
-
-}
-}
-}
diff --git a/combo/example/src/main/scala/net/liftweb/example/lib/StatelessHtml.scala b/combo/example/src/main/scala/net/liftweb/example/lib/StatelessHtml.scala
index 5f4aa0b..196645b 100644
--- a/combo/example/src/main/scala/net/liftweb/example/lib/StatelessHtml.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/lib/StatelessHtml.scala
@@ -15,29 +15,28 @@
*/
package net.liftweb {
-package example {
-package lib {
+ package example {
+ package lib {
-import _root_.net.liftweb._
-import http._
-import common._
+ import http._
+ import common._
-import scala.xml._
+ import scala.xml._
-/**
- * Use Lift's templating without a session and without state
- */
-object StatelessHtml {
- private val fakeSession = new LiftSession("/", "fakeSession", Empty)
+ /**
+ * Use Lift's templating without a session and without state
+ */
+ object StatelessHtml {
+ private val fakeSession = new LiftSession("/", "fakeSession", Empty)
+
+ def render(req: Req)(): Box[LiftResponse] = {
+ val xml: Box[NodeSeq] = S.init(Full(req), fakeSession) {
+ S.runTemplate(List("stateless"))
+ }
+ xml.map(ns => XhtmlResponse(ns(0), Empty, Nil, Nil, 200, false))
+ }
+ }
- def render(req: Req)(): Box[LiftResponse] = {
- val xml: Box[NodeSeq] = S.init(req, fakeSession) {
- S.runTemplate(List("stateless"))
}
- xml.map(ns => XhtmlResponse(ns(0), Empty, Nil, Nil, 200, false))
}
}
-
-}
-}
-}
diff --git a/combo/example/src/main/scala/net/liftweb/example/lib/StatelessJson.scala b/combo/example/src/main/scala/net/liftweb/example/lib/StatelessJson.scala
index 2545929..f6eaec3 100644
--- a/combo/example/src/main/scala/net/liftweb/example/lib/StatelessJson.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/lib/StatelessJson.scala
@@ -14,11 +14,9 @@
* limitations under the License.
*/
-package net.liftweb {
- package example {
- package lib {
+package net.liftweb.example.lib
-import _root_.net.liftweb._
+import net.liftweb._
import http._
import js._
import JsCmds._
@@ -29,29 +27,36 @@ import net.liftmodules.textile._
import scala.xml._
/**
- * Respond to JSON requests in a stateless dispatch
- */
+ * Respond to JSON requests in a stateless dispatch
+ */
object StatelessJson {
def init() {
// register the JSON handler
- LiftRules.statelessDispatch.append{
- case r @ Req("stateless_json_call" :: Nil, _, PostRequest) => () => handleJson(r)
+ LiftRules.statelessDispatch.append {
+ case r @ Req("stateless_json_call" :: Nil, _, PostRequest) =>
+ () =>
+ handleJson(r)
}
}
- implicit def iterableToBox[X](in: Iterable[X]): Box[X] = in.toList.headOption
+ implicit def iterableToBox[X](in: Iterable[X]): Box[X] =
+ in.toList.headOption
def handleJson(req: Req): Box[LiftResponse] =
- for {
- json <- req.json // get the JSON
- JObject(List(JField("command", JString(cmd)), JField("params", JString(params)))) <- json // extract the command
- } yield JavaScriptResponse(SetHtml("json_result",cmd match { // build the response
- case "show" => Text(params)
- case "textile" => TextileParser.toHtml(params, Empty)
- case "count" => Text(params.length+" Characters")
- case x => Problem... didn't handle JSON message {x}
- }))
-}
- }
- }
+ for {
+ json <- req.json // get the JSON
+ JObject(
+ List(JField("command", JString(cmd)),
+ JField("params", JString(params)))) <- json // extract the command
+ } yield
+ JavaScriptResponse(
+ SetHtml(
+ "json_result",
+ cmd match { // build the response
+ case "show" => Text(params)
+ case "textile" => TextileParser.toHtml(params, Empty)
+ case "count" => Text(params.length + " Characters")
+ case x => Problem... didn't handle JSON message {x}
+ }
+ ))
}
diff --git a/combo/example/src/main/scala/net/liftweb/example/lib/WebServices.scala b/combo/example/src/main/scala/net/liftweb/example/lib/WebServices.scala
index c8798e0..fe34df4 100644
--- a/combo/example/src/main/scala/net/liftweb/example/lib/WebServices.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/lib/WebServices.scala
@@ -15,92 +15,91 @@
*/
package net.liftweb {
-package example {
-package lib {
+ package example {
+ package lib {
-import _root_.net.liftweb._
-import http._
-import http.rest._
-import common._
-import json._
-import util._
-import _root_.net.liftweb.example.model._
+ import http._
+ import http.rest._
+ import common._
+ import json._
+ import _root_.net.liftweb.example.model._
-object WebServices extends RestHelper {
- // a JSON-able class that holds a User
- case class UserInfo(firstName: String, lastName: String,
- email: String) {
- def toXml =
- def toJson = Extraction.decompose(this)
- }
-
- // a JSON-able class that holds all the users
- case class AllUsers(users: List[UserInfo]) {
- def toJson = Extraction.decompose(this)
- def toXml = {users.map(_.toXml)}
- }
+ def toJson = Extraction.decompose(this)
+ }
- // define a REST handler for an XML request
- serve {
- case "webservices" :: "all_users" :: _ XmlGet _ =>
- AllUsers(User.findAll()).toXml
- }
+ // a JSON-able class that holds all the users
+ case class AllUsers(users: List[UserInfo]) {
+ def toJson = Extraction.decompose(this)
+ def toXml = {users.map(_.toXml)}
+ }
- // define a REST handler for a JSON reqest
- serve {
- case "webservices" :: "all_users" :: _ JsonGet _ =>
- AllUsers(User.findAll()).toJson
- }
+ // define a REST handler for an XML request
+ serve {
+ case "webservices" :: "all_users" :: _ XmlGet _ =>
+ AllUsers(User.findAll()).toXml
+ }
+ // define a REST handler for a JSON reqest
+ serve {
+ case "webservices" :: "all_users" :: _ JsonGet _ =>
+ AllUsers(User.findAll()).toJson
+ }
- /*
- * While many on the Web use GET requests in this way, a client shouldn't
- * be given the expectation of resource state change or creation
- * through a GET. GET should be idempotent and safe. This doesn't mean
- * that a service couldn't create or modify state as as result
- * (e.g. logging, counting the number of requests, creating business
- * objects). It's just that any such state-related operations should
- * not be visible through GET. In the above example, it is implied
- * that a client could send a GET request in order to create a user.
- *
- * AKA -- don't do it this way in the real world, this is an example
- * of using Scala's guards
- */
+ /*
+ * While many on the Web use GET requests in this way, a client shouldn't
+ * be given the expectation of resource state change or creation
+ * through a GET. GET should be idempotent and safe. This doesn't mean
+ * that a service couldn't create or modify state as as result
+ * (e.g. logging, counting the number of requests, creating business
+ * objects). It's just that any such state-related operations should
+ * not be visible through GET. In the above example, it is implied
+ * that a client could send a GET request in order to create a user.
+ *
+ * AKA -- don't do it this way in the real world, this is an example
+ * of using Scala's guards
+ */
- serveJx[UserInfo] {
- case Req("webservices" :: "add_user" :: _, _, rt) if rt.post_? || rt.get_? =>
- addUser()
- } { // How do we convert a UserInfo to either XML or JSON?
- case (JsonSelect, u, _) => u.toJson
- case (XmlSelect, u, _) => u.toXml
- }
-
- // a couple of helpful conversion rules
- implicit def userToInfo(u: User): UserInfo =
- UserInfo(u.firstName, u.lastName, u.email)
+ serveJx[UserInfo] {
+ case Req("webservices" :: "add_user" :: _, _, rt)
+ if rt.post_? || rt.get_? =>
+ addUser()
+ } { // How do we convert a UserInfo to either XML or JSON?
+ case (JsonSelect, u, _) => u.toJson
+ case (XmlSelect, u, _) => u.toXml
+ }
- implicit def uLstToInfo(ul: List[User]): List[UserInfo] =
- ul.map(userToInfo)
+ // a couple of helpful conversion rules
+ implicit def userToInfo(u: User): UserInfo =
+ UserInfo(u.firstName.get, u.lastName.get, u.email.get)
- // extract the parameters, create a user
- // return the appropriate response
- def addUser(): Box[UserInfo] =
- for {
- firstname <- S.param("firstname") ?~ "firstname parameter missing" ~> 400
- lastname <- S.param("lastname") ?~ "lastname parameter missing"
- email <- S.param("email") ?~ "email parameter missing"
- } yield {
- val u = User.create.firstName(firstname).
- lastName(lastname).email(email)
+ implicit def uLstToInfo(ul: List[User]): List[UserInfo] =
+ ul.map(userToInfo)
- S.param("password") foreach u.password.set
+ // extract the parameters, create a user
+ // return the appropriate response
+ def addUser(): Box[UserInfo] =
+ for {
+ firstname <- S.param("firstname") ?~ "firstname parameter missing" ~> 400
+ lastname <- S.param("lastname") ?~ "lastname parameter missing"
+ email <- S.param("email") ?~ "email parameter missing"
+ } yield {
+ val u =
+ User.create.firstName(firstname).lastName(lastname).email(email)
- u.saveMe
- }
-}
+ S.param("password") foreach u.password.set
-}
-}
+ u.saveMe
+ }
+ }
+
+ }
+ }
}
diff --git a/combo/example/src/main/scala/net/liftweb/example/lib/WikiStuff.scala b/combo/example/src/main/scala/net/liftweb/example/lib/WikiStuff.scala
index 60fc94c..daae4a4 100644
--- a/combo/example/src/main/scala/net/liftweb/example/lib/WikiStuff.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/lib/WikiStuff.scala
@@ -14,9 +14,7 @@
* limitations under the License.
*/
-package net.liftweb {
-package example {
-package lib {
+package net.liftweb.example.lib
import _root_.net.liftweb._
import net.liftmodules.textile._
@@ -34,25 +32,25 @@ import model._
import scala.xml.{Text, NodeSeq}
/**
- * A wiki location
- *
- * @param page - the name of the page
- * @param edit - are we viewing or editing the page?
- */
+ * A wiki location
+ *
+ * @param page - the name of the page
+ * @param edit - are we viewing or editing the page?
+ */
case class WikiLoc(page: String, edit: Boolean) {
/**
- * Get the underly database record for this page
- */
+ * Get the underly database record for this page
+ */
lazy val record: WikiEntry =
- WikiEntry.find(By(WikiEntry.name, page)) openOr
- WikiEntry.create.name(page)
+ WikiEntry.find(By(WikiEntry.name, page)) openOr
+ WikiEntry.create.name(page)
}
/**
- * The WikiStuff object that provides menu, URL rewriting,
- * and snippet support for the page that displays wiki contents
- */
+ * The WikiStuff object that provides menu, URL rewriting,
+ * and snippet support for the page that displays wiki contents
+ */
object WikiStuff extends Loc[WikiLoc] {
object AllLoc extends WikiLoc("all", false)
@@ -62,79 +60,80 @@ object WikiStuff extends Loc[WikiLoc] {
// the default parameters (used for generating the menu listing)
def defaultValue = Full(WikiLoc("HomePage", false))
+ // def text = S.loc("Wiki HomePage")
// no extra parameters
- def params = List(Unless(() => Props.inGAE || Props.productionMode, "Disabled for GAE"))
+ def params =
+ List(Unless(() => Props.inGAE || Props.productionMode, "Disabled for GAE"), LocGroup("topNav"))
// is the current page an "edit" or "view"
def currentEdit = requestValue.is.map(_.edit) openOr false
/**
- * Check for page-specific snippets and
- * do appropriate dispatching
- */
+ * Check for page-specific snippets and
+ * do appropriate dispatching
+ */
override val snippets: SnippetTest = {
- case ("wiki", Full(AllLoc)) => showAll _
- case ("wiki", Full(wp @ WikiLoc(_ , true))) => editRecord(wp.record) _
- case ("wiki", Full(wp @ WikiLoc(_ , false)))
- if !wp.record.saved_? => editRecord(wp.record) _
+ case ("wiki", Full(AllLoc)) => showAll _
+ case ("wiki", Full(wp @ WikiLoc(_, true))) => editRecord(wp.record) _
+ case ("wiki", Full(wp @ WikiLoc(_, false))) if !wp.record.saved_? =>
+ editRecord(wp.record) _
case ("wiki", Full(wp: WikiLoc)) => displayRecord(wp.record) _
}
-
/**
- * Generate a link based on the current page
- */
+ * Generate a link based on the current page
+ */
val link =
- new Loc.Link[WikiLoc](List("wiki"), false) {
- override def createLink(in: WikiLoc) = {
- if (in.edit)
- Full(Text("/wiki/edit/"+urlEncode(in.page)))
- else
- Full(Text("/wiki/"+urlEncode(in.page)))
+ new Loc.Link[WikiLoc](List("wiki"), false) {
+ override def createLink(in: WikiLoc) = {
+ if (in.edit)
+ Full(Text("/wiki/edit/" + urlEncode(in.page)))
+ else
+ Full(Text("/wiki/" + urlEncode(in.page)))
+ }
}
- }
/**
- * What's the text of the link?
- */
+ * What's the text of the link?
+ */
val text = new Loc.LinkText(calcLinkText _)
-
def calcLinkText(in: WikiLoc): NodeSeq =
- if (in.edit)
- Text("Wiki edit "+in.page)
- else
- Text("Wiki "+in.page)
+ if (in.edit)
+ S.loc("Wiki edit " + in.page, Text("Wiki edit " + in.page))
+ else
+ S.loc("Wiki " + in.page, Text("Wiki " + in.page))
/**
- * Rewrite the request and emit the type-safe parameter
- */
+ * Rewrite the request and emit the type-safe parameter
+ */
override val rewrite: LocRewrite =
- Full(NamedPF("Wiki Rewrite") {
- case RewriteRequest(ParsePath("wiki" :: "edit" :: page :: Nil, _, _,_),
- _, _) =>
- (RewriteResponse("wiki" :: Nil), WikiLoc(page, true))
+ Full(NamedPF("Wiki Rewrite") {
+ case RewriteRequest(ParsePath("wiki" :: "edit" :: page :: Nil, _, _, _),
+ _,
+ _) =>
+ (RewriteResponse("wiki" :: Nil), Full(WikiLoc(page, true)))
- case RewriteRequest(ParsePath("wiki" :: page :: Nil, _, _,_),
- _, _) =>
- (RewriteResponse("wiki" :: Nil), WikiLoc(page, false))
+ case RewriteRequest(ParsePath("wiki" :: page :: Nil, _, _, _), _, _) =>
+ (RewriteResponse("wiki" :: Nil), Full(WikiLoc(page, false)))
})
def showAll(in: NodeSeq): NodeSeq =
- WikiEntry.findAll(OrderBy(WikiEntry.name, Ascending)).flatMap(entry =>
- )
+ WikiEntry
+ .findAll(OrderBy(WikiEntry.name, Ascending))
+ .flatMap(entry =>
+ )
def url(page: String) = createLink(WikiLoc(page, false))
-
def editRecord(r: WikiEntry)(in: NodeSeq): NodeSeq =
-
+
Show All Pages
{
val isNew = !r.saved_?
- val pageName = r.name.is
+ val pageName = r.name.get
val action = url(pageName)
val message =
if (isNew)
@@ -142,16 +141,16 @@ object WikiStuff extends Loc[WikiLoc] {
else
Text("Edit entry named "+pageName)
- val hobixLink = Textile Markup Reference
+ val texMarkRefLink = Textile Markup Reference
- val cancelLink = Cancel
+ val cancelLink = Cancel
val textarea = r.entry.toForm
- val submitButton = SHtml.submit(isNew ? "Add" | "Edit", () => r.save)
+ val submitButton = SHtml.submit(isNew ? "Add" | "Edit", () => r.save, "class" -> "btn btn-primary")
def displayRecord(entry: WikiEntry)(in: NodeSeq): NodeSeq =
-
+
Show All Pages
- {TextileParser.toHtml(entry.entry, textileWriter)}
+ {TextileParser.toHtml(entry.entry.get, textileWriter)}
- Edit
+ Edit
import TextileParser._
@@ -176,13 +175,9 @@ object WikiStuff extends Loc[WikiLoc] {
info match {
case WikiURLInfo(page, _) =>
(stringUrl(page), Text(page), None)
- })
+ })
def stringUrl(page: String): String =
- url(page).map(_.text) getOrElse ""
-
+ url(page).map(_.text) getOrElse ""
}
-}
-}
-}
diff --git a/combo/example/src/main/scala/net/liftweb/example/lib/XmlServer.scala b/combo/example/src/main/scala/net/liftweb/example/lib/XmlServer.scala
index 9727079..d6a2189 100644
--- a/combo/example/src/main/scala/net/liftweb/example/lib/XmlServer.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/lib/XmlServer.scala
@@ -15,30 +15,28 @@
*/
package net.liftweb {
-package example {
-package lib {
-
-import _root_.net.liftweb._
-import http._
-import common._
-import util._
-import Helpers._
-
-object XmlServer {
- def init() {
- LiftRules.dispatch.prepend(NamedPF("Web Services Example") {
- // if the url is "showcities" then return the showCities function
- case Req("showcities":: Nil, _, GetRequest) => XmlServer.showCities
-
- // if the url is "showstates" "curry" the showStates function with the optional second parameter
- case Req("showstates":: xs, _, GetRequest) =>
- XmlServer.showStates(if (xs.isEmpty) "default" else xs.head)
- })
- }
-
- def showStates(which: String)(): Box[XmlResponse] =
- Full(XmlResponse(
- {
+ package example {
+ package lib {
+
+ import http._
+ import common._
+ import util._
+ import Helpers._
+
+ object XmlServer {
+ def init() {
+ LiftRules.dispatch.prepend(NamedPF("Web Services Example") {
+ // if the url is "showcities" then return the showCities function
+ case Req("showcities" :: Nil, _, GetRequest) => XmlServer.showCities
+
+ // if the url is "showstates" "curry" the showStates function with the optional second parameter
+ case Req("showstates" :: xs, _, GetRequest) =>
+ XmlServer.showStates(if (xs.isEmpty) "default" else xs.head)
+ })
+ }
+
+ def showStates(which: String)(): Box[XmlResponse] =
+ Full(XmlResponse({
which match {
case "red" =>
@@ -48,16 +46,15 @@ object XmlServer {
} }
))
- def showCities(): Box[XmlResponse] =
- Full(XmlResponse(
-
+ def showCities(): Box[XmlResponse] =
+ Full(XmlResponse(
))
-}
-}
-}
+ }
+ }
+ }
}
diff --git a/combo/example/src/main/scala/net/liftweb/example/model/Person.scala b/combo/example/src/main/scala/net/liftweb/example/model/Person.scala
index 4231d22..f68ab27 100644
--- a/combo/example/src/main/scala/net/liftweb/example/model/Person.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/model/Person.scala
@@ -14,37 +14,38 @@
* limitations under the License.
*/
-package net.liftweb {
-package example {
-package model {
+package net.liftweb.example.model
import _root_.net.liftweb._
import mapper._
-import common._
import util._
object Person extends Person with LongKeyedMetaMapper[Person]
class Person extends LongKeyedMapper[Person] with IdPK {
- def getSingleton = Person
-
- object firstName extends MappedString(this, 100) {
- override def validations = valMinLen(2, "First name must be 2 characters long") _ :: super.validations
- }
- object lastName extends MappedString(this, 100)
-
- object personalityType extends MappedEnum(this, Personality)
+ val common_bs_classes = Seq("class" -> "form-control")
+ def getSingleton = Person
+
+ object firstName extends MappedString(this, 100) {
+ override def formElemAttrs = common_bs_classes
+ override def validations =
+ valMinLen(2, "First name must be 2 characters long") _ :: super.validations
+ }
+ object lastName extends MappedString(this, 100) {
+ override def formElemAttrs = common_bs_classes
+ }
+
+ object personalityType extends MappedEnum(this, Personality) {
+ override def formElemAttrs = common_bs_classes
+ }
}
object Personality extends Enumeration {
- val TypeA = Value(1, "Type A")
- val TypeB = Value(2, "Type B")
- val ENTJ = Value(3, "ENTJ")
- val INTJ = Value(4, "INTJ")
+ val TypeA = Value(1, "Type A")
+ val TypeB = Value(2, "Type B")
+ val ENTJ = Value(3, "ENTJ")
+ val INTJ = Value(4, "INTJ")
- val allTypes = Array(TypeA, TypeB, ENTJ, INTJ)
- def rand = allTypes(Helpers.randomInt(allTypes.length))
-}
-}
-}
+ val allTypes = Array(TypeA, TypeB, ENTJ, INTJ)
+ def rand = allTypes(Helpers.randomInt(allTypes.length))
}
diff --git a/combo/example/src/main/scala/net/liftweb/example/model/User.scala b/combo/example/src/main/scala/net/liftweb/example/model/User.scala
index 4cb8262..9ea8380 100644
--- a/combo/example/src/main/scala/net/liftweb/example/model/User.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/model/User.scala
@@ -14,38 +14,33 @@
* limitations under the License.
*/
-package net.liftweb {
-package example {
-package model {
+package net.liftweb.example.model
import _root_.net.liftweb._
import mapper._
/**
- * The singleton that has methods for accessing the database
- */
+ * The singleton that has methods for accessing the database
+ */
object User extends User with KeyedMetaMapper[Long, User] {
override def dbTableName = "users" // define the DB table name
// define the order fields will appear in forms and output
- override lazy val fieldOrder = List(id, firstName, lastName,
- email, password, textArea)
+ override lazy val fieldOrder =
+ List(id, firstName, lastName, email, password, textArea)
}
/**
- * An O-R mapped "User" class that includes first name, last name,
- * password and we add a "Personal Essay" to it
- */
+ * An O-R mapped "User" class that includes first name, last name,
+ * password and we add a "Personal Essay" to it
+ */
class User extends ProtoUser[User] {
def getSingleton = User
// define an additional field for a personal essay
object textArea extends MappedTextarea(this, 2048) {
- override def textareaRows = 10
+ override def textareaRows = 10
override def textareaCols = 50
override def displayName = "Personal Essay"
}
}
-}
-}
-}
diff --git a/combo/example/src/main/scala/net/liftweb/example/model/WikiEntry.scala b/combo/example/src/main/scala/net/liftweb/example/model/WikiEntry.scala
index fd607e7..f357bad 100644
--- a/combo/example/src/main/scala/net/liftweb/example/model/WikiEntry.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/model/WikiEntry.scala
@@ -15,33 +15,33 @@
*/
package net.liftweb {
-package example {
-package model {
+ package example {
+ package model {
-import _root_.net.liftweb.mapper._
+ import _root_.net.liftweb.mapper._
-/**
- * The singleton that has methods for accessing the database
- */
-object WikiEntry extends WikiEntry with LongKeyedMetaMapper[WikiEntry]
+ /**
+ * The singleton that has methods for accessing the database
+ */
+ object WikiEntry extends WikiEntry with LongKeyedMetaMapper[WikiEntry]
-/**
- * An O-R mapped wiki entry
- */
-class WikiEntry extends LongKeyedMapper[WikiEntry] with IdPK {
- def getSingleton = WikiEntry // what's the "meta" object
+ /**
+ * An O-R mapped wiki entry
+ */
+ class WikiEntry extends LongKeyedMapper[WikiEntry] with IdPK {
+ def getSingleton = WikiEntry // what's the "meta" object
- // the name of the entry
- object name extends MappedString(this, 32) {
- override def dbIndexed_? = true // indexed in the DB
- }
+ // the name of the entry
+ object name extends MappedString(this, 32) {
+ override def dbIndexed_? = true // indexed in the DB
+ }
- // the text of the entry
- object entry extends MappedTextarea(this, 8192) {
- override def textareaRows = 10
- override def textareaCols = 50
+ // the text of the entry
+ object entry extends MappedTextarea(this, 8192) {
+ override def textareaRows = 10
+ override def textareaCols = 50
+ }
+ }
+ }
}
}
-}
-}
-}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/Ajax.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/Ajax.scala
index 3148bca..70ddb6a 100644
--- a/combo/example/src/main/scala/net/liftweb/example/snippet/Ajax.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/Ajax.scala
@@ -14,23 +14,20 @@
* limitations under the License.
*/
-package net.liftweb {
-package example {
-package snippet {
+package net.liftweb.example.snippet
-import _root_.net.liftweb.http._
-import _root_.net.liftmodules.widgets.autocomplete._
-import S._
+import net.liftweb._
+import http._
import SHtml._
import js._
import js.jquery._
-import http.jquery._
import JqJsCmds._
import JsCmds._
import common._
import util._
import Helpers._
-import _root_.scala.xml.{Text, NodeSeq}
+import net.liftmodules.widgets.autocomplete._
+import scala.xml.{Text, NodeSeq}
class Ajax extends Loggable {
@@ -44,47 +41,66 @@ class Ajax extends Loggable {
// build up an ajax tag to increment the counter
def doClicker(text: NodeSeq) =
- a(() => {cnt = cnt + 1; SetHtml(spanName, Text( cnt.toString))}, text)
+ a(() => { cnt = cnt + 1; SetHtml(spanName, Text(cnt.toString)) }, text)
// create an ajax select box
def doSelect(msg: NodeSeq) =
- ajaxSelect((1 to 50).toList.map(i => (i.toString, i.toString)),
- Full(1.toString),
- v => DisplayMessage(msgName,
- bind("sel", msg, "number" -> Text(v)),
- 5 seconds, 1 second))
+ ajaxSelect(
+ (1 to 50).toList.map(i => (i.toString, i.toString)),
+ Full(1.toString),
+ v => {
+ val selectBind = "#selNumber" #> Text(v)
+ DisplayMessage(
+ msgName,
+ {selectBind(msg)} ,
+ 5 seconds,
+ 1 second
+ )
+ },
+ "class" -> "form-control"
+ )
// build up an ajax text box
def doText(msg: NodeSeq) =
- ajaxText("", v => DisplayMessage(msgName,
- bind("text", msg, "value" -> Text(v)),
- 4 seconds, 1 second))
-
-
+ ajaxText(
+ "",
+ v => {
+ val textBind = "#textValue" #> Text(v)
+ DisplayMessage(msgName,
+ {textBind(msg)} ,
+ 6 seconds,
+ 1 second)
+ },
+ "class" -> "form-control"
+ )
// bind the view to the functionality
- bind("ajax", xhtml,
- "clicker" -> doClicker _,
- "select" -> doSelect _,
- "text" -> doText _,
- "auto" -> AutoComplete("", buildQuery _, _ => ()))
+ val viewBind = {
+ "#ajaxClicker" #> doClicker _ &
+ "#ajaxSelect" #> doSelect _ &
+ "#ajaxText" #> doText _ &
+ "#ajaxAuto" #> AutoComplete("",
+ buildQuery _,
+ (x: String) => (),
+ "class" -> "form-control")
+ }
+ viewBind(xhtml)
}
private def buildQuery(current: String, limit: Int): Seq[String] = {
- logger.info("Checking on server side with "+current+" limit "+limit)
- (1 to limit).map(n => current+""+n)
+ logger.info("Checking on server side with " + current + " limit " + limit)
+ (1 to limit).map(n => current + "" + n)
}
- def time = Text(timeNow.toString)
+ def time = Text(now.toString)
def buttonClick = {
import js.JE._
- "* [onclick]" #> SHtml.ajaxCall(ValById("the_input"),
- s => SetHtml("messages",
- Text box is {s} ))
+ "* [onclick]" #> SHtml.ajaxCall(
+ ValById("the_input"),
+ s =>
+ SetHtml("bcmessages",
+ Latest Button click was with text box value '{s}' ))
}
}
-}
-}
-}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/AjaxForm.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/AjaxForm.scala
index aa2714a..7f34d8a 100644
--- a/combo/example/src/main/scala/net/liftweb/example/snippet/AjaxForm.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/AjaxForm.scala
@@ -19,7 +19,6 @@ package example
package snippet
import _root_.scala.xml._
-import _root_.net.liftweb._
import http._
import S._
import SHtml._
@@ -38,295 +37,296 @@ class AjaxForm {
val first = cities.head
// make the select "untrusted" because we might put new values
// in the select
- untrustedSelect(cities.map(s => (s,s)), Full(first), s => city = s)
+ untrustedSelect(cities.map(s => (s, s)),
+ Full(first),
+ s => city = s,
+ "class" -> "form-control")
}
private def replace(state: String): JsCmd = {
val cities = AjaxForm.citiesFor(state)
val first = cities.head
- ReplaceOptions("city_select", cities.map(s => (s,s)), Full(first))
+ ReplaceOptions("city", cities.map(s => (s, s)), Full(first))
}
-
- // bind the view to the dynamic HTML
- def show(xhtml: Group): NodeSeq = {
- val (name: String, js): (String, JsExp) = ajaxCall(JE.JsRaw("this.value"),
- s => After(200, replace(s)))
- bind("select", xhtml,
- "state" -> select(AjaxForm.states.map(s => (s,s)),
- Full(state), s => state = s, "onchange" -> js.toJsCmd) %
- (new PrefixedAttribute("lift", "gc", name, Null)),
- "city" -> cityChoice(state) % ("id" -> "city_select"),
- "submit" -> submit(?("Save"),
- () =>
- {S.notice("City: "+city+" State: "+state);
- redirectTo("/")}))
+ def render = {
+ "#state" #> ajaxSelect(AjaxForm.states.map(s => (s, s)), Full(state), { s =>
+ state = s; After(200, replace(state))
+ }, "class" -> "form-control") &
+ "#city" #> cityChoice(state) &
+ "type=submit" #> submit(?("Save"), () => {
+ S.notice("City: " + city + ", State: " + state);
+ redirectTo("#stateForm")
+ }, "class" -> "btn btn-primary")
}
}
object AjaxForm {
- val citiesAndStates = List("Alabama" -> "Birmingham",
- "Alabama" -> "Huntsville",
- "Alabama" -> "Mobile",
- "Alabama" -> "Montgomery",
- "Alaska" -> "Anchorage municipality",
- "Arizona" -> "Chandler",
- "Arizona" -> "Gilbert town",
- "Arizona" -> "Glendale",
- "Arizona" -> "Mesa",
- "Arizona" -> "Peoria",
- "Arizona" -> "Phoenix",
- "Arizona" -> "Scottsdale",
- "Arizona" -> "Tempe",
- "Arizona" -> "Tucson",
- "Arkansas" -> "Little Rock",
- "California" -> "Anaheim",
- "California" -> "Antioch",
- "California" -> "Bakersfield",
- "California" -> "Berkeley",
- "California" -> "Burbank",
- "California" -> "Chula Vista",
- "California" -> "Concord",
- "California" -> "Corona",
- "California" -> "Costa Mesa",
- "California" -> "Daly City",
- "California" -> "Downey",
- "California" -> "El Monte",
- "California" -> "Elk Grove",
- "California" -> "Escondido",
- "California" -> "Fairfield",
- "California" -> "Fontana",
- "California" -> "Fremont",
- "California" -> "Fresno",
- "California" -> "Fullerton",
- "California" -> "Garden Grove",
- "California" -> "Glendale",
- "California" -> "Hayward",
- "California" -> "Huntington Beach",
- "California" -> "Inglewood",
- "California" -> "Irvine",
- "California" -> "Lancaster",
- "California" -> "Long Beach",
- "California" -> "Los Angeles",
- "California" -> "Modesto",
- "California" -> "Moreno Valley",
- "California" -> "Norwalk",
- "California" -> "Oakland",
- "California" -> "Oceanside",
- "California" -> "Ontario",
- "California" -> "Orange",
- "California" -> "Oxnard",
- "California" -> "Palmdale",
- "California" -> "Pasadena",
- "California" -> "Pomona",
- "California" -> "Rancho Cucamonga",
- "California" -> "Richmond",
- "California" -> "Riverside",
- "California" -> "Roseville",
- "California" -> "Sacramento",
- "California" -> "Salinas",
- "California" -> "San Bernardino",
- "California" -> "San Buenaventura (Ventura)",
- "California" -> "San Diego",
- "California" -> "San Francisco",
- "California" -> "San Jose",
- "California" -> "Santa Ana",
- "California" -> "Santa Clara",
- "California" -> "Santa Clarita",
- "California" -> "Santa Rosa",
- "California" -> "Simi Valley",
- "California" -> "Stockton",
- "California" -> "Sunnyvale",
- "California" -> "Thousand Oaks",
- "California" -> "Torrance",
- "California" -> "Vallejo",
- "California" -> "Visalia",
- "California" -> "West Covina",
- "Colorado" -> "Arvada",
- "Colorado" -> "Aurora",
- "Colorado" -> "Colorado Springs",
- "Colorado" -> "Denver",
- "Colorado" -> "Fort Collins",
- "Colorado" -> "Lakewood",
- "Colorado" -> "Pueblo",
- "Colorado" -> "Thornton",
- "Colorado" -> "Westminster",
- "Connecticut" -> "Bridgeport",
- "Connecticut" -> "Hartford",
- "Connecticut" -> "New Haven",
- "Connecticut" -> "Stamford",
- "Connecticut" -> "Waterbury",
- "District of Columbia" -> "Washington",
- "Florida" -> "Cape Coral",
- "Florida" -> "Clearwater",
- "Florida" -> "Coral Springs",
- "Florida" -> "Fort Lauderdale",
- "Florida" -> "Gainesville",
- "Florida" -> "Hialeah",
- "Florida" -> "Hollywood",
- "Florida" -> "Jacksonville",
- "Florida" -> "Miami",
- "Florida" -> "Miramar",
- "Florida" -> "Orlando",
- "Florida" -> "Pembroke Pines",
- "Florida" -> "Pompano Beach",
- "Florida" -> "Port St. Lucie",
- "Florida" -> "St. Petersburg",
- "Florida" -> "Tallahassee",
- "Florida" -> "Tampa",
- "Georgia" -> "Athens-Clarke County (balance)",
- "Georgia" -> "Atlanta",
- "Georgia" -> "Augusta-Richmond County (balance)",
- "Georgia" -> "Columbus",
- "Georgia" -> "Savannah",
- "Hawaii" -> "Honolulu CDP",
- "Idaho" -> "Boise City",
- "Illinois" -> "Aurora",
- "Illinois" -> "Chicago",
- "Illinois" -> "Elgin",
- "Illinois" -> "Joliet",
- "Illinois" -> "Naperville",
- "Illinois" -> "Peoria",
- "Illinois" -> "Rockford",
- "Illinois" -> "Springfield",
- "Indiana" -> "Evansville",
- "Indiana" -> "Fort Wayne",
- "Indiana" -> "Indianapolis city (balance)",
- "Indiana" -> "South Bend",
- "Iowa" -> "Cedar Rapids",
- "Iowa" -> "Des Moines",
- "Kansas" -> "Kansas City",
- "Kansas" -> "Olathe",
- "Kansas" -> "Overland Park",
- "Kansas" -> "Topeka",
- "Kansas" -> "Wichita",
- "Kentucky" -> "Lexington-Fayette",
- "Kentucky" -> "Louisville/Jefferson County (balance)",
- "Louisiana" -> "Baton Rouge",
- "Louisiana" -> "Lafayette",
- "Louisiana" -> "New Orleans",
- "Louisiana" -> "Shreveport",
- "Maryland" -> "Baltimore",
- "Massachusetts" -> "Boston",
- "Massachusetts" -> "Cambridge",
- "Massachusetts" -> "Lowell",
- "Massachusetts" -> "Springfield",
- "Massachusetts" -> "Worcester",
- "Michigan" -> "Ann Arbor",
- "Michigan" -> "Detroit",
- "Michigan" -> "Flint",
- "Michigan" -> "Grand Rapids",
- "Michigan" -> "Lansing",
- "Michigan" -> "Sterling Heights",
- "Michigan" -> "Warren",
- "Minnesota" -> "Minneapolis",
- "Minnesota" -> "St. Paul",
- "Mississippi" -> "Jackson",
- "Missouri" -> "Independence",
- "Missouri" -> "Kansas City",
- "Missouri" -> "Springfield",
- "Missouri" -> "St. Louis",
- "Montana" -> "Billings",
- "Nebraska" -> "Lincoln",
- "Nebraska" -> "Omaha",
- "Nevada" -> "Henderson",
- "Nevada" -> "Las Vegas",
- "Nevada" -> "North Las Vegas",
- "Nevada" -> "Reno",
- "New Hampshire" -> "Manchester",
- "New Jersey" -> "Elizabeth",
- "New Jersey" -> "Jersey City",
- "New Jersey" -> "Newark",
- "New Jersey" -> "Paterson",
- "New Mexico" -> "Albuquerque",
- "New York" -> "Buffalo",
- "New York" -> "New York",
- "New York" -> "Rochester",
- "New York" -> "Syracuse",
- "New York" -> "Yonkers",
- "North Carolina" -> "Cary town",
- "North Carolina" -> "Charlotte",
- "North Carolina" -> "Durham",
- "North Carolina" -> "Fayetteville",
- "North Carolina" -> "Greensboro",
- "North Carolina" -> "Raleigh",
- "North Carolina" -> "Winston-Salem",
- "Ohio" -> "Akron",
- "Ohio" -> "Cincinnati",
- "Ohio" -> "Cleveland",
- "Ohio" -> "Columbus",
- "Ohio" -> "Dayton",
- "Ohio" -> "Toledo",
- "Oklahoma" -> "Norman",
- "Oklahoma" -> "Oklahoma City",
- "Oklahoma" -> "Tulsa",
- "Oregon" -> "Eugene",
- "Oregon" -> "Portland",
- "Oregon" -> "Salem",
- "Pennsylvania" -> "Allentown",
- "Pennsylvania" -> "Erie",
- "Pennsylvania" -> "Philadelphia",
- "Pennsylvania" -> "Pittsburgh",
- "Rhode Island" -> "Providence",
- "South Carolina" -> "Charleston",
- "South Carolina" -> "Columbia",
- "South Dakota" -> "Sioux Falls",
- "Tennessee" -> "Chattanooga",
- "Tennessee" -> "Clarksville",
- "Tennessee" -> "Knoxville",
- "Tennessee" -> "Memphis",
- "Tennessee" -> "Nashville-Davidson (balance)",
- "Texas" -> "Abilene",
- "Texas" -> "Amarillo",
- "Texas" -> "Arlington",
- "Texas" -> "Austin",
- "Texas" -> "Beaumont",
- "Texas" -> "Brownsville",
- "Texas" -> "Carrollton",
- "Texas" -> "Corpus Christi",
- "Texas" -> "Dallas",
- "Texas" -> "Denton",
- "Texas" -> "El Paso",
- "Texas" -> "Fort Worth",
- "Texas" -> "Garland",
- "Texas" -> "Grand Prairie",
- "Texas" -> "Houston",
- "Texas" -> "Irving",
- "Texas" -> "Killeen",
- "Texas" -> "Laredo",
- "Texas" -> "Lubbock",
- "Texas" -> "McAllen",
- "Texas" -> "McKinney",
- "Texas" -> "Mesquite",
- "Texas" -> "Midland",
- "Texas" -> "Pasadena",
- "Texas" -> "Plano",
- "Texas" -> "San Antonio",
- "Texas" -> "Waco",
- "Utah" -> "Provo",
- "Utah" -> "Salt Lake City",
- "Utah" -> "West Valley City",
- "Virginia" -> "Alexandria",
- "Virginia" -> "Arlington CDP",
- "Virginia" -> "Chesapeake",
- "Virginia" -> "Hampton",
- "Virginia" -> "Newport News",
- "Virginia" -> "Norfolk",
- "Virginia" -> "Portsmouth",
- "Virginia" -> "Richmond",
- "Virginia" -> "Virginia Beach",
- "Washington" -> "Bellevue",
- "Washington" -> "Seattle",
- "Washington" -> "Spokane",
- "Washington" -> "Tacoma",
- "Washington" -> "Vancouver",
- "Wisconsin" -> "Green Bay",
- "Wisconsin" -> "Madison",
- "Wisconsin" -> "Milwaukee")
+ val citiesAndStates = List(
+ "Alabama" -> "Birmingham",
+ "Alabama" -> "Huntsville",
+ "Alabama" -> "Mobile",
+ "Alabama" -> "Montgomery",
+ "Alaska" -> "Anchorage municipality",
+ "Arizona" -> "Chandler",
+ "Arizona" -> "Gilbert town",
+ "Arizona" -> "Glendale",
+ "Arizona" -> "Mesa",
+ "Arizona" -> "Peoria",
+ "Arizona" -> "Phoenix",
+ "Arizona" -> "Scottsdale",
+ "Arizona" -> "Tempe",
+ "Arizona" -> "Tucson",
+ "Arkansas" -> "Little Rock",
+ "California" -> "Anaheim",
+ "California" -> "Antioch",
+ "California" -> "Bakersfield",
+ "California" -> "Berkeley",
+ "California" -> "Burbank",
+ "California" -> "Chula Vista",
+ "California" -> "Concord",
+ "California" -> "Corona",
+ "California" -> "Costa Mesa",
+ "California" -> "Daly City",
+ "California" -> "Downey",
+ "California" -> "El Monte",
+ "California" -> "Elk Grove",
+ "California" -> "Escondido",
+ "California" -> "Fairfield",
+ "California" -> "Fontana",
+ "California" -> "Fremont",
+ "California" -> "Fresno",
+ "California" -> "Fullerton",
+ "California" -> "Garden Grove",
+ "California" -> "Glendale",
+ "California" -> "Hayward",
+ "California" -> "Huntington Beach",
+ "California" -> "Inglewood",
+ "California" -> "Irvine",
+ "California" -> "Lancaster",
+ "California" -> "Long Beach",
+ "California" -> "Los Angeles",
+ "California" -> "Modesto",
+ "California" -> "Moreno Valley",
+ "California" -> "Norwalk",
+ "California" -> "Oakland",
+ "California" -> "Oceanside",
+ "California" -> "Ontario",
+ "California" -> "Orange",
+ "California" -> "Oxnard",
+ "California" -> "Palmdale",
+ "California" -> "Pasadena",
+ "California" -> "Pomona",
+ "California" -> "Rancho Cucamonga",
+ "California" -> "Richmond",
+ "California" -> "Riverside",
+ "California" -> "Roseville",
+ "California" -> "Sacramento",
+ "California" -> "Salinas",
+ "California" -> "San Bernardino",
+ "California" -> "San Buenaventura (Ventura)",
+ "California" -> "San Diego",
+ "California" -> "San Francisco",
+ "California" -> "San Jose",
+ "California" -> "Santa Ana",
+ "California" -> "Santa Clara",
+ "California" -> "Santa Clarita",
+ "California" -> "Santa Rosa",
+ "California" -> "Simi Valley",
+ "California" -> "Stockton",
+ "California" -> "Sunnyvale",
+ "California" -> "Thousand Oaks",
+ "California" -> "Torrance",
+ "California" -> "Vallejo",
+ "California" -> "Visalia",
+ "California" -> "West Covina",
+ "Colorado" -> "Arvada",
+ "Colorado" -> "Aurora",
+ "Colorado" -> "Colorado Springs",
+ "Colorado" -> "Denver",
+ "Colorado" -> "Fort Collins",
+ "Colorado" -> "Lakewood",
+ "Colorado" -> "Pueblo",
+ "Colorado" -> "Thornton",
+ "Colorado" -> "Westminster",
+ "Connecticut" -> "Bridgeport",
+ "Connecticut" -> "Hartford",
+ "Connecticut" -> "New Haven",
+ "Connecticut" -> "Stamford",
+ "Connecticut" -> "Waterbury",
+ "District of Columbia" -> "Washington",
+ "Florida" -> "Cape Coral",
+ "Florida" -> "Clearwater",
+ "Florida" -> "Coral Springs",
+ "Florida" -> "Fort Lauderdale",
+ "Florida" -> "Gainesville",
+ "Florida" -> "Hialeah",
+ "Florida" -> "Hollywood",
+ "Florida" -> "Jacksonville",
+ "Florida" -> "Miami",
+ "Florida" -> "Miramar",
+ "Florida" -> "Orlando",
+ "Florida" -> "Pembroke Pines",
+ "Florida" -> "Pompano Beach",
+ "Florida" -> "Port St. Lucie",
+ "Florida" -> "St. Petersburg",
+ "Florida" -> "Tallahassee",
+ "Florida" -> "Tampa",
+ "Georgia" -> "Athens-Clarke County (balance)",
+ "Georgia" -> "Atlanta",
+ "Georgia" -> "Augusta-Richmond County (balance)",
+ "Georgia" -> "Columbus",
+ "Georgia" -> "Savannah",
+ "Hawaii" -> "Honolulu CDP",
+ "Idaho" -> "Boise City",
+ "Illinois" -> "Aurora",
+ "Illinois" -> "Chicago",
+ "Illinois" -> "Elgin",
+ "Illinois" -> "Joliet",
+ "Illinois" -> "Naperville",
+ "Illinois" -> "Peoria",
+ "Illinois" -> "Rockford",
+ "Illinois" -> "Springfield",
+ "Indiana" -> "Evansville",
+ "Indiana" -> "Fort Wayne",
+ "Indiana" -> "Indianapolis city (balance)",
+ "Indiana" -> "South Bend",
+ "Iowa" -> "Cedar Rapids",
+ "Iowa" -> "Des Moines",
+ "Kansas" -> "Kansas City",
+ "Kansas" -> "Olathe",
+ "Kansas" -> "Overland Park",
+ "Kansas" -> "Topeka",
+ "Kansas" -> "Wichita",
+ "Kentucky" -> "Lexington-Fayette",
+ "Kentucky" -> "Louisville/Jefferson County (balance)",
+ "Louisiana" -> "Baton Rouge",
+ "Louisiana" -> "Lafayette",
+ "Louisiana" -> "New Orleans",
+ "Louisiana" -> "Shreveport",
+ "Maryland" -> "Baltimore",
+ "Massachusetts" -> "Boston",
+ "Massachusetts" -> "Cambridge",
+ "Massachusetts" -> "Lowell",
+ "Massachusetts" -> "Springfield",
+ "Massachusetts" -> "Worcester",
+ "Michigan" -> "Ann Arbor",
+ "Michigan" -> "Detroit",
+ "Michigan" -> "Flint",
+ "Michigan" -> "Grand Rapids",
+ "Michigan" -> "Lansing",
+ "Michigan" -> "Sterling Heights",
+ "Michigan" -> "Warren",
+ "Minnesota" -> "Minneapolis",
+ "Minnesota" -> "St. Paul",
+ "Mississippi" -> "Jackson",
+ "Missouri" -> "Independence",
+ "Missouri" -> "Kansas City",
+ "Missouri" -> "Springfield",
+ "Missouri" -> "St. Louis",
+ "Montana" -> "Billings",
+ "Nebraska" -> "Lincoln",
+ "Nebraska" -> "Omaha",
+ "Nevada" -> "Henderson",
+ "Nevada" -> "Las Vegas",
+ "Nevada" -> "North Las Vegas",
+ "Nevada" -> "Reno",
+ "New Hampshire" -> "Manchester",
+ "New Jersey" -> "Elizabeth",
+ "New Jersey" -> "Jersey City",
+ "New Jersey" -> "Newark",
+ "New Jersey" -> "Paterson",
+ "New Mexico" -> "Albuquerque",
+ "New York" -> "Buffalo",
+ "New York" -> "New York",
+ "New York" -> "Rochester",
+ "New York" -> "Syracuse",
+ "New York" -> "Yonkers",
+ "North Carolina" -> "Cary town",
+ "North Carolina" -> "Charlotte",
+ "North Carolina" -> "Durham",
+ "North Carolina" -> "Fayetteville",
+ "North Carolina" -> "Greensboro",
+ "North Carolina" -> "Raleigh",
+ "North Carolina" -> "Winston-Salem",
+ "Ohio" -> "Akron",
+ "Ohio" -> "Cincinnati",
+ "Ohio" -> "Cleveland",
+ "Ohio" -> "Columbus",
+ "Ohio" -> "Dayton",
+ "Ohio" -> "Toledo",
+ "Oklahoma" -> "Norman",
+ "Oklahoma" -> "Oklahoma City",
+ "Oklahoma" -> "Tulsa",
+ "Oregon" -> "Eugene",
+ "Oregon" -> "Portland",
+ "Oregon" -> "Salem",
+ "Pennsylvania" -> "Allentown",
+ "Pennsylvania" -> "Erie",
+ "Pennsylvania" -> "Philadelphia",
+ "Pennsylvania" -> "Pittsburgh",
+ "Rhode Island" -> "Providence",
+ "South Carolina" -> "Charleston",
+ "South Carolina" -> "Columbia",
+ "South Dakota" -> "Sioux Falls",
+ "Tennessee" -> "Chattanooga",
+ "Tennessee" -> "Clarksville",
+ "Tennessee" -> "Knoxville",
+ "Tennessee" -> "Memphis",
+ "Tennessee" -> "Nashville-Davidson (balance)",
+ "Texas" -> "Abilene",
+ "Texas" -> "Amarillo",
+ "Texas" -> "Arlington",
+ "Texas" -> "Austin",
+ "Texas" -> "Beaumont",
+ "Texas" -> "Brownsville",
+ "Texas" -> "Carrollton",
+ "Texas" -> "Corpus Christi",
+ "Texas" -> "Dallas",
+ "Texas" -> "Denton",
+ "Texas" -> "El Paso",
+ "Texas" -> "Fort Worth",
+ "Texas" -> "Garland",
+ "Texas" -> "Grand Prairie",
+ "Texas" -> "Houston",
+ "Texas" -> "Irving",
+ "Texas" -> "Killeen",
+ "Texas" -> "Laredo",
+ "Texas" -> "Lubbock",
+ "Texas" -> "McAllen",
+ "Texas" -> "McKinney",
+ "Texas" -> "Mesquite",
+ "Texas" -> "Midland",
+ "Texas" -> "Pasadena",
+ "Texas" -> "Plano",
+ "Texas" -> "San Antonio",
+ "Texas" -> "Waco",
+ "Utah" -> "Provo",
+ "Utah" -> "Salt Lake City",
+ "Utah" -> "West Valley City",
+ "Virginia" -> "Alexandria",
+ "Virginia" -> "Arlington CDP",
+ "Virginia" -> "Chesapeake",
+ "Virginia" -> "Hampton",
+ "Virginia" -> "Newport News",
+ "Virginia" -> "Norfolk",
+ "Virginia" -> "Portsmouth",
+ "Virginia" -> "Richmond",
+ "Virginia" -> "Virginia Beach",
+ "Washington" -> "Bellevue",
+ "Washington" -> "Seattle",
+ "Washington" -> "Spokane",
+ "Washington" -> "Tacoma",
+ "Washington" -> "Vancouver",
+ "Wisconsin" -> "Green Bay",
+ "Wisconsin" -> "Madison",
+ "Wisconsin" -> "Milwaukee"
+ )
val states = citiesAndStates.map(_._1).distinct
val state: String = states.head
- def citiesFor(state: String): List[String] = citiesAndStates.filter(_._1 == state).map(_._2)
+ def citiesFor(state: String): List[String] =
+ citiesAndStates.filter(_._1 == state).map(_._2)
}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/AllJson.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/AllJson.scalaREM
similarity index 99%
rename from combo/example/src/main/scala/net/liftweb/example/snippet/AllJson.scala
rename to combo/example/src/main/scala/net/liftweb/example/snippet/AllJson.scalaREM
index c63eab3..5580925 100644
--- a/combo/example/src/main/scala/net/liftweb/example/snippet/AllJson.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/AllJson.scalaREM
@@ -19,6 +19,7 @@ package example {
package snippet {
import net.liftweb._
+import json._
import http._
import common._
import util._
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/ArcChallenge.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/ArcChallenge.scala
index 2b1f596..333dbfe 100644
--- a/combo/example/src/main/scala/net/liftweb/example/snippet/ArcChallenge.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/ArcChallenge.scala
@@ -14,58 +14,63 @@
* limitations under the License.
*/
-package net.liftweb {
-package example {
-package snippet {
+package net.liftweb.example.snippet
-import _root_.net.liftweb.example.model._
import _root_.net.liftweb.http._
-import _root_.net.liftweb.http.S
-import _root_.net.liftweb.mapper._
-import _root_.net.liftweb.http.S._
import _root_.net.liftweb.http.SHtml._
-import _root_.net.liftweb.util.Helpers._
-import _root_.net.liftweb.common._
-import _root_.net.liftweb.util._
-import _root_.scala.xml.{NodeSeq, Text, Group}
/**
- * The Arc Challenge is Paul Graham's quest for web framework concision.
- *
- * http://www.paulgraham.com/arcchallenge.html
- *
- * This is one potential lift-based solution to it using StatefulSnippets.
- * There are doubtless many other ways.
- *
- * @author: Steve Jenson
- */
+ * The Arc Challenge is Paul Graham's quest for web framework concision.
+ *
+ * http://www.paulgraham.com/arcchallenge.html
+ *
+ * This is one potential lift-based solution to it using StatefulSnippets.
+ * There are doubtless many other ways.
+ *
+ * @author: Steve Jenson
+ */
class ArcChallenge extends StatefulSnippet {
- var dispatch: DispatchIt = {case _ => xhtml => ask}
+ var dispatch: DispatchIt = {
+ case _ =>
+ xhtml =>
+ ask
+ }
/**
- * Step 1: Type in a Phrase.
- */
+ * Step 1: Type in a Phrase.
+ */
def ask = {
-
- Say Anything:
- {text("", p => phrase = p)}
- {submit("Submit", () => dispatch = {case _ => xhtml => think})}
-
+
}
/**
- * Step 2: Show a link that takes you to the Phrase you entered.
- */
- def think = submit("Click here to see what you said",
- () => dispatch = {case _ => xhtml => answer})
+ * Step 2: Show a link that takes you to the Phrase you entered.
+ */
+ def think =
+ submit("Click here to see what you said",
+ () =>
+ dispatch = {
+ case _ =>
+ xhtml =>
+ answer
+ },
+ "class" -> "btn btn-primary")
/**
- * Step 3: Show the phrase.
- */
+ * Step 3: Show the phrase.
+ */
def answer = You said: {phrase}
private var phrase = ""
}
-}
-}
-}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/BSDialog.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/BSDialog.scala
new file mode 100644
index 0000000..0e2dd2f
--- /dev/null
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/BSDialog.scala
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2009-2010 WorldWide Conferencing, LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.liftweb.example.snippet
+
+import net.liftweb.http.SHtml._
+import net.liftweb.http._
+import net.liftweb.http.js.JsCmds._
+import net.liftweb.http.js._
+import net.liftweb.http.js.JE.JsRaw
+import net.liftweb.util.Helpers._
+import net.liftweb.common._
+import scala.xml.NodeSeq
+
+class BSDialog {
+ // build the button... when pressed, present
+ // a dialog based on the _bsdialog_confirm
+ // template
+ def button(in: NodeSeq) =
+ ajaxButton(in,
+ () => injectDialogTemplate & openDialog,
+ "type" -> "button",
+ "class" -> "btn btn-primary",
+ "data-target" -> "#exampleModal")
+
+ def confirm = {
+ "#yes" #> ((b: NodeSeq) =>
+ ajaxButton(b, () => {
+ logger.debug("Rhode Island Destroyed")
+ showDestroyAlert & closeDialog
+ }, "type" -> "button", "class" -> "btn btn-primary")) &
+ "#no" #> ((b: NodeSeq) =>
+ ajaxButton(
+ b,
+ () => {
+ logger.debug("Rhode Island intact")
+ Noop //we could have used closeDialog here but we are instead using the data-dismiss attribute.
+ },
+ "type" -> "button",
+ "class" -> "btn btn-primary",
+ "data-dismiss" -> "modal"
+ ))
+ }
+
+ private val logger = Logger(classOf[BSDialog])
+ private val bsDialogTemplate: Box[NodeSeq] = Templates(
+ List("_bsdialog_confirm"))
+ private val openDialog
+ : JsCmd = JsRaw("""$('#exampleModal').modal('show')""").cmd
+ private val closeDialog
+ : JsCmd = JsRaw("""$('#exampleModal').modal('hide')""").cmd
+ private val showDestroyAlert = Alert("Rhode Island Destroyed")
+ private val showTemplateNotFoundAlert = Alert(
+ "Couldn't find _bsdialog_confirm template")
+
+ private def setAtPlaceholder(ns: NodeSeq) = SetHtml("modalPlaceholder", ns)
+ private def injectDialogTemplate =
+ bsDialogTemplate map setAtPlaceholder openOr showTemplateNotFoundAlert
+}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/CacheBust.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/CacheBust.scala
new file mode 100644
index 0000000..c13e59a
--- /dev/null
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/CacheBust.scala
@@ -0,0 +1,18 @@
+package net.liftweb.example.snippet
+
+import java.text.SimpleDateFormat
+import java.util.Date
+
+import net.liftweb.util.Helpers._
+import net.liftweb.util._
+
+import net.liftweb.example.lib.BuildInfo
+
+class CacheBust {
+ private lazy val date: Date = new Date(BuildInfo.buildTime)
+ private lazy val formatter = new SimpleDateFormat("yyMMddHHmmss")
+ private lazy val strDate: String = formatter.format(date)
+
+ def usingBuildTime: CssSel =
+ "link [href+]" #> s"?bt=$strDate" & "script [src+]" #> s"?bt=$strDate"
+}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/Count.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/Count.scala
index ff1b772..5f55619 100644
--- a/combo/example/src/main/scala/net/liftweb/example/snippet/Count.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/Count.scala
@@ -14,30 +14,23 @@
* limitations under the License.
*/
-package net.liftweb {
-package example {
-package snippet {
+package net.liftweb.example.snippet
-import _root_.net.liftweb.example.model._
-import _root_.scala.xml.{NodeSeq, Text, Group, Node}
+import _root_.scala.xml.{Text}
import _root_.net.liftweb.http._
import _root_.net.liftweb.http.S
-import _root_.net.liftweb.mapper._
-import _root_.net.liftweb.http.S._
import _root_.net.liftweb.http.SHtml._
import _root_.net.liftweb.util.Helpers._
-import _root_.net.liftweb.common._
-import _root_.net.liftweb.util._
import _root_.scala.collection.mutable.HashMap
-
/**
* This session variable holds a set of Names and Integers, with a default value
* of 0 (zero)
*/
-object CountHolder extends SessionVar[HashMap[String, Int]](new HashMap[String, Int] {
- override def default(key: String): Int = 0
-})
+object CountHolder
+ extends SessionVar[HashMap[String, Int]](new HashMap[String, Int] {
+ override def default(key: String): Int = 0
+ })
/**
* This snippet handles counting
@@ -47,7 +40,7 @@ class Count {
/**
* This method is invoked by the <lift:Count /> tag
*/
- def render(in: NodeSeq): NodeSeq = {
+ def render = {
// get the attribute name (the name of the thing to count)
val attr: String = S.attr("name").openOr("N/A")
@@ -55,11 +48,12 @@ class Count {
val value = CountHolder.is(attr)
// Bind the incoming view data and the model data
- bind("count", in, "value" -> value,
- "incr" -> link("/count", () => CountHolder.is(attr) = value + 1, Text("++")),
- "decr" -> link("/count", () => CountHolder.is(attr) = 0 max (value - 1), Text("--")))
+ ".value" #> Text(value.toString) &
+ ".incr" #> link("/count",
+ () => CountHolder.is(attr) = value + 1,
+ Text("++")) &
+ ".decr" #> link("/count",
+ () => CountHolder.is(attr) = 0 max (value - 1),
+ Text("--"))
}
}
-}
-}
-}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/CountGame.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/CountGame.scala
index af8653c..77cae98 100644
--- a/combo/example/src/main/scala/net/liftweb/example/snippet/CountGame.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/CountGame.scala
@@ -14,47 +14,52 @@
* limitations under the License.
*/
-package net.liftweb {
-package example {
-package snippet {
+package net.liftweb.example.snippet
-import _root_.net.liftweb.example.model._
-import _root_.scala.xml.{NodeSeq, Text, Group, Node}
+import _root_.scala.xml.{NodeSeq, Text, Node}
import _root_.net.liftweb.http._
-import _root_.net.liftweb.http.S
-import _root_.net.liftweb.mapper._
import _root_.net.liftweb.http.S._
import _root_.net.liftweb.http.SHtml._
import _root_.net.liftweb.util.Helpers._
import _root_.net.liftweb.common._
import _root_.net.liftweb.util._
-
class CountGame extends StatefulSnippet {
val dispatch: DispatchIt = {
case "run" if lastGuess == number =>
- xhtml => win(chooseTemplate("choose", "win", xhtml))
+ xhtml =>
+ win(xhtml)
case "run" =>
- xhtml => nextGuess(chooseTemplate("choose", "guess", xhtml))
+ xhtml =>
+ nextGuess(xhtml)
case "count_down" =>
- xhtml => countDown(attr("from").map(Helpers.toInt).openOr(0))
+ xhtml =>
+ countDown(attr("from").map(Helpers.toInt).openOr(0))
}
- def win(xhtml: NodeSeq) = bind("count", xhtml, "number" -> number,
- "count" -> count) ++ Counting backward: {countDown(number)}
+ def win(xhtml: NodeSeq) =
+ ("#win ^*" #> "#choose" &
+ ".number" #> Text(number.toString) &
+ ".count" #> Text(count.toString)).apply(xhtml) ++
+ Counting backward:
+ {countDown(number)}
+
- def countDown(number: Int): Node = if (number <= 0) Text("")
- else {number}
+ def countDown(number: Int): Node =
+ if (number <= 0) Text("")
+ else
+ {number}
- def nextGuess(xhtml: NodeSeq) = bind("count", xhtml,
- "input" -> text("", guess _),
- "last" ->
- lastGuess.map(v =>
- if (v < number) v+" is low"
- else v+" is high").
- openOr("Make first Guess"))
+ def nextGuess(xhtml: NodeSeq): NodeSeq =
+ ("#guess ^*" #> "#choose" &
+ ".input" #> text("", guess _, "class" -> "form-control") &
+ ".last *" #> lastGuess
+ .map(v =>
+ if (v < number) v + " is low"
+ else v + " is high")
+ .openOr("Make first Guess")).apply(xhtml)
private def guess(in: String) {
count += 1
@@ -65,6 +70,3 @@ class CountGame extends StatefulSnippet {
private var lastGuess: Box[Int] = Empty
private var count = 0
}
-}
-}
-}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/Database.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/Database.scala
index 3a446c8..7f0a85b 100644
--- a/combo/example/src/main/scala/net/liftweb/example/snippet/Database.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/Database.scala
@@ -14,41 +14,38 @@
* limitations under the License.
*/
-package net.liftweb {
-package example {
-package snippet {
+package net.liftweb.example.snippet
import _root_.net.liftweb.example.model._
-import _root_.scala.xml.{NodeSeq, Text, Group, Node}
-import _root_.net.liftweb.http._
-import _root_.net.liftweb.http.S
import _root_.net.liftweb.mapper._
import _root_.net.liftweb.http.S._
import _root_.net.liftweb.http.SHtml._
import _root_.net.liftweb.util.Helpers._
-import _root_.net.liftweb.common._
/**
* This snippet handles counting
*/
class Database {
- /**
- * This method is invoked by the <lift:Count /> tag
- */
- def render(in: NodeSeq): NodeSeq = {
- val count = Person.count()
- val first = Person.find(OrderBy(Person.firstName, Ascending), MaxRows[Person](1))
+ def render = {
+ val count = Person.count()
+ val first =
+ Person.find(OrderBy(Person.firstName, Ascending), MaxRows[Person](1))
- bind("database", in, "count" -> count,
- "first" -> first.map(_.asHtml).openOr(No Persons in the system ),
- "submit" -> submit("Create More Records", () => {
- val cnt = 10 + randomInt(50)
- for (x <- 1 to cnt) Person.create.firstName(randomString(20)).lastName(randomString(20)).personalityType(Personality.rand).save
- notice("Added "+cnt+" records to the Person table")
- }))
+ "#count" #> count &
+ "#first" #> first.map(_.asHtml).openOr(No Persons in the system ) &
+ "type=submit" #> submit(
+ "Create More Records",
+ () => {
+ val cnt = 10 + randomInt(50)
+ for (x <- 1 to cnt)
+ Person.create
+ .firstName(randomString(20))
+ .lastName(randomString(20))
+ .personalityType(Personality.rand)
+ .save
+ notice("Added " + cnt + " records to the Person table")
+ }
+ )
}
}
-}
-}
-}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/DivSelector.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/DivSelector.scala
index 127ec70..2b92056 100644
--- a/combo/example/src/main/scala/net/liftweb/example/snippet/DivSelector.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/DivSelector.scala
@@ -14,39 +14,31 @@
* limitations under the License.
*/
-package net.liftweb {
-package example {
-package snippet {
-
-import _root_.net.liftweb.example.model._
-import _root_.net.liftweb.http._
-import _root_.net.liftweb.http.S
-import _root_.net.liftweb.mapper._
-import _root_.net.liftweb.http.S._
-import _root_.net.liftweb.http.SHtml._
-import _root_.net.liftweb.util.Helpers._
-import _root_.net.liftweb.common._
-import _root_.net.liftweb.util._
-import _root_.scala.xml.{NodeSeq, Text, Group}
+package net.liftweb.example.snippet
+import net.liftweb.http._
+import net.liftweb.http.SHtml._
+import net.liftweb.util.Helpers._
+import net.liftweb.common._
+import net.liftweb.util._
+import scala.xml.{NodeSeq, Text}
class DivSelector extends StatefulSnippet {
- private var whichDivs: Array[Boolean] = Array(true, true, true, true, true, true)
- def dispatch: DispatchIt =
- {
- case "select" => selectDivs
+ private val whichDivs: Array[Boolean] =
+ Array(true, true, true, true, true, true)
+
+ def dispatch: DispatchIt = {
+ case "select" => selectDivs
case "populate" => populate
}
- def populate(in: NodeSeq): NodeSeq =
- bind("div", in, "line" ->
- (line =>
- whichDivs.toList.zipWithIndex.flatMap{
- case (value, num) =>
- bind("div", line,
- "number" -> Text(num.toString),
- "checkbox" -> checkbox(value, v => whichDivs(num) = v))}))
+ def populate: CssSel = "#line" #> whichDivs.toList.zipWithIndex.flatMap {
+ case (value, num) =>
+ List(
+ "#number" #> Text(num.toString) &
+ "#checkbox" #> checkbox(value, v => whichDivs(num) = v))
+ }
def selectDivs(in: NodeSeq): NodeSeq = {
def calcNum(in: String): Box[Int] =
@@ -60,6 +52,3 @@ class DivSelector extends StatefulSnippet {
} yield div
}
}
-}
-}
-}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/FormWithAjax.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/FormWithAjax.scala
index a4b7e3d..fa07781 100644
--- a/combo/example/src/main/scala/net/liftweb/example/snippet/FormWithAjax.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/FormWithAjax.scala
@@ -14,50 +14,56 @@
* limitations under the License.
*/
-package net.liftweb {
-package example {
-package snippet {
+package net.liftweb.example.snippet
-import _root_.net.liftweb._
+import net.liftweb._
import http._
import SHtml._
import js._
import JsCmds._
-import common._
import util._
import Helpers._
-import scala.xml.NodeSeq
-
class FormWithAjax extends StatefulSnippet {
private var firstName = ""
private var lastName = ""
- private val from = S.referer openOr "/"
+ private val to = "#wrappedNoticeAtHead"
def dispatch = {
- case _ => render _
+ case _ => render
}
- def render(xhtml: NodeSeq): NodeSeq =
- {
-
+ def render = {
def validate() {
(firstName.length, lastName.length) match {
- case (f, n) if f < 2 && n < 2 => S.error("First and last names too short")
- case (f, _) if f < 2 => S.error("First name too short")
- case (_, n) if n < 2 => S.error("Last name too short")
- case _ => S.notice("Thanks!"); S.redirectTo(from)
+ case (f, n) if f < 2 && n < 2 =>
+ S.error("fwaErrMsg", "First and last names too short")
+ case (f, _) if f < 2 => S.error("fwaErrMsg", "First name too short")
+ case (_, n) if n < 2 => S.error("fwaErrMsg", "Last name too short")
+ case _ => {
+ S.notice("fwaNoticeMsg", "Ajax form says Thanks!")
+ S.redirectTo(to)
+ }
}
}
- bind("form", xhtml,
- "first" -> textAjaxTest(firstName, s => firstName = s, s => {S.notice("First name "+s); Noop}),
- "last" -> textAjaxTest(lastName, s => lastName = s, s => {S.notice("Last name "+s); Noop}),
- "submit" -> submit("Send", validate _)
- )
+ "#first" #> textAjaxTest(firstName,
+ s => firstName = s,
+ s => {
+ S.notice("fwaNoticeMsg", "First name " + s); Noop
+ },
+ "class" -> "form-control",
+ "type" -> "text",
+ "placeholder" -> "First name") &
+ "#last" #> textAjaxTest(lastName,
+ s => lastName = s,
+ s => {
+ S.notice("fwaNoticeMsg", "Last name " + s); Noop
+ },
+ "class" -> "form-control",
+ "type" -> "text",
+ "placeholder" -> "Last name") &
+ "type=submit" #> submit("Send", validate _, "class" -> "btn btn-primary")
}
}
-}
-}
-}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/InvoiceWiring.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/InvoiceWiring.scala
index 9d1bccb..e85d0f7 100644
--- a/combo/example/src/main/scala/net/liftweb/example/snippet/InvoiceWiring.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/InvoiceWiring.scala
@@ -14,9 +14,7 @@
* limitations under the License.
*/
-package net.liftweb {
-package example {
-package snippet {
+package net.liftweb.example.snippet
import _root_.net.liftweb._
import http._
@@ -24,24 +22,23 @@ import util._
import Helpers._
import js.JsCmds._
import js.jquery._
-import _root_.scala.xml.{NodeSeq, Text}
+import _root_.scala.xml.{NodeSeq}
case class Line(guid: String, name: String, price: Double, taxable: Boolean)
/**
- * An invoice system with subtotals, tax, etc.
- */
+ * An invoice system with subtotals, tax, etc.
+ */
class InvoiceWiring {
private object Info {
val invoices = ValueCell(List(newLine))
val taxRate = ValueCell(0.05d)
val subtotal = invoices.lift(_.foldLeft(0d)(_ + _.price))
- val taxable = invoices.lift(_.filter(_.taxable).
- foldLeft(0D)(_ + _.price))
+ val taxable = invoices.lift(_.filter(_.taxable).foldLeft(0D)(_ + _.price))
- val tax = taxRate.lift(taxable) {_ * _}
+ val tax = taxRate.lift(taxable) { _ * _ }
- val total = subtotal.lift(tax) {_ + _}
+ val total = subtotal.lift(tax) { _ + _ }
}
def subtotal(in: NodeSeq) = WiringUI.asText(in, Info.subtotal)
@@ -52,13 +49,13 @@ class InvoiceWiring {
def total(in: NodeSeq) = WiringUI.asText(in, Info.total, JqWiringSupport.fade)
- def taxRate = SHtml.ajaxText(Info.taxRate.get.toString,
- s => {
- Helpers.asDouble(s).foreach {
- Info.taxRate.set
- }
- Noop
- })
+ def taxRate =
+ SHtml.ajaxText(Info.taxRate.get.toString, s => {
+ Helpers.asDouble(s).foreach {
+ Info.taxRate.set
+ }
+ Noop
+ }, "class" -> "form-control")
def showLines = "* *" #> (Info.invoices.get.flatMap(renderLine): NodeSeq)
@@ -68,18 +65,18 @@ class InvoiceWiring {
val theLine = appendLine
val guid = theLine.guid
JqJsCmds.AppendHtml(div, renderLine(theLine))
- })
+ }, "class" -> "btn btn-primary mx-sm-2 mb-2")
}
private def renderLine(theLine: Line): NodeSeq =
- {
+
{
SHtml.ajaxText(theLine.name,
s => {
mutateLine(theLine.guid) {
l => Line(l.guid, s, l.price, l.taxable)
}
Noop
- })
+ },"class" -> "form-control mx-sm-2 mb-2") //mx-sm-2 mb-2
}
{
@@ -92,7 +89,7 @@ class InvoiceWiring {
}
}
Noop
- })
+ },"class" -> "form-control mx-sm-2 mb-2") //mx-sm-2 mb-2
}
{
@@ -102,28 +99,23 @@ class InvoiceWiring {
l => Line(l.guid, l.name, l.price, b)
}
Noop
- })
+ }, "class" -> "mx-sm-2 mb-2") //mx-sm-2 mb-2
}
- private def newLine = Line(nextFuncName, "", 0, false)
-
- private def appendLine: Line = {
- val ret = newLine
- Info.invoices.set(ret :: Info.invoices.get)
- ret
- }
-
- private def mutateLine(guid: String)(f: Line => Line) {
- val all = Info.invoices.get
- val head = all.filter(_.guid == guid).map(f)
- val rest = all.filter(_.guid != guid)
- Info.invoices.set(head ::: rest)
- }
+ private def newLine = Line(nextFuncName, "", 0, false)
+ private def appendLine: Line = {
+ val ret = newLine
+ Info.invoices.set(ret :: Info.invoices.get)
+ ret
+ }
-}
+ private def mutateLine(guid: String)(f: Line => Line) {
+ val all = Info.invoices.get
+ val head = all.filter(_.guid == guid).map(f)
+ val rest = all.filter(_.guid != guid)
+ Info.invoices.set(head ::: rest)
+ }
}
-}
-}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/JSDialog.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/JSDialog.scala
index b1ccf01..64189fa 100644
--- a/combo/example/src/main/scala/net/liftweb/example/snippet/JSDialog.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/JSDialog.scala
@@ -15,41 +15,47 @@
*/
package net.liftweb {
-package example {
-package snippet {
+ package example {
+ package snippet {
-import _root_.net.liftweb._
-import http._
-import SHtml._
-import js._
-import JsCmds._
-import js.jquery._
-import JqJsCmds._
-import common._
-import util._
-import Helpers._
+ import http._
+ import SHtml._
+ import js._
+ import JsCmds._
+ import js.jquery._
+ import JqJsCmds._
+ import util._
+ import Helpers._
-import _root_.scala.xml.NodeSeq
+ import _root_.scala.xml.NodeSeq
-class JSDialog {
- // build the button... when pressed, present
- // a dialog based on running the _jsdialog_confirm
- // template
- def button(in: NodeSeq) =
- ajaxButton(in,
- () => S.runTemplate(List("_jsdialog_confirm")).
- map(ns => ModalDialog(ns)) openOr
- Alert("Couldn't find _jsdialog_confirm template"))
+ class JSDialog {
+ // build the button... when pressed, present
+ // a dialog based on running the _jsdialog_confirm
+ // template
+ def button(in: NodeSeq) =
+ ajaxButton(
+ in,
+ () =>
+ S.runTemplate(List("_jsdialog_confirm"))
+ .map(ns => ModalDialog(ns)) openOr
+ Alert("Couldn't find _jsdialog_confirm template"),
+ "class" -> "btn btn-primary"
+ )
- // the template needs to bind to either server-side behavior
- // and unblock the UI
- def confirm(in: NodeSeq) =
- bind("confirm", in,
- "yes" -> ((b: NodeSeq) => ajaxButton(b, () =>
- {println("Rhode Island Destroyed")
- Unblock & Alert("Rhode Island Destroyed")})),
- "no" -> ((b: NodeSeq) =>
{b} ))
-}
-}
-}
+ // the template needs to bind to either server-side behavior
+ // and unblock the UI
+ def confirm = {
+ "#yes" #> ((b: NodeSeq) =>
+ ajaxButton(b, () => {
+ println("Rhode Island Destroyed")
+ Unblock & Alert("Rhode Island Destroyed")
+ })) &
+ "#no" #> ((b: NodeSeq) =>
+ {b}
+ )
+ }
+ }
+ }
+ }
}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/Json.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/Json.scala
index 955af8d..5b090ea 100644
--- a/combo/example/src/main/scala/net/liftweb/example/snippet/Json.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/Json.scala
@@ -14,41 +14,39 @@
* limitations under the License.
*/
-package net.liftweb {
-package example {
-package snippet {
+package net.liftweb.example.snippet
-import _root_.net.liftweb.http._
-import S._
+import net.liftweb.http._
import js._
import JsCmds._
import JE._
import net.liftmodules.textile._
-import _root_.net.liftweb.common._
-import _root_.net.liftweb.util._
+import net.liftweb.common._
+import net.liftweb.util._
import Helpers._
-import _root_.scala.xml._
+
+import scala.xml._
class Json {
- object json extends JsonHandler {
+ object json {
def apply(in: Any): JsCmd =
- SetHtml("json_result", in match {
- case JsonCmd("show", _, p: String, _) => Text(p)
- case JsonCmd("textile", _, p: String, _) =>
- TextileParser.toHtml(p, Empty)
- case JsonCmd("count", _, p: String, _) => Text(p.length+" Characters")
- case x =>
Problem... didn't handle JSON message {x}
- })
+ SetHtml(
+ "json_result",
+ in match {
+ case JsonCmd("show", _, p: String, _) => Text(p)
+ case JsonCmd("textile", _, p: String, _) =>
+ TextileParser.toHtml(p, Empty)
+ case JsonCmd("count", _, p: String, _) =>
+ Text(p.length.toString + " Characters")
+ case x =>
Problem... didn't handle JSON message {x}
+ }
+ )
}
- def sample(in: NodeSeq): NodeSeq =
- bind("json", in,
- "script" -> Script(json.jsCmd),
- AttrBindParam("onclick",
- Text(json.call(ElemById("json_select")~>Value,
- ElemById("json_question")~>Value).toJsCmd),
- "onclick"))
-}
-}
-}
+ def sample =
+ "#jsonscript" #> Script(JsRaw(json.apply()).cmd) &
+ ".json [onclick]" #> Text(
+ json(ElemById("json_select") ~> Value,
+ ElemById("json_question") ~> Value).toJsCmd)
+
}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/Json2.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/Json2.scala
new file mode 100644
index 0000000..cc341a1
--- /dev/null
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/Json2.scala
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2007-2010 WorldWide Conferencing, LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.liftweb.example.snippet
+
+import net.liftweb.util.Helpers._
+import net.liftweb.http.SHtml
+import net.liftweb.http.js.{JE, JsCmd, JsonCall}
+import net.liftweb.common.Logger
+import net.liftweb.json.JsonAST._
+import net.liftweb.http.js.JsCmds.Alert
+import net.liftweb.json.DefaultFormats
+
+// Example taken from http://cookbook.liftweb.net/book.html#id-rjCJTYFwuYtbh9
+object JsonCall {
+
+ private val logger = Logger(classOf[JsonCall])
+ implicit val formats = DefaultFormats
+
+ case class Question(first: Int, second: Int, answer: Int) {
+ def valid_? = first + second == answer
+ }
+
+ def render = {
+
+ def validate(value: JValue): JsCmd = {
+ logger.info(value)
+ value.extractOpt[Question].map(_.valid_?) match {
+ case Some(true) => Alert("Looks good")
+ case Some(false) => Alert("That doesn't add up")
+ case None => Alert("That doesn't make sense")
+ }
+ }
+
+ "button [onclick]" #>
+ SHtml.jsonCall(JE.Call("currentQuestion"), validate _)
+ }
+}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/LongTime.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/LongTime.scala
index c366de5..4275135 100644
--- a/combo/example/src/main/scala/net/liftweb/example/snippet/LongTime.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/LongTime.scala
@@ -15,22 +15,20 @@
*/
package net.liftweb {
-package example {
-package snippet {
+ package example {
+ package snippet {
-import net.liftweb.util.Helpers._
+ import net.liftweb.util.Helpers._
-object LongTime {
- def render = {
- val delay = 1000L + randomLong(10000)
+ object LongTime {
+ def render = {
+ val delay = 1000L + randomLong(10000)
- Thread.sleep(delay)
-
-
- This thread delayed {delay / 1000L} seconds
-
+ Thread.sleep(delay)
+
+
This thread delayed {delay / 1000L} seconds
+ }
+ }
+ }
}
}
-}
-}
-}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/Misc.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/Misc.scala
index e3a0da8..7eb73ca 100644
--- a/combo/example/src/main/scala/net/liftweb/example/snippet/Misc.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/Misc.scala
@@ -14,53 +14,57 @@
* limitations under the License.
*/
-package net.liftweb
-package example
-package snippet
+package net.liftweb.example.snippet
-import model._
+import net.liftweb.example.model._
-import _root_.net.liftweb._
-import http._
-import mapper._
+import net.liftweb.http._
+import net.liftweb.mapper._
import S._
import SHtml._
-import common._
-import util._
+import net.liftweb.common._
+import net.liftweb.util._
import Helpers._
-import _root_.scala.xml.{NodeSeq, Text, Group}
-import _root_.java.util.Locale
+import scala.xml.{NodeSeq, Text, Group}
+import java.util.Locale
class Misc {
private object selectedUser extends RequestVar[Box[User]](Empty)
+ private val logger = Logger(classOf[Misc])
/**
- * Get the XHTML containing a list of users
- */
+ * Get the XHTML containing a list of users
+ */
def users: NodeSeq = {
User.find() match {
- case Empty => User.create.firstName("Archer").lastName("Dog").email("archer@dogfood.com").password("mypassword").save
+ case Empty =>
+ User.create
+ .firstName("Archer")
+ .lastName("Dog")
+ .email("archer@dogfood.com")
+ .password("mypassword")
+ .save
case _ =>
}
// the header
-
{User.htmlHeaders}Edit Delete ::
- // get and display each of the users
- User.findAll(OrderBy(User.id, Ascending)).flatMap(u =>
{u.htmlLine}
- {link("/simple/edit", () => selectedUser(Full(u)), Text("Edit"))}
- {link("/simple/delete", () => selectedUser(Full(u)), Text("Delete"))}
+ {User.htmlHeaders}Edit Delete ::
+ // get and display each of the users
+ User.findAll(OrderBy(User.id, Ascending)).flatMap(u => {u.htmlLine}
+ {link("/simple/edit", () => selectedUser(Full(u)), , "class" -> "btn btn-sm btn-outline-secondary")}
+ {link("/simple/delete", () => selectedUser(Full(u)), , "class" -> "btn btn-sm btn-outline-secondary")}
)
}
/**
- * Confirm deleting a user
- */
+ * Confirm deleting a user
+ */
def confirmDelete(xhtml: Group): NodeSeq = {
(for (user <- selectedUser.is) // find the user
- yield {
+ yield {
def deleteUser() {
- notice("User "+(user.firstName+" "+user.lastName)+" deleted")
+ notice("User " + (user.firstName + " " + user.lastName) + " deleted")
user.delete_!
redirectTo("/simple/index.html")
}
@@ -69,12 +73,18 @@ class Misc {
// when the delete button is pressed, call the "deleteUser"
// function (which is a closure and bound the "user" object
// in the current content)
- bind("xmp", xhtml, "username" -> (user.firstName.is+" "+user.lastName.is),
- "delete" -> submit("Delete", deleteUser _))
+ val bindDelete = {
+ "#username" #> (user.firstName.get + " " + user.lastName.get) &
+ "#delete" #> submit("Yes delete",
+ deleteUser _,
+ "type" -> "button",
+ "class" -> "btn btn-danger")
+ }
+ bindDelete(xhtml)
// if the was no ID or the user couldn't be found,
// display an error and redirect
- }) openOr {error("User not found"); redirectTo("/simple/index.html")}
+ }) openOr { error("User not found"); redirectTo("/simple/index.html") }
}
// called when the form is submitted
@@ -83,65 +93,80 @@ class Misc {
// back to the "list" page
case Nil => user.save; redirectTo("/simple/index.html")
- // oops... validation errors
- // display the errors and make sure our selected user is still the same
- case x => error(x); selectedUser(Full(user))
+ // oops... validation errors
+ // display the errors and make sure our selected user is still the same
+ case x => {
+ logger.debug("SaveUser got a validation error=" + x.toString())
+ S.error(x)
+ selectedUser(Full(user))
+ }
}
/**
- * Add a user
- */
+ * Add a user
+ */
def add(xhtml: Group): NodeSeq =
- selectedUser.is.openOr(new User).toForm(Empty, saveUser _) ++
- Cancel
-
+ selectedUser.is.openOr(new User).toForm(Empty, saveUser _) ++
+ Cancel
+ Create
/**
- * Edit a user
- */
+ * Edit a user
+ */
def edit(xhtml: Group): NodeSeq =
- selectedUser.map(_.
- // get the form data for the user and when the form
- // is submitted, call the passed function.
- // That means, when the user submits the form,
- // the fields that were typed into will be populated into
- // "user" and "saveUser" will be called. The
- // form fields are bound to the model's fields by this
- // call.
- toForm(Empty, saveUser _) ++
- Cancel
-
+ selectedUser.map(
+ _.
+ // get the form data for the user and when the form
+ // is submitted, call the passed function.
+ // That means, when the user submits the form,
+ // the fields that were typed into will be populated into
+ // "user" and "saveUser" will be called. The
+ // form fields are bound to the model's fields by this
+ // call.
+ toForm(Empty, saveUser _) ++
+ Cancel
+ Save
- // bail out if the ID is not supplied or the user's not found
- ) openOr {error("User not found"); redirectTo("/simple/index.html")}
+ // bail out if the ID is not supplied or the user's not found
+ ) openOr { error("User not found"); redirectTo("/simple/index.html") }
// the request-local variable that hold the file parameter
private object theUpload extends RequestVar[Box[FileParamHolder]](Empty)
/**
- * Bind the appropriate XHTML to the form
- */
+ * Bind the appropriate XHTML to the form
+ */
def upload(xhtml: Group): NodeSeq =
- if (S.get_?) bind("ul", chooseTemplate("choose", "get", xhtml),
- "file_upload" -> fileUpload(ul => theUpload(Full(ul))))
- else bind("ul", chooseTemplate("choose", "post", xhtml),
- "file_name" -> theUpload.is.map(v => Text(v.fileName)),
- "mime_type" -> theUpload.is.map(v => Box.legacyNullTest(v.mimeType).map(Text).openOr(Text("No mime type supplied"))), // Text(v.mimeType)),
- "length" -> theUpload.is.map(v => Text(v.file.length.toString)),
- "md5" -> theUpload.is.map(v => Text(hexEncode(md5(v.file))))
- );
-
+ if (S.get_?)
+ (
+ "#get ^*" #> "#choose" &
+ ".custom-file-input" #> fileUpload(ul => theUpload(Full(ul)))
+ ) apply (xhtml)
+ else
+ ("#post ^*" #> "#choose" &
+ ".file_name" #> theUpload.is.map(v => Text(v.fileName)) &
+ ".mime_type" #> theUpload.is.map(
+ v =>
+ Box
+ .legacyNullTest(v.mimeType)
+ .map(Text.apply)
+ .openOr(Text("No mime type supplied"))) &
+ ".length" #> theUpload.is.map(v => Text(v.file.length.toString)) &
+ ".md5" #> theUpload.is.map(v => Text(hexEncode(md5(v.file))))) apply (xhtml)
def lang = {
"#lang" #> locale.getDisplayLanguage(locale) &
- "#select" #> SHtml.selectObj(locales.map(lo => (lo, lo.getDisplayName)),
- definedLocale, setLocale)
+ "#select" #> SHtml.selectObj(locales.map(lo => (lo, lo.getDisplayName)),
+ definedLocale,
+ setLocale,
+ "class" -> "form-control")
}
private def locales =
- Locale.getAvailableLocales.toList.sortWith(_.getDisplayName < _.getDisplayName)
+ Locale.getAvailableLocales.toList
+ .sortWith(_.getDisplayName < _.getDisplayName)
private def setLocale(loc: Locale) = definedLocale(Full(loc))
}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/Parallel.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/Parallel.scala
index e703823..5538367 100644
--- a/combo/example/src/main/scala/net/liftweb/example/snippet/Parallel.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/Parallel.scala
@@ -15,18 +15,18 @@
*/
package net.liftweb {
-package example {
-package snippet {
+ package example {
+ package snippet {
-object Parallel {
- def render = {
-
This snippet evaluated on
+ object Parallel {
+ def render = {
+
This snippet evaluated on
{
Thread.currentThread.getName()
}
+ }
+ }
+ }
}
}
-}
-}
-}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/RuntimeStats.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/RuntimeStats.scala
index 7912363..a7bc83d 100644
--- a/combo/example/src/main/scala/net/liftweb/example/snippet/RuntimeStats.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/RuntimeStats.scala
@@ -15,44 +15,52 @@
*/
package net.liftweb {
-package example {
-package snippet {
+ package example {
+ package snippet {
-import _root_.net.liftweb._
-import http._
-import common._
-import util._
-import Helpers._
+ import http._
+ import util._
+ import Helpers._
-import _root_.java.text.NumberFormat
-import _root_.scala.xml.{NodeSeq, Text}
+ import _root_.java.text.NumberFormat
+ import _root_.scala.xml.{Text}
-object RuntimeStats extends DispatchSnippet {
- @volatile
- var totalMem: Long = Runtime.getRuntime.totalMemory
- @volatile
- var freeMem: Long = Runtime.getRuntime.freeMemory
+ object RuntimeStats extends DispatchSnippet {
+ @volatile
+ var totalMem: Long = Runtime.getRuntime.totalMemory
+ @volatile
+ var freeMem: Long = Runtime.getRuntime.freeMemory
- @volatile
- var sessions = 1
+ @volatile
+ var sessions = 1
- @volatile
- var lastUpdate = timeNow
+ @volatile
+ var lastUpdate = now
- val startedAt = timeNow
+ val startedAt = now
- private def nf(in: Long): String = NumberFormat.getInstance.format(in)
+ private def nf(in: Long): String = NumberFormat.getInstance.format(in)
- def dispatch = {
- case "total_mem" => i => Text(nf(totalMem))
- case "free_mem" => i => Text(nf(freeMem))
- case "sessions" => i => Text(sessions.toString)
- case "updated_at" => i => Text(lastUpdate.toString)
- case "started_at" => i => Text(startedAt.toString)
- }
+ def dispatch = {
+ case "total_mem" =>
+ i =>
+ Text(nf(totalMem))
+ case "free_mem" =>
+ i =>
+ Text(nf(freeMem))
+ case "sessions" =>
+ i =>
+ Text(sessions.toString)
+ case "updated_at" =>
+ i =>
+ Text(lastUpdate.toString)
+ case "started_at" =>
+ i =>
+ Text(startedAt.toString)
+ }
-}
+ }
-}
-}
+ }
+ }
}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/Show.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/Show.scala
new file mode 100644
index 0000000..69409b1
--- /dev/null
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/Show.scala
@@ -0,0 +1,51 @@
+package net.liftweb.example.snippet
+
+import net.liftweb._
+import http._
+import SHtml._
+import js._
+import common._
+import JsCmds._
+import util._
+import Helpers._
+
+class Show {
+ def render = {
+ "#birthyear" #> SHtml.ajaxSelect(Show.yearsOptions,
+ Show.yearsDefault,
+ Show.yearsHandler) &
+ "name=name" #> SHtml.ajaxText("", false, Show.nameHandler _) &
+ "type=submit" #> submit("Submit", Show.submitHandler _)
+ }
+}
+
+object Show {
+ private var name: String = ""
+ private var year: Int = 0
+ val years: Map[String, Int] = Map("2006" -> 2006,
+ "2007" -> 2007,
+ "2008" -> 2008,
+ "2009" -> 2009,
+ "2010" -> 2010)
+ val yearsOptions: List[(String, String)] = ("" -> "") :: years.keys
+ .map(p => (p, p))
+ .toList
+ val yearsDefault = Empty
+ // The function to call when an option is picked:
+ def yearsHandler(selected: String): JsCmd = {
+ this.year = years(selected)
+ S.notice("Selected year '" + years(selected) + "'")
+ SetHtml("selectedyear",
+
{"Selected year '" + years(selected) + "'"}
)
+ }
+ def nameHandler(name: String): JsCmd = {
+ this.name = name
+ S.notice("The name is '" + name + "'")
+ SetHtml("namevalue",
{"The name is '" + name + "'"}
)
+ }
+ def submitHandler(): JsCmd = {
+ S.notice(
+ "The name and year was set to (" + this.name + "," + this.year + ")")
+ S.redirectTo("#myForm")
+ }
+}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/SimpleWiring.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/SimpleWiring.scala
index 22ff47c..8693bff 100644
--- a/combo/example/src/main/scala/net/liftweb/example/snippet/SimpleWiring.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/SimpleWiring.scala
@@ -14,22 +14,19 @@
* limitations under the License.
*/
-package net.liftweb {
-package example {
-package snippet {
+package net.liftweb.example.snippet
-import _root_.net.liftweb._
+import net.liftweb._
import http._
import util._
import Helpers._
-import js.JsCmds._
import js.jquery._
-import _root_.scala.xml.{NodeSeq, Text}
+import scala.xml.NodeSeq
/**
- * A simple example of Wiring. The count of done
- * To-do items
- */
+ * A simple example of Wiring.
+ * The count of done To-do items
+ */
class SimpleWiring {
// define the cells
private val feedFish = ValueCell(false)
@@ -38,30 +35,37 @@ class SimpleWiring {
private val watchTv = ValueCell(false)
// Our count is the collection of cells and we sum them up
- private val count = SeqCell(feedFish,
- walkDog,
- doDishes,
- watchTv).lift {
- _.map(_.toInt).reduceLeft(_ + _)}
+ private val count = SeqCell(feedFish, walkDog, doDishes, watchTv).lift {
+ _.map(_.toInt).sum
+ }
- private class BtoI(b: Boolean) {def toInt: Int = if (b) 1 else 0}
+ private class BtoI(b: Boolean) { def toInt: Int = if (b) 1 else 0 }
private implicit def bToI(b: Boolean): BtoI = new BtoI(b)
// define the count transformation
- def count(in: NodeSeq): NodeSeq =
+ def count(in: NodeSeq): NodeSeq =
WiringUI.asText(in, count, JqWiringSupport.fade)
def toDo = {
import SHtml._
"* *" #> List[NodeSeq](
-
Feed Fish {ajaxCheckboxElem(feedFish)} ,
-
Walk Dog {ajaxCheckboxElem(walkDog)} ,
-
Do Dishes {ajaxCheckboxElem(doDishes)} ,
-
Watch TV {ajaxCheckboxElem(watchTv)} )
+
+ {ajaxCheckboxElem(feedFish)}
+ Feed Fish
+
,
+
+ {ajaxCheckboxElem(walkDog)}
+ Walk Dog
+
,
+
+ {ajaxCheckboxElem(doDishes)}
+ Do Dishes
+
,
+
+ {ajaxCheckboxElem(watchTv)}
+ Watch TV
+
+ )
}
-
-}
}
-}
-}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/SimpleWizard.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/SimpleWizard.scala
index bca42bf..3954340 100644
--- a/combo/example/src/main/scala/net/liftweb/example/snippet/SimpleWizard.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/SimpleWizard.scala
@@ -14,91 +14,107 @@
* limitations under the License.
*/
-package net.liftweb {
-package example {
-package snippet {
+package net.liftweb.example.snippet
-import _root_.net.liftweb.example.model._
import _root_.net.liftweb.http._
import _root_.net.liftweb.http.S
-import _root_.net.liftweb.mapper._
-import _root_.net.liftweb.http.S._
import _root_.net.liftweb.http.SHtml._
import _root_.net.liftweb.util.Helpers._
-import _root_.net.liftweb.common._
-import _root_.net.liftweb.util._
-import _root_.scala.xml.{NodeSeq, Text, Group}
+import _root_.scala.xml.{NodeSeq}
/**
- * The Arc Challenge is Paul Graham's quest for web framework concision.
- *
- * http://www.paulgraham.com/arcchallenge.html
- *
- * This is one potential lift-based solution to it using StatefulSnippets.
- * There are doubtless many other ways.
- *
- * @author: Steve Jenson
- */
+ * The Arc Challenge is Paul Graham's quest for web framework concision.
+ *
+ * http://www.paulgraham.com/arcchallenge.html
+ *
+ * This is one potential lift-based solution to it using StatefulSnippets.
+ * There are doubtless many other ways.
+ *
+ * @author: Steve Jenson
+ */
class SimpleWizard extends StatefulSnippet {
val fromWhence = S.referer openOr "/"
- var dispatch: DispatchIt = {case _ => xhtml => pageOne}
+ var dispatch: DispatchIt = {
+ case _ =>
+ xhtml =>
+ pageOne
+ }
var name = ""
var quest = ""
var color = ""
private def template(name: String, f: NodeSeq => NodeSeq): NodeSeq =
Templates(List("templating") ::: List(name)).map(f) openOr
- NodeSeq.Empty
+ NodeSeq.Empty
/**
- * pageOne -- Ask the name
- */
+ * pageOne -- Ask the name
+ */
def pageOne = {
def validate() {
this.registerThisSnippet()
if (name.length < 2) S.error(S.?("Name too short"))
- else dispatch = {case _ => xhtml => pageTwo}
+ else
+ dispatch = {
+ case _ =>
+ xhtml =>
+ pageTwo
+ }
}
-
- template("pageOne",
- ("#name" replaceWith text(name, name = _)) &
- ("#submit" replaceWith submit(S ? "Next", validate)))
+
+ template(
+ "pageOne",
+ ("#name" replaceWith text(name, name = _, "class" -> "form-control")) &
+ ("#submit" replaceWith submit(S ? "Next",
+ validate,
+ "class" -> "btn btn-primary")))
}
-
+
/**
- * pageTwo -- Ask the quest
- */
+ * pageTwo -- Ask the quest
+ */
def pageTwo = {
def validate() {
this.registerThisSnippet()
if (quest.length < 2) S.error(S.?("Quest too short"))
- else dispatch = {case _ => xhtml => pageThree}
+ else
+ dispatch = {
+ case _ =>
+ xhtml =>
+ pageThree
+ }
}
- template("pageTwo",
- ("#quest" replaceWith text(quest, quest = _)) &
- ("#submit" replaceWith submit(S ? "Next", validate)))
+ template(
+ "pageTwo",
+ ("#quest" replaceWith text(quest, quest = _, "class" -> "form-control")) &
+ ("#submit" replaceWith submit(S ? "Next",
+ validate,
+ "class" -> "btn btn-primary")))
}
-
+
/**
- * pageThree -- Ask the color
- */
+ * pageThree -- Ask the color
+ */
def pageThree = {
def validate() {
this.registerThisSnippet()
- if (!List("red", "yellow", "blue").contains(color.toLowerCase)) S.error(S.?("Color not red, yellow or blue"))
+ if (!List("red", "yellow", "blue").contains(color.toLowerCase))
+ S.error(S.?("Color not red, yellow or blue"))
else {
- S.notice("You, "+name+" on the quest "+quest+" may cross the bridge of sorrows")
+ S.notice(
+ "You, " + name + " on the quest " + quest + " may cross the bridge of sorrows")
S.redirectTo(fromWhence)
}
}
-
- template("pageThree",
- ("#color" replaceWith text(color, color = _)) &
- ("#submit" replaceWith submit(S ? "Finish", validate)))
+
+ template(
+ "pageThree",
+ ("#color" replaceWith text(color, color = _, "class" -> "form-control")) &
+ ("#submit" replaceWith submit(S ? "Finish",
+ validate,
+ "class" -> "btn btn-primary"))
+ )
}
-
-}
-}
-}
+
}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/Template.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/Template.scalaREM
similarity index 100%
rename from combo/example/src/main/scala/net/liftweb/example/snippet/Template.scala
rename to combo/example/src/main/scala/net/liftweb/example/snippet/Template.scalaREM
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/Timely.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/Timely.scala
index 1dd3d61..9c5ffdc 100644
--- a/combo/example/src/main/scala/net/liftweb/example/snippet/Timely.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/Timely.scala
@@ -14,40 +14,42 @@
* limitations under the License.
*/
-package net.liftweb
-package example
+package net.liftweb
+package example
package snippet
-import net.liftweb._
import http._
import util._
import js._
import JsCmds._
-import JE._
import scala.xml._
/**
- * A demo of the LiftSession.addPostPageJavaScript feature.
- * This snippet sets the innerHTML of the specified ID
- * to the current time and the count of how
- * many times the message was updated.
- */
+ * A demo of the LiftSession.addPostPageJavaScript feature.
+ * This snippet sets the innerHTML of the specified ID
+ * to the current time and the count of how
+ * many times the message was updated.
+ */
object Timely {
def render(in: NodeSeq): NodeSeq = {
var x = 0
+ def timesStr(x: Int): String = if (x == 1) "time" else "times"
+
for {
theId <- (in \ "@id")
session <- S.session
} {
session.addPostPageJavaScript(() => {
x += 1
- SetHtml(theId.text,
-
The time of the last update to
+ SetHtml(
+ theId.text,
+ The time of the last update to
this page is {Helpers.now.toString} ,
- and this section was updated {x} times.
- )
+ and this section was updated {x} {timesStr(x)} .
+
+ )
})
}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/ValidateSession.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/ValidateSession.scala
index eeaa682..2252f16 100644
--- a/combo/example/src/main/scala/net/liftweb/example/snippet/ValidateSession.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/ValidateSession.scala
@@ -15,41 +15,31 @@
*/
package net.liftweb {
-package example {
-package snippet {
+ package example {
+ package snippet {
-import _root_.net.liftweb.example.model._
-import _root_.net.liftweb.example.lib._
-import _root_.scala.xml.{NodeSeq, Text, Group, Node}
-import _root_.net.liftweb.http._
-import _root_.net.liftweb.http.S
-import _root_.net.liftweb.mapper._
-import _root_.net.liftweb.http.S._
-import js._
-import JsCmds._
-import _root_.net.liftweb.util.Helpers._
-import _root_.net.liftweb.common._
-import _root_.net.liftweb.util._
-import _root_.scala.collection.mutable.HashMap
+ import _root_.net.liftweb.example.lib._
+ import _root_.scala.xml.{NodeSeq}
+ import _root_.net.liftweb.http._
+ import _root_.net.liftweb.http.S
+ import js._
+ import JsCmds._
+ /**
+ * This snippet handles counting
+ */
+ class ValidateSession {
-
-/**
- * This snippet handles counting
- */
-class ValidateSession {
-
- /**
- * This method is invoked by the <lift:Count /> tag
- */
- def render(in: NodeSeq): NodeSeq =
- SHtml.ajaxButton("Validate",
- () => {
- LoginStuff(true)
- S.notice("Your session is validated")
- RedirectTo("/login/index")
- })
-}
-}
-}
+ /**
+ * This method is invoked by the <lift:Count /> tag
+ */
+ def render(in: NodeSeq): NodeSeq =
+ SHtml.ajaxButton("Validate", () => {
+ LoginStuff(true)
+ S.notice("Your session is validated")
+ RedirectTo("/login/index")
+ }, "class" -> "btn btn-outline-primary")
+ }
+ }
+ }
}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/Wiki.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/Wiki.scala
index 05f7923..14060c5 100644
--- a/combo/example/src/main/scala/net/liftweb/example/snippet/Wiki.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/Wiki.scala
@@ -15,97 +15,144 @@
*/
package net.liftweb {
-package example {
-package snippet {
-
+ package example {
+ package snippet {
/*
-
-import _root_.net.liftweb.example.model._
-import _root_.scala.xml.{NodeSeq, Text, Group}
-import _root_.net.liftweb.http.{S, SHtml}
-import _root_.net.liftweb.mapper._
-import _root_.net.liftweb.http.S._
-import _root_.net.liftweb.util._
-import _root_.net.liftweb.util.Helpers._
-import _root_.net.liftweb.textile._
+ import _root_.net.liftweb.example.model._
+ import _root_.scala.xml.{NodeSeq, Text, Group}
+ import _root_.net.liftweb.http.{S, SHtml}
+ import _root_.net.liftweb.mapper._
+ import _root_.net.liftweb.http.S._
+ import _root_.net.liftweb.util._
+ import _root_.net.liftweb.util.Helpers._
+ import _root_.net.liftweb.textile._
// show determines which one is used. bind hooks the content into the lift view
-case class BindChoice(show: Boolean, bind: () => NodeSeq)
-
-class Wiki extends MetaWikiEntry {
-
- def uriFor(path:String) = "/wiki/" + path
-
- /**
- * Display the Textile marked up wiki or an edit box
- */
- def main: NodeSeq = {
- val pageName = S.param("wiki_page") openOr "HomePage" // set the name of the page
- def showAll = {
- findAll(OrderBy(WikiEntry.name, Ascending)).flatMap(entry =>
-
)
- }
-
- if (pageName == "all") showAll // if the page is "all" display all the pages
- else {
- // find the entry in the database or create a new one
- val entry = find(By(WikiEntry.name, pageName)) openOr create.name(pageName)
-
- // is it a new entry?
- val isNew = !entry.saved_?
-
- // show edit or just display
- val edit = isNew || (S.param("param1").map(_ == "edit") openOr false)
-
-
Show All Pages {
+ case class BindChoice(show: Boolean, bind: () => NodeSeq)
+
+ class Wiki extends MetaWikiEntry {
+
+ def uriFor(path: String) = "/wiki/" + path
+
+ /**
+ * Display the Textile marked up wiki or an edit box
+ */
+ def main: NodeSeq = {
+ val pageName = S.param("wiki_page") openOr "HomePage" // set the name of the page
+ def showAll = {
+ findAll(OrderBy(WikiEntry.name, Ascending)).flatMap(entry =>
+ )
+ }
+
+ if (pageName == "all")
+ showAll // if the page is "all" display all the pages
+ else {
+ // find the entry in the database or create a new one
+ val entry = find(By(WikiEntry.name, pageName)) openOr create.name(
+ pageName)
+
+ // is it a new entry?
+ val isNew = !entry.saved_?
+
+ // show edit or just display
+ val edit = isNew || (S
+ .param("param1")
+ .map(_ == "edit") openOr false)
+
+ Show All Pages {
if (edit) editEntry(entry, isNew, pageName)
else TextileParser.toHtml(entry.entry,
Some(TextileParser.DefaultRewriter("/wiki"))) ++
Edit // and add an "edit" link
}
- }
- }
-
- def choosebind(xhtml : NodeSeq) = {
- def pageName = S.param("wiki_page") openOr "HomePage" // set the name of the page
-
- def showAll = BindChoice((pageName == "all"), () => bind("pages",
- (xhtml \\ "showAll").filter(_.prefix == "wiki").toList.head.child,
- TheBindParam("all", findAll(OrderBy(WikiEntry.name, Ascending)).flatMap(entry =>
- ))))
-
- // find the entry in the database or create a new one
- def entry = find(By(WikiEntry.name, pageName)) openOr create.name(pageName)
-
- // is it a new entry?
- def isNew = !entry.saved_?
- def toEdit = isNew || (S.param("param1").map(_ == "edit") openOr false)
-
- def edit = BindChoice(toEdit, () => bind("edit",
- (xhtml \\ "editting").filter(_.prefix == "wiki").toList.head.child,
- "form" -> editEntry(entry, isNew, pageName)))
-
- def view = BindChoice(!toEdit, () => bind("view",
- (xhtml \\ "displaying").filter(_.prefix == "wiki").toList.head.child,
- TheBindParam("name", Text(pageName)),
- TheBindParam("value", (TextileParser.toHtml(entry.entry,
- Some(TextileParser.DefaultRewriter("/wiki"))) ++
- Edit ))))
-
- (showAll :: edit :: view :: Nil).find(_.show == true).map(_.bind()) match {
- case Some(x) => x
- case _ =>
- }
- }
-
- private def editEntry(entry: WikiEntry, isNew: Boolean, pageName: String) = {
- val action = uriFor(pageName)
- val message = if (isNew) Text("Create Entry named "+pageName) else Text("Edit entry named "+pageName)
- val hobixLink = Textile Markup Reference
- val cancelLink = Cancel
- val textarea = entry.entry.toForm
- val submitButton = SHtml.submit(isNew ? "Add" | "Edit", () => entry.save)
-
- }
-}
+ }
+ }
*/
-}
-}
+ }
+ }
}
diff --git a/combo/example/src/main/scala/net/liftweb/example/snippet/Wizard.scala b/combo/example/src/main/scala/net/liftweb/example/snippet/Wizard.scala
index 3df412f..9cf8f23 100644
--- a/combo/example/src/main/scala/net/liftweb/example/snippet/Wizard.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/snippet/Wizard.scala
@@ -14,23 +14,18 @@
* limitations under the License.
*/
-package net.liftweb {
-package example {
-package snippet {
+package net.liftweb.example.snippet
-import _root_.scala.xml.{NodeSeq, Text}
-import _root_.net.liftweb.util._
-import _root_.net.liftweb.http._
-import _root_.net.liftweb.wizard._
-import _root_.net.liftweb.common._
-import _root_.java.util.Date
-import Helpers._
+import scala.xml.{NodeSeq, Text}
+import net.liftweb.util._
+import net.liftweb.http._
+import net.liftweb.common._
-import model._
+import net.liftweb.example.model._
/**
- * An example of a wizard in Lift
- */
+ * An example of a wizard in Lift
+ */
object MyWizard extends Wizard {
object completeInfo extends WizardVar(false)
@@ -38,13 +33,20 @@ object MyWizard extends Wizard {
val nameAndAge = new Screen {
// it has a name field
- val name = field(S ? "First Name", "",
+ val name = field(S ? "First Name",
+ "",
valMinLen(2, S ? "Name Too Short"),
- valMaxLen(40, S ? "Name Too Long"))
+ valMaxLen(40, S ? "Name Too Long"),
+ "type" -> "text",
+ "class" -> "form-control")
// and an age field
- val age = field(S ? "Age", 0, minVal(5, S ?? "Too young"),
- maxVal(120, S ? "You should be dead"))
+ val age = field(S ? "Age",
+ 0,
+ minVal(5, S ? "Too young"),
+ maxVal(120, S ? "You should be dead"),
+ "type" -> "number",
+ "class" -> "form-control")
// choose the next screen based on the age
override def nextScreen = if (age.is < 18) parentName else favoritePet
@@ -52,16 +54,22 @@ object MyWizard extends Wizard {
// We ask the parent's name if the person is under 18
val parentName = new Screen {
- val parentName = field(S ? "Mom or Dad's name", "",
+ val parentName = field(S ? "Mom or Dad's name",
+ "",
valMinLen(2, S ? "Name Too Short"),
- valMaxLen(40, S ? "Name Too Long"))
+ valMaxLen(40, S ? "Name Too Long"),
+ "type" -> "text",
+ "class" -> "form-control")
}
// we ask for the favorite pet
val favoritePet = new Screen {
- val petName = field(S ? "Pet's name", "",
+ val petName = field(S ? "Pet's name",
+ "",
valMinLen(2, S ? "Name Too Short"),
- valMaxLen(40, S ? "Name Too Long"))
+ valMaxLen(40, S ? "Name Too Long"),
+ "type" -> "text",
+ "class" -> "form-control")
}
// what to do on completion of the wizard
@@ -73,17 +81,24 @@ object MyWizard extends Wizard {
class WizardChallenge extends Wizard {
val page1 = new Screen {
- val info = field(S ? "Page one entry", "")
+ val info = field(S ? "Page one entry",
+ "",
+ "type" -> "text",
+ "class" -> "form-control")
}
val page2 = new Screen {
override def screenTop = Page one field is {page1.info}
- val info = field(S ? "Page two entry", "")
+ val info = field(S ? "Page two entry",
+ "",
+ "type" -> "text",
+ "class" -> "form-control")
}
val page3 = new Screen {
- override def screenTop = Page one field is {page1.info} Page two field is {page2.info}
+ override def screenTop =
+ Page one field is {page1.info} Page two field is {page2.info}
}
def finish() {
@@ -94,21 +109,23 @@ class WizardChallenge extends Wizard {
class PersonScreen extends LiftScreen {
object person extends ScreenVar(Person.create)
+ override def formName = "PersonScreen"
+
override def screenTop =
- A single screen with some input validation
+ A single screen with some input validation
addFields(() => person.is)
- val shouldSave = field("Save ?", false)
+ val shouldSave = field("Save ?", false, "style" -> "vertical-align:bottom")
- val likeCats = builder("Do you like cats?", "") ^/
- (s => if (Helpers.toBoolean(s)) Nil else "You have to like cats") make
+ val likeCats = builder("Do you like cats?", "", "class" -> "form-control") ^/
+ (s => if (Helpers.toBoolean(s)) Nil else "You have to like cats") make
def finish() {
- S.notice("Thank you for adding "+person.is)
+ S.notice("Thank you for adding " + person.is)
if (shouldSave.is) {
person.is.save
- S.notice(person.is.toString+" Saved in the database")
+ S.notice(person.is.toString + " Saved in the database")
}
}
}
@@ -122,34 +139,37 @@ object VariableScreenInfo {
def name: BaseField = new BaseField with FEP {
private var _name = ""
- def toForm: Box[NodeSeq] = Full(SHtml.text(_name, _name = _))
+ def toForm: Box[NodeSeq] =
+ Full(SHtml.text(_name, _name = _, "class" -> "form-control"))
def setFilter = Nil
def validations = Nil
- def set(v: String) = {_name = v; v}
+ def set(v: String) = { _name = v; v }
def get = _name
def is = get
type ValueType = String
- def name = "Name"
+ def name = "Name"
override val uniqueFieldId: Box[String] = Full(Helpers.nextFuncName)
- def validate = if (_name.length >= 4) Nil
- else "Name must be 4 characters"
+ def validate =
+ if (_name.length >= 4) Nil
+ else "Name must be 4 characters"
}
def address: BaseField = new BaseField with FEP {
private var address = ""
- def toForm: Box[NodeSeq] = Full(SHtml.text(address, address = _))
+ def toForm: Box[NodeSeq] =
+ Full(SHtml.text(address, address = _, "class" -> "form-control"))
def setFilter = Nil
def validations = Nil
- def set(v: String) = {address = v; v}
+ def set(v: String) = { address = v; v }
def get = address
def is = get
type ValueType = String
@@ -158,16 +178,20 @@ object VariableScreenInfo {
override val uniqueFieldId: Box[String] = Full(Helpers.nextFuncName)
- def validate = if (address.length >= 3) Nil
- else "Address must be 3 characters"
+ def validate =
+ if (address.length >= 3) Nil
+ else "Address must be 3 characters"
}
def age: BaseField = new BaseField with FEP {
private var age = 0
- def toForm: Box[NodeSeq] = Full(SHtml.text(age.toString,
- s => Helpers.asInt(s).map(age = _)))
+ def toForm: Box[NodeSeq] =
+ Full(
+ SHtml.text(age.toString,
+ s => Helpers.asInt(s).map(age = _),
+ "class" -> "form-control"))
- def set(v: Int) = {age = v; v}
+ def set(v: Int) = { age = v; v }
def get = age
def is = get
type ValueType = Int
@@ -179,19 +203,24 @@ object VariableScreenInfo {
override val uniqueFieldId: Box[String] = Full(Helpers.nextFuncName)
- def validate = if (age > 10) Nil
- else "Age must be greater than 10"
+ def validate =
+ if (age > 10) Nil
+ else "Age must be greater than 10"
}
def selection: BaseField = new BaseField {
private val opts = List("A", "B", "C", "Last")
private var sel = Full("C")
- def toForm: Box[NodeSeq] = Full(SHtml.select(opts.map(a => a -> a), sel,
- x => sel = Full(x)))
- def set(v: String) = {sel = Full(v); v}
+ def toForm: Box[NodeSeq] =
+ Full(
+ SHtml.select(opts.map(a => a -> a),
+ sel,
+ x => sel = Full(x),
+ "class" -> "form-control"))
+ def set(v: String) = { sel = Full(v); v }
def name = "Selection Thing"
- def get = sel.open_!
+ def get = sel.openOrThrowException("Value should not be empty.")
def is = get
type ValueType = String
@@ -204,22 +233,25 @@ object VariableScreenInfo {
def validate = Nil
}
- def chooseFields: FieldContainer =
- List(name, address, age, selection) filter {
- ignore => Helpers.randomInt(100) > 50
+ def chooseFields: FieldContainer =
+ List(name, address, age, selection) filter { ignore =>
+ Helpers.randomInt(100) > 50
} match {
case Nil => chooseFields
- case xs => new FieldContainer {
- def allFields = xs
- }
+ case xs =>
+ new FieldContainer {
+ def allFields = xs
+ }
}
}
class VariableScreen extends LiftScreen {
object fields extends ScreenVar(VariableScreenInfo.chooseFields)
+ override def formName = "VariableScreen"
+
override def screenTop =
- A single screen with variable fields
+ A single screen with variable fields
addFields(() => fields.is)
@@ -229,61 +261,73 @@ class VariableScreen extends LiftScreen {
}
class AskAboutIceCream1 extends LiftScreen {
+
+ override def formName = "AskAboutIceCream1"
+
val flavor = field(S ? "What's your favorite Ice cream flavor", "")
def finish() {
- S.notice("I like "+flavor.is+" too!")
+ S.notice("I like " + flavor.is + " too!")
}
}
class AskAboutIceCream2 extends LiftScreen {
- val flavor = field(S ? "What's your favorite Ice cream flavor", "",
+
+ override def formName = "AskAboutIceCream2"
+
+ val flavor = field(S ? "What's your favorite Ice cream flavor",
+ "",
trim,
valMinLen(2, "Name too short"),
valMaxLen(40, "That's a long name"))
def finish() {
- S.notice("I like "+flavor.is+" too!")
+ S.notice("I like " + flavor.is + " too!")
}
}
class AskAboutIceCream3 extends LiftScreen {
- val flavor = field(S ? "What's your favorite Ice cream flavor", "",
- trim, valMinLen(2,S ? "Name too short"),
- valMaxLen(40,S ? "That's a long name"))
+
+ override def formName = "AskAboutIceCream3"
+
+ val flavor = field(S ? "What's your favorite Ice cream flavor",
+ "",
+ trim,
+ valMinLen(2, S ? "Name too short"),
+ valMaxLen(40, S ? "That's a long name"))
val sauce = field(S ? "Like chocalate sauce?", false)
def finish() {
if (sauce) {
- S.notice(flavor.is+" tastes especially good with chocolate sauce!")
- }
- else S.notice("I like "+flavor.is+" too!")
+ S.notice(flavor.is + " tastes especially good with chocolate sauce!")
+ } else S.notice("I like " + flavor.is + " too!")
}
}
class AskAboutIceCream4 extends LiftScreen {
- val flavor = field(S ? "What's your favorite Ice cream flavor", "",
- trim, valMinLen(2,S ? "Name too short"),
- valMaxLen(40,S ? "That's a long name"))
+
+ override def formName = "AskAboutIceCream4"
+
+ val flavor = field(S ? "What's your favorite Ice cream flavor",
+ "",
+ trim,
+ valMinLen(2, S ? "Name too short"),
+ valMaxLen(40, S ? "That's a long name"))
val sauce = field(S ? "Like chocalate sauce?", false)
override def validations = notTooMuchChocolate _ :: super.validations
def notTooMuchChocolate(): Errors = {
- if (sauce && flavor.toLowerCase.contains("chocolate")) "That's a lot of chocolate"
+ if (sauce && flavor.toLowerCase.contains("chocolate"))
+ "That's a lot of chocolate"
else Nil
}
def finish() {
if (sauce) {
- S.notice(flavor.is+" tastes especially good with chocolate sauce!")
- }
- else S.notice("I like "+flavor.is+" too!")
+ S.notice(flavor.is + " tastes especially good with chocolate sauce!")
+ } else S.notice("I like " + flavor.is + " too!")
}
}
-
-}
-}
-}
diff --git a/combo/example/src/main/scala/net/liftweb/example/view/XmlFun.scala b/combo/example/src/main/scala/net/liftweb/example/view/XmlFun.scala
index 0cc1f6d..530d7d0 100644
--- a/combo/example/src/main/scala/net/liftweb/example/view/XmlFun.scala
+++ b/combo/example/src/main/scala/net/liftweb/example/view/XmlFun.scala
@@ -14,15 +14,12 @@
* limitations under the License.
*/
-package net.liftweb {
-package example {
-package view {
+package net.liftweb.example.view
-import _root_.scala.xml.{Text, Node, NodeSeq}
-import _root_.net.liftweb.http._
+import scala.xml.{Text, NodeSeq}
+import net.liftweb.http._
import S._
-import _root_.net.liftweb.common._
-import _root_.net.liftweb.util._
+import net.liftweb.common._
class XmlFun extends LiftView {
def dispatch = Map("index" -> render _)
@@ -30,45 +27,50 @@ class XmlFun extends LiftView {
def render = {
val addresses = List(
addressNode("123 any street", null, "SF", "CA", "94122", "US"),
- addressNode("456 other lane", "flat 3", "London", "", "NW3", "GB"),
- addressNode("14 gordon st", "#204", "Brighton", "MA", "02135", "US"),
- addressNode("37 foo lane", null, "Ixtapa", "MX", "ABC", "MX"),
- addressNode("44 sheep st", "#1", "Liverpool", "", "GE1", "GB"),
- addressNode("74 nice st", "#1801", "Chicago", "IL", "60606", "US"))
+ addressNode("456 other lane", "flat 3", "London", "", "NW3", "GB"),
+ addressNode("14 gordon st", "#204", "Brighton", "MA", "02135", "US"),
+ addressNode("37 foo lane", null, "Ixtapa", "MX", "ABC", "MX"),
+ addressNode("44 sheep st", "#1", "Liverpool", "", "GE1", "GB"),
+ addressNode("74 nice st", "#1801", "Chicago", "IL", "60606", "US")
+ )
val toCount = param("country") openOr "US"
- Full(
-
-
- The XML is
-
{addresses.map{e => Text(e.toString) :: :: Nil}}
-
- The count for {toCount} nodes is {countryCount(toCount, addresses)}
-
- Count US addresses.
- Count GB addresses.
-
-
- )
+ Full(
+
+
+ Template
+
+
+
+
XML Fun
+
+
The XML is
+
{addresses.map{e => Text(e.toString) :: :: Nil}}
+
The count for {toCount} nodes is {countryCount(toCount, addresses)}
+
Count US addresses.
+
Count GB addresses.
+
+
+ )
}
- private def addressNode(line1: String, line2: String, city: String,
- state: String, zip_pc: String, country: String) =
-
+ private def addressNode(line1: String,
+ line2: String,
+ city: String,
+ state: String,
+ zip_pc: String,
+ country: String) =
+
{line1} {
if (line2 != null && line2.length > 0) {line2} else Text("")}
{city} {state} {country}
-
private def countryCount(toMatch: String, xml: NodeSeq) =
- (for {
+ (for {
addr <- xml \\ "address"
- country <- addr \\ "country" if country.text == toMatch}
- yield country).length
+ country <- addr \\ "country" if country.text == toMatch
+ } yield country).length
}
-}
-}
-}
diff --git a/combo/example/src/main/webapp/WEB-INF/geronimo-web.xml b/combo/example/src/main/webapp/WEB-INF/geronimo-web.xml
new file mode 100644
index 0000000..46ca12c
--- /dev/null
+++ b/combo/example/src/main/webapp/WEB-INF/geronimo-web.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+ net.liftweb
+ demo
+ 0.9.4-SNAPSHOT
+
+
+
+
+ !org.apache.commons.codec*
+
+
+ /demo
+
+
+
diff --git a/combo/example/src/main/webapp/_bsdialog_confirm.html b/combo/example/src/main/webapp/_bsdialog_confirm.html
new file mode 100644
index 0000000..30cef6f
--- /dev/null
+++ b/combo/example/src/main/webapp/_bsdialog_confirm.html
@@ -0,0 +1,19 @@
+
+
+
+
+
+ Do you really want to destroy Rhode Island?
+
+
+
+
+
\ No newline at end of file
diff --git a/combo/example/src/main/webapp/_chat_fixed.html b/combo/example/src/main/webapp/_chat_fixed.html
index daa76de..4ffd4fa 100644
--- a/combo/example/src/main/webapp/_chat_fixed.html
+++ b/combo/example/src/main/webapp/_chat_fixed.html
@@ -1,4 +1,10 @@
-
+
\ No newline at end of file
diff --git a/combo/example/src/main/webapp/_jsdialog_confirm.html b/combo/example/src/main/webapp/_jsdialog_confirm.html
index c0746b7..1a6ca63 100644
--- a/combo/example/src/main/webapp/_jsdialog_confirm.html
+++ b/combo/example/src/main/webapp/_jsdialog_confirm.html
@@ -1,7 +1,22 @@
-
- Do you really want to destroy Rhode Island?
-
-
Yes
-
No way, dude
+
+
+
+
+
+
Template
+
+
+
+
+
+
+ Do you really want to destroy Rhode Island?
+
+
-
+
+
+
\ No newline at end of file
diff --git a/combo/example/src/main/webapp/ajax-form.html b/combo/example/src/main/webapp/ajax-form.html
index 9e95a78..e1d8047 100644
--- a/combo/example/src/main/webapp/ajax-form.html
+++ b/combo/example/src/main/webapp/ajax-form.html
@@ -1,84 +1,91 @@
-
- AJAX Form Update
-
- Choose city and state:
-
- State:
- City:
-
-
-
- Here's the code:
-
-
-
-class AjaxForm {
- var state = AjaxForm.state
- var city = ""
-
- private def cityChoice (state : String ): Elem = {
- val cities = AjaxForm.citiesFor(state)
- val first = cities.head
- untrustedSelect(cities.map(s => (s,s)), Full(first), city = _)
- }
+
+
+
+
+
+ Template
+
+
+
+
+
%*%
+
+
+
+
Choose city and state:
+
+
+
+
-
private def replace (
state :
String ):
JsCmd = {
-
val cities = AjaxForm.citiesFor(state)
-
val first = cities.head
- ReplaceOptions(
"city_select" , cities.map(s => (s,s)), Full(first))
+
The
+ Lift Scala code
+
class AjaxForm {
+ var state = AjaxForm.state
+ var city = ""
+
+ private def cityChoice(state: String): Elem = {
+ val cities = AjaxForm.citiesFor(state)
+ val first = cities.head
+ // make the select "untrusted" because we might put new values
+ // in the select
+ untrustedSelect(cities.map(s => (s, s)),
+ Full(first),
+ s => city = s,
+ "class" -> "form-control")
}
+ private def replace(state: String): JsCmd = {
+ val cities = AjaxForm.citiesFor(state)
+ val first = cities.head
+ ReplaceOptions("city", cities.map(s => (s, s)), Full(first))
+ }
- def show (xhtml : Group ): NodeSeq = {
- val (name , js ) = ajaxCall(JE.JsRaw("this.value" ),
- s => After(200, replace(s)))
- bind("select" , xhtml,
- "state" -> select(AjaxForm.states.map(s => (s,s)),
- Full(state), state = _, "onchange" -> js.toJsCmd) %
- (new PrefixedAttribute("lift" , "gc" , name, Null)),
- "city" -> cityChoice(state) % ("id" -> "city_select" ),
- "submit" -> submit(?("Save" ),
- () =>
- {S.notice("City: " +city+" State: " +state);
- redirectTo("/" )}))
+ def render = {
+ "#state" #> ajaxSelect(AjaxForm.states.map(s => (s, s)), Full(state), { s =>
+ state = s; After(200, replace(state))
+ }, "class" -> "form-control") &
+ "#city" #> cityChoice(state) &
+ "type=submit" #> submit(?("Save"), () => {
+ S.notice("City: " + city + ", State: " + state); redirectTo("/")
+ }, "class" -> "btn btn-primary")
}
}
-
+object AjaxForm {
+ val citiesAndStates = List(
+ "Alabama" -> "Birmingham",
+ "Alabama" -> "Huntsville",
+ :
+ :
+ "Wisconsin" -> "Milwaukee"
+ )
+
+ val states = citiesAndStates.map(_._1).distinct
+
+ val state: String = states.head
+
+ def citiesFor(state: String): List[String] =
+ citiesAndStates.filter(_._1 == state).map(_._2)
+}
+
+
+
-
-
+
\ No newline at end of file
diff --git a/combo/example/src/main/webapp/ajax.html b/combo/example/src/main/webapp/ajax.html
index 1c738af..dca03ed 100644
--- a/combo/example/src/main/webapp/ajax.html
+++ b/combo/example/src/main/webapp/ajax.html
@@ -1,134 +1,163 @@
-
-
- AJAX Samples
-
-
-
- Click me to increase the count (currently 0 )
-
-
-
-
-
-
- You selected From the select box.
-
-
-
-
- You entered in the text box.
-
-
-
-
- An example of autocomplete with a server round trip to
- calculate the autocomplete list
-
-
-
-
-
-
- And each time an Ajax or Comet update is made to the page,
- we update this span:
- The time is
-
-
+
+
+
+
+
+
Template
+
+
+
+
+
+
+
+
+
+
%*%
+
+
+
+
+
+
+
+ Click me to increase the count (currently
+ 0 )
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Each time an Ajax or Comet update is made to the page, we update this span:
+ The time is
+
+
+
+
+
+
+
+
+
+
The
+ Lift Scala code
+
class Ajax extends Loggable {
+
+ def sample(xhtml: NodeSeq): NodeSeq = {
+ // local state for the counter
+ var cnt = 0
+
+ // get the id of some elements to update
+ val spanName: String = S.attr("id_name") openOr "cnt_id"
+ val msgName: String = S.attr("id_msgs") openOr "messages"
+
+ // build up an ajax <a> tag to increment the counter
+ def doClicker(text: NodeSeq) =
+ a(() => { cnt = cnt + 1; SetHtml(spanName, Text(cnt.toString)) }, text)
+
+ // create an ajax select box
+ def doSelect(msg: NodeSeq) =
+ ajaxSelect(
+ (1 to 50).toList.map(i => (i.toString, i.toString)),
+ Full(1.toString),
+ v => {
+ val selectBind = "#selNumber" #> Text(v)
+ DisplayMessage(
+ msgName,
+ <span>{selectBind(msg)}</span>,
+ 5 seconds,
+ 1 second
+ )
+ },
+ "class" -> "form-control"
+ )
+
+ // build up an ajax text box
+ def doText(msg: NodeSeq) =
+ ajaxText(
+ "",
+ v => {
+ val textBind = "#textValue" #> Text(v)
+ DisplayMessage(msgName,
+ <span>{textBind(msg)}</span>,
+ 6 seconds,
+ 1 second)
+ },
+ "class" -> "form-control"
+ )
+
+ // bind the view to the functionality
+ val viewBind = {
+ "#ajaxClicker" #> doClicker _ &
+ "#ajaxSelect" #> doSelect _ &
+ "#ajaxText" #> doText _ &
+ "#ajaxAuto" #> AutoComplete("",
+ buildQuery _,
+ (x: String) => (),
+ "class" -> "form-control")
+ }
+ viewBind(xhtml)
+ }
-
-
-
- Enter some text:
- and Click Here
-
-
-
-
-
-
- The
Lift Scala code to render the controls:
-
-
-
-
-
-
-class Ajax {
-
- def sample (xhtml : NodeSeq ): NodeSeq = {
- var cnt = 0
-
- val spanName : String = S.attr("id_name" ) openOr "cnt_id"
- val msgName : String = S.attr("id_msgs" ) openOr "messages"
-
- def doClicker (text : NodeSeq ) =
- a(() => {cnt = cnt + 1; SetHtml(spanName, Text( cnt.toString))}, text)
-
- def doSelect (msg : NodeSeq ) =
- ajaxSelect((1 to 50).toList.map(i => (i.toString, i.toString)),
- Full(1.toString),
- v => DisplayMessage(msgName,
- bind("sel" , msg, "number" -> Text(v)),
- 5 seconds, 1 second))
-
- def doText (msg : NodeSeq ) =
- ajaxText("" , v => DisplayMessage(msgName,
- bind("text" , msg, "value" -> Text(v)),
- 4 seconds, 1 second))
-
-
-
- bind("ajax" , xhtml,
- "clicker" -> doClicker _,
- "select" -> doSelect _,
- "text" -> doText _,
- "auto" -> JqSHtml.autocomplete("" , buildQuery _, _ => ()))
+ private def buildQuery(current: String, limit: Int): Seq[String] = {
+ logger.info("Checking on server side with " + current + " limit " + limit)
+ (1 to limit).map(n => current + "" + n)
}
- private def buildQuery (current : String , limit : Int ): Seq[String] = {
- Log.info("Checking on server side with " +current+" limit " +limit)
- (1 to limit).map(n => current+"" +n)
+ def time = Text(now.toString)
+
+ def buttonClick = {
+ import js.JE._
+
+ "* [onclick]" #> SHtml.ajaxCall(
+ ValById("the_input"),
+ s =>
+ SetHtml("bcmessages",
+ <i>Latest Button click was with text box value '{s}'</i>))
}
+}
+
+
+
- def time = Text(timeNow.toString)
-}
-
-
-
+
\ No newline at end of file
diff --git a/combo/example/src/main/webapp/arc.html b/combo/example/src/main/webapp/arc.html
index 8526c22..261a40e 100644
--- a/combo/example/src/main/webapp/arc.html
+++ b/combo/example/src/main/webapp/arc.html
@@ -1,82 +1,84 @@
-
-
+
+
- The Code
-
-
-
+
+
+
%*%
-
-
-class ArcChallenge extends StatefulSnippet {
- var dispatch : DispatchIt = {case _ => xhtml => ask}
+
-
- def ask = {
- <p>
- Say Anything:
- {text("" , p => phrase = p)}
- {submit("Submit" , () => dispatch = {case _ => xhtml => think})}
- </p>
+
+
+
+
+
+
+ The
+ Lift Scala code
+ /**
+ * The Arc Challenge is Paul Graham's quest for web framework concision.
+ *
+ * http://www.paulgraham.com/arcchallenge.html
+ *
+ * This is one potential lift-based solution to it using StatefulSnippets.
+ * There are doubtless many other ways.
+ *
+ * @author: Steve Jenson
+ */
+class ArcChallenge extends StatefulSnippet {
+ var dispatch: DispatchIt = {
+ case _ =>
+ xhtml =>
+ ask
+ }
+
+ /**
+ * Step 1: Type in a Phrase.
+ */
+ def ask = {
+ <form class="form-inline">
+ <div class="form-group">
+ <label for="answer">Say Anything:</label>
+ {text("",
+ p => phrase = p,
+ "id" -> "answer",
+ "class" -> "form-control mx-sm-3")}
+ </div>
+ {submit("Submit",
+ () => dispatch = {case _ => xhtml => think},
+ "class" -> "btn btn-primary")}
+ </form>
}
-
- def think = submit("Click here to see what you said" ,
- () => dispatch = {case _ => xhtml => answer})
+ /**
+ * Step 2: Show a link that takes you to the Phrase you entered.
+ */
+ def think =
+ submit("Click here to see what you said",
+ () =>
+ dispatch = {
+ case _ =>
+ xhtml =>
+ answer
+ },
+ "class" -> "btn btn-primary")
-
- def answer = <p>You said: {phrase}</p>
+ /**
+ * Step 3: Show the phrase.
+ */
+ def answer = <p>You said: {phrase}</p>
- private var phrase = ""
-}
-
+ private var phrase = ""
+}
+
+
-
+
\ No newline at end of file
diff --git a/combo/example/src/main/webapp/assets/css/app.css b/combo/example/src/main/webapp/assets/css/app.css
new file mode 100644
index 0000000..1be8667
--- /dev/null
+++ b/combo/example/src/main/webapp/assets/css/app.css
@@ -0,0 +1,249 @@
+
+.navbar {
+ background-color: #fff;
+ box-shadow: 0px 1px 1px 0px rgba(0,0,0,0.25);
+}
+.navbar .dropdown-menu {
+ background-color: inherit;
+ border: none;
+}
+
+.dropdown-divider {
+ border-top: 1px solid #fff;
+}
+
+.widget {
+ border: 1px solid #ccc;
+ background: #f5f5f5;
+ padding: 5px;
+ margin: 10px 0 0 0;
+ font-size: 8pt;
+}
+
+.sidebar > ul {
+ min-width: 200px;
+ padding: 0;
+ background-color: #fff;
+ margin-left: 0;
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+ -webkit-box-shadow: 0 1px 4px rgba(0,0,0,.065);
+ -moz-box-shadow: 0 1px 4px rgba(0,0,0,.065);
+ box-shadow: 0 1px 4px rgba(0,0,0,.065);
+}
+.sidebar > ul > li > ul,
+.sidebar > ul > li > ul > li > ul {
+ min-width: 200px;
+ padding: 0;
+ background-color: #fff;
+ margin-left: 0;
+}
+.sidebar ul li,
+.sidebar ul li ul li,
+.sidebar ul li ul li ul li {
+ list-style: none;
+}
+.sidebar > ul > li > a,
+.sidebar > ul > li > span,
+.sidebar > ul > li > ul > li > a,
+.sidebar > ul > li > ul > li > span,
+.sidebar > ul > li > ul > li > ul > li > a,
+.sidebar > ul > li > ul > li > ul > li > span {
+ display: block;
+ margin: 0 0 -1px;
+ font-size: 14px;
+ padding: 3px;
+ text-indent: 10px;
+ text-decoration: none;
+ border: 1px solid #e5e5e5;
+}
+
+.sidebar > ul > li > ul > li > a ,
+.sidebar > ul > li > ul > li > span {
+ padding-left: 15px;
+}
+.sidebar > ul > li > ul > li > ul > li > a ,
+.sidebar > ul > li > ul > li > ul > li > span {
+ padding-left: 25px;
+}
+
+.sidebar > ul > li:first-child > a,
+.sidebar > ul > li:first-child > span {
+ -webkit-border-radius: 6px 6px 0 0;
+ -moz-border-radius: 6px 6px 0 0;
+ border-radius: 6px 6px 0 0;
+}
+.sidebar ul li:last-child > a,
+.sidebar ul li:last-child > span {
+ -webkit-border-radius: 0 0 6px 6px;
+ -moz-border-radius: 0 0 6px 6px;
+ border-radius: 0 0 6px 6px;
+}
+
+.sidebar ul li a:hover,
+.sidebar ul li span:hover {
+ background-color: #eee;
+}
+
+#poweredBy .alt {
+ color: #666;
+ font-family: "Warnock Pro", "Goudy Old Style", "Palatino", "Book Antiqua", Georgia, serif;
+ font-style: italic;
+ font-weight: normal;
+}
+
+div.globalErrors ul {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+}
+
+ul.errors {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+}
+
+.lift_error {
+ color: red;
+}
+
+.lift_warning {
+ color: yellow;
+}
+
+.lift_notice {}
+
+.main-border {
+ border-left: none;
+}
+
+.dpp_stuff p {
+ padding-left: 15px;
+}
+
+
+/*Lift stuff*/
+
+
+/*Lift notice*/
+
+#wrappedNotice #lift__noticesContainer___notice ul,
+#wrappedNotice #lift__noticesContainer___warning ul,
+#wrappedNotice #lift__noticesContainer___error ul {
+ padding: 5px;
+ list-style-type: none;
+}
+
+#wrappedNotice #lift__noticesContainer___notice {
+ border-radius: 5px;
+ background-color: #D9EDF7;
+ border-color: #BCE8F1;
+ color: #3A87AD;
+}
+
+#wrappedNotice #lift__noticesContainer___warning {
+ border-radius: 5px;
+ background-color: #FCF8E3;
+ border-color: #FBEED5;
+ color: #C09853;
+}
+
+#wrappedNotice #lift__noticesContainer___error {
+ border-radius: 5px;
+ background-color: #F2DEDE;
+ border-color: #EED3D7;
+ color: #B94A48;
+}
+
+#wrappedNoticeAtHead #lift__noticesContainer___notice ul,
+#wrappedNoticeAtHead #lift__noticesContainer___warning ul,
+#wrappedNoticeAtHead #lift__noticesContainer___error ul {
+ padding: 5px;
+ list-style-type: none;
+}
+
+#wrappedNoticeAtHead #lift__noticesContainer___notice {
+ border-radius: 5px;
+ background-color: #D9EDF7;
+ border-color: #BCE8F1;
+ color: #3A87AD;
+}
+
+#wrappedNoticeAtHead #lift__noticesContainer___warning {
+ border-radius: 5px;
+ background-color: #FCF8E3;
+ border-color: #FBEED5;
+ color: #C09853;
+}
+
+#wrappedNoticeAtHead #lift__noticesContainer___error {
+ border-radius: 5px;
+ background-color: #F2DEDE;
+ border-color: #EED3D7;
+ color: #B94A48;
+}
+
+.error_class {
+ border-radius: 5px;
+ padding: 5px;
+ background-color: #F2DEDE;
+ border-color: #EED3D7;
+ color: #B94A48;
+}
+
+.notice_class {
+ border-radius: 5px;
+ padding: 5px;
+ background-color: #D9EDF7;
+ border-color: #BCE8F1;
+ color: #3A87AD;
+}
+
+.widget ul {
+ padding: 5px;
+}
+
+.widget ul li {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ border: 1px solid #ccc;
+ border-bottom: none;
+}
+
+.widget ul li:last-child {
+ border-bottom: 1px solid #ccc;
+}
+
+.bd-callout {
+ padding: 1.25rem;
+ margin-top: 1.25rem;
+ margin-bottom: 1.25rem;
+ border: 1px solid #eee;
+ border-left-width: .25rem;
+ border-radius: .25rem;
+}
+
+.bd-callout-info {
+ border-left-color: #5bc0de;
+}
+
+.bd-callout-warning {
+ border-left-color: #f0ad4e;
+}
+
+
+/* bootstrap overrides */
+
+.breadcrumb {
+ font-size: 0.8rem;
+ padding: 0.2rem 0.8rem;
+}
+
+@media (min-width: 768px) {
+ .main-border {
+ border-left: 1px solid rgba(0, 0, 0, 0.1);
+ }
+}
\ No newline at end of file
diff --git a/combo/example/src/main/webapp/async_rest.html b/combo/example/src/main/webapp/async_rest.html
index 13b304f..2602660 100644
--- a/combo/example/src/main/webapp/async_rest.html
+++ b/combo/example/src/main/webapp/async_rest.html
@@ -1,75 +1,62 @@
-
-
- This example demonstrates how to use the container's
- Asynchronous (continuation) response capabilities such
- that no I/O threads are consumed during the calculation
- of the REST response value.
-
Click to see the response
- after a 2 second delay.
-
+
+
+
+
+
+ Template
+
+
+
+
+
%*%
+
+
+
+
-
-
+
+ This example demonstrates how to use the container's Asynchronous (continuation) response capabilities such that
+ no I/O threads
+ are consumed during the calculation of the REST response value.
+
Click to see the response after a 2 second delay.
+
-
-
-object AsyncRest extends RestHelper {
+ */
+object AsyncRest extends RestHelper {
- serve {
- case "async" :: id :: _ Get _ =>
+ // serve the URL /async/:id
+ serve {
+ case "async" :: id :: _ Get _ =>
- RestContinuation.async(
- reply => {
- Thread.sleep(2000) val name1 = Thread.currentThread.getName
- val outerSesStr = S.session.toString
- reply{
- val name2 = Thread.currentThread.getName
- val innerSesStr = S.session.toString <i id={id}>name1: {name1} outer: {outerSesStr} name2: {name2}
+ // move the calculation to another thread
+ RestContinuation.async(
+ reply => {
+ Thread.sleep(2000) // sleep for 2 seconds
+ val name1 = Thread.currentThread.getName
+ val outerSesStr = S.session.toString // this should be Empty
+
+ // the code block for reply will be executed in the
+ // scope of the original request and that may mean
+ // that JDBC connections are consumed, etc.
+ reply{
+ val name2 = Thread.currentThread.getName
+ val innerSesStr = S.session.toString // this should be Full()
+ <i id={id}>name1: {name1} outer: {outerSesStr} name2: {name2}
inner: {innerSesStr}</i>
}
})
}
-}
-
+}
+
-
+
+
+
+
\ No newline at end of file
diff --git a/combo/example/src/main/webapp/chat.html b/combo/example/src/main/webapp/chat.html
index 3171029..b306087 100644
--- a/combo/example/src/main/webapp/chat.html
+++ b/combo/example/src/main/webapp/chat.html
@@ -1,159 +1,148 @@
-
-
-
- The total chat app, including the ask/answer component for soliciting a
- name
- comments, etc. is listed on this page.
- There is no special code to support AJAX/Comet
- (all the wrapping is done automatically by Lift ).
-
-
-
- When the Chat comet widget is added to the page, it needs to solict the
- user for a "chat name". It asks the "AskName" comet widget for the name.
- Until the AskName comet widget provides a name, all rendering messages
- are forwarded to AskName.
- Here's the code for the "AskName":
-
-
-
-class Chat extends CometActor with CometListener {
- private var userName = ""
- private var chats : List[ChatLine] = Nil
+
-
- private val ulId = S.attr("ul_id" ) openOr "some_ul_id"
+ */
+ private val ulId = S.attr("ul_id") openOr "some_ul_id"
- private val liId = S.attr("li_id" )
+ private val liId = S.attr("li_id")
- private lazy val li = liId.
- flatMap{ Helpers.findId(defaultXml, _) } openOr NodeSeq.Empty
+ private lazy val li = liId.
+ flatMap{ Helpers.findId(defaultHtml, _) } openOr NodeSeq.Empty
- private val inputId = Helpers.nextFuncName
+ private val inputId = Helpers.nextFuncName
- override def lowPriority = {
- case ChatServerUpdate (value ) => {
- val update = (value -- chats).reverse.
- map(b => AppendHtml(ulId, line(b)))
+ // handle an update to the chat lists
+ // by diffing the lists and then sending a partial update
+ // to the browser
+ override def lowPriority = {
+ case ChatServerUpdate(value) => {
+ val update = (value filterNot (chats contains)).reverse.
+ map(b => AppendHtml(ulId, line(b)))
partialUpdate(update)
chats = value
}
}
- override lazy val fixedRender : Box[NodeSeq] =
- S.runTemplate("_chat_fixed" :: Nil,
- "postit" -> Helpers.evalElemWithId {
- (id, elem) =>
- SHtml.onSubmit((s: String) => {
+ // render the input area by binding the
+ // appropriate dynamically generated code to the
+ // view supplied by the template
+ override lazy val fixedRender: Box[NodeSeq] =
+ S.runTemplate("_chat_fixed" :: Nil,
+ "postit" -> Helpers.evalElemWithId {
+ (id, elem) =>
+ SHtml.onSubmit((s: String) => {
ChatServer ! ChatServerMsg(userName, s.trim)
- SetValById(id, "" )
+ SetValById(id, "")
})(elem)
} _)
- private def line (c : ChatLine ) = {
- ("name=when" #> hourFormat(c.when) &
- "name=who" #> c.user &
- "name=body" #> c.msg)(li)
+ // display a line
+ private def line(c: ChatLine) = {
+ ("name=when" #> hourFormat(c.when) &
+ "name=who" #> c.user &
+ "name=body" #> c.msg)(li)
}
- private def displayList : NodeSeq = chats.reverse.flatMap(line)
+ // display a list of chats
+ private def displayList: NodeSeq = chats.reverse.flatMap(line)
- override def render = {
- "name=chat_name" #> userName &
- ("#" +ulId+" *" ) #> displayList
+ // render the whole list of chats
+ override def render = {
+ "name=chat_name" #> userName &
+ ("#"+ulId+" *") #> displayList
}
- override def localSetup {
+ // setup the component
+ override def localSetup {
askForName
- super .localSetup
+ super.localSetup
}
- def registerWith = ChatServer
+ // register as a listener
+ def registerWith = ChatServer
- private def askForName {
- if (userName.length == 0) {
- ask(new AskName, "what's your username" ) {
- case s : String if (s.trim.length > 2) =>
+ // ask for the user's name
+ private def askForName {
+ if (userName.length == 0) {
+ ask(new AskName, "what's your username") {
+ case s: String if (s.trim.length > 2) =>
userName = s.trim
- reRender(true )
+ reRender(true)
- case _ =>
+ case _ =>
askForName
- reRender(false )
+ reRender(false)
}
}
}
-}
-
+}
+
+
+ This example demonstrates the power of Scala's Actors and
+ Lift . With very few lines of code, we've got a complete AJAX/Comet app that has Seaside style Ask/Answer
+ for building
+ modal dialogs.
+
+
+
-
- This example demonstrates the power of Scala's Actors and Lift .
- With very few lines of code, we've got a complete AJAX/Comet app that
- has Seaside style Ask/Answer for building modal dialogs.
-
-
+