вторник, 5 апреля 2011 г.

Progressbar

Добрый вечер читатели.

Сегодня столкнулся с проблемой.
Нужно реализовать прогресс бар с несколькими шкалами:
  • Законченные задачи
  • Задачи находящиеся в процессе
  • Не начатые задачи
А именно нечто похожее на:

Немного поискав в интернете не нашел ничего стоящего что могло лечь на поставленную задачу.

Выход был написать самому, первое, что пришло в голову генерировать на сервере картинку, кешировать и отдавать клиенту. Но немного обдумав решил реализовать все на jquery.

Получился простой плагин (jquery.progress.js):
$.fn.progress = function (options)
{
    var defaults = { InProgress: 0, Completed: 0 };
    var opt = $.extend(defaults, options);

    function addScale(container, scaleValue, cssClass)
    {
        // Ignore scale when value is zero.
        if (scaleValue == 0)
            return;

        // Create scale.
        var scale = $('<div/>');
        scale.addClass("scale");
        scale.addClass(cssClass);
        scale.css("width", scaleValue + "%");
        scale.html(scaleValue + "%");

        // Append scale to container.
        container.append(scale);
    }

    return this.each(function ()
    {
        var container = $(this);

        // Remove any data from container.
        container.empty();

        // Truncate to 100%
        if (opt.Completed > 100) opt.Completed = 100;
        if (opt.InProgress > 100) opt.InProgress = 100;
        if (opt.Completed + opt.InProgress > 100)
            opt.InProgress = 100 - opt.Completed;

        // Make container like progress bar.
        container.addClass("progress");
        container.css("width", opt.Width + "px");

        // Add scales.
        addScale(container, opt.Completed, "complete");
        addScale(container, opt.InProgress, "inprogress");

        // Create corners.
        container.corner("3px");
    });
};
Стили (jquery.progress.css):
.progress
{
    background-color: #f5f5f5;
    border: solid 1px #636564;
    height:10px;
    font-family:Verdana;
    font-size:6pt;
    color: #85847a;
    vertical-align:middle;
}

.progress > .scale
{
    float: left;
    height:inherit;
    overflow:hidden;
}
        
.progress > .complete
{
    background-color:#86d603;        
}        
        
.progress > .inprogress
{
    background-color:#dfd842;        
}

И пример использования:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Progressbar demo</title>

    <script type="text/javascript" src="jquery-1.5.1.min.js"></script>
    <script type="text/javascript" src="jquery.corner.js"></script>    
    <script type="text/javascript" src="jquery.progress.js"></script>         
    <link type="text/css" rel="Stylesheet" href="jquery.progress.css"  />

    <style type="text/css">
        #container0 { width:50px; }
        #container1 { width:100px; }
        #container2 { width:120px; }
        #container3 { width:140px; }
        #container4 { width:150px; }
        #container5 { width:180px; }
    </style>
</head>
<body>
    <div id="container0"></div>
    <div id="container1"></div>
    <div id="container2"></div>
    <div id="container3"></div>
    <div id="container4"></div>
    <div id="container5"></div>

    <script type="text/javascript">
        function DoProgress()
        {
            for (var i = 0; i <= 5; i++)
            {
                var completed = Math.round(Math.random() * 100);
                var free = (100 - completed);
                var inProgress = Math.round(Math.random() * free);
                
                $("#container" + i).progress(
                { 
                    Completed: completed,
                    InProgress: inProgress
                });
            }
        }            

        function Init()
        {
            DoProgress();
        }

        $(document).ready(Init);
    </script>
</body>
</html>

Спасибо за чтение, жду ваших комментариев.

6 комментариев:

  1. Нужен пример. И ещё подсветка кода.

    И ещё ширину нужно в цсс задавать, ящетаю. Код `container.css("width", opt.Width + "px");` выглядит грустно.

    `var scaleLen = totalWidth * scaleValue / 100;` - тоже не нужно. Разве нельзя задавать длину дива в процентах от размера родительского контейнера? Тогда не нужно этой магии с циферками.

    И да, код - на гитхаб. Тогда можно будет форкнуть, вкостылить свои изменения, и показать на примере.

    UPD: в опере не добавляются каменты.

    ОтветитьУдалить
  2. И ещё хорошо бы пример с прогресс баром в действии.

    ОтветитьУдалить
  3. И ещё: код копипастится с номерами строк. Не котируется.

    ОтветитьУдалить
  4. Тащемта вот кодярник с изменениями, которые я предлагаю. https://github.com/DNNX/multiprogressbar

    ОтветитьУдалить
  5. А он вообще динамически меняется? Если нужно прогресс какой-нибудь операции показать?

    ОтветитьУдалить
  6. На данный момент такой задачи не стояло. Самый простой способ - пересоздать. Самый правильный - дописать метод update() или ему подобный, но это в другой раз.

    ОтветитьУдалить