forked from BorisMoore/jquery-tmpl
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added moviesNoGlobals samples to show how to access functions from te…
…mplates without creating globals. - Code is wrapped in a function closure: (function($) {...})(jQuery); - The formatDate function within the closure is called from within the template by passing it in with options: $( "#bookingEditTmpl" ).tmpl( booking, { formatDate: formatDate } ) - and accessing it on the template item, $item: ${$item.formatDate()}. See https://github.com/jquery/jquery-tmpl/issues#issue/39
- Loading branch information
1 parent
4a8ce1c
commit f9b00c8
Showing
2 changed files
with
363 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,363 @@ | ||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||
<!-- | ||
This sample illustrates using templates for a more complete and | ||
realistic scenario. | ||
It uses the NetFlix OData JSONP services as a source of data. | ||
This version of the movies sample demo uses the | ||
$( templateSelector ).tmpl( data ).appendTo( targetSelector ) | ||
pattern, and does not use the tmplCmd plugin or the rendered event. | ||
Notice that in the example there are no global variables: | ||
Code is wrapped in a function closure: (function($) {...})(jQuery); | ||
The formatDate function within the closure is called from within the | ||
template by passing it in with options: | ||
$( "#bookingEditTmpl" ).tmpl( booking, { formatDate: formatDate } ) | ||
and accessing it on the template item, $item: | ||
${$item.formatDate()}. | ||
--> | ||
<html xmlns="http://www.w3.org/1999/xhtml"> | ||
<head> | ||
<title>jQuery + OData + Netflix Catalog API</title> | ||
<link href="../css/jquery-ui-1.8.1.custom.css" rel="stylesheet" type="text/css" /> | ||
<link href="../css/movies.css" rel="stylesheet" type="text/css" /> | ||
</head> | ||
<body> | ||
<div id="pageBody"> | ||
<h1>Netflix: Book a Movie...</h1> | ||
|
||
<ul id="genres"> | ||
<li class="selected">Cartoons</li> | ||
<li>Drama</li> | ||
<li>Foreign</li> | ||
<li>Action Classics</li> | ||
<li>Horror</li> | ||
<li>Sci-Fi Cult Classics</li> | ||
</ul> | ||
|
||
<div id="pager"><ul class="pages"><li class="pgEmpty">first</li><li class="pgEmpty">prev</li></ul></div> | ||
|
||
<div id="movieList"></div> | ||
<table id="bookingsList"> | ||
<tbody><tr class="cart"><td class="cart-false" colspan="4"> | ||
<span class="text">0 items in Cart...</span> | ||
</td></tr></tbody> | ||
</table> | ||
<br/> | ||
</div> | ||
<script src="http://code.jquery.com/jquery.js"></script> | ||
<script src="../../../jquery.tmpl.js" type="text/javascript"></script> | ||
<script src="../components/jquery.pager.js" type="text/javascript"></script> | ||
<script src="../components/jquery-ui-1.8.1.custom.js" type="text/javascript"></script> | ||
|
||
<script id="movieTmpl" type="text/x-jquery-tmpl"> | ||
<div> | ||
<div><img src="${BoxArt.LargeUrl}" /> </div> | ||
<strong>${Name}</strong> | ||
<p>{{html Synopsis}}</p> | ||
<input type="button" title="Buy tickets for '${Name}'" value="Add to cart..." class="buyButton"/> | ||
<br/> | ||
</div> | ||
</script> | ||
|
||
<script id="cartTmpl" type="text/x-jquery-tmpl"> | ||
<td class="cart-${!!count}" colspan="4"> | ||
<span class="text">${count} items in Cart...</span> | ||
{{if count}} | ||
<span id="submit">Checkout</span> | ||
<span id="cancel">Remove All</span> | ||
{{if count>1}} | ||
<span id="sort"><span id="sortBtn">Sort</span>: | ||
<select> | ||
<option value="0" {{if sortBy==="0"}}selected{{/if}}>Name A-Z</option> | ||
<option value="1" {{if sortBy==="1"}}selected{{/if}}>Name Z-A</option> | ||
<option value="2" {{if sortBy==="2"}}selected{{/if}}>Date</option> | ||
</select> | ||
</span> | ||
{{/if}} | ||
</select> | ||
{{/if}} | ||
</td> | ||
</script> | ||
|
||
<script id="bookingTitleTmpl" type="text/x-jquery-tmpl"> | ||
<tr class="bookingTitle${$item.mode}"> | ||
<td>${movie.Name}</td><td>${movieTheater}</td> | ||
<td>${$item.formatDate()}</td> | ||
<td> | ||
${quantity} | ||
<span class="ui-icon close"></span> | ||
</td> | ||
</tr> | ||
</script> | ||
|
||
<script id="bookingEditTmpl" type="text/x-jquery-tmpl"> | ||
{{tmpl($data, { mode: "Edit", formatDate: $item.formatDate }) "#bookingTitleTmpl"}} | ||
<tr class="bookingEdit"> | ||
<td colspan="4"> | ||
<div class="fields"> | ||
<span>Movie Theater: </span><input class="theater" type="text" value="${movieTheater}" /><br/> | ||
<span>Date: </span><input class="date" type="text" value="${$item.formatDate()}" /><br/> | ||
<span>Quantity: </span><input class="quantity" type="text" value="${quantity}" /> | ||
</div> | ||
<div><img src="${movie.BoxArt.LargeUrl}" /></div> | ||
</td> | ||
</tr> | ||
</script> | ||
|
||
<script type="text/javascript"> | ||
(function($) { | ||
var genre="Cartoons", pageIndex = 1, pageSize = 3, pageCount = 0, | ||
cart = { bookings: {}, count: 0, sortBy:0 }, bookingTmplItems = {}, selectedBooking; | ||
|
||
getMovies( pageIndex ); | ||
|
||
$( "#genres li" ).click( selectGenre ); | ||
|
||
$( ".cart" ) | ||
.delegate( "select", "change", sort ) | ||
.delegate( "#sortBtn", "click", sort ) | ||
.delegate( "#submit", "click", function() { | ||
alert( cart.count + " bookings submitted for payment..."); | ||
removeBookings(); | ||
}) | ||
.delegate( "#cancel", "click", function() { | ||
removeBookings(); | ||
}) | ||
.empty(); | ||
|
||
$( "#cartTmpl" ) | ||
.tmpl( cart ) | ||
.appendTo( ".cart", cart ); | ||
|
||
var cartTmplItem = $( ".cart td" ).tmplItem(); | ||
|
||
function selectGenre() { | ||
$( "#genres li" ).removeClass( "selected" ); | ||
$( this ).addClass( "selected" ); | ||
|
||
pageIndex = 1; | ||
genre = encodeURI( $(this).text() ); | ||
getMovies( pageIndex ); | ||
} | ||
|
||
function sort() { | ||
var compare = compareName, reverse = false, data = []; | ||
cart.sortBy = $( "#sort select" ).val(); | ||
switch ( $( "#sort select" ).val() ) { | ||
case "1": | ||
reverse = true; | ||
break; | ||
case "2": | ||
compare = compareDate; | ||
break; | ||
} | ||
|
||
for ( var item in cart.bookings ) { | ||
data.push( cart.bookings[item] ); | ||
} | ||
data = data.sort( compare ); | ||
|
||
for ( var i = 0, l = data.length; i < l; i++ ) { | ||
$( bookingTmplItems[data[i].movie.Id].nodes ).appendTo( "#bookingsList" ); | ||
} | ||
|
||
function compareName( a, b ) { | ||
return a == b ? 0 : (((a.movie.Name > b.movie.Name) !== reverse) ? 1 : -1); | ||
} | ||
function compareDate( a, b ) { | ||
return a.date - b.date; | ||
} | ||
} | ||
|
||
function getMovies( index ) { | ||
var query = "http://odata.netflix.com/Catalog/Genres('" + genre + "')/Titles" + | ||
"?$format=json" + | ||
"&$inlinecount=allpages" + // get total number of records | ||
"&$skip=" + (index-1) * pageSize + // skip to first record of page | ||
"&$top=" + pageSize; // page size | ||
|
||
pageIndex = index; | ||
|
||
$( "#movieList" ) | ||
.fadeOut( "medium", function () { | ||
$.ajax({ | ||
dataType: "jsonp", | ||
url: query, | ||
jsonp: "$callback", | ||
success: showMovies | ||
}); | ||
}); | ||
} | ||
|
||
function showMovies( data ) { | ||
pageCount = Math.ceil( data.d.__count/pageSize ), | ||
movies = data.d.results; | ||
|
||
$( "#pager" ).pager({ pagenumber: pageIndex, pagecount: pageCount, buttonClickCallback: getMovies }); | ||
|
||
$( "#movieList" ).empty(); | ||
|
||
$( "#movieTmpl" ) | ||
// Render movies using the movieTemplate | ||
.tmpl( movies ) | ||
|
||
// Display rendered movies in the movieList container | ||
.appendTo( "#movieList" ) | ||
|
||
// Animate | ||
.find( "div" ).fadeIn( 4000 ).end() | ||
|
||
// Add click handler | ||
.find( ".buyButton" ).click( function() { | ||
buyTickets( $(this).tmplItem().data ); | ||
}); | ||
|
||
$( "#movieList" ).fadeIn( "medium" ) | ||
} | ||
|
||
function buyTickets( movie ) { | ||
// Add item to cart | ||
var booking = cart.bookings[movie.Id]; | ||
if ( booking ) { | ||
booking.quantity++; | ||
} else { | ||
cart.count++; | ||
cartTmplItem.update(); | ||
booking = { movie: movie, date: new Date(), quantity: 1, movieTheater: "" }; | ||
} | ||
selectBooking( booking ); | ||
} | ||
|
||
function selectBooking( booking ) { | ||
if ( selectedBooking ) { | ||
if ( selectedBooking === booking ) { | ||
updateBooking( bookingTmplItems[selectedBooking.movie.Id]); | ||
return; | ||
} | ||
// Collapse previously selected booking, and switch to non-edit view | ||
var oldSelected = selectedBooking; | ||
$( "div", bookingTmplItems[oldSelected.movie.Id].nodes ).animate( { height: 0 }, 500, function() { | ||
switchView( oldSelected ); | ||
}); | ||
} | ||
selectedBooking = booking; | ||
if ( !booking ) { | ||
return; | ||
} | ||
if ( cart.bookings[booking.movie.Id] ) { | ||
switchView( booking, true ); | ||
} else { | ||
cart.bookings[booking.movie.Id] = booking; | ||
|
||
var bookingNode = $( "#bookingEditTmpl" ) | ||
|
||
// Render the booking for the chosen movie using the bookingEditTemplate | ||
.tmpl( booking, { animate: true, formatDate: formatDate } ) | ||
|
||
// Append the rendered booking to the bookings list | ||
.appendTo( "#bookingsList" ) | ||
|
||
// Get the 2nd <tr> of the appended booking | ||
.last()[0]; | ||
|
||
// Get the template item for the 2nd <tr>, which is the template item for the "bookingEditTmpl" template | ||
var newItem = $.tmplItem( bookingNode ); | ||
bookingTmplItems[booking.movie.Id] = newItem; | ||
|
||
// Attach handlers etc. on the rendered template. | ||
bookingEditRendered( newItem ); | ||
} | ||
} | ||
|
||
function bookingEditRendered( item ) { | ||
var data = item.data, nodes = item.nodes; | ||
|
||
$( nodes[0] ).click( function() { | ||
selectBooking(); | ||
}); | ||
|
||
$( ".close", nodes ).click( removeBooking ); | ||
|
||
$( ".date", nodes ).change( function() { | ||
data.date = $(this).datepicker( "getDate" ); | ||
updateBooking( item ); | ||
}) | ||
.datepicker({ dateFormat: "DD, d MM, yy" }); | ||
|
||
$( ".quantity", nodes ).change( function() { | ||
data.quantity = $(this).val(); | ||
updateBooking( item ); | ||
}); | ||
|
||
$( ".theater", nodes ).change( function() { | ||
data.movieTheater = $(this).val(); | ||
updateBooking( item ); | ||
}); | ||
|
||
if ( item.animate ) { | ||
$( "div", nodes ).css( "height", 0 ).animate( { height: 116 }, 500 ); | ||
} | ||
} | ||
|
||
function bookingRendered( item ) { | ||
$( item.nodes ).click( function() { | ||
selectBooking( item.data ); | ||
}); | ||
$( ".close", item.nodes ).click( removeBooking ); | ||
} | ||
|
||
function switchView( booking, edit ) { | ||
if ( !booking ) { | ||
return; | ||
} | ||
var item = bookingTmplItems[booking.movie.Id], | ||
tmpl = $( edit ? "#bookingEditTmpl" : "#bookingTitleTmpl" ).template(); | ||
if ( item.tmpl !== tmpl) { | ||
item.tmpl = tmpl; | ||
item.update(); | ||
(edit ? bookingEditRendered : bookingRendered)( item ); | ||
} | ||
} | ||
|
||
function updateBooking( item ) { | ||
item.animate = false; | ||
item.update(); | ||
(item.data === selectedBooking ? bookingEditRendered : bookingRendered)( item ); | ||
item.animate = true; | ||
} | ||
|
||
function removeBooking() { | ||
var booking = $.tmplItem(this).data; | ||
if ( booking === selectedBooking ) { | ||
selectedBooking = null; | ||
} | ||
delete cart.bookings[booking.movie.Id]; | ||
cart.count--; | ||
cartTmplItem.update(); | ||
$( bookingTmplItems[booking.movie.Id].nodes ).remove(); | ||
delete bookingTmplItems[booking.movie.Id]; | ||
return false; | ||
} | ||
|
||
function removeBookings() { | ||
for ( var item in bookingTmplItems ) { | ||
$( bookingTmplItems[item].nodes ).remove(); | ||
delete bookingTmplItems[item]; | ||
} | ||
bookingTmplItems = {}; | ||
cart.count = 0; | ||
cart.bookings = {}; | ||
selectedBooking = null; | ||
cartTmplItem.update(); | ||
} | ||
|
||
function formatDate() { | ||
return this.data.date.toLocaleDateString(); | ||
} | ||
})(jQuery); | ||
</script> | ||
|
||
</body> | ||
</html> |