Social Icons

twitter google plus linkedin rss feed

Pages

Showing posts with label WSS. Show all posts
Showing posts with label WSS. Show all posts

5.4.12

Hiding Edit in Datasheet in the Actions Menu with javascript code

Coming back after all this time to write such an ugly post? That’s exactly my style…
Well, the title of the post explains very well what was the objective and everybody knows that this is not the best way, but editing the permissions was causing issues somewhere else so we decided to do this.
This is the enemy:
Edit in Datasheet
And in order to hide it we added a Content Editor Web Part and then clicked in the Source Editor Button:
Content Editor Web Part Source Editor
There we added this script:
<script type="text/javascript" >
var allMenuItems = document.getElementsByTagName('ie:menuitem'); 
for(var i = 0; i < allMenuItems.length; i++ )   
{
 try
        {
         if (allMenuItems[i].text.toLowerCase() == "edit in datasheet")
         {
   var parentNodeOfMenuItem = allMenuItems[i].parentNode;  
                 parentNodeOfMenuItem.removeChild(allMenuItems[i]);                                
  }
 }
 catch(err)
 {}

} 
</script>

It could look a bit weird, but SharePoint won’t mind. Then we should click Save.
CEWP Source Editor Window
After that, in the Appearance group of the web part we could change the parameter Chrome Type to “None” (Or Layout –> Hidden) to make the CEWP invisible to the users.
And that’s all.
Edit in Datasheet Hidden
Enjoy!

No comments:

Post a Comment

14.2.12

Extension Methods for Null Objects

Is it possible to use an extension method on something that is null?

How beautiful would it be to do something like:
if (!MyString.IsNull()) return MyString.ToString();
I read somewhere a couple of years ago that would be impossible because if the object was null you’d not be allowed to call the method or something like that… But in my head it makes perfect sense.

So I have been refraining myself of doing this for a long time but today I felt brave enough.

The Method Extensions:
public static bool IsNull(this string str)
{
    return str == null;
}

public static string ToStringSafe(this object obj)
{
    return (obj ?? string.Empty).ToString();
}
The main method obviously every good test program should be a console application:
static void Main(string[] args)
{
    string str = null;

    if (str.IsNull())
        Console.WriteLine("It was null...");
    else
        Console.WriteLine("It wasn't null...");

    Console.WriteLine(str.ToStringSafe());

    Console.ReadKey();
}
And it works! This just opens a new dimension to my spaghetti recipes.

The first useful example that comes to my mind apart from the ToStringSafe and ToInt, ToDateTime... Look at me, I can't stop! is:

/// 
/// Disposes the object if it's not null.
/// 
public static void DisposeSafe(this IDisposable DisposableObject)
{
    if (DisposableObject != null)
        DisposableObject.Dispose();
}
With this method I won’t have to worry if the object is null or not. Everything is disposed properly!

It frightens me sometimes to get so excited about this things…

No comments:

Post a Comment

8.9.11

Filter Provider Web Part with a Silverlight Tree in a ModalDialog window

I started with this a couple of days ago… I didn’t want to do it, because I knew it was going to be painful… But they made me… An then I thought it would be a perfect post for the blog because of the painful.
What we wanted to achieve was to filter the items in a List View Web Part by Entity. We have an entity hierarchy, so we thought it would be a good idea to have a web part showing the hierarchy as a tree.

Alright so we need web part with a TreeView that is able to send the selected entity as a filter to a LVWP. Great. I built it… And no-one liked it. They wanted it to be Silverlight, and not only that, they wanted it to be in a pop up window. Yes, they got me. I have never done anything like that. But hey, where’s your spirit of adventure?

It is a lot of code, most of it ugly. So I’ll only post the most tricky parts (basically the parts related to the communication of the pages and the Silverlight) and the URL’s from where I got the ideas.

