2011-12-13 31 views
6

Tengo una página de Visualforce que utiliza un controlador personalizado que se utiliza para editar varios registros en una oportunidad.Botón personalizado o vínculo a una página de Visualforce con un controlador personalizado

Me gustaría crear un botón o enlace personalizado desde Oportunidades a esta página de Visualforce.

Actualmente el enlace parece:

/apex/ExamplePage?oppId={!Opportunity.Id} 

Esto funciona bien en el arenero de desarrollo, pero cuando se implementa como parte de un paquete conseguido el link se rompe como la referencia de página no tiene el prefijo de espacio de nombres .

Encontré la publicación Managed Package Redirecting Problem en los Foros de discusión de Force.com que implicaba que era posible usar $ Page para hacer referencia a la página de Visualforce en la URL. P.ej.

{!URLFOR($Page.MyExamplePage,'',[objectId = campaign.id])} 

Pero hacerlo sólo me da el error de sintaxis:

Error: Field $Page.MyExamplePage does not exist. Check spelling.

Hay otra parte que el post que sugiere el uso de una clase de Apex y ejecutar Javascript para trabajar alrededor de ella. Pero me parece que esto acaba de mover el problema del espacio de nombres al Javascript.

¿Cómo puedo hacer referencia de forma segura a la página de Visualforce para que funcione tanto dentro como fuera de un paquete administrado?

+1

Encontré [Botón personalizado: Exponer $ Page en el Tipo de contenido de URL] (https://sites.secure.force.com/success/ideaView?id=08730000000aVIfAAM) en IdeaExchange que sería bueno promocionar. –

Respuesta

7

Lo mejor es hacer esto desde un valor de retorno de PageReference de Apex. Algo como esto funcionará:

public PageReference returnPage() 
{ 
    return Page.MyExamplePage; 
} 

luego llamar a esto desde Visualforce:

<apex:commandButton value="Go To New Page" action="{!returnPage}"/> 

La llamada Apex página se encargará de la traducción para usted.

[EDIT]

Crear un esqueleto página Visualforce así:

<apex:page standardController="Opportunity" extensions="TheController" action="{!returnPage}"/> 

Añadir el método returnPage anterior() para un nuevo TheController (o lo que sea) de clase. Ni siquiera necesita un constructor. La clase puede tener este aspecto:

public TheController 
{ 
    public PageReference returnPage() 
    { 
     return Page.MyExamplePage; 
    } 
} 

Entonces, desde la página de configuración de la oportunidad ir a botones y enlaces y crear un nuevo encargo botón Visualforce la selección de la nueva página que acaba de crear.

Eso debería hacerlo.

+0

Necesito mostrar el enlace a la página de Visualforce desde la página estándar de Detalle de oportunidad. Con un botón de página de detalle personalizado, el usuario puede colocar este botón libremente usando el Editor de diseño de página. ¿Su sugerencia funcionará de manera similar a esto? Si mi comprensión es correcta, necesitaría un controlador personalizado para el método returnPage() y alguna forma de poner el CommandButton en la página de detalles de Oportunidades. –

+0

Se requerirá un controlador Apex personalizado. Siempre que haga referencia a standardController = "Opportunity" y extensions = "NewCustomController" en la definición de apex: page, estarás bien. Voy a modificar mi respuesta para adaptarse a su situación. Implica un pequeño truco cuando se lanza directamente desde una página de detalles de Oportunidad. – Adam

+0

Gracias, eso funciona. Crea un ligero rebote a medida que el usuario pasa por la página intermedia pero soluciona el problema de PageReference. Pude agregar parámetros adicionales a PageReference usando un constructor que tomó el ApexPages.StandardController como argumento. Mi única preocupación ahora es que he agregado una página adicional y una clase Apex para cada botón personalizado. –

0

El post sobre las placas de desarrollo que ha asociado a la muestra que se utiliza para el botón de la siguiente javascript:

{!REQUIRESCRIPT("/soap/ajax/15.0/connection.js")} 
{!REQUIRESCRIPT("/soap/ajax/15.0/apex.js")} 
var pageUrl = sforce.apex.execute("mynamespace.PageUrl", "getPageUrl", {objectId:"{!Campaign.Id}"}); 
window.location.href = pageUrl; 

es decir que están usando javascript para llamar a un método de servicio web en la clase ellos tienen definido para obtener la referencia de página. Hacer esto le permitiría obtener la URL de la página en apex, donde el paquete administrado no tendrá un impacto.

Dicho esto, el primer parámetro es el nombre completo de la clase, por lo que probablemente pueda verificar el valor de retorno de un error (no sé el valor de retorno del error, entonces supongo que es null aquí):

// try the namespace first 
var pageUrl = sforce.apex.execute("mynamespace.myClass", "getPageUrl", {objectId:"{!Campaign.Id}"}); 
if (pageUrl == null) 
{ 
    pageUrl = sforce.apex.execute("myClass", "getPageUrl", {objectId:"{!Campaign.Id}"}); 
} 

window.location.href = pageUrl; 

Obviamente es necesario comprobar qué sucede cuando sforce.apex.execute() falla, y es probable que quieren un poco más de control de errores.

+0

Gracias, esto es lo que estaba pensando. El problema con el espacio de nombres del paquete administrado se ha movido al Javascript y necesita ser manejado allí. Creo que intentaré esto y veré cómo funciona. –

0

Se me ocurrió que una opción menos que ideal sería crear dos botones personalizados en cada caso. Uno con el espacio de nombres del paquete administrado y otro sin él.

Al construir el paquete, se puede seleccionar el botón personalizado correcto.

Un problema con este enfoque es la necesidad de mantener dos botones personalizados.

+0

¿Cómo se codificaría la fórmula de URL del botón administrado? Estamos viendo que el host completo para nuestras páginas empaquetadas es diferente una vez instalado. Vemos algo como 'ourpackage.cs8.visual.force.com'! – Marc

+0

@Marc, fui con la solución basada en Apex, así que no necesitaba pensar en el dominio o el espacio de nombres del paquete administrado. –

0

Parece que la respuesta es simplemente /apex/package__Page según lo provisto here por @zachelrath. Puedo confirmar que esto funciona en paquetes administrados tanto en organizaciones de producción como en desarrollo.

Cuestiones relacionadas