| <!DOCTYPE html> |
| <html> |
| <head> |
| <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
| <meta charset="utf-8"> |
| |
| |
| |
| <title>Ajax Counter | Apache Wicket</title> |
| <meta name="viewport" content="width=device-width, initial-scale=1" /> |
| |
| <link rel="shortcut icon" href="/favicon.ico" type="image/vnd.microsoft.icon" /> |
| <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen" /> |
| <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" /> |
| |
| <script src="//code.jquery.com/jquery-1.11.3.min.js"></script> |
| |
| |
| </head> |
| <body class=""> |
| <div class="header default"> |
| <div class="l-container"> |
| |
| <nav class="mainmenu"> |
| <div class="nav-logo"> |
| <a href="/"><img src="/img/logo-apachewicket.svg" alt="Apache Wicket"></a> |
| </div> |
| |
| <div class="nav-container"> |
| |
| |
| |
| |
| |
| <!-- /start/quickstart.html || /learn/examples/ajaxcounter --> |
| |
| |
| |
| <a href="/start/quickstart.html" class=" nav-items">Quick Start</a> |
| |
| |
| |
| |
| |
| <!-- /start/download.html || /learn/examples/ajaxcounter --> |
| |
| |
| |
| <a href="/start/download.html" class=" nav-items">Download</a> |
| |
| |
| |
| |
| |
| <!-- /learn || /learn/examples/ajaxcounter --> |
| |
| |
| |
| <a href="/learn" class=" nav-items">Documentation</a> |
| |
| |
| |
| |
| |
| <!-- /help || /learn/examples/ajaxcounter --> |
| |
| |
| |
| <a href="/help" class=" nav-items">Support</a> |
| |
| |
| |
| |
| |
| <!-- /contribute || /learn/examples/ajaxcounter --> |
| |
| |
| |
| <a href="/contribute" class=" nav-items">Contribute</a> |
| |
| |
| |
| |
| |
| <!-- /community || /learn/examples/ajaxcounter --> |
| |
| |
| |
| <a href="/community" class=" nav-items">Community</a> |
| |
| |
| |
| |
| |
| <!-- /apache || /learn/examples/ajaxcounter --> |
| |
| |
| |
| <a href="/apache" class=" nav-items">Apache</a> |
| |
| </div> |
| <div class="nav-container "> |
| <a href="https://github.com/apache/wicket" target="_blank"><i class="fa fa-github nav-items"></i></a> |
| <a href="https://twitter.com/apache_wicket" target="_blank"><i class="fa fa-twitter nav-items"></i></a> |
| <a href="https://builtwithwicket.tumblr.com" target="_blank"><i class="fa fa-tumblr nav-items"></i></a> |
| </div> |
| </nav> |
| |
| </div> |
| </div> |
| <main> |
| <div class="l-container"> |
| <header class="l-full preamble"> |
| <h1>Ajax Counter</h1> |
| |
| |
| |
| </header> |
| <section class="toc left default "> |
| <div id="toc" class="toc"><div id="toc-title"><h2>Table of Contents</h2></div><ul><li class="toc--level-1 toc--section-1"><a href="#counter-page"><span class="toc-number">1</span> <span class="toc-text">Counter page</span></a></li><li class="toc--level-1 toc--section-2"><a href="#adding-ajax"><span class="toc-number">2</span> <span class="toc-text">Adding Ajax</span></a></li><li class="toc--level-1 toc--section-3"><a href="#summary"><span class="toc-number">3</span> <span class="toc-text">Summary</span></a></li></ul></div> |
| </section> |
| <section> |
| <p>This example shows you how to use Wicket’s Ajax behaviors and components by |
| building a simple counter that updates through Ajax link clicks.</p> |
| |
| <p>In all the Wicket examples, you have to put all files in the same package |
| directory. This means putting the markup files and the java files next to one |
| another. It is possible to alter this behavior, but that is beyond the scope |
| of this example. The only exception is the obligatory <code class="language-plaintext highlighter-rouge">web.xml</code> file which |
| should reside in the <code class="language-plaintext highlighter-rouge">WEB-INF/</code> directory of your web application root |
| folder.</p> |
| |
| <p>In this example we assume you already have read and understood the other |
| examples which give you information on the structure and nature of Wicket |
| applications. Specifically read and understand the <a href="helloworld.html">Hello, World |
| example</a>.</p> |
| |
| <h2 id="counter-page">Counter page</h2> |
| |
| <p>First we’ll create a page that just counts the number of times a link has been clicked. In the following markup you’ll see a link and a label.</p> |
| |
| <figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><html></span> |
| <span class="nt"><head></head></span> |
| <span class="nt"><body></span> |
| <span class="nt"><a</span> <span class="na">href=</span><span class="s">"#"</span> <span class="na">wicket:id=</span><span class="s">"link"</span><span class="nt">></span>click me<span class="nt"></a></span> |
| <span class="nt"><p></span> |
| Counter: <span class="nt"><span</span> <span class="na">wicket:id=</span><span class="s">"counter"</span><span class="nt">></span>nr of times<span class="nt"></span></span> |
| <span class="nt"></p></span> |
| <span class="nt"></body></span> |
| <span class="nt"></html></span></code></pre></figure> |
| |
| <p>The link component will refresh the page and the label will replace the text |
| ‘nr of times’ with the count. Take a look at the following Java file to see |
| how it works on the Java side:</p> |
| |
| <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kn">package</span> <span class="nn">wicket.quickstart</span><span class="o">;</span> |
| |
| <span class="kn">import</span> <span class="nn">wicket.Component</span><span class="o">;</span> |
| <span class="kn">import</span> <span class="nn">wicket.markup.html.basic.Label</span><span class="o">;</span> |
| <span class="kn">import</span> <span class="nn">wicket.markup.html.link.Link</span><span class="o">;</span> |
| <span class="kn">import</span> <span class="nn">wicket.model.Model</span><span class="o">;</span> |
| |
| <span class="kd">public</span> <span class="kd">class</span> <span class="nc">Index</span> <span class="kd">extends</span> <span class="nc">QuickStartPage</span> <span class="o">{</span> |
| <span class="kd">public</span> <span class="nf">Index</span><span class="o">()</span> <span class="o">{</span> |
| <span class="nc">Model</span><span class="o"><</span><span class="nc">Integer</span><span class="o">></span> <span class="n">model</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Model</span><span class="o"><</span><span class="nc">Integer</span><span class="o">>()</span> <span class="o">{</span> |
| <span class="kd">private</span> <span class="kt">int</span> <span class="n">counter</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> |
| |
| <span class="kd">public</span> <span class="nc">Integer</span> <span class="nf">getObject</span><span class="o">()</span> <span class="o">{</span> |
| <span class="k">return</span> <span class="n">counter</span><span class="o">++;</span> |
| <span class="o">}</span> |
| <span class="o">};</span> |
| <span class="n">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">Link</span><span class="o">(</span><span class="s">"link"</span><span class="o">)</span> <span class="o">{</span> |
| <span class="kd">public</span> <span class="kt">void</span> <span class="nf">onClick</span><span class="o">()</span> <span class="o">{</span> |
| <span class="c1">// do nothing.</span> |
| <span class="o">}</span> |
| <span class="o">});</span> |
| <span class="n">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">Label</span><span class="o"><</span><span class="nc">Integer</span><span class="o">>(</span><span class="s">"counter"</span><span class="o">,</span> <span class="n">model</span><span class="o">));</span> |
| <span class="o">}</span> |
| <span class="o">}</span></code></pre></figure> |
| |
| <p>In this class we created a <code class="language-plaintext highlighter-rouge">Model</code> subclass that increases its counter |
| everytime the <code class="language-plaintext highlighter-rouge">getObject</code> method gets called, and returns its value. We set |
| this model on the label component, so that each time the label gets rendered |
| the counter gets increased.</p> |
| |
| <p>The link doesn’t do anything, just listen to the requests and update the |
| page. If you run this code in your application (download the Quickstart |
| project and copy/paste the code in the homepage for a quick experience).</p> |
| |
| <p>The page gets fully refreshed with each link click. That is not very web 2.0, |
| so let’s make it more modern by adding some Ajax stuff.</p> |
| |
| <h2 id="adding-ajax">Adding Ajax</h2> |
| |
| <p>To make this a more modern UI we’ll have to change a couple of things. First |
| we need to make the link an Ajax link. Wicket provides several types of Ajax |
| links, but the best one for our purposes is the <code class="language-plaintext highlighter-rouge">AjaxFallbackLink</code>, as it |
| provides a fallback to a normal request in case no Ajax is available.</p> |
| |
| <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kn">package</span> <span class="nn">wicket.quickstart</span><span class="o">;</span> |
| |
| <span class="kn">import</span> <span class="nn">wicket.Component</span><span class="o">;</span> |
| <span class="kn">import</span> <span class="nn">wicket.ajax.AjaxRequestTarget</span><span class="o">;</span> |
| <span class="kn">import</span> <span class="nn">wicket.ajax.markup.html.AjaxFallbackLink</span><span class="o">;</span> |
| <span class="kn">import</span> <span class="nn">wicket.markup.html.basic.Label</span><span class="o">;</span> |
| <span class="kn">import</span> <span class="nn">wicket.model.Model</span><span class="o">;</span> |
| |
| <span class="kd">public</span> <span class="kd">class</span> <span class="nc">Index</span> <span class="kd">extends</span> <span class="nc">QuickStartPage</span> <span class="o">{</span> |
| <span class="kd">public</span> <span class="nf">Index</span><span class="o">()</span> <span class="o">{</span> |
| <span class="nc">Model</span><span class="o"><</span><span class="nc">Integer</span><span class="o">></span> <span class="n">model</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Model</span><span class="o"><</span><span class="nc">Integer</span><span class="o">>()</span> <span class="o">{</span> |
| <span class="kd">private</span> <span class="kt">int</span> <span class="n">counter</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> |
| |
| <span class="kd">public</span> <span class="nc">Integer</span> <span class="nf">getObject</span><span class="o">()</span> <span class="o">{</span> |
| <span class="k">return</span> <span class="n">counter</span><span class="o">++;</span> |
| <span class="o">}</span> |
| <span class="o">};</span> |
| <span class="n">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">AjaxFallbackLink</span><span class="o">(</span><span class="s">"link"</span><span class="o">)</span> <span class="o">{</span> |
| <span class="kd">public</span> <span class="kt">void</span> <span class="nf">onClick</span><span class="o">(</span><span class="nc">AjaxRequestTarget</span> <span class="n">target</span><span class="o">)</span> <span class="o">{</span> |
| <span class="c1">// add the components that need to be updated to </span> |
| <span class="c1">// the target</span> |
| <span class="o">}</span> |
| <span class="o">});</span> |
| <span class="n">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">Label</span><span class="o"><</span><span class="nc">Integer</span><span class="o">>(</span><span class="s">"counter"</span><span class="o">,</span> <span class="n">model</span><span class="o">));</span> |
| <span class="o">}</span> |
| <span class="o">}</span></code></pre></figure> |
| |
| <p>As you can see, the <code class="language-plaintext highlighter-rouge">Link</code> has been replaced with the <code class="language-plaintext highlighter-rouge">AjaxFallbackLink</code>, and the |
| <code class="language-plaintext highlighter-rouge">onClick</code> method now takes a new argument: the <code class="language-plaintext highlighter-rouge">AjaxRequestTarget</code>. If you want a |
| component to be updated in the Ajax request, you’ll have to add them to the |
| target. So let’s alter the file to make it possible to add the label to the |
| request target.</p> |
| |
| <figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kn">package</span> <span class="nn">wicket.quickstart</span><span class="o">;</span> |
| |
| <span class="kn">import</span> <span class="nn">wicket.Component</span><span class="o">;</span> |
| <span class="kn">import</span> <span class="nn">wicket.ajax.AjaxRequestTarget</span><span class="o">;</span> |
| <span class="kn">import</span> <span class="nn">wicket.ajax.markup.html.AjaxFallbackLink</span><span class="o">;</span> |
| <span class="kn">import</span> <span class="nn">wicket.markup.html.basic.Label</span><span class="o">;</span> |
| <span class="kn">import</span> <span class="nn">wicket.model.Model</span><span class="o">;</span> |
| |
| <span class="kd">public</span> <span class="kd">class</span> <span class="nc">Index</span> <span class="kd">extends</span> <span class="nc">QuickStartPage</span> <span class="o">{</span> |
| <span class="kd">public</span> <span class="nf">Index</span><span class="o">()</span> <span class="o">{</span> |
| <span class="nc">Model</span><span class="o"><</span><span class="nc">Integer</span><span class="o">></span> <span class="n">model</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Model</span><span class="o"><</span><span class="nc">Integer</span><span class="o">>()</span> <span class="o">{</span> |
| <span class="kd">private</span> <span class="kt">int</span> <span class="n">counter</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> |
| |
| <span class="kd">public</span> <span class="nc">Integer</span> <span class="nf">getObject</span><span class="o">()</span> <span class="o">{</span> |
| <span class="k">return</span> <span class="n">counter</span><span class="o">++;</span> |
| <span class="o">}</span> |
| <span class="o">};</span> |
| <span class="kd">final</span> <span class="nc">Label</span><span class="o"><</span><span class="nc">Integer</span><span class="o">></span> <span class="n">label</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Label</span><span class="o"><</span><span class="nc">Integer</span><span class="o">>(</span><span class="s">"counter"</span><span class="o">,</span> <span class="n">model</span><span class="o">);</span> |
| <span class="n">label</span><span class="o">.</span><span class="na">setOutputMarkupId</span><span class="o">(</span><span class="kc">true</span><span class="o">);</span> |
| <span class="n">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">AjaxFallbackLink</span><span class="o">(</span><span class="s">"link"</span><span class="o">)</span> <span class="o">{</span> |
| <span class="kd">public</span> <span class="kt">void</span> <span class="nf">onClick</span><span class="o">(</span><span class="nc">AjaxRequestTarget</span> <span class="n">target</span><span class="o">)</span> <span class="o">{</span> |
| <span class="k">if</span> <span class="o">(</span><span class="n">target</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span> |
| <span class="c1">// target is only available in an Ajax request</span> |
| <span class="n">target</span><span class="o">.</span><span class="na">addComponent</span><span class="o">(</span><span class="n">label</span><span class="o">);</span> |
| <span class="o">}</span> |
| <span class="o">}</span> |
| <span class="o">});</span> |
| <span class="n">add</span><span class="o">(</span><span class="n">label</span><span class="o">);</span> |
| <span class="o">}</span> |
| <span class="o">}</span></code></pre></figure> |
| |
| <p>We’ve moved the instantiation of the label to the beginning of the page |
| constructor and made a local, final variable. This way we can reference the |
| label in the event handler of the link component.</p> |
| |
| <p>We also had to call <code class="language-plaintext highlighter-rouge">setOutputMarkupId(true)</code> on the label to be able to |
| update the component when the request is returned to the client browser. If |
| we don’t, Wicket will not know how to update the markup in the client.</p> |
| |
| <p>If you put this code into your page’s class, then you’ll have a working Ajax |
| updating counter.</p> |
| |
| <h2 id="summary">Summary</h2> |
| |
| <p>Working with Ajax and Wicket using the standard Wicket libraries doesn’t |
| require a degree in JavaScript. Even better, you don’t necessarily need to |
| update your markup file to work with Ajax. In this (simple) example we were |
| able to add Ajax behavior to the page without touching the markup file.</p> |
| |
| <p>The most important lesson here is that in order to update components using |
| Ajax is that you need to add those components to the <code class="language-plaintext highlighter-rouge">AjaxRequestTarget</code> and |
| that the components that are to be updated in that request, should have |
| <code class="language-plaintext highlighter-rouge">setOutputMarkupId(true)</code>.</p> |
| |
| |
| </section> |
| </div> |
| </main> |
| |
| <footer> |
| <div class="l-container"> |
| <div class="left"> |
| <img src="/img/asf_logo_url.svg" style="height:90px; float:left; margin-right:10px;"> |
| <div style="margin-top:12px;">Copyright © 2021 — The Apache Software Foundation. Apache Wicket, Wicket, Apache, the Apache feather logo, and the Apache Wicket project logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners.</div> |
| </div> |
| </div> |
| |
| </footer> |
| </body> |
| </html> |