 
 LIST    = 1
 INTEGER = 2
 YEAR    = 3
 FLOAT   = 4
 STRING  = 5 
 DAY     = 6
 DATE    = 8
 RADIO   = 9
 LOCATION = 10
 var uiv_Email = 11
 var uiv_Color = 12
 var uiv_Time  = 13
 var uiv_DateTimeSelectorA = 14
 
 NOTREQ = 0
 REQ = 1
 MLSREQ = 2
 TRANSREQ = 3
 CREDREQ = 4
 PERSREQ = 5
 COMPREQ = 6


// Wypisuje komunikat o błędzie i ustawia kursor w polu
function AbortEntry(sMsg, eSrc, tabname)
{
  window.alert(sMsg);
  if(tabname) {
    SelectTab(tabname);
  }
  if(IsThisRadioButtonArray(eSrc)) eSrc = eSrc[0];
  if(eSrc && CanFocuss(eSrc)){
    eSrc.focus();
  }
  return false
}

// być może do poprawy
function CanFocuss(elem)
{
  do {
    if(elem.disabled) return false;
    if(elem.type == 'hidden') return false;
    if(elem.style && elem.style.display == 'none') return false;
  } while(elem = elem.parentNode);
  return true;
}

//start_transl
/*
  Sprawdza, czy pole formularza zawiera poprawną kwotę pieniędzy.
  Na razie słaba implementacja.
  Parametry:
     field     - pole formularza (obiekt)
     displName - nazwa pola do wyświetlenia w komunikacie
     required  - czy wypełnienie pola jest obligatoryjne
*/
function CheckCurrencyField( field, displName, required )
{
  if( required && !CheckFieldNotEmpty( field, displName ) ) return false;
  if(Trim(field.value) == '') return true;
  if( field.value.search( /^ *\d+(\.\d*)? *$/ ) < 0 ) {
    AbortEntry( "Pole \"" + displName + "\" może zawierać tylko cyfry i kropkę", field ); //transl
    return false;
  }else{
    return true;
  }
}  

function CheckFloatField( field, displName, required )
{
  if( required && !CheckFieldNotEmpty( field, displName ) ) return false;
  if(Trim(field.value) == '') return true;
  if( field.value.search( /^ *[-+]?\d+(\.\d*)? *$/ ) < 0 ) {
    AbortEntry( "Pole \"" + displName + "\" może zawierać tylko cyfry, kropkę, plus, minus", field ); //transl
    return false;
  }else{
    return true;
  }
}  

function CheckDateField( field, displName, required, tabname )
{
  if( required && !CheckFieldNotEmpty( field, displName ) ) return false;
  if(Trim(field.value) == '') return true;

  if(!CheckDateYYYYMMDD(field.value)){
    return AbortEntry(GetErrMsg(ERR_BAD_DATE, displName), field, tabname);
  }else{
    return true;
  }
}  

function CheckTimeField( field, displName, required, tabname )
{
  if( required && !CheckFieldNotEmpty( field, displName ) ) return false;
  if(Trim(field.value) == '') return true;

  if(field.value.search( /^ *([01]?\d|2[0-3]):[0-5]?\d *$/ ) < 0 ){
    return AbortEntry("Pole '" + displName + "' nie jest poprawnym czasem! \nProszę stosować format gg:mm.", field, tabname); // transl
  }else{
    return true;
  }
}  

function CheckDateTimeSelectorAField( field, displName, required, tabname )
{
  return CheckTimeField(field.form.elements['dsqa_' + field.name + '_Time'], displName, required, tabname)
}  

/*
  Sprawdza, czy pole formularza zawiera poprawny adres email.
  Parametry:
     field     - pole formularza (obiekt)
     displName - nazwa pola do wyświetlenia w komunikacie
     required  - czy wypełnienie pola jest obligatoryjne
*/
function CheckEmailField(field, displName, required, tabname)
{
  if( required && !CheckFieldNotEmpty( field, displName ) ) return false;
  if(!CheckEmail(field.value)){
    if(CanFocus(field)) field.focus();
    return false;
  }
  return true;
}

