Редактируемый список

25-09-2010

В этом уроке попробуем создать редактируемый список, то есть элементы списка можно будет перемещать вверх, вниз, а также удалять элементы списка. Внешне это все будет выглядеть примерно так:

uledit

Конечно же будем использовать javascript также библиотеку jQuery, для перемещения элементов по списку. Ну а начнем как всегда с html.

HTML

Для начала создадим простой неупорядоченный список с пару элементами:

<ul class="mylist">
	<li>1. Element1</li>
	<li>2. Element2</li>
	<li>3. Element3</li>
</ul>

Теперь нам надо как то структурировать наши элементы для для удобного обращения к ним через javascript, также создадим три кнопки вверх, вниз и кнопку удаления. После преобразований код элемента выглядит следующим образом:

<li>
	<span class="num">1.</span>
	<span class="subj">Element1</span>
	
	<div class="top"></div>
	<div class="bottom"></div>
	<div class="delete"></div>
</li>

Далее нужно проделать тоже самое со всеми элементами. Теперь наши элементы имеют следующую структуру:

editeble ul

С html вроде все понятно давайте теперь приведем это все в божеский вид. Приступим к CSS.

CSS

Зададим списку какую нибудь ширину и расположим посередине, еще уберем отступы зададим фон в общем вот:

.mylist{
    background:#eee;
    padding:0px;
    list-style:none;
    margin:0px;
    width:250px;
    margin:0px auto;
    border:1px solid #aaa;
    border-top:none;
  }

Дальше приступим к самим элементам списка, установим отступы (pdding), ну и какой нибудь эффект при наведении:

.mylist li{
    border-top:1px solid #aaa;
    padding:4px 7px;
    overflow:hidden;
  }
.mylist li:hover{
    background:#bbb;
  }

Теперь уже приступим к содержимому самих элементов это два spana и три diva начнем со spanов:

.mylist .num{
    color:#000;
    width:30px;
    float:left;
  }
.mylist .subj{
    color:#444;
    width:150px;
    float:left;
  }

Цвет текста, ширины и floata думаю достаточно, все таки это пост не о том как красивее оформить список :). Дальше приступим к divам , кнопкам, скроем их и будем показывать только при наведении на элемент списка, ну еще разукрасим в разные цвета чтоб они отличались, допустим кнопка вверх будет зеленым цветом, вниз оранжевым, кнопка удаления красным:

.mylist div{
    visibility:hidden;
    cursor:pointer;
  }
.mylist li:hover div{
    visibility:visible;
  }
.mylist .top{
    height:17px;
    width:17px;
    float:left;
    background:green;
  }
.mylist .bottom{
    height:17px;
    width:17px;
    float:left;
    background:orange;
  }
.mylist .delete{
    height:17px;
    width:17px;
    float:left;
    background:red;
  }

Теперь мы имеем готовый стилизованный кое как список выглядящий вот так:


Осталось написать javascript функции управления этим списком, приступим.

Javascript

Начнем раздел javascript чуть чуть не с javascripta , я решил все таки вынести этот пункт сюда. Нашим кнопка следует прописать onclck равным функциям которые будут вызываться по нажатию на определенный тип кнопки. Вот список того кому че нужно прописывать:

  • top onclick=move_top([здесь порядковый номер элемента в списке])
  • bottom onclick=move_bottom([здесь порядковый номер элемента в списке])
  • delete onclick=delete([здесь порядковый номер элемента в списке])

В итоге элемент, допустим второй будет выглядеть так:

<li class="li2">
      
  <span class="num">2.</span>
  <span class="subj"> Elemen2</span>
  
  <div class="top" onclick="move_top(2)"></div>
  <div class="bottom" onclick="move_bottom(2)"></div>
  <div class="delete" onclick="delete_li(2)"></div>
  
</li>

И наконец приступим к javascriptу для начала создадим функцию создания элемента входным параметрами которого будут порядковый номер элемента в списке и текст создаваемого элемента:

function create_new_li(el_id,el_text){
      
    return '<li class="li'+el_id+'">\
      \
      <span class="num">'+el_id+'.</span>\
      <span class="subj"> '+el_text+'</span>\
      \
      <div class="top" onclick="move_top('+el_id+')"></div>\
      <div class="bottom" onclick="move_bottom('+el_id+')"></div>\
      <div class="delete" onclick="delete_li('+el_id+')"></div>\
      \
      \
    </li>';  
    
}//end of the function create_new_li

Функция как вы заметили не создает а просто возвращает строку содержащую разметку нового элемента. Начнем написание функция которые мы прописывали для кнопок. Итак функция move_top:

