Showing posts with label webmethod. Show all posts
Showing posts with label webmethod. Show all posts

Tuesday, July 10, 2012

Restrict datepicker date using database driven dates

In this post we will be discussing restricting dates in jQuery UI datepicker dates using database driven dates.

We can restrict date using beforeShowDay event of the datepicker. Inside this function we can return [true] if we want the date to be enabled and return [false] if we want to disable date.

Let’s first get the date from server. For simplicity we will simply return an in memory date array like below-
    [WebMethod]
    public static List<string> GetDates()
    { 
        List<string> arr= new List<string>();
        arr.Add("2012-07-12");
        arr.Add("2012-07-25");
        arr.Add("2012-07-28");
        arr.Add("2012-07-13");
        arr.Add("2012-07-20");
        return arr;
    }
We can call this method from jQuery ajax like below-
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.js" type="text/javascript"></script>
    <script src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.9/jquery-ui.js" type="text/javascript"></script>
    <link href="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.9/themes/redmond/jquery-ui.css"
        rel="stylesheet" type="text/css" />
    <script type="text/javascript">
        $(function () {
            $.ajax({
                type: "POST",
                contentType: "application/json",
                data: "{}",
                url: "jquery datepicker fill with sql database dates.aspx/GetDates",
                dataType: "json",
                success: function (data) {
                    //enable date picker 
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    debugger;
                }
            });
        });
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
    </div>
    </form>
</body>
</html>
In the success method we can enable the datepicker and restrict the date by using the date from server (data.d). The code goes here-
$('#TextBox1').datepicker({
        minDate: new Date(2012, 6, 10),
        maxDate: new Date(2012, 8, 28),
        beforeShowDay: function (date) {
            function addZero(no) {
                if (no < 10) {
                    return "0" + no;
                } else {
                    return no;
                }
            }

        var date_str = [
        addZero(date.getFullYear()),
        addZero(date.getMonth() + 1),
        addZero(date.getDate())
        ].join('-');

        if ($.inArray(date_str, data.d) != -1) {
            return [true];
        } else {
            return [false];
        }
    }
});
What we are doing inside beforeShowDay is preparing the date string(date_str) in the format yyyy-mm-dd and then checking whether this date exists in the array data.d. If exists return [true] else return [false].

Wednesday, June 6, 2012

Ajax data paging with dataTables.net jQuery plugin in asp.net web form

I have recently added a post on calling ajax data to dataTables.net jQuery plugin with asp.net MVC 3. You can refer the following post-

http://growingtech.blogspot.in/2012/06/ajax-data-paging-with-datatablesnet.html

I will suggest to study the above post before proceeding this post. But the approach does not work with web form. So, how to do it with web form. As per my knowledge ajax paging with dataTable.net does not work properly with pagemethod or web service. We can solve this with an aspx page directly. But please take care of the security constraints as per your requirement.

First add a aspx page separate from your previous page. And change the sAjaxSource of the dataTable plugin like-
"sAjaxSource": 'Datatable Plugin Pagination Issue AjaxPath.aspx'
And in page load of the page use the following code-
public partial class Datatable_Plugin_Pagination_Issue_AjaxPath : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        var data = new[]{   
                new []{"Trident test","Internet Explorer 4.0","Win 95+","4","X"},
                new []{"Trident","Internet Explorer 5.0","Win 95+","5","C"},
                new []{"Trident","Internet Explorer 5.5","Win 95+","5.5","A"},
                new []{"Trident","Internet Explorer 6","Win 98+","6","A"},
                new []{"Trident","Internet Explorer 7","Win XP SP2+","7","A"},
                new []{"Trident","AOL browser (AOL desktop)","Win XP","6","A"},
                new []{"Gecko","Firefox 1.0","Win 98+ / OSX.2+","1.7","A"},
                .
                .
                .
                .
                new []{"Other browsers","All others","-","-","U"}
            };
        var pagedData = data.Skip(int.Parse(Request.QueryString["iDisplayStart"])).Take(int.Parse(Request.QueryString["iDisplayLength"]));
        System.Web.Script.Serialization.JavaScriptSerializer toJSON = new System.Web.Script.Serialization.JavaScriptSerializer();
        Response.Clear();
        string dataString = toJSON.Serialize(new
        {
            sEcho = Request.QueryString["sEcho"],
            iTotalRecords = data.Count(),
            iTotalDisplayRecords = data.Count(),
            aaData = pagedData
        });
        Response.Write(dataString);
        Response.End();
    }
}
That's all. Problem solved.

