Showing posts with label dialog. Show all posts
Showing posts with label dialog. Show all posts

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.

Friday, January 20, 2012

Validation summary popup UI modification

In this post we will discuss how to modify the UI of validation summary with some CSS and jQuery.

Problem
Suppose we have two fields named first name and last name. And we need to implement required field validation. If we use asp.net RequiredFieldValidator and ValidationSummary with ShowMessageBox="true", then we can get the following result if we are not providing any value for the text fields-

Now we know that we cannot modify the message box UI. But if we want to do so-

Solution
If we change the ValidationSummary a little by ShowMessageBox="false" ShowSummary="true" DisplayMode="BulletList", then we get the following UI-

If we check the UI created for the summary we can find the following HTML generated-
    <div style="color: red" id="vsInfo" headertext="Following error occurs:" displaymode="BulletList">
        Following error occurs:
        <ul>
            <li>Provide first name</li>
            <li>Provide last name</li></ul>
    </div>
What we can do is add a little trick here. We can use jQuery dialog to change the UI (I believe that we know how to use jQuery dialog. For reference check here).

The modified code goes here-
    <div id="dialog" style="display:none">
    </div>
    <div class="itemContent">
        <label></label>
        <div class="controls" style="display:none">
           <asp:ValidationSummary ID="vsInfo" runat="server" HeaderText="Following error occurs:"
                ShowMessageBox="false" ShowSummary="true" DisplayMode="BulletList"  />
        </div> 
    </div>   
    <script type="text/javascript">
        $(document).ready(function() {
            $("#btnSaveInfo").click(function() {
                document.TimeID = setTimeout("checkMessage()", 5);
            });
        });
        function checkMessage() {
            if ($("div#vsInfo").length > 0) {
                $("#dialog").empty();
                $("#dialog").append($("div#vsInfo UL"));
                $("#dialog").dialog({
                    title: $("div#vsInfo").text(), 
                    close: function(event, ui) {
                        clearTimeout(document.TimeID);
                    }
                });
                clearTimeout(document.TimeID);
            }
            else 
                document.TimeID = setTimeout("checkMessage()", 5);
            
        }
    </script>
What we are doing here is binding the click event to the save button, in the button click we are calling a function named checkMessage() periodically after every 5 milliseconds and checking whether a div with id vsInfo exists in the DOM. If exists, then copying the HTML of the ValidationSummary and putting it in the dialog div, opening the dialog and finally clearing the timer. So, final UI looks like-
That’s what we wanted. We can change the UI of the dialog as we need.

Download the code from here.

Tuesday, December 13, 2011

Modify DOM using jQuery contextMenu and dialog

Introduction
Recently we got a requirement to modify document object model with jQuery context menu  plugin. We could achieve this very easily with jQuery context menu plugin and jQuery dialog.

Details goes here-
For ease let us take a list of divs with some margin, padding and background color. The HTML for this goes here-
    <style>
        div.enableCtx
        {
            width:200px;
            background-color: Gray;
            margin: 5px 5px 5px 5px;
            padding: 5px 5px 5px 5px;
            color:White;
            font-size:15px;
        }
    </style>
    <div class="enableCtx"> data 1</div>
    <div class="enableCtx"> data 2</div>
    <div class="enableCtx"> data 3</div>
    <div class="enableCtx"> data 4</div>
    <div class="enableCtx"> data 5</div>
    <div class="enableCtx"> data 6</div>
    <div class="enableCtx"> data 7</div>
    <div class="enableCtx"> data 8</div>
    <div class="enableCtx"> data 9</div>
The requirement that we are going to implement here is as follows-
  • Use context menu jQuery plugin for this
  • The context menu should have options for add, edit and delete.
  • For adding and editing the data in each div we are going to use jQuery dialog.
  • The add functionality will add a similar div with with the added content next to the current div. 
Now to use contextMenu, we need the necessary JavaScript and CSS files. In this case we can use the following references-
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.js" type="text/javascript"></script>

    <script src="http://labs.abeautifulsite.net/archived/jquery-contextMenu/demo/jquery.contextMenu.js"
        type="text/javascript"></script>

    <link href="http://labs.abeautifulsite.net/archived/jquery-contextMenu/demo/jquery.contextMenu.css"
        rel="stylesheet" type="text/css" />
Next we need to create UI for context menu. And it goes like below-
    <ul id="myMenu" class="contextMenu">
        <li class="copy"><a href="#Add">Add</a></li>
        <li class="edit"><a href="#Edit">Edit</a></li>
        <li class="delete"><a href="#Delete">Delete</a></li>
        <li class="quit separator"><a href="#Cancel">Cancel</a></li>
    </ul>
Now we can enable context menu by calling the following JavaScript-
        $(document).ready(function() {
            EnableContext();
        });
        function EnableContext() {
            $("div.enableCtx").contextMenu({
                menu: 'myMenu'
            },
            function(action, el, pos) {
            });
        }
If we notice we can check that the contextMenu takes a function as a second parameter with three attributes called action, el and pos. action stands for what option we have selected from the menu potion. In this case these can be Add, Edit, Delete and Cancel. The value of this is taken from the href value except #. el stands for target element, in our case its one of the div we are right clicking. And the last parameter pos is the coordinate position of the mouse click.

Now what we can do is write a function for each of the operation with exactly the same name as in action and use eval for evaluating the function call. The code goes here-
     <script type="text/javascript">
        $(document).ready(function() {
            EnableContext();
        });
        function EnableContext() {
            $("div.enableCtx").contextMenu({
                menu: 'myMenu'
            },
            function(action, el, pos) {
                eval(action + "(el)");
            });
        }

        function Add(el) {
            //add implementation
        }
        function Edit(el) {
            //edit implementation
        }
        function Delete(el) {
            //delete implementation
        }
        function Cancel(el) {
            //cancel implementation
        }
     </script>
Here is the beauty of eval function. Suppose we have selected Add option from the context menu then it will evaluate the statement Add(el). That means its going to call the add function. Similarly for others.

Next comes the actual implementation of the functions. As we have decided to use jQuery dialog for add and edit purpose. So, we need to setup dialog. Here we are going to take dialog as a div with a text box for editing the content of the selected div. The dialog references and HTML goes here-
     <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" />
    <div style="display:none" id="dialog" title="Add content">
        Enter Text: <nput type="text" id="text" />
   </div>
Add function-
   
        function Add(el) {
            $("#text").val("");
            $("#dialog").dialog({
                model: true,
                buttons: {
                    add: function() {
                        el.after($("<div>").addClass("enableCtx").html($("#text").val()));
                        EnableContext();
                        $(this).dialog("close");
                    }
                }
            });
        }
What we are doing in the add function is setting the textbox inside the dialog to empty, opening the dialog with a button called add. And in the add button click handler we are creating a dynamic div with class enableCtx and adding the content of the div as the textbox value. We are then adding the dynamic div next to the current div(el). We are recalling the EnableContext() function to add the same context behavior to the added div. And finally closing the dialog.

Edit, delete and cancel functions-
 
        function Edit(el) {
            $("#text").val(el.html());
            $("#dialog").dialog({
                model: true,
                buttons: {
                    Edit: function() {
                        el.html($("#text").val());
                        $(this).dialog("close");
                    }
                }
            });
        }
        function Delete(el) {
            el.remove();
        }
        function Cancel(el) {
        }
Edit function is simple, we are first copying the div HTML to textbox inside dialog, replacing the current div(el) HTML with textbox changed value. and closing the dialog.

Delete function is simply removing the current div. And in case of cancel function we need to to implement anything as it will automatically close the context menu.

Source code is here.