Skip to content
This repository
Browse code

Completing the Lift widgets chapter

  • Loading branch information...
commit 41816cff1b76c74f880a1b7142debf66b450fef7 1 parent 31307d6
unknown authored
386 chap-widgets.lyx
@@ -90,9 +90,11 @@ Lift framework comes with a set of widgets existent in the lift-widgets
90 90 sub-project.
91 91 This list of widget is expect to grow in time providing a rich set of widgets
92 92 that you can just use in your application.
93   - We also encourge you towrite your own widgets but we'll see in a bit how
94   - you can create your own widget, or better yet what is the approach that
95   - we chose for building Lift widgets.
  93 + This also means that this is not a complete list of Lift widgets as by
  94 + the time you read this book more widgets might be available.We also encourge
  95 + you to write your own widgets but we'll see in a bit how you can create
  96 + your own widget, or better yet what is the approach that we chose for building
  97 + Lift widgets.
96 98 \end_layout
97 99
98 100 \begin_layout Subsection
@@ -1238,7 +1240,7 @@ case class Tree(text:String, // The node text
1238 1240
1239 1241 \begin_layout Plain Layout
1240 1242
1241   - hasChildren: Boolean, // Indicates if this node has choldern of not.
  1243 + hasChildren: Boolean, // Indicates if this node has children of not.
1242 1244 \end_layout
1243 1245
1244 1246 \begin_layout Plain Layout
@@ -1254,15 +1256,385 @@ case class Tree(text:String, // The node text
1254 1256 \end_deeper
1255 1257 \begin_layout Standard
1256 1258 There is also a companion module providing different overloaded apply functions.
1257   - As you've noticed we have a List of choldern which can be empty (Nil) but
1258   - we also have a hasChildren flag.
  1259 + As you've noticed we have a List of Tree which can be empty (Nil) but we
  1260 + also have a hasChildren flag.
1259 1261 The reason is that hasChildren semantic is beyond the scope of an empty
1260   - childern list.
  1262 + Tree list.
1261 1263 For instance for Ajax nodes we can have
1262 1264 \family typewriter
1263 1265 hasChildren = true
1264 1266 \family default
1265 1267 but the actual children list will be fetched dynamically using Ajax call.
  1268 + Here is an example of building a tree:
  1269 +\end_layout
  1270 +
  1271 +\begin_layout Standard
  1272 +\begin_inset listings
  1273 +inline false
  1274 +status open
  1275 +
  1276 +\begin_layout Plain Layout
  1277 +
  1278 +\begin_inset Caption
  1279 +
  1280 +\begin_layout Plain Layout
  1281 +
  1282 +Tree example
  1283 +\end_layout
  1284 +
  1285 +\end_inset
  1286 +
  1287 +
  1288 +\end_layout
  1289 +
  1290 +\begin_layout Plain Layout
  1291 +
  1292 +\end_layout
  1293 +
  1294 +\begin_layout Plain Layout
  1295 +
  1296 +Tree("1.
  1297 + Pre Lunch (120 min)", "folder", false, false,
  1298 +\end_layout
  1299 +
  1300 +\begin_layout Plain Layout
  1301 +
  1302 + Tree("1.1 The State of the Powerdome (30 min)", "file") ::
  1303 +\end_layout
  1304 +
  1305 +\begin_layout Plain Layout
  1306 +
  1307 + Tree("1.2 The Future of jQuery (30 min)", "file") ::
  1308 +\end_layout
  1309 +
  1310 +\begin_layout Plain Layout
  1311 +
  1312 + Tree("1.2 jQuery UI - A step to richnessy (60 min)", "file") ::
  1313 +\end_layout
  1314 +
  1315 +\begin_layout Plain Layout
  1316 +
  1317 + Nil)
  1318 +\end_layout
  1319 +
  1320 +\end_inset
  1321 +
  1322 +
  1323 +\end_layout
  1324 +
  1325 +\begin_layout Subsection
  1326 +Sparklines widget
  1327 +\end_layout
  1328 +
  1329 +\begin_layout Standard
  1330 +The sparklines widget is baed on http://www.willarson.com/code/sparklines/sparklin
  1331 +es.html script.
  1332 + It renders charts using HTML canvas.
  1333 +\end_layout
  1334 +
  1335 +\begin_layout Standard
  1336 +\begin_inset Float figure
  1337 +wide false
  1338 +sideways false
  1339 +status open
  1340 +
  1341 +\begin_layout Plain Layout
  1342 +\align center
  1343 +\begin_inset Graphics
  1344 + filename images/sparklines.png
  1345 +
  1346 +\end_inset
  1347 +
  1348 +
  1349 +\end_layout
  1350 +
  1351 +\begin_layout Plain Layout
  1352 +\begin_inset Caption
  1353 +
  1354 +\begin_layout Plain Layout
  1355 +Sparklines widget
  1356 +\end_layout
  1357 +
  1358 +\end_inset
  1359 +
  1360 +
  1361 +\end_layout
  1362 +
  1363 +\begin_layout Plain Layout
  1364 +
  1365 +\end_layout
  1366 +
  1367 +\end_inset
  1368 +
  1369 +
  1370 +\end_layout
  1371 +
  1372 +\begin_layout Standard
  1373 +Similarly with other widgets you need to initialize the widget in Boot by
  1374 + calling
  1375 +\family typewriter
  1376 +Sparklines.init
  1377 +\family default
  1378 +.
  1379 + Here is a snippet code example:
  1380 +\end_layout
  1381 +
  1382 +\begin_layout Standard
  1383 +\begin_inset listings
  1384 +inline false
  1385 +status open
  1386 +
  1387 +\begin_layout Plain Layout
  1388 +
  1389 +\begin_inset Caption
  1390 +
  1391 +\begin_layout Plain Layout
  1392 +
  1393 +Sparklines example
  1394 +\end_layout
  1395 +
  1396 +\end_inset
  1397 +
  1398 +
  1399 +\end_layout
  1400 +
  1401 +\begin_layout Plain Layout
  1402 +
  1403 +/*
  1404 +\end_layout
  1405 +
  1406 +\begin_layout Plain Layout
  1407 +
  1408 +The template example:
  1409 +\end_layout
  1410 +
  1411 +\begin_layout Plain Layout
  1412 +
  1413 +<lift:surround with="default" at="content">
  1414 +\end_layout
  1415 +
  1416 +\begin_layout Plain Layout
  1417 +
  1418 + <lift:SparklinesDemo.renderOnLoad />
  1419 +\end_layout
  1420 +
  1421 +\begin_layout Plain Layout
  1422 +
  1423 + <canvas id="bar" style="width: 500px; height: 200px;"></canvas>
  1424 +\end_layout
  1425 +
  1426 +\begin_layout Plain Layout
  1427 +
  1428 +</lift:surround>
  1429 +\end_layout
  1430 +
  1431 +\begin_layout Plain Layout
  1432 +
  1433 +*/
  1434 +\end_layout
  1435 +
  1436 +\begin_layout Plain Layout
  1437 +
  1438 +class SparklinesDemo {
  1439 +\end_layout
  1440 +
  1441 +\begin_layout Plain Layout
  1442 +
  1443 + def renderOnLoad(html: NodeSeq): NodeSeq = {
  1444 +\end_layout
  1445 +
  1446 +\begin_layout Plain Layout
  1447 +
  1448 + val data = JsArray(100,500,300,200,400,500,400,400,100,200, 345, 412,
  1449 + 111, 234, 490);
  1450 +\end_layout
  1451 +
  1452 +\begin_layout Plain Layout
  1453 +
  1454 + val opts = JsObj(("percentage_lines" -> JsArray(0.5, 0.75)),
  1455 +\end_layout
  1456 +
  1457 +\begin_layout Plain Layout
  1458 +
  1459 + ("fill_between_percentage_lines" -> true),
  1460 +\end_layout
  1461 +
  1462 +\begin_layout Plain Layout
  1463 +
  1464 + ("extend_markings" -> false));
  1465 +\end_layout
  1466 +
  1467 +\begin_layout Plain Layout
  1468 +
  1469 + Sparklines.onLoad("bar", SparklineStyle.BAR, data, opts);
  1470 +\end_layout
  1471 +
  1472 +\begin_layout Plain Layout
  1473 +
  1474 + }
  1475 +\end_layout
  1476 +
  1477 +\begin_layout Plain Layout
  1478 +
  1479 +}
  1480 +\end_layout
  1481 +
  1482 +\end_inset
  1483 +
  1484 +
  1485 +\end_layout
  1486 +
  1487 +\begin_layout Standard
  1488 +First of all in the template we are including our SparklinesDemo snippet
  1489 + and then add a canvas element.
  1490 + This element will contain the actual chart.
  1491 + In our little snippet we have the chart data as a JsArray (that abstracts
  1492 + a JavaScript array) then the JSON object containing configuration options
  1493 + that the sparklines script will use.
  1494 + Then calling Sparklines.onLoad will render a JavaScript function that when
  1495 + DOM document is ready for processing will render the actual chart.
  1496 +\end_layout
  1497 +
  1498 +\begin_layout Section
  1499 +How to build a widget
  1500 +\end_layout
  1501 +
  1502 +\begin_layout Standard
  1503 +As explained before there is no magic formula as with Lift & Scala there
  1504 + are so many ways of building widgets.
  1505 + But here are some guidelines that we use for building widgets in Lift:
  1506 +\end_layout
  1507 +
  1508 +\begin_layout Enumerate
  1509 +Assume that you want to package the widget in a single .jar file.
  1510 + Also the widget's resources (scripts, stylesheets, images) are incorporated
  1511 + in the same jar file.
  1512 +\end_layout
  1513 +
  1514 +\begin_layout Enumerate
  1515 +Because the resources are embedded in your jar you need to help lift find
  1516 + them when the browser is requesting them.
  1517 + Here the init function that we call in the application Boot comes into
  1518 + picture.
  1519 + Here i an example of init function:
  1520 +\end_layout
  1521 +
  1522 +\begin_deeper
  1523 +\begin_layout Standard
  1524 +\begin_inset listings
  1525 +inline false
  1526 +status open
  1527 +
  1528 +\begin_layout Plain Layout
  1529 +
  1530 + import _root_.net.liftweb.http.ResourceServer
  1531 +\end_layout
  1532 +
  1533 +\begin_layout Plain Layout
  1534 +
  1535 + def init() {
  1536 +\end_layout
  1537 +
  1538 +\begin_layout Plain Layout
  1539 +
  1540 + ResourceServer.allow{
  1541 +\end_layout
  1542 +
  1543 +\begin_layout Plain Layout
  1544 +
  1545 + case "sparklines" :: _ => true
  1546 +\end_layout
  1547 +
  1548 +\begin_layout Plain Layout
  1549 +
  1550 + }
  1551 +\end_layout
  1552 +
  1553 +\begin_layout Plain Layout
  1554 +
  1555 + }
  1556 +\end_layout
  1557 +
  1558 +\end_inset
  1559 +
  1560 +
  1561 +\end_layout
  1562 +
  1563 +\end_deeper
  1564 +\begin_layout Enumerate
  1565 +This tells Lift that it is OK to load the resources from /classpath/sparklines
  1566 + folder.
  1567 + Actually
  1568 +\family typewriter
  1569 +classpath
  1570 +\family default
  1571 + is given by
  1572 +\family typewriter
  1573 +LiftRules.resourceServerPath
  1574 +\family default
  1575 + variable that of course you can change.
  1576 +\end_layout
  1577 +
  1578 +\begin_layout Enumerate
  1579 +Now you can build your own classes/object containing various functions.
  1580 + These functions usually return the actual widget markup rendered based
  1581 + on the information that user provides but it also can render <head> elements.
  1582 + Not to worry because Lift will automatically merge any <head> element found
  1583 + in HTML body into the top level head.
  1584 + This is a very handy feature.
  1585 + For instance Sparkilines.onLoad function would render:
  1586 +\end_layout
  1587 +
  1588 +\begin_deeper
  1589 +\begin_layout Standard
  1590 +\begin_inset listings
  1591 +inline false
  1592 +status open
  1593 +
  1594 +\begin_layout Plain Layout
  1595 +
  1596 + <head>
  1597 +\end_layout
  1598 +
  1599 +\begin_layout Plain Layout
  1600 +
  1601 + <script type="text/javascript" src="/classpath/sparklines/sparklines.min.js"/>
  1602 +\end_layout
  1603 +
  1604 +\begin_layout Plain Layout
  1605 +
  1606 + ...
  1607 +\end_layout
  1608 +
  1609 +\begin_layout Plain Layout
  1610 +
  1611 + </head>
  1612 +\end_layout
  1613 +
  1614 +\end_inset
  1615 +
  1616 +
  1617 +\end_layout
  1618 +
  1619 +\begin_layout Standard
  1620 +Note the path we used: /classpath/sparklines.
  1621 + It is recommended to not hardcode /classpath there instead use
  1622 +\family typewriter
  1623 +LiftRules.resourceServerPath
  1624 +\family default
  1625 +variable.
  1626 +\end_layout
  1627 +
  1628 +\end_deeper
  1629 +\begin_layout Enumerate
  1630 +After you defined your functions you can simply use them from regular snippets,
  1631 + just as we did for the widgets presented above.
  1632 +\end_layout
  1633 +
  1634 +\begin_layout Standard
  1635 +That is pretty much it as far as Lift widgets go.
  1636 + As you can see we did not really have to build a rich design (or over-design
  1637 + it) because Lift framework itself facilitates lots of things for us.
1266 1638 \end_layout
1267 1639
1268 1640 \end_body
BIN  images/rssfeed.png
BIN  images/sparklines.png
BIN  images/treeview.png

0 comments on commit 41816cf

Please sign in to comment.
Something went wrong with that request. Please try again.