Thursday, March 22, 2012

Full calendar - saving event using ajax / pagemethod/ webmethod in asp.net

In this post we will be saving the event in a full calendar plugin using jQuery ajax and asp.net pagemethod or web service. To go through the post I request you to first check the following post. We are going the proceed forward with the same post and its source code.

http://growingtech.blogspot.in/2012/02/full-calendar-with-json-data-source.html

In addition to the previous script and CSS file references, we have added one more script file for this purpose-
<script src="https://github.com/douglascrockford/JSON-js/raw/master/json2.js" type="text/javascript"></script>
This file is used hare to to JSON stringify the event object.

Now how we are going to solve this issue is that on click of a day, we are going popup an entry form for the event and we will use ajax to save the event to the server and after successful saving we will be adding the event to the calender. Now calender plugin has some event to solve this purpose-
  1. dayClick - this event happen during the mouse click of a day.
  2. renderEvent - using this event we can add an event to the calender. We can set stick to true to permanently add the event to the calender.
For popup we are going to use jQuery dialog. For adding the event we can add the following HTML-
<div id="eventToAdd" style="display: none; font-size: 12px;">
    Event name:
    <input id="eventName" type="text" /><br />
    Event start date:
    <input id="eventStartDate" type="text" />(MM-dd-yyyy)<br />
    Event end date:
    <input id="eventEndDate" type="text" />(MM-dd-yyyy)<br />
</div>
Now we need to show popup dialog for adding event on the day click of the calendar day. To do so we will take the help of the dayClick event of the calender and it goes here-
<script type="text/javascript">
    $('div[id*=fullcal]').fullCalendar({
        dayClick: function (dateSelected, allDay, jsEvent, view) {
            $("#eventToAdd").dialog(
            {
                title: "Add event",
                modal: true,
                buttons: {
                    "Add": function () {
                       //event adding logic goes here                 
                    }
                }
            });
        }
    });
</script>
Now on click of add button in the dialog we need to do two things. First save the event data using jQuery ajax and page method / web service. And secondly on the success of the ajax call add the event on the calender. Both the work is done here-
"Add": function () {
    var event = new Object(), eventToSave = new Object(); ;
    eventToSave.EventID = event.id = Math.floor(200 * Math.random());
    event.start = new Date($("#eventToAdd #eventStartDate").val());
    eventToSave.StartDate = $("#eventToAdd #eventStartDate").val();
    if ($("#eventToAdd #eventEndDate").val() == "") {
        event.end = event.start;
        eventToSave.EndDate = eventToSave.StartDate;
    }
    else {
        event.end = new Date($("#eventToAdd #eventEndDate").val());
        eventToSave.EndDate = $("#eventToAdd #eventEndDate").val();
    }
    eventToSave.EventName = event.title = $("#eventToAdd #eventName").val();

    $("#eventToAdd input").val("");
    $.ajax({
        type: "POST",
        contentType: "application/json",
        data: "{eventdata:" + JSON.stringify(eventToSave) + "}",
        url: "FullcalenderwithPagemethod.aspx/AddEvents",
        dataType: "json",
        success: function (data) {
            $('div[id*=fullcal]').fullCalendar('renderEvent', event, true);
            $("#eventToAdd").dialog("close");
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            debugger;
        }
    });
}
What we are doing here is in line 2 we are creating two JavaScript objects event and eventToSave and line 3-14 we are assigning the values from the popup. And finally we are saving the data to server using ajax call. Why we have taken two objects here is event data of the calender has different property name and the server event have different name. Once the saving of event is successful we are adding the event object to the calendar using line number 24. The page method using for this is as follows-
[System.Web.Services.WebMethod]
public static bool AddEvents(Event eventdata)
{
    List events;
    if (HttpContext.Current.Session["events"] != null)
        events = (List)HttpContext.Current.Session["events"];
    else
        events = new List();
    events.Add(eventdata);
    HttpContext.Current.Session["events"] = events;
    return true;
}
For this example we have used in memory event object. We can easily replace it with proper database driven. The complete modified code for this is available here for download.