The firs thing is to get a proper Filter Provider Web Part working. To do so, I followed the instructions from here. My first try was with IWebPartRow, but it wasn’t what I was looking for, so I went for ITransformableFilterValues. It’s pretty straightforward so I won’t comment anything here.
The second thing is to create the PopUp Window. After googling a while I found this post a good point to start. My code in the web part ended like this:
        protected override void OnLoad(EventArgs e)
        {
            if (Page.IsPostBack)
            {
                if (!string.IsNullOrEmpty(GetFormValue("HiddenEntityName")))
                {
                    Page.Session["SelectedEntityName"] = Page.Request.Form["HiddenEntityName"];
                    Page.Session["SelectedEntityID"] = Page.Request.Form["HiddenEntityID"];

                    RenderHeader();

                    //SelectedEntityText.Text = string.Format("{0}  ", Page.Request.Form["HiddenEntityName"], Page.Request.Form["HiddenEntityID"]);
                }
                else
                    RenderHeader();
            }

            string CurrentWeb = SPContext.Current.Web.Url;
            string height = "500";
            string width = "500";
            string page = "/_layouts/stratex/EntityTree.aspx";

            // use next line for direct with  between  and  
            string scrp = @"
                            ";

            Type t = this.GetType();
            if (!Page.ClientScript.IsClientScriptBlockRegistered(t, "bindWebserviceToAutocomplete"))
                Page.ClientScript.RegisterClientScriptBlock(t, "bindWebserviceToAutocomplete", scrp);
        }

I had problems retrieving the values from the ModalDialog. I was not able to find the controls in the web part because the IDs and the Titles of the were being dynamically. The trick I used to fix this was to create two hidden fields in the CreateChildControls:
        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            ...

            Page.ClientScript.RegisterHiddenField("HiddenEntityName", "");
            Page.ClientScript.RegisterHiddenField("HiddenEntityID", "");

            ...
        }

Hey Chan, have you noticed that you could use the session and forget about the HiddenFields? Don’t ask. I’m warning you…

The next part is to get the new aspx page for the modal dialog. I created a new directory in the layouts folder and created my page there. It looks like this:
<%@ Page Language="C#" Inherits="StratExFramework.EntityTree,StratExFramework,Version=2.2.0.0,Culture=neutral,PublicKeyToken=311246df7412ca98" %>

<html>
<head>
<title>Select Entity for filtering</title>
<script type='text/javascript'>
    function PassParameterAndClose(EntityName, EntityID) {

        window.returnValue = new Array( EntityName, EntityID) ;

        var version = parseFloat(navigator.appVersion.split('MSIE')[1]);
        if (version >= 7) 
            { window.open('', '_parent', ''); }
        else
            { window.opener = self; }

        window.close();
    }
</script>
</head>
<body></body>
</html>

I have also created a code behind class as you can see in the first line of the aspx… :
    public class EntityTree : WebPartPage
    {
        string CurrentWeb;
        string SelectedEntityID;

        protected void Page_Load(object sender, System.EventArgs e)
        {
            CurrentWeb = Request.Params["CurrentWeb"];
            SelectedEntityID = Request.Params["SelectedEntityID"];
        }

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

            string Source = CurrentWeb + "/Lists/XAPLibrary/SilverlightEntityTreeSelector.xap";
            string SilverlightHeight = "515";
            string SilverlightWidth = "500";

            LiteralControl obj = new LiteralControl();
            obj.Text = "<object id='silverlightHost' style='height: " + SilverlightHeight + "; width: " + SilverlightWidth + @"; margin: 0; padding: 0;' data='data:application/x-silverlight-2,' type='application/x-silverlight-2'>
                            <param name='Source' value='" + Source + @"' />
                            <param name='MinRuntimeVersion' value='3.0.40624.0' />
                            <param name='Background' value='#FFFFFFFF' />
                            <param name='initParams' value='" +
                                string.Format("{0}={1}", "site", HttpUtility.UrlEncode(CurrentWeb)) +
                                string.Format(", {0}={1}", "selectedentityid", HttpUtility.UrlEncode(SelectedEntityID)) +
                                @"' />
                            </object>";
            this.Controls.Add(obj);
        }

        public override void VerifyRenderingInServerForm(Control control)
        {
            return;
        }
    }