function CheckColorField(field, displName, tabname)
{
  return IsValidColor(Trim(field.value)) || AbortEntry('Błędne pole "' + displName + '"', field, tabname); //transl
}

function IsValidColor(c)
{
  return c.match(/^(Black|Green|Silver|Lime|Gray|White|Yellow|Maroon|Navy|Red|Blue|Purple|Teal|Fuchsia|Aqua|transparent|#([\da-f]{3}|[\da-f]{6}))$/i);
}

var MaxLong =  2147483647
var MinLong = -2147483648

/*
  Sprawdza, czy pole formularza jest poprawną liczbą typu Long (4 bajty ze znakiem).
  Parametry:
     field     - pole formularza (obiekt)
     displName - nazwa pola do wyświetlenia w komunikacie
     required  - czy wypełnienie pola jest obligatoryjne
*/
function CheckLongField( field, displName, required, tabname )
{
  if( required && !CheckFieldNotEmpty( field, displName ) ) return false;
  if(Trim(field.value) == '') return true;
  if( field.value.search( /^ *-?\d* *$/ ) < 0 ) {
    AbortEntry( "Pole \"" + displName + "\" może zawierać tylko cyfry", field, tabname ); //transl
    return false;
  }
  var num = Number( field.value );
  if( isNaN( num ) || num < MinLong || num > MaxLong ) {
    AbortEntry( "Wartość w polu \"" + displName + "\" jest za duża", field, tabname ); //transl
    return false;
  }  
  return true;
}  

// Zwraca true
function CheckBooleanField( field, displName, required )
{
  return true;
}

function CheckStringField( field, displName, required )
{
  if( required && !CheckFieldNotEmpty( field, displName ) ) return false;
  return true;
}

function CheckRadioField( buttonSet, displName, required )
{
  return !required || RadioSetValue(buttonSet) != "" ||
   AbortEntry( "Pole \"" + displName + "\" musi być wypełnione", buttonSet[0] );
}

/*
  Funkcja CheckFieldNotEmpty
  sprawdza, czy pole formularza zostało wypełnione.  Jeśli nie, to wyświetla
  komunikat, ustawia kursor w polu i zwraca false.
  Parametry:
     fld     - pole (obiekt)
     fldName - nazwa pola do wyświetlenia w komunikacie o błędzie   
*/
function CheckFieldNotEmpty( fld, fldName, tabname )
{
  if(IsThisRadioButtonArray(fld) ? RadioSetValue(fld) == '' : fld.value.search( /^ *$/ ) >= 0 ) {
    AbortEntry( "Pole \"" + fldName + "\" musi być wypełnione", fld, tabname );
    return false;
  }
  return true;
}
//stop_transl

var ERR_REQ_FIELD = 0, ERR_BAD_NUMBER = 1, ERR_BAD_YEAR = 2, ERR_VAL_OUTSIDE_RANGE = 3
var ERR_MUSTBE_GET = 5 //grater or equal then
var ERR_SEL_REQ = 6, ERR_BAD_FLOAT = 7
var ERR_BAD_DATE = 8

// funkcja zwraca ciąg znaków reprezentujący opis błędu wyświetlany użytkownikowi
// wynikający z niepoprawnego wypełnienia, lub niewypełnienia obowiązkowych pól formularza
function GetErrMsg(type, fieldName)
{
//  var lang = arguments[2]
  switch(type)
  {
    case 0: // ERR_REQ_FIELD - not empty required
        return "Pole '" + fieldName + "' jest wymagane!"  //transl
    break;
    case 1: // ERR_BAD_NUMBER - number required
      return "Pole '" + fieldName + "' musi być liczbą całkowitą!"  //transl  
    break;
    case 2: // ERR_BAD_YEAR - year required
      return "Pole '" + fieldName + "' musi być liczbą całkowitą powyżej 1000!"  //transl  
    break
    case 3: // ERR_VAL_OUTSIDE_RANGE
      return "Pole '" + fieldName + "' musi się zawierać w granicach <" + arguments[2] + ", " + arguments[3] + ">"  //transl    
    break;
    case 5: // ERR_MUSTBE_GET - equal or grater then required
      return "Pole '" + fieldName + "' musi być równe lub większe niż pole " + arguments[2]   //transl  
    break
    case 6: //ERR_SEL_REQ
      return "Proszę wybrać pozycję listy '" + fieldName + "'. Pole jest wymagane."  //transl
    break;
    case 7: // ERR_BAD_FLOAT
      return "Pole '" + fieldName + "' nie jest poprawną liczbą! \nProszę stosować (.) kropkę, jako separator miejsc dziesiętnych."   //transl
    break;
    case 8: //ERR_BAD_DATE:
      return "Pole '" + fieldName + "' nie jest poprawną datą! \nProszę stosować format RRRR-MM-DD."   //transl
    break;
  }
}

// indeksy do tablicy z opisem pola formularza
var qfc_type          = 0;
var qfc_name          = 1;
var qfc_descr         = 2;
var qfc_required      = 3;
var qfc_lowerBound    = 4;
var qfc_upperBound    = 5;
var qfc_tabname       = 6;

/*
  function CheckField - checks if the field value or state (in case of list) 
                        complies to the rules defined in the item structure,
                        if not proper message is showed
                        
  form - form (object) containing fields to check
  item - element of an array with check procedure description
  
  result
    true  - if ok
    false - if not  
*/
function CheckField(form, item)
{
  var type, name, descr, required, lowerBound, upperBound, tabname, num, elem, fieldrequired, val;
   
  type          = 0
  name          = 1
  descr         = 2
  required      = 3
  lowerBound    = 4
  upperBound    = 5
  tabname       = 6

  if(item[name] && form[item[name]].disabled) return true;

  if(typeof(item[type]) == 'function'){
    if(item[name]){// standardowa obsługa pola obowiązkowego, o ile pole zostało określone
      if(item[required] && !CheckFieldNotEmpty( form[item[name]], item[descr])) return false;
      if(form[item[name]].value != undefined && Trim(form[item[name]].value) == '') return true; // pierwszy warunek wyłapuje radiobutton
    }
    return item[type](item, form);
  }

  if(item[required] == 2)
    {
    fieldrequired = MLSListing
    }
  else
    {
    if(item[required] == 3)
      {
      fieldrequired = MLSListing && MLSTrans
      }
    else
      {
      if(item[required] == 4)
        {
        fieldrequired = MLSListing && MLSTrans && MLSCredit
        }
      else
        {
        if(item[required] == 5)
          {
          fieldrequired = MLSListing && MLSTrans && MLSPerson
          }
        else
          {
          if(item[required] == 6)
            {
            fieldrequired = MLSListing && MLSTrans && MLSCompany
            }
          else
            {
            fieldrequired = item[required]
            }
          }
        }
      }
    }
  //elem = form[item[name]]; NIE, bo IE głupieje dla nazw pól zaczynających się od cyfry
  elem = form.elements[item[name]];
  //jeśli element nie istnieje: !undefined = true
  if(!elem) return true

  // obejście buraka, ale nie pamiętam w jakiej sytuacji
  if(elem.name != item[name] &&
     /* radio */!(!elem.tagName && elem.length && elem[0].name == item[name])){
    elem = form.elements(item[name]);
  }
  if(elem.maxLength && elem.maxLength > 0 /*<-na FireFoxa*/ && elem.value.length > elem.maxLength) {
    return AbortEntry('Za dużo znaków w polu "' + item[descr] + '".', elem, item[tabname]);
  }

  if(typeof(elem.value) == 'string' && elem.value.search(/[^\x20-\x7F\r\n\t€‚„…†‡‰Š‹ŚŤŽŹ‘’“”•–—™š›śťžźˇ˘Ł¤Ą¦§¨©Ş«¬­®Ż°±˛ł´µ¶·¸ąş»Ľ˝ľżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙]/i) >= 0)
     return AbortEntry('Niedopuszczalne znaki w polu "' + item[descr] + '".', elem, item[tabname]);

  if(item[type]==9){
    if(fieldrequired && RadioSetValue(elem)==""){
      return AbortEntry(GetErrMsg(ERR_REQ_FIELD, item[descr]), elem, item[tabname])
    }
    return true;
  }
  if(elem.value==undefined) return true // Tymczasowo !
  val = elem.value
  if(fieldrequired && isEmpty(val))
  {
    return AbortEntry(GetErrMsg(ERR_REQ_FIELD, item[descr]), elem, item[tabname])
  }    
  
  if(isEmpty(val)) return true;
  
  switch(item[type])
  {
  case 1: //LIST   
    if(eval(elem.selectedIndex == 0))
    {
      return AbortEntry(GetErrMsg(ERR_SEL_REQ, item[descr]), elem, item[tabname])
    }
  break;
  case 2: //INTEGER
    val = elem.value
    num = Number(val)
    lBound = item[lowerBound]   
    uBound = item[upperBound]
    if(!CheckLongField(elem, item[descr], fieldrequired, item[qfc_tabname])) return false; 
    return UIVisBetween(val, item[lowerBound], item[upperBound], item[descr], elem, item[tabname]);
  break;
  case 3: //YEAR
    val = elem.value
    num = Number(val)
    
    if((!isEmpty(val)) && (!isInteger(num) || num < 1000))
    {
        return AbortEntry(GetErrMsg(ERR_BAD_YEAR, item[descr]), elem, item[tabname])
    }
  break;
  case 4: //FLOAT
    val = elem.value
    if(!isFloat(val))
    {
      return AbortEntry(GetErrMsg(ERR_BAD_FLOAT, item[descr]), elem, item[tabname])
    }
    return UIVisBetween(val, item[lowerBound], item[upperBound], item[descr], elem, item[tabname]);
  break;
  case 5: //STRING
    val = elem.value
    if(item[upperBound] && val.length > item[upperBound])
      return AbortEntry('Za dużo znaków w polu "' + item[descr] + '".', elem, item[tabname]);
  break;  
  case 8: //DATE:
    if(!CheckDateYYYYMMDD(val)){
      return AbortEntry(GetErrMsg(ERR_BAD_DATE, item[descr]), elem, item[tabname])
    }
    if(item[upperBound] && (StringToDate(val) > StringToDate(item[upperBound]))) {
      return AbortEntry(item[descr] + " nie może być późniejsza niż " + item[upperBound] + ".", elem, item[tabname]);
    }
    if(item[lowerBound] && (StringToDate(val) < StringToDate(item[lowerBound]))) {
      return AbortEntry(item[descr] + " nie może być wcześniejsza niż " + item[lowerBound] + ".", elem, item[tabname]);
    }
  break;  
  case 9: //RADIO:
  break;
  case 10: // LOCATION
    if(Trim(elem.value).length < item[lowerBound]*3 + 3){
      var txt = item[lowerBound] == 1 ?
                   '1 poziom lokalizacji musi być podany!' :
                   item[lowerBound] + ' poziomy lokalizacji muszą być podane!';
      return AbortEntry('Co najmniej ' + txt, void(1), item[tabname]);
    }
  break;  
  case 11: // uiv_Email
    return CheckEmailField(elem, item[qfc_descr], item[qfc_required], item[qfc_tabname]);
  case 12: // uiv_Color
    return CheckColorField(elem, item[qfc_descr], item[qfc_tabname]);
  case 13: // uiv_Time
    return CheckTimeField(elem, item[qfc_descr], item[qfc_required], item[qfc_tabname]);
  case 14: // uiv_DateTimeSelectorA
    return CheckDateTimeSelectorAField(elem, item[qfc_descr], item[qfc_required], item[qfc_tabname]);
  }
  return true
}

//---------------------------------------------------------------------------
function QueueForCheck(arrayName)
{ 
  /*
    Arguments description:
    -----------------------------------
    1 - field type: INTEGER/YEAR
    2 - field name
    3 - field description
    4 - wheather required - NOTREQ/REQ/MLSREQ/TRANSREQ/CREDREQ/PECOREQ (0/1/2/3/4/5)
    5 - lower bound
    6 - upper bound
    7 - tab name
    -----------------------------------    
  */
  
  arrayName[arrayName.length] = [arguments[1], arguments[2], arguments[3],
                                 arguments[4], arguments[5], arguments[6], arguments[7]]
}

var fieldsToCheck = new Array()

function QueueForCheckStd()
{
  // na razie bez rozpoznawania formularza
  QueueForCheck(fieldsToCheck, arguments[0], arguments[1], arguments[2], arguments[3],
                               arguments[4], arguments[5], arguments[6])
}


function CheckFormFields(form)
{
    if(typeof(form) == 'string') form = document.forms[form];
    var item, checkResult
    for(var i=0;i<fieldsToCheck.length;i++)
    { 
      item = fieldsToCheck[i]
      checkResult = CheckField(form, item)
      if(!checkResult) return false      
    }
    return true
}

/*
 Sprawdza poprawność wypełnienia formularza (patrz CheckFormFields)
 i wysyła w razie powodzenia.
 Parametry:
    formPtr  - nazwa lub obiekt formularza
*/
function SubmitFormAfterCheck(formPtr)
{
  var form = typeof formPtr == 'object' ? formPtr : document.forms[formPtr];
  if(CheckFormFields(form)) form.submit();
}

function DaysInMonth(year, month) {
  var days_in_month, leep_year
  
  year = Number(year)
  month = Number(month)
  
  days_in_month = ["",31,28,31,30,31,30,31,31,30,31,30,31 ]
	leep_year = 2000
	
  if ((leep_year - year) % 4 == 0)    days_in_month[2] = 29
  if ((leep_year - year) % 100 == 0)  days_in_month[2] = 28
  if ((leep_year - year) % 400 == 0)  days_in_month[2] = 29
  
  return days_in_month[month]
}

/*
  Zwraca, czy zadany tekst reprezentuje poprawną datę w formacie RRRR-MM-DD. 
*/
function CheckDateYYYYMMDD( data )
{
  var mat = data.match( /^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})$/ );
  if( mat ) {
    var dzien = parseInt( mat[ 3 ], 10 );
    var miesiac = parseInt( mat[ 2 ], 10 );
    var rok = parseInt( mat[ 1 ], 10 );
    if( miesiac < 1 || miesiac > 12 ) return false;  
    if( dzien < 1 || dzien > DaysInMonth( rok, miesiac ) ) return false;
    if( rok < 1900 || rok > 2079 ) return false;
  } else {
    return false;
  }
  return true;
}