Monday, March 19, 2012

Dynamic galleriffic using pagemethod / webmethod in asp.net

In this post we are going to explore using Galleriffic jQuery plugin with asp.net web method/page method /web service. Also we will see how to change the image source dynamically. The detail of the plugin available here. First lets quickly go through the plugin usage-

First of all we need to add the following script files for working with Galleriffic-
<link rel="stylesheet" href="http://www.twospy.com/galleriffic/css/basic.css" type="text/css" />
    <link rel="stylesheet" href="http://www.twospy.com/galleriffic/css/galleriffic-2.css"
        type="text/css" />
    <script type="text/javascript" src="http://www.twospy.com/galleriffic/js/jquery-1.3.2.js"></script>
    <script type="text/javascript" src="http://www.twospy.com/galleriffic/js/jquery.galleriffic.js"></script>
    <script type="text/javascript" src="http://www.twospy.com/galleriffic/js/jquery.opacityrollover.js"></script>
The opacityrollover js file is optional. And also if we want we can define our own CSS files.

The HTML needed for the plugin is as follows-
<div id="container">
    <div id="gallery" class="content">
        <div id="controls" class="controls">
        </div>
        <div class="slideshow-container">
            <div id="loading" class="loader">
            </div>
            <div id="slideshow" class="slideshow">
            </div>
        </div>
        <div id="caption" class="caption-container">
        </div>
    </div>
    <div id="thumbs" class="navigation">
        <ul class="thumbs noscript" id="containerID">
            <li>
                <a class="thumb" name="drop" href="http://www.gallery2c.com/admin/Upload/FullImage/moda01.jpg"
                    title="Title #1">
                    <img src="http://www.gallery2c.com/admin/Upload/ThumbNail/moda01.jpg" alt="Title #1" />
                </a>
                <div class="caption">
                    Any html can be placed here ...
                </div>
            </li>
            .
            .
            .
            .
            .
        </ul>
    </div>
    <div style="clear: both;">
    </div>
</div>
Lets explain the HTML a little more. Line 3-4 is used for adding buttons of the slideshow(Play/Stop slideshow, Next image, previous image). Line 5-10 is used for showing the big image where line 6-7 is used to show the loading effect while the image is getting loaded and line 8-9 is used to show the actual image. And line 11-12 is used to show any additional information for the image. And the line 14-30 is used to add the image information. In that UL represent the image container. And each LI correspond to a image. It contains many information. Image tag in the LI represent the thumbnail image and the href of the container anchor represent the image that will be shown as a big image. Finally the div with class caption can be used as a container of additional information. The additional information can be of type HTML.

We are also going to use an additional select box as an option to change the data source for the plugin. The code goes here-
<select id="changeGallery">
    <option value="gett" selected="selected">Gallery 1</option>
    <option value="moda">Gallery 2</option>
</select>
Now to activate the plugin with rollover we call use the following code block-
var onMouseOutOpacity = 0.67;
$('#thumbs ul.thumbs li').opacityrollover({
    //add all option here
});

