Official jQuery plugins: Templates plugin. Learning to work with jQuery templates Layout of digital data in jquery
On October 4, 2010, the announcement of three jQuery plugins, created with the support of the Microsoft team, was published. These plugins—the jQuery Templates plugin, the jQuery Data Link plugin, and the jQuery Globalization plugin—are designated as “Officially Supported Plugins of the jQuery Project.”
The template plugin is used when it is necessary to display a data object or an array of objects in the page markup. The data binding plugin is needed to link objects with page elements and change values synchronously. The globalization plugin allows you to display data such as numbers, date and time, amount of money, etc., on a page in accordance with the format of the current language.
It should be noted that the Microsoft team used its considerable experience in these areas, as did the jQuery project team, and with well-established interaction, in my opinion, they turned out to be excellent tools for developers. To support my opinion, I can add that the jQuery developers have announced the inclusion of template plugins and data binding in the core jQuery libraries already version 1.5, and the globalization plugin - into the corresponding version of jQuery UI. The plugins have not yet received release status, but documentation is already being actively written on the site. By the way, the Microsoft team followed the traditions of jQuery development and posted materials on plugin development on github.com, where descriptions and source codes of the plugins are available.
In this article I will talk a little about the template plugin.
Let's start with a simple example:
So, in the example, the page developer described a template for displaying objects in the form of markup (the first element script), then I got an array of objects from somewhere movies and called the instruction to generate the required markup according to the template, taking data from the provided array of objects, and adding the result to the end of the list #movieList
.
As a result of the plugin running, we will get the following markup:
- The Red Violin (1998)
- Eyes Wide Shut (1999)
- The Inheritance (1976)
And now to the essence of the question.
What does the plugin do?
The plugin receives as input a template string and a set of objects (or one object) that need to be output to a string (or markup) with formatting.
Where is this applied?
This plugin is mainly useful for dynamically displaying JS objects on the page, the objects can be obtained in the most in different ways, for example, during calculations or based on the results of some user actions and, of course, the most frequently cited example, in the form of JSON in the server response to an AJAX request.
.tmpl([ data ], [ options ])
Gets the contents of the first selected element and uses it as a template for formatted output of the specified data.
data– data to be output to a template (object or array of objects).
options– optional, user-defined extension in the form of key-value pairs for the output object in the template.
jQuery.tmpl(template, [ data ], [ options ])
Uses the specified template to produce formatted output of the specified data.
template– a template for formatting data, can be one of the following types: a string with markup, an HTML element (including in a jQuery wrapper), a string corresponding to the name of a previously compiled template.
data, options– have the same meaning as above
.tmplItem()
Returns a structure (object) for the first selected element with the results of the template engine. The object returned by the method provides access to:
- HTML parts that make up the template
- associated transmitted data unit
- to the parent template if the current template is nested
- the current template used for output
- user-defined extension (fields and methods) passed to the options parameter of the tmpl() method
This method is used, for example, when, after formatting the data, you need to find out what data was used to form a certain piece of markup, or to update a piece of markup using new data.
jQuery.tmplItem(element)
Similar to the .tmplItem method, only the structure with the results of the template engine is searched for the element element(HTML element, including in jQuery wrapper).
.template([ name ])
The method makes a compiled version of the formatting template from the contents of the first selected element.
name– optional template name, if the name is specified, then you can use it to access this template in a method jQuery.tmpl(name, data, options)
jQuery.template([ name, ] template)
The method is similar to that described above, only here the template is passed as a parameter template– this can be a string, a string with markup, an HTML element (including in a jQuery wrapper).
I will briefly describe several of the most basic elements of the template; I hope to describe the rest in more detail in the next article (if there is a positive response to this article)
$(fieldNameOrExpression) and ((= fieldNameOrExpression))
Allows you to insert the value of a field (property) of a data object into the template; it can also be used to insert the result of a method or js expression. For example, "$(Name)"– will insert the value of the obj.Name field into the template, and given that Languages is a field of the object to which the array is assigned, "$(Languages.length)"– will insert the length of this array into the template, and finally, if the object has a getLanguages method with two parameters, then “$(getLanguages(Languages, ‘ – ‘))”– will insert the result of this method into the template.
((html fieldNameOrExpression))
The template element $(field) (or ((= field))) inserts the value of the specified field as text into the result, i.e. If there are HTML tags in the string, they will be encoded rather than converted to markup. If you need to insert data into the template in the form of HTML markup, then you need to use the syntax ((html))
.
To get started with the plugin, I’ve already said enough about it, I can only add that the template syntax allows you to insert nested templates, conditional instructions, access some JS and jQuery objects and something else... The rest is material for a future article.
The article was written based on materials found on the World Wide Web. This is mainly a translation of official documentation. The originals can be viewed at the following links:
- (examples taken from there)
My name is Andrey Zaitsev, profile on the zandroid forum
This is my first article on this blog, I hope, and not the last. Many thanks to Gennady for the opportunity to publish and for useful tips on writing and designing material.
ExamplesExample 1: Dynamically switching the applied template
table ( cursor:pointer; border-collapse:collapse; border:2px solid blue; width:300px; margin:8px; ) table tr ( border:1px solid blue; color:blue; background-color:#f8f8f8; ) table td ( padding:3px; ) table tr:hover ( color:red; ) .movieDetail ( background-color:yellow; ) .movieDetail.row1 ( border-bottom:none; ) .movieDetail.row2 ( border-top:none; )
Quite complex and voluminous, it uses several plugin methods at once, taken from.
Example 2: Inserting data with markup into a template
.role (font-weight:bold;font-style: italic;) #movieContainer (padding-left: 8px;) $(Name)
((html Synopsis))
/* The Synopsis data field contains HTML markup. */ var movie = ( Name: "Meet Joe Black", Synopsis: "The grim reaper (Brad Pitt) visits Bill Parrish (Anthony Hopkins)..." ); /* Render the template with the movie data. The template uses the ((html)) template tag to insert the Synopsis HTML markup data. */ $("#movieTemplate").tmpl(movie) .appendTo("#movieContainer");In this example, both simple string field values and values with markup are added to the template, taken from here.
P.S.I didn’t describe the examples, but if the audience supports my initiatives, then I can describe step by step what, how and why, and give a few more examples.
Please ask questions about the plugin on the forum, if there are comments specifically on the article, then comment below.
With the release of jQuery, life has become much easier for developers. For example, we can easily do the following:
$("#someElement").children().each(function() ( $(this).wrap($("")); ));
This code will put all descendants of the element with id #someElement into the tag. There is nothing wrong with such operations; This expression is absolutely correct and is very convenient in some situations. But the HTML code placed in our script is a violation of the structural logic of the code. In this simple example This violation is not significant, but it is very common in real projects. Typically, such code contains many HTML fragments that are built into the DOM after receiving data from AJAX requests. This style can quickly turn into something that is extremely unreadable.
Using templates will allow us to eliminate this drawback by separating HTML fragments from scripts, thus separating the content logic different types code. Along the way, I can't help but show you some super cool AJAX new features introduced by jQuery 1.5.
StartIn this example, we will be developing a Twitter widget that will load not only our most recent posts, but also a list of friends and followers. I chose Twitter for this example because it interacts with JSON data that is easy and fun to work with.
Let's get started; the widget itself will be built based on the following HTML structure:
jQuery, AJAX and Templating Dan Wellman
Husband, father, front-end developer and author. Writes for Nettuts and Packt Publishing. Works for @designhaus | jQuery fanatic
- Tweets
- Friends
- Followers
In this example we are using HTML5. To do this, we specified a simplified DOCTYPE and a meta element. You may also notice in the code a connection to style sheets, which will be described in a couple of minutes. For support purposes current version IE8 and below, we use conditional comments on the special html5shiv plugin.
Using asideMost likely, this widget will look like a sidebar and display the content of the specified Twitter user. With this in mind, I decided to put the content in a . In order to easily access this element, we will set an ID for it.
Speaking of markings. All of the Twitter user's post titles will be included in the tag, and the image and everything else will be included in the tag.
You can change this to your own preference when you remodel this example. We could get all the required data via JSON, which we will do, however, if there is a delay in the loading process, the visitor will be shown a lot of empty blocks. So it’s better for us to wait until the download is complete and then fill the blocks.
We will also have tabs on our page for switching between lists of messages, friends and subscribers. All of them will be enclosed in tags
- ,
- And . The post list tab will be displayed by default, so we need to provide a custom CSS class for the active tab. In a larger project, it would be preferable to use jQuery to switch interface tabs, but I didn't want to focus on this because... The topic of the lesson is different.
Finally, we have everything we need to place all the incoming data: an external container with an ID, three tabs for messages, friends and followers, who also have their own IDs for easy sampling. We have also added an element for those visitors who do not use JavaScript when viewing web pages. Note that we will be using the tmpl plugin, which will give us the ability to use jQuery templates. This plugin can be downloaded.
A little earlier I mentioned special style sheets. Open a new file in your favorite text editor and add the following code:
#tweetbox ( display:block; width:300px; padding:10px; border:1px solid #aaa; -moz-border-radius:5px; border-radius:5px; font-family:"Trebuchet MS", Arial, Helvetica, sans-serif; background-color:#eee; ) #tweetbox img ( display:block; ) #user ( margin-bottom:10px; float:left; ) #user h2 ( margin:0 0 10px 0; position:relative; font-size:18px; ) #user img ( float:left; ) #user p ( width:230px; margin:0; position:relative; float:left; font-size:10px; color:#333; ) #user img ( display:block; margin-right:10px; border:3px solid #333; ) #tools ( margin:0; *margin-bottom:-10px; padding:0; clear:both; list-style-type:none ; ) #tools li ( float:left; ) #tools a ( display:block; height:20px; padding:3px 24px; border:1px solid #aaa; border-bottom:none; -moz-border-radius:5px 5px 0 0; border-radius:5px 0 0; position:relative:14px; background-color:#d6d6d6; , left top, left bottom, color-stop(0.5, #E8E8E8), color-stop(0, #DBDBDB), color-stop(0.5, #D6D6D6)); background-image: -moz-linear-gradient(center top, #E8E8E8 50%, #DBDBDB 0%, #D6D6D6 50%); ) a ( text-decoration:none; color:#333; ) #tools .on ( height:21px; margin-top:-1px; top:1px; ) #feed ( width:298px; border:1px solid #aaa; clear:both; background-color:#d6d6d6; ) #feed > div ( display:none; ) noscript ( display:block; padding:10px; font-size:13px; color:#333; )
Save this file as tweetbox.css in the same directory as your HTML pages. This is just a small amount that we can specify for the design of our widget. In the code we just provided, you may notice a few CSS3 tricks: rounded corners (note that we no longer need -WebKit- for these purposes!), as well as some gradients for the tabs. It should be noted that we hide all blocks, except for one - the active one. At this point the widget should look like this:
Adding a scriptNow let's write a small script to implement tab switching. Create a new file and add the following code:
(function($) ( //tabs var tweetbox = $("#tweetbox"), tweetData = null, friendData = null, followData = null; tweetbox.find("#tools a").click(function(e) ( e.preventDefault(); var link = $(this), target = link.attr("href").split("#"); tweetbox.find(".on").removeClass("on"); .addClass("on"); tweetbox.find("#feed > div").hide(); tweetbox.find("#" + target).show());
Save this file (tweetbox.js) in the same directory as everything else. There is nothing complicated here. Tabs aren't the point of this tutorial, so I won't dwell on it too long. The script works as follows: we use an anonymous function that catches the container that is active. We will also initialize three variables that we will use later. We set their value to null.
The selection of elements will be carried out repeatedly, so it will not be superfluous to cache the whole thing, which will help minimize the number of jQuery requests. Next, we install a click handler on tabs that are not active, and set the appropriate classes to display styles. In other words, we make the active tab inactive, and one of the inactive tabs is active. Before displaying the contents of the selected tab, we hide them all and only then display the information.
Getting dataNow the fun begins. We will make a request to Twitter in order to get data for all 3 tabs, and we will also use a plugin in order to be able to use jQuery templates. Add this code after the previous one:
$.ajaxSetup(( dataType: "jsonp" )); function getTweets() ( $.ajax("http://api.twitter.com/statuses/user_timeline/danwellman.json", ( success: function(data) ( var arr = ; for (var x = 0; x< 5; x++) { var dataItem = {}; dataItem["tweetlink"] = data[x].id_str; dataItem["timestamp"] = convertDate(data, x); dataItem["text"] = breakTweet(data, x); arr.push(dataItem); } tweetData = arr; } }); } function getFriends() { return $.ajax("http://api.twitter.com/1/statuses/friends/danwellman.json", { dataType: "jsonp", success: function(data) { var arr = ; for (var x = 0; x < 5; x++) { var dataItem = {}; dataItem["screenname"] = data[x].screen_name; dataItem["img"] = data[x].profile_image_url; dataItem["name"] = data[x].name; dataItem["desc"] = data[x].description; arr.push(dataItem); } friendData = arr; } }); } function getFollows() { return $.ajax("http://api.twitter.com/1/statuses/followers/danwellman.json", { dataType: "jsonp", success: function(data) { var arr = ; for (var x = 0; x < 5; x++) { var dataItem = {}; dataItem["screenname"] = data[x].screen_name; dataItem["img"] = data[x].profile_image_url; dataItem["name"] = data[x].name; dataItem["desc"] = data[x].description; arr.push(dataItem); } followData = arr; } }); } $.when(getTweets(), getFriends(), getFollows()).then(function(){ // используем шаблоны });
First we use the ajaxSetup() method to specify the data format we will be dealing with - jsonp. Since we will be running multiple queries, it is better to specify this value once.
Next, we write 3 standard methods in terms of functionality, in which we use separate ajax() methods. It will make a request to the Twitter service and return data. For the request we will use special keywords: user_timeline, friends and followers. To be sure that the data will be generated after a successful request, we will include our code in the success block. Each of these functions will return 100 well-packed Twitter data objects.
For the croque, we don’t need that much data, so we’ll put only 5 objects in the array. To make sure that we are generating JSON data in the correct format, we place the keys of each element in double quotes.
These functions are almost identical to each other. Please note that for each request, we use our own unique keywords. At the end of each function, we assign the accumulated arrays to the elements that contained null values (formed above).
Notice that we're not just calling our three methods - we're using a when() method that will run its contents only when the three methods have finished running. After all three functions return success, we will run the then() method, where the template functionality will be located.
By the way. In this context, you can also specify the fail() method, which will run if requests to Twitter fail.
This is all very cool, since earlier versions of jQuery did not provide such functionality.
Auxiliary functionsIn the previous example we use some helper functions convertDate() and breakTweet(). Here are their contents:
//date format convertDate = function(obj, i) ( if (window.ActiveXObject) ( obj[i].created_at = obj[i].created_at.replace(/[+]\d(4)/, "") ; ) var days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], date = new Date(obj[i].created_at), formattedTimeStampArray = .created_at], date.toLocaleDateString(), date.toLocaleTimeString()]; return formattedTimeStampArray.join(" "); breakTweet = function(obj, i) ( var text = obj[i].text, brokenTweet = , atExpr = /(@[\w]+)/; if (text.match(atExpr)) ( var splitTweet = text.split(atExpr); for (var x = 0, y = splitTweet.length; x< y; x++) { var tmpObj = {}; if (splitTweet[x].indexOf("@") != -1) { tmpObj["Name"] = splitTweet[x]; } else { tmpObj["Text"] = splitTweet[x]; } brokenTweet.push(tmpObj); } } else { var tmpObj = {}; tmpObj["Text"] = text; brokenTweet.push(tmpObj); } return brokenTweet; }
convertDate() function: First of all, we check whether the browser is using window.ActiveXObject. If so, we use the JavaScript replace() method to remove the Timezone that is contained in the JSON object returned from Twitter. This method uses regular expressions to find and replace a string.
Next we create some variables; an array that contains abbreviated names of months. Days in JavaScript dates start at 0. We then create a Date object using the new Date( constructor, and pass the date, which is stored in the created_at property of the object passed to the function.
Let's create another array of 3 elements: the first is the day of the week, the second is the localized date, the third is the localized time. After the array is formed, we return it.
The breakTweet() function is a little more complicated. Here we need to convert plain text into a JSON array, in which each element is an object containing the Name or Text properties. These will be used in the template. First, we get the text from the object that Twitter returned to us (we passed it to the function). We also use a regular expression here that catches the presence of @usernames.
Next, we scan the text to find the username; if it is present, take it out. We get an array of text values. We go through this array, looking for a test containing the @ symbol; If this symbol is present, then write it with the Name key. The rest of the text is written with the Text key. The generated objects are placed in an array.
That's it. We've just created an object that we can pass to the jQuery template.
Working with a templateNow that all the necessary data has been generated, we can proceed to the last part of our lesson: templates. Let's return to the contents of the then() method block. Paste the code inside this block:
//apply templates tweetbox.find("#tweetTemplate").tmpl(tweetData).appendTo("#tweetList"); tweetbox.find("#ffTemplate").tmpl(friendData).appendTo("#friendList"); tweetbox.find("#ffTemplate").tmpl(followData).appendTo("#followList"); //show messages tweetbox.find("#tweets").show();
Here I demonstrate the use of the tmpl() plugin. In this fragment, we pass the generated data to the template, indicating which element will receive it. The tmpl() method is called for each element that we have not yet created. So let's add them.
Adding jQuery templatesLet's go back to HTML again. The first thing we will do is add a tag immediately after the empty ul with the id “tweetList”:
((each text)) ((if Name)) ((tmpl(Name) "#atTemplate")) ((else)) $(Text) ((/if)) ((/each)) $(timestamp)
$($item.data)jQuery templates are added to an HTML page directly through the . Each such element must have an id element so that they can be recognized and processed by the tmpl() method. The type attribute must also store the following value - text/x-jquery-tmpl.
In the first template, we add a structure that we later want to display in the DOM. In particular, each Twitter message will be enclosed in tags,
AND . To insert data from a JSON object passed through the tmpl() method, we use a series of template tags. We then use ((each)) to iterate through each element that is stored in the array.
This array contains all Twitter messages. For each of them we check for the presence of the Name key. If the key is present, use the ((tmpl)) tag. We indicate the name of the function through which the data will pass in parentheses after tmpl, and also indicate the id of the template that we will use (we will look at it in more detail in a few minutes). If the object does not contain the Name key, then we are dealing with plain text, which we will insert using $(text). This conditional is achieved using the ((if)) and ((else)) tags. After this we have to close the condition using ((/if) and similarly end the loop ((/foreach)).
Now we need to create a link that will lead directly to Twitter. To do this, we use $(tweetlink) as part of the href attribute, and the $(timestamp) property. This is the data we created and successfully processed using the user_timeline request.
In the same way, we need to create tabs to display our friends and followers. We will create them according to exactly the same principle. There is one base for everyone:
-
$(screenname)$(desc)
So we learned how to transfer data to a template using json and output it using the $(data);
Finishing touchNow that everything is almost ready, we can add a few more CSS styles so that it all looks more or less decent. Add the following code to the end of the tweetbox.css file:
#feed ul ( padding:0; margin:0; ) #feed li ( padding:0; border-bottom:1px solid #aaa; list-style-type:none; font-size:11px; ) #feed li:last -child, #feed li:last-child p ( border-bottom:none; ) #feed p ( padding:10px; margin:0; border-bottom:1px solid #eee; background-image:-webkit-gradient(linear , left bottom, left top, color-stop(0.48, #c2c2c2), color-stop(0.71, #d6d6d6)); background-image:-moz-linear-gradient(center bottom, #c2c2c2 48%, #d6d6d6 71 %); ) #feed p:after ( content:""; display:block; width:100%; height:0; clear:both; ) .tweet-link ( display:block; margin-top:5px; color: #777; ) .img-link ( display:block; margin:4px 10px 0 0; float:left; ) #feed .username a ( font-size:14px; font-weight:bold; ) #feed .bio ( display :block;margin-top:10px;
After saving the file, our application will look like this:
There's one more thing we should probably implement: at the moment, our formatting does not work in IE, because IE is not friendly with the split() method. To fix this problem, we can use the excellent JavaScript patch created by Steven Levithan. It can be downloaded from: http://blog.stevenlevithan.com/archives/cross-browser-split. Let's connect this code using a conditional comment:
This code must be added immediately before including the tweetbox.js file.
ConclusionIn this tutorial we looked at some of the more advanced templating features in jQuery. We were introduced to the iterative loop ((each)) and the conditions ((if)) and ((else)).
The key point is that new system templates in jQuery allows us to split up our code by moving all the HTML fragments out of the JS files and back into the HTML file.
Some might argue that we are now simply increasing the number of tags on our page.
However, I think this alternative is preferable. Elements in the $("") format are simply strings (until the browser starts and they are created and inserted into the DOM, of course).
We also looked at the new when() method added in JQuery 1.5, which allows you to manage multiple asynchronous requests. Next we used the then() method. This function will launch its content only after all asynchronous processes have completed.
I hope the article was useful to you. Thank you for your attention.
The best way to start learning about data patterns is to start working with them right away. The basic capabilities of the templates are shown. I've included the full HTML document in this listing because of the way we set up templates using the script element, but I'll show you the relevant elements in later examples.
Listing 12-3: First example of a data template Example $(document).ready(function () ( var data = [ ( name: "Astor", product: "astor", stocklevel: "10", price: 2.99 ), ( name: "Daffodil", product: "daffodil", stocklevel: "12", price: 1.99 ), ( name: "Rose", product: "rose", stocklevel: "2", price: 4.99 ), ( name: "Peony", product: "peony", stocklevel: "0", price: 1.50 ), ( name: "Primula", product: "primula", stocklevel: "1", price: 3.12 ), ( name: "Snowdrop ", product: "snowdrop", stocklevel: "15", price: 0.99 ), ]; )); $(name): Jacqui's Flower Shop Place OrderIn the following sections, I will break down the example and explain each part. If the data is part of a document, it is known as embedded data. An alternative is deleted data, this is when you receive data from the server separately from the document. We'll touch on remote data later in this chapter, but it touches on jQuery's support for Ajax, which is the topic of Chapters 14 and 15.
Data DefinitionThe starting point of the example is the data, which in this case is an array of objects, each of which describes a separate unit of flower production. B shows the corresponding expressions from the document.
Listing 12-4: Defining color data var data = [ ( name: "Astor", product: "astor", stocklevel: "10", price: 2.99 ), ( name: "Daffodil", product: "daffodil", stocklevel: "12", price: 1.99 ), ( name: "Rose", product: "rose", stocklevel: "2", price: 4.99 ), ( name: "Peony", product: "peony", stocklevel: "0", price: 1.50 ), ( name: "Primula", product: "primula", stocklevel: "1", price: 3.12 ), ( name: "Snowdrop", product: "snowdrop", stocklevel: "15 ", price: 0.99 ), ];You express your data as one or more JavaScript objects. The jQuery template library is very flexible when it comes to the kind of objects that can be used as data, but the format shown in the template is used most often because it follows the JSON data format, which I'll cover in Chapter 14.
Advice
JSON is important because it is often used with Ajax, which I'll cover in Chapters 14 and 15.
In this example, the array contains six objects, each with a set of properties that describe the flower shop's products: display name, product name, inventory size (quantity available), and price.
Template DefinitionAs you can imagine, at the heart of the data template library is the data template. This is a set HTML elements, containing placeholders that correspond to aspects of the data objects. B shows the template for this example.
Listing 12-5: Defining a data template $(product).png" /> $(name) :The first thing to notice about the template is that it is contained inside a script element with a type attribute value of text/x-jquery-tmpl . We do this to prevent the browser from interpreting the template content as regular HTML. This is not entirely necessary, but it is a good practice and will help avoid many potential problems.
The second point to note is that when you define a template in a script element, you will assign a name to the template using the id attribute. In our case, the template is called flowerTmpl. You need to know the template name when you apply it to your data.
The contents of the template will be applied to the objects in the data array to create a set of HTML elements for each object individually. You can see that the structure of the template matches the set of elements that I used for floral products in previous chapters. The key difference, of course, lies in the pieces of code that I have highlighted in the listing. This is it data placeholders.
When the template library processes a template, it replaces any data placeholders with the property values of the object it is working on. So, for example, the template library will associate the first object in the array with the label $(product) and replace it with the value of the product unit property, that is, in this case, astor . This is the part of the template:
$(product).png"/>
transformed into this:
astor .png"/>
Inserting data values is just one of the things you can do with a template. I'll explain other possibilities later in this chapter.
Applying a templateWe flatten the template using the tmpl method. This allows us to specify the data we want to use and the template that should be applied to it. The use of this method is shown.
Listing 12-6: $("#flowerTmpl").tmpl(data).appendTo("#row1");I use the jQuery $function to select the element that contains the template, and then call the tmpl method on the result, passing as an argument the data you want to process.
The tmpl method returns a standard jQuery object that contains the elements obtained from the template. In our case, I wrap this up with a set of div elements, each containing an img , label , and input element that have been processed for one of the objects in my data array. I'm using the appendTo method to insert the full set of children for row1 . The result can be seen at.
Figure 12-2: Using a Data Template Customizing the ResultWe didn't get the full result we expected because all the products are located on the same line. But since we're working with a jQuery object, we can do whatever we did before with the elements. It shows how this can be done using the result of the tmpl method.
Listing 12-7: Processing the results obtained from the template $("#flowerTmpl").tmpl(data) .slice(0, 3).appendTo("#row1").end().end().slice(3 ).appendTo("#row2"); )); $(name):In this example, I use the slice and end methods to narrow and expand the selection, and the appendTo method to add subsets of the elements generated from the template to different rows.
Note that I had to call the end method twice in a row to work through the narrowing of the selection caused by the slice and appendTo methods. It's very functional, and I generally like to use the end method to create commands in one statement, but I don't really like the end().end() sequence. Instead, I usually separate such sequences into separate commands, as shown in .
Listing 12-8: Separating elements using multiple expressions var templResult = $("#flowerTmpl").tmpl(data); templResult.slice(0, 3).appendTo("#row1"); templResult.slice(3).appendTo("#row2");In any case, you get the same result, that is, the produce is divided into two rows, each containing three flowers, as shown in.
Figure 12-3: Adjusting the results to suit the layout
Data entry correctionAnother method can be used to correct the data passed to the tmpl method. It shows how this can be done.
Listing 12-9: Using data to adjust results from the template $(document).ready(function () ( var data = [ ( name: "Astor", product: "astor", stocklevel: "10", price: 2.99 ) , ( name: "Daffodil", product: "daffodil", stocklevel: "12", price: 1.99), ( name: "Rose", product: "rose", stocklevel: "2", price: 4.99), ( name: "Peony", product: "peony", stocklevel: "0", price: 1.50 ), ( name: "Primula", product: "primula", stocklevel: "1", price: 3.12 ), ( name: "Snowdrop", product: "snowdrop", stocklevel: "15", price: 0.99 ), ]; var template = $("#flowerTmpl"); template.tmpl(data.slice(0, 3)).appendTo( "#row1"); template.tmpl(data.slice(3)).appendTo("#row2"); $(name):In this script, I solved the problem of placing flowers in rows by using the template twice: once for each row. I used the slice method, this way I was able to pass a specific set of data objects each time to the template. The technique is different, but the result is the same as on.
Evaluating ExpressionsWe are not limited solely to the property values of data objects. You can place a JavaScript expression between the curly braces and the template engine will do the calculations and insert the template's output into the HTML. Contains an example.
Listing 12-10: $(name):In this pattern I am using triple JavaScript operator to set the input element's value attribute based on the stocklevel property. I place this expression between curly braces, just like I did when I inserted property values directly. If the stocklevel property is greater than zero then the value attribute will be set to 1 , otherwise it will be 0 . The result can be seen at. For all flowers except peony, the stocklevel value is greater than zero.
Figure 12-4: Evaluating an expression in a templateThis example briefly demonstrates the basic functionality of a template: you combine data with a template to produce DOM objects, which you then add to the document using basic jQuery. Data values can then be used directly or indirectly in expressions to generate content.
It provides the ability to use templates to make it easy to generate HTML elements from JavaScript data objects.
To avoid any misunderstanding, I would like to warn you that this module is not currently in active development or support, and is not recommended by the jQuery team. This doesn't mean you shouldn't use it, but I felt it was my duty to tell you this before you include it in your projects. I would be happy to recommend some other option that is actively being developed, but I have not yet been able to find a replacement for jQuery Templates that is even close in its capabilities. But even with the above-mentioned attitude of the developers towards it, this module still remains the best.
The history of the jQuery Templates module is quite unusual. Microsoft and the jQuery team announced that three Microsoft-developed plugins had been given "official" status, something that no plugin had ever achieved before.
After some time, the jQuery team announced that they were deprecating these modules and depriving them of their official status, as well as their plans to replace them with other functionality. The intended replacement was supposed to be part of the jQuery UI library. It's unfortunate but true: nothing that was promised has yet been delivered, and discarded plugins are still available and widely used (especially the template plugin).
Obviously, whether or not to use deprecated code is a personal decision, but I personally like the functionality provided by templates and use it often. At the same time, I proceed from the fact that I can look into the source code and eliminate any serious problem if it arises, and the fact that sometimes you still have to find workarounds to overcome minor difficulties is worth the benefits that come from using templates.
Setting up the jQuery Templates libraryBefore you can use jQuery templates, you need to download the jQuery Templates library and connect it to your document.
Unpack the archive and copy the jQuery.tmpl.js (development version) or jQuery.tmpl.min.js (deployment version) file to your web server. The next thing to do is to add a script element to the sample document that includes the template library, as shown in the example below:
jQuery library $(function() ( // Example code will go here )); h1 (min-width: 70px; border: thick double black; margin-left: auto; margin-right: auto; text-align: center; font-size: x-large; padding: ..png"); background- size: contain; margin-top: 0; .dtable (display: table;) .drow (display: table-row;).dcell (display: table-cell; padding: 10px;) .dcell > * (vertical- align: middle) input (width: 2em; text-align: right; border: thin solid black; padding: 2px;) label (width: 6em; padding-left: .5em; display: inline-block;) #buttonDiv ( text-align: center;) button (padding: 12px;) #oblock (display: block; margin-left: auto; margin-right: auto; min-width: 700px; ) Flower shop Order
We will use this code as a sample document in this article. You probably noticed that it differs from the original version discussed earlier not only in that a library of templates has been added to it, but also in the fact that elements corresponding to various types of floral products have been removed. This is done specifically so that we can restore these elements in the document in various ways using the template library.
The appearance of the source document in the browser window at this stage is shown in the figure:
Simple Data Template ExampleThe best way to learn data patterns is to hit the ground running. To demonstrate the basic capabilities of templates, we use the example code below:
... $(function() ( var data = [ ( name: "Astra", product: "astor", stocklevel: "10", price: 2.99), ( name: "Narcissus", product: "daffodil", stocklevel: "12", price: 1.99), ( name: "Rose", product: "rose", stocklevel: "2", price: 4.99), ( name: "Peony", product: "peony", stocklevel: "0", price: 1.50), ( name: "Primula", product: "primula", stocklevel: "1", price: 3.12), ( name: "Snowdrop", product: "snowdrop", stocklevel: "15 ", price: 0.99), ]; $("#flowerTmpl").tmpl(data).appendTo("#row1"); )); .png"/> $(name): ...
In the following sections, we will break the example into separate parts and analyze the code for each of them separately. When data is part of a document, it is called inline data. An alternative to them is remote data, stored on the server separately from the document. We'll look at remote data a little later, but for now you can see that this issue is closely related to the Ajax support that jQuery provides.
Data DefinitionThe example starts with a data definition. In our case, the data is an array of objects, each of which describes a separate type of flower product. The relevant code snippet is below:
Var data = [ ( name: "Astra", product: "astor", stocklevel: "10", price: 2.99), ( name: "Narcissus", product: "daffodil", stocklevel: "12", price: 1.99 ), ( name: "Rose", product: "rose", stocklevel: "2", price: 4.99), ( name: "Peony", product: "peony", stocklevel: "0", price: 1.50), ( name: "Primula", product: "primula", stocklevel: "1", price: 3.12), ( name: "Snowdrop", product: "snowdrop", stocklevel: "15", price: 0.99), ];
Data is expressed as one or more JavaScript objects. The jQuery templating library provides considerable flexibility in the choice of objects that can be used as data, but the format presented above, corresponding to the JSON data format, is the most common. The JS0N format plays very well important role, since it is often used when working with Ajax.
In this example, the array consists of six objects, each of which has a number of properties that describe a specific product: display name, product name, number of units available, and price.
Template DefinitionAs you can probably guess, the central element of the template library is the data template. It is a collection of HTML elements containing placeholders that correspond to various properties of data objects. The template for this example is shown below:
.png"/> $(name):
The first thing to notice is that the template is placed in a script element whose type attribute is set to a non-existent type - text/x-jquery-tmpl. This is done to prevent the browser from trying to interpret the template content as regular HTML markup. Although not essential, this practice should be followed as it is extremely beneficial and will allow you to avoid many potential problems in the future.
The second point I want to highlight is that the id attribute is used to name the template defined in the script element. In this case, the template name is flowerTmpl. To apply a template to data, you need to know its name.
The contents of the template will be applied to all objects in the data array, resulting in a set of HTML elements for each object. You can see that the structure of the template generally corresponds to the set of elements that were used in previous articles to represent various types flower products. The main difference between them is the code elements that act as data placeholders.
During template processing, each placeholder is replaced with a property value taken from the current object. For example, for the first object of the array, instead of the $(product) placeholder, the value of the product property will be substituted, i.e. "astor". So part of the pattern
$(name):
is converted into the following HTML fragment:
Aster:
Value substitution isn't the only thing templates can do. Their other capabilities are discussed below.
Applying a templateThe tmpl() method is used to combine the template with data. When you do this, you specify the data to be used and the template to apply to it. An example of using this method is given below:
$("#flowerTmpl").tmpl(data).appendTo("#row1");
Here we select the element that contains the template using the $() function for this purpose, and call the tmpl() method on the resulting result, passing it the data we want to process as an argument.
The tmpl() method returns a standard jQuery object that contains the elements derived from the template. In this case, this results in a set of divs, each containing img, label, and input elements configured for one of the objects contained in the data array. To paste the entire set as child element The row1 element uses the appendTo() method. The result is shown in the figure:
Modifying the resultThe resulting result is not entirely satisfactory to us, since all elements corresponding to different colors are displayed in one row. But since we're dealing with a jQuery object, arranging the elements the way we want shouldn't be too difficult. The example below shows how this can be done by manipulating the output of the tmpl() method:
... $("#flowerTmpl").tmpl(data) .slice(0, 3).appendTo("#row1").end().end() .slice(3).appendTo("#row2" );
In this example, the slice() and end() methods are used to narrow and expand the set of selected elements, and the appendTo() method is used to add subsets of elements generated by the template to various rows.
Note that to return the set to the state it was in before slice() and appendTo() were used, end() had to be called twice in a row. There's nothing illegal about this, and I'm happy to use the end() method to get things done in a single statement, but the end().end() sequence doesn't excite me. In such cases, I prefer to break the entire sequence of actions into a series of individual operations, as shown in the example below:
Var templResult = $("#flowerTmpl").tmpl(data); templResult.slice(0, 3).appendTo("#row1"); templResult.slice(3).appendTo("#row2");
In both cases, the result will be the same: a representation of a collection of products in two rows, each of which displays three types of colors, as shown in the figure:
Changing the way input is providedAnother possible approach is to change the way data is passed to the tmpl() method. A corresponding example is given below:
Var template = $("#flowerTmpl"); template.tmpl(data.slice(0, 3)).appendTo("#row1"); template.tmpl(data.slice(3)).appendTo("#row2");
In this scenario, the distribution of elements into rows is done by using the template twice - once for each row. The corresponding part of the data objects is passed to the template each time using the slice() method. Despite the difference between this approach and the previous one, we get the same result that was presented in the figure above.
Evaluating ExpressionsData objects can be used for more than just getting property values. If you place a JavaScript expression between two curly braces, the template engine will evaluate it and insert it into the HTML markup generated by the template. A corresponding example is given below:
$(name):
In this pattern, the value attribute of the input element is set based on the value of the stocklevel property using a ternary conditional operator. The expression enclosed in curly braces plays the same role as the direct value of the property written in its place would play. If the value of the stocklevel property is greater than zero, then value is set to 1, otherwise - 0.
The resulting page in the browser window is shown in the figure below. A stocklevel value greater than zero is set for all colors except peonies:
This example illustrates the basic way of working with templates: data is combined with a template to produce DOM objects, which are then added to the document using basic jQuery functionality. You can use either directly specified values or calculated expressions to generate content.
Using Template VariablesTemplates are not JavaScript scripts. Any content you add to the script element is considered part of the template and will be included in the output. To make templates more flexible, you are provided with a small number of context variables that can be used in placeholder descriptors. Brief description These variables are contained in the table below:
Using the $data VariableThe $data variable returns the current data element to which the template is applied. For example, the $data variable used will reference each of the objects corresponding to the different types of colors in turn. To obtain the data in the previous example, the template used a ternary conditional operator. This approach is quite acceptable, but reading the resulting templates often causes difficulties, which, of course, it is advisable to avoid.
I always try to keep my template code to the minimum necessary and therefore prefer to use the $data variable inside JavaScript functions that I then call from the template. The corresponding demo is given below:
$(function() ( var data = [ ( name: "Astra", product: "astor", stocklevel: "10", price: 2.99), ( name: "Narcissus", product: "daffodil", stocklevel: " 12", price: 1.99), ( name: "Rose", product: "rose", stocklevel: "2", price: 4.99), ( name: "Peony", product: "peony", stocklevel: "0" , price: 1.50), ( name: "Primula", product: "primula", stocklevel: "1", price: 3.12), ( name: "Snowdrop", product: "snowdrop", stocklevel: "15", price : 0.99), ]; var template = $("#flowerTmpl"); template.tmpl(data.slice(0, 3)).appendTo("#row1"); template.tmpl(data.slice(3)) .appendTo("#row2" )); function stockDisplay(product) ( return product.stocklevel > 0 ? 1: 0; ) .png"/> $(name):
This example defines a function stockDisplay() that returns the value that should be displayed in the input element. The argument to this function is a data object, which we get inside the template using the $data variable. Considering that this is just a simple ternary operator, the difference in code readability compared to the previous version is not very significant, but in the case of more complex expressions or in the case of repeated use of an expression within the same template, it will be much more noticeable.
Be careful when defining functions that will be called from the template. The point is that such functions must be defined before calling the tmpl() method. I always try to put them at the end of the script element, but if the function must be inside the ready event handler, then you should definitely make sure that it has been previously defined. Another common mistake is that a function is often defined inside a template.
Using the $() function inside a templatePlaceholders used within a template can use jQuery's $() function, but it is important to remember that elements generated by the template are not attached to the document and therefore will not be included in the selection sets. jQuery elements. I rarely use this feature because I'm usually more interested in the elements and associated data that I generate myself.
Using the $item VariableThe object returned by $item serves several purposes. The first is to allow additional data to be exchanged between the JavaScript script and the template. A corresponding example is given below:
$(function() ( var data = [ ( name: "Astra", product: "astor", stocklevel: "10", price: 2.99), ( name: "Narcissus", product: "daffodil", stocklevel: " 12", price: 1.99), ( name: "Rose", product: "rose", stocklevel: "2", price: 4.99), ( name: "Peony", product: "peony", stocklevel: "0" , price: 1.50), ( name: "Primula", product: "primula", stocklevel: "1", price: 3.12), ( name: "Snowdrop", product: "snowdrop", stocklevel: "15", price : 0.99), ]; $(" Special offer for today: " + "50 cents discount") .insertAfter("h1") .css(( color: "red", fontSize: "14pt", textAlign: "center" )); var options = ( discount: $ ("#offer").data("discount"), stockDisplay: function(product) ( return product.stocklevel > 0 ? 1: 0; ) ); var template = $("#flowerTmpl"); data.slice(0, 3), options).appendTo("#row1"); template.tmpl(data.slice(3), options).appendTo("#row2" )); $(name):
In this example, we create an options object that defines a property (discount) and a method (stockDisplay()). This object is then passed to the tmpl() method as the second argument. The $item variable provides access to the properties and methods of an object from the template. As you can see, to handle the price discount, the discount property of the options object is used here.
I would like to draw your attention to the need to include the $ prefix in the names of context variables: $item and $data. The same prefix is also required in the template descriptor construction $(...), used to substitute values into the template. Omitting any of these prefixes is one of the most common mistakes.
We will talk about other applications of this object later.
Using Nested TemplatesWhen creating complex applications, it sometimes makes sense to break a large template into several parts, which are combined at the execution stage of the application. As will be shown later, this method of combining templates provides more flexible output control. We'll start with the most basic. The example below shows how one template can reference another:
... .png"/> $(name): ((tmpl($data, $item) "#inputTmpl"))
In this example, the template is split into two parts. The first of these, the flowerTmpl template, is called for each element of the data array. This template in turn calls the inputTmpl template to create input elements. The second template is called using the handle ((tmpl)). This call takes three arguments. The first two are the current item and the options object; these arguments are enclosed in parentheses. The third argument is the template to call. It can be specified either by a jQuery selector (as done above), or by a variable or function defined in the script.
Using Conditional PatternsThe template engine provides the ability to dynamically make decisions regarding the use of different parts of the template depending on the fulfillment of certain conditions. For this, there are descriptors ((if)) and ((/if)), an example of their use is presented below:
... ((if stocklevel > 0)).png"/> $(name): ((/if))
The condition is specified in the ((if)) descriptor, and the portion of the template between this descriptor and the ((/if)) descriptor will be used only if the conditional expression evaluates to true. If this result is false, then the specified part of the template is ignored. In this case, the value of the stocklevel property is checked, and if it is equal to zero, then the entire flowerTmpl template is ignored. This means that only those products that are in stock will be displayed, as shown in the image:
More complex conditions can be specified using the ((else)) descriptor, which allows you to specify the part of the pattern that should be used in cases where the expression in the ((if)) descriptor evaluates to false. A corresponding example is given below:
... ((if stocklevel > 5)) .png"/> $(name): ((else stocklevel > 0)) .png"/> $(name): (Small amount) ((else)) .png " style="opacity:0.5"/> $(name) (Out of stock) ((/if))
In this scenario, the set of items displayed is determined by how many units of each product type are in stock: more than five, five, less than five, or out of stock. I've introduced only minor differences between the elements generated for each of these conditions, but you are free to use these features to generate completely different content. Finally, if necessary, you can call other templates by condition.
The result of the above script is shown in the figure:
Plugin for implementing changing words with various animated effects. CSS effect Suitable for implementing promotional sites and animated banners.
Implementation of dividing page content into tabs using animated CSS3 effects. Four design options: horizontal and vertical tabs with various animated effects.
3. Adaptive jQuery slider based on the IMPRESS.JS pluginCool slider with simulating 3D effect when scrolling through slides. When you increase/decrease the screen size, the size of the font, images and all elements on the slide changes, which guarantees correct display at any screen size. Automatic scrolling is provided.
jQuery solution to create easy navigation by sections of the document without reloading the page. Each section is displayed in a separate block with vertical scrolling, and the transition between them can be done either with a mouse click or by using the title (with large screens, the title is displayed on the left side, when viewing the site on a small screen - at the top of the document).
Implementation of content navigation in the form List of categories → List of sections → Section content. Navigation is accompanied by various JS effects.
Scrolling through slides is carried out with Parallax effect(movement of layers at different speeds, together create a 3D effect). The size of the slider changes in proportion to the size of the browser window.
Slideshow with musical accompaniment. It is possible to pause or skip a musical composition.
11. A unique menu using jQuery and CSSWhen you select a menu item, the area with its contents expands on top.
A horizontal drop-down menu with an interesting jQuery effect of nested items appearing.
An awesome jQuery CSS plugin that will be a very useful addition to the website of any web studio or freelancer. With its help, you can clearly display examples of completed work broken down by time. The timeline itself is displayed at the bottom, and the completed work is displayed at the top. To navigate between jobs, you can use both the scale and the left/right arrows.
14. “TouchTouch” gallery, optimized for viewing from mobile devices 15. CSS3 image slider “Cycle Slider”When you click on the name, an image with a description appears. Only CSS3 is used.
17. Cool, colorful jQuery and CSS3 tooltips
Lesson on creating a gallery.jQuery tooltips in 7 styles. Easy to connect and use in your projects.
If there are more than 5 images in the gallery, left/right arrows appear to navigate through the photos.
Slides can be not only images, but also other HTML content.
Plugin for creating photorealistic shadows.
Fresh implementation of the slider.
26. Wrap text “Bacon”An unusual effect of transferring text on a page to a new line along a curve or a given line with a certain offset step.
The plugin automatically calculates the font size for each word so that all text occupies the same width, regardless of the number of words in the line.
28. Choosing the type of block display using CSS3Four types of block display: image with a description in three columns, image with a description in one column, images only, text description only. To switch the type of display of blocks, you need to use the icons at the top.