// Funkcja sprawdzająca poprawność wprowadzonego adresu e-mail
function CheckEmail(email) {
 wzornik=/^(.+);(.+)$/
 tabl=email.match(wzornik)
 while (tabl!=null) {
  wynik=CheckOne(tabl[1])
  email=tabl[2]
  tabl=email.match(wzornik)
 }
 return CheckOne(email)
}

function CheckOne(AdresEmail) {
 if(AdresEmail == 'testLokalny') return true;
 wzornikE=/^(.+)@(.+)$/
 znakiSpec="\\(\\)<>@,;:\\\\\\\"\\.\\[\\]"
 znakiDozw="\[^\\s" + znakiSpec + "\]"
 uzytkC="(\"[^\"]*\")"
 wzornikIP=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/
 atom=znakiDozw + '+'
 slowo="(" + atom + "|" + uzytkC + ")"
 wzornikU=new RegExp("^" + slowo + "(\\." + slowo + ")*$")
 wzornikD=new RegExp("^" + atom + "(\\." + atom +")*$")
 tablW=AdresEmail.match(wzornikE)
 if (tablW==null) {
  alert("Adres <"+AdresEmail+"> jest nieprawidłowy!")
  return false
 }
 uzytk=tablW[1]
 domena=tablW[2]
 if (uzytk.match(wzornikU)==null) {
  alert("Nazwa użytkownika w adresie <"+AdresEmail+"> jest nieprawidłowa!")
  return false
 }
 tablIP=domena.match(wzornikIP)
 if (tablIP!=null) {
  for (i=1;i<=4;i++) {
   if (tablIP[i]>255) {
    alert("Numer IP w adresie <"+AdresEmail+"> jest nieprawidłowy!")
    return false
   }
  }
 return true
 }
 tablD=domena.match(wzornikD)
 if (tablD==null) {
  alert("Nazwa domeny w adresie <"+AdresEmail+"> jest nieprawidłowa!")
  return false
 }
 wzornikA=new RegExp(atom,"g")
 tablD=domena.match(wzornikA)
 len=tablD.length
 if (tablD[tablD.length-1].length<2 || tablD[tablD.length-1].length>4) {
  alert("Adres <"+AdresEmail+"> nie kończy się trzyliterową lub czteroliterową domeną lub dwiema literami kodu kraju.")
  return false
 }
 if (len<2) {
  alert("W adresie <"+AdresEmail+"> brak nazwy hosta!")
  return false
 }
 return true;
}