// Initialize Advanced Galleriffic Gallery
var gallery = $('#thumbs').galleriffic({
    //add all option here
});
So for enabling the Galleriffic we are going to use the following code-
function attachGallery() {
    var onMouseOutOpacity = 0.67;
    $('#thumbs ul.thumbs li').opacityrollover({
        mouseOutOpacity: onMouseOutOpacity,
        mouseOverOpacity: 1.0,
        fadeSpeed: 'fast',
        exemptionSelector: '.selected'
    });

    galleryVar = $('#thumbs').galleriffic({
        delay: 2500,
        numThumbs: 15,
        preloadAhead: 10,
        enableTopPager: true,
        enableBottomPager: true,
        maxPagesToShow: 7,
        imageContainerSel: '#slideshow',
        controlsContainerSel: '#controls',
        captionContainerSel: '#caption',
        loadingContainerSel: '#loading',
        renderSSControls: true,
        renderNavControls: true,
        playLinkText: 'Play Slideshow',
        pauseLinkText: 'Pause Slideshow',
        prevLinkText: '&lsaquo; Previous Photo',
        nextLinkText: 'Next Photo &rsaquo;',
        nextPageLinkText: 'Next &rsaquo;',
        prevPageLinkText: '&lsaquo; Prev',
        enableHistory: false,
        autoStart: false,
        syncTransitions: true,
        defaultTransitionDuration: 900,
        onSlideChange: function (prevIndex, nextIndex) {
            this.find('ul.thumbs').children()
     .eq(prevIndex).fadeTo('fast', onMouseOutOpacity).end()
     .eq(nextIndex).fadeTo('fast', 1.0);
        },
        onPageTransitionOut: function (callback) {
            this.fadeTo('fast', 0.0, callback);
        },
        onPageTransitionIn: function () {
            this.fadeTo('fast', 1.0);
        }
    });
}
Now to implement the dynamic Galleriffic, lets remove all the LI's form the UL container. And let add a hidden block of LI that we will be using as a template. The code block is as follows-
<div id="itemContainer" style="display: none">
    <li><a class="thumb" name="drop" href="http://www.gallery2c.com/admin/Upload/FullImage/moda01.jpg"
        title="Title #1">
        <img src="http://www.gallery2c.com/admin/Upload/ThumbNail/moda01.jpg" alt="Title #1" />
    </a>
        <div class="caption">
            Any html can be placed here ...
        </div>
    </li>
</div>
Now to make it database driven we need to do the following-
  1. Clone the hidden LI
  2. Change HREF and TITLE of the anchor tag using database values
  3. Change SRC and ALT of the image tag using database values
  4. Change the caption div inner HTML with database value
  5. Append the cloned LI to the container UL
  6. Repeat the process for all images
