jueves, 29 de abril de 2010

Popup para seleccionar lista

Alguna vez nos hemos preguntado como mostrar una propiedad que nos permita seleccionar una lista dentro de la site collection, de la misma forma que hace la content query webpart "CQWP". El siguiente post intentará mostrar como hacer esto:

Lo primero que se ha hecho es crear un editor part que carga un user control, este user control tendría que tener un textbox para añadir la url de la lista, y un botón que llame a un javascript, en nuestro caso "launchpicker" que nos permita mostrar el popup.



var lastSelectedListSmtPickerId = '';

function launchPicker(id) {

if (!document.getElementById) return;

var listurlfield = document.getElementById(id);
var defaulturl = '<%=SPContext.Current.Web.ServerRelativeUrl %>';

var url = defaulturl;

if (listurlfield != null && listurlfield.value != '') {
url = listurlfield.value.substring(0, listurlfield.value.lastIndexOf('/'));
}

var callback = function(results) {
if (results == null || results == undefined || results[1] == null || results[2] == null) return;

lastSelectedListSmtPickerId = results[0];
var listUrl = '/';
if (results[1].charAt(0) == '/') results[1] = results[1].substring(1);
listUrl = listUrl + results[1];
if (listUrl.substring(listUrl.length - 1) != '/') listUrl = listUrl + '/';
if (results[2].charAt(0) == '/') results[2] = results[2].substring(1);
listUrl = listUrl + results[2];
listurlfield.value = listUrl;
};

LaunchPickerTreeDialog('CbqPickerSelectListTitle', 'CbqPickerSelectListTitle', 'listsOnly', '', url, lastSelectedListSmtPickerId, '', '', '/_layouts/images/smt_icon.gif', '', callback);
}



Luego nuestra editor part tendría que cargar dinámicamente este user control que hemos creado, además ha de implementar los métodos Synchanges, de donde obtendremos el valor actual configurado en la webpart y el método ApplyChanges donde haremos un set de la propiedad de la webpart.



public class FooEditorPart: EditorPart
{
#region Fields

protected GetListUserControl editorUC;

#endregion

#region Constructor

public FooEditorPart(string webpartid)
{
this.ID = "FooEditorPart" + webpartid;
this.Title = "Link Editor";
}

#endregion

#region Overriden Methods

///
/// Create the controls
///

protected override void CreateChildControls()
{
base.CreateChildControls();

try
{
editorUC = (GetListUserControl)this.Page.LoadControl("~/_CONTROLTEMPLATES/GetListUserControl.ascx");

Controls.Add(editorUC);
}
catch (Exception ex)
{
LogHelper(ex)
}
}

///
/// Get the value from webpart
///

public override void SyncChanges()
{
EnsureChildControls();

WebpartFoo webPart = WebPartToEdit as WebpartFoo;
if (webPart != null)
{
editorUC.TbListUrl.Text = webPart.LinkList;
}
}

///
/// ApplyChanges in webpart
///

///
public override bool ApplyChanges()
{
EnsureChildControls();
WebpartFoo webPart = WebPartToEdit as WebpartFoo;
if (webPart != null)
{
webPart.LinkList= editorUC.TbListUrl.Text;
}
return true;
}

#endregion
}



Por último nuestra webpart tendrá que tener una propiedad string con el atributo WebBrowsable(false), y tendrá que implementar la interfaz IWebEditable, esto nos obliga a implementar el método CreateEditorParts, donde añadiremos nuestro nuevo editor part, y la propiedad WebBrowsableObject.



public class WebpartFoo: WebPart, IWebEditable
{
#region Properties

[Personalizable(PersonalizationScope.Shared)]
[WebBrowsable(false)]
public string LinkList { get; set; }

#endregion

#region Default Constructor
public WebpartFoo()
{
ExportMode = WebPartExportMode.All;
}

#endregion


#region IWebEditable Members

EditorPartCollection IWebEditable.CreateEditorParts()
{
List editors = new List();

// Add the base editor parts
EditorPartCollection baseParts = base.CreateEditorParts();
foreach (EditorPart basePart in baseParts)
editors.Add(basePart);

editors.Add(new FooEditorPart(this.ID));
return new EditorPartCollection(editors);
}

object IWebEditable.WebBrowsableObject
{
get { return this; }
}

#endregion

}



A partir de aquí ya podriamos usar nuestra lista seleccionada, cómo curiosidad, remarcar que el popup al obtener la url de la lista no le añade el /Lists ni la url correcta de la lista, sino que le añade el title de la lista, por lo que para poder desde codigo obtener la lista podriamos hacer algo como lo siguiente:



private void foo()
{
if (!String.IsNullOrEmpty(LinkList))
{
string UrlWeb = LinkList.Substring(0, LinkList.LastIndexOf("/"));
string ListName = LinkList.Substring(LinkList.LastIndexOf("/") + 1);

using (SPWeb web = SPContext.Current.Site.OpenWeb(UrlWeb))
{
SPList list = web.Lists[ListName];

// TODO
}
}
}

No hay comentarios: