Revision 609

Date:
2016/11/02 14:43:55
Author:
ahitrov
Revision Log:
Manual document sorting using ajax.
Inline editing type can differ from form editing type.

Files:

Legend:

 
Added
 
Removed
 
Modified
  • utf8/core/comps/contenido/ajax/document_move.html

     
    1 <% $json %>
    2 <%once>
    3
    4 use JSON::XS;
    5
    6 </%once>
    7 <%args>
    8
    9 $id => undef
    10 $aid => undef
    11 $s => undef
    12 $move => undef
    13
    14 </%args>
    15 <%init>
    16
    17 my %result;
    18
    19 if ( $id && $id =~ /^\d+$/ && $s && $s =~ /^\d+$/ && $move && $move =~ /^(up|down|first|last|before|after)$/ && (!$aid || $aid && $aid =~ /^\d+$/) ) {
    20 my $section = $keeper->get_section_by_id( $s );
    21 if ( ref $section ) {
    22 if ( $section->_sorted ) {
    23 if ( $section->dmove( $id, $move, $aid ) ) {
    24 my $position = $section->_get_document_pos( $id );
    25 warn Dumper( $position );
    26 if ( ref $position && exists $position->{index} ) {
    27 if ( exists $position->{before} ) {
    28 $result{before} = $position->{before};
    29 $result{success} = 1;
    30 }
    31 if ( exists $position->{after} ) {
    32 $result{after} = $position->{after};
    33 $result{success} = 1;
    34 }
    35 if ( exists $position->{first} ) {
    36 $result{first} = 1;
    37 $result{success} = 1;
    38 }
    39 if ( exists $position->{last} ) {
    40 $result{last} = 1;
    41 $result{success} = 1;
    42 }
    43 unless ( exists $result{success} ) {
    44 $result{error} = Encode::decode('utf-8', 'Ошибка индексации. Для разбора полетов обратитесь к разработчикам');
    45 }
    46 } else {
    47 $result{error} = Encode::decode('utf-8', 'Ошибка индексации. Для разбора полетов обратитесь к разработчикам');
    48 }
    49 } else {
    50 $result{error} = Encode::decode('utf-8', 'Ошибка перемещения. Для разбора полетов обратитесь к разработчикам');
    51 }
    52 } else {
    53 $result{error} = Encode::decode('utf-8', 'В данной секции отключен режим ручной сортировки');
    54 }
    55 } else {
    56 $result{error} = Encode::decode('utf-8', 'Секция не найдена');
    57 }
    58 } else {
    59 $result{error} = Encode::decode('utf-8', 'Переданы неверные параметры');
    60 }
    61
    62 my $json = encode_json \%result;
    63
    64 </%init>
  • utf8/core/comps/contenido/components/section_browse.msn

     
    42 42 });
    43 43 % }
    44 44
    45
    46 45 function mydump(arr,level) {
    47 46 var dumped_text = "";
    48 47 if(!level) level = 0;
     
    67 66 return dumped_text;
    68 67 }
    69 68
    70
    69 $(document).ready(function(){
    70 $('.move-up').on('click', function( ev ){
    71 ev.preventDefault();
    72 var $nID = $(this).data('id');
    73 $.ajax({
    74 'url' : '/contenido/ajax/document_move.html',
    75 'data' : { 's' : <% ref $section ? $section->id : 0 %>, 'id' : $nID, 'move' : 'up' },
    76 'dataType' : 'json',
    77 'success' : function( data ){
    78 if ( data.error ) {
    79 alert( data.error );
    80 } else if ( data.before ) {
    81 var $nBefore = data.before;
    82 $('#row-' + $nID).insertBefore('#row-' + $nBefore);
    83 }
    84 }
    85 });
    86 });
    87 $('.move-down').on('click', function( ev ){
    88 ev.preventDefault();
    89 var $nID = $(this).data('id');
    90 $.ajax({
    91 'url' : '/contenido/ajax/document_move.html',
    92 'data' : { 's' : <% ref $section ? $section->id : 0 %>, 'id' : $nID, 'move' : 'up' },
    93 'dataType' : 'json',
    94 'success' : function( data ){
    95 if ( data.error ) {
    96 alert( data.error );
    97 } else if ( data.after ) {
    98 var $nAfter = data.after;
    99 $('#row-' + $nID).insertAfter('#row-' + $nAfter);
    100 }
    101 }
    102 });
    103 });
    104 });
    71 105 //-->
    72 106 </script>
    73 107 <form name="section_browse" action="sections.html" method="POST">
     
    151 185 my $params_unsection = ref $filter eq 'HASH' ? join ('&', map { $_.'='.$filter->{$_} } grep { $_ ne 's' } keys %$filter ) : '';
    152 186
    153 187 my %lookup_elements;
    154 my @inline_pickups = grep { exists $_->{inline} && ($_->{type} eq 'pickup' || $_->{type} eq 'autocomplete') } @$columns;
    188 my @inline_pickups = grep {
    189 my $type = exists $_->{inline_type} ? $_->{inline_type} : $_->{type};
    190 exists $_->{inline} && ($type eq 'pickup' || $type eq 'autocomplete')
    191 } @$columns;
    155 192
    156 193 map {
    157 194 $_->{document_access} = $user->section_accesses($user, $_->section);
  • utf8/core/comps/contenido/components/section_browse_row.msn

     
    1 <tr valign="top">
    1 <tr valign="top" id="row-<% $document->id %>">
    2 2 <td nowrap>\
    3 3 % if ($document_access == 2) {
    4 4 <input type="checkbox" class="common-check" name="<% 'delete_'.$document->id.'_id' %>">
     
    10 10 % for my $col (@$columns) {
    11 11 % if ($col->{attr} eq '_sort_') {
    12 12 %
    13 <td width="20px"><% $document->{sorder} %>&nbsp;<a
    13 <td width="20px"><% $document->{sorder} %>&nbsp;<a class="move-up" data-id="<% $document->id %>"
    14 14 href="document_move.html?id=<% $document->{id} %>&move=up&s=<% $id %><% $params_unsection ? '&'.$params_unsection : '' %>"><img
    15 src="/contenido/i/ico-up-9x10.gif" border=0 alt="Переместить документ на шаг вверх"></a>&nbsp;<a
    15 src="/contenido/i/ico-up-9x10.gif" border=0 alt="Переместить документ на шаг вверх"></a>&nbsp;<a class="move-down" data-id="<% $document->id %>"
    16 16 href="document_move.html?id=<% $document->{id} %>&move=down&s=<% $id %><% $params_unsection ? '&'.$params_unsection : '' %>"><img
    17 17 src="/contenido/i/ico-down-9x10.gif" border=0 alt="Переместить документ на шаг вниз"></a>\
    18 18 %
     
    56 56 %
    57 57 % } elsif ( exists $col->{inline} && $col->{inline} ) {
    58 58 % my $attr = $col->{attr};
    59 % if ( $col->{type} =~ /^(string|integer|float)$/ && $col->{inline} ) {
    59 % my $type = exists $col->{inline_type} ? $col->{inline_type} : $col->{type};
    60 % if ( $type =~ /^(string|integer|float)$/ && $col->{inline} ) {
    60 61 % my $style = $col->{inline_style} ? $col->{inline_style} : ($col->{type} =~ /^(integer|float)$/ ? 'text-align:right; ' : '' );
    61 62 % $style .= $col->{inline_width} ? ' width:'.$col->{inline_width}.'px; ' : ' width:65px; ';
    62 63 <td><input type="text" name="<% 'update_'.$document->id.'_'.$attr %>" value="<% $document->$attr |h %>" style="<% $style %>">
    63 % } elsif ($col->{type} eq 'checkbox') {
    64 % } elsif ($type eq 'checkbox') {
    64 65 % my $checked = $document->$attr ? ' checked' : '';
    65 66 <td align="center"><input type="checkbox" class="<% $attr %>-check" name="<% 'update_'.$document->id.'_'.$attr %>"<% $checked %>>
    66 % } elsif ($col->{type} eq 'text') {
    67 % } elsif ($type eq 'text') {
    67 68 % my $style = $col->{inline_style} ? $col->{inline_style} : '';
    68 69 % $style .= $col->{inline_width} ? ' width:'.$col->{inline_width}.'px; ' : ' width:100px; ';
    69 70 % $style .= $col->{inline_height} ? ' width:'.$col->{inline_height}.'px; ' : ' height:70px; ';
     
    73 74 % s/>/&gt;/sgi;
    74 75 % }
    75 76 <td><textarea name="<% 'update_'.$document->id.'_'.$attr %>" style="<% $style %>"><% $value %></textarea>
    76 % } elsif ($col->{type} eq 'select') {
    77 % } elsif ($type eq 'select') {
    77 78 % my $options = {};
    78 79 % if ($toopi && (ref($toopi) eq 'HASH') && (exists($toopi->{$document->class}))) {
    79 80 % %{ $options } = %{ $toopi->{$document->class} };
     
    87 88 % }
    88 89 % }
    89 90 </select>
    90 % } elsif ($col->{type} eq 'status') {
    91 % } elsif ($type eq 'status') {
    91 92 % my $cases = $col->{cases};
    92 93 % if ( ref $cases eq 'ARRAY' ) {
    93 94 <td><select name="<% 'update_'.$document->id.'_'.$attr %>" style="<% $col->{inline_width} ? 'width:'.$col->{inline_width}.'px;' : '' %> <% $col->{inline_style} || '' %>" autocomplete="off">
     
    97 98 % }
    98 99 </select>
    99 100 % }
    100 % } elsif ($col->{type} eq 'pickup' || $col->{type} eq 'autocomplete') {
    101 % } elsif ($type eq 'pickup' || $type eq 'autocomplete') {
    101 102 % my %opts = %{ $col->{lookup_opts} };
    102 103 % my $doc;
    103 104 % if ( $document->$attr ) {
     
    108 109 title="<% defined $document->$attr ? 'Значение: '.$document->$attr : '' %>"
    109 110 rel="<% 'update_'.$document->id.'_'.$attr %>" style="<% $col->{inline_width} ? 'width:'.$col->{inline_width}.'px;' : '' %> <% $col->{inline_style} || '' %>"
    110 111 old-value="<% (ref $doc ? $doc->name : '') |h %>" onfocus="" onblur="">
    111 % } elsif ($col->{type} eq 'lookup') {
    112 % } elsif ($type eq 'lookup') {
    112 113 % my %opts = %{ $col->{lookup_opts} };
    113 114 % delete $opts{search_by} if exists $opts{search_by};
    114 115 % my $docs;
     
    139 140 %
    140 141 <td><% $document->class_name %>&nbsp;<font color="#999999">(<% $document->class %>)</font>\
    141 142 %
    142 % } elsif ($col->{type} eq 'datetime') {
    143 % } elsif ($type eq 'datetime') {
    143 144 %
    144 145 <td nowrap><& "/contenido/components/show_dtime.msn", dtime=>$document->{$col->{attr}} &>\
    145 146 %
     
    176 177 %
    177 178 % } else {
    178 179 % my $attr = $col->{attr};
    179 % if ($col->{type} eq 'date') {
    180 % if ($type eq 'date') {
    180 181 % my $date=$document->{$col->{attr}};
    181 182 % $date=~/(\d{4}-\d{2}-\d{2})/;
    182 183 <td nowrap align="right"><% $1 || '&nbsp;' %>\
    183 % } elsif ($col->{type} eq 'datetime') {
    184 % } elsif ($type eq 'datetime') {
    184 185 <td nowrap align="right"><% $document->{$col->{attr}} || '&nbsp;' %>\
    185 % } elsif ($col->{type} eq 'integer') {
    186 % } elsif ($type eq 'integer') {
    186 187 <td align="right"><% $document->{$col->{attr}} %>&nbsp;\
    187 % } elsif ($col->{type} eq 'lookup' || $col->{type} eq 'pickup' || $col->{type} eq 'autocomplete') {
    188 % } elsif ($type eq 'lookup' || $type eq 'pickup' || $type eq 'autocomplete') {
    188 189 <td align="left">\
    189 190 % my $id = $document->{$col->{attr}};
    190 191 % if ($id) {
     
    197 198 % } else {
    198 199 <span class="hiddensect">NULL</span>\
    199 200 % }
    200 % } elsif ($col->{type} eq 'checkbox') {
    201 % } elsif ($type eq 'checkbox') {
    201 202 <td align="center"><% $document->$attr ? '<img src="/contenido/i/checked-16x16.png" width="16" height="16">' : '&nbsp;' %>\
    202 % } elsif ($col->{type} eq 'status') {
    203 % } elsif ($type eq 'status') {
    203 204 % my $status_map = ref $col->{cases} eq 'ARRAY' ? $col->{cases} : $keeper->default_status();
    204 205 % my ($doc_status) = grep { $_->[0] eq $document->{$col->{attr}} } @$status_map;
    205 206 % $doc_status ||= [$document->{$col->{attr}}, 'Неизвестный'];
  • utf8/core/lib/Contenido/Section.pm

     
    200 200
    201 201 sub _get_document_order {
    202 202 my ($self) = shift;
    203 return unless $self->_sorted;
    203 204
    204 205 my @order = $self->_sorted_order ? split( /,/, $self->_sorted_order ) : ();
    205 206
     
    244 245 }
    245 246
    246 247
    248 sub _get_document_pos {
    249 my ($self) = shift;
    250 my ($doc_id) = shift;
    251 return unless $doc_id && $doc_id =~ /^\d+$/;
    252 return unless $self->_sorted;
    253
    254 my @order = $self->_sorted_order ? split( /,/, $self->_sorted_order ) : ();
    255 my %pos;
    256 for ( my $i = 0; $i < scalar @order; $i++ ) {
    257 if ( $order[$i] == $doc_id ) {
    258 $pos{index} = $i;
    259 if ( $i > 0 ) {
    260 $pos{after} = $order[$i-1];
    261 }
    262 if ( $i < $#order ) {
    263 $pos{before} = $order[$i+1];
    264 }
    265 if ( $i == $#order ) {
    266 $pos{last} = 1;
    267 } elsif ( $i == 0 ) {
    268 $pos{first} = 1;
    269 }
    270 last;
    271 }
    272 }
    273 return (exists $pos{index} ? \%pos : undef);
    274 }
    275
    276
    247 277 # ----------------------------------------------------------------------------
    248 278 # Метод для перемещение секции вверх/вниз по рубрикатору (изменение
    249 279 # sorder)...

Небольшая справка по веткам

cnddist – контейнер, в котором хранятся все дистрибутивы всех библиотек и программных пакетов, которые использовались при построении различных версий Contenido. Если какой-то библиотеки в данном хранилище нет, инсталлятор сделает попытку "подтянуть" ее с веба (например, с CPAN). Если библиотека слишком старая, есть очень большая вероятность, что ее там уже нет. Поэтому мы храним весь хлам от всех сборок. Если какой-то дистрибутив вдруг отсутствует в cnddist - напишите нам, мы положим его туда.

koi8 – отмирающая ветка, чей код, выдача и все внутренние библиотеки заточены на кодировку KOI8-R. Вносятся только те дополнения, которые касаются внешнего вида и функционала админки, баги ядра, обязательные обновления портов и мелочи, которые легко скопипастить. В дальнейшем планируется полная остановка поддержки по данной ветке.

utf8 – актуальная ветка, заточенная под UTF-8.

Внутри каждой ветки: core – исходники ядра; install – скрипт установки инсталляции; plugins – плагины; samples – "готовые к употреблению" проекты, которые можно поставить, запустить и посмотреть, как они работают.