Now let us have some asp.net page method or web method that will return images that need to be added dynamically. It goes here-
[WebMethod]
public static object GetImageDetail(string id)
{
    var imageData = new { ImageID = 0, URL = string.Format("http://www.gallery2c.com/admin/Upload/FullImage/{0}01.jpg",id), Thumb = string.Format("http://www.gallery2c.com/admin/Upload/ThumbNail/{0}01.jpg",id), Title = "Title 0", Caption = "Caption 0" };
    var imageDataList = (new[] { imageData }).ToList();
    for (int i = 2; i < 10; i++)
        imageDataList.Add(new { ImageID = 0, URL = string.Format("http://www.gallery2c.com/admin/Upload/FullImage/{0}0{1}.jpg", id, i), Thumb = string.Format("http://www.gallery2c.com/admin/Upload/ThumbNail/{0}0{1}.jpg", id, i), Title = string.Format("Title {0}", i), Caption = string.Format("Caption {0}", i) });
    for (int i = 10; i < 20; i++)
        imageDataList.Add(new { ImageID = 0, URL = string.Format("http://www.gallery2c.com/admin/Upload/FullImage/{0}{1}.jpg", id, i), Thumb = string.Format("http://www.gallery2c.com/admin/Upload/ThumbNail/{0}{1}.jpg", id, i), Title = string.Format("Title {0}", i), Caption = string.Format("Caption {0}", i) });
    return imageDataList;
} 
Here I have taken the help of Gallery2c.com for images. And the jQuery code used to dynamically load the images goes here-
var templete, containerVar;
jQuery(document).ready(function ($) {
    templete = $("#itemContainer li");
    containerVar = $("#containerID");
    getData();
});
function getData() {
    $.ajax({
        type: "POST",
        contentType: "application/json",
        data: "{id:'gett'}",
        url: "Clear ALL images in the Galleriffic jquery plugin and Insert new images using jquery or javas.aspx/GetImageDetail",
        dataType: "json",
        success: function (data) {
            $(data.d).each(function (i, item) {
                containerVar.append(templete.clone());
                containerVar.find("li:last a.thumb").attr({ "href": item.URL, "Title": item.Title });
                containerVar.find("li:last a.thumb img").attr({ "src": item.Thumb, "Title": item.Title });
                containerVar.find("li:last .caption").html(item.Caption);
            });
            attachGallery();
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            debugger;
        }
    });
    $('div.navigation').css({ 'width': '300px', 'float': 'left' });
    $('div.content').css('display', 'block');
}
And to dynamically change the datasource in the plugin we can call the getData() method on the change of the previously added dropdown. The code is as below-
$("#changeGallery").change(getData);
And also we need to remove the content of the container UL before changing the content of the UL. So, at the start of the getData() method we can append the code containerVar.empty();. But there is a small problem, if we play the slide show and then change the dropdown selection. Then the slide show shows wrong image in the big image. It shows the previous datasource images. So, before changing the data source we can stop the slide show and then change the source. The final code looks like-
        var templete, containerVar;
        jQuery(document).ready(function ($) {
            templete = $("#itemContainer li");
            containerVar = $("#containerID");
            getData();
            $("#changeGallery").change(getData);
        });

        function getData() {
            try {
                galleryVar.pause();
            }
            catch (ex) {
            }
            containerVar.empty();
            $.ajax({
                type: "POST",
                contentType: "application/json",
                data: "{id:'" + $("#changeGallery").val() + "'}",
                url: "Clear ALL images in the Galleriffic jquery plugin and Insert new images using jquery or javas.aspx/GetImageDetail",
                dataType: "json",
                success: function (data) {
                    $(data.d).each(function (i, item) {
                        containerVar.append(templete.clone());
                        containerVar.find("li:last a.thumb").attr({ "href": item.URL, "Title": item.Title });
                        containerVar.find("li:last a.thumb img").attr({ "src": item.Thumb, "Title": item.Title });
                        containerVar.find("li:last .caption").html(item.Caption);
                    });
                    attachGallery();
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    debugger;
                }
            });
            $('div.navigation').css({ 'width': '300px', 'float': 'left' });
            $('div.content').css('display', 'block');
        }
You can download the code form here.

Wednesday, February 1, 2012

Full Calendar with JSON data source using asp.net web service/ pagemethod/ webmethod

In this blog post we are going to discuss using full calendar plugin with JSON data source through asp.net webservice / pagemethod / webmethod. We can get the detail of the plugin here.

For using this plugin we need to add the reference of the following files-
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" type="text/javascript"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.min.js" type="text/javascript"></script>
    <link rel='stylesheet' type='text/css' href='http://arshaw.com/js/fullcalendar-1.5.2/fullcalendar/fullcalendar.css' />
    <script type='text/javascript' src='http://arshaw.com/js/fullcalendar-1.5.2/jquery/jquery-ui-1.8.11.custom.min.js'></script>
    <script type='text/javascript' src='http://arshaw.com/js/fullcalendar-1.5.2/fullcalendar/fullcalendar.min.js'></script>
Basic style HTML infrastructure using for this implementation is as follows-
        #loading
        {
            width: 600px;
            height: 550px;
            position: absolute;
            background-color: gray;
            color: white;
            text-align: center;
            vertical-align: middle;
            display: table-cell;
        }
        #fullcal
        {
            width: 600px;
            height: 600px;
            position: absolute;
            display: none;
        }
    <div>
        <div id="loading">
            <label style="top: 50%; position: relative">
                loading events....</label>
        </div>
        <div id="fullcal">
        </div>
    </div>
