001 // Copyright 2006 The Apache Software Foundation 002 // 003 // Licensed under the Apache License, Version 2.0 (the "License"); 004 // you may not use this file except in compliance with the License. 005 // You may obtain a copy of the License at 006 // 007 // http://www.apache.org/licenses/LICENSE-2.0 008 // 009 // Unless required by applicable law or agreed to in writing, software 010 // distributed under the License is distributed on an "AS IS" BASIS, 011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 // See the License for the specific language governing permissions and 013 // limitations under the License. 014 015 package org.apache.tapestry.form; 016 017 import org.apache.tapestry.IForm; 018 import org.apache.tapestry.IMarkupWriter; 019 import org.apache.tapestry.IRequestCycle; 020 021 /** 022 * A {@link FormSupport} implementation that can work when a form is 023 * included multiple times in a given page ( due to it being in a loop 024 * or in a component that's included many times in the page). 025 * <p/> 026 * This is achieved by prefixing the ids of all form elements with the 027 * form's id. 028 * 029 * @since 4.1.1 030 */ 031 public class MultipleFormSupport extends FormSupportImpl 032 { 033 /** 034 * The prefix to use for the form elements. On render, this is the 035 * clientId of the form. On rewind, it's computed from the posted data. 036 */ 037 private String _prefix; 038 039 public MultipleFormSupport(IMarkupWriter writer, IRequestCycle cycle, IForm form) 040 { 041 super(writer, cycle, form); 042 _prefix = form.getClientId() + ":"; 043 } 044 045 /** 046 * Constructs a unique identifier (within the page). The identifier consists of the component's 047 * id, with an index number added to ensure uniqueness. 048 */ 049 050 public String getElementId(IFormComponent component, String baseId) 051 { 052 return super.getElementId(component, _prefix + baseId); 053 } 054 055 public String peekClientId(IFormComponent comp) 056 { 057 String id = comp.getSpecifiedId(); 058 if (id == null) 059 return null; 060 061 return peekClientId(comp, id); 062 } 063 064 protected String peekClientId(IFormComponent comp, String baseId) 065 { 066 return _elementIdAllocator.peekNextId(_prefix + baseId); 067 } 068 069 public String rewind() 070 { 071 findIdPrefix(); 072 return super.rewind(); 073 } 074 075 private void findIdPrefix() 076 { 077 String allocatedFormIds = _cycle.getParameter(FORM_IDS); 078 if (allocatedFormIds==null) 079 return; 080 int pos = allocatedFormIds.indexOf(':'); 081 if (pos>=0) 082 _prefix = allocatedFormIds.substring(0, pos + 1); 083 } 084 }