• Developing a portal with Drag and Drop Portlets using JQuery

    Posted on May 22, 2012 by in Jquery, Other Programming

    The article explains how to create simple portal with drag and drop portlets with JQuery/Jquery UI (with out use of any plugins) from scratch. The portal with have the ability to drag and drop portlets and also save the position and state of the portlets.

    portal

    Creating a Portal with Drag and Drop Portlets

    Jquery UI has a sortable plugin which allows you drag and drop any element. To create Drag and Drop portlet , first we create HTML similar to code below.

    	<div id="portletcontainer" class="mcontainer portalbox">
                            <div id="myportlet1" class="portlet">
                                <div class="portlet-header" style="vertical-align: middle;">
                                    <span class="heading ">I am Portlet1 </span>
                                </div>
                                <div class="content">
                                    You cannot drag me. Just removed the sortable class for the div. Is not it simple
                                </div>
                            </div>
                            <div id="myportlet2" class="portlet sortable" _close="0" _max="0">
                                <div class="portlet-header" style="vertical-align: middle;">
                                    <span class="heading ">I am Portlet2 </span>
                                </div>
                                <div class="content">
                                    This is portlet2
                                </div>
                            </div>
                            <div id="myportlet3" class="portlet sortable" _close="0" _max="0">
                                <div class="portlet-header" style="vertical-align: middle;">
                                    <span class="heading ">I am Portlet3 </span>
                                </div>
                                <div class="content">
                                    This is portlet3
                                </div>
                            </div>
                    </div>
    
    

    Class portalbox for container,Class portlet for the portlet and class portlet-header have some significance , if you change any of those please change the code below accordingly.

    After creating HTML markup, Include JQuery and JQuery UI libraries

        <script type='text/javascript' src='js/jquery-1.7.2.min.js'></script>
        <script src="js/jquery-ui-1.8.15.custom.min.js" type="text/javascript"></script>
    

    Just another piece of code and your basic drag and drop portlet website is ready for use.

                $(document).ready(function () {
                    $(".portalbox").sortable({
                        connectWith: '.portalBox',
                        items: '.sortable',
                        handle: '.portlet-header',
                        forcePlaceholderSize: true,
                        forceHelperSize: true,
                        revert: true,
                        dropOnEmpty: true
                    });
    
                });
    

    If you look closely at the HTML markup, you notice that only portlets 2 and 3 have class sortable assigned to them.

    items : ‘.sortable’ lets only the items with sortable class to be dragged. So, when you run the example, you wont be able drag the portlet1.

    Saving the State of Portlets

    The above code enables drag and drop of portlets, it misses one important feature, it doesnot remember the position of the portlets and state of the portlets, i.e whether the porlet is closed or minimized etc.

    Although there are many ways to do it, In this article we are going to save every time the position or state of a portlet is changed, i.e we are going to save every time portlet is moved or it is closed or minimized.

    //After dropping update the portal order
                    $(".portalbox").bind("sortstop", function (event, ui) {
                        ui.item.data("container", $(event.target));
                        updatePortletOrder();
                    });
    
    //Close buttonClick
                    $(".portlet-header .portlet-close").click(function () {
                        var portletId = $(this).parents(".portlet:first").attr("id");
                        $("#" + portletId).hide();
                        $("#" + portletId).attr("_close", '1');
                        //update portal order
                        updatePortletOrder();
                    });
    // minmize & maximize portlet
                    $(".portlet-header .minmax").click(function () {
                        $(this).toggleClass("na-icon-triangle-1-n").toggleClass("na-icon-triangle-1-s");
                        $(this).parents(".portlet:first").find(".content").toggle();
                        var porletId = $(this).parents(".portlet:first").attr("id");
                        if ($(this).attr("title") == "Minimize") {
                            $(this).attr("title", "Maximize");
                            $("#" + porletId).attr("_max", "0");
                        } else {
                            $(this).attr("title", "Minimize");
                            $("#" + porletId).attr("_max", "1");
                        }
                        //write code to save the sate of the portlet if required
                        updatePortletOrder();
                    });
    

    $(“.portalbox”).bind(“sortstop”…. function is triggerred after you dropped your portlet. In all the events above we call updatePortletOrder function, which saves the order of portlets and state of portlets.

    Ideally, the settings should be saved to a database, but in this example i am saving to cookie.

    function updatePortletOrder() {
                    var oprid = "123456";//get login username/userid
                    var POrder = "";
                    $(".sortable").each(function () {
                        //alert($(this).attr("id"));
                        POrder = POrder + $(this).attr("id") + ",";
                    });
                    POrder = POrder.substring(0, POrder.length - 1);
    
                    var PClosed = "";
                    $(".portalbox > div.portlet[_close='1']").each(function () {
                        //alert($(this).attr("id"));
                        PClosed = PClosed + $(this).attr("id") + ",";
                    });
                    if (PClosed.length > 0) {
                        PClosed = PClosed.substring(0, PClosed.length - 1);
                    }
    
                    var PMax = "";
                    $(".portalbox > div.portlet[_max='1']").each(function () {
                        //alert($(this).attr("id"));
                        PMax = PMax + $(this).attr("id") + ",";
                    });
                    if (PMax.length > 0) {
                        PMax = PMax.substring(0, PMax.length - 1);
                    }
    
                    var parameters = "{'Oprid':'" + oprid + "','POrder':'" + POrder + "','PClosed':'" + PClosed + 
    
    "','PMax':'" + PMax + "'}";
    
                    document.cookie = "PortletOrder=" + parameters;
    
                }
    
    

    How you get the state and position of portlet may vary with the structure of HTML, the above code works only for portlets with 100% width, i.e one portlet below the other, but it can be easily modified to meet your requirements.

    Hope you enjoyed the article and will help you, do leave a feedback with your questions and suggestions.


    Be Sociable, Share!

    Written by

    Vanamali Juvvadi is a Web enthusiast and loves all things design and technology. Founded qnownow with a group of friends to share anything/everything they know/find on the internet.

    View all articles by

    Email : [email protected]

    10 Responsesso far.

    1. Robert says:

      Good Day, I am looking for advice on converting your code to work in a 3 collum layout. When I add a css class collumn and just wrap a div around the myportlets …myportlet1..myportlet2… the page will not refresh correctly.
      Any help would be apprecieated.

    2. Mike says:

      Thanks, a bit buggy but a great base none the less :)

    3. dskanth says:

      A great way to order the divs on a page. The only difference is that i am using ajax to save the position of the divs after they are dragged.

    4. Great job! With a few modifications and a couple of bug fixes, I made it work with a two-column layout.

    5. James says:

      great start for my project , but i seem to be stuck on adding an expand, and prolapse all button

      • Vanamali says:

        For expand all you can use

                                    $("#portletcontainer .portlet").attr("_max", '1');
                                    //maximize ,show content
                                    $("#portletcontainer .portlet").find(".content").show();
                                    $("#portletcontainer .portlet").find(".portlet-header").find(".minmax").attr("title", "Minimize");
                                    $("#portletcontainer .portlet").find(".portlet-header").find(".minmax").removeClass("na-icon-triangle-1-s").addClass("na-icon-triangle-1-n");
        

        For collapse all you can use

                                    $("#portletcontainer .portlet").attr("_max", '0');
                                    //maximize ,show content
                                    $("#portletcontainer .portlet").find(".content").hide();
                                    $("#portletcontainer .portlet").find(".portlet-header").find(".minmax").attr("title", "Maximize");
                                    $("#portletcontainer .portlet").find(".portlet-header").find(".minmax").removeClass("na-icon-triangle-1-n").addClass("na-icon-triangle-1-s");
        

        let me know if it works.

        • James says:

          perfect! I really didn’t expect you to write it for me :-) this has become the major part of a work project – are you available for contract work?

    6. […] Developing a portal with Drag and Drop Portlets using JQueryEverything Technical […]

    Leave a Reply