Используйте Javascript для сравнения временных диапазонов в PDF-форме - PullRequest
0 голосов
/ 28 июня 2018

У меня есть PDF-форма с 6 различными периодами времени для каждого дня месяца, и я должен убедиться, что эти периоды не перекрываются, когда пользователь их заполняет. Не все периоды времени могут быть завершены, но те, которые делают, должны быть уникальными. Я черпал вдохновение из этого предыдущего поста Используйте JavaScript для сравнения временных интервалов , в частности, вклад @RobG. Однако отсутствие у меня знаний в области сценариев мешает мне формировать этот код для моего конкретного приложения. В дополнение к проверке периодов времени, я также должен повторять это для каждого дня в форме, но я хотел бы сделать это один день за один раз, особенно когда записи сделаны для этого дня. Поскольку это PDF-форма, я не уверен, как выполнить эту проверку. Например, должен ли он выполняться каждый раз по истечении определенного периода времени? То есть есть время начала и время окончания? Таким образом, это будет действовать как «сценарий проверки» для этой записи времени? Вот пример того, как выглядит форма:

enter image description here

enter image description here

Вот моя попытка обновить код для моей формы:

var TimeIn1 = this.getField("Day1Pd1TimeInRes").value;
var TimeOut1 = this.getField("Day1Pd1TimeOutRes").value;
var TimeIn2 = this.getField("Day1Pd2TimeInRes").value;
var TimeOut2 =  this.getField("Day1Pd2TimeOutRes").value;
var TimeIn3 = this.getField("Day1Pd3TimeInRes").value;
var TimeOut3 = this.getField("Day1Pd3TimeOutRes").value;
var TimeIn4 = this.getField("Day1Pd4TimeInRes").value;
var TimeOut4 = this.getField("Day1Pd4TimeOutRes").value;
var TimeIn5 = this.getField("Day1Pd5TimeInRes").value;
var TimeOut5 =  this.getField("Day1Pd5TimeOutRes").value;
var TimeIn6 = this.getField("Day1Pd6TimeInRes").value;
var TimeOut6 = this.getField("Day1Pd6TimeOutRes").value;

var timeSlots = [
  {BeginTime: new Date("10/25/2015 " + TimeIn1),
   EndTime: new Date("10/25/2015 " + TimeOut1)},
  {BeginTime: new Date("10/25/2015 " + TimeIn2),
   EndTime: new Date("10/25/2015 " + TimeOut2)},
  {BeginTime: new Date("10/25/2015 " + TimeIn3),
   EndTime: new Date("10/25/2015 " + TimeOut3)},
  {BeginTime: new Date("10/25/2015 " + TimeIn4),
   EndTime: new Date("10/25/2015 " + TimeOut4)},
  {BeginTime: new Date("10/25/2015 " + TimeIn5),
   EndTime: new Date("10/25/2015 " + TimeOut5)},
  {BeginTime: new Date("10/25/2015 " + TimeIn6),
   EndTime: new Date("10/25/2015 " + TimeOut6)}
];
function slotFits(slot) {
  if (timeSlots.length == 0) return true; // If no slots, must fit
  return timeSlots.some(function(s, i) {
    return (i == 0 && slot.EndTime <= s.BeginTime) || //slot is before all others
  (s.EndTime <= slot.BeginTime && !timeSlots[i + 1]) || //slot is after all others
  (s.EndTime <= slot.BeginTime && timeSlots[i + 1].BeginTime >= slot.EndTime) // Slot between others
  });
}

[{BeginTime: new Date("10/25/2015 " + TimeIn1),
  EndTime: new Date("10/25/2015 " + TimeOut1)},
 {BeginTime: new Date("10/25/2015 " + TimeIn2),
  EndTime: new Date("10/25/2015 " + TimeOut2)},
 {BeginTime: new Date("10/25/2015 " + TimeIn3),
  EndTime: new Date("10/25/2015 " + TimeOut3)},
 {BeginTime: new Date("10/25/2015 " + TimeIn4),
  EndTime: new Date("10/25/2015 " + TimeOut4)},
 {BeginTime: new Date("10/25/2015 " + TimeIn5),
  EndTime: new Date("10/25/2015 " + TimeOut5)},
 {BeginTime: new Date("10/25/2015 " + TimeIn6),
  EndTime: new Date("10/25/2015 " + TimeOut6)},
].forEach(function(slot, i) {
  app.alert('Slot ' + i + ': ' + slotFits(slot));
});

В этом примере я прописал имена полей, но, поскольку я буду повторять это до 31 дня, я хотел бы найти способ создания сценария документа, в который я мог бы вставить TimeIn. и 'Переменные TimeOut и вызывать их для каждого дня, но я думаю, что я могу обойтись без этого в случае необходимости, просто обеспокоившись размером формы, повторяющим столько кода для 6 периодов в течение потенциально 31 дня. Спасибо!

Редактировать: Значения времени: ЧЧ: мм

1 Ответ

0 голосов
/ 29 июня 2018

Давайте немного перепишем это, потому что типичное решение «все становится странно сложным», как правило, «выбрать лучшую структуру данных», что в данном случае означает использование представления Entry и создание того, что делает работу за вас.

Учитывая, что Foxit, очевидно, не поддерживает современный JS, при использовании более старой ES5 это будет выглядеть примерно так:

function Entry(pdfObject, day, pd, dateOffset) {
  this.id = day + '-' + pd;
  this.in = pdfObject.getField('Day'+day+'Pd'+pd+'TimeInRes').value;
  this.out = pdfObject.getField('Day'+day+'Pd'+pd+'TimeOutRes').value;
  this.begin = new Date(dateOffset+' '+this.in);
  this.end = new Date(dateOffset+' '+this.out);
  this.interval = this.end.getTime() - this.begin.getTime(); 
}

Entry.prototype = {
  checkFit: function checkFit(entries) {
    // 1: find out where our start fits into the list of start times
    var start = -1, l = entries.length, other, i, e;
    for (i=0; i<l; i++) {
      e = entries[i];
      if (this.begin < e.begin) {
        start = i;
        other = e;
      }
      if (this.begin > e.begin) break;
    }
    // are we the last entry? if so, we fit if we start after the last end.
    if (!other || start === l-1) return (this.begin > entries[l-1].end);
    // IF not, there is a next entry; do we end before that begins?
    return other.begin <= this.end;
  }
}

Entry.loadAll = function loadAll(pdfObject, day, dateOffset) {
  return [1,2,3,4,5,6]
         .map(function(i) { return new Entry(pdfObject, day, i, dateOffset); })
         .sort(function(a,b) { return a.end - b.end; });
}

И затем мы можем использовать этот объект, используя такой код:

// Make sure we have a reference to the pdf API so we can getField etc.
var pdfObject = this;

// I'm assuming the day and date offset should not be hardcoded
var entries = Entry.loadAll(pdfObject, 1, "10/25/2015");

// check the entries
entries.forEach( function(entry) {
  let fits = entry.checkFit(entries);
  console.log('Slot check for entry '+entry.id+': '+fits);
});
...