提交 354bf471 编写于 作者: H huybrechts

Support for databinding on descriptor list

Merging changes made by Kohsuke in nodeproperties branch

Revision: 14927
Author: kohsuke
Date: 20:44:52, vrijdag 30 januari 2009
Message:
added support for form databinding
----
Modified : /branches/nodeproperties/main/core/src/main/resources/lib/form/descriptorList.jelly

Revision: 14925
Author: kohsuke
Date: 20:41:35, vrijdag 30 januari 2009
Message:
handle overlapping nested <rowSet> correctly.
----
Modified : /branches/nodeproperties/main/war/resources/scripts/hudson-behavior.js

Revision: 14924
Author: kohsuke
Date: 20:33:48, vrijdag 30 januari 2009
Message:
added another convenience method.
----
Modified : /branches/nodeproperties/main/core/src/main/java/hudson/util/DescribableList.java

Revision: 14918
Author: kohsuke
Date: 19:02:44, vrijdag 30 januari 2009
Message:
added optional @name to create an JSON object
----
Modified : /branches/nodeproperties/main/core/src/main/resources/lib/form/section.jelly

Revision: 14917
Author: kohsuke
Date: 19:02:30, vrijdag 30 januari 2009
Message:
added documentation and supported graceful no-op.
----
Modified : /branches/nodeproperties/main/core/src/main/resources/lib/form/rowSet.jelly

Revision: 14915
Author: kohsuke
Date: 18:44:56, vrijdag 30 januari 2009
Message:
I hate cursor stealing
----
Modified : /branches/nodeproperties/main/core/src/main/resources/lib/form/descriptorList.jelly

Revision: 14914
Author: kohsuke
Date: 18:44:04, vrijdag 30 januari 2009
Message:
title is not mandatory
----
Modified : /branches/nodeproperties/main/core/src/main/resources/lib/form/descriptorList.jelly