In the div with id fullcal we will be loading the calendar control. By default this div is marked as hidden, and a place holder div (with id loading) is added in the place. This is just to show while server data is getting loaded from server. Once the data is loaded on the calendar we will show back the calendar and hide the placeholder.

The script used for activating calendar is as follows-
    $('div[id*=fullcal]').fullCalendar({
        header: {
            left: 'prev,next today',
            center: 'title',
            right: 'month,agendaWeek,agendaDay'
        },
        editable: true,
        events: list of event here
    });
Now in full calendar the event object has lots of information. We can get more information about the event object here. Lets represent the event as a C# class as follows-
public class Event
{
    public int EventID { get; set; }
    public string EventName { get; set; }
    public string StartDate { get; set; }
    public string EndDate { get; set; }
}
There are many other properties for the event object. For the sack of implementation we are taking these only. And I think the class properties are self explanatory. We can get the data for the event from database. For this post we are creating in memory object for data source. The page method used for data retrieval is as follows-
   [WebMethod]
    public List GetEvents()
    {
        List events = new List();
        events.Add(new Event()
        {
            EventID = 1,
            EventName = "EventName 1",
            StartDate = DateTime.Now.ToString("MM-dd-yyyy"),
            EndDate = DateTime.Now.AddDays(2).ToString("MM-dd-yyyy")
        });
        events.Add(new Event()
        {
            EventID = 2,
            EventName = "EventName 2",
            StartDate = DateTime.Now.AddDays(4).ToString("MM-dd-yyyy"),
            EndDate = DateTime.Now.AddDays(5).ToString("MM-dd-yyyy")
        });
        events.Add(new Event()
        {
            EventID = 3,
            EventName = "EventName 3",
            StartDate = DateTime.Now.AddDays(10).ToString("MM-dd-yyyy"),
            EndDate = DateTime.Now.AddDays(11).ToString("MM-dd-yyyy")
        });
        events.Add(new Event()
        {
            EventID = 4,
            EventName = "EventName 4",
            StartDate = DateTime.Now.AddDays(22).ToString("MM-dd-yyyy"),
            EndDate = DateTime.Now.AddDays(25).ToString("MM-dd-yyyy")
        });
        return events;
    }
Now we can read the web service data using jQuery and fill the full calendar using server driven event list like following-
    $.ajax({
        type: "POST",
        contentType: "application/json",
        data: "{}",
        url: "FullcalenderwithWebservice.asmx/GetEvents",
        dataType: "json",
        success: function(data) {
            $('div[id*=fullcal]').fullCalendar({
                header: {
                    left: 'prev,next today',
                    center: 'title',
                    right: 'month,agendaWeek,agendaDay'
                },
                editable: true,
                events: data.d
     });
            $("div[id=loading]").hide();
            $("div[id=fullcal]").show();
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            debugger;
        }
    });
Now here is a slight problem, the calendar will get loaded but not the list of events returned. Few points we need to remember here-
  1.  The full calendar event object has certain naming like EventID should be id, EventName – title, StartDate – start, EndDate – end and so on. So, we have to map the returned object to full calendar’s desired object.
  2. One more thing that we need to remember is that the start and end need to be in date type. The proper conversation is as follows-
    $('div[id*=fullcal]').fullCalendar({
        header: {
            left: 'prev,next today',
            center: 'title',
            right: 'month,agendaWeek,agendaDay'
        },
        editable: true,
        events: $.map(data.d, function(item, i) {
                    var event = new Object();
                    event.id = item.EventID;
                    event.start = new Date(item.StartDate);
                    event.end = new Date(item.EndDate);
                    event.title = item.EventName;
                    return event;
                })
    });
