Showing posts with label Javascript. Show all posts
Showing posts with label Javascript. Show all posts

Wednesday, August 13, 2014

[KnockOut.js]Sample code to for beginners.

Goal

The blog is to create a working form using KnockOut.js, generic handler(ashx) and JQuery. This is strictly for beginners, who want to use KnockOut.js. I am not giving any solution in this blog, this is just a starting thread for the people who are still having trouble using KnockOut.

Steps

  1. Create a visual studio project. I have named the solution as Sample and project name is Sample.KnockOut.
  2. Tools > NuGet Package Manager > Package Manager Console > Run "Install-Package knockoutjs" (CLICK HERE)
  3. Tools > NuGet Package Manager > Package Manager Console > Run "Install-Package jQuery" (CLICK HERE)
  4. Add the files which are shown in the Solution Explorer image below and use the code which is mentioned in the blog.


OrderHandler.ashx.cs

#region System

using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.SessionState;
#endregion

namespace Sample.KnockOut.Ajax
{
    /// <summary>
    /// OrderHandler.ashx - Just processes data coming from default.aspx.
    /// </summary>
    public class OrderHandler : IHttpHandler, IRequiresSessionState
    {
        #region Properties

        /// <summary>
        /// Is Reusable
        /// </summary>
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        /// <summary>
        /// Http Context
        /// </summary>
        private HttpContext Context { get; set; }

        /// <summary>
        /// Sample Entity List
        /// </summary>
        private IList<Entity.Order> OrderList
        {
            get
            {
                if (Context.Session["OrderList"] == null)
                {
                    Context.Session["OrderList"] = new List<Entity.Order>();
                }
                return (List<Entity.Order>)Context.Session["OrderList"];
            }
            set { Context.Session["OrderList"] = value; }
        }

        #endregion

        #region Process Request

        /// <summary>
        /// Process Request
        /// </summary>
        /// <param name="context"></param>
        public void ProcessRequest(HttpContext context)
        {
            // Set the context 
            Context = context;

            // Action which is passed to get the 
            var action = (context.Request["Process"] ?? string.Empty);

            // Check for action and settings
            switch (action)
            {
                case "GetOrder":
                    {
                        GetOrder();
                    }
                    break;
                case "AddUpdateItem":
                    {
                        AddUpdateItem();
                    }
                    break;
                case "DeleteOrder":
                    {
                        DeleteItem();
                    }
                    break;
                case "GetList":
                default:
                    {
                        GetList();
                    }
                    break;
            }
        }

        #endregion

        #region Actions

        /// <summary>
        /// Get List : Gets the list of 
        /// </summary>
        private void GetList()
        {
            // Sample Entity List
            OrderList = OrderList.OrderBy(a => a.OrderId).ToList();

            // Response the settings
            Context.Response.ContentType = "application/json";
            Context.Response.ContentEncoding = Encoding.UTF8;
            Context.Response.Write(new JavaScriptSerializer().Serialize(OrderList));
        }

        /// <summary>
        /// Get Order By Order Id
        /// </summary>
        private void GetOrder()
        {
            // Remove the item
            var orderId = Convert.ToInt32(Context.Request.Params["OrderId"] ?? "0");

            // Sample Entity List
            var order = OrderList.FirstOrDefault(a => a.OrderId == orderId);

            // Response the settings
            Context.Response.ContentType = "application/json";
            Context.Response.ContentEncoding = Encoding.UTF8;
            Context.Response.Write(new JavaScriptSerializer().Serialize(order));
        }

        /// <summary>
        /// Add/Update Item
        /// </summary>
        private void AddUpdateItem()
        {
            // Get the request
            var request = (new JavaScriptSerializer()).Deserialize<Entity.Order>(Context.Request.Params["Request"]);

            // Add Item
            if (request.OrderId == 0) 
            {
                // Get the max id
                var maxId = (OrderList.Any() ? OrderList.Max(a => a.OrderId) : 0);
                request.OrderId = maxId + 1;

                // Add to the session
                OrderList.Add(request);
            }
            else // Update Item
            {
                // remove the item
                OrderList = OrderList.Where(a => a.OrderId != request.OrderId).ToList();

                // Add to the session
                OrderList.Add(request);
            }

            // Returns the list
            GetList();
        }

        /// <summary>
        /// Delete Item
        /// </summary>
        private void DeleteItem()
        {
            // Remove the item
            var orderId = Convert.ToInt32(Context.Request.Params["OrderId"] ?? "0");

            // remove the item
            OrderList = OrderList.Where(a => a.OrderId != orderId).ToList();

            // Returns the list
            GetList();
        }

        #endregion
    }
}


Style.css

