Отрисовка календаря на JavaScript

Задача: нарисовать нечто подобное

Решение:

var days_week = [          
          'Жуть',  
          'Понедельник',
          'Вторник',
          'Среда',
          'Четверг',
          'Пятница',
          'Суббота',
          'Воскресенье',
        ];        
      var month_names=[
        "",  
        "Январь",
        "Февраль",
        "Март",
        "Апрель",
        "Май",
        "Июнь",
        "Июль",
        "Август",
        "Сентябрь",
        "Октябрь",
        "Ноябрь",
        "Декабрь"
      ];
    function GetDayWork(year,month,day){
        dayw=new Date(year, month-1, day).getDay();
        if (dayw==0) return 7;
        return dayw;
    };
    function ReturnToBookingPanel(){
      $(".DateTimePickerForBooking").hide();  
      $(".booking-now").show();
    };
    function GetLastNextCal(month,year,next){
        month=month+next;
        if (month==0){month=12;year--;}
        if (month==13){month=1;year++;}
        PaintBookingMonth(month,year);
    };
    function PaintBookingMonth(month,year){       
       cal_html='';
       cal_html=cal_html+'<div class="calendar_row calendar_row-head">';
       cal_html=cal_html+' <div class="calendar_head-date">'+month_names[month]+' <span>'+year+'</span></div>';
       cal_html=cal_html+'       <div class="calendar_row-head-arrows">';
       cal_html=cal_html+'            <div class="arrow arrow-prev" onclick="GetLastNextCal('+month+','+year+',-1)">';
       cal_html=cal_html+'                  <img src="/img/arr_cal_l.svg">';
       cal_html=cal_html+'            </div>';
       cal_html=cal_html+'            <div class="arrow arrow-next"  onclick="GetLastNextCal('+month+','+year+',1)">';
       cal_html=cal_html+'                  <img src="/img/arr_cal_r.svg">';
       cal_html=cal_html+'           </div>';
       cal_html=cal_html+'       </div>';
       cal_html=cal_html+'</div>'; 
       cal_html=cal_html+'<div class="calendar_row calendar_row-weekdays">';
       cal_html=cal_html+'   <div class="item">Пн</div>';
       cal_html=cal_html+'   <div class="item">Вт</div>';
       cal_html=cal_html+'   <div class="item">Ср</div>';
       cal_html=cal_html+'   <div class="item">Чт</div>';
       cal_html=cal_html+'   <div class="item">Пт</div>';
       cal_html=cal_html+'   <div class="item">Сб</div>';
       cal_html=cal_html+'   <div class="item">Вс</div>';
       cal_html=cal_html+'</div>';

       days = new Date(year, month, 0).getDate() 
       console.log("Дней в месяце:",days);
       // рисуем, пока не кончатся дни
       day=1;
       while (day<=days) {
          cal_html=cal_html+'<div class="calendar_row">';  
          for(let dayw = 1; dayw <= 7; dayw++) {            
            if (GetDayWork(year, month, day)==dayw){               
                if (day>days){
                  console.log("- пропуск");  
                  cal_html=cal_html+'<div class="item"></div>';  
                } else {
                  console.log(day);  
                  available="available";
                  selected="";
                  if (month<(new Date().getMonth()+1)) available=""; //если месяц меньше чем текущий
                  if (month==(new Date().getMonth()+1)){
                      if (day<new Date().getDate()) available="";
                      if (day==new Date().getDate()) selected="selected today";
                  };
                  cal_html=cal_html+'<div id="day_'+year+'_'+month+'_'+day+'" onclick="ChangeDataForBooking('+year+','+month+','+day+')" class="item '+available+' '+selected+'" data-date="'+year+'-'+month+'-'+day+'">'+day+'</div>';
                };               
               day++;
            } else {
              console.log("- пропуск");  
              cal_html=cal_html+'<div class="item"></div>';  
            };          
          };  
          cal_html=cal_html+'</div>'; 
       };       
       cal_html=cal_html+'<div class="booking_date-current_date">';
       cal_html=cal_html+'   Пятница <span>21.01.2022 январь</span>';
       cal_html=cal_html+'</div>';
       $(".booking_date-wrapper").html(cal_html);
    };
    function ChangeDataForBooking(year,month,day){
       console.log("!ChangeDataForBooking",year,month,day); 
       if ($('#day_'+year+'_'+month+'_'+day).hasClass("available")){
         $(".item").removeClass("selected");   
         $('#day_'+year+'_'+month+'_'+day).addClass("selected");
       };
        
    };

JavaScript: отслеживание клика вне элемента

Задача: отследить клик вне элемента div.

Решение: для этого навесим событие на клик вышестоящего элемента, и при клике анализируем, то на чём кликнули «внутри» или «снаружи»:

Например:

html:

<div class="el1">
   <div class="el2"></div>
   <div class="el3"></div>
   <div class="el4"></div>
   <div class="el5"></div>



</div>

javascript:

$(".el1" ).bind( "click", function(e) {
                        if ( $(e.target).closest('.el4').length ) {
                            console.log("внутри");
                        return;
                        };
                        console.log("снаружи");  
                   });

Datatables.net: субгриды для таблицы

Задача: при щелчке по одной из ячеек, разворачивать «subgrid» для таблицы. Примерно так:

Решение:

<table id="ownersgrid" class="display" style="width:100%">
        <thead>
            <tr>                
                <th>#</th>
                <th></th>
                <th>Наименование</th>
                <th>Полное наименование</th>
                <th>Телефон</th>    
                <th>Email</th> 
                <th>Договора</th>
            </tr>
        </thead>
