I was about to write a blog about how to create this custom action but obviously someone did it before. Cheers to Bjørn Furuknaps who explains it well on his blog !
Useless to write another one but usefull to reference its blog !
12 years of work within the Sharepoint world : let's talk about technical and functional thoughts around Sharepoint.
Showing posts with label MOSS. Show all posts
Showing posts with label MOSS. Show all posts
Wednesday, June 10, 2009
Send a document by email (from a document library)
Wednesday, April 22, 2009
MOSS Administrator
I was bored of using tools for MOSS administration cause, on all of them, something was missing, so I decided to make mine...and so far I'm quite happy with the result.I have created a codeplex project for this one : http://mossadministration.codeplex.com/

Some screen shot (official version so far : 0.2). I hope to
I splitted the tool in three part : "Solutions" , "Features" and "Site hierarchy"
- Install solution
- Uninstall solution
- Deploy solutions
- Retract solution
- GetInformations on his farm and to get some information that the administration site doesn't give (information that you can also have using stsadm command lines..
The second one "Features"list everything about features :
- You can check basic information about your features. (order by scope)
- You can see on which element each of the feature is deployed (For instance, you can see all the sites on which you rfeature is deployed)
- A usefull functionnality is to be able to deploy a feature in a wider scope than the original scope (for example, deploying w site feature on all site of a webapplication (or even a farm!))
- You can activate Feature on One or some elements.
The third one is the big one :) It gives you, many information about your farm structure (from object ids, to content DBs for web apps, passing by activated feature listing...) and much much more. You can interact with object. For instance, you can set read or write lock mode.
Of course cause, it's a big thing, so far, not everything have been developped, but i work on it. I'll keep you informed.
The codeplex project for this : http://mossadministration.codeplex.com/Some screen shot (official version so far : 0.2). I hope to
- Features tab :
- WSP Solutions tab :
Tuesday, March 10, 2009
Replace a webpart by another
In My "problem of the day" list, I have been asked whether it was possible or not to replace a webpart by another programatically. And obviously I have been asked to set the property values for the news Webpart.... So, I made a small tool for that.
I have created a Codeplex for this : http://webpartreplacer.codeplex.com The next versions will be uploaded there soon !!!
Basically, How does it work? On a specific application, I try to load the assembly that contains the webparts (source and destination) using reflection :
Then I look inside the Default page of each web and subweb trying to find the webpart (by checking the type of each webparts on the page) and if I find it, I replace the webpart using the SPLimitedWebPartManager.
I know that I should also parse all the document libraries to find other webpart pages in order to parse them as well... But in my current project, it wasn't a need, and I was kind of lazy!
Below is the iteration how I check whether the webparts on the page are to be replaced.
This is the part 1 of the replacement. Now let's say that we want to go futher. Why not trying to specify some properties on this new webpart?
OK, I have created a ObjectCollection object containing a list of KeyValuePair (simply by taking the Items attribute of a listBox !
Then before the AddWebPart([...]) code line, I have added the following code :
What happens here? We just try to get The property we try to set contained in our newly instanced WebPart. If found, we try to Use the Parse method of this property (Yes this only work with simple types (as Int32, Bool, String), and then we invoke it! Simple!!
That's it. You just have to make an iteration on each SPSite of you application and here we are!
Once again, be aware that this code only checks the default.aspx page !!
Sorry for that!!
Go to check in the codeplex project.
I have created a Codeplex for this : http://webpartreplacer.codeplex.com The next versions will be uploaded there soon !!!
Basically, How does it work? On a specific application, I try to load the assembly that contains the webparts (source and destination) using reflection :
System.Reflection.Assembly asm = System.Reflection.Assembly.Load(AssemblySrc);
System.Web.UI.WebControls.WebParts.WebPart wpS = (System.Web.UI.WebControls.WebParts.WebPart) asm.CreateInstance(ClassSrc);
Then I look inside the Default page of each web and subweb trying to find the webpart (by checking the type of each webparts on the page) and if I find it, I replace the webpart using the SPLimitedWebPartManager.
I know that I should also parse all the document libraries to find other webpart pages in order to parse them as well... But in my current project, it wasn't a need, and I was kind of lazy!
Below is the iteration how I check whether the webparts on the page are to be replaced.
public void ReplaceWebpart(SPWeb web)
{
try
{
SPLimitedWebPartManager theMan =
web.Files["Default.aspx"].GetLimitedWebPartManager(System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);
System.Reflection.Assembly asm = System.Reflection.Assembly.Load(AssemblySrc);
System.Web.UI.WebControls.WebParts.WebPart wpS = (System.Web.UI.WebControls.WebParts.WebPart) asm.CreateInstance(ClassSrc);
System.Reflection.Assembly asmD = System.Reflection.Assembly.Load(AssemblyDest);
for (int i = 0; i < theMan.WebParts.Count; i++)
{
System.Web.UI.WebControls.WebParts.WebPart wp = theMan.WebParts[i];
if (wp.GetType().Equals(wpS.GetType()))
{
System.Web.UI.WebControls.WebParts.WebPart wpD = (System.Web.UI.WebControls.WebParts.WebPart)asmD.CreateInstance(ClassDest);
wpD.Title = wp.Title;
theMan.AddWebPart(wpD, theMan.GetZoneID(wp), wp.ZoneIndex);
theMan.WebParts[wpD.ID].
theMan.DeleteWebPart(wp);
Result++;
i--;
}
}
foreach (SPWeb Sweb in web.Webs)
{
ReplaceWebpart(Sweb);
Sweb.Dispose();
}
}
catch (Exception ex)
{
}
finally
{
}
}
OK, I have created a ObjectCollection object containing a list of KeyValuePair
Then before the AddWebPart([...]) code line, I have added the following code :
foreach (Object LstItem in PropCollection)
{
try
{
System.Reflection.PropertyInfo prop = wpD.GetType().GetProperty(((KeyValuePair<String, String>)LstItem).Key);
if (prop != null)
{
String[] propValues = new String[1] { ((KeyValuePair<String, String>)LstItem).Value };
if (prop.PropertyType.Equals(String.Empty.GetType()))
{
prop.SetValue(wpD,((KeyValuePair<String, String>)LstItem).Value,null);
}
else
{
Type[] types = new Type[1] { String.Empty.GetType() };
prop.SetValue(wpD, prop.PropertyType.GetMethod("Parse", types, null).Invoke(prop, propValues), null);
}
}
}
catch (Exception exceptionProp)
{}
}
What happens here? We just try to get The property we try to set contained in our newly instanced WebPart. If found, we try to Use the Parse method of this property (Yes this only work with simple types (as Int32, Bool, String), and then we invoke it! Simple!!
That's it. You just have to make an iteration on each SPSite of you application and here we are!
Once again, be aware that this code only checks the default.aspx page !!
Sorry for that!!
Go to check in the codeplex project.
Labels:
add webparts programmatically,
MOSS,
Tool,
webpart replacement,
Webparts
Wednesday, February 25, 2009
Dynamically creat a SPView with checkbox that will be display in a dynamically created ListViewe
Hi,
My problem was this one :
"I need to display on a specific page the default view of a list, BUT beside each items of this list must be displayed a checkbox in order to be able to select items on this list"
huuu....
The solution I chose was to recreate a clone of the defaultview that will never be displayed to the users but that will be selected as SPView of the ListView I create on my page.
Here we go...
1/ My Page takes in parameter the ID of the list I'm working on, i call the parameter "List":
Now, let me explain the code a little bit.
1/ How to create a column Checkbox in a list?
It's quite tricky cause you must create the column using a CAML definition.
Sorry for the "+" but it's for my code lisibility! In fact you just create a field where the display is an HTML input component !!
2/ OK, but now, i have the display How do I get my checkboxes values after postback ?
Well, let's continue to be tricky!! I just create two Hidden field on my page
And on my validation button i fill it before validation using a JS function called fill_ids
The js function simply puts inside the listSrv_Items the ids of each item in the list, and checked_ids will finally contain the list of items ids that are checked.
here we go for the js that i manually add to the page in the render method:
Now my field checked_Ids will contain the ids of my checked items so in my Btn_valid_Click; i just have to use it to do anything I want! That's it!
My problem was this one :
"I need to display on a specific page the default view of a list, BUT beside each items of this list must be displayed a checkbox in order to be able to select items on this list"
huuu....
The solution I chose was to recreate a clone of the defaultview that will never be displayed to the users but that will be selected as SPView of the ListView I create on my page.
Here we go...
1/ My Page takes in parameter the ID of the list I'm working on, i call the parameter "List":
Guid ListId = new Guid(this.Page.Request["List"]);2/ Then whenever I reach the page, i check whether the view already exists, if not i create it cloning the default view and adding to it a checbox field. If the clone of the actual defaultview exists i just use it! Easy! In my code below, the listview object is called Select_List
bool creatingView = false;
SPView newView = null;
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite Mysite = new SPSite(siteID))
{
SPWeb MyWeb = Mysite.OpenWeb(webID);
MyWeb.AllowUnsafeUpdates = true;
SPList MyList = MyWeb.Lists[ListId];
foreach (SPView view in MyList.Views)
{
if (view.Title.Equals(MyList.DefaultView.Title+ "_CloneForSelect"))
{
newView = view;
}
}
if (newView == null)
{
if (!MyList.Fields.ContainsField("Select"))
{
MyList.Fields.AddFieldAsXml("<Field Type=\"Computed\" ReadOnly=\"TRUE\" Name=\"ListItemSelection\" DisplayName=\"Select\" Sortable=\"FALSE\" Filterable=\"FALSE\" EnableLookup=\"FALSE\" SourceID=\"http://schemas.microsoft.com/sharepoint/v3\" StaticName=\"ListItemSelection\">" +"<FieldRefs> <FieldRef Name=\"ID\" /> </FieldRefs>" + "<DisplayPattern> <HTML><![CDATA[<input id=\"chk_select]]></HTML><Column Name=\"ID\" HTMLEncode=\"TRUE\" /><HTML><![CDATA[\" name=\"chk_select\" type=\"checkbox\" ]]></HTML>" + "<HTML><![CDATA[LItemId=\"]]></HTML>" + "<Column Name=\"ID\" HTMLEncode=\"TRUE\" />" + "<HTML><![CDATA[\"/> ]]></HTML>" + "</DisplayPattern></Field>");
}
SPFieldComputed fieldComp = (SPFieldComputed)MyList.Fields["Select"];
newView = MyList.DefaultView.Clone(MyList.DefaultView.Title + "_CloneForSelect", 1000, true, false);
newView.Hidden = true;
newView.Scope = SPViewScope.FilesOnly;
newView.ViewFields.Add(fieldComp);
newView.Update();
creatingView = true;
}
MyWeb.Dispose();
}
});
if (!creatingView)
{
Select_List.ViewId = newView.ID.ToString();
}
else
{
Response.Write("");
}
Select_List.ListId = this.Page.Request["List"];
1/ How to create a column Checkbox in a list?
It's quite tricky cause you must create the column using a CAML definition.
if (!MyList.Fields.ContainsField("Select"))
{
MyList.Fields.AddFieldAsXml("<Field Type=\"Computed\" ReadOnly=\"TRUE\" Name=\"ListItemSelection\" DisplayName=\"Select\" Sortable=\"FALSE\" Filterable=\"FALSE\" EnableLookup=\"FALSE\" SourceID=\"http://schemas.microsoft.com/sharepoint/v3\" StaticName=\"ListItemSelection\">" +"<FieldRefs> <FieldRef Name=\"ID\" /> </FieldRefs>" +
"<DisplayPattern> <HTML><![CDATA[<input id=\"chk_select]]></HTML><Column Name=\"ID\" HTMLEncode=\"TRUE\" /><HTML><![CDATA[\"
name=\"chk_select\" type=\"checkbox\" ]]></HTML>" +
"<HTML><![CDATA[LItemId=\"]]></HTML>" +
"<Column Name=\"ID\" HTMLEncode=\"TRUE\" />" +
"<HTML><![CDATA[\"/> ]]></HTML>" + "</DisplayPattern></Field>");
}
2/ OK, but now, i have the display How do I get my checkboxes values after postback ?
Well, let's continue to be tricky!! I just create two Hidden field on my page
<asp:HiddenField runat="server" id="listSrv_items" />
<asp:HiddenField runat="server" id="checked_ids" />
<asp:Button ID="Btn_valid" OnClientClick="fill_ids();" OnClick="Btn_valid_Click" runat="server"/>
here we go for the js that i manually add to the page in the render method:
protected override void Render(HtmlTextWriter writer)
{
this.ClientScript.RegisterClientScriptBlock(this.GetType(), "MyScript", @"
<script>
function fill_ids()
{
var items= document.getElementById('" + listSrv_items.ClientID + @"').value;
var checkedIds= document.getElementById('" + checked_ids.ClientID + @"');
checkedIds.value='';
var SParray = items.split(';');
for (ix=0; ix< SParray.length-1; ix++)
{
var item = document.getElementById(""chk_select""+SParray[ix])
if (item!=null && item.checked)
{
checkedIds.value += SParray[ix] + ';';
}
}
if (checkedIds.value.length>0)
checkedIds.value = checkedIds.value.substr(0,checkedIds.value.length-1);
}
</script>");
listSrv_items.Value = "";
foreach (SPListItem item in _rootList.Items)
{
listSrv_items.Value += item.ID + ";";
}
}
Subscribe to:
Posts (Atom)