001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.ajax;
018
019import org.apache.wicket.Component;
020import org.apache.wicket.markup.html.form.TextField;
021import org.apache.wicket.util.io.IClusterable;
022
023/**
024 * A mixin that allows behaviors and components to override the id of the markup region that will be
025 * updated via ajax. If this mixin is not used then {@link Component#getMarkupId()} is used.
026 * <p>
027 * This mixin is useful when behaviors write directly to the response. Lets examine a simple
028 * behavior that wraps the component in a paragraph tag:
029 * 
030 * <pre>
031 * class PB extends Behavior
032 * {
033 *      public void beforeRender(Component c)
034 *      {
035 *              c.getResponse().write(&quot;&lt;p&gt;&quot;);
036 *      }
037 * 
038 *      public void afterRender(Component c)
039 *      {
040 *              c.getResponse().write(&quot;&lt;/p&gt;&quot;);
041 *      }
042 * }
043 * </pre>
044 * 
045 * If we add this behavior to a {@link TextField} the generated markup will be:
046 * 
047 * <pre>
048 * &lt;p&gt;&lt;input wicket:id="name" type="text"&gt;&lt;/p&gt;
049 * </pre>
050 * 
051 * If we then update this {@link TextField} via ajax the generated markup will erroneously be:
052 * 
053 * <pre>
054 * &lt;p&gt;&lt;p&gt;&lt;input wicket:id="name" type="text"&gt;&lt;/p&gt;&lt;/p&gt;
055 * </pre>
056 * 
057 * Notice the doubling of the {@code <p>} tags. This is happening because every ajax render the
058 * input field is replaced with the markup that contains the input field surrounded by paragraph
059 * tags.
060 * 
061 * To fix this we can modify our behavior as follows:
062 * 
063 * <pre>
064 * class PB extends Behavior implements IAjaxRegionMarkupIdProvider
065 * {
066 *      public void beforeRender(Component c)
067 *      {
068 *              c.getResponse().write(&quot;&lt;p id='&quot; + c.getMarkupId() + &quot;_p'&gt;&quot;);
069 *      }
070 * 
071 *      public void afterRender(Component c)
072 *      {
073 *              c.getResponse().write(&quot;&lt;/p&gt;&quot;);
074 *      }
075 * 
076 *      public String getAjaxRegionMarkupId(Component component)
077 *      {
078 *              return component.getMarkupId() + &quot;_p&quot;;
079 *      }
080 * }
081 * </pre>
082 * 
083 * Now, the ajax update will properly replace the markup region that includes the paragraph tags
084 * with the generated markup.
085 * 
086 * </p>
087 * <p>
088 * In the rare case that {@link Component} needs to implement this interface the {@code component}
089 * argument of the {@link #getAjaxRegionMarkupId(Component)} method can be safely ignored because it
090 * will be the component itself.
091 * </p>
092 * 
093 * @author Igor Vaynberg (ivaynberg)
094 */
095@FunctionalInterface
096public interface IAjaxRegionMarkupIdProvider extends IClusterable
097{
098        /**
099         * @param component
100         * @return the id of the markup region that will be updated via ajax.
101         */
102        String getAjaxRegionMarkupId(Component component);
103}