function move_top(el_id){
  
  if(el_id!=1){
    
    //узнаем ид верхнего li
    var top_li_id = el_id-1;
    
    //узнаем текст верхнего li
    var top_li_text = $('li.li'+top_li_id+' .subj').html();
    
    //удаляем верхний li
    $('li.li'+top_li_id).remove();

    //узнаем текст перемещаемого элемента
    var per_li_text = $('li.li'+el_id+' .subj').html();
    
    //создаем копию перемещаемого вверх элемента над ни же с другим ид
    var newli = create_new_li(top_li_id,per_li_text);
    $('li.li'+el_id).before(newli);

    //удаляем перемещаемый элемент
    $('li.li'+el_id).remove();
    
    //зодаем под до этого созданным элементом эелемент который был до этого над
    //перемещаемым вверх, создаем его с ид на 1 меньше
    var newli = create_new_li(el_id,top_li_text);
    $('li.li'+top_li_id).after(newli);

    
  }//end if
  
}//end of the function move_top

Вкратце как работает эта функция, она сперва удаляет элемент расположенный над перемещаемым, в данном случае вверх, и создает на его место копию своего элемента, но уже с другим порядковым номером и ид на один меньше, так как счет идет сверху вниз (ид и порядковый номер соводают точнее конец ид), затем она удаляет перемещаемый элемент и создает на его месте до этого удаленный элемент, опять же с другим ид (в этот раз на 1больше).
Тперь разберемся с другой функцией, которая перемещает наоборот вниз move_bottom:

function move_bottom(el_id){
     
   //узнаем количество элементов в списке
   var li_count = $('.mylist li').size();
  
   //проверяем не пытаемся ли мы сместить вниз последний элемент
   if(el_id!=li_count){
  
     //узнаем порядковый номер нижнего элемента
    var bot_li_id = el_id+1;
    
    //узнаем текст элемента расположенного под перемещаемым
    var bot_li_text = $('li.li'+bot_li_id+' .subj').html();
    
    //удаляем елемент расположенный под перемещаемым
    $('li.li'+bot_li_id).remove();
     
    //узнаем текст перемещаемого элемента
    var per_li_text = $('li.li'+el_id+' .subj').html();
    
    //создаем копию перемещаемого вниз элемента под ним же с другим ил +1
    var newli = create_new_li(bot_li_id,per_li_text);
    $('li.li'+el_id).after(newli);
     
    //удаляем перемещаемый элемент
    $('li.li'+el_id).remove();
     
    //создаем над созданным элементом копию элемнета котрый был расположен под
    //перемещаемым элементом
    var newli = create_new_li(el_id,bot_li_text);
    $('li.li'+bot_li_id).before(newli);
     
   }//end if
    
}//end function move_bottom

В принципе эта функция делает то же самое что и предыдущая только наоборот, даже описвать ниче не надо :), комментариев тоже думаю достаточно.
Ну и последняя фукция для кнопки удаления элемента delete:

function delete_li(el_id){

  //узнаем количество элементов в списке
  var li_count = $('.mylist li').size();
  
  //если елемент не последний пересоздаем нижние элементы
  //с другими ид
  if(el_id!=li_count){
  
    //узнаем количество элементов после удаляемого
    var dif = li_count - el_id;
    
    //удаляем удаляемый элемент
    $('li.li'+el_id).remove();
    
    //копмруем порядковый номер удоля
    var count = el_id;
    
    //проходим циклом под элементам расположенныым под удаленным
    //и пересоздаем их
    for(i=1;i<=dif;i++){
    
      //узнаем порядковый номер следующего элемента
      var next_el = count*1 + 1;
      
      //узнаем текст следующего элемента
      var next_li_text = $('li.li'+next_el+' .subj').html();
      
      //пересоздаем элемент
      var newli = create_new_li(count,next_li_text);
      $('li.li'+next_el).before(newli);
      
      //удаляем элемент
      $('li.li'+next_el).remove();
      
      
      count++
    }
    
  }
  //если элемент последний просто удоляем его  
  else{
    
    //удаляем элемент
    $('li.li'+el_id).remove();
  
  }//end else
  
}//end function delete_li

Функция сперва проверяет последний ли проверяемы элемент или нет, если последний просто удаляем его а если не последний удаляем элемент и пересоздаем нижние элементы с новыми порядковыми номерами.
Прогнозы на спорт
Вот и все вот и tutorial'у конец :). Смотрим тестируем комментируем ->

ДЕМО ВЕРСИЯ
посмотреть в действииСКАЧАТЬ
скачать на компьютер