* { font-family: verdana; }
div{padding: 2px;}
input{ border: 1px solid #808080;}

.div-main { width: 600px; }
.div-sub-row { width: 600px; }
.div-left-box { width: 150px;text-align: right;float: left;}
.div-right-box { width: 395px;text-align: left;float: left;padding-left: 5px;}
.div-clear { clear: both; }

.div-order-counter{border: 1px solid #efefef;padding:5px;background: red;color: #fff;}

.div-main-grid{ width: 600px;font-size: 11px; }

.div-main-grid-column1{ float: left;text-align: center;width: 50px; }
.div-main-grid-column2{ float: left;text-align: center;width: 150px; }
.div-main-grid-column3{ float: left;text-align: center;width: 250px; }
.div-main-grid-column4{ float: left;text-align: center;width: 50px; }
.div-main-grid-column5{ float: left;text-align: center;width: 50px; }

.div-main-grid-header{ background: #1e90ff;color:#ffffff;height: 25px; }
.div-main-grid-item{ background: #efefef;color:#000;height: 25px; }
.div-main-grid-alternating-item{ background: #fff;color:#000;height: 25px; }


Entity.cs

#region System
using System;
using System.Collections;
using System.Collections.Generic;
#endregion

namespace Sample.KnockOut.Entity
{
    /// <summary>
    /// Order
    /// </summary>
    [Serializable]
    public class Order
    {
        public int OrderId { get; set; }

        public string OrderName { get; set; }

        public IList<OrderItem> OrderItems { get; set; }
    }

    /// <summary>
    /// Order Items
    /// </summary>
    [Serializable]
    public class OrderItem
    {
        public int Quantity { get; set; }

        public string ItemName { get; set; }
    }
}


Sample.js

/*
    Author : Maulik Dhorajia
    Description : Sample to show KnockOut.js usage. This will be helpful for beginners only.
*/

// Default settings for KnockOut.js
if (location.protocol != "data:") {
    $(window).bind('hashchange', function () {
        window.parent.handleChildIframeUrlChange(location.hash);
    });
}

// GLOBAL DECLARATIONS
var viewModel;

// Page Load
$(document).ready(function () {
    // Apply Binding - Which can help in applying binding.
    ApplyBindingHandlers();
    // Apply exterders
    ApplyNumericExtender();
    // Populate View Model
    PopulateViewModel();
});

// Apply Binding Handlers
function ApplyBindingHandlers() {
    ko.bindingHandlers.integerBoxSettings = {
        init: function (element, valueAccessor) {

            // Define the settings
            var $element = $(element);
            
            // Bind change event
            $element.blur(function () {
                if (parseInt($(this).val()) > 0) {
                    $(this).css("border", "1px solid green");
                    $(this).css("color", "green");
                }
                else if (parseInt($(this).val()) < 0) {
                    $(this).css("border", "1px solid red");
                    $(this).css("color", "red");
                }
                else if (parseInt($(this).val()) == 0) {
                    $(this).css("border", "1px solid #808080");
                    $(this).css("color", "black");
                }
            });
            
            $element.focus(function () {
                $(this).css("border", "1px solid #808080");
                $(this).css("color", "black");
            });
        }
    };
    
    // combine Items And Display - This will bind the items in the gird
    ko.bindingHandlers.combineItemsAndDisplay = {
        init: function (element, valueAccessor) {

            // Define the settings
            var $element = $(element);
            var value = ko.utils.unwrapObservable(valueAccessor());

            if (value != null && value.OrderItems.length > 0) {
                var html = "";
                for (var i = 0; i < value.OrderItems.length; i++) {
                    if (!(value.OrderItems[i].Quantity <= 0 || value.OrderItems[i].ItemName == "")) {
                        if (html != "") {
                            html += ", ";
                        }
                        html += value.OrderItems[i].Quantity.toString() + " - " + value.OrderItems[i].ItemName;
                    }
                }
                $element.html(html);
            }
        }
    };
    
    // Edit Item Settings
    ko.bindingHandlers.editItemSettings = {
        init: function (element, valueAccessor) {

            // Define the settings
            var $element = $(element);
            var value = ko.utils.unwrapObservable(valueAccessor());
            
            $element.click(function () {
                CallHandler("GetOrder", value.OrderId.toString());
            });
        }
    };
    
    // Delete Item Settings
    ko.bindingHandlers.deleteItemSettings = {
        init: function (element, valueAccessor) {

            // Define the settings
            var $element = $(element);
            var value = ko.utils.unwrapObservable(valueAccessor());
            
            $element.click(function () {
                if (confirm("Are you sure you want to delete the record?")) {
                    CallHandler("DeleteOrder", value.OrderId.toString());
                }
            });
        }
    };
}

// Applies the extenders
function ApplyNumericExtender() {

    // Validate numbers only
    ko.extenders.numeric = function (target, precision) {
        // create a writeable computed observable to intercept writes to our observable
        var result = ko.computed({
            read: target,  // always return the original observables value
            write: function (newValue) {
                var current = target(),
                    roundingMultiplier = Math.pow(10, precision),
                    newValueAsNum = isNaN(newValue) ? 0 : parseFloat(+newValue),
                    valueToWrite = Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;

                // only write if it changed
                if (valueToWrite !== current) {
                    target(valueToWrite);
                } else {
                    // if the rounded value is the same, but a different value was written, force a notification for the current field
                    if (newValue !== current) {
                        target.notifySubscribers(valueToWrite);
                    }
                }
            }
        });

        // initialize with current value to make sure it is rounded appropriately
        result(target());

        // return the new computed observable
        return result;
    };
}

// OrderItem : Object
function OrderItem(quantity, itemName) {
    var self = this;
    self.Quantity = ko.observable(quantity).extend({ numeric: 0 }); // Extended to check if Quantity is string it will replace it with 0.
    self.ItemName = ko.observable(itemName);
}

// Order View Model
function OrderViewModel() {
    var self = this;
    self.OrderId = ko.observable(0);
    self.OrderName = ko.observable("");
    self.OrderItemList = ko.observableArray([new OrderItem(0, ""), new OrderItem(0, ""), new OrderItem(0, "")]);

    // This will be the result from json call
    self.OrderList = ko.observableArray([]);
    
    // Events
    self.SaveClick = function () {
        // Validation
        if (viewModel.OrderName() == "") {
            alert("Order name is required.");
            return;
        }

        var orderItems = new Array();
        for (var i = 0; i < viewModel.OrderItemList().length; i++) {
            orderItems.push({ Quantity: viewModel.OrderItemList()[i].Quantity(), ItemName: viewModel.OrderItemList()[i].ItemName() });
        }
        var request = { "OrderId": viewModel.OrderId(), "OrderName": viewModel.OrderName(), "OrderItems": orderItems };
        var postData = { Request: JSON.stringify(request) };
        CallHandler("AddUpdateItem", postData);
    };
    
    self.ClearClick = function () {
        ClearScreen();
    };
}

// Populates view model
function PopulateViewModel() {
    CallHandler("GetList", null);
}

// Call Handler
function CallHandler(callMethod, postData) {
    //Supports cors
    $.ajaxSetup({ cache: false });
    $.support.cors = true;
    if (callMethod == "GetOrder" || callMethod == "DeleteOrder") {
        postData = { OrderId: postData };
    }
    // Cart Proxy
    $.post("Ajax/OrderHandler.ashx?Process=" + callMethod.toString(), postData, function (response) {
        SuccessOnServiceCall(response, callMethod);
    }).fail(function (jqXhr, textStatus, errorThrown) {
        ErrorOnServiceCall(jqXhr, textStatus, errorThrown);
    });
}

// Bind the screen
function SuccessOnServiceCall(response, callMethod) {
    switch (callMethod) {
    case "GetList":
        {
            // DO nothing
        } break;
        case "GetOrder":
            {
                if (response != null) {
                    viewModel.OrderId(response.OrderId);
                    viewModel.OrderName(response.OrderName);
                    
                    for (var i = 0; i < response.OrderItems.length; i++) {
                        viewModel.OrderItemList()[i].Quantity(response.OrderItems[i].Quantity);
                        viewModel.OrderItemList()[i].ItemName(response.OrderItems[i].ItemName);
                    }
                }
            } break;
    case "AddUpdateItem":
        {
            ClearScreen();
            alert("Order saved successfully.");
        } break;
    case "DeleteItem":
        {
            ClearScreen();
            alert("Order deleted successfully.");
        } break;
    }
    
    // Apply the model if null
    if (viewModel == null) {
        // Apply the View Model
        viewModel = new OrderViewModel();
        RefreshOrderList(response);
        // This should be called only once.
        ko.applyBindings(viewModel, document.getElementById("knockout-main-form")); // document.getElementById => Should be the like this. Whatever controls are there in this element can only be use the script.   
    } else {
        if (callMethod != "GetOrder") {
            RefreshOrderList(response);
        }
    }
}

// Display on error message
function ErrorOnServiceCall(jqXhr, textStatus, errorThrown) {
    alert(JSON.stringify(jqXhr));
}

// Refresh Order List : VERY IMPORTANT DONT BIND THE WHOLE OBJECT IT WONT WORK :)
function RefreshOrderList(orders) {
    viewModel.OrderList([]);
    if (orders != null && orders.length > 0) {
        for (var i = 0; i < orders.length; i++) {
            viewModel.OrderList.push(ko.observable(orders[i]));
        }
    }
}

// Clear screen
function ClearScreen() {
    viewModel.OrderId(0);
    viewModel.OrderName("");
    for (var i = 0; i < viewModel.OrderItemList().length; i++) {
        viewModel.OrderItemList()[i].Quantity(0);
        viewModel.OrderItemList()[i].ItemName("");
    }
}


Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Sample.KnockOut.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <!-- Title -->
    <title>KnockOut.js - Sample</title>
    <!-- Script -->
    <script type="text/javascript" src="Scripts/jquery-2.1.1.js"></script>
    <script type="text/javascript" src="Scripts/knockout-3.1.0.js"></script>
    <script type="text/javascript" src="Scripts/Sample.js"></script>
    <!-- Css -->
    <link rel="stylesheet" href="Css/Style.css" />
</head>
<body>
    <form id="form1" runat="server">
        <div id="knockout-main-form">
            <h3>KnockOut.js - Sample for observable object by KnockOut.js.</h3>
            <div id="divMain" class="div-main">
                <div class="div-sub-row">
                    <div class="div-left-box"><b>Order name :</b></div>
                    <div class="div-right-box">
                        <input type="text" data-bind="value: OrderName" maxlength="15" /><span data-bind="text: OrderId, visible: false" /></div>
                </div>
                <div class="div-clear"></div>
                <div class="div-sub-row">
                    <table>
                        <thead>
                            <tr>
                                <th>Quantity</th>
                                <th>Item Name</th>
                            </tr>
                        </thead>
                        <tbody data-bind="foreach: OrderItemList">
                            <tr>
                                <td>
                                    <input type="text" data-bind="value: Quantity, integerBoxSettings: $data" maxlength="3" style="width: 100px" /></td>
                                <td>
                                    <input type="text" data-bind="value: ItemName" maxlength="15" style="width: 250px" /></td>
                            </tr>
                        </tbody>
                    </table>
                </div>
                <div class="div-clear"></div>
                <div>
                    <input type="button" value="Save" data-bind="click: SaveClick" />&nbsp;<input type="button" value="Clear" data-bind="click: ClearClick" />
                </div>
                <div class="div-order-counter">
                    <span data-bind="text: 'There are '+ OrderList().length +' order(s) in memory.'"></span>
                </div>

                <div data-bind="visible: OrderList().length > 0" class="div-main-grid">
                    <div class="div-main-grid-header">
                        <div class="div-main-grid-column1">Id</div>
                        <div class="div-main-grid-column2">Name</div>
                        <div class="div-main-grid-column3">Items</div>
                        <div class="div-main-grid-column4">Edit</div>
                        <div class="div-main-grid-column5">Delete</div>
                    </div>
                </div>
                <div data-bind="visible: OrderList().length > 0, foreach: OrderList" class="div-main-grid">
                    <div data-bind="css: (($index() + 1) % 2 == 0 ? 'div-main-grid-alternating-item' : 'div-main-grid-item' )">
                        <div class="div-main-grid-column1" data-bind="text: OrderId"></div>
                        <div class="div-main-grid-column2" data-bind="text: OrderName"></div>
                        <div class="div-main-grid-column3" data-bind="combineItemsAndDisplay: $data"></div>
                        <div class="div-main-grid-column4"><a href="javascript:void(0);" data-bind="text: 'Edit', editItemSettings: $data"></a></div>
                        <div class="div-main-grid-column5"><a href="javascript:void(0);" data-bind="text: 'Delete', deleteItemSettings: $data"></a></div>
                    </div>
                </div>
            </div>
        </div>
    </form>
</body>
</html>


Final Out Come



Please let me know if this helped or not.

Thursday, September 20, 2012

Sharepoint 2010 Error Solution : The Visible property cannot be set on Web Part 'g_XXX'. It can only be set on a standalone Web Part.

Problem

There is an issue with OOTB SharePoint logic.

Scenario

  1. 2 types of Users
    • User1 is Site Administrator
    • User2 is a simple user with Read, Limited Access.
  2. Issue comes under blog site.


How to reproduce? Follow the below given test case.

  1. Create a site collection. In my case I have created it on "http://pc92".
  2. I create a blog site with name "TestBlog" using User1. In my case it is "http://pc92/TestBlog/".
  3. Navigate to default blog created on site and add 11 comments. Right now the URL will be "http://pc92/TestBlog/Lists/Posts/Post.aspx?ID=1". This will enable the paging at the comments webpart.
  4. Now login with User2(Read, Limited Access User) and navigate to the URL "http://pc92/TestBlog/Lists/Posts/Post.aspx?ID=1". The page will show normal. The only difference here is you won't see the "Add Comment" box at the bottom of the screen.
  5. Click the next button. You will see the error.


Cause

The cause of the whole act is when you login as a User2(Read, Limited Access) the Comment Box(ListFormWebPart) is not available for this users. On page load everything is fine. But when you do a postback like paging event it bombs out. This might have got out of the site of MicroSoft Team.

Solution

I created 2 features, one is a site based feature(BlogFixSite) and another one web based feature(BlogFixWeb). On the BlogFixSite activation we check all the web which doesnot have BlogFixWeb activated and the template is a Blog template. So if the feature is activated I assume that the site is already having a fix. In the BlogFixWeb I go to the "Posts" folder and copy "Post.aspx" content and create "Post1.aspx". In the "Post1.aspx" i will remove the "ListFormWebPart" programatically. In "Post.aspx" at the bottom i will place a jquery which will check if the "Add Comment" box is missing than take the user to "Post1.aspx". Repeat the above given test cases and you should be all good.

BlogFixSite - C#

#region System
using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Administration;
using System.Collections.Generic;
using System.Linq;
#endregion

namespace BlogFix.Features.BlogFixSite
{
    [Guid("63c859cc-77ff-436e-a79e-b4619a67c7c3")]
    public class BlogFixSiteEventReceiver : SPFeatureReceiver
    {
        #region Events

        /// <summary>
        /// Activating
        /// </summary>
        /// <param name="properties"></param>
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            base.FeatureActivated(properties);

            try
            {
                //Site object
                SPSite _site = (SPSite)properties.Feature.Parent;

                if (_site != null)
                {
                    //Feature ID - BlogFixWeb
                    Guid _featureWeGuid = new Guid("c7178a85-ed45-4f27-bd4a-db2ec3eed95b");

                    //Web List
                    IList<SPWeb> _webList = (from _web in _site.AllWebs.Cast<SPWeb>()
                                             where string.Compare(_web.WebTemplate, "Blog", true) == 0
                                                 && _web.Features[_featureWeGuid] == null
                                             select _web).ToList();

                    //Change the post page
                    foreach (SPWeb _web in _webList)
                    {
                        //Enables the feature - BlogFixWeb
                        if (_web.Features[_featureWeGuid] == null)
                        {
                            _web.Features.Add(_featureWeGuid);
                        }
                    }
                }
            }
            catch (Exception Exc)
            {
                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("BlogFixSiteEventReceiver - Activated", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, Exc.Message, Exc.StackTrace);
            }
        }

        #endregion
    }
}


BlogFixWeb - C#

#region System
using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Administration;
using System.Collections.Generic;
using System.Linq;
#endregion

namespace BlogFix.Features.BlogFixWeb
{
    [Guid("564b0ad9-90a0-45fc-a672-901ec1fd111b")]
    public class BlogFixWebEventReceiver : SPFeatureReceiver
    {
        #region Events

        /// <summary>
        /// Activate the web based feautre
        /// </summary>
        /// <param name="properties"></param>
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            base.FeatureActivated(properties);

            try
            {
                SPWeb _web = (SPWeb)properties.Feature.Parent;

                //All the subfolders
                SPFolderCollection _folderCollection = _web.Folders["Lists"].SubFolders;

                //Finds the folder containing Post.aspx
                IList<SPFolder> _folderPostList = (from _folderX in _folderCollection.Cast<SPFolder>()
                                                   let _fName = _folderX.Name
                                                   let _fCount = (from _fileX in _folderX.Files.Cast<SPFile>()
                                                                  where string.Compare(_fileX.Name, "post.aspx", true) == 0
                                                                  select _fileX).Count()
                                                   where _fCount > 0
                                                   select _folderX).ToList();


                //Loop it if there are more than one
                if (_folderPostList != null)
                {
                    foreach (SPFolder _folderPost in _folderPostList)
                    {
                        //Get the Post file
                        SPFile _filePost = (from _fileX in _folderPost.Files.Cast<SPFile>()
                                            where string.Compare(_fileX.Name, "post.aspx", true) == 0
                                            select _fileX).FirstOrDefault();

                        //The file post to be copied
                        if (_filePost != null)
                        {
                            //New Post1.aspx URL
                            string _newPostUrl = string.Format("{0}/{1}/{2}",
                                _web.Url,
                                _folderPost.Url,
                                "Post1.aspx");

                            //Copy the file
                            _filePost.CopyTo(_newPostUrl, true);
                            
                            //Update the folder
                            _folderPost.Update();

                            //Remove the control once the page is copied
                            Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager _webPartCollection = _web.GetLimitedWebPartManager(_newPostUrl, System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);

                            //Retrive the webpart and remove
                            Microsoft.SharePoint.WebPartPages.WebPart _listFormWebPart = (from _wp in _webPartCollection.WebParts.Cast<Microsoft.SharePoint.WebPartPages.WebPart>()
                                                                                          where _wp.GetType().UnderlyingSystemType.Name == "ListFormWebPart"
                                                                                          select _wp).FirstOrDefault();


                            //Microsoft.SharePoint.WebPartPages.ListFormWebPart _XlistFormWebPart = (Microsoft.SharePoint.WebPartPages.ListFormWebPart)_listFormWebPart;
                            //string _webPartTitle = _XlistFormWebPart.Title
                            //return;

                            if (_listFormWebPart != null)
                            {
                                //Remove the webpart
                                _webPartCollection.DeleteWebPart(_listFormWebPart);

                                //Update
                                _web.Update();
                            }

                            //Modify Post1.aspx and add the javascript tag
                            if (_filePost.RequiresCheckout)
                            {
                                _filePost.CheckOut();
                            }

                            //Edit the file
                            byte[] _htmlByte = _filePost.OpenBinary();
                            string _html = System.Text.Encoding.ASCII.GetString(_htmlByte);
                            string _topHtml = _html.Substring(0, _html.LastIndexOf("</asp:Content>"));
                            string _stript = "\n<script language=\"javascript\" type=\"text/javascript\">!window.jQuery && document.write('<script src=\"http://code.jquery.com/jquery-1.4.2.min.js\"><\\/script>');</script>\n<script language='javascript'>\n\r$(document).ready(function(){\n\r\rif($(\"h3[class='ms-CommentHeader']\").length == 1){\n\r\r\r\rwindow.location.href =     window.location.href.replace(\".aspx?\" , \"1.aspx?\");\n\r\r}\n\r});</script>";
                                

                            _html = string.Format("{0}{1}</asp:Content>", _topHtml, _stript);
                            _filePost.SaveBinary(System.Text.Encoding.ASCII.GetBytes(_html));

                            //Check In
                            if (_filePost.RequiresCheckout)
                            {
                                _filePost.CheckIn(string.Empty);
                            }
                        }
                    }
                }

            }
            catch (Exception Exc)
            {
                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("BlogFixWebEventReceiver - Activated", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, Exc.Message, Exc.StackTrace);
            }
        }

        #endregion
    }
}



JavaScript added on Post.aspx

There are 2 "<h3></h3>" tags on the post.aspx page. (1) is "Comments" and (2) is "Add Comments". So if a user dont have access he/she wont see "Add Comment" box. If that box doesnot exists on the page I simply send the user to Post1.aspx.
<script>    !window.jQuery && document.write('<script src="http://code.jquery.com/jquery-1.4.2.min.js"><\/script>');</script>
<script language='javascript'>
    $(document).ready(function () {
        if ($("h3[class='ms-CommentHeader']").length == 1) {
            window.location.href = window.location.href.replace(".aspx?", "1.aspx?");
        }
    });</script>


Final Comments

To make this feature available for all the webs just create a feature stapler which activates the web based feature just like its done in "BlogFixSite".
I know many people wont agree with my solution but right now it is what it is. Happy Coding. Do let me know if this helped you.

Tuesday, September 4, 2012

JQuery : Quick paging solution with JQuery

Goal

Many of the times we have to give the paging solutions with JQuery. I have created a small generic script that will allow you to apply paging on html table very quickly. Just a few settings and script will manage the paging(Note:- Right now the script will apply one one table on a page).

Settings

  1. Table ID : Apply an ID to the table with prefix "rpt". In our case we have used "rptPagingTable".
  2. Paging Items : All the rows which are going to be shown on the basis of page. Apply a custom tag to the row(tag="item").
  3. Next/Previous : The paging box will have a tag(tag="paging"). There are seperate tags assigned to the button Next and Previous. For Previous it is (tag="pre") and for Next it is (tag="next").


Solution

<html>
<head>
    <style type="text/css">
        body{font-family:Calibri,Verdana,Arial,Times New Roman;}
        .datagrid{border: 1px solid #808080;}
        .datagrid td{border: 1px solid #efefef;border-collapse: none;padding: 5px;}
        .header{background-color: #808080;color: #fff;text-align: center;font-size: 20px;}
        .itemtemplate{background-color: #fff;}
        .alternatingitemtemplate{background-color: #efefdf;}
        .footer{background-color: #808080;color: #fff;font-size: 15px;}
        .pager{background-color: #CED3D6;color: #000;font-size: 15px;text-align: center;}
        .pager a{color: #0877BD;}
        .pre{float: left;}
        .next{float: right;}
    </style>
    <script>!window.jQuery && document.write('<script src="http://code.jquery.com/jquery-1.4.2.min.js"><\/script>');</script>
    <script language="javascript" type="text/javascript">
        //CODE WHICH WILL HELP IN PAGING

        //Variable for paging
        var _currentPage = 1;
        var _pageSize = 0;
        var _totalPages = 1;

        $(document).ready(function () {

            //Setting the page size
            _pageSize = $("table[id*='rpt']").attr("pagesize");

            //Total Item
            var _trItem = $("tr[tag='item']");
            var _pager = $("tr[tag='paging']");

            //Calculate the page size
            _totalPages = parseInt($(_trItem).length / _pageSize) + ($(_trItem).length % _pageSize > 0 ? 1 : 0);

            //Hide the pager if the items are less than 13
            if ($(_trItem).length > _pageSize) {
                $(_pager).show();
            }
            else {
                $(_pager).hide();
            }

            //Page One Settings
            Paging();

            //Previous
            $("a[tag='pre']").click(function () {

                if (_currentPage == 1) {
                    return;
                }

                //Reduce the page index
                _currentPage = _currentPage - 1;

                //Paging
                Paging();
            });

            //Next
            $("a[tag='next']").click(function () {

                if (_currentPage == _totalPages) {
                    return;
                }

                //Increase the page index
                _currentPage = _currentPage + 1;

                //Paging
                Paging();
            });

        });

        //Shows/Hides the tr
        function Paging() {

            //Get the correct start index and end index
            var _endIndex = (_currentPage * _pageSize);
            var _startIndex = (_endIndex - _pageSize) + 1;

            //Hide all first
            $("tr[tag='item']").hide();

            //Show correct items
            $("tr[tag='item']").each(function (i) {
                var x = i + 1;
                if (x >= _startIndex && x <= _endIndex) {
                    $(this).show();
                }
            });
        }

    </script>
</head>
<body>
    <table id="rptPagingTable" cellpadding="0" cellspacing="0" border="0" class="datagrid"
        style="width: 700px" align="center" calculativegrid="PM" pagesize="5">
        <tr class="header"><td>No.</td><td style="width: 100%;">Instant Paging</td></tr>
        <tr tag="item" class='itemtemplate'><td>1</td><td>Ahmedabad</td></tr>
        <tr tag="item" class='alternatingitemtemplate'><td>2</td><td>Mumbai</td></tr>
        <tr tag="item" class='itemtemplate'><td>3</td><td>Delhi</td></tr>
        <tr tag="item" class='alternatingitemtemplate'><td>4</td><td>Calcutta</td></tr>
        <tr tag="item" class='itemtemplate'><td>5</td><td>Chicago</td></tr>
        <tr tag="item" class='alternatingitemtemplate'><td>6</td><td>New York</td></tr>
        <tr tag="item" class='itemtemplate'><td>7</td><td>New Jersy</td></tr>
        <tr tag="item" class='alternatingitemtemplate'><td>8</td><td>Bangalore</td></tr>
        <tr tag="item" class='itemtemplate'><td>9</td><td>Hyderabad</td></tr>
        <tr tag="item" class='alternatingitemtemplate'><td>10</td><td>Noida</td></tr>
        <tr tag="item" class='itemtemplate'><td>11</td><td>Mangalore</td></tr>
        <tr tag="item" class='alternatingitemtemplate'><td>12</td><td>Pune</td></tr>
        <tr tag="paging" class="pager">
            <td colspan="6">
                <a tag="pre" class="pre" href="javascript:void(0);"><< Prev</a>
                <a tag="next" class="next" href="javascript:void(0);">Next >></a>
            </td>
        </tr>
    </table>   
</body>
</html>


Display



Please let me know if this was helpful.

Thursday, May 17, 2012

SharePoint 2010 : Placing the SharePoint:PeopleEditor icons on right instead of bottom.

Goal

The SharePoint:PeopleEditor show the icons on the right side instead of bottom.

Sample Page : ASPX

<style type="text/css">
        .ppimg{border: 0px;vertical-align: middle !important;}
    </style>
    <br /><br /><br /><br />
    <table border="0" cellpadding="10" cellspacing="5" style="border:1px solid #808080">
        <tr>
            <td colspan="2">People picker on right instead of bottom</td>
        </tr>
        <tr>
            <td>
                Default
            </td>
            <td>
                <SharePoint:PeopleEditor AllowEmpty="false" ValidatorEnabled="true" ID="ppDefault"
                    runat="server" ShowCreateButtonInActiveDirectoryAccountCreationMode="false" SelectionSet="User,SPGroup"
                    Rows="1" Width="300px" />
            </td>
        </tr>
        <tr>
            <td nowrap="nowrap">
                Custom View
            </td>
            <td>
                <table>
                    <tr>
                        <td>
                            <SharePoint:PeopleEditor AllowEmpty="false" ValidatorEnabled="true" ID="ppCustom"
                                runat="server" ShowCreateButtonInActiveDirectoryAccountCreationMode="false" SelectionSet="User,SPGroup"
                                Rows="1" Width="300px" ShowButtons="false" />
                        </td>
                        <td valign="top">
                            <a id="aPPChekNames" runat="server" title="Check Name" href="javascript:">
                                <img src="/_layouts/images/checknames.png" alt="Check Names" class="ppimg" /></a>
                        </td>
                        <td valign="top">
                            <a id="aPPBrowse" runat="server" title="Browse" href="javascript:">
                                <img src="/_layouts/images/addressbook.gif" alt="Browse" class="ppimg" /></a>
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>


Sample Page : Code

//Apply the Javascript to the Icons
aPPChekNames.Attributes.Add("onclick", "if(!ValidatePickerControl('" + ppCustom.ClientID + "')){ ShowValidationError(); return false;} var arg=getUplevel('" + ppCustom.ClientID + "'); var ctx='" + ppCustom.ClientID + "';EntityEditorSetWaitCursor(ctx);WebForm_DoCallback('" + ppCustom.UniqueID + "',arg,EntityEditorHandleCheckNameResult,ctx,EntityEditorHandleCheckNameError,true);return false;");
aPPBrowse.Attributes.Add("onclick", "javascript:__Dialog__" + ppCustom.ClientID + "(); return false;");


Result



I am not sure if many know about this or this is normal, but just wanted to share. Let me know if this helped.

Friday, April 6, 2012

Get all properties of Object using Javascript.

Goal

Assuming we are working on an a task. On a process we get an object. We don't know what exactly is there in the object or what properties the object is having. The javascript mentioned will print the list of properties of an object.

Solution

<script language="javascript" type="text/javascript">       
    var _jsonObject = {"Property1":1,"Property2":"Simple String","Property3":true};
    alert(_jsonObject);

    var _html = "";
    for (var key in _jsonObject) {
        _html = _html + key + " : " + _jsonObject[key] + "<br />" ;
    }
    document.writeln(_html);
</script>


Output

Wednesday, February 22, 2012

SharePoint 2010 : Using ECMA script recall javascript function on control click in UpdatePanel.

I dont know if this is important or not but I found this thing interesting to blog.

Goal

There is a in UpdatePanel on the page. We have to call a javascript everytime the page is postback. Even if it is a postback from a control under UpdatePanel. I discovered a way using ECMA using which we can easily call the javascript function.

Solution

<script>!window.jQuery && document.write('<script src="http://code.jquery.com/jquery-1.4.2.min.js"><\/script>');</script>
<script type="text/javascript">
    //Call the function or assign the event on ready
    $(document).ready(function(){
        //This will wait until script is loaded and than call our function
        ExecuteOrDelayUntilScriptLoaded(PageLoadEvent, "sp.js");
    });
    
    //This function is the most important function that will add the end request
    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(FunctionHandler);
    
    //Event handler that fires on the UpdatePanel control events too
    function FunctionHandler(sender, args) {
        ExecuteOrDelayUntilScriptLoaded(ButtonClickEvent, "sp.js");
    }
    
    //Write the time on page load
    function PageLoadEvent(){
        alert('Page Load : ' + (new Date()).toString() );
    }

    //Will call on button click event
    function ButtonClickEvent(){
        alert('Button Click : ' + (new Date()).toString() );
    }                
</script>
<asp:UpdatePanel ID="upPanel" runat="server">
    <ContentTemplate>
        <asp:Button ID="btn" runat="server" Text="Click here!!!" />
    </ContentTemplate>
</asp:UpdatePanel>


Important Note

The most important thing in this is, if you remove "Sys.WebForms.PageRequestManager.getInstance().add_endRequest(FunctionHandler);" and try clicking the button the event wont be raised to call "function ButtonClickEvent()". So that is the magic trick.

Let me know if this helped you!

Monday, November 21, 2011

Sharepoint 2010 - Get Current User's sharepoint group information using javascript.

Goal

To retrieve the SharePoint Group information of Current User logged in using Javascript.

Solution

  1. Dowload the "jquery.SPServices-0.6.2.js" file from CodePlex. Save the file somewhere. I save it in "Style Library".
  2. Use the below given script to get the list of SharePoint Group using javascript.
<!--http://www.jquery.com-->
<script>    !window.jQuery && document.write('<script src="http://code.jquery.com/jquery-1.4.2.min.js"><\/script>');</script>
<!--http://spservices.codeplex.com/releases/view/64390-->
<script language="javascript" tye="text/javascript" src="/style library/jquery.SPServices-0.6.2.js"></script>
<!--Custom Script-->
<script language="javascript" tye="text/javascript">
    $(document).ready(function () {

        $().SPServices({
            operation: "GetGroupCollectionFromUser",
            userLoginName: $().SPServices.SPGetCurrentUser(),
            async: false,
            completefunc: function (xData, Status) {
                //Shows the XML returned from the server
                alert(xData.responseXML.xml);
                //Replace the "<<SHAREPOINT GROUP NAME>>" with your group name will tell that user is on a particular group or not.
                if ($(xData.responseXML).find("Group[Name='<<SHAREPOINT GROUP NAME>>']").length == 1) {
                    alert('User in a group');
                }
            }

        });

    });
</script>
This should be it. Happy Coding.