function isInteger(val)
{
  return (!isNaN(val) && (parseInt(val) == val))
}

function isFloat(expr)
{
  return (expr.search( /^ *-?\d+(\.\d*)? *$/ ) >= 0)
}


function UIVisBetween(value, lBound, uBound, dsc, elem, tab)
{
  lBnum = Number(lBound);
  lUnum = Number(uBound);
  if(!isNaN(lBnum) && value < lBnum)
    return AbortEntry('Wartość \'' + dsc + '\' nie może być mniejsza niż ' + lBound + '.',
                       elem, tab);
  if(!isNaN(lUnum) && value > lUnum)
    return AbortEntry('Wartość \'' + dsc + '\' nie może być większa niż ' + uBound + '.',
                       elem, tab);

  return true
}

function onkey(evt, vtype) {
  var keycode = evt.keyCode || evt.charCode;
  if(keycode==CharCode(',')) {
    keycode = CharCode('.');
    try{
      evt.keyCode = keycode;
      evt.charCode = keycode;
    }catch(e){
      return false; // nie umiemy zmienić przecinka na kropkę (np. Opera, Firefox)
    }
  }
 if(keycode == 8) return true;
 switch(vtype) {
 case 2: // INTEGER
  return (keycode > 47 && keycode < 58);
  break;
 case 4: // FLOAT
  return ((keycode > 47 && keycode < 58) || keycode==46);
  break;
 case 8: // DATE
  return ((keycode > 47 && keycode < 58) || keycode==45);
  break;
 }
}

