1

I've received the request to add AJAX functionality to an existing custom visual webpart in SP2013 (more precisely: partial refresh of the webpart after clicking a link inside the webpart without reloading the whole page).

I'm totally new to AJAX and came across the ASP.NET UpdatePanel.

But it's been said that the UpdatePanel doesn't work with SharePoint OTB causing a full postback. You should install/set a reference to the SharePoint Guidance libraries to use the SafeScriptManager. For example see this post refering to this MSDN article.

Is this approach still necessary for SP2013, in particular because there is no release of SharePoint Guidance for SP2013 (yet)? Or is there an easier approach to implement a "partial reload" in a custom webpart with the OTB api?

2
  • 2
    I've already used UpdatePanel in SharePoint 2010 custom web parts without having to install or configure anything, so I think you should be able to do it in SharePoint 2013 too. Commented Jan 9, 2014 at 15:38
  • Yes, it works perfectly with an OTB ASP.NET UpdatePanel. I'm just curious: Is the need to use a SafeScriptManager just an approach/best practice from the WSSv3 era that survived until today?
    – jcp
    Commented Jan 13, 2014 at 13:38

1 Answer 1

1

I recently worked on custom RSSViewer webpart. I had originally developed it on my SP 2013 VM. It used AJAX update panel and it worked without any issues. The code for the webpart is provided below:

using System;
using System.ComponentModel;
using System.ServiceModel.Syndication;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml;

namespace RSSFeedWebPart.RSSFeedWebPart
{
    [ToolboxItemAttribute(false)]
    public class RSSFeedWebPart : WebPart
    {
        UpdatePanel updatePanel;
        Timer timer;
        HtmlTable feedTable;
        private const int const_NumberOfFeedItems = 5;
        private const int const_RereshInterval = 30;
        private int _numberOfFeedItems = const_NumberOfFeedItems;
        private int _rereshInterval = const_RereshInterval;

        [WebBrowsable(true),  
        WebDisplayName("RSS feed url"),
        WebDescription("RSS feed url"),  
        Personalizable(PersonalizationScope.Shared),  
        Category("RSS Feed Custom Properties")]  
        public string RSSFeedUrl { get; set; }

        [WebBrowsable(true),
        WebDisplayName("Show publish date"),
        WebDescription("Show publish date"),
        Personalizable(PersonalizationScope.Shared),
        Category("RSS Feed Custom Properties")]
        public bool IsPublishDate { get; set; }

        [WebBrowsable(true),
        WebDisplayName("Open links in new window"),
        WebDescription("Open links in new window"),
        Personalizable(PersonalizationScope.Shared),
        Category("RSS Feed Custom Properties")]
        public bool IsOpenInNewWindow { get; set; }

        [WebBrowsable(true),
        WebDisplayName("Number of feed items"),
        WebDescription("Number of feed items"),
        Personalizable(PersonalizationScope.Shared),
        DefaultValue(const_NumberOfFeedItems),
        Category("RSS Feed Custom Properties")]
        public int NumberOfItems
        {
            get
            {
                return _numberOfFeedItems;
            }
            set
            {
                _numberOfFeedItems = value;
            }
        }

        [WebBrowsable(true),
        WebDisplayName("Feed refresh time (in minutes)"),
        WebDescription("Feed refresh time (in minutes)"),
        Personalizable(PersonalizationScope.Shared),
        DefaultValue(const_RereshInterval),
        Category("RSS Feed Custom Properties")]
        public int RereshInterval
        {
            get
            {
                return _rereshInterval;
            }
            set
            {
                _rereshInterval = value;
            }
        }

        [WebBrowsable(true),
        WebDisplayName("Feed title style"),
        WebDescription("Enter the optional css style. For example: font-weight:bold; color:red"),
        Personalizable(PersonalizationScope.Shared),
        Category("RSS Feed Custom Properties")]
        public string FeedTitleStyle { get; set; }

        [WebBrowsable(true),
        WebDisplayName("Item title style"),
        WebDescription("Enter the optional css style. For example: font-weight:bold; color:red"),
        Personalizable(PersonalizationScope.Shared),
        Category("RSS Feed Custom Properties")]
        public string ItemTitleStyle { get; set; }

        [WebBrowsable(true),
        WebDisplayName("Item publish date style"),
        WebDescription("Enter the optional css style. For example: font-weight:bold; color:red"),
        Personalizable(PersonalizationScope.Shared),
        Category("RSS Feed Custom Properties")]
        public string ItemPublishDateStyle { get; set; }