We can note one more thing that we are returning the date in MM-dd-yyyy format (DateTime.Now.ToString("MM-dd-yyyy")). The reason is that we can pass such a string to Date constructor in JavaScript to create the date.

We can download the full source code from here.

Sunday, January 22, 2012

POST complex data to pagemethod or webservice using jQuery

In many occasion we need to post some complex data like class (object), array, list of objects to pagemethod, webmethod or web service. I have answered many such posts in asp.net forum. So, decided to list few posts here-

http://forums.asp.net/p/1688559/4454363.aspx/1?Re+Post+array+of+array+of+html+form. This post is used to post generic list of a class objects where the UI is represented as UL, LI. Each LI has a checkbox, a hidden filed and an input box. The underlying structure of the class is as-
public class ComplexData {
    public int id { get; set; }
    public bool flag { get; set; }
    public string note { get; set; }
}
http://forums.asp.net/p/1709268/4549152.aspx/1?Re+how+to+save+data+using+jquery+ajex. This post is used to post name id based class where the UI is represented as HTML table. The class structure is as-
public class NameIDData
{
    public int id { get; set; }
    public string name { get; set; }
}
http://forums.asp.net/p/1690207/4462756.aspx/1?Re+Problem+with+charset+ajax+request. This post is used to post a class which contains non English characters. The class structure is as-
public class PersonClass
{
    public Guid Userid { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public string Username { get; set; }
}
And input sample data is as-
            var jsonString = { "Userid": "eec756aa-56e0-4515-b3bb-70b6c31b3d8a",
                "Firstname": "сркшы",
                "Lastname": "сркшы",
                "Username": "russiantest"
            };
http://forums.asp.net/p/1694914/4482943.aspx/1?Re+Getting+form+Values+. This post is used to post some complex data with parent child relationship. The UI is little complex with field set as each row of data. And the content can be added dynamically. The class is represented as-
public class ParentChild
{
    public string Parent { get; set; }
    public string Child { get; set; }
}
http://forums.asp.net/p/1662319/4338617.aspx. This post is used to post a list of object from reading Grid View rows. The class structure goes like-
public class Screening
{
    public string ScreeningPropertyID { get; set; }
    public string ScreeningValue { get; set; }
}
http://forums.asp.net/p/1653108/4303194.aspx#4303194. This post deals with posting a string array to webmethod.

http://forums.asp.net/p/1650626/4292348.aspx#4292348. This post deals with reordering of HTML element and post the reordered list to the webmethod. The class structure goes like below-
public class DivsDetail {
    public int DivID { get; set; }
    public int Order { get; set; }
}

Monday, January 16, 2012

Implement drag drop events from outside in Full Calender for an ajax based data source

Introduction
With this post I will try to describe Full Calender plugin with drag and drop feature where we can drag and drop events from an Ajax based event data source outside the calender. For this to implement we need to know basics about jQuery and full calender plugin. We can get the plugin detail form this URL.

Details goes here-
CSS used in this post goes here-
   <style type='text/css'>
        body
        {
            margin-top: 40px;
            text-align: center;
            font-size: 14px;
            font-family: "Lucida Grande" ,Helvetica,Arial,Verdana,sans-serif;
        }
        #wrap
        {
            width: 1100px;
            margin: 0 auto;
        }
        #external-events
        {
            float: left;
            width: 150px;
            padding: 0 10px;
            border: 1px solid #ccc;
            background: #eee;
            text-align: left;
        }
        #external-events h4
        {
            font-size: 16px;
            margin-top: 0;
            padding-top: 1em;
        }
        .external-event
        {
            margin: 10px 0;
            padding: 2px 4px;
            background: #3366CC;
            color: #fff;
            font-size: .85em;
            cursor: pointer;
        }
        #external-events p
        {
            margin: 1.5em 0;
            font-size: 11px;
            color: #666;
        }
        #external-events p input
        {
            margin: 0;
            vertical-align: middle;
        }
        #calendar
        {
            float: right;
            width: 900px;
        }
    </style>
For this to work we need to take some CSS and JS files as a reference as follows-
    <link rel='stylesheet' type='text/css' href='http://arshaw.com/js/fullcalendar-1.5.2/fullcalendar/fullcalendar.css' />
    <link rel='stylesheet' type='text/css' href='http://arshaw.com/js/fullcalendar-1.5.2/fullcalendar/fullcalendar.print.css'
        media='print' />