// Walidacja wciśniętego klawisza w polu z liczbą float.
function KeyPressFloat(evt, elem) {
  // Firefox wchodzi tu także po naciśnięciu backspace, delete, czy strzałek,
  // ale nie pozwala łatwo tego obsłużyć
  var keycode = evt.keyCode || evt.charCode;
  if(keycode==CharCode(',')) {
    keycode = CharCode('.');
    try{
      evt.keyCode = keycode;
      evt.charCode = keycode;
    }catch(e){
      return false; // nie umiemy zmienić przecinka na kropkę (np. Opera)
    }
  }
  if(keycode == CharCode('.')){
    // tylko jedna kropka
    return (elem.value.indexOf('.') < 0);
  }else{
    return ((keycode > 47 && keycode < 58) || keycode==46 || keycode==8);
  }
}

// Walidacja wciśniętego klawisza w polu z liczbą całkowitą (long).
function KeyPressInteger(evt, elem) {
  var keycode = evt.keyCode || evt.charCode;
  return ((keycode > 47 && keycode < 58) || keycode==8);
}


// Zwraca liczbę zapisaną w polu po ewentualnych poprawkach
// (usunięcie nadmiarowych kropek, zamiana przecinka na kropkę itp.)
function RepairFloatField(field, allowEmpty)
{
  field = FindElement(field);
  if(Trim(field.value) == ''){
    if(allowEmpty) return '';
    field.value = '0';
  }
  var repaired = field.value.replace(/,/g, '.');;
  while(repaired.indexOf('.') != repaired.lastIndexOf('.')){
    repaired = repaired.replace('.', '');
  }
  repaired = repaired.replace(/[^\.0-9\s]/g, '');
  if(repaired != field.value) field.value = repaired;
  return parseFloat(field.value.replace(/ /g, ''));
}