        [WebBrowsable(true),
        WebDisplayName("Item summary style"),
        WebDescription("Enter the optional css style. For example: font-weight:bold; color:red"),
        Personalizable(PersonalizationScope.Shared),
        Category("RSS Feed Custom Properties")]
        public string ItemSummaryStyle { get; set; }

        protected override void CreateChildControls()
        {
            feedTable = new HtmlTable();
            updatePanel = new UpdatePanel();
            updatePanel.ID = "updatePanel";
            timer = new Timer()
            {
                ID = "timer",
                Interval = RereshInterval * 60000,
            };
            timer.Tick += new EventHandler<EventArgs>(timer_Tick);
            this.Controls.Add(timer);
            updatePanel.Triggers.Add(new AsyncPostBackTrigger()
            {
                ControlID = timer.ID,
                EventName = "Tick"
            }
            );
            this.Controls.Add(updatePanel);
            this.Controls.Add(feedTable);                                  
        }

        protected override void OnPreRender(EventArgs e)
        {
            GetFeedData();
        }

        void timer_Tick(object sender, EventArgs e)
        {

        }

        private void GetFeedData()
        {
            try
            {
                feedTable.Border = 0;
                HtmlTableRow htmlrow;
                HtmlTableCell htmlcell;

                if (!string.IsNullOrEmpty(RSSFeedUrl))
                {
                    XmlReader reader = XmlReader.Create(RSSFeedUrl);
                    SyndicationFeed feed = SyndicationFeed.Load(reader);

                    // Add header row in HTML table
                    htmlrow = new HtmlTableRow();
                    htmlcell = new HtmlTableCell();
                    htmlcell.InnerHtml = feed.Title.Text;                    
                    htmlcell.Style.Value = FeedTitleStyle;
                    htmlrow.Cells.Add(htmlcell);
                    feedTable.Rows.Add(htmlrow);
                    int itemCount = 1;
                    foreach (SyndicationItem item in feed.Items)
                    {
                        if (itemCount <= NumberOfItems)
                        {
                            itemCount++;
                            htmlrow = new HtmlTableRow();
                            htmlcell = new HtmlTableCell();                            
                            htmlcell.Style.Value = ItemTitleStyle;
                            if (IsOpenInNewWindow)
                                htmlcell.InnerHtml = "<a href=" + item.Id + "  target=\"_blank\">" + item.Title.Text + "</a>";
                            else
                                htmlcell.InnerHtml = "<a href=" + item.Id + ">" + item.Title.Text + "</a>";  
                            htmlrow.Cells.Add(htmlcell);
                            feedTable.Rows.Add(htmlrow);
                            if (IsPublishDate)
                            {
                                htmlrow = new HtmlTableRow();
                                htmlcell = new HtmlTableCell();
                                htmlcell.InnerHtml = item.PublishDate.ToString();
                                htmlcell.Style.Value = ItemPublishDateStyle;
                                htmlrow.Cells.Add(htmlcell);
                                feedTable.Rows.Add(htmlrow);
                            }
                            htmlrow = new HtmlTableRow();
                            htmlcell = new HtmlTableCell();
                            htmlcell.InnerHtml = ((TextSyndicationContent)item.Summary).Text;
                            htmlcell.Style.Value = ItemSummaryStyle;
                            htmlrow.Cells.Add(htmlcell);
                            feedTable.Rows.Add(htmlrow);                           
                        }
                    }
                }

                updatePanel.ContentTemplateContainer.Controls.Add(feedTable);
            }
            catch (Exception ex)
            {
                // Log exception
            }
        }
    }
}

Perhaps this will help you in creating the custom webpart you want. For more information see my blog post:

http://sharepointnadeem.blogspot.in/2013/11/sharepoint-rss-viewer-webpart-for-wss.html

3
  • Did you check whether you webpart is not causing any trouble when using it together with the OOTB project summary webpart of SP2013? Because when I try your code I face the problem that the timeline of the project summary webpart is added another time each the timer is ticking so when a postback is performed.
    – André
    Commented Mar 4, 2014 at 19:47
  • Haven't checked that Commented Mar 5, 2014 at 3:32
  • Same problem of @André here
    – Ewerton
    Commented Oct 25, 2016 at 19:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.