</table>

<script>
 ownerstable=$('#ownersgrid').DataTable( {
        dom: 'frtipB',
        destroy: true,
        select: true,
        lengthMenu: [
            [ 10, 25, 50, -1 ],
            [ '10 строк', '25 строк', '50 строк', 'Все строки' ]
        ],
        buttons: [            
            {
            text: 'Редактировать',
                action: function ( e, dt, node, config ) {
                  ConnectorEdit("edit");  
                }
            },
            {
            text: 'Добавить',
                action: function ( e, dt, node, config ) {
                  ConnectorEdit("add");  
                }
            },
            
            'excel','print','pageLength',
        ],        
         paging: true,
         keys: true,
         //scrollY:        400,
        //scrollCollapse: true,
        //scroller:       true,         
        "processing": true,
        "serverSide": true,
        "ajax": {
            "url": "/server/owners/OwnersGrid",
            "type": "POST",
            "data": {               
            }
        },
    "language": {
             url: '/js/i18n/datatable.json'
        },        
    "columns": [                    
            { "data": "id"},
            { "data": "deleted" },
            { "data": "name"},
            { "data": "full_name" },
            { "data": "phone" },
            { "data": "email" },
            { className: 'dt-control',orderable: false,data: null,defaultContent: '',width: '10%'},
        ]        
    } );
    $('#ownersgrid').unbind();
    $('#ownersgrid').on('dblclick', 'tbody td', function () {        
         OwnerEdit("edit");
    }); 
    $('#ownersgrid tbody').on('click', 'td.dt-control', function () {
        var tr = $(this).closest('tr');
        var row = ownerstable.row( tr );

        if ( row.child.isShown() ) {
            // This row is already open - close it
            destroyChild(row);
            tr.removeClass('shown');
        }
        else {
            // Open this row
            createChild(row);
            tr.addClass('shown');
        }
    } );    
function createChild ( row ) {
    // This is the table we'll convert into a DataTable
    var table = $('<table class="display" style="width:100%">'+
        '<thead>'+
        '    <tr>                '+
        '        <th>#</th>'+
        '        <th></th>'+
        '        <th>Наименование</th>'+
        '        <th>Полное наименование</th>'+
        '        <th>Телефон</th>    '+
        '        <th>Email</th> '+
        '        <th>Договора</th>'+
        '    </tr>'+
       ' </thead>'+
    '</table>');


    // Display it the child row
    row.child( table ).show();
 
    // Initialise as a DataTable
    var usersTable = table.DataTable( {
       dom: 't',
        destroy: true,
        select: true,
        lengthMenu: [
            [ 10, 25, 50, -1 ],
            [ '10 строк', '25 строк', '50 строк', 'Все строки' ]
        ],
        buttons: [            
            {
            text: 'Редактировать',
                action: function ( e, dt, node, config ) {
                  ConnectorEdit("edit");  
                }
            },
            {
            text: 'Добавить',
                action: function ( e, dt, node, config ) {
                  ConnectorEdit("add");  
                }
            },
            
            'excel','print','pageLength',
        ],        
         paging: true,
         keys: true,
         //scrollY:        400,
        //scrollCollapse: true,
        //scroller:       true,         
        "processing": true,
        "serverSide": true,
        "ajax": {
            "url": "/server/owners/OwnersGrid",
            "type": "POST",
            "data": {               
            }
        },
    "language": {
             url: '/js/i18n/datatable.json'
        },        
    "columns": [                    
            { "data": "id"},
            { "data": "deleted" },
            { "data": "name"},
            { "data": "full_name" },
            { "data": "phone" },
            { "data": "email" },
            { className: 'dt-control',orderable: false,data: null,defaultContent: '',width: '10%'},
        ]        
    } );
};
function destroyChild(row) {
    var table = $("table", row.child());
    table.detach();
    table.DataTable().destroy();
 
    // And then hide the row
    row.child.hide();
}
</script>

Битрикс: Вывод файла в детальном отображении товара

Задача: 1) позволять прикреплять инструкцию к товару. 2) Отображать её в товаре, в том случае если файл прикреплен.

Решение:

  1. Добавляем руками новое свойство в информационном блоке «Основной каталог товаров»

2) Открываем шаблон детального отображения товара и добавляем:

В начале файла, заполняем переменную $INCTRUCTION_SRC

<?		
$res = CIBlockElement::GetProperty($arResult['IBLOCK_ID'], $arResult['ID'], "sort", "asc", array("CODE" => "files"));
if ($ob = $res->GetNext())
    {			
$INSTRUCTION_VALUE = $ob['VALUE'];
$file = CFile::GetFileArray($INSTRUCTION_VALUE);
$INSTRUCTION_SRC = $file['SRC'];
    }
?>

В нужном месте для вывода добавляем:

<?php
 if ($INSTRUCTION_SRC!=""){
?>
<a href="<?=$INSTRUCTION_SRC;?>">Инструкция</a>
<?php
};
?>

Результат:

datatables.net: перекашивает заголовок таблицы при переключении между вкладками

При переключении между вкладками, иногда шапка таблицы «узежает».

Решение: в момент переключения вкладок, «перерисовываем» шапку:

    $("#tabs").tabs({
	activate: function( event, ui ) { 
		$('#client_pays_grid').dataTable().fnAdjustColumnSizing();
   });
1 14 15 16 17 18 56