// Zwraca wartość wybranego przycisku z zestawu przycisków radiowych
function RadioSetValue(buttonSet)
{
  for(RsvCnt = 0; RsvCnt < buttonSet.length; RsvCnt++)
  {
    if(buttonSet[RsvCnt].checked) return buttonSet[RsvCnt].value;
  }
  return "";
}

function IsThisRadioButtonArray(elem)
{
  return elem && elem.length && elem[0].type && elem[0].type.toLowerCase() == 'radio' ? true : false; 
}

// Czy tekst zawiera jedynie litery ascii i cyfry.
function IsAlphaNumeric(str)
{
  return (str.match( /^[a-zA-Z0-9]*$/i ) != null);
}

// Do kontrolki HTMLDateSelector2. Sprawdza poprawność wybranej daty.
// Jeśli trzeba, to zmienia dzień na ostatni dzień miesiąca.
function DateSelectorOnChange(elem, fldName)
{
  var form = elem.form;
  var dayElem = form.elements['dsq_' + fldName + 'Day'];
  var month = form.elements['dsq_' + fldName + 'Month'].value;
  var year = form.elements['dsq_' + fldName + 'Year'].value;
  if(DaysInMonth(year, month) < dayElem.value) dayElem.value = DaysInMonth(year, month);
  form.elements[fldName].value = '' + year + '-' + month + '-' + dayElem.value;
}