git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@15368 71c3de6d-444a-0410-be80-ed276b4c234a
上级 284771d5
...@@ -97,6 +97,11 @@ public class DescribableList<T extends Describable<T>, D extends Descriptor<T>> ...@@ -97,6 +97,11 @@ public class DescribableList<T extends Describable<T>, D extends Descriptor<T>>
onModified(); onModified();
} }
public void replaceBy(Collection<? extends T> col) throws IOException {
data.replaceBy(col);
onModified();
}
public T get(D descriptor) { public T get(D descriptor) {
for (T t : data) for (T t : data)
if(t.getDescriptor()==descriptor) if(t.getDescriptor()==descriptor)
......
...@@ -26,17 +26,26 @@ THE SOFTWARE. ...@@ -26,17 +26,26 @@ THE SOFTWARE.
<st:documentation> <st:documentation>
Generate config pages from a list of Descriptors into a section. Generate config pages from a list of Descriptors into a section.
<st:attribute name="title" use="required"> <st:attribute name="title">
Human readable title of the section to be rendered in HTML. Human readable title of the section to be rendered in HTML.
</st:attribute> </st:attribute>
<st:attribute name="descriptors" use="required"> <st:attribute name="descriptors" use="required">
hudson.model.Descriptor collection whose configuration page is rendered. hudson.model.Descriptor collection whose configuration page is rendered.
</st:attribute> </st:attribute>
<st:attribute name="instances" use="required"> <st:attribute name="instances">
Map&lt;Descriptor,Describable> that defines current instances of those descriptors. Map&lt;Descriptor,Describable> that defines current instances of those descriptors.
These are used to fill initial values. Other classes that define the get(Descriptor) These are used to fill initial values. Other classes that define the get(Descriptor)
method works fine, too. method works fine, too.
</st:attribute> </st:attribute>
<st:attribute name="field">
Either @field or @instances are required. If field is specified, instances are assumed to be
instance[field].
When this attribute is specified, JSON structure is properly set up so that the databinding
can set the field (or pass this collection as a constructor parameter of the same name.
This is more modern way of doing databinding, and thus preferred approach.
</st:attribute>
<st:attribute name="targetType"> <st:attribute name="targetType">
the type for which descriptors will be configured. the type for which descriptors will be configured.
default to ${it.class} default to ${it.class}
...@@ -44,7 +53,17 @@ THE SOFTWARE. ...@@ -44,7 +53,17 @@ THE SOFTWARE.
</st:documentation> </st:documentation>
<j:set var="targetType" value="${h.defaulted(attrs.targetType,it.class)}"/> <j:set var="targetType" value="${h.defaulted(attrs.targetType,it.class)}"/>
<f:section title="${attrs.title}"> <j:set var="instances" value="${h.ifThenElse(attrs.instances!=null,attrs.instances,instance[field])}"/>
<f:section title="${attrs.title}" name="${attrs.field}">
<j:if test="${attrs.field!=null}">
<tr>
<td>
<input type="hidden" name="stapler-class-bag" value="true" />
</td>
</tr>
</j:if>
<d:invokeBody /> <d:invokeBody />
<j:forEach var="d" items="${descriptors}"> <j:forEach var="d" items="${descriptors}">
<f:optionalBlock name="${d.jsonSafeClassName}" help="${d.helpFile}" <f:optionalBlock name="${d.jsonSafeClassName}" help="${d.helpFile}"
......
...@@ -22,17 +22,26 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ...@@ -22,17 +22,26 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
--> -->
<!-- <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<st:documentation>
Adds @nameRef to all table rows inside this tag, so that when the form is submitted, Adds @nameRef to all table rows inside this tag, so that when the form is submitted,
it gets grouped in one JSON object. it gets grouped in one JSON object.
@ref: id of the thing that serves as the group head, if that's available separately <st:attribute name="name">
if the group head is not available outside, use this attribute to specify the name.
@name: if the group head is not available outside, use this attribute to specify the name.
@name and @ref are mutually exclusive. @name and @ref are mutually exclusive.
--> </st:attribute>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form"> <st:attribute name="ref">
id of the thing that serves as the group head, if that's available separately
</st:attribute>
</st:documentation>
<j:choose>
<j:when test="${attrs.ref==null and attrs.name==null}">
<!-- noop -->
<d:invokeBody />
</j:when>
<j:otherwise>
<j:set var="id" value="${h.generateId()}" /> <j:set var="id" value="${h.generateId()}" />
<j:set var="head" value="rowGroupStart${id}"/> <j:set var="head" value="rowGroupStart${id}"/>
<j:set var="ref" value="${h.ifThenElse(attrs.ref!=null, attrs.ref, head)}"/> <j:set var="ref" value="${h.ifThenElse(attrs.ref!=null, attrs.ref, head)}"/>
...@@ -43,4 +52,6 @@ THE SOFTWARE. ...@@ -43,4 +52,6 @@ THE SOFTWARE.
<script> <script>
applyNameRef($$('${head}') , $$('rowGroupEnd${id}') , '${ref}') applyNameRef($$('${head}') , $$('rowGroupEnd${id}') , '${ref}')
</script> </script>
</j:otherwise>
</j:choose>
</j:jelly> </j:jelly>
\ No newline at end of file
...@@ -30,7 +30,12 @@ THE SOFTWARE. ...@@ -30,7 +30,12 @@ THE SOFTWARE.
The section header text. The section header text.
If null is given, the entire &lt;f:section> tag becomes no-op. If null is given, the entire &lt;f:section> tag becomes no-op.
</st:attribute> </st:attribute>
<st:attribute name="name">
Optional attribute to create a JSON object from this section.
</st:attribute>
</st:documentation> </st:documentation>
<f:rowSet name="${attrs.name}">
<j:if test="${attrs.title!=null}"> <j:if test="${attrs.title!=null}">
<f:block> <f:block>
<div style="font-weight:bold; border-bottom: 1px solid black; margin-bottom:0.2em; margin-top:0.4em"> <div style="font-weight:bold; border-bottom: 1px solid black; margin-bottom:0.2em; margin-top:0.4em">
...@@ -39,4 +44,5 @@ THE SOFTWARE. ...@@ -39,4 +44,5 @@ THE SOFTWARE.
</f:block> </f:block>
</j:if> </j:if>
<d:invokeBody /> <d:invokeBody />
</f:rowSet>
</j:jelly> </j:jelly>
\ No newline at end of file
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
// //
initOptionalBlock//
// JavaScript for Hudson // JavaScript for Hudson
// See http://www.ibm.com/developerworks/web/library/wa-memleak/?ca=dgr-lnxw97JavascriptLeaks // See http://www.ibm.com/developerworks/web/library/wa-memleak/?ca=dgr-lnxw97JavascriptLeaks
// for memory leak patterns and how to prevent them. // for memory leak patterns and how to prevent them.
...@@ -580,8 +581,11 @@ function replaceDescription() { ...@@ -580,8 +581,11 @@ function replaceDescription() {
function applyNameRef(s,e,id) { function applyNameRef(s,e,id) {
$(id).groupingNode = true; $(id).groupingNode = true;
// s contains the node itself // s contains the node itself
for(var x=s.nextSibling; x!=e; x=x.nextSibling) for(var x=s.nextSibling; x!=e; x=x.nextSibling) {
// to handle nested <f:rowSet> correctly, don't overwrite the existing value
if(x.getAttribute("nameRef")==null)
x.setAttribute("nameRef",id); x.setAttribute("nameRef",id);
}
} }
function initOptionalBlock(sid, eid, cid) { function initOptionalBlock(sid, eid, cid) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册