    <script type='text/javascript' src='http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.js'></script>

    <script type='text/javascript' src='http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.9/jquery-ui.js'></script>

    <script type='text/javascript' src='http://arshaw.com/js/fullcalendar-1.5.2/fullcalendar/fullcalendar.min.js'></script>
We can implement a full calender in a div like container as follows-
    <div id='calendar'>
    </div>
            $('#calendar').fullCalendar({
                header: {
                    left: 'prev,next today',
                    center: 'title',
                    right: 'month,agendaWeek,agendaDay'
                },
                editable: true,
                droppable: true,
                drop: function(date, allDay) {
                //drop functionality goes here
                }
            });
Now the basic construct for the problem is done. Lets add a div in the page as a container and list all the events on the div using Ajax. We will now implement drag and drop such that we can drag an event form the list of events and add the events to calender by dropping it into the full calender. To list the events in a div using Ajax we can use page method like below-
    <div id='external-events'>
        <h4>
            Draggable Events</h4>
        
        <p id="events">
            <input type='checkbox' id='drop-remove' />
            <label for='drop-remove'>
                remove after drop</label>
        </p>
    </div> 
            $.ajax({
                url: "Fill draggable events area of FullCalendar.aspx/GetEvents",
                type: "POST",
                dataType: "json",
                contentType: "application/json; charset=utf-8",
                success: function(data) {
                    $(data.d).each(function(i, item) {
                        $("#events").before($("<div class='external-event'></div>").html(item.EventName));
                    });
                },
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    debugger;
                    alert(textStatus);
                }
            });
    [System.Web.Services.WebMethod]
    public static object GetEvents()
    {
        var obj = new { EventName = "My Event 1"};
        var objList = (new[] { obj }).ToList();
        objList.Add(new { EventName = "My Event 2" });
        objList.Add(new { EventName = "My Event 3" });
        objList.Add(new { EventName = "My Event 4" });
        objList.Add(new { EventName = "My Event 5" });
        objList.Add(new { EventName = "My Event 6" });
        objList.Add(new { EventName = "My Event 7" });
        return objList;
    }
In the above code we have some in memory object as event datasource. We can change to any data source as we need.
Now we need to make the event divs, constructed in the above js code, as draggable. We can do this by implementing the draggable UI plugin by modifying the success method of the Ajax call like below-
                success: function(data) {
                    $(data.d).each(function(i, item) {
                        $("#events").before($("<div class='external-event'></div>").html(item.EventName));
                    });
                    $('#external-events div.external-event').each(function() {
                        var eventObject = {
                            title: $.trim($(this).text())
                        };

                        $(this).data('eventObject', eventObject);

                        $(this).draggable({
                            zIndex: 999,
                            revert: true,
                            revertDuration: 0
                        });
                    });
                }
And finally we can implement drop functionality of the full calender plugin to accept the draggable events and we can achieve this by modifying the full calender jquery call as below-
            $('#calendar').fullCalendar({
                header: {
                    left: 'prev,next today',
                    center: 'title',
                    right: 'month,agendaWeek,agendaDay'
                },
                editable: true,
                droppable: true,
                drop: function(date, allDay) {

                    var originalEventObject = $(this).data('eventObject');

                    var copiedEventObject = $.extend({}, originalEventObject);

                    copiedEventObject.start = date;
                    copiedEventObject.allDay = allDay;

                    $('#calendar').fullCalendar('renderEvent', copiedEventObject, true);

                    if ($('#drop-remove').is(':checked')) {
                        $(this).remove();
                    }

                }
            });