function DateSelectorDisable(form, fldName, disabled)
{
  form = FindElement(form);
  form.elements['dsq_' + fldName + 'Day'].disabled = disabled;
  form.elements['dsq_' + fldName + 'Month'].disabled = disabled;
  form.elements['dsq_' + fldName + 'Year'].disabled = disabled;
}

function DateSelectorSetDate(form, fldName, d)
{
  form = FindElement(form);
  if(typeof(d) == 'string') d = StringToDate(d);
  form.elements['dsq_' + fldName + 'Day'].value = (d.getDate()).toString();
  form.elements['dsq_' + fldName + 'Month'].value =(d.getMonth()+1).toString();
  form.elements['dsq_' + fldName + 'Year'].value = (d.getFullYear()).toString();
  DateSelectorOnChange(form.elements['dsq_' + fldName + 'Day'], fldName);
}

function DateTimeSelectorAOnChange(elem, fldName)
{
  var form = elem.form;
  var date = form.elements['dsqa_' + fldName + '_Date'].value;
  var time = form.elements['dsqa_' + fldName + '_Time'].value;
  form.elements[fldName].value = '' + date + ' ' + time;
}

// nie rusza godzin, minut
function DateTimeSelectorASetDate(form, fldName, d)
{
  DateSelectorSetDate(form, 'dsqa_' + fldName + '_Date', d);
  DateTimeSelectorAOnChange(form.elements['dsqa_' + fldName + '_Date'], fldName)
}
