2013-04-05 11 views
6

Beim Anzeigen einer Xpage im Web mit einer Tabelle mit einer ComboBox in einer Spalte erzeugt das von Domino generierte HTML eine Tabelle für die Combobox, aber einen Bereich für andere Komponenten (derzeit getestet auf textFields und computedFields).
Dies wird dann mit einem Pixel der vertikalen Ausrichtung Unterschied gerendert, die mich ärgert.
Wie kann ich das überwinden?ComboBox generiert eine Tabelle anstelle von span in readmode web

<table> 
     <tbody> 
      <tr> 
       <td colspan="3"> 
        <table id="view:_id1:_id2:_id3:legend1:callbackFieldControlSet:CounterpartyName"> 
         <tbody> 
          <tr> 
           <td> 
            AVANZA SWEDEN 
           </td> 
          </tr> 
         </tbody> 
        </table> 
       </td> 
      </tr> 
      <tr> 
       <td> 
        <span id="view:_id1:_id2:_id3:legend1:callbackFieldControlSet:CounterpartyShort">AVANZA SWEDEN</span> 
       </td> 
      </tr> 
     </tbody> 
    </table> 

Im Bearbeitungsmodus ist der Unterschied immer noch da, aber die erzeugte HTML-Code der Combobox ist kein Tisch, sondern ein wählen und dann kann ich es mit CSS steuern.
Siehe Bild unten.

Beispiel Lesemodus
example read mode

Beispiel Bearbeitungsmodus (css bearbeitet):
example edit mode

<xp:table> 
     <xp:tr> 
      <xp:td> 
       <xp:label 
        value="Counterparty name:" 
        id="counterpartyName_Label1" 
        for="CounterpartyName" 
       > 
       </xp:label> 
      </xp:td> 
      <xp:td> 
       <xp:comboBox 
        id="CounterpartyName" 
        value="#{document1.CounterpartyName}" 
        required="true" 
       > 
       </xp:comboBox> 
      </xp:td> 
     </xp:tr> 
     <xp:tr> 
      <xp:td> 
       <xp:label 
        value="Counterparty short:" 
        id="counterpartyShort_Label1" 
        for="CounterpartyShort" 
       > 
       </xp:label> 
      </xp:td> 
      <xp:td> 
       <xp:inputText 
        value="#{document1.CounterpartyShort}" 
        id="CounterpartyShort" 
        required="true" 
        styleClass="xspInputFieldEditBox" 
       > 
       </xp:inputText> 
      </xp:td> 
     </xp:tr> 
     <xp:tr> 
      <xp:td> 
       <xp:label 
        value="Bic Code:" 
        id="bicCode_Label1" 
        for="BicCode" 
       > 
       </xp:label> 
      </xp:td> 
      <xp:td> 
       <xp:inputText 
        value="#{document1.BicCode}" 
        id="BicCode" 
        styleClass="xspInputFieldEditBox" 
       > 
       </xp:inputText> 
      </xp:td> 
     </xp:tr> 
    </xp:table> 
+0

Jeder dachte, Warum wird es als Tabelle gerendert? –

Antwort

6

Problem ist, dass die innere Tabelle der eigenen Grenzen hat (wie immer: eine für die Tabelle selbst und eine für die td), die zusammengelegt werden müssen. Erstellen Sie einfach einige CSS, um damit umzugehen:

  1. geben Sie Ihrer äußeren Tabelle eine eigene Stil-Klasse, z. "MyOuterTable"
  2. Ihre CSS würde adressieren dann jede Tabelle in ".myOuterTable", wie folgt aus:

    table.myOuterTable table {border-collapse: collapse;}

Dies funktioniert gut in beide bearbeiten und lesen Modus, weil nur im Lesemodus haben Sie diese extra "innere" Tabelle; btw im Bearbeitungsmodus, gibt es nichts zusammengebrochen werden ...

funktioniert auch in IE, ...

Hoffe, dass es für Sie

+0

Funktioniert gut, thx. Ich denke, IBM sollte es anders machen, obwohl –

+0

völlig zustimmen; auf der anderen Seite können wir nicht ausschließen, dass sie einen Grund hatten, es so zu lösen ... –

+0

In meinem Fall war der angezeigte Wert auch rechts daneben.Ich musste auch diese 'table.myOuterTable td {padding: 0;}' hinzufügen. –

1

3 mögliche Aktionen (in Abhängigkeit der Komplexität):

  • Schreiben Sie Ihre eigene Dropdown-Komponente
  • fügen Sie ein Textfeld hinzu. Verwenden Sie die Eigenschaft Visible zum Anzeigen/Verbergen nur eines auf Basis von Lese/Editiermodus
  • Verwendung CSS und Polsterung (können negative Werte annehmen) zu bewegen, um ein Pixel
+0

stimme zu, dass # 1 oder # 2 die "richtigen" Lösungen sein könnten, während mein Ansatz etwas Geschmack von css hack dazu hat. Ich weiß nie, ob das auf lange Sicht gut oder schlecht ist. –

+1

Eine weitere Ergänzung zu Ihrer Liste - Sie könnten Ihren eigenen benutzerdefinierten Renderer definieren. – Naveen

+0

