Bootstrap: модальное окно в модальном

Без поправок в CSS, модальное окно, открытое в модальном окне, выглядит не презентабельно — нет краёв.

Что бы поправить ситуацию, достаточно добавить CSS:

.modal:nth-of-type(even) {
    z-index: 1062 !important;
}
.modal-backdrop.show:nth-of-type(even) {
    z-index: 1061 !important;
}
    

DataTables.net: маленькие трюки

Небольшой сборник нужных трюков

  1. Выделение цветом строки, по признаку
"createdRow": function( row, data, dataIndex ) {
            if (data.deleted == true ) {
                $(row).addClass('deleted');
            }
        },

2. Вынос кнопки «Поиск» в свой контейнер

 <label for="TableSearch" class="col-form-label me-2">Поиск</label>
	<div class="me-3">
	<input type="text" id="TableSearch" class="form-control">
    </div>
...
oTable = $('#ezs_grid').DataTable();
        $('#TableSearch').keyup(function(){
        oTable.search($(this).val()).draw() ;
    });

3. Вынос кнопки «строк на странице» в свой контейнер

	<label class="me-3">Показать <select onchange="EzsGridList()" name="lengthtable" id="lengthtable" class="dataTable-selector">
		<option selected="" value="10">10</option>
		<option value="20">20</option>
		<option value="30">30</option>
		<option value="40">40</option>
		</select> строк
	</label>
...
    ezs_table=$('#ezs_grid').DataTable( {
        dom: 'rtipB',
        destroy: true,
        altEditor: true,
        "pageLength": lengthtable.value,
        "pagingType": "full_numbers",
        buttons: [

4. Вынос кнопок экспорта в свой контейнер

var buttons = new $.fn.dataTable.Buttons(table, {
         buttons: [
        { text:"Excel",extend: 'excel', className: 'excel_export_style',
            init: function(api, node, config) {
             $(node).removeClass('btn btn-secondary')
            }
    },
        { text:"Print",extend: 'print', className: 'print_export_style',
            init: function(api, node, config) {
                $(node).removeClass('btn btn-secondary')            
            }
        }
      ]
    }).container().appendTo($('#export_buttons'));

5. Отслеживание клика на строке таблицы

 $('#clientsgrid').on('dblclick', 'tbody td', function () {
         tr = $(this).closest('tr');         
         row = table.row( tr );
         data=row.data();
         user_id=data.id;         
         console.log(user_id);
    }); 

6. Перегрузка данных таблицы

table.ajax.reload();

7. Рендер своих данных для столбца

"columns": [
 { "data": null,
                render: function (data, type, row, meta) {
                    console.log(row);
                    return '<span onclick="EzsEdit('+row.id+')">E</span><span id="ezs_service_'+row.id+'" onclick="DeleteEzs('+row.id+')">D</span>';
                },
                disabled: true
            },

8. Перебор всех загруженных данных таблицы

 params_ezs_table.rows().data().each(function(entry) {
   //console.log(entry)
   if (entry.id==id){
      param_ezs_value.value=entry.value;
   };
 }); 

9. Получение id выделенной строки

 rows=segment_table.rows('.selected').data(); 
              if (rows.length>0){
                ShowDialogAttachAgreement(rows[0].id);      
              } else {
                ToastMessage("error","Внимание!","Выберите сегмент для присвоения договора");  
              };

datatables.net: вынос кнопок экспорта в любое место

Задача: задать местоположение кнопок экспорта, назначить им собственный стиль

Решение:

var buttons = new $.fn.dataTable.Buttons(table, {
         buttons: [
        { text:"Excel",extend: 'excel', className: 'excel_export_style',
            init: function(api, node, config) {
             $(node).removeClass('btn btn-secondary')
            }
    },
        { text:"Print",extend: 'print', className: 'print_export_style',
            init: function(api, node, config) {
                $(node).removeClass('btn btn-secondary')            
            }
        }
      ]
    }).container().appendTo($('#export_buttons'));

Краткое выделение всей строчки при клике в radiobutton

Проблема обнаруживается в webview приложений на android. А именно, если где-то в коде есть radiobutton обёрнутый чем угодно, то при клике по нему, кратковременно (на долю секунды) выделяется вся строчка целиком.

Решение: достаточно добавить в стилевое оформление этого элемента cursor:default

Update: достаточно применить к body -webkit-tap-highlight-color: rgba(255, 255, 255, 0);

Отрисовка календаря на 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");
       };
        
    };
1 13 14 15 16 17 55