What I am doing here is getting the parameters and passing them to the Silverlight. I use the CurrentWeb to tell the web services I use in the Silverlight what’s the context and the SelectedEntityID to highlight the previously selected Entity in case it’s not null. This is the code of the Silverlight:
namespace SilverlightEntityTreeSelector
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();

            Tree.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(Tree_PropertyChanged);

            Tree.Show(string.Empty);
        }

        void Tree_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "SelectedEntityID")
                HtmlPage.Window.Invoke("PassParameterAndClose", Tree.SelectedEntityName, Tree.SelectedEntityID);
            else if (e.PropertyName == "TreeLoaded")
                if (Application.Current.Resources.Contains("selectedentityid"))
                    if (!string.IsNullOrEmpty(Application.Current.Resources["selectedentityid"] as string))
                        Tree.ChangeSelectedItemTo(Application.Current.Resources["selectedentityid"] as string);
        }
    }
}

Now we have all the components.

The way it works is: You chose an entity in the Silverlight tree, then the Silverlight calls the javascript function in the modal window that returns the parameters to the parent web part window and closes the ModalDialog. And then the web part sends the filter to the List View Web Part.


If you try to use this code you’ll be missing some methods, but what I wanted to share here is the solution I've used mainly because I don’t want to think about this again if I’m asked to do something similar in the future.



I would love to share some pics but the web parts haven’t been retouched by the skilled hand of Adam, our designer, and your eyes could pop out of their sockets.

No comments:

Post a Comment

11.7.11

HTTP 500 (No authority could be contacted for authentication.) in SharePoint

I was getting an HTTP error 500 after restoring my SharePoint development server in a different network (at home). The thing was a bit curious because I could see the SharePoint site from the virtual server, but not from my physical server and yes, I checked the IPs and they were OK. The first thing I did was to configure the IE9 to show me the HTTP errors the way I like them, the “unfriendly” way.

To do so I went to Tools –> Internet Options –> Advanced, and there in the tree below Browsing I unchecked the “Show friendly HTTP error messages”.

After that I could see that the problem I was having when connecting from outside was “No authority could be contacted for authentication.” Here I saw that the easiest way to fix the problem was to remove the server from the domain and then add it again.

And it worked... Finally…

No comments:

Post a Comment

8.7.11

Hiding List View web parts when they are empty

Today I have been required to hide the List View web parts of the solution when they are empty… Even though I don’t like javascript, it was the obvious way to go so I asked Google and it sent me to this post.

I copied the code to a Content Editor Web Part and it worked more or less, but when I tried to hide the column headers and adding a message instead it was only working for two of my the three listview web parts in the page… After a bit more of googling I changed it to:

<script type="text/javascript">
 function HideEmptyWebParts()
 {
   var itemsfound = new Array;
   var elements = document.getElementsByTagName('*');
   for(var i=0;i<elements.length;i++)
   {
      if(elements[i].className == 'ms-vb')
      {
         itemsfound.push(elements[i]);
      }
   }
  
   for (var i=0;i<itemsfound.length;i++)
   {
       if (itemsfound[i].innerHTML.indexOf("There are no items to show in this view of the")>-1)
       {
                itemsfound[i].parentNode.parentNode.parentNode.parentNode.innerHTML="<div class='ms-vb'>Not enough data to produce a dashboard.</div>";
         
       }
   }
 }

_spBodyOnLoadFunctionNames.push("HideEmptyWebParts")
 
</script>

And after that it worked as expected.

No comments:

Post a Comment

1.2.11

Not SharePoint nor SQL Servers are working on the Azure VM Role

As you know, if you read me, I have been trying to be accepted in the Azure VM Role beta program, well, I have finally got a meeting with the guys that could grant me access and they've asked me the most feared question... What do you want it for?

My idea was to set up a farm in the cloud with SQL and SharePoint so I could use SSIS, our BI cube, Reporting services and SharePoint.

Well, this Microsoft guys say that "At the moment that's impossible"... Looks like there are connectivity problems between the machines in VM Role so not SharePoint nor SQL are working properly.

The advice they have for me is to set everything up on Office 365. But, what happens to my BI cube and my reporting services if I can't use web services from the Office 365's sandbox? Hmmm they won't work, so I'll just have half of my solution working and the other half sadly forgotten in the recesses of my hard disk.

