All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.liftweb.builtin.snippet.Msgs.scala Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2007-2011 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
package builtin
package snippet

import http._
import scala.xml._
import net.liftweb.util.Helpers._
import net.liftweb.http.js._
import JsCmds._
import net.liftweb.common.{Box, Empty}
import common.Full
import xml.Text


/**
 * This built in snippet renders messages (Errors, Warnings, Notices) in a div.
 * Typically it is used in templates as a place holder for any messages that are not associated with an ID.
 * Setting the attribute showAll to true will render all messages, with and without an ID.
 * This will lead to duplicate messages if additionally the Msg built in snippet is used to show
 * messages associated with an ID.
 *
 * E.g. (child nodes are optional)
 * 
 * <lift:Msgs showAll="false">
 *   <lift:error_msg class="errorBox" >Error!  The details are:</lift:error_msg>
 *   <lift:warning_msg>Whoops, I had a problem:</lift:warning_msg>
 *   <lift:warning_class>warningBox</lift:warning_class>
 *   <lift:notice_msg>Note:</lift:notice_msg>
 *   <lift:notice_class>noticeBox</lift:notice_class>
 * </lift:snippet>
 * 
* * JavaScript fadeout and effects for the three types of notices (Errors, Warnings and Notices) can * be configured via LiftRules.noticesAutoFadeOut and LiftRules.noticesEffects. Notices for individual * elements based on id can be rendered using the <lift:msg/> tag. * * @see net.liftweb.builtin.snippet.Msg * @see net.liftweb.http.LiftRules#noticesAutoFadeOut * @see net.liftweb.http.LiftRules#noticesEffects */ object Msgs extends DispatchSnippet { // Dispatch to the render method no matter how we're called def dispatch: DispatchIt = { case _ => render } /** * This method performs extraction of custom formatting and then * renders the current notices. * * @see #renderNotices() */ def render(styles: NodeSeq): NodeSeq = { // Capture the value for later AJAX updates ShowAll(toBoolean(S.attr("showAll") or S.attr("showall"))) // Extract user-specified titles and CSS classes for later use List((NoticeType.Error, MsgsErrorMeta), (NoticeType.Warning, MsgsWarningMeta), (NoticeType.Notice, MsgsNoticeMeta)).foreach { case (noticeType, ajaxStorage) => { // Extract the title if provided, or default to none. Allow for XML nodes // so that people can localize, etc. val title : NodeSeq = (styles \\ noticeType.titleTag). filter(_.prefix == "lift").flatMap(_.child) // Extract any provided classes for the messages val cssClasses = ((styles \\ noticeType.styleTag) ++ (styles \\ noticeType.titleTag \\ "@class")). toList.map(_.text.trim) match { case Nil => Empty case classes => Full(classes.mkString(" ")) } // Save the settings for AJAX usage ajaxStorage(Full(AjaxMessageMeta(title,cssClasses))) } } // Delegate the actual rendering to a shared method so that we don't // duplicate code for the AJAX pipeline (
{renderNotices()}
% ("id" -> LiftRules.noticesContainerId)) ++ noticesFadeOut(NoticeType.Notice) ++ noticesFadeOut(NoticeType.Warning) ++ noticesFadeOut(NoticeType.Error) ++ effects(NoticeType.Notice) ++ effects(NoticeType.Warning) ++ effects(NoticeType.Error) } /** * This method renders the current notices to XHtml based on * the current user-specific formatting from the <lift:Msgs> tag. */ def renderNotices() : NodeSeq = { // Determine which formatting function to use based on tag usage val f = if (ShowAll.is) { S.messages _ } else { S.noIdMessages _ } // Compute the formatted set of messages for a given input def computeMessageDiv (args : (List[(NodeSeq,Box[String])],NoticeType.Value,SessionVar[Box[AjaxMessageMeta]])) : NodeSeq = args match { case (messages,noticeType,ajaxStorage) => // get current settings val title = ajaxStorage.get.map(_.title) openOr Text("") val styles = ajaxStorage.get.flatMap(_.cssClasses) // Compute the resulting div f(messages).toList.map(e => (
  • {e}
  • ) ) match { case Nil => Nil case msgList => { val ret =
    {title}
      {msgList}
    styles.foldLeft(ret)((xml, style) => xml % new UnprefixedAttribute("class", Text(style), Null)) } } } // Render all three types together List((S.errors, NoticeType.Error, MsgsErrorMeta), (S.warnings, NoticeType.Warning, MsgsWarningMeta), (S.notices, NoticeType.Notice, MsgsNoticeMeta)).flatMap(computeMessageDiv) } // This wraps the JavaScript fade and effect scripts into a script that runs onLoad private[snippet] def tailScript (script : JsCmd) : NodeSeq = {Script(OnLoad(script))} /** * This method produces appropriate JavaScript to fade out the given * notice type. The caller must provide a default value for cases where * fadeout is not configured, as well as a wrapping * function to transform the output. * * @see net.liftweb.http.LiftRules.noticesAutoFadeOut */ def noticesFadeOut[T](noticeType: NoticeType.Value, default : T, wrap : JsCmd => T): T = LiftRules.noticesAutoFadeOut()(noticeType) map { case (duration, fadeTime) => { wrap(LiftRules.jsArtifacts.fadeOut(noticeType.id, duration, fadeTime)) } } openOr default /** * This method produces an appropriate