Sie können keine negative Auffüllung haben, nur negative Ränder. Aber das war vielleicht das, was Stwissel sagen wollte. – jBoive

16

arbeitet Ich sehe Sie eine Antwort akzeptiert haben, aber ich vorschlage eine alternative Lösung, die einfach das generierte HTML eliminiert. Ich realisiere, dass dies eine langweilige Lösung sein kann :)

Ich hatte ein ähnliches Problem mit XPages generating tables for checkbox group. Tim Tripcony schlug mir vor, create a custom renderer die Ausgabe des Steuerelements zu ändern. Es ist zunächst ein wenig schwierig, aber sobald Sie einen Hang davon haben, macht es einen ziemlich guten Job.In Ihrem Fall von schreibgeschützten Felder, wäre es einfacher sein :)

1. Erstellen Sie eine benutzerdefinierte Renderer

Hier erstelle ich einen benutzerdefinierten Renderer Java-Klasse namens pkg.MyRenderer. Sie können diese Java-Datei in "Code> Java" erstellen. Hier gebe ich nur den ausgewählten Wert des Kombinationsfelds und sonst nichts aus.

package pkg; 

import java.io.IOException; 
import java.io.Writer; 
import javax.faces.component.UISelectOne; 
import javax.faces.component.UIComponent; 
import javax.faces.context.FacesContext; 
import javax.faces.render.Renderer; 

public class MyRenderer extends Renderer { 
    public void encodeBegin(FacesContext context, UIComponent component) throws IOException { 
     UISelectOne obj = (UISelectOne)component; 
     Writer writer = context.getResponseWriter(); 
     writer.write(obj.getValue().toString()); 
    } 

    public void encodeEnd(FacesContext context, UIComponent component) throws IOException { 
    } 
} 

2. Registrieren Sie Ihre benutzerdefinierten Renderer

Jetzt im Paket-Explorer gehen Sie auf "YourDatabase.nsf> WebContent> WEB-INF>faces-config.xml". Dort müssen Sie Ihren benutzerdefinierten Renderer registrieren. Sie müssen nur sicherstellen, dass der component-family der gleiche ist wie der, zu dem das Kombinationsfeld gehört.

<?xml version="1.0" encoding="UTF-8"?> 
<faces-config> 
    <render-kit> 
     <renderer> 
      <component-family>javax.faces.SelectOne</component-family> 
      <renderer-type>pkg.MyRendererType</renderer-type> 
      <renderer-class>pkg.MyRenderer</renderer-class> 
     </renderer> 
    </render-kit> 
</faces-config> 

3. Ordnen Sie Ihre benutzerdefinierten Renderer

zu steuern, wie Sie den benutzerdefinierten Renderer wollen nur aktiv sein, wenn es beim Lesen nur Modus ist sie es überprüfen und dann die rendererType der Kontrolle die renderer-type definiert in faces-config.xml dh pkg.MyRendererType.

Hier überprüfe ich, ob das Steuerelement comboBox1 im schreibgeschützten Modus ist, wenn ja, dann benutze pkg.MyRendererType sonst verwende den Renderer des Steuerelements.

<xp:comboBox id="comboBox1" .....> 
    <xp:this.rendererType><![CDATA[${javascript:var cb:com.ibm.xsp.component.xp.XspSelectOneMenu = getComponent("comboBox1"); 
cb.isReadonly() ? "pkg.MyRendererType" : cb.getRendererType();}]]></xp:this.rendererType> 
..... 
..... 
..... 
</xp:comboBox> 

Beschreibung Wenn Sie diese mit Kontrolle auf Nur-Lese-Modus wird nur der Wert des Kombinationsfeldes ist anders angezeigt und nichts (keine Tabellen, yay!). Und wenn das Steuerelement nicht im schreibgeschützten Modus ist, wird wie zuvor eine Dropdown-Liste angezeigt.

+0

Thx, das werde ich mir merken. Der Einfachheit halber bleibe ich bei der CSS-Lösung –

+1

@Naveen: das ist ein großartiges Beispiel; Ich war neugierig, wie man benutzerdefinierte Renderer verwendet. Vielen Dank! –

1

Dieser Code wird alle Comboboxen auf der Seite mit Dojo lösen, führen onClientLoad:

if("#{javascript:document1.isEditable()}" == "false"){ 
    // Search for all nested tables with ids 
    dojo.query('table td table[id]').forEach(function(node) { 
     var value = ''; 

     // Locate the first table cell, which contains the value 
     dojo.query('td:first-child', node).forEach(function(innerNode) { 
      value = innerNode.innerHTML; 
     }); 

     // Replace the table with only the value (or a blank) 
     node.outerHTML = value; 
    }); 
} 

Hinweise:

  • Aktualisieren Sie den Namen des Dokuments in Zeile 1 den Namen des Dokuments entsprechen Auf deiner Seite.
  • Dieser Code setzt voraus, dass Ihre Combobox bereits in einer Tabellenzelle verschachtelt ist. Wenn das nicht der Fall ist, können Sie den Selektor in Zeile verfeinern 3.
  • Wenn Sie in Konflikte mit diesen Auswirkungen auf andere Tabellen in Ihrer Seite ausführen, müssen Sie den Selektor in der Linie verfeinern 3.
Verwandte Themen