The solution they provide... wait until summer.

I'll try to convince my boss to give me six months off, but if this doesn't work I am going to be forced to look for another place to set up my farm on.

Oh and, in case someone doubts it, I wasn't granted the access to the beta program.

And in the meantime Google is giving away laptops for the developers to test their new Chrome OS...

No comments:

Post a Comment

3.12.10

Copying ListViewWebparts between sites with their own custom views

In a new example of what I call "Guerrilla Coding" I had a couple of hours to develop a little program to copy hundreds of webpart pages full of ListViewWebparts, each one with its own custom view. I don't know if you feel the same, but I start to tremble every time I have to touch anything related to the ListViewWebpart

The ListViewWebparts create in the parent list a hidden view when we customize their view. This means that if you want to copy the webparts to a new site you'll have to copy the views from the parent list to its destination equivalent, I don't think I'm explaining my point well... I'd better paste the code...

What I do in this code snippet is copying the webparts from every origin file to the destination one giving them a special treatment if they are LisvViewWebpart which is enough for the application I need.

private static void CopyWebParts(SPFile origFile, SPFile destFile)
        {
            SPLimitedWebPartManager origWpm = origFile.GetLimitedWebPartManager(PersonalizationScope.Shared);
            SPLimitedWebPartManager destWpm = destFile.GetLimitedWebPartManager(PersonalizationScope.Shared);

            DeleteWebparts(destWpm);

            foreach (Microsoft.SharePoint.WebPartPages.WebPart webpart in origWpm.WebParts)
            {
                Microsoft.SharePoint.WebPartPages.WebPart newWp;

                if (webpart is ListViewWebPart)
                    newWp = UpdateListViewWebPart(webpart as ListViewWebPart, origFile.GetWeb(), destFile.GetWeb());
                else
                    newWp = webpart;

                destWpm.AddWebPart(newWp, Common.ConvertToString(newWp.ZoneID), newWp.ZoneIndex);
            }

            try
            {
                destFile.Publish("Added Web Parts");
                destFile.Approve("Web Part additions approved");
            }
            catch { }
        }

        private static ListViewWebPart UpdateListViewWebPart(ListViewWebPart webpart, SPWeb origWeb, SPWeb destWeb)
        {
            ListViewWebPart newWebPart = webpart; //yeah I know.

            string oldListName = webpart.ListName;
            string oldViewGuid = webpart.ViewGuid;

            SPList OrigList = origWeb.Lists.GetList(new Guid(oldListName), true);
            
            SPList DestList = destWeb.Lists[OrigList.Title];

            SPView OrigView = OrigList.GetView(new Guid(oldViewGuid));
            SPView DestView = DestList.Views.Add(string.Empty, OrigView.ViewFields.ToStringCollection(), OrigView.Query,
                OrigView.RowLimit, OrigView.Paged, OrigView.DefaultView);
            DestView.Hidden = OrigView.Hidden;
            DestView.Scope = OrigView.Scope;
            DestView.ApplyStyle(destWeb.ViewStyles.StyleByID(Convert.ToInt32(OrigView.StyleID)));

            DestView.Update();

            newWebPart.ViewGuid = DestView.ID.ToString("B").ToUpper();
            newWebPart.ListName = destWeb.Lists[OrigList.Title].ID.ToString("B").ToUpper();


            return newWebPart;
        }
And against all odds it worked, I hope I don't have to deal with this webparts for a while.

No comments:

Post a Comment

17.9.10

Lambdas, Method Extensions and RunWithElevatedPrivileges

Nowadays it's not a problem for anyone to create a new site as an administrator regardless of the loged user, but I'd like to suggest a function that seems useful to me:
/// 
        /// Returns a NEW site with full permissions
        /// 
        public static SPSite OpenSiteWithElevatedPrivileges(this SPSite site)
        {
            SPSite newSite = null;

            SPSecurity.RunWithElevatedPrivileges(() => newSite = new SPSite(site.ID));

            return newSite;
        }
Looks easy, doesn't it? I like doing
SPSite site = SPContext.Current.Site.OpenSiteWithElevatedPrivileges();
What do you think?

No comments:

Post a Comment