diff --git a/.codeclimate.yml b/.codeclimate.yml new file mode 100644 index 00000000000..fd65f8b817f --- /dev/null +++ b/.codeclimate.yml @@ -0,0 +1,11 @@ +# Save as .codeclimate.yml (note leading .) in project root directory +languages: + Ruby: false + JavaScript: true + PHP: true +exclude_paths: + - 'build/*' + - 'dev/*' + - 'doc/*' + - 'test/*' + - 'htdocs/includes/*' \ No newline at end of file diff --git a/ChangeLog b/ChangeLog index 9fb65d403a4..3a882e1bb30 100644 --- a/ChangeLog +++ b/ChangeLog @@ -233,6 +233,10 @@ FIX [ bug #2900 ] Courtesy title is not stored in create thirdparty form FIX [ bug #3055 ] Product image thumbnails were not deleted after deleting the image FIX [ bug 1634 ] Error deleting a project when it had many linked objects FIX [ bug 1925 ] "Link to order" option in supplier invoices is not working properly +FIX [ bug #3198 ] Trigger LINECONTRACT_INSERT passes Contrat as $object instead of ContratLigne +FIX: Not showing delivery date on rouget pdf + +NEW: Created new ContratLigne::insert function ***** ChangeLog for 3.7.1 compared to 3.7.* ***** FIX Bug in the new photo system diff --git a/dev/skeletons/build_class_from_table.php b/dev/skeletons/build_class_from_table.php index e83b9e2debf..43f29a17ad3 100755 --- a/dev/skeletons/build_class_from_table.php +++ b/dev/skeletons/build_class_from_table.php @@ -227,6 +227,13 @@ foreach($property as $key => $prop) $targetcontent=preg_replace('/if \(isset\(\$this->prop1\)\) {((\n|\r|\t)*)\$this->prop1 = trim\(\$this->prop1\);((\n|\r|\t)*)}/', $varprop, $targetcontent); $targetcontent=preg_replace('/if \(isset\(\$this->prop2\)\) {((\n|\r|\t)*)\$this->prop2 = trim\(\$this->prop2\);((\n|\r|\t)*)}/', '', $targetcontent); + +$no_output_field=0; +foreach($property as $key => $prop) +{ + if ($prop['field'] == 'tms') $no_output_field++; // This is a field of type timestamp edited automatically + if ($prop['extra'] == 'auto_increment') $no_output_field++; +} // Substitute insert into parameters $varprop="\n"; $cleanparam=''; @@ -241,7 +248,7 @@ foreach($property as $key => $prop) if ($addfield) { $varprop.="\t\t\$sql.= '".$prop['field']; - if ($i < count($property)) $varprop.=","; + if ($i <= count($property)-$no_output_field) $varprop.=","; $varprop.="';"; $varprop.="\n"; } @@ -255,12 +262,7 @@ $cleanparam=''; $i=0; //Count nb field to output to manage commat at end SQL instruction -$no_output_field=0; -foreach($property as $key => $prop) -{ - if ($prop['field'] == 'tms') $no_output_field++; // This is a field of type timestamp edited automatically - if ($prop['extra'] == 'auto_increment') $no_output_field++; -} + foreach($property as $key => $prop) { @@ -307,6 +309,7 @@ foreach($property as $key => $prop) $varprop.='.\').'; } + if ($i < (count($property)-$no_output_field)) $varprop.=".','"; $varprop.=';'; $varprop.="\n"; diff --git a/dev/skeletons/skeleton_class.class.php b/dev/skeletons/skeleton_class.class.php index 72ee07c259d..83938b158e7 100644 --- a/dev/skeletons/skeleton_class.class.php +++ b/dev/skeletons/skeleton_class.class.php @@ -234,7 +234,7 @@ class Skeleton_Class extends CommonObject $sql .= ' t.field1,'; $sql .= ' t.field2'; //... - $sql .= ' FROM ' . MAIN_DB_PREFIX . 'mytable as t'; + $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element. ' as t'; // Manage filter $sqlwhere = array(); diff --git a/htdocs/adherents/admin/public.php b/htdocs/adherents/admin/public.php index d591d377ac9..187f71e93a8 100644 --- a/htdocs/adherents/admin/public.php +++ b/htdocs/adherents/admin/public.php @@ -219,7 +219,12 @@ print ''; print '
'; //print $langs->trans('FollowingLinksArePublic').'
'; print img_picto('','object_globe.png').' '.$langs->trans('BlankSubscriptionForm').':
'; -print ''.DOL_MAIN_URL_ROOT.'/public/members/new.php'; +if ($conf->multicompany->enabled) { + $entity_qr='?entity='.$conf->entity; +} else { + $entity_qr=''; +} +print ''.DOL_MAIN_URL_ROOT.'/public/members/new.php'.$entity_qr.''; /* print ''; diff --git a/htdocs/adherents/agenda.php b/htdocs/adherents/agenda.php index 343c8c4a628..71106dddee6 100644 --- a/htdocs/adherents/agenda.php +++ b/htdocs/adherents/agenda.php @@ -141,7 +141,7 @@ if ($object->id > 0) if (! empty($conf->agenda->enabled)) { - print '
'.$langs->trans("AddAction").'
'; + print '
'.$langs->trans("AddAction").'
'; } print ''; diff --git a/htdocs/admin/agenda_extsites.php b/htdocs/admin/agenda_extsites.php index 633b62f2316..2e113f22430 100644 --- a/htdocs/admin/agenda_extsites.php +++ b/htdocs/admin/agenda_extsites.php @@ -65,6 +65,7 @@ if ($actionsave) { $name=trim(GETPOST('AGENDA_EXT_NAME'.$i,'alpha')); $src=trim(GETPOST('AGENDA_EXT_SRC'.$i,'alpha')); + $offsettz=trim(GETPOST('AGENDA_EXT_OFFSETTZ'.$i,'alpha')); $color=trim(GETPOST('AGENDA_EXT_COLOR'.$i,'alpha')); if ($color=='-1') $color=''; $enabled=trim(GETPOST('AGENDA_EXT_ENABLED'.$i,'alpha')); @@ -82,6 +83,8 @@ if ($actionsave) if (! $res > 0) $error++; $res=dolibarr_set_const($db,'AGENDA_EXT_SRC'.$i,$src,'chaine',0,'',$conf->entity); if (! $res > 0) $error++; + $res=dolibarr_set_const($db,'AGENDA_EXT_OFFSETTZ'.$i,$offsettz,'chaine',0,'',$conf->entity); + if (! $res > 0) $error++; $res=dolibarr_set_const($db,'AGENDA_EXT_COLOR'.$i,$color,'chaine',0,'',$conf->entity); if (! $res > 0) $error++; $res=dolibarr_set_const($db,'AGENDA_EXT_ENABLED'.$i,$enabled,'chaine',0,'',$conf->entity); @@ -191,6 +194,7 @@ print ""; print ""; print ""; print "'; +print "'; print ''; print ""; @@ -201,6 +205,7 @@ while ($i <= $MAXAGENDA) $key=$i; $name='AGENDA_EXT_NAME'.$key; $src='AGENDA_EXT_SRC'.$key; + $offsettz='AGENDA_EXT_OFFSETTZ'.$key; $color='AGENDA_EXT_COLOR'.$key; $enabled='AGENDA_EXT_ENABLED'.$key; @@ -212,6 +217,8 @@ while ($i <= $MAXAGENDA) print ''; // URL print ''; + // Offset TZ + print ''; // Color (Possible colors are limited by Google) print '\n"; $var=!$var; - /*print '\n"; - $var=!$var;*/ } print ''."\n"; $var = true; $tmpfilelist = dol_sort_array($file_list['missing'], 'filename'); - foreach ($tmpfilelist as $file) + if (is_array($tmpfilelist)) { - $var = !$var; - print ''; - print '' . "\n"; - print '' . "\n"; - print "\n"; + foreach ($tmpfilelist as $file) + { + $var = !$var; + print ''; + print '' . "\n"; + print '' . "\n"; + print "\n"; + } } print '
".$langs->trans("Parameter")."".$langs->trans("Name")."".$langs->trans("ExtSiteUrlAgenda")." (".$langs->trans("Example").': http://yoursite/agenda/agenda.ics)".$form->textwithpicto($langs->trans("FixTZ"), $langs->trans("FillFixTZOnlyIfRequired"), 1).''.$langs->trans("Color").'
'; //print $formadmin->selectColor($conf->global->$color, "google_agenda_color".$key, $colorlist); diff --git a/htdocs/admin/supplier_order.php b/htdocs/admin/supplier_order.php index 87d46ea10b0..4b39b2381f7 100644 --- a/htdocs/admin/supplier_order.php +++ b/htdocs/admin/supplier_order.php @@ -168,19 +168,11 @@ else if ($action == 'addcat') else if ($action == 'set_SUPPLIER_ORDER_OTHER') { $freetext = GETPOST('SUPPLIER_ORDER_FREE_TEXT'); // No alpha here, we want exact string - $doubleapproval = GETPOST('SUPPLIER_ORDER_DOUBLE_APPROVAL'); - //$doubleapprovalgroup = GETPOST('SUPPLIER_ORDER_DOUBLE_APPROVAL_GROUP') > 0 ? GETPOST('SUPPLIER_ORDER_DOUBLE_APPROVAL_GROUP') : ''; + $doubleapproval = GETPOST('SUPPLIER_ORDER_DOUBLE_APPROVAL','alpha'); + $doubleapproval = price2num($doubleapproval ); $res1 = dolibarr_set_const($db, "SUPPLIER_ORDER_FREE_TEXT",$freetext,'chaine',0,'',$conf->entity); $res2 = dolibarr_set_const($db, "SUPPLIER_ORDER_DOUBLE_APPROVAL",$doubleapproval,'chaine',0,'',$conf->entity); - /*if (isset($_POST["SUPPLIER_ORDER_DOUBLE_APPROVAL_GROUP"])) - { - $res3 = dolibarr_set_const($db, "SUPPLIER_ORDER_DOUBLE_APPROVAL_GROUP",$doubleapprovalgroup,'chaine',0,'',$conf->entity); - } - else - { - $res3=1; - }*/ // TODO We add/delete permission here until permission can have a condition on a global var include_once DOL_DOCUMENT_ROOT.'/core/modules/modFournisseur.class.php'; @@ -486,18 +478,11 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) print $langs->trans("UseDoubleApproval").'
'; print $langs->trans("IfSetToYesDontForgetPermission"); print '
'; - print $form->selectyesno('SUPPLIER_ORDER_DOUBLE_APPROVAL', $conf->global->SUPPLIER_ORDER_DOUBLE_APPROVAL, 1); + print ''; print ''; print ''; print "
'; - print $langs->trans("GroupOfUserForSecondApproval").''; - print $form->select_dolgroups($conf->global->SUPPLIER_ORDER_DOUBLE_APPROVAL_GROUP,'SUPPLIER_ORDER_DOUBLE_APPROVAL_GROUP', 1); - print ''; - print ''; - print "
'; diff --git a/htdocs/admin/system/filecheck.php b/htdocs/admin/system/filecheck.php index 431de103fd3..f8876a7ea30 100644 --- a/htdocs/admin/system/filecheck.php +++ b/htdocs/admin/system/filecheck.php @@ -87,13 +87,16 @@ if (file_exists($xmlfile)) print '
'.$file['filename'].''.$file['expectedmd5'].'
'.$file['filename'].''.$file['expectedmd5'].'
'; @@ -109,16 +112,19 @@ if (file_exists($xmlfile)) print ''."\n"; $var = true; $tmpfilelist = dol_sort_array($file_list['updated'], 'filename'); - foreach ($tmpfilelist as $file) + if (is_array($tmpfilelist)) { - $var = !$var; - print ''; - print ''.$file['filename'].'' . "\n"; - print ''.$file['expectedmd5'].'' . "\n"; - print ''.$file['md5'].'' . "\n"; - print ''.dol_print_size(dol_filesize(DOL_DOCUMENT_ROOT.'/'.$file['filename'])).'' . "\n"; - print ''.dol_print_date(dol_filemtime(DOL_DOCUMENT_ROOT.'/'.$file['filename']),'dayhour').'' . "\n"; - print "\n"; + foreach ($tmpfilelist as $file) + { + $var = !$var; + print ''; + print ''.$file['filename'].'' . "\n"; + print ''.$file['expectedmd5'].'' . "\n"; + print ''.$file['md5'].'' . "\n"; + print ''.dol_print_size(dol_filesize(DOL_DOCUMENT_ROOT.'/'.$file['filename'])).'' . "\n"; + print ''.dol_print_date(dol_filemtime(DOL_DOCUMENT_ROOT.'/'.$file['filename']),'dayhour').'' . "\n"; + print "\n"; + } } print ''; } diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 623ebcbf1bc..f2fce88dc31 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -780,6 +780,8 @@ if ($action == 'create') print ''.dolGetElementUrl($originid,$origin,1).''; print ''; print ''; + print ''; + print ''; } if (GETPOST("datep") && preg_match('/^([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])$/',GETPOST("datep"),$reg)) diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index 5e8f898e830..bc5bf9da9e3 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -110,8 +110,8 @@ class ActionComm extends CommonObject var $note; // Description var $userassigned = array(); // Array of user ids - var $userownerid; // Id of user owner - var $userdoneid; // Id of user done + var $userownerid; // Id of user owner = fk_user_action into table + var $userdoneid; // Id of user done (deprecated) /** * Object user of owner diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index c414d3409d6..f445c7f3596 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -179,12 +179,13 @@ if (empty($conf->global->AGENDA_DISABLE_EXT)) $i++; $source='AGENDA_EXT_SRC'.$i; $name='AGENDA_EXT_NAME'.$i; + $offsettz='AGENDA_EXT_OFFSETTZ'.$i; $color='AGENDA_EXT_COLOR'.$i; $buggedfile='AGENDA_EXT_BUGGEDFILE'.$i; if (! empty($conf->global->$source) && ! empty($conf->global->$name)) { // Note: $conf->global->buggedfile can be empty or 'uselocalandtznodaylight' or 'uselocalandtzdaylight' - $listofextcals[]=array('src'=>$conf->global->$source,'name'=>$conf->global->$name,'color'=>$conf->global->$color,'buggedfile'=>(isset($conf->global->buggedfile)?$conf->global->buggedfile:0)); + $listofextcals[]=array('src'=>$conf->global->$source,'name'=>$conf->global->$name,'offsettz'=>$conf->global->$offsettz,'color'=>$conf->global->$color,'buggedfile'=>(isset($conf->global->buggedfile)?$conf->global->buggedfile:0)); } } } @@ -197,13 +198,14 @@ if (empty($user->conf->AGENDA_DISABLE_EXT)) $i++; $source='AGENDA_EXT_SRC_'.$user->id.'_'.$i; $name='AGENDA_EXT_NAME_'.$user->id.'_'.$i; + $offsettz='AGENDA_EXT_OFFSETTZ_'.$user->id.'_'.$i; $color='AGENDA_EXT_COLOR_'.$user->id.'_'.$i; $enabled='AGENDA_EXT_ENABLED_'.$user->id.'_'.$i; $buggedfile='AGENDA_EXT_BUGGEDFILE_'.$user->id.'_'.$i; if (! empty($user->conf->$source) && ! empty($user->conf->$name)) { // Note: $conf->global->buggedfile can be empty or 'uselocalandtznodaylight' or 'uselocalandtzdaylight' - $listofextcals[]=array('src'=>$user->conf->$source,'name'=>$user->conf->$name,'color'=>$user->conf->$color,'buggedfile'=>(isset($user->conf->buggedfile)?$user->conf->buggedfile:0)); + $listofextcals[]=array('src'=>$user->conf->$source,'name'=>$user->conf->$name,'offsettz'=>$user->conf->$offsettz,'color'=>$user->conf->$color,'buggedfile'=>(isset($user->conf->buggedfile)?$user->conf->buggedfile:0)); } } } @@ -507,8 +509,12 @@ if ($resql) // Create a new object action $event=new ActionComm($db); $event->id=$obj->id; - $event->datep=$db->jdate($obj->datep); // datep and datef are GMT date + + $event->datep=$db->jdate($obj->datep); // datep and datef are GMT date. Example: 1970-01-01 01:00:00, jdate will return 0 if TZ of PHP server is Europe/Berlin $event->datef=$db->jdate($obj->datep2); + //var_dump($obj->datep); + //var_dump($event->datep); + $event->type_code=$obj->type_code; $event->type_label=$obj->type_label; $event->libelle=$obj->label; @@ -664,6 +670,7 @@ if (count($listofextcals)) { $url=$extcal['src']; // Example: https://www.google.com/calendar/ical/eldy10%40gmail.com/private-cde92aa7d7e0ef6110010a821a2aaeb/basic.ics $namecal = $extcal['name']; + $offsettz = $extcal['offsettz']; $colorcal = $extcal['color']; $buggedfile = $extcal['buggedfile']; //print "url=".$url." namecal=".$namecal." colorcal=".$colorcal." buggedfile=".$buggedfile; @@ -805,12 +812,22 @@ if (count($listofextcals)) { $datestart=$icalevent['DTSTART']; $dateend=$icalevent['DTEND']; + + $datestart+=+($offsettz * 3600); + $dateend+=+($offsettz * 3600); + $addevent=true; + //var_dump($offsettz); + //var_dump(dol_print_date($datestart, 'dayhour', 'gmt')); } elseif (isset($icalevent['DTSTART']['unixtime'])) // File contains a local timezone + a TZ (for example when using bluemind) { $datestart=$icalevent['DTSTART']['unixtime']; $dateend=$icalevent['DTEND']['unixtime']; + + $datestart+=+($offsettz * 3600); + $dateend+=+($offsettz * 3600); + // $buggedfile is set to uselocalandtznodaylight if conf->global->AGENDA_EXT_BUGGEDFILEx = 'uselocalandtznodaylight' if ($buggedfile === 'uselocalandtznodaylight') // unixtime is a local date that does not take daylight into account, TZID is +1 for example for 'Europe/Paris' in summer instead of 2 { @@ -1308,7 +1325,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa // Hour start if ($tmpyearstart == $annee && $tmpmonthstart == $mois && $tmpdaystart == $jour) { - $daterange.=dol_print_date($event->date_start_in_calendar,'%H:%M'); + $daterange.=dol_print_date($event->date_start_in_calendar,'%H:%M'); // Il faudrait utiliser ici tzuser, mais si on ne peut pas car qd on rentre un date dans fiche action, en input la conversion local->gmt se base sur le TZ server et non user if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) { if ($tmpyearstart == $tmpyearend && $tmpmonthstart == $tmpmonthend && $tmpdaystart == $tmpdayend) @@ -1328,7 +1345,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) { if ($tmpyearend == $annee && $tmpmonthend == $mois && $tmpdayend == $jour) - $daterange.=dol_print_date($event->date_end_in_calendar,'%H:%M'); + $daterange.=dol_print_date($event->date_end_in_calendar,'%H:%M'); // Il faudrait utiliser ici tzuser, mais si on ne peut pas car qd on rentre un date dans fiche action, en input la conversion local->gmt se base sur le TZ server et non user } //print $daterange; if ($event->type_code != 'ICALEVENT') diff --git a/htdocs/comm/askpricesupplier/tpl/linkedobjectblock.tpl.php b/htdocs/comm/askpricesupplier/tpl/linkedobjectblock.tpl.php index a45fac8b3c9..48d916c6a5c 100644 --- a/htdocs/comm/askpricesupplier/tpl/linkedobjectblock.tpl.php +++ b/htdocs/comm/askpricesupplier/tpl/linkedobjectblock.tpl.php @@ -38,24 +38,26 @@ print_titre($langs->trans('RelatedAskPriceSupplier')); trans("Date"); ?> trans("AmountHTShort"); ?> trans("Status"); ?> + $objectlink) { $var=!$var; ?> > - trans("ShowAskPriceSupplier"),"askpricesupplier").' '.$object->ref; ?> + trans("ShowAskPriceSupplier"),"askpricesupplier").' '.$objectlink->ref; ?> - datec,'day'); ?> + datec,'day'); ?> rights->askpricesupplier->lire) { - $total = $total + $object->total_ht; - echo price($object->total_ht); + $total = $total + $objectlink->total_ht; + echo price($objectlink->total_ht); } ?> - getLibStatut(3); ?> + getLibStatut(3); ?> + ">transnoentitiesnoconv("RemoveLink")); ?> rights->askpricesupplier->lire) { echo price($total); } ?> -   + + diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php index dc0f376234e..4b9f84553ce 100644 --- a/htdocs/comm/propal.php +++ b/htdocs/comm/propal.php @@ -103,6 +103,8 @@ if ($id > 0 || ! empty($ref)) { $hookmanager->initHooks(array('propalcard','globalcard')); $permissionnote = $user->rights->propale->creer; // Used by the include of actions_setnotes.inc.php +$permissiondellink=$user->rights->propale->creer; // Used by the include of actions_dellink.inc.php +$permissiontoedit = $user->rights->propale->creer; // Used by the include of actions_lineupdown.inc.php /* @@ -117,7 +119,11 @@ if (empty($reshook)) { if ($cancel) $action = ''; - include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not includ_once + include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not includ_once + + include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once + + include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; // Must be include, not include_once // Action clone object if ($action == 'confirm_clone' && $confirm == 'yes') @@ -1133,47 +1139,7 @@ if (empty($reshook)) $result=$object->setShippingMethod(GETPOST('shipping_method_id', 'int')); } - /* - * Ordonnancement des lignes - */ - - else if ($action == 'up' && $user->rights->propal->creer) { - $object->line_up(GETPOST('rowid')); - - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) { - $outputlangs = new Translate("", $conf); - $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->thirdparty->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret = $object->fetch($id); // Reload to get new records - $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id . '#' . GETPOST('rowid')); - exit(); - } - - else if ($action == 'down' && $user->rights->propal->creer) { - $object->line_down(GETPOST('rowid')); - - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) { - $outputlangs = new Translate("", $conf); - $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->thirdparty->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret = $object->fetch($id); // Reload to get new records - $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id . '#' . GETPOST('rowid')); - exit(); - } else if ($action == 'update_extras') { + else if ($action == 'update_extras') { // Fill array 'array_options' with data from update form $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); $ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute')); diff --git a/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php b/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php index 19763f8510c..66cde8692ce 100644 --- a/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php +++ b/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php @@ -43,24 +43,26 @@ print_titre($langs->trans('RelatedCommercialProposals')); trans("Date"); ?> trans("AmountHTShort"); ?> trans("Status"); ?> + $objectlink) { $var=!$var; ?> > - getNomUrl(1); ?> - ref_client; ?> - date,'day'); ?> + getNomUrl(1); ?> + ref_client; ?> + date,'day'); ?> rights->propale->lire) { - $total = $total + $object->total_ht; - echo price($object->total_ht); + $total = $total + $objectlink->total_ht; + echo price($objectlink->total_ht); } ?> - getLibStatut(3); ?> + getLibStatut(3); ?> + ">transnoentitiesnoconv("RemoveLink")); ?> rights->propale->lire) { echo price($total); } ?> -   + + diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 5cc0c6db9ce..5c860eee1f6 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -93,8 +93,9 @@ include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be inclu // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array $hookmanager->initHooks(array('ordercard','globalcard')); -$permissionnote = $user->rights->commande->creer; // Used by the include of actions_setnotes.inc.php -$permissionedit = $user->rights->commande->creer; // Used by the include of actions_lineupdown.inc.php +$permissionnote = $user->rights->commande->creer; // Used by the include of actions_setnotes.inc.php +$permissiondellink = $user->rights->commande->creer; // Used by the include of actions_dellink.inc.php +$permissionedit = $user->rights->commande->creer; // Used by the include of actions_lineupdown.inc.php @@ -112,6 +113,8 @@ if (empty($reshook)) include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not include_once + include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once + include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; // Must be include, not include_once // Action clone object diff --git a/htdocs/commande/tpl/linkedobjectblock.tpl.php b/htdocs/commande/tpl/linkedobjectblock.tpl.php index 2eb94d7974a..a661013802d 100644 --- a/htdocs/commande/tpl/linkedobjectblock.tpl.php +++ b/htdocs/commande/tpl/linkedobjectblock.tpl.php @@ -40,24 +40,26 @@ print_titre($langs->trans('RelatedCustomerOrders')); trans("Date"); ?> trans("AmountHTShort"); ?> trans("Status"); ?> + $objectlink) { $var=!$var; ?> > - getNomUrl(1); ?> - ref_client; ?> - date,'day'); ?> + getNomUrl(1); ?> + ref_client; ?> + date,'day'); ?> rights->commande->lire) { - $total = $total + $object->total_ht; - echo price($object->total_ht); + $total = $total + $objectlink->total_ht; + echo price($objectlink->total_ht); } ?> - getLibStatut(3); ?> + getLibStatut(3); ?> + ">transnoentitiesnoconv("RemoveLink")); ?> rights->commande->lire) { echo price($total); } ?> -   + + diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index 087780fdaad..7f5b33ee73a 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -108,6 +108,8 @@ if ($id > 0 || ! empty($ref)) { $hookmanager->initHooks(array('invoicecard','globalcard')); $permissionnote = $user->rights->facture->creer; // Used by the include of actions_setnotes.inc.php +$permissiondellink=$user->rights->facture->creer; // Used by the include of actions_dellink.inc.php +$permissiontoedit = $user->rights->facture->creer; // Used by the include of actions_lineupdonw.inc.php /* @@ -120,7 +122,11 @@ if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'e if (empty($reshook)) { - include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not includ_once + include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not includ_once + + include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once + + include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; // Must be include, not include_once // Action clone object if ($action == 'confirm_clone' && $confirm == 'yes' && $user->rights->facture->creer) { @@ -1644,54 +1650,6 @@ if (empty($reshook)) exit(); } - // Modify line position (up) - else if ($action == 'up' && $user->rights->facture->creer) { - $object->fetch($id); - $object->fetch_thirdparty(); - $object->line_up($_GET ['rowid']); - - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '#' . $_GET ['rowid']); - exit(); - } // Modify line position (down) - else if ($action == 'down' && $user->rights->facture->creer) { - $object->fetch($id); - $object->fetch_thirdparty(); - $object->line_down($_GET ['rowid']); - - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '#' . $_GET ['rowid']); - exit(); - } - // Link invoice to order if (GETPOST('linkedOrder')) { $object->fetch($id); diff --git a/htdocs/compta/facture/tpl/linkedobjectblock.tpl.php b/htdocs/compta/facture/tpl/linkedobjectblock.tpl.php index eac0043e56f..b295e72f19e 100644 --- a/htdocs/compta/facture/tpl/linkedobjectblock.tpl.php +++ b/htdocs/compta/facture/tpl/linkedobjectblock.tpl.php @@ -39,24 +39,26 @@ print_titre($langs->trans("RelatedCustomerInvoices")); trans("Date"); ?> trans("AmountHTShort"); ?> trans("Status"); ?> + $objectlink) { $var=!$var; ?> > - getNomUrl(1); ?> - ref_client; ?> - date,'day'); ?> + getNomUrl(1); ?> + ref_client; ?> + date,'day'); ?> rights->facture->lire) { - $total = $total + $object->total_ht; - echo price($object->total_ht); + $total = $total + $objectlink->total_ht; + echo price($objectlink->total_ht); } ?> - getLibStatut(3); ?> + getLibStatut(3); ?> + ">transnoentitiesnoconv("RemoveLink")); ?> rights->facture->lire) { echo price($total); } ?> -   + + diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 4005cb9abdf..4cea0fb8c5e 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -90,6 +90,7 @@ $extrafieldsline = new ExtraFields($db); $extralabelslines=$extrafieldsline->fetch_name_optionals_label($object->table_element_line); $permissionnote=$user->rights->contrat->creer; // Used by the include of actions_setnotes.inc.php +$permissiondellink=$user->rights->contrat->creer; // Used by the include of actions_dellink.inc.php /* @@ -98,6 +99,8 @@ $permissionnote=$user->rights->contrat->creer; // Used by the include of actions include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not includ_once +include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once + if ($action == 'confirm_active' && $confirm == 'yes' && $user->rights->contrat->activer) { $result = $object->active_line($user, GETPOST('ligne'), GETPOST('date'), GETPOST('dateend'), GETPOST('comment')); diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index fb0038b509f..ce02649674b 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -905,8 +905,7 @@ class Contrat extends CommonObject $modCodeContract = new $module(); } - //Commerce Efficace - Debut : Modification r�f�rence Contrat - /*if (!empty($modCodeContract->code_auto)) { + if (!empty($modCodeContract->code_auto)) { // Mise a jour ref $sql = 'UPDATE '.MAIN_DB_PREFIX."contrat SET ref='(PROV".$this->id.")' WHERE rowid=".$this->id; if ($this->db->query($sql)) @@ -916,8 +915,7 @@ class Contrat extends CommonObject $this->ref="(PROV".$this->id.")"; } } - }*/ - //Commerce Efficace - Fin : Modification r�f�rence Contrat + } // Insert contacts commerciaux ('SALESREPSIGN','contrat') $result=$this->add_contact($this->commercial_signature_id,'SALESREPSIGN','internal'); @@ -1345,8 +1343,6 @@ class Contrat extends CommonObject $sql.= ", ".($fk_unit?"'".$this->db->escape($fk_unit)."'":"null"); $sql.= ")"; - dol_syslog(get_class($this)."::addline", LOG_DEBUG); - $resql=$this->db->query($sql); if ($resql) { @@ -2629,4 +2625,74 @@ class ContratLigne extends CommonObjectLine } } + + /** + * Inserts a contrat line into database + * + * @param int $notrigger Set to 1 if you don't want triggers to be fired + * @return int <0 if KO, >0 if OK + */ + public function insert($notrigger = 0) + { + global $user; + + // Insertion dans la base + $sql = "INSERT INTO ".MAIN_DB_PREFIX."contratdet"; + $sql.= " (fk_contrat, label, description, fk_product, qty, tva_tx,"; + $sql.= " localtax1_tx, localtax2_tx, localtax1_type, localtax2_type, remise_percent, subprice,"; + $sql.= " total_ht, total_tva, total_localtax1, total_localtax2, total_ttc,"; + $sql.= " info_bits,"; + $sql.= " price_ht, remise, fk_product_fournisseur_price, buy_price_ht"; + if ($this->date_ouverture_prevue > 0) { $sql.= ",date_ouverture_prevue"; } + if ($this->date_fin_validite > 0) { $sql.= ",date_fin_validite"; } + $sql.= ") VALUES ($this->fk_contrat, '', '" . $this->db->escape($this->description) . "',"; + $sql.= ($this->fk_product>0 ? $this->fk_product : "null").","; + $sql.= " '".$this->qty."',"; + $sql.= " '".$this->tva_tx."',"; + $sql.= " '".$this->localtax1_tx."',"; + $sql.= " '".$this->localtax2_tx."',"; + $sql.= " '".$this->localtax1_type."',"; + $sql.= " '".$this->localtax2_type."',"; + $sql.= " ".price2num($this->remise_percent).",".price2num($this->subprice).","; + $sql.= " ".price2num($this->total_ht).",".price2num($this->total_tva).",".price2num($this->total_localtax1).",".price2num($this->total_localtax2).",".price2num($this->total_ttc).","; + $sql.= " '".$this->info_bits."',"; + $sql.= " ".price2num($this->price_ht).",".price2num($this->remise).","; + if ($this->fk_fournprice > 0) $sql.= ' '.$this->fk_fournprice.','; + else $sql.= ' null,'; + if ($this->pa_ht > 0) $sql.= ' '.price2num($this->pa_ht); + else $sql.= ' null'; + if ($this->date_ouverture_prevue > 0) { $sql.= ",'".$this->db->idate($this->date_ouverture_prevue)."'"; } + if ($this->date_fin_validite > 0) { $sql.= ",'".$this->db->idate($this->date_fin_validite)."'"; } + $sql.= ")"; + + dol_syslog(get_class($this)."::insert", LOG_DEBUG); + + $resql=$this->db->query($sql); + if ($resql) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'contratdet'); + + // FIXME Missing insert of extrafields + + if (!$notrigger) + { + // Call trigger + $result = $this->call_trigger('LINECONTRACT_CREATE', $user); + if ($result < 0) { + $this->db->rollback(); + return -1; + } + // End call triggers + } + + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + $this->error=$this->db->error()." sql=".$sql; + return -1; + } + } } diff --git a/htdocs/contrat/tpl/linkedobjectblock.tpl.php b/htdocs/contrat/tpl/linkedobjectblock.tpl.php index f7f840dce13..4daf5deef02 100644 --- a/htdocs/contrat/tpl/linkedobjectblock.tpl.php +++ b/htdocs/contrat/tpl/linkedobjectblock.tpl.php @@ -34,19 +34,21 @@ print_titre($langs->trans('RelatedContracts')); trans("Date"); ?>   trans("Status"); ?> + $objectlink) { - $object->fetch_lines(); + $objectlink->fetch_lines(); $var=!$var; ?> > - getNomUrl(1); ?> - date_contrat,'day'); ?> + getNomUrl(1); ?> + date_contrat,'day'); ?>   - getLibStatut(6); ?> + getLibStatut(6); ?> + ">transnoentitiesnoconv("RemoveLink")); ?> diff --git a/htdocs/core/actions_dellink.inc.php b/htdocs/core/actions_dellink.inc.php new file mode 100644 index 00000000000..1ba98a8435a --- /dev/null +++ b/htdocs/core/actions_dellink.inc.php @@ -0,0 +1,36 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/actions_dellink.inc.php + * \brief Code for actions on deleting link between elements + */ + + +// $action must be defined +// $object must be defined +// $permissiondellink must be defined + +$dellinkid = GETPOST('dellinkid','int'); + +// Set public note +if ($action == 'dellink' && ! empty($permissiondellink) && ! GETPOST('cancel') && $dellinkid > 0) +{ + $result=$object->deleteObjectLinked(0, '', 0, '', $dellinkid); + if ($result < 0) setEventMessages($object->error,$object->errors,'errors'); +} diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 5bc08cab739..69f1c6df145 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -2166,7 +2166,7 @@ abstract class CommonObject } // Links between objects are stored in table element_element - $sql = 'SELECT fk_source, sourcetype, fk_target, targettype'; + $sql = 'SELECT rowid, fk_source, sourcetype, fk_target, targettype'; $sql.= ' FROM '.MAIN_DB_PREFIX.'element_element'; $sql.= " WHERE "; if ($justsource || $justtarget) @@ -2201,11 +2201,11 @@ abstract class CommonObject $obj = $this->db->fetch_object($resql); if ($obj->fk_source == $sourceid) { - $this->linkedObjectsIds[$obj->targettype][]=$obj->fk_target; + $this->linkedObjectsIds[$obj->targettype][$obj->rowid]=$obj->fk_target; } if ($obj->fk_target == $targetid) { - $this->linkedObjectsIds[$obj->sourcetype][]=$obj->fk_source; + $this->linkedObjectsIds[$obj->sourcetype][$obj->rowid]=$obj->fk_source; } $i++; } @@ -2260,16 +2260,15 @@ abstract class CommonObject $classfile = 'fournisseur.commande'; $classname = 'CommandeFournisseur'; } + // Here $module, $classfile and $classname are set if ($conf->$module->enabled && (($element != $this->element) || $alsosametype)) { dol_include_once('/'.$classpath.'/'.$classfile.'.class.php'); - $num=count($objectids); - - for ($i=0;$i<$num;$i++) + foreach($objectids as $i => $objectid); // $i is rowid into llx_element_element { $object = new $classname($this->db); - $ret = $object->fetch($objectids[$i]); + $ret = $object->fetch($objectid); if ($ret >= 0) { $this->linkedObjects[$objecttype][$i] = $object; @@ -2338,10 +2337,11 @@ abstract class CommonObject * @param string $sourcetype Object source type * @param int $targetid Object target id * @param string $targettype Object target type - * @return int >0 if OK, <0 if KO + * @param int $rowid Row id of line to delete. If defined, other parameters are not used. + * @return int >0 if OK, <0 if KO * @see add_object_linked, updateObjectLinked, fetchObjectLinked */ - function deleteObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='') + function deleteObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $rowid='') { $deletesource=false; $deletetarget=false; @@ -2356,21 +2356,28 @@ abstract class CommonObject $sql = "DELETE FROM ".MAIN_DB_PREFIX."element_element"; $sql.= " WHERE"; - if ($deletesource) + if ($rowid > 0) { - $sql.= " fk_source = ".$sourceid." AND sourcetype = '".$sourcetype."'"; - $sql.= " AND fk_target = ".$this->id." AND targettype = '".$this->element."'"; - } - else if ($deletetarget) - { - $sql.= " fk_target = ".$targetid." AND targettype = '".$targettype."'"; - $sql.= " AND fk_source = ".$this->id." AND sourcetype = '".$this->element."'"; + $sql.=" rowid = ".$rowid; } else { - $sql.= " (fk_source = ".$this->id." AND sourcetype = '".$this->element."')"; - $sql.= " OR"; - $sql.= " (fk_target = ".$this->id." AND targettype = '".$this->element."')"; + if ($deletesource) + { + $sql.= " fk_source = ".$sourceid." AND sourcetype = '".$sourcetype."'"; + $sql.= " AND fk_target = ".$this->id." AND targettype = '".$this->element."'"; + } + else if ($deletetarget) + { + $sql.= " fk_target = ".$targetid." AND targettype = '".$targettype."'"; + $sql.= " AND fk_source = ".$this->id." AND sourcetype = '".$this->element."'"; + } + else + { + $sql.= " (fk_source = ".$this->id." AND sourcetype = '".$this->element."')"; + $sql.= " OR"; + $sql.= " (fk_target = ".$this->id." AND targettype = '".$this->element."')"; + } } dol_syslog(get_class($this)."::deleteObjectLinked", LOG_DEBUG); @@ -2381,6 +2388,7 @@ abstract class CommonObject else { $this->error=$this->db->lasterror(); + $this->errors[]=$this->error; return -1; } } diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 34abeeb8c6e..ebac8ccd797 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -1324,6 +1324,10 @@ class ExtraFields $value=$object->getNomUrl(3); } } + elseif ($type == 'text') + { + $value=dol_htmlentitiesbr($value); + } else { $showsize=round($size); diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index c7b7374a8f9..5287155357f 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4900,20 +4900,20 @@ class Form print '' . $langs->trans("AmountHTShort") . ''; print '' . $langs->trans("Company") . ''; print ''; - while ($i < $num) { + while ($i < $num) + { $objp = $this->db->fetch_object($resqlorderlist); - if ($objp->socid == $societe->id) { - $var = ! $var; - print ''; - print ''; - print ''; - print '' . $objp->ref . ''; - print '' . $objp->ref_supplier . ''; - print '' . price($objp->total_ht) . ''; - print '' . $objp->name . ''; - print ''; - print ''; - } + + $var = ! $var; + print ''; + print ''; + print ''; + print '' . $objp->ref . ''; + print '' . $objp->ref_supplier . ''; + print '' . price($objp->total_ht) . ''; + print '' . $objp->name . ''; + print ''; + print ''; $i ++; } diff --git a/htdocs/core/db/mysql.class.php b/htdocs/core/db/mysql.class.php index bca6d0798b8..cc373acc163 100644 --- a/htdocs/core/db/mysql.class.php +++ b/htdocs/core/db/mysql.class.php @@ -253,6 +253,8 @@ class DoliDBMysql extends DoliDB */ function query($query,$usesavepoint=0,$type='auto') { + global $conf; + $query = trim($query); if (! in_array($query,array('BEGIN','COMMIT','ROLLBACK'))) dol_syslog('sql='.$query, LOG_DEBUG); @@ -277,7 +279,8 @@ class DoliDBMysql extends DoliDB $this->lasterror = $this->error(); $this->lasterrno = $this->errno(); - dol_syslog(get_class($this)."::query SQL Error message: ".$this->lasterrno." ".$this->lasterror, LOG_ERR); + if ($conf->global->SYSLOG_LEVEL < LOG_DEBUG) dol_syslog(get_class($this)."::query SQL Error query: ".$query, LOG_ERR); // Log of request was not yet done previously + dol_syslog(get_class($this)."::query SQL Error message: ".$this->lasterrno." ".$this->lasterror, LOG_ERR); } $this->lastquery=$query; $this->_results = $ret; diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php index d714a277ae0..4033dc01117 100644 --- a/htdocs/core/db/mysqli.class.php +++ b/htdocs/core/db/mysqli.class.php @@ -255,6 +255,8 @@ class DoliDBMysqli extends DoliDB */ function query($query,$usesavepoint=0,$type='auto') { + global $conf; + $query = trim($query); if (! in_array($query,array('BEGIN','COMMIT','ROLLBACK'))) dol_syslog('sql='.$query, LOG_DEBUG); @@ -278,6 +280,7 @@ class DoliDBMysqli extends DoliDB $this->lasterror = $this->error(); $this->lasterrno = $this->errno(); + if ($conf->global->SYSLOG_LEVEL < LOG_DEBUG) dol_syslog(get_class($this)."::query SQL Error query: ".$query, LOG_ERR); // Log of request was not yet done previously dol_syslog(get_class($this)."::query SQL Error message: ".$this->lasterrno." ".$this->lasterror, LOG_ERR); } $this->lastquery=$query; diff --git a/htdocs/core/db/pgsql.class.php b/htdocs/core/db/pgsql.class.php index 0466c2ad96b..41bd45bebff 100644 --- a/htdocs/core/db/pgsql.class.php +++ b/htdocs/core/db/pgsql.class.php @@ -509,11 +509,11 @@ class DoliDBPgsql extends DoliDB $this->lastqueryerror = $query; $this->lasterror = $this->error(); $this->lasterrno = $this->errno(); - } - dol_syslog(get_class($this)."::query SQL Error query: ".$query, LOG_ERR); - dol_syslog(get_class($this)."::query SQL Error message: ".$this->lasterror." (".$this->lasterrno.")", LOG_ERR); - dol_syslog(get_class($this)."::query SQL error usesavepoint = ".$usesavepoint, LOG_ERR); + if ($conf->global->SYSLOG_LEVEL < LOG_DEBUG) dol_syslog(get_class($this)."::query SQL Error query: ".$query, LOG_ERR); // Log of request was not yet done previously + dol_syslog(get_class($this)."::query SQL Error message: ".$this->lasterror." (".$this->lasterrno.")", LOG_ERR); + dol_syslog(get_class($this)."::query SQL Error usesavepoint = ".$usesavepoint, LOG_ERR); + } if ($usesavepoint && $this->transaction_opened) // Warning, after that errno will be erased { diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index 2eb0fbb77ba..d59e3c9a864 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -40,7 +40,8 @@ function versiontostring($versionarray) } /** - * Compare 2 versions (stored into 2 arrays) + * Compare 2 versions (stored into 2 arrays). + * For example, to check if Dolibarr version is lower than (x,y,z), do "if versioncompare(versiondolibarrarray(), array(x.y.z)) <= 0" * * @param array $versionarray1 Array of version (vermajor,verminor,patch) * @param array $versionarray2 Array of version (vermajor,verminor,patch) diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php index 9eae0038194..67c7df4be5b 100644 --- a/htdocs/core/lib/date.lib.php +++ b/htdocs/core/lib/date.lib.php @@ -88,6 +88,7 @@ function getServerTimeZoneInt($refgmtdate='now') if ($refgmtdate == 'now') $newrefgmtdate=$yearref.'-'.$monthref.'-'.$dayref; elseif ($refgmtdate == 'summer') $newrefgmtdate=$yearref.'-08-01'; else $newrefgmtdate=$yearref.'-01-01'; + $newrefgmtdate.='T00:00:00+00:00'; $localtz = new DateTimeZone(getServerTimeZoneString()); $localdt = new DateTime($newrefgmtdate, $localtz); $tmp=-1*$localtz->getOffset($localdt); @@ -97,30 +98,6 @@ function getServerTimeZoneInt($refgmtdate='now') { $tmp=0; dol_print_error('','PHP version must be 5.3+'); - /* - // Method 2 (does not include daylight, not supported by adodb) - if ($refgmtdate == 'now') - { - if (ini_get("date.timezone")=='UTC') return 0; - // We don't know server timezone string, so we don't know location, so we can't guess daylight. We assume we use same than client but this may be a bug. - $gmtnow=dol_now('gmt'); $yearref=dol_print_date($gmtnow,'%Y'); $monthref=dol_print_date($gmtnow,'%m'); $dayref=dol_print_date($gmtnow,'%d'); - if (dol_stringtotime($_SESSION['dol_dst_first']) <= $gmtnow && $gmtnow < dol_stringtotime($_SESSION['dol_dst_second'])) $daylight=1; - else $daylight=0; - $tmp=dol_mktime(0,0,0,$monthref,$dayref,$yearref,false,0)-dol_mktime(0,0,0,$monthref,$dayref,$yearref,true,0)-($daylight*3600); - return 'unknown'; // For true result - } - elseif ($refgmtdate == 'summer') - { - if (ini_get("date.timezone")=='UTC') return 0; - // We don't know server timezone string, so we don't know location, so we can't guess daylight. We assume we use same than client but this may be a bug. - $gmtnow=dol_now('gmt'); $yearref=dol_print_date($gmtnow,'%Y'); $monthref='08'; $dayref='01'; - if (dol_stringtotime($_SESSION['dol_dst_first']) <= dol_stringtotime($yearref.'-'.$monthref.'-'.$dayref) && dol_stringtotime($yearref.'-'.$monthref.'-'.$dayref) < dol_stringtotime($_SESSION['dol_dst_second'])) $daylight=1; - else $daylight=0; - $tmp=dol_mktime(0,0,0,$monthref,$dayref,$yearref,false,0)-dol_mktime(0,0,0,$monthref,$dayref,$yearref,true,0)-($daylight*3600); - return 'unknown'; // For true result - } - else $tmp=dol_mktime(0,0,0,1,1,1970); - */ } $tz=round(($tmp<0?1:-1)*abs($tmp/3600)); return $tz; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 30d8e7a5045..6074f6fe841 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -962,7 +962,8 @@ function dol_strftime($fmt, $ts=false, $is_gmt=false) * "day", "daytext", "dayhour", "dayhourldap", "dayhourtext", "dayrfc", "dayhourrfc" * @param string $tzoutput true or 'gmt' => string is for Greenwich location * false or 'tzserver' => output string is for local PHP server TZ usage - * 'tzuser' => output string is for local browser TZ usage + * 'tzuser' => output string is for user TZ (current browser TZ with current dst) + * 'tzuserrel' => output string is for user TZ (current browser TZ with dst or not, depending on date position) * @param Translate $outputlangs Object lang that contains language for text translation. * @param boolean $encodetooutput false=no convert into output pagecode * @return string Formated date or '' if time is null @@ -984,19 +985,17 @@ function dol_print_date($time,$format='',$tzoutput='tzserver',$outputlangs='',$e if ($tzoutput == 'tzserver') { $to_gmt=false; - $offsettz=$offsetdst=0; + $offsettzstring=@date_default_timezone_get(); // Example 'Europe/Berlin' or 'Indian/Reunion' + $offsettz=0; + $offsetdst=0; } elseif ($tzoutput == 'tzuser') { $to_gmt=true; + $offsettzstring=(empty($_SESSION['dol_tz_string'])?'UTC':$_SESSION['dol_tz_string']); // Example 'Europe/Berlin' or 'Indian/Reunion' $offsettz=(empty($_SESSION['dol_tz'])?0:$_SESSION['dol_tz'])*60*60; $offsetdst=(empty($_SESSION['dol_dst'])?0:$_SESSION['dol_dst'])*60*60; } - elseif ($tzoutput == 'tzcompany') - { - $to_gmt=false; - $offsettz=$offsetdst=0; // TODO Define this and use it later - } } } if (! is_object($outputlangs)) $outputlangs=$langs; @@ -1045,9 +1044,9 @@ function dol_print_date($time,$format='',$tzoutput='tzserver',$outputlangs='',$e $format=str_replace('%A','__A__',$format); } - // Analyze date (deprecated) Ex: 1970-01-01, 1970-01-01 01:00:00, 19700101010000 + // Analyze date if (preg_match('/^([0-9]+)\-([0-9]+)\-([0-9]+) ?([0-9]+)?:?([0-9]+)?:?([0-9]+)?/i',$time,$reg) - || preg_match('/^([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])$/i',$time,$reg)) + || preg_match('/^([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])$/i',$time,$reg)) // Deprecated. Ex: 1970-01-01, 1970-01-01 01:00:00, 19700101010000 { // This part of code should not be used. TODO Remove this. dol_syslog("Functions.lib::dol_print_date function call with deprecated value of time in page ".$_SERVER["PHP_SELF"], LOG_WARNING); @@ -1067,7 +1066,7 @@ function dol_print_date($time,$format='',$tzoutput='tzserver',$outputlangs='',$e // Date is a timestamps if ($time < 100000000000) // Protection against bad date values { - $ret=adodb_strftime($format,$time+$offsettz+$offsetdst,$to_gmt); // TODO Remove this + $ret=adodb_strftime($format,$time+$offsettz+$offsetdst,$to_gmt); // TODO Replace this with function Date PHP. We also should not use anymore offsettz and offsetdst but only offsettzstring. } else $ret='Bad value '.$time.' for date'; } @@ -1198,13 +1197,13 @@ function dol_mktime($hour,$minute,$second,$month,$day,$year,$gm=false,$check=1) { if (empty($gm) || $gm === 'server') { - $default_timezone=@date_default_timezone_get(); + $default_timezone=@date_default_timezone_get(); // Example 'Europe/Berlin' $localtz = new DateTimeZone($default_timezone); } else if ($gm === 'user') { - // We use dol_tz_string first because it contains dst. - $default_timezone=(empty($_SESSION["dol_tz_string"])?@date_default_timezone_get():$_SESSION["dol_tz_string"]); + // We use dol_tz_string first because it is more reliable. + $default_timezone=(empty($_SESSION["dol_tz_string"])?@date_default_timezone_get():$_SESSION["dol_tz_string"]); // Example 'Europe/Berlin' try { $localtz = new DateTimeZone($default_timezone); } diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php index e7566107613..de3b112e37f 100644 --- a/htdocs/core/lib/functions2.lib.php +++ b/htdocs/core/lib/functions2.lib.php @@ -1351,8 +1351,7 @@ function dol_print_reduction($reduction,$langs) /** * Return OS version. - * Note that PHP_OS returns only OS (not version) and OS PHP was built on, not - * necessarly OS PHP runs on. + * Note that PHP_OS returns only OS (not version) and OS PHP was built on, not necessarly OS PHP runs on. * * @return string OS version */ @@ -1366,6 +1365,7 @@ function version_os() * Return PHP version * * @return string PHP version + * @see versionphparray */ function version_php() { @@ -1376,6 +1376,7 @@ function version_php() * Return Dolibarr version * * @return string Dolibarr version + * @see versiondolibarrarray */ function version_dolibarr() { diff --git a/htdocs/core/lib/json.lib.php b/htdocs/core/lib/json.lib.php index e3f00a064e5..5a87e253758 100644 --- a/htdocs/core/lib/json.lib.php +++ b/htdocs/core/lib/json.lib.php @@ -253,7 +253,9 @@ function dol_json_decode($json, $assoc=false) if (! empty($array)) { $object = false; - + if (count($array)>0) { + $object = (object) array(); + } foreach ($array as $key => $value) { if ($key) $object->{$key} = $value; diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 5167fcd69f3..f924922cb87 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -378,7 +378,7 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t // Title of task print ""; if ($showlineingray) print ''; - else print ''; + else print ''; for ($k = 0 ; $k < $level ; $k++) { print "     "; @@ -401,7 +401,7 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t $plannedworkloadoutputformat='allhourmin'; $timespentoutputformat='allhourmin'; if (! empty($conf->global->PROJECT_PLANNED_WORKLOAD_FORMAT)) $plannedworkloadoutputformat=$conf->global->PROJECT_PLANNED_WORKLOAD_FORMAT; - if (! empty($conf->global->PROJECT_TIMES_PENT_FORMAT)) $timespentoutputformat=$conf->global->PROJECT_TIME_SPENT_FORMAT; + if (! empty($conf->global->PROJECT_TIMES_SPENT_FORMAT)) $timespentoutputformat=$conf->global->PROJECT_TIME_SPENT_FORMAT; // Planned Workload (in working hours) print ''; diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql index d65108e5f1a..19ada8b9b56 100644 --- a/htdocs/core/menus/init_menu_auguria.sql +++ b/htdocs/core/menus/init_menu_auguria.sql @@ -301,7 +301,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->holiday->enabled', __HANDLER__, 'left', 5002__+MAX_llx_menu__, 'hrm', '', 5000__+MAX_llx_menu__, '/holiday/define_holiday.php?&action=request', 'MenuConfCP', 1, 'holiday', '$user->rights->holiday->define_holiday', '', 0, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->holiday->enabled', __HANDLER__, 'left', 5003__+MAX_llx_menu__, 'hrm', '', 5000__+MAX_llx_menu__, '/holiday/view_log.php?&action=request', 'MenuLogCP', 1, 'holiday', '$user->rights->holiday->view_log', '', 0, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->holiday->enabled', __HANDLER__, 'left', 5004__+MAX_llx_menu__, 'hrm', '', 5000__+MAX_llx_menu__, '/holiday/month_report.php?&action=request', 'MenuReportMonth', 1, 'holiday', '$user->rights->holiday->month_report', '', 0, 4, __ENTITY__); --- HRM - Trips and expenses +-- HRM - Expense reports insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->deplacement->enabled', __HANDLER__, 'left', 2100__+MAX_llx_menu__, 'accountancy', 'tripsandexpenses', 15__+MAX_llx_menu__, '/compta/deplacement/index.php?leftmenu=tripsandexpenses', 'TripsAndExpenses', 0, 'trips', '$user->rights->deplacement->lire', '', 0, 5, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->deplacement->enabled', __HANDLER__, 'left', 2101__+MAX_llx_menu__, 'accountancy', '', 2100__+MAX_llx_menu__, '/compta/deplacement/card.php?action=create&leftmenu=tripsandexpenses', 'New', 1, 'trips', '$user->rights->deplacement->creer', '', 0, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->deplacement->enabled', __HANDLER__, 'left', 2102__+MAX_llx_menu__, 'accountancy', '', 2100__+MAX_llx_menu__, '/compta/deplacement/list.php?leftmenu=tripsandexpenses', 'List', 1, 'trips', '$user->rights->deplacement->lire', '', 0, 2, __ENTITY__); diff --git a/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php b/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php index 3188359367c..5123f713a6e 100644 --- a/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php @@ -567,7 +567,7 @@ class pdf_rouget extends ModelePdfExpedition $posy+=4; $pdf->SetXY($posx,$posy); $pdf->SetTextColor(0,0,60); - $pdf->MultiCell(100, 4, $outputlangs->transnoentities("DateDeliveryPlanned")." : ".dol_print_date($object->date_livraison,"daytext",false,$outputlangs,true), '', 'R'); + $pdf->MultiCell(100, 4, $outputlangs->transnoentities("DateDeliveryPlanned")." : ".dol_print_date($object->date_delivery,"daytext",false,$outputlangs,true), '', 'R'); if (! empty($object->client->code_client)) { diff --git a/htdocs/core/modules/modAgenda.class.php b/htdocs/core/modules/modAgenda.class.php index 0e8eae911d2..819ee0c1206 100644 --- a/htdocs/core/modules/modAgenda.class.php +++ b/htdocs/core/modules/modAgenda.class.php @@ -227,7 +227,7 @@ class modAgenda extends DolibarrModules // Calendar $this->menu[$r]=array('fk_menu'=>'r=1', 'type'=>'left', - 'titre'=>'Calendar', + 'titre'=>'Agenda', 'mainmenu'=>'agenda', 'url'=>'/comm/action/index.php?mainmenu=agenda&leftmenu=agenda', 'langs'=>'agenda', diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 8b56049fe7f..b1426f4a391 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -493,7 +493,7 @@ jQuery(document).ready(function() { jQuery('#trlinefordates').show(); }); - /* Sur changemenr de produit, on recharge la liste des prix fournisseur */ + /* When changing predefined product, we reload list of supplier prices */ $("#idprod, #idprodfournprice").change(function() { setforpredef(); @@ -521,6 +521,11 @@ jQuery(document).ready(function() { if (this.id != 'pmpprice') { i++; + + // If margin is calculated on best supplier price, we set it by defaut (but only if value is not 0) + var defaultbuyprice = 'global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == '1')?'bestsupplierprice':''); ?>'; + if (i == 1 && this.price > 0 && 'bestsupplierprice' == defaultbuyprice) { defaultkey = this.id; defaultprice = this.price; } + options += ''; @@ -528,16 +533,19 @@ jQuery(document).ready(function() { if (this.id == 'pmpprice') { // If margin is calculated on PMP, we set it by defaut (but only if value is not 0) - var defaultbuyprice = global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == 'pmp')?1:0); ?>; - if (this.price > 0 && 1 == defaultbuyprice) { defaultkey = this.id; defaultprice = this.price; } + var defaultbuyprice = 'global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == 'pmp')?'pmp':''); ?>'; + if (this.price > 0 && 'pmp' == defaultbuyprice) { defaultkey = this.id; defaultprice = this.price; } + options += ''; } }); options += ''; - /* alert(defaultkey+' '+defaultprice); */ $("#fournprice_predef").html(options).show(); - $("#fournprice_predef").val(defaultkey); + if (defaultkey != '') + { + $("#fournprice_predef").val(defaultkey); + } /* At loading, no product are yet selected, so we hide field of buying_price */ $("#buying_price").hide(); diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 51a3bc51fbe..9cee623b679 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -82,6 +82,9 @@ include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be inclu // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array $hookmanager->initHooks(array('expeditioncard','globalcard')); +$permissiondellink=$user->rights->expedition->livraison->creer; // Used by the include of actions_dellink.inc.php + + /* * Actions @@ -114,6 +117,8 @@ if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'e if (empty($reshook)) { + include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once + if ($action == 'add') { $error=0; diff --git a/htdocs/expedition/tpl/linkedobjectblock.tpl.php b/htdocs/expedition/tpl/linkedobjectblock.tpl.php index abca7594962..d4a9d1f9af2 100644 --- a/htdocs/expedition/tpl/linkedobjectblock.tpl.php +++ b/htdocs/expedition/tpl/linkedobjectblock.tpl.php @@ -39,24 +39,26 @@ print_titre($langs->trans('RelatedShippings')); trans("DateDeliveryPlanned"); ?> trans("AmountHTShort"); ?> trans("Status"); ?> + $objectlink) { $var=!$var; ?> > - getNomUrl(1); ?> - date_creation,'day'); ?> - date_delivery,'day'); ?> + getNomUrl(1); ?> + date_creation,'day'); ?> + date_delivery,'day'); ?> rights->expedition->lire) { - $total = $total + $object->total_ht; - echo price($object->total_ht); + $total = $total + $objectlink->total_ht; + echo price($objectlink->total_ht); } ?> - getLibStatut(3); ?> + getLibStatut(3); ?> + ">transnoentitiesnoconv("RemoveLink")); ?> rights->expedition->lire) { echo price($total); } ?> -   + + diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 0d582217011..e7990631457 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1546,7 +1546,7 @@ else else { print ''; - print ''.$langs->trans("Approbator").''; + print ''.$langs->trans("ApprovedBy").''; print ''; if ($object->fk_user_approve > 0) { @@ -1580,6 +1580,7 @@ else if($object->fk_statut==6) { + /* TODO this fields are not yet filled print ''; print ''.$langs->trans("AUTHORPAIEMENT").''; print ''; @@ -1591,6 +1592,7 @@ else print ''.$langs->trans("DATE_PAIEMENT").''; print ''.$object->date_paiement.''; print ''; + */ } print ''; diff --git a/htdocs/exports/export.php b/htdocs/exports/export.php index 3418acc6f18..452f8474e97 100644 --- a/htdocs/exports/export.php +++ b/htdocs/exports/export.php @@ -118,7 +118,7 @@ $field=GETPOST("field"); $objexport=new Export($db); $objexport->load_arrays($user,$datatoexport); -$objmodelexport=new ModeleExports(); +$objmodelexport=new ModeleExports($db); $form = new Form($db); $htmlother = new FormOther($db); $formfile = new FormFile($db); @@ -293,7 +293,7 @@ if ($action == 'add_export_model') $hexafiltervalue.=$key.'='.$val; } } - + $objexport->model_name = $export_name; $objexport->datatoexport = $datatoexport; $objexport->hexa = $hexa; diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php index b73d2281a3a..198eb11dddb 100644 --- a/htdocs/fichinter/card.php +++ b/htdocs/fichinter/card.php @@ -93,6 +93,7 @@ if ($id > 0 || ! empty($ref)) } $permissionnote=$user->rights->ficheinter->creer; // Used by the include of actions_setnotes.inc.php +$permissiondellink=$user->rights->ficheinter->creer; // Used by the include of actions_dellink.inc.php /* @@ -103,832 +104,837 @@ $parameters=array('socid'=>$socid); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not include_once - -if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->ficheinter->creer) +if (empty($reshook)) { - $result = $object->setValid($user); - if ($result >= 0) + include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not include_once + + include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once + + if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->ficheinter->creer) { - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','alpha')) $newlang=GETPOST('lang_id','alpha'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) $result=fichinter_create($db, $object, GETPOST('model','alpha'), $outputlangs); - - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); - exit; - } - else - { - $mesg='
'.$object->error.'
'; - } -} - -else if ($action == 'confirm_modify' && $confirm == 'yes' && $user->rights->ficheinter->creer) -{ - $result = $object->setDraft($user); - if ($result >= 0) - { - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','alpha')) $newlang=GETPOST('lang_id','alpha'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) $result=fichinter_create($db, $object, (!GETPOST('model','alpha'))?$object->model:GETPOST('model','apha'), $outputlangs); - - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); - exit; - } - else - { - $mesg='
'.$object->error.'
'; - } -} - -else if ($action == 'add' && $user->rights->ficheinter->creer) -{ - $object->socid = $socid; - $object->duration = GETPOST('duration','int'); - $object->fk_project = GETPOST('projectid','int'); - $object->fk_contrat = GETPOST('contratid','int'); - $object->author = $user->id; - $object->description = GETPOST('description'); - $object->ref = $ref; - $object->modelpdf = GETPOST('model','alpha'); - $object->note_private = GETPOST('note_private'); - $object->note_public = GETPOST('note_public'); - - if ($object->socid > 0) - { - // If creation from another object of another module (Example: origin=propal, originid=1) - if (!empty($origin) && !empty($originid) ) - { - // Parse element/subelement (ex: project_task) - $element = $subelement = $_POST['origin']; - if (preg_match('/^([^_]+)_([^_]+)/i',$_POST['origin'],$regs)) - { - $element = $regs[1]; - $subelement = $regs[2]; - } - - // For compatibility - if ($element == 'order') { - $element = $subelement = 'commande'; - } - if ($element == 'propal') { - $element = 'comm/propal'; $subelement = 'propal'; - } - if ($element == 'contract') { - $element = $subelement = 'contrat'; - } - - $object->origin = $origin; - $object->origin_id = $originid; - - // Possibility to add external linked objects with hooks - $object->linked_objects[$object->origin] = $object->origin_id; - if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects'])) - { - $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']); - } - - // Extrafields - $extrafields = new ExtraFields($db); - $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); - $array_options = $extrafields->getOptionalsFromPost($extralabels); - - $object->array_options = $array_options; - - $id = $object->create($user); - - if ($id > 0) - { - dol_include_once('/'.$element.'/class/'.$subelement.'.class.php'); - - $classname = ucfirst($subelement); - $srcobject = new $classname($db); - - dol_syslog("Try to find source object origin=".$object->origin." originid=".$object->origin_id." to add lines"); - $result=$srcobject->fetch($object->origin_id); - if ($result > 0) - { - $srcobject->fetch_thirdparty(); - $lines = $srcobject->lines; - if (empty($lines) && method_exists($srcobject,'fetch_lines')) - { - $srcobject->fetch_lines(); - $lines = $srcobject->lines; - } - - $fk_parent_line=0; - $num=count($lines); - - for ($i=0;$i<$num;$i++) - { - $product_type=($lines[$i]->product_type?$lines[$i]->product_type:0); - - if ($product_type == 1 || !empty($conf->global->FICHINTER_PRINT_PRODUCTS)) { //only services except if config includes products - // service prédéfini - if ($lines[$i]->fk_product > 0) - { - // Define output language - if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) - { - $prod = new Product($db); - $prod->id=$lines[$i]->fk_product; - $prod->getMultiLangs(); - // We show if duration is present on service (so we get it) - $prod->fetch($lines[$i]->fk_product); - if ($prod->duration_value && $prod->duration_unit == 'h' && $conf->global->FICHINTER_USE_SERVICE_DURATION) - { - $durationproduct=$prod->duration_value * 3600 * $lines[$i]->qty; - } - else - $durationproduct=3600; - $outputlangs = $langs; - $newlang=''; - if (empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id'); - if (empty($newlang)) $newlang=$srcobject->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - - $label = (! empty($prod->multilangs[$outputlangs->defaultlang]["libelle"])) ? $prod->multilangs[$outputlangs->defaultlang]["libelle"] : $lines[$i]->product_label; - } - else - { - $label = $lines[$i]->product_label; - } - - $desc = $label; - $desc .= ' ('.$langs->trans('Quantity').': '.$lines[$i]->qty.')'; - } - else { - $desc = dol_htmlentitiesbr($lines[$i]->desc); - $desc .= ' ('.$langs->trans('Quantity').': '.$lines[$i]->qty.')'; - } - $timearray=dol_getdate(mktime()); - $date_intervention=dol_mktime(0,0,0,$timearray['mon'],$timearray['mday'],$timearray['year']); - if ($product_type == 1) - { //service - $duration = $durationproduct; - } - else - { //product - $duration = 0; - } - - $predef = ''; - // Extrafields - $extrafieldsline = new ExtraFields($db); - $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); - $array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef); - - - $result = $object->addline( - $user, - $id, - $desc, - $date_intervention, - $duration, - $array_options - ); - - if ($result < 0) - { - $error++; - break; - } - - } - } - - } - else - { - $mesg=$srcobject->error; - $error++; - } - } - else - { - $mesg=$object->error; - $error++; - } - } - else - { - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels, $object); - if ($ret < 0) { - $error ++; - $action = 'create'; - } - - if (! $error) - { - // Extrafields - $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); - $array_options = $extrafields->getOptionalsFromPost($extralabels); - - $object->array_options = $array_options; - - $result = $object->create($user); - if ($result > 0) - { - $id=$result; // Force raffraichissement sur fiche venant d'etre cree - } - else - { - $langs->load("errors"); - setEventMessages($object->error, $object->errors, 'errors'); - $action = 'create'; - } - } - } - } - else - { - $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->trans("ThirdParty")).'
'; - $action = 'create'; - } -} - -else if ($action == 'update' && $user->rights->ficheinter->creer) -{ - $object->socid = $socid; - $object->fk_project = GETPOST('projectid','int'); - $object->fk_contrat = GETPOST('contratid','int'); - $object->author = $user->id; - $object->description = GETPOST('description','alpha'); - $object->ref = $ref; - - $result=$object->update($user); - if ($result<0) { - setEventMessage($object->error,'errors'); - } -} - -/* - * Build doc - */ -else if ($action == 'builddoc' && $user->rights->ficheinter->creer) // En get ou en post -{ - $object->fetch_lines(); - - // Save last template used to generate document - if (GETPOST('model')) $object->setDocModel($user, GETPOST('model','alpha')); - - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','alpha')) $newlang=GETPOST('lang_id','alpha'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - $result=fichinter_create($db, $object, GETPOST('model','alpha'), $outputlangs); - if ($result <= 0) - { - dol_print_error($db,$result); - exit; - } -} - -// Remove file in doc form -else if ($action == 'remove_file') -{ - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - $object->fetch_thirdparty(); - - $langs->load("other"); - $upload_dir = $conf->ficheinter->dir_output; - $file = $upload_dir . '/' . GETPOST('file'); - $ret=dol_delete_file($file,0,0,0,$object); - if ($ret) setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile'))); - else setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors'); -} - -// Set into a project -else if ($action == 'classin' && $user->rights->ficheinter->creer) -{ - $result=$object->setProject(GETPOST('projectid','int')); - if ($result < 0) dol_print_error($db,$object->error); -} - -// Set into a contract -else if ($action == 'setcontrat' && $user->rights->contrat->creer) -{ - $result=$object->set_contrat($user,GETPOST('contratid','int')); - if ($result < 0) dol_print_error($db,$object->error); -} - -else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->ficheinter->supprimer) -{ - $result=$object->delete($user); - if ($result<0) { - setEventMessage($object->error,'errors'); - } - - header('Location: '.DOL_URL_ROOT.'/fichinter/list.php?leftmenu=ficheinter'); - exit; -} - -else if ($action == 'setdescription' && $user->rights->ficheinter->creer) -{ - $result=$object->set_description($user,GETPOST('description')); - if ($result < 0) dol_print_error($db,$object->error); -} - -// Add line -else if ($action == "addline" && $user->rights->ficheinter->creer) -{ - if (!GETPOST('np_desc')) - { - $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Description")).'
'; - $error++; - } - if (!GETPOST('durationhour','int') && !GETPOST('durationmin','int')) - { - $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Duration")).'
'; - $error++; - } - if (GETPOST('durationhour','int') >= 24 && GETPOST('durationmin','int') > 0) - { - $mesg='
'.$langs->trans("ErrorValueTooHigh").'
'; - $error++; - } - if (! $error) - { - $db->begin(); - - $desc=GETPOST('np_desc'); - $date_intervention = dol_mktime(GETPOST('dihour','int'), GETPOST('dimin','int'), 0, GETPOST('dimonth','int'), GETPOST('diday','int'), GETPOST('diyear','int')); - $duration = convertTime2Seconds(GETPOST('durationhour','int'), GETPOST('durationmin','int')); - - - // Extrafields - $extrafieldsline = new ExtraFields($db); - $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); - $array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline); - - $result=$object->addline( - $user, - $id, - $desc, - $date_intervention, - $duration, - $array_options - ); - - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','alpha')) $newlang=GETPOST('lang_id','alpha'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - + $result = $object->setValid($user); if ($result >= 0) { - $db->commit(); + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','alpha')) $newlang=GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) $result=fichinter_create($db, $object, GETPOST('model','alpha'), $outputlangs); - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) fichinter_create($db, $object, $object->modelpdf, $outputlangs); header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); exit; } else { - $mesg=$object->error; - $db->rollback(); + $mesg='
'.$object->error.'
'; } } -} -// Classify Billed -else if ($action == 'classifybilled' && $user->rights->ficheinter->creer) -{ - $result=$object->setStatut(2); - if ($result > 0) + else if ($action == 'confirm_modify' && $confirm == 'yes' && $user->rights->ficheinter->creer) { - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); - exit; - } - else - { - setEventMessages($object->error, $object->errors, 'errors'); - } -} - -// Classify Billed -else if ($action == 'classifyunbilled' && $user->rights->ficheinter->creer) -{ - $result=$object->setStatut(1); - if ($result > 0) - { - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); - exit; - } - else - { - $mesg='
'.$object->error.'
'; - } -} - -/* - * Mise a jour d'une ligne d'intervention - */ -else if ($action == 'updateline' && $user->rights->ficheinter->creer && GETPOST('save','alpha') == $langs->trans("Save")) -{ - $objectline = new FichinterLigne($db); - if ($objectline->fetch($lineid) <= 0) - { - dol_print_error($db); - exit; - } - - if ($object->fetch($objectline->fk_fichinter) <= 0) - { - dol_print_error($db); - exit; - } - $object->fetch_thirdparty(); - - $desc = GETPOST('np_desc'); - $date_inter = dol_mktime(GETPOST('dihour','int'), GETPOST('dimin','int'), 0, GETPOST('dimonth','int'), GETPOST('diday','int'), GETPOST('diyear','int')); - $duration = convertTime2Seconds(GETPOST('durationhour','int'),GETPOST('durationmin','int')); - - $objectline->datei = $date_inter; - $objectline->desc = $desc; - $objectline->duration = $duration; - - // Extrafields - $extrafieldsline = new ExtraFields($db); - $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); - $array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline); - $objectline->array_options = $array_options; - - $result = $objectline->update($user); - if ($result < 0) - { - dol_print_error($db); - exit; - } - - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','alpha')) $newlang=GETPOST('lang_id','alpha'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) fichinter_create($db, $object, $object->modelpdf, $outputlangs); - - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); - exit; -} - -/* - * Supprime une ligne d'intervention AVEC confirmation -*/ -else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->ficheinter->creer) -{ - $objectline = new FichinterLigne($db); - if ($objectline->fetch($lineid) <= 0) - { - dol_print_error($db); - exit; - } - $result=$objectline->deleteline($user); - - if ($object->fetch($objectline->fk_fichinter) <= 0) - { - dol_print_error($db); - exit; - } - - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','alpha')) $newlang=GETPOST('lang_id','alpha'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) fichinter_create($db, $object, $object->modelpdf, $outputlangs); -} - -/* - * Ordonnancement des lignes -*/ - -else if ($action == 'up' && $user->rights->ficheinter->creer) -{ - $object->line_up($lineid); - - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','alpha')) $newlang=GETPOST('lang_id','alpha'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) fichinter_create($db, $object, $object->modelpdf, $outputlangs); - - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.'#'.$lineid); - exit; -} - -else if ($action == 'down' && $user->rights->ficheinter->creer) -{ - $object->line_down($lineid); - - // Define output language - $outputlangs = $langs; - $newlang=''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','alpha')) $newlang=GETPOST('lang_id','alpha'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; - if (! empty($newlang)) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); - } - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) fichinter_create($db, $object, $object->modelpdf, $outputlangs); - - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.'#'.$lineid); - exit; -} - - -/* - * Add file in email form -*/ -if (GETPOST('addfile','alpha')) -{ - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - // Set tmp user directory TODO Use a dedicated directory for temp mails files - $vardir=$conf->user->dir_output."/".$user->id; - $upload_dir_tmp = $vardir.'/temp'; - - dol_add_file_process($upload_dir_tmp,0,0); - $action='presend'; -} - -/* - * Remove file in email form -*/ -if (GETPOST('removedfile','alpha')) -{ - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - // Set tmp user directory - $vardir=$conf->user->dir_output."/".$user->id; - $upload_dir_tmp = $vardir.'/temp'; - - // TODO Delete only files that was uploaded from email form - dol_remove_file_process(GETPOST('removedfile','alpha'),0); - $action='presend'; -} - -/* - * Send mail -*/ -if ($action == 'send' && ! GETPOST('cancel','alpha') && (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->ficheinter->ficheinter_advance->send)) -{ - $langs->load('mails'); - - if (GETPOST('sendto','alpha')) - { - // Le destinataire a ete fourni via le champ libre - $sendto = GETPOST('sendto','alpha'); - $sendtoid = 0; - } - elseif (GETPOST('receiver','alpha') != '-1') - { - // Recipient was provided from combo list - if (GETPOST('receiver','alpha') == 'thirdparty') // Id of third party + $result = $object->setDraft($user); + if ($result >= 0) { - $sendto = $object->client->email; + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','alpha')) $newlang=GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) $result=fichinter_create($db, $object, (!GETPOST('model','alpha'))?$object->model:GETPOST('model','apha'), $outputlangs); + + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); + exit; + } + else + { + $mesg='
'.$object->error.'
'; + } + } + + else if ($action == 'add' && $user->rights->ficheinter->creer) + { + $object->socid = $socid; + $object->duration = GETPOST('duration','int'); + $object->fk_project = GETPOST('projectid','int'); + $object->fk_contrat = GETPOST('contratid','int'); + $object->author = $user->id; + $object->description = GETPOST('description'); + $object->ref = $ref; + $object->modelpdf = GETPOST('model','alpha'); + $object->note_private = GETPOST('note_private'); + $object->note_public = GETPOST('note_public'); + + if ($object->socid > 0) + { + // If creation from another object of another module (Example: origin=propal, originid=1) + if (!empty($origin) && !empty($originid) ) + { + // Parse element/subelement (ex: project_task) + $element = $subelement = $_POST['origin']; + if (preg_match('/^([^_]+)_([^_]+)/i',$_POST['origin'],$regs)) + { + $element = $regs[1]; + $subelement = $regs[2]; + } + + // For compatibility + if ($element == 'order') { + $element = $subelement = 'commande'; + } + if ($element == 'propal') { + $element = 'comm/propal'; $subelement = 'propal'; + } + if ($element == 'contract') { + $element = $subelement = 'contrat'; + } + + $object->origin = $origin; + $object->origin_id = $originid; + + // Possibility to add external linked objects with hooks + $object->linked_objects[$object->origin] = $object->origin_id; + if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects'])) + { + $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']); + } + + // Extrafields + $extrafields = new ExtraFields($db); + $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); + $array_options = $extrafields->getOptionalsFromPost($extralabels); + + $object->array_options = $array_options; + + $id = $object->create($user); + + if ($id > 0) + { + dol_include_once('/'.$element.'/class/'.$subelement.'.class.php'); + + $classname = ucfirst($subelement); + $srcobject = new $classname($db); + + dol_syslog("Try to find source object origin=".$object->origin." originid=".$object->origin_id." to add lines"); + $result=$srcobject->fetch($object->origin_id); + if ($result > 0) + { + $srcobject->fetch_thirdparty(); + $lines = $srcobject->lines; + if (empty($lines) && method_exists($srcobject,'fetch_lines')) + { + $srcobject->fetch_lines(); + $lines = $srcobject->lines; + } + + $fk_parent_line=0; + $num=count($lines); + + for ($i=0;$i<$num;$i++) + { + $product_type=($lines[$i]->product_type?$lines[$i]->product_type:0); + + if ($product_type == 1 || !empty($conf->global->FICHINTER_PRINT_PRODUCTS)) { //only services except if config includes products + // service prédéfini + if ($lines[$i]->fk_product > 0) + { + // Define output language + if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) + { + $prod = new Product($db); + $prod->id=$lines[$i]->fk_product; + $prod->getMultiLangs(); + // We show if duration is present on service (so we get it) + $prod->fetch($lines[$i]->fk_product); + if ($prod->duration_value && $prod->duration_unit == 'h' && $conf->global->FICHINTER_USE_SERVICE_DURATION) + { + $durationproduct=$prod->duration_value * 3600 * $lines[$i]->qty; + } + else + $durationproduct=3600; + $outputlangs = $langs; + $newlang=''; + if (empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id'); + if (empty($newlang)) $newlang=$srcobject->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + + $label = (! empty($prod->multilangs[$outputlangs->defaultlang]["libelle"])) ? $prod->multilangs[$outputlangs->defaultlang]["libelle"] : $lines[$i]->product_label; + } + else + { + $label = $lines[$i]->product_label; + } + + $desc = $label; + $desc .= ' ('.$langs->trans('Quantity').': '.$lines[$i]->qty.')'; + } + else { + $desc = dol_htmlentitiesbr($lines[$i]->desc); + $desc .= ' ('.$langs->trans('Quantity').': '.$lines[$i]->qty.')'; + } + $timearray=dol_getdate(mktime()); + $date_intervention=dol_mktime(0,0,0,$timearray['mon'],$timearray['mday'],$timearray['year']); + if ($product_type == 1) + { //service + $duration = $durationproduct; + } + else + { //product + $duration = 0; + } + + $predef = ''; + // Extrafields + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef); + + + $result = $object->addline( + $user, + $id, + $desc, + $date_intervention, + $duration, + $array_options + ); + + if ($result < 0) + { + $error++; + break; + } + + } + } + + } + else + { + $mesg=$srcobject->error; + $error++; + } + } + else + { + $mesg=$object->error; + $error++; + } + } + else + { + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels, $object); + if ($ret < 0) { + $error ++; + $action = 'create'; + } + + if (! $error) + { + // Extrafields + $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); + $array_options = $extrafields->getOptionalsFromPost($extralabels); + + $object->array_options = $array_options; + + $result = $object->create($user); + if ($result > 0) + { + $id=$result; // Force raffraichissement sur fiche venant d'etre cree + } + else + { + $langs->load("errors"); + setEventMessages($object->error, $object->errors, 'errors'); + $action = 'create'; + } + } + } + } + else + { + $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->trans("ThirdParty")).'
'; + $action = 'create'; + } + } + + else if ($action == 'update' && $user->rights->ficheinter->creer) + { + $object->socid = $socid; + $object->fk_project = GETPOST('projectid','int'); + $object->fk_contrat = GETPOST('contratid','int'); + $object->author = $user->id; + $object->description = GETPOST('description','alpha'); + $object->ref = $ref; + + $result=$object->update($user); + if ($result<0) { + setEventMessage($object->error,'errors'); + } + } + + /* + * Build doc + */ + else if ($action == 'builddoc' && $user->rights->ficheinter->creer) // En get ou en post + { + $object->fetch_lines(); + + // Save last template used to generate document + if (GETPOST('model')) $object->setDocModel($user, GETPOST('model','alpha')); + + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','alpha')) $newlang=GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + $result=fichinter_create($db, $object, GETPOST('model','alpha'), $outputlangs); + if ($result <= 0) + { + dol_print_error($db,$result); + exit; + } + } + + // Remove file in doc form + else if ($action == 'remove_file') + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $object->fetch_thirdparty(); + + $langs->load("other"); + $upload_dir = $conf->ficheinter->dir_output; + $file = $upload_dir . '/' . GETPOST('file'); + $ret=dol_delete_file($file,0,0,0,$object); + if ($ret) setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile'))); + else setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors'); + } + + // Set into a project + else if ($action == 'classin' && $user->rights->ficheinter->creer) + { + $result=$object->setProject(GETPOST('projectid','int')); + if ($result < 0) dol_print_error($db,$object->error); + } + + // Set into a contract + else if ($action == 'setcontrat' && $user->rights->contrat->creer) + { + $result=$object->set_contrat($user,GETPOST('contratid','int')); + if ($result < 0) dol_print_error($db,$object->error); + } + + else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->ficheinter->supprimer) + { + $result=$object->delete($user); + if ($result<0) { + setEventMessage($object->error,'errors'); + } + + header('Location: '.DOL_URL_ROOT.'/fichinter/list.php?leftmenu=ficheinter'); + exit; + } + + else if ($action == 'setdescription' && $user->rights->ficheinter->creer) + { + $result=$object->set_description($user,GETPOST('description')); + if ($result < 0) dol_print_error($db,$object->error); + } + + // Add line + else if ($action == "addline" && $user->rights->ficheinter->creer) + { + if (!GETPOST('np_desc')) + { + $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Description")).'
'; + $error++; + } + if (!GETPOST('durationhour','int') && !GETPOST('durationmin','int')) + { + $mesg='
'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Duration")).'
'; + $error++; + } + if (GETPOST('durationhour','int') >= 24 && GETPOST('durationmin','int') > 0) + { + $mesg='
'.$langs->trans("ErrorValueTooHigh").'
'; + $error++; + } + if (! $error) + { + $db->begin(); + + $desc=GETPOST('np_desc'); + $date_intervention = dol_mktime(GETPOST('dihour','int'), GETPOST('dimin','int'), 0, GETPOST('dimonth','int'), GETPOST('diday','int'), GETPOST('diyear','int')); + $duration = convertTime2Seconds(GETPOST('durationhour','int'), GETPOST('durationmin','int')); + + + // Extrafields + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline); + + $result=$object->addline( + $user, + $id, + $desc, + $date_intervention, + $duration, + $array_options + ); + + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','alpha')) $newlang=GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + + if ($result >= 0) + { + $db->commit(); + + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) fichinter_create($db, $object, $object->modelpdf, $outputlangs); + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); + exit; + } + else + { + $mesg=$object->error; + $db->rollback(); + } + } + } + + // Classify Billed + else if ($action == 'classifybilled' && $user->rights->ficheinter->creer) + { + $result=$object->setStatut(2); + if ($result > 0) + { + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); + exit; + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } + } + + // Classify Billed + else if ($action == 'classifyunbilled' && $user->rights->ficheinter->creer) + { + $result=$object->setStatut(1); + if ($result > 0) + { + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); + exit; + } + else + { + $mesg='
'.$object->error.'
'; + } + } + + /* + * Mise a jour d'une ligne d'intervention + */ + else if ($action == 'updateline' && $user->rights->ficheinter->creer && GETPOST('save','alpha') == $langs->trans("Save")) + { + $objectline = new FichinterLigne($db); + if ($objectline->fetch($lineid) <= 0) + { + dol_print_error($db); + exit; + } + + if ($object->fetch($objectline->fk_fichinter) <= 0) + { + dol_print_error($db); + exit; + } + $object->fetch_thirdparty(); + + $desc = GETPOST('np_desc'); + $date_inter = dol_mktime(GETPOST('dihour','int'), GETPOST('dimin','int'), 0, GETPOST('dimonth','int'), GETPOST('diday','int'), GETPOST('diyear','int')); + $duration = convertTime2Seconds(GETPOST('durationhour','int'),GETPOST('durationmin','int')); + + $objectline->datei = $date_inter; + $objectline->desc = $desc; + $objectline->duration = $duration; + + // Extrafields + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline); + $objectline->array_options = $array_options; + + $result = $objectline->update($user); + if ($result < 0) + { + dol_print_error($db); + exit; + } + + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','alpha')) $newlang=GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) fichinter_create($db, $object, $object->modelpdf, $outputlangs); + + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); + exit; + } + + /* + * Supprime une ligne d'intervention AVEC confirmation + */ + else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->ficheinter->creer) + { + $objectline = new FichinterLigne($db); + if ($objectline->fetch($lineid) <= 0) + { + dol_print_error($db); + exit; + } + $result=$objectline->deleteline($user); + + if ($object->fetch($objectline->fk_fichinter) <= 0) + { + dol_print_error($db); + exit; + } + + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','alpha')) $newlang=GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) fichinter_create($db, $object, $object->modelpdf, $outputlangs); + } + + /* + * Ordonnancement des lignes + */ + + else if ($action == 'up' && $user->rights->ficheinter->creer) + { + $object->line_up($lineid); + + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','alpha')) $newlang=GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) fichinter_create($db, $object, $object->modelpdf, $outputlangs); + + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.'#'.$lineid); + exit; + } + + else if ($action == 'down' && $user->rights->ficheinter->creer) + { + $object->line_down($lineid); + + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','alpha')) $newlang=GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) fichinter_create($db, $object, $object->modelpdf, $outputlangs); + + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.'#'.$lineid); + exit; + } + + + /* + * Add file in email form + */ + if (GETPOST('addfile','alpha')) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + // Set tmp user directory TODO Use a dedicated directory for temp mails files + $vardir=$conf->user->dir_output."/".$user->id; + $upload_dir_tmp = $vardir.'/temp'; + + dol_add_file_process($upload_dir_tmp,0,0); + $action='presend'; + } + + /* + * Remove file in email form + */ + if (GETPOST('removedfile','alpha')) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + // Set tmp user directory + $vardir=$conf->user->dir_output."/".$user->id; + $upload_dir_tmp = $vardir.'/temp'; + + // TODO Delete only files that was uploaded from email form + dol_remove_file_process(GETPOST('removedfile','alpha'),0); + $action='presend'; + } + + /* + * Send mail + */ + if ($action == 'send' && ! GETPOST('cancel','alpha') && (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->ficheinter->ficheinter_advance->send)) + { + $langs->load('mails'); + + if (GETPOST('sendto','alpha')) + { + // Le destinataire a ete fourni via le champ libre + $sendto = GETPOST('sendto','alpha'); $sendtoid = 0; } - else // Id du contact + elseif (GETPOST('receiver','alpha') != '-1') { - $sendto = $object->client->contact_get_property(GETPOST('receiver'),'email'); - $sendtoid = GETPOST('receiver','alpha'); - } - } - - if (dol_strlen($sendto)) - { - $langs->load("commercial"); - - $from = GETPOST('fromname','alpha') . ' <' . GETPOST('frommail','alpha') .'>'; - $replyto = GETPOST('replytoname','alpha'). ' <' . GETPOST('replytomail','alpha').'>'; - $message = GETPOST('message'); - $sendtocc = GETPOST('sendtocc','alpha'); - $deliveryreceipt = GETPOST('deliveryreceipt','alpha'); - - if ($action == 'send') - { - if (strlen(GETPOST('subject','alphs'))) $subject = GETPOST('subject','alpha'); - else $subject = $langs->transnoentities('Intervention').' '.$object->ref; - $actiontypecode='AC_OTH_AUTO'; - $actionmsg = $langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto; - if ($message) + // Recipient was provided from combo list + if (GETPOST('receiver','alpha') == 'thirdparty') // Id of third party { - if ($sendtocc) $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . $sendtocc); - $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subject); - $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":"); - $actionmsg = dol_concatdesc($actionmsg, $message); + $sendto = $object->client->email; + $sendtoid = 0; } - $actionmsg2=$langs->transnoentities("InterventionSentByEMail",$object->ref); - } - - // Create form object - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - - $attachedfiles=$formmail->get_attached_files(); - $filepath = $attachedfiles['paths']; - $filename = $attachedfiles['names']; - $mimetype = $attachedfiles['mimes']; - - // Send by email - require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,'',$deliveryreceipt,-1); - if ($mailfile->error) - { - $mesg='
'.$mailfile->error.'
'; - } - else - { - $result=$mailfile->sendfile(); - if ($result) + else // Id du contact { - $mesg=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2)); - setEventMessage($mesg); - $error=0; + $sendto = $object->client->contact_get_property(GETPOST('receiver'),'email'); + $sendtoid = GETPOST('receiver','alpha'); + } + } - // Initialisation donnees - $object->sendtoid = $sendtoid; - $object->actiontypecode = $actiontypecode; - $object->actionmsg = $actionmsg; - $object->actionmsg2 = $actionmsg2; - $object->fk_element = $object->id; - $object->elementtype = $object->element; + if (dol_strlen($sendto)) + { + $langs->load("commercial"); - // Appel des triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($db); - $result=$interface->run_triggers('FICHINTER_SENTBYMAIL',$object,$user,$langs,$conf); - if ($result < 0) { - $error++; $object->errors=$interface->errors; - } - // Fin appel triggers + $from = GETPOST('fromname','alpha') . ' <' . GETPOST('frommail','alpha') .'>'; + $replyto = GETPOST('replytoname','alpha'). ' <' . GETPOST('replytomail','alpha').'>'; + $message = GETPOST('message'); + $sendtocc = GETPOST('sendtocc','alpha'); + $deliveryreceipt = GETPOST('deliveryreceipt','alpha'); - if ($error) + if ($action == 'send') + { + if (strlen(GETPOST('subject','alphs'))) $subject = GETPOST('subject','alpha'); + else $subject = $langs->transnoentities('Intervention').' '.$object->ref; + $actiontypecode='AC_OTH_AUTO'; + $actionmsg = $langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto; + if ($message) { - dol_print_error($db); - } - else - { - // Redirect here - // This avoid sending mail twice if going out and then back to page - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); - exit; + if ($sendtocc) $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . $sendtocc); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subject); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":"); + $actionmsg = dol_concatdesc($actionmsg, $message); } + $actionmsg2=$langs->transnoentities("InterventionSentByEMail",$object->ref); + } + + // Create form object + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + + $attachedfiles=$formmail->get_attached_files(); + $filepath = $attachedfiles['paths']; + $filename = $attachedfiles['names']; + $mimetype = $attachedfiles['mimes']; + + // Send by email + require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; + $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,'',$deliveryreceipt,-1); + if ($mailfile->error) + { + $mesg='
'.$mailfile->error.'
'; } else { - $langs->load("other"); - $mesg='
'; - if ($mailfile->error) + $result=$mailfile->sendfile(); + if ($result) { - $mesg.=$langs->trans('ErrorFailedToSendMail',$from,$sendto); - $mesg.='
'.$mailfile->error; + $mesg=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2)); + setEventMessage($mesg); + $error=0; + + // Initialisation donnees + $object->sendtoid = $sendtoid; + $object->actiontypecode = $actiontypecode; + $object->actionmsg = $actionmsg; + $object->actionmsg2 = $actionmsg2; + $object->fk_element = $object->id; + $object->elementtype = $object->element; + + // Appel des triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($db); + $result=$interface->run_triggers('FICHINTER_SENTBYMAIL',$object,$user,$langs,$conf); + if ($result < 0) { + $error++; $object->errors=$interface->errors; + } + // Fin appel triggers + + if ($error) + { + dol_print_error($db); + } + else + { + // Redirect here + // This avoid sending mail twice if going out and then back to page + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); + exit; + } } else { - $mesg.='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS'; + $langs->load("other"); + $mesg='
'; + if ($mailfile->error) + { + $mesg.=$langs->trans('ErrorFailedToSendMail',$from,$sendto); + $mesg.='
'.$mailfile->error; + } + else + { + $mesg.='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS'; + } + $mesg.='
'; } - $mesg.='
'; } } - } - else - { - $langs->load("other"); - $mesg='
'.$langs->trans('ErrorMailRecipientIsEmpty').' !
'; - dol_syslog('Recipient email is empty'); - } - - $action='presend'; -} - -else if ($action == 'update_extras') -{ - // Fill array 'array_options' with data from update form - $extralabels=$extrafields->fetch_name_optionals_label($object->table_element); - $ret = $extrafields->setOptionalsFromPost($extralabels,$object,GETPOST('attribute')); - if ($ret < 0) $error++; - - if (! $error) - { - // Actions on extra fields (by external module or standard code) - // TODO le hook fait double emploi avec le trigger !! - $hookmanager->initHooks(array('interventiondao')); - $parameters=array('id'=>$object->id); - $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks - if (empty($reshook)) - { - $result=$object->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } - else if ($reshook < 0) $error++; - } - - if ($error) $action = 'edit_extras'; -} - -if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->ficheinter->creer) -{ - if ($action == 'addcontact') - { - if ($result > 0 && $id > 0) - { - $contactid = (GETPOST('userid','int') ? GETPOST('userid','int') : GETPOST('contactid','int')); - $result = $object->add_contact($contactid, GETPOST('type','int'), GETPOST('source','alpha')); - } - - if ($result >= 0) - { - header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; - } else { - if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') + $langs->load("other"); + $mesg='
'.$langs->trans('ErrorMailRecipientIsEmpty').' !
'; + dol_syslog('Recipient email is empty'); + } + + $action='presend'; + } + + else if ($action == 'update_extras') + { + // Fill array 'array_options' with data from update form + $extralabels=$extrafields->fetch_name_optionals_label($object->table_element); + $ret = $extrafields->setOptionalsFromPost($extralabels,$object,GETPOST('attribute')); + if ($ret < 0) $error++; + + if (! $error) + { + // Actions on extra fields (by external module or standard code) + // TODO le hook fait double emploi avec le trigger !! + $hookmanager->initHooks(array('interventiondao')); + $parameters=array('id'=>$object->id); + $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks + if (empty($reshook)) { - $langs->load("errors"); - $mesg = '
'.$langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType").'
'; + $result=$object->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + else if ($reshook < 0) $error++; + } + + if ($error) $action = 'edit_extras'; + } + + if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->ficheinter->creer) + { + if ($action == 'addcontact') + { + if ($result > 0 && $id > 0) + { + $contactid = (GETPOST('userid','int') ? GETPOST('userid','int') : GETPOST('contactid','int')); + $result = $object->add_contact($contactid, GETPOST('type','int'), GETPOST('source','alpha')); + } + + if ($result >= 0) + { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; } else { - $mesg = '
'.$object->error.'
'; + if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') + { + $langs->load("errors"); + $mesg = '
'.$langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType").'
'; + } + else + { + $mesg = '
'.$object->error.'
'; + } } } - } - // bascule du statut d'un contact - else if ($action == 'swapstatut') - { - $result=$object->swapContactStatus(GETPOST('ligne','int')); - } - - // Efface un contact - else if ($action == 'deletecontact') - { - $result = $object->delete_contact(GETPOST('lineid','int')); - - if ($result >= 0) + // bascule du statut d'un contact + else if ($action == 'swapstatut') { - header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; + $result=$object->swapContactStatus(GETPOST('ligne','int')); } - else { - dol_print_error($db); + + // Efface un contact + else if ($action == 'deletecontact') + { + $result = $object->delete_contact(GETPOST('lineid','int')); + + if ($result >= 0) + { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else { + dol_print_error($db); + } } } } diff --git a/htdocs/fichinter/tpl/linkedobjectblock.tpl.php b/htdocs/fichinter/tpl/linkedobjectblock.tpl.php index adc348a1c53..81a82f06627 100644 --- a/htdocs/fichinter/tpl/linkedobjectblock.tpl.php +++ b/htdocs/fichinter/tpl/linkedobjectblock.tpl.php @@ -34,17 +34,19 @@ print_titre($langs->trans('RelatedInterventions')); trans("Ref"); ?> trans("Date"); ?> trans("Status"); ?> + $objectlink) { $var=!$var; ?> > - getNomUrl(1); ?> - datev,'day'); ?> - getLibStatut(3); ?> + getNomUrl(1); ?> + datev,'day'); ?> + getLibStatut(3); ?> + ">transnoentitiesnoconv("RemoveLink")); ?> id > 0) print ''; } + $var = True; while ($i < $num && $i <= $MAXLIST) { $obj = $db->fetch_object($resql); @@ -494,6 +495,7 @@ if ($object->id > 0) print ''; print ''; } + $var=True; while ($i < min($num,$MAXLIST)) { $obj = $db->fetch_object($resql); diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 6628aeb19d7..9bd341e357c 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -703,7 +703,10 @@ class CommandeFournisseur extends CommonOrder { $sql.= " date_approve='".$this->db->idate($now)."',"; $sql.= " fk_user_approve = ".$user->id; - if (! empty($conf->global->SUPPLIER_ORDER_DOUBLE_APPROVAL)) $movetoapprovestatus=false; + if (! empty($conf->global->SUPPLIER_ORDER_DOUBLE_APPROVAL) && $conf->global->MAIN_FEATURES_LEVEL > 0 && $this->total_ht >= $conf->global->SUPPLIER_ORDER_DOUBLE_APPROVAL) + { + if (empty($this->user_approve_id2)) $movetoapprovestatus=false; // second level approval not done + } } else // request a second level approval { diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 27a33216865..9ca609c154c 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -117,6 +117,7 @@ else if (! empty($socid) && $socid > 0) } $permissionnote=$user->rights->fournisseur->commande->creer; // Used by the include of actions_setnotes.inc.php +$permissiondellink=$user->rights->fournisseur->commande->creer; // Used by the include of actions_dellink.inc.php $permissiontoedit=$user->rights->fournisseur->commande->creer; // Used by the include of actions_lineupdown.inc.php @@ -134,6 +135,8 @@ if (empty($reshook)) include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not include_once + include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once + include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; // Must be include, not include_once if ($action == 'setref_supplier' && $user->rights->fournisseur->commande->creer) @@ -2626,7 +2629,7 @@ elseif (! empty($object->id)) { if ($user->rights->fournisseur->commande->approuver) { - if (! empty($conf->global->SUPPLIER_ORDER_DOUBLE_APPROVAL) && ! empty($object->user_approve_id)) + if (! empty($conf->global->SUPPLIER_ORDER_DOUBLE_APPROVAL) && $conf->global->MAIN_FEATURES_LEVEL > 0 && $object->total_ht >= $conf->global->SUPPLIER_ORDER_DOUBLE_APPROVAL && ! empty($object->user_approve_id)) { print ''.$langs->trans("ApproveOrder").''; } @@ -2642,23 +2645,26 @@ elseif (! empty($object->id)) } // Second approval (if option SUPPLIER_ORDER_DOUBLE_APPROVAL is set) - if ($object->statut == 1) + if (! empty($conf->global->SUPPLIER_ORDER_DOUBLE_APPROVAL) && $conf->global->MAIN_FEATURES_LEVEL > 0 && $object->total_ht >= $conf->global->SUPPLIER_ORDER_DOUBLE_APPROVAL) { - if ($user->rights->fournisseur->commande->approve2) + if ($object->statut == 1) { - if (! empty($conf->global->SUPPLIER_ORDER_DOUBLE_APPROVAL) && ! empty($object->user_approve_id2)) + if ($user->rights->fournisseur->commande->approve2) { - print ''.$langs->trans("Approve2Order").''; + if (! empty($object->user_approve_id2)) + { + print ''.$langs->trans("Approve2Order").''; + } + else + { + print ''.$langs->trans("Approve2Order").''; + } } else { - print ''.$langs->trans("Approve2Order").''; + print ''.$langs->trans("Approve2Order").''; } } - else - { - print ''.$langs->trans("Approve2Order").''; - } } // Refuse diff --git a/htdocs/fourn/commande/tpl/linkedobjectblock.tpl.php b/htdocs/fourn/commande/tpl/linkedobjectblock.tpl.php index 0c2d5eed0af..cfcb5567bb6 100644 --- a/htdocs/fourn/commande/tpl/linkedobjectblock.tpl.php +++ b/htdocs/fourn/commande/tpl/linkedobjectblock.tpl.php @@ -37,35 +37,38 @@ print_titre($langs->trans('RelatedSupplierOrders')); trans("Date"); ?> trans("AmountHTShort"); ?> trans("Status"); ?> + $objectlink) { $var=!$var; ?> - > - trans("ShowOrder"),"order").' '.$object->ref; ?> - date,'day'); ?> + > + trans("ShowOrder"),"order").' '.$objectlink->ref; ?> + date,'day'); ?> rights->fournisseur->commande->lire) { - $total = $total + $object->total_ht; - echo price($object->total_ht); + $total = $total + $objectlink->total_ht; + echo price($objectlink->total_ht); } ?> - getLibStatut(3); ?> + getLibStatut(3); ?> + ">transnoentitiesnoconv("RemoveLink")); ?> - trans('TotalHT'); ?> + trans("TotalHT"); ?> rights->fournisseur->commande->lire) { echo price($total); } ?> -   + + diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index e74e9f8ee8d..38d11843714 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -87,6 +87,7 @@ if ($id > 0 || ! empty($ref)) } $permissionnote=$user->rights->fournisseur->facture->creer; // Used by the include of actions_setnotes.inc.php +$permissiondellink=$user->rights->fournisseur->facture->creer; // Used by the include of actions_dellink.inc.php $permissionedit=$user->rights->fournisseur->facture->creer; // Used by the include of actions_lineupdown.inc.php @@ -104,6 +105,8 @@ if (empty($reshook)) include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not include_once + include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once + include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; // Must be include, not include_once // Action clone object diff --git a/htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php b/htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php index 500e3ed50f3..8678d22384b 100644 --- a/htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php +++ b/htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php @@ -40,24 +40,26 @@ print_titre($langs->trans("RelatedSupplierInvoices")); trans("Date"); ?> trans("AmountHTShort"); ?> trans("Status"); ?> + $objectlink) { $var=!$var; ?> > - trans("ShowBill"),"bill").' '.$object->ref; ?> - ref_supplier; ?> - date,'day'); ?> + trans("ShowBill"),"bill").' '.$objectlink->ref; ?> + ref_supplier; ?> + date,'day'); ?> rights->fournisseur->facture->lire) { - $total = $total + $object->total_ht; - echo price($object->total_ht); + $total = $total + $objectlink->total_ht; + echo price($objectlink->total_ht); } ?> - getLibStatut(3); ?> + getLibStatut(3); ?> + ">transnoentitiesnoconv("RemoveLink")); ?> rights->fournisseur->facture->lire) { echo price($total); } ?> -   + + diff --git a/htdocs/includes/jquery/plugins/datatables/Contributing.md b/htdocs/includes/jquery/plugins/datatables/Contributing.md new file mode 100644 index 00000000000..17a8f1f10b1 --- /dev/null +++ b/htdocs/includes/jquery/plugins/datatables/Contributing.md @@ -0,0 +1,18 @@ +# Support requests + +Please direct support requests to the [DataTables forums](https://datatables.net/forums), ensuring that you provide a link to a test page that shows the problem and a full description of the issue. If you require urgent help, [priority support](https://datatables.net/support) is available. + + +# Contributing code + +If you are thinking of contributing code to DataTables, first of all, thank you! All fixes, patches and enhancements to DataTables are very warmly welcomed. In order to keep thing manageable, there are a number of guidelines that should be followed in order to ensure that your modification is included in DataTables as quickly as possible: + +1. Make contributions in the DataTables/DataTablesSrc repo. Changes to the built files in the built repo (DataTables/DataTables) will not be accepted since they would be overwritten by the next build! + +2. Follow the style of the code in the existing files. They might not be to everyone's tastes, but consistency is key for a mature project like DataTables. DataTables doesn't have a coding standards document, but simple common sense of following the same style as in the existing files is ideal. For example use tabs not spaces (as you will see all source files use tabs). + +3. Link to a test page showing the bug you are fixing or the feature you are adding. This allows to me to quickly identify what is being changed and why. Don't worry about being verbose in pull requests - its much better to know exactly what is changing and why! + +4. DataTables is a large and complex project and it isn't always possible or suitable to pull in every suggested change. Please don't be offended if a pull request is not merged in, it will explained why not if this is the case. Also it isn't always possible to fully check and test pull requests as quickly as I would like due to other commitments. Again this is no reflection on your pull request, just the busy life that we all lead! If you have any questions about your potential contribution and its place in the DataTables project structure, please ask ahead of time in the [DataTables forums](//datatables.net/forums). + +5. Pull requests will only be accepted if you acknowledge that your contribution is offered under and will be made available under the project's existing license (MIT). If your initial pull request doesn't explicitly acknowledge this I'll ask before it is pulled in. \ No newline at end of file diff --git a/htdocs/includes/jquery/plugins/datatables/Readme.md b/htdocs/includes/jquery/plugins/datatables/Readme.md new file mode 100644 index 00000000000..dd952d84ce8 --- /dev/null +++ b/htdocs/includes/jquery/plugins/datatables/Readme.md @@ -0,0 +1,53 @@ +# DataTables plug-in for jQuery + +DataTables is a table enhancing plug-in for the [jQuery](//jquery.com) Javascript library, adding sorting, paging and filtering abilities to plain HTML tables with minimal effort. The stated goal of DataTables is: + +> To enhance the accessibility of data in HTML tables. + +To meet this goal, DataTables is developed with two distinct groups of users in mind: + +* You the developers using DataTables. For developers DataTables provides a wide array of options for how data should be obtained, displayed and acted upon, along with an extensive API for accessing and manipulating the table. + +* End users. For those using the interface DataTables presents, actions to get the most from the information contained in tables, such as sorting and filtering, along with paging and scrolling of the data in table, are easy to use, intuitive and fast. + + +## Installation + +In most cases, to use DataTables all you need to do is include jQuery, the DataTables Javascript and DataTables CSS files in your HTML page. See the [DataTables manual](http://datatables.net/manual/installation#Including-Javascript-/-CSS) for details on how to do this using the latest version of DataTables. + + +## Usage + +In its simplest case, DataTables can be initialised with a single line of Javascript: + +```js +$('table').dataTable(); +``` + +where the jQuery selector is used to obtain a reference to the table you want to enhance with DataTables. Optional configuration parameters can be passed in to DataTables to have it perform certain actions by using a configuration object as the parameter passed in to the DataTables constructor. For example: + +```js +$('table').dataTable( { + paginate: false, + scrollY: 300 +} ); +``` + +will disable paging and enable scrolling. + +A full list of the options available for DataTables are available in the [documentation](//datatables.net). + + +## Documentation + +Full documentation of the DataTables options, API and pug-in interface are available on the [DataTables web-site](//datatables.net). The site also contains information on the wide variety of plug-ins that are available for DataTables, which can be used to enhance and customise your table even further. + + +## Support + +Support for DataTables is available through the [DataTables forums](//datatables.net/forums) and [commercial support options](//datatables.net/support) are available. + + +## License + +DataTables is release under the [MIT license](//datatables.net/license). You are free to use, modify and distribute this software, as long as the copyright header is left intact (specifically the comment block which starts with `/*!`. diff --git a/htdocs/includes/jquery/plugins/datatables/Readme.txt b/htdocs/includes/jquery/plugins/datatables/Readme.txt deleted file mode 100644 index 96a47cbde67..00000000000 --- a/htdocs/includes/jquery/plugins/datatables/Readme.txt +++ /dev/null @@ -1,11 +0,0 @@ -This DataTables plugin (v1.9.x) for jQuery was developed out of the desire to allow highly configurable access to HTML tables with advanced access features. - -For detailed installation, usage and API instructions, please refer to the DataTables web-pages: http://www.datatables.net - -Questions, feature requests and bug reports (etc) can all be asked on the DataTables forums: http://www.datatables.net/forums/ - -The DataTables source can be found in the media/js/ directory of this archive. - -DataTables is released with dual licensing, using the GPL v2 (license-gpl2.txt) and an BSD style license (license-bsd.txt). You may select which of the two licenses you wish to use DataTables under. Please see the corresponding license file for details of these licenses. You are free to use, modify and distribute this software, but all copyright information must remain. - -If you discover any bugs in DataTables, have any suggestions for improvements or even if you just like using it, please free to get in touch with me: www.datatables.net/contact \ No newline at end of file diff --git a/htdocs/includes/jquery/plugins/datatables/css/jquery.dataTables.css b/htdocs/includes/jquery/plugins/datatables/css/jquery.dataTables.css deleted file mode 100644 index b257b33bee5..00000000000 --- a/htdocs/includes/jquery/plugins/datatables/css/jquery.dataTables.css +++ /dev/null @@ -1,221 +0,0 @@ - -/* - * Table - */ -table.dataTable { - margin: 0 auto; - clear: both; - width: 100%; -} - -table.dataTable thead th { - padding: 3px 18px 3px 10px; - border-bottom: 1px solid black; - font-weight: bold; - cursor: pointer; - *cursor: hand; -} - -table.dataTable tfoot th { - padding: 3px 18px 3px 10px; - border-top: 1px solid black; - font-weight: bold; -} - -table.dataTable td { - padding: 3px 10px; -} - -table.dataTable td.center, -table.dataTable td.dataTables_empty { - text-align: center; -} - -table.dataTable tr.odd { background-color: #E2E4FF; } -table.dataTable tr.even { background-color: white; } - -table.dataTable tr.odd td.sorting_1 { background-color: #D3D6FF; } -table.dataTable tr.odd td.sorting_2 { background-color: #DADCFF; } -table.dataTable tr.odd td.sorting_3 { background-color: #E0E2FF; } -table.dataTable tr.even td.sorting_1 { background-color: #EAEBFF; } -table.dataTable tr.even td.sorting_2 { background-color: #F2F3FF; } -table.dataTable tr.even td.sorting_3 { background-color: #F9F9FF; } - - -/* - * Table wrapper - */ -.dataTables_wrapper { - position: relative; - clear: both; - *zoom: 1; -} - - -/* - * Page length menu - */ -.dataTables_length { - float: left; -} - - -/* - * Filter - */ -.dataTables_filter { - float: right; - text-align: right; -} - - -/* - * Table information - */ -.dataTables_info { - clear: both; - float: left; -} - - -/* - * Pagination - */ -.dataTables_paginate { - float: right; - text-align: right; -} - -/* Two button pagination - previous / next */ -.paginate_disabled_previous, -.paginate_enabled_previous, -.paginate_disabled_next, -.paginate_enabled_next { - height: 19px; - float: left; - cursor: pointer; - *cursor: hand; - color: #111 !important; -} -.paginate_disabled_previous:hover, -.paginate_enabled_previous:hover, -.paginate_disabled_next:hover, -.paginate_enabled_next:hover { - text-decoration: none !important; -} -.paginate_disabled_previous:active, -.paginate_enabled_previous:active, -.paginate_disabled_next:active, -.paginate_enabled_next:active { - outline: none; -} - -.paginate_disabled_previous, -.paginate_disabled_next { - color: #666 !important; -} -.paginate_disabled_previous, -.paginate_enabled_previous { - padding-left: 23px; -} -.paginate_disabled_next, -.paginate_enabled_next { - padding-right: 23px; - margin-left: 10px; -} - -.paginate_enabled_previous { background: url('../images/back_enabled.png') no-repeat top left; } -.paginate_enabled_previous:hover { background: url('../images/back_enabled_hover.png') no-repeat top left; } -.paginate_disabled_previous { background: url('../images/back_disabled.png') no-repeat top left; } - -.paginate_enabled_next { background: url('../images/forward_enabled.png') no-repeat top right; } -.paginate_enabled_next:hover { background: url('../images/forward_enabled_hover.png') no-repeat top right; } -.paginate_disabled_next { background: url('../images/forward_disabled.png') no-repeat top right; } - -/* Full number pagination */ -.paging_full_numbers { - height: 22px; - line-height: 22px; -} -.paging_full_numbers a:active { - outline: none -} -.paging_full_numbers a:hover { - text-decoration: none; -} - -.paging_full_numbers a.paginate_button, -.paging_full_numbers a.paginate_active { - border: 1px solid #aaa; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; - padding: 2px 5px; - margin: 0 3px; - cursor: pointer; - *cursor: hand; - /* DOL_LDR CHANGE color: #333 !important; */ -} - -.paging_full_numbers a.paginate_button { - background-color: #ddd; -} - -.paging_full_numbers a.paginate_button:hover { - background-color: #ccc; - text-decoration: none !important; -} - -.paging_full_numbers a.paginate_active { - background-color: #99B3FF; -} - - -/* - * Processing indicator - */ -.dataTables_processing { - position: absolute; - top: 50%; - left: 50%; - width: 250px; - height: 30px; - margin-left: -125px; - margin-top: -15px; - padding: 14px 0 2px 0; - border: 1px solid #ddd; - text-align: center; - color: #999; - font-size: 14px; - background-color: white; -} - - -/* - * Sorting - */ -.sorting { background: url('../images/sort_both.png') no-repeat center right; } -.sorting_asc { background: url('../images/sort_asc.png') no-repeat center right; } -.sorting_desc { background: url('../images/sort_desc.png') no-repeat center right; } - -.sorting_asc_disabled { background: url('../images/sort_asc_disabled.png') no-repeat center right; } -.sorting_desc_disabled { background: url('../images/sort_desc_disabled.png') no-repeat center right; } - -table.dataTable thead th:active, -table.dataTable thead td:active { - outline: none; -} - - -/* - * Scrolling - */ -.dataTables_scroll { - clear: both; -} - -.dataTables_scrollBody { - *margin-top: -1px; - -webkit-overflow-scrolling: touch; -} - diff --git a/htdocs/includes/jquery/plugins/datatables/css/jquery.dataTables_jui.css b/htdocs/includes/jquery/plugins/datatables/css/jquery.dataTables_jui.css deleted file mode 100644 index a210af51ae9..00000000000 --- a/htdocs/includes/jquery/plugins/datatables/css/jquery.dataTables_jui.css +++ /dev/null @@ -1,501 +0,0 @@ -/* - * File: demo_table_jui.css - * CVS: $Id$ - * Description: CSS descriptions for DataTables demo pages - * Author: Allan Jardine - * Created: Tue May 12 06:47:22 BST 2009 - * Modified: $Date$ by $Author$ - * Language: CSS - * Project: DataTables - * - * Copyright 2009 Allan Jardine. All Rights Reserved. - * - * *************************************************************************** - * DESCRIPTION - * - * The styles given here are suitable for the demos that are used with the standard DataTables - * distribution (see www.datatables.net). You will most likely wish to modify these styles to - * meet the layout requirements of your site. - * - * Common issues: - * 'full_numbers' pagination - I use an extra selector on the body tag to ensure that there is - * no conflict between the two pagination types. If you want to use full_numbers pagination - * ensure that you either have "example_alt_pagination" as a body class name, or better yet, - * modify that selector. - * Note that the path used for Images is relative. All images are by default located in - * ../images/ - relative to this CSS file. - */ - - -/* - * jQuery UI specific styling - */ - -.paging_two_button .ui-button { - float: left; - cursor: pointer; - * cursor: hand; -} - -.paging_full_numbers .ui-button { - padding: 2px 6px; - margin: 0; - cursor: pointer; - * cursor: hand; - color: #333 !important; -} - -.dataTables_paginate .ui-button { - margin-right: -0.1em !important; -} - -.paging_full_numbers { - width: 350px !important; -} - -.dataTables_wrapper .ui-toolbar { - padding: 5px; -} - -.dataTables_paginate { - width: auto; -} - -.dataTables_info { - padding-top: 3px; -} - -table.display thead th { - padding: 3px 0px 3px 10px; - cursor: pointer; - * cursor: hand; -} - -div.dataTables_wrapper .ui-widget-header { - font-weight: normal; -} - - -/* - * Sort arrow icon positioning - */ -table.display thead th div.DataTables_sort_wrapper { - position: relative; - padding-right: 20px; -} - -table.display thead th div.DataTables_sort_wrapper span { - position: absolute; - top: 50%; - margin-top: -8px; - right: 0; -} - - - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * - * Everything below this line is the same as demo_table.css. This file is - * required for 'cleanliness' of the markup - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * DataTables features - */ - -.dataTables_wrapper { - position: relative; - clear: both; -} - -.dataTables_processing { - position: absolute; - top: 0px; - left: 50%; - width: 250px; - margin-left: -125px; - border: 1px solid #ddd; - text-align: center; - color: #999; - font-size: 11px; - padding: 2px 0; -} - -.dataTables_length { - width: 40%; - float: left; -} - -.dataTables_filter { - width: 50%; - float: right; - text-align: right; -} - -.dataTables_info { - width: 50%; - float: left; -} - -.dataTables_paginate { - float: right; - text-align: right; -} - - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * DataTables display - */ -table.display { - margin: 0 auto; - width: 100%; - clear: both; - border-collapse: collapse; -} - -table.display tfoot th { - padding: 3px 0px 3px 10px; - font-weight: bold; - font-weight: normal; -} - -table.display tr.heading2 td { - border-bottom: 1px solid #aaa; -} - -table.display td { - padding: 3px 10px; -} - -table.display td.center { - text-align: center; -} - - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * DataTables sorting - */ - -.sorting_asc { - background: url('../images/sort_asc.png') no-repeat center right; -} - -.sorting_desc { - background: url('../images/sort_desc.png') no-repeat center right; -} - -.sorting { - background: url('../images/sort_both.png') no-repeat center right; -} - -.sorting_asc_disabled { - background: url('../images/sort_asc_disabled.png') no-repeat center right; -} - -.sorting_desc_disabled { - background: url('../images/sort_desc_disabled.png') no-repeat center right; -} - - - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * DataTables row classes - */ -table.display tr.odd.gradeA { - background-color: #ddffdd; -} - -table.display tr.even.gradeA { - background-color: #eeffee; -} - - - - -table.display tr.odd.gradeA { - background-color: #ddffdd; -} - -table.display tr.even.gradeA { - background-color: #eeffee; -} - -table.display tr.odd.gradeC { - background-color: #ddddff; -} - -table.display tr.even.gradeC { - background-color: #eeeeff; -} - -table.display tr.odd.gradeX { - background-color: #ffdddd; -} - -table.display tr.even.gradeX { - background-color: #ffeeee; -} - -table.display tr.odd.gradeU { - background-color: #ddd; -} - -table.display tr.even.gradeU { - background-color: #eee; -} - - -tr.odd { - background-color: #E2E4FF; -} - -tr.even { - background-color: white; -} - - - - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Misc - */ -.dataTables_scroll { - clear: both; -} - -.dataTables_scrollBody { - -webkit-overflow-scrolling: touch; -} - -.top, .bottom { - padding: 15px; - background-color: #F5F5F5; - border: 1px solid #CCCCCC; -} - -.top .dataTables_info { - float: none; -} - -.clear { - clear: both; -} - -.dataTables_empty { - text-align: center; -} - -tfoot input { - margin: 0.5em 0; - width: 100%; - color: #444; -} - -tfoot input.search_init { - color: #999; -} - -td.group { - background-color: #d1cfd0; - border-bottom: 2px solid #A19B9E; - border-top: 2px solid #A19B9E; -} - -td.details { - background-color: #d1cfd0; - border: 2px solid #A19B9E; -} - - -.example_alt_pagination div.dataTables_info { - width: 40%; -} - -.paging_full_numbers a.paginate_button, - .paging_full_numbers a.paginate_active { - border: 1px solid #aaa; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - padding: 2px 5px; - margin: 0 3px; - cursor: pointer; - *cursor: hand; - color: #333 !important; -} - -.paging_full_numbers a.paginate_button { - background-color: #ddd; -} - -.paging_full_numbers a.paginate_button:hover { - background-color: #ccc; - text-decoration: none !important; -} - -.paging_full_numbers a.paginate_active { - background-color: #99B3FF; -} - -table.display tr.even.row_selected td { - background-color: #B0BED9; -} - -table.display tr.odd.row_selected td { - background-color: #9FAFD1; -} - - -/* - * Sorting classes for columns - */ -/* For the standard odd/even */ -tr.odd td.sorting_1 { - background-color: #D3D6FF; -} - -tr.odd td.sorting_2 { - background-color: #DADCFF; -} - -tr.odd td.sorting_3 { - background-color: #E0E2FF; -} - -tr.even td.sorting_1 { - background-color: #EAEBFF; -} - -tr.even td.sorting_2 { - background-color: #F2F3FF; -} - -tr.even td.sorting_3 { - background-color: #F9F9FF; -} - - -/* For the Conditional-CSS grading rows */ -/* - Colour calculations (based off the main row colours) - Level 1: - dd > c4 - ee > d5 - Level 2: - dd > d1 - ee > e2 - */ -tr.odd.gradeA td.sorting_1 { - background-color: #c4ffc4; -} - -tr.odd.gradeA td.sorting_2 { - background-color: #d1ffd1; -} - -tr.odd.gradeA td.sorting_3 { - background-color: #d1ffd1; -} - -tr.even.gradeA td.sorting_1 { - background-color: #d5ffd5; -} - -tr.even.gradeA td.sorting_2 { - background-color: #e2ffe2; -} - -tr.even.gradeA td.sorting_3 { - background-color: #e2ffe2; -} - -tr.odd.gradeC td.sorting_1 { - background-color: #c4c4ff; -} - -tr.odd.gradeC td.sorting_2 { - background-color: #d1d1ff; -} - -tr.odd.gradeC td.sorting_3 { - background-color: #d1d1ff; -} - -tr.even.gradeC td.sorting_1 { - background-color: #d5d5ff; -} - -tr.even.gradeC td.sorting_2 { - background-color: #e2e2ff; -} - -tr.even.gradeC td.sorting_3 { - background-color: #e2e2ff; -} - -tr.odd.gradeX td.sorting_1 { - background-color: #ffc4c4; -} - -tr.odd.gradeX td.sorting_2 { - background-color: #ffd1d1; -} - -tr.odd.gradeX td.sorting_3 { - background-color: #ffd1d1; -} - -tr.even.gradeX td.sorting_1 { - background-color: #ffd5d5; -} - -tr.even.gradeX td.sorting_2 { - background-color: #ffe2e2; -} - -tr.even.gradeX td.sorting_3 { - background-color: #ffe2e2; -} - -tr.odd.gradeU td.sorting_1 { - background-color: #c4c4c4; -} - -tr.odd.gradeU td.sorting_2 { - background-color: #d1d1d1; -} - -tr.odd.gradeU td.sorting_3 { - background-color: #d1d1d1; -} - -tr.even.gradeU td.sorting_1 { - background-color: #d5d5d5; -} - -tr.even.gradeU td.sorting_2 { - background-color: #e2e2e2; -} - -tr.even.gradeU td.sorting_3 { - background-color: #e2e2e2; -} - - -/* - * Row highlighting example - */ -.ex_highlight #example tbody tr.even:hover, #example tbody tr.even td.highlighted { - background-color: #ECFFB3; -} - -.ex_highlight #example tbody tr.odd:hover, #example tbody tr.odd td.highlighted { - background-color: #E6FF99; -} \ No newline at end of file diff --git a/htdocs/includes/jquery/plugins/datatables/extensions/AutoFill/Readme.txt b/htdocs/includes/jquery/plugins/datatables/extensions/AutoFill/Readme.txt new file mode 100644 index 00000000000..017d1d0d5f1 --- /dev/null +++ b/htdocs/includes/jquery/plugins/datatables/extensions/AutoFill/Readme.txt @@ -0,0 +1,38 @@ +# AutoFill + +AutoFill gives an Excel like option to a DataTable to click and drag over multiple cells, filling in information over the selected cells and incrementing numbers as needed. Key features include: + +* Click and drag cell content insertion +* Automatic incrementing of numeric information +* Enable and disable on any column +* Detailed callback functions for customisation +* Support for both DataTables and browser window scrolling + + +# Installation + +To use AutoFill, first download DataTables ( http://datatables.net/download ) and place the unzipped AutoFill package into a `extensions` directory in the DataTables package. This will allow the pages in the examples to operate correctly. To see the examples running, open the `examples` directory in your web-browser. + + +# Basic usage + +AutoFill is initialised using the `$.fn.dataTable.AutoFill` constructor. For example: + +```js +$(document).ready( function () { + var table = $('#example').dataTable(); + new $.fn.dataTable.AutoFill( table ); +} ); +``` + + +# Documentation / support + +* Documentation: http://datatables.net/extensions/autofill/ +* DataTables support forums: http://datatables.net/forums + + +# GitHub + +If you fancy getting involved with the development of AutoFill and help make it better, please refer to its GitHub repo: https://github.com/DataTables/AutoFill + diff --git a/htdocs/includes/jquery/plugins/datatables/extensions/AutoFill/css/dataTables.autoFill.css b/htdocs/includes/jquery/plugins/datatables/extensions/AutoFill/css/dataTables.autoFill.css new file mode 100644 index 00000000000..cab59b3a059 --- /dev/null +++ b/htdocs/includes/jquery/plugins/datatables/extensions/AutoFill/css/dataTables.autoFill.css @@ -0,0 +1,24 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * AutoFill styles + */ + +div.AutoFill_filler { + display: none; + position: absolute; + height: 14px; + width: 14px; + background: url(../images/filler.png) no-repeat center center; + z-index: 1002; +} + +div.AutoFill_border { + display: none; + position: absolute; + background-color: #0063dc; + z-index: 1001; + + box-shadow: 0px 0px 5px #76b4ff; + -moz-box-shadow: 0px 0px 5px #76b4ff; + -webkit-box-shadow: 0px 0px 5px #76b4ff; +} + diff --git a/htdocs/includes/jquery/plugins/datatables/extensions/AutoFill/css/dataTables.autoFill.min.css b/htdocs/includes/jquery/plugins/datatables/extensions/AutoFill/css/dataTables.autoFill.min.css new file mode 100644 index 00000000000..b485f2163fc --- /dev/null +++ b/htdocs/includes/jquery/plugins/datatables/extensions/AutoFill/css/dataTables.autoFill.min.css @@ -0,0 +1 @@ +div.AutoFill_filler{display:none;position:absolute;height:14px;width:14px;background:url(../images/filler.png) no-repeat center center;z-index:1002}div.AutoFill_border{display:none;position:absolute;background-color:#0063dc;z-index:1001;box-shadow:0px 0px 5px #76b4ff;-moz-box-shadow:0px 0px 5px #76b4ff;-webkit-box-shadow:0px 0px 5px #76b4ff} diff --git a/htdocs/includes/jquery/plugins/datatables/extensions/AutoFill/images/filler.png b/htdocs/includes/jquery/plugins/datatables/extensions/AutoFill/images/filler.png new file mode 100644 index 00000000000..f2af65d8c38 Binary files /dev/null and b/htdocs/includes/jquery/plugins/datatables/extensions/AutoFill/images/filler.png differ diff --git a/htdocs/includes/jquery/plugins/datatables/extensions/AutoFill/js/dataTables.autoFill.js b/htdocs/includes/jquery/plugins/datatables/extensions/AutoFill/js/dataTables.autoFill.js new file mode 100755 index 00000000000..6bbfa35b937 --- /dev/null +++ b/htdocs/includes/jquery/plugins/datatables/extensions/AutoFill/js/dataTables.autoFill.js @@ -0,0 +1,855 @@ +/*! AutoFill 1.2.1 + * ©2008-2014 SpryMedia Ltd - datatables.net/license + */ + +/** + * @summary AutoFill + * @description Add Excel like click and drag auto-fill options to DataTables + * @version 1.2.1 + * @file dataTables.autoFill.js + * @author SpryMedia Ltd (www.sprymedia.co.uk) + * @contact www.sprymedia.co.uk/contact + * @copyright Copyright 2010-2014 SpryMedia Ltd. + * + * This source file is free software, available under the following license: + * MIT license - http://datatables.net/license/mit + * + * This source file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. + * + * For details please refer to: http://www.datatables.net + */ + +(function( window, document, undefined ) { + +var factory = function( $, DataTable ) { +"use strict"; + +/** + * AutoFill provides Excel like auto-fill features for a DataTable + * + * @class AutoFill + * @constructor + * @param {object} oTD DataTables settings object + * @param {object} oConfig Configuration object for AutoFill + */ +var AutoFill = function( oDT, oConfig ) +{ + /* Sanity check that we are a new instance */ + if ( ! (this instanceof AutoFill) ) { + throw( "Warning: AutoFill must be initialised with the keyword 'new'" ); + } + + if ( ! $.fn.dataTableExt.fnVersionCheck('1.7.0') ) { + throw( "Warning: AutoFill requires DataTables 1.7 or greater"); + } + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Public class variables + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + this.c = {}; + + /** + * @namespace Settings object which contains customisable information for AutoFill instance + */ + this.s = { + /** + * @namespace Cached information about the little dragging icon (the filler) + */ + "filler": { + "height": 0, + "width": 0 + }, + + /** + * @namespace Cached information about the border display + */ + "border": { + "width": 2 + }, + + /** + * @namespace Store for live information for the current drag + */ + "drag": { + "startX": -1, + "startY": -1, + "startTd": null, + "endTd": null, + "dragging": false + }, + + /** + * @namespace Data cache for information that we need for scrolling the screen when we near + * the edges + */ + "screen": { + "interval": null, + "y": 0, + "height": 0, + "scrollTop": 0 + }, + + /** + * @namespace Data cache for the position of the DataTables scrolling element (when scrolling + * is enabled) + */ + "scroller": { + "top": 0, + "bottom": 0 + }, + + /** + * @namespace Information stored for each column. An array of objects + */ + "columns": [] + }; + + + /** + * @namespace Common and useful DOM elements for the class instance + */ + this.dom = { + "table": null, + "filler": null, + "borderTop": null, + "borderRight": null, + "borderBottom": null, + "borderLeft": null, + "currentTarget": null + }; + + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Public class methods + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /** + * Retreieve the settings object from an instance + * @method fnSettings + * @returns {object} AutoFill settings object + */ + this.fnSettings = function () { + return this.s; + }; + + + /* Constructor logic */ + this._fnInit( oDT, oConfig ); + return this; +}; + + + +AutoFill.prototype = { + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Private methods (they are of course public in JS, but recommended as private) + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /** + * Initialisation + * @method _fnInit + * @param {object} dt DataTables settings object + * @param {object} config Configuration object for AutoFill + * @returns void + */ + "_fnInit": function ( dt, config ) + { + var + that = this, + i, iLen; + + // Use DataTables API to get the settings allowing selectors, instances + // etc to be used, or for backwards compatibility get from the old + // fnSettings method + this.s.dt = DataTable.Api ? + new DataTable.Api( dt ).settings()[0] : + dt.fnSettings(); + this.s.init = config || {}; + this.dom.table = this.s.dt.nTable; + + $.extend( true, this.c, AutoFill.defaults, config ); + + /* Add and configure the columns */ + this._initColumns(); + + /* Auto Fill click and drag icon */ + var filler = $('
', { + 'class': 'AutoFill_filler' + } ) + .appendTo( 'body' ); + this.dom.filler = filler[0]; + + // Get the height / width of the click element + this.s.filler.height = filler.height(); + this.s.filler.width = filler.width(); + filler[0].style.display = "none"; + + /* Border display - one div for each side. We can't just use a single + * one with a border, as we want the events to effectively pass through + * the transparent bit of the box + */ + var border; + var appender = document.body; + if ( that.s.dt.oScroll.sY !== "" ) { + that.s.dt.nTable.parentNode.style.position = "relative"; + appender = that.s.dt.nTable.parentNode; + } + + border = $('
', { + "class": "AutoFill_border" + } ); + this.dom.borderTop = border.clone().appendTo( appender )[0]; + this.dom.borderRight = border.clone().appendTo( appender )[0]; + this.dom.borderBottom = border.clone().appendTo( appender )[0]; + this.dom.borderLeft = border.clone().appendTo( appender )[0]; + + /* Events */ + filler.on( 'mousedown.DTAF', function (e) { + this.onselectstart = function() { return false; }; + that._fnFillerDragStart.call( that, e ); + return false; + } ); + + $('tbody', this.dom.table).on( + 'mouseover.DTAF mouseout.DTAF', + '>tr>td, >tr>th', + function (e) { + that._fnFillerDisplay.call( that, e ); + } + ); + + $(this.dom.table).on( 'destroy.dt.DTAF', function () { + filler.off( 'mousedown.DTAF' ).remove(); + $('tbody', this.dom.table).off( 'mouseover.DTAF mouseout.DTAF' ); + } ); + }, + + + _initColumns: function ( ) + { + var that = this; + var i, ien; + var dt = this.s.dt; + var config = this.s.init; + + for ( i=0, ien=dt.aoColumns.length ; i offsetEnd.left) { + x1 = offsetEnd.left - border; + x2 = offsetStart.left + $(nStart).outerWidth(); + width = offsetStart.left + $(nStart).outerWidth() - offsetEnd.left + (2*border); + } + + if ( this.s.dt.oScroll.sY !== "" ) + { + /* The border elements are inside the DT scroller - so position relative to that */ + var + offsetScroll = $(this.s.dt.nTable.parentNode).offset(), + scrollTop = $(this.s.dt.nTable.parentNode).scrollTop(), + scrollLeft = $(this.s.dt.nTable.parentNode).scrollLeft(); + + x1 -= offsetScroll.left - scrollLeft; + x2 -= offsetScroll.left - scrollLeft; + y1 -= offsetScroll.top - scrollTop; + y2 -= offsetScroll.top - scrollTop; + } + + /* Top */ + oStyle = this.dom.borderTop.style; + oStyle.top = y1+"px"; + oStyle.left = x1+"px"; + oStyle.height = this.s.border.width+"px"; + oStyle.width = width+"px"; + + /* Bottom */ + oStyle = this.dom.borderBottom.style; + oStyle.top = y2+"px"; + oStyle.left = x1+"px"; + oStyle.height = this.s.border.width+"px"; + oStyle.width = width+"px"; + + /* Left */ + oStyle = this.dom.borderLeft.style; + oStyle.top = y1+"px"; + oStyle.left = x1+"px"; + oStyle.height = height+"px"; + oStyle.width = this.s.border.width+"px"; + + /* Right */ + oStyle = this.dom.borderRight.style; + oStyle.top = y1+"px"; + oStyle.left = x2+"px"; + oStyle.height = height+"px"; + oStyle.width = this.s.border.width+"px"; + }, + + + /** + * Mouse down event handler for starting a drag + * @method _fnFillerDragStart + * @param {Object} e Event object + * @returns void + */ + "_fnFillerDragStart": function (e) + { + var that = this; + var startingTd = this.dom.currentTarget; + + this.s.drag.dragging = true; + + that.dom.borderTop.style.display = "block"; + that.dom.borderRight.style.display = "block"; + that.dom.borderBottom.style.display = "block"; + that.dom.borderLeft.style.display = "block"; + + var coords = this._fnTargetCoords( startingTd ); + this.s.drag.startX = coords.x; + this.s.drag.startY = coords.y; + + this.s.drag.startTd = startingTd; + this.s.drag.endTd = startingTd; + + this._fnUpdateBorder( startingTd, startingTd ); + + $(document).bind('mousemove.AutoFill', function (e) { + that._fnFillerDragMove.call( that, e ); + } ); + + $(document).bind('mouseup.AutoFill', function (e) { + that._fnFillerFinish.call( that, e ); + } ); + + /* Scrolling information cache */ + this.s.screen.y = e.pageY; + this.s.screen.height = $(window).height(); + this.s.screen.scrollTop = $(document).scrollTop(); + + if ( this.s.dt.oScroll.sY !== "" ) + { + this.s.scroller.top = $(this.s.dt.nTable.parentNode).offset().top; + this.s.scroller.bottom = this.s.scroller.top + $(this.s.dt.nTable.parentNode).height(); + } + + /* Scrolling handler - we set an interval (which is cancelled on mouse up) which will fire + * regularly and see if we need to do any scrolling + */ + this.s.screen.interval = setInterval( function () { + var iScrollTop = $(document).scrollTop(); + var iScrollDelta = iScrollTop - that.s.screen.scrollTop; + that.s.screen.y += iScrollDelta; + + if ( that.s.screen.height - that.s.screen.y + iScrollTop < 50 ) + { + $('html, body').animate( { + "scrollTop": iScrollTop + 50 + }, 240, 'linear' ); + } + else if ( that.s.screen.y - iScrollTop < 50 ) + { + $('html, body').animate( { + "scrollTop": iScrollTop - 50 + }, 240, 'linear' ); + } + + if ( that.s.dt.oScroll.sY !== "" ) + { + if ( that.s.screen.y > that.s.scroller.bottom - 50 ) + { + $(that.s.dt.nTable.parentNode).animate( { + "scrollTop": $(that.s.dt.nTable.parentNode).scrollTop() + 50 + }, 240, 'linear' ); + } + else if ( that.s.screen.y < that.s.scroller.top + 50 ) + { + $(that.s.dt.nTable.parentNode).animate( { + "scrollTop": $(that.s.dt.nTable.parentNode).scrollTop() - 50 + }, 240, 'linear' ); + } + } + }, 250 ); + }, + + + /** + * Mouse move event handler for during a move. See if we want to update the display based on the + * new cursor position + * @method _fnFillerDragMove + * @param {Object} e Event object + * @returns void + */ + "_fnFillerDragMove": function (e) + { + if ( e.target && e.target.nodeName.toUpperCase() == "TD" && + e.target != this.s.drag.endTd ) + { + var coords = this._fnTargetCoords( e.target ); + + if ( this.c.mode == "y" && coords.x != this.s.drag.startX ) + { + e.target = $('tbody>tr:eq('+coords.y+')>td:eq('+this.s.drag.startX+')', this.dom.table)[0]; + } + if ( this.c.mode == "x" && coords.y != this.s.drag.startY ) + { + e.target = $('tbody>tr:eq('+this.s.drag.startY+')>td:eq('+coords.x+')', this.dom.table)[0]; + } + + if ( this.c.mode == "either") + { + if(coords.x != this.s.drag.startX ) + { + e.target = $('tbody>tr:eq('+this.s.drag.startY+')>td:eq('+coords.x+')', this.dom.table)[0]; + } + else if ( coords.y != this.s.drag.startY ) { + e.target = $('tbody>tr:eq('+coords.y+')>td:eq('+this.s.drag.startX+')', this.dom.table)[0]; + } + } + + // update coords + if ( this.c.mode !== "both" ) { + coords = this._fnTargetCoords( e.target ); + } + + var drag = this.s.drag; + drag.endTd = e.target; + + if ( coords.y >= this.s.drag.startY ) { + this._fnUpdateBorder( drag.startTd, drag.endTd ); + } + else { + this._fnUpdateBorder( drag.endTd, drag.startTd ); + } + this._fnFillerPosition( e.target ); + } + + /* Update the screen information so we can perform scrolling */ + this.s.screen.y = e.pageY; + this.s.screen.scrollTop = $(document).scrollTop(); + + if ( this.s.dt.oScroll.sY !== "" ) + { + this.s.scroller.scrollTop = $(this.s.dt.nTable.parentNode).scrollTop(); + this.s.scroller.top = $(this.s.dt.nTable.parentNode).offset().top; + this.s.scroller.bottom = this.s.scroller.top + $(this.s.dt.nTable.parentNode).height(); + } + }, + + + /** + * Mouse release handler - end the drag and take action to update the cells with the needed values + * @method _fnFillerFinish + * @param {Object} e Event object + * @returns void + */ + "_fnFillerFinish": function (e) + { + var that = this, i, iLen, j; + + $(document).unbind('mousemove.AutoFill mouseup.AutoFill'); + + this.dom.borderTop.style.display = "none"; + this.dom.borderRight.style.display = "none"; + this.dom.borderBottom.style.display = "none"; + this.dom.borderLeft.style.display = "none"; + + this.s.drag.dragging = false; + + clearInterval( this.s.screen.interval ); + + var cells = []; + var table = this.dom.table; + var coordsStart = this._fnTargetCoords( this.s.drag.startTd ); + var coordsEnd = this._fnTargetCoords( this.s.drag.endTd ); + var columnIndex = function ( visIdx ) { + return that.s.dt.oApi._fnVisibleToColumnIndex( that.s.dt, visIdx ); + }; + + // xxx - urgh - there must be a way of reducing this... + if ( coordsStart.y <= coordsEnd.y ) { + for ( i=coordsStart.y ; i<=coordsEnd.y ; i++ ) { + if ( coordsStart.x <= coordsEnd.x ) { + for ( j=coordsStart.x ; j<=coordsEnd.x ; j++ ) { + cells.push( { + node: $('tbody>tr:eq('+i+')>td:eq('+j+')', table)[0], + x: j - coordsStart.x, + y: i - coordsStart.y, + colIdx: columnIndex( j ) + } ); + } + } + else { + for ( j=coordsStart.x ; j>=coordsEnd.x ; j-- ) { + cells.push( { + node: $('tbody>tr:eq('+i+')>td:eq('+j+')', table)[0], + x: j - coordsStart.x, + y: i - coordsStart.y, + colIdx: columnIndex( j ) + } ); + } + } + } + } + else { + for ( i=coordsStart.y ; i>=coordsEnd.y ; i-- ) { + if ( coordsStart.x <= coordsEnd.x ) { + for ( j=coordsStart.x ; j<=coordsEnd.x ; j++ ) { + cells.push( { + node: $('tbody>tr:eq('+i+')>td:eq('+j+')', table)[0], + x: j - coordsStart.x, + y: i - coordsStart.y, + colIdx: columnIndex( j ) + } ); + } + } + else { + for ( j=coordsStart.x ; j>=coordsEnd.x ; j-- ) { + cells.push( { + node: $('tbody>tr:eq('+i+')>td:eq('+j+')', table)[0], + x: coordsStart.x - j, + y: coordsStart.y - i, + colIdx: columnIndex( j ) + } ); + } + } + } + } + + // An auto-fill requires 2 or more cells + if ( cells.length <= 1 ) { + return; + } + + var edited = []; + var previous; + + for ( i=0, iLen=cells.length ; i",{"class":"AutoFill_filler"}).appendTo("body");this.dom.filler=e[0];this.s.filler.height=e.height();this.s.filler.width=e.width();e[0].style.display= +"none";var g,f=j.body;""!==a.s.dt.oScroll.sY&&(a.s.dt.nTable.parentNode.style.position="relative",f=a.s.dt.nTable.parentNode);g=c("
",{"class":"AutoFill_border"});this.dom.borderTop=g.clone().appendTo(f)[0];this.dom.borderRight=g.clone().appendTo(f)[0];this.dom.borderBottom=g.clone().appendTo(f)[0];this.dom.borderLeft=g.clone().appendTo(f)[0];e.on("mousedown.DTAF",function(b){this.onselectstart=function(){return false};a._fnFillerDragStart.call(a,b);return false});c("tbody",this.dom.table).on("mouseover.DTAF mouseout.DTAF", +">tr>td, >tr>th",function(b){a._fnFillerDisplay.call(a,b)});c(this.dom.table).on("destroy.dt.DTAF",function(){e.off("mousedown.DTAF").remove();c("tbody",this.dom.table).off("mouseover.DTAF mouseout.DTAF")})},_initColumns:function(){var d=this,b,a,e=this.s.dt,g=this.s.init;b=0;for(a=e.aoColumns.length;bg.left&&(f=g.left-a,i=e.left+c(d).outerWidth(),j=e.left+c(d).outerWidth()-g.left+2*a);""!==this.s.dt.oScroll.sY&&(a=c(this.s.dt.nTable.parentNode).offset(),e=c(this.s.dt.nTable.parentNode).scrollTop(), +g=c(this.s.dt.nTable.parentNode).scrollLeft(),f-=a.left-g,i-=a.left-g,n-=a.top-e,h-=a.top-e);a=this.dom.borderTop.style;a.top=n+"px";a.left=f+"px";a.height=this.s.border.width+"px";a.width=j+"px";a=this.dom.borderBottom.style;a.top=h+"px";a.left=f+"px";a.height=this.s.border.width+"px";a.width=j+"px";a=this.dom.borderLeft.style;a.top=n+"px";a.left=f+"px";a.height=k+"px";a.width=this.s.border.width+"px";a=this.dom.borderRight.style;a.top=n+"px";a.left=i+"px";a.height=k+"px";a.width=this.s.border.width+ +"px"},_fnFillerDragStart:function(d){var b=this,a=this.dom.currentTarget;this.s.drag.dragging=!0;b.dom.borderTop.style.display="block";b.dom.borderRight.style.display="block";b.dom.borderBottom.style.display="block";b.dom.borderLeft.style.display="block";var e=this._fnTargetCoords(a);this.s.drag.startX=e.x;this.s.drag.startY=e.y;this.s.drag.startTd=a;this.s.drag.endTd=a;this._fnUpdateBorder(a,a);c(j).bind("mousemove.AutoFill",function(a){b._fnFillerDragMove.call(b,a)});c(j).bind("mouseup.AutoFill", +function(a){b._fnFillerFinish.call(b,a)});this.s.screen.y=d.pageY;this.s.screen.height=c(o).height();this.s.screen.scrollTop=c(j).scrollTop();""!==this.s.dt.oScroll.sY&&(this.s.scroller.top=c(this.s.dt.nTable.parentNode).offset().top,this.s.scroller.bottom=this.s.scroller.top+c(this.s.dt.nTable.parentNode).height());this.s.screen.interval=setInterval(function(){var a=c(j).scrollTop();b.s.screen.y=b.s.screen.y+(a-b.s.screen.scrollTop);b.s.screen.height-b.s.screen.y+a<50?c("html, body").animate({scrollTop:a+ +50},240,"linear"):b.s.screen.y-a<50&&c("html, body").animate({scrollTop:a-50},240,"linear");b.s.dt.oScroll.sY!==""&&(b.s.screen.y>b.s.scroller.bottom-50?c(b.s.dt.nTable.parentNode).animate({scrollTop:c(b.s.dt.nTable.parentNode).scrollTop()+50},240,"linear"):b.s.screen.ytr:eq("+b.y+")>td:eq("+this.s.drag.startX+")",this.dom.table)[0]);"x"==this.c.mode&&b.y!=this.s.drag.startY&&(d.target=c("tbody>tr:eq("+this.s.drag.startY+")>td:eq("+b.x+")",this.dom.table)[0]);"either"==this.c.mode&&(b.x!=this.s.drag.startX?d.target=c("tbody>tr:eq("+this.s.drag.startY+")>td:eq("+b.x+")",this.dom.table)[0]:b.y!=this.s.drag.startY&&(d.target=c("tbody>tr:eq("+b.y+")>td:eq("+this.s.drag.startX+ +")",this.dom.table)[0]));"both"!==this.c.mode&&(b=this._fnTargetCoords(d.target));var a=this.s.drag;a.endTd=d.target;b.y>=this.s.drag.startY?this._fnUpdateBorder(a.startTd,a.endTd):this._fnUpdateBorder(a.endTd,a.startTd);this._fnFillerPosition(d.target)}this.s.screen.y=d.pageY;this.s.screen.scrollTop=c(j).scrollTop();""!==this.s.dt.oScroll.sY&&(this.s.scroller.scrollTop=c(this.s.dt.nTable.parentNode).scrollTop(),this.s.scroller.top=c(this.s.dt.nTable.parentNode).offset().top,this.s.scroller.bottom= +this.s.scroller.top+c(this.s.dt.nTable.parentNode).height())},_fnFillerFinish:function(){var d=this,b,a;c(j).unbind("mousemove.AutoFill mouseup.AutoFill");this.dom.borderTop.style.display="none";this.dom.borderRight.style.display="none";this.dom.borderBottom.style.display="none";this.dom.borderLeft.style.display="none";this.s.drag.dragging=!1;clearInterval(this.s.screen.interval);var e=[],g=this.dom.table,f=this._fnTargetCoords(this.s.drag.startTd),i=this._fnTargetCoords(this.s.drag.endTd),h=function(a){return d.s.dt.oApi._fnVisibleToColumnIndex(d.s.dt, +a)};if(f.y<=i.y)for(b=f.y;b<=i.y;b++)if(f.x<=i.x)for(a=f.x;a<=i.x;a++)e.push({node:c("tbody>tr:eq("+b+")>td:eq("+a+")",g)[0],x:a-f.x,y:b-f.y,colIdx:h(a)});else for(a=f.x;a>=i.x;a--)e.push({node:c("tbody>tr:eq("+b+")>td:eq("+a+")",g)[0],x:a-f.x,y:b-f.y,colIdx:h(a)});else for(b=f.y;b>=i.y;b--)if(f.x<=i.x)for(a=f.x;a<=i.x;a++)e.push({node:c("tbody>tr:eq("+b+")>td:eq("+a+")",g)[0],x:a-f.x,y:b-f.y,colIdx:h(a)});else for(a=f.x;a>=i.x;a--)e.push({node:c("tbody>tr:eq("+b+")>td:eq("+a+")",g)[0],x:f.x-a,y:f.y- +b,colIdx:h(a)});if(!(1>=e.length)){var g=[],m;b=0;for(a=e.length;bg||0>f?-1:1)):a===m?b:a}}};return h};"function"===typeof define&&define.amd? +define(["jquery","datatables"],l):"object"===typeof exports?l(require("jquery"),require("datatables")):jQuery&&!jQuery.fn.dataTable.AutoFill&&l(jQuery,jQuery.fn.dataTable)})(window,document); diff --git a/htdocs/includes/jquery/plugins/datatables/extensions/ColReorder/License.txt b/htdocs/includes/jquery/plugins/datatables/extensions/ColReorder/License.txt new file mode 100644 index 00000000000..9ade2f1b640 --- /dev/null +++ b/htdocs/includes/jquery/plugins/datatables/extensions/ColReorder/License.txt @@ -0,0 +1,20 @@ +Copyright (c) 2010-2015 SpryMedia Limited +http://datatables.net + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/htdocs/includes/jquery/plugins/datatables/extensions/ColReorder/Readme.md b/htdocs/includes/jquery/plugins/datatables/extensions/ColReorder/Readme.md new file mode 100644 index 00000000000..217dd60e2c8 --- /dev/null +++ b/htdocs/includes/jquery/plugins/datatables/extensions/ColReorder/Readme.md @@ -0,0 +1,39 @@ +# ColReorder + +ColReorder adds the ability for the end user to click and drag column headers to reorder a table as they see fit, to DataTables. Key features include: + +* Very easy integration with DataTables +* Tight integration with all other DataTables plug-ins +* The ability to exclude the first (or more) column from being movable +* Predefine a column order +* Save staving integration with DataTables + + +# Installation + +To use ColReorder, first download DataTables ( http://datatables.net/download ) and place the unzipped ColReorder package into a `extensions` directory in the DataTables package. This will allow the pages in the examples to operate correctly. To see the examples running, open the `examples` directory in your web-browser. + + +# Basic usage + +ColReorder is initialised using the `$.fn.dataTable.ColReorder` constructor. For example: + +```js +$(document).ready( function () { + $('#example').DataTable(); + + new $.fn.dataTable.ColReorder( table ); +} ); +``` + + +# Documentation / support + +* Documentation: http://datatables.net/extensions/colreorder/ +* DataTables support forums: http://datatables.net/forums + + +# GitHub + +If you fancy getting involved with the development of ColReorder and help make it better, please refer to its GitHub repo: https://github.com/DataTables/ColReorder + diff --git a/htdocs/includes/jquery/plugins/datatables/extras/ColReorder/css/ColReorder.css b/htdocs/includes/jquery/plugins/datatables/extensions/ColReorder/css/dataTables.colReorder.css similarity index 50% rename from htdocs/includes/jquery/plugins/datatables/extras/ColReorder/css/ColReorder.css rename to htdocs/includes/jquery/plugins/datatables/extensions/ColReorder/css/dataTables.colReorder.css index 9c597e34871..bdd6aa0b9ad 100644 --- a/htdocs/includes/jquery/plugins/datatables/extras/ColReorder/css/ColReorder.css +++ b/htdocs/includes/jquery/plugins/datatables/extensions/ColReorder/css/dataTables.colReorder.css @@ -3,7 +3,7 @@ */ table.DTCR_clonedTable { - background-color: white; + background-color: rgba(255, 255, 255, 0.7); z-index: 202; } @@ -11,11 +11,4 @@ div.DTCR_pointer { width: 1px; background-color: #0259C4; z-index: 201; -} - -body.alt div.DTCR_pointer { - margin-top: -15px; - margin-left: -9px; - width: 18px; - background: url('../images/insert.png') no-repeat top left; } \ No newline at end of file diff --git a/htdocs/includes/jquery/plugins/datatables/extensions/ColReorder/css/dataTables.colReorder.min.css b/htdocs/includes/jquery/plugins/datatables/extensions/ColReorder/css/dataTables.colReorder.min.css new file mode 100644 index 00000000000..77b230e0136 --- /dev/null +++ b/htdocs/includes/jquery/plugins/datatables/extensions/ColReorder/css/dataTables.colReorder.min.css @@ -0,0 +1 @@ +table.DTCR_clonedTable{background-color:rgba(255,255,255,0.7);z-index:202}div.DTCR_pointer{width:1px;background-color:#0259C4;z-index:201} diff --git a/htdocs/includes/jquery/plugins/datatables/extras/ColReorder/images/insert.png b/htdocs/includes/jquery/plugins/datatables/extensions/ColReorder/images/insert.png similarity index 100% rename from htdocs/includes/jquery/plugins/datatables/extras/ColReorder/images/insert.png rename to htdocs/includes/jquery/plugins/datatables/extensions/ColReorder/images/insert.png diff --git a/htdocs/includes/jquery/plugins/datatables/extensions/ColReorder/js/dataTables.colReorder.js b/htdocs/includes/jquery/plugins/datatables/extensions/ColReorder/js/dataTables.colReorder.js new file mode 100755 index 00000000000..c3b2f1e2adc --- /dev/null +++ b/htdocs/includes/jquery/plugins/datatables/extensions/ColReorder/js/dataTables.colReorder.js @@ -0,0 +1,1372 @@ +/*! ColReorder 1.1.3 + * ©2010-2014 SpryMedia Ltd - datatables.net/license + */ + +/** + * @summary ColReorder + * @description Provide the ability to reorder columns in a DataTable + * @version 1.1.3 + * @file dataTables.colReorder.js + * @author SpryMedia Ltd (www.sprymedia.co.uk) + * @contact www.sprymedia.co.uk/contact + * @copyright Copyright 2010-2014 SpryMedia Ltd. + * + * This source file is free software, available under the following license: + * MIT license - http://datatables.net/license/mit + * + * This source file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. + * + * For details please refer to: http://www.datatables.net + */ + +(function(window, document, undefined) { + + +/** + * Switch the key value pairing of an index array to be value key (i.e. the old value is now the + * key). For example consider [ 2, 0, 1 ] this would be returned as [ 1, 2, 0 ]. + * @method fnInvertKeyValues + * @param array aIn Array to switch around + * @returns array + */ +function fnInvertKeyValues( aIn ) +{ + var aRet=[]; + for ( var i=0, iLen=aIn.length ; i= iCols ) + { + this.oApi._fnLog( oSettings, 1, "ColReorder 'from' index is out of bounds: "+iFrom ); + return; + } + + if ( iTo < 0 || iTo >= iCols ) + { + this.oApi._fnLog( oSettings, 1, "ColReorder 'to' index is out of bounds: "+iTo ); + return; + } + + /* + * Calculate the new column array index, so we have a mapping between the old and new + */ + var aiMapping = []; + for ( i=0, iLen=iCols ; i this.s.fixed-1 && i < iLen - this.s.fixedRight ) + { + this._fnMouseListener( i, this.s.dt.aoColumns[i].nTh ); + } + + /* Mark the original column order for later reference */ + this.s.dt.aoColumns[i]._ColReorder_iOrigCol = i; + } + + /* State saving */ + this.s.dt.oApi._fnCallbackReg( this.s.dt, 'aoStateSaveParams', function (oS, oData) { + that._fnStateSave.call( that, oData ); + }, "ColReorder_State" ); + + /* An initial column order has been specified */ + var aiOrder = null; + if ( this.s.init.aiOrder ) + { + aiOrder = this.s.init.aiOrder.slice(); + } + + /* State loading, overrides the column order given */ + if ( this.s.dt.oLoadedState && typeof this.s.dt.oLoadedState.ColReorder != 'undefined' && + this.s.dt.oLoadedState.ColReorder.length == this.s.dt.aoColumns.length ) + { + aiOrder = this.s.dt.oLoadedState.ColReorder; + } + + /* If we have an order to apply - do so */ + if ( aiOrder ) + { + /* We might be called during or after the DataTables initialisation. If before, then we need + * to wait until the draw is done, if after, then do what we need to do right away + */ + if ( !that.s.dt._bInitComplete ) + { + var bDone = false; + this.s.dt.aoDrawCallback.push( { + "fn": function () { + if ( !that.s.dt._bInitComplete && !bDone ) + { + bDone = true; + var resort = fnInvertKeyValues( aiOrder ); + that._fnOrderColumns.call( that, resort ); + } + }, + "sName": "ColReorder_Pre" + } ); + } + else + { + var resort = fnInvertKeyValues( aiOrder ); + that._fnOrderColumns.call( that, resort ); + } + } + else { + this._fnSetColumnIndexes(); + } + }, + + + /** + * Set the column order from an array + * @method _fnOrderColumns + * @param array a An array of integers which dictate the column order that should be applied + * @returns void + * @private + */ + "_fnOrderColumns": function ( a ) + { + if ( a.length != this.s.dt.aoColumns.length ) + { + this.s.dt.oInstance.oApi._fnLog( this.s.dt, 1, "ColReorder - array reorder does not "+ + "match known number of columns. Skipping." ); + return; + } + + for ( var i=0, iLen=a.length ; i
') + .addClass( 'DTCR_pointer' ) + .css( { + position: 'absolute', + top: scrolling ? + $('div.dataTables_scroll', this.s.dt.nTableWrapper).offset().top : + $(this.s.dt.nTable).offset().top, + height : scrolling ? + $('div.dataTables_scroll', this.s.dt.nTableWrapper).height() : + $(this.s.dt.nTable).height() + } ) + .appendTo( 'body' ); + }, + + /** + * Clean up ColReorder memory references and event handlers + * @method _fnDestroy + * @returns void + * @private + */ + "_fnDestroy": function () + { + var i, iLen; + + for ( i=0, iLen=this.s.dt.aoDrawCallback.length ; ib||b>=n)this.oApi._fnLog(a,1,"ColReorder 'from' index is out of bounds: "+b);else if(0>e||e>=n)this.oApi._fnLog(a,1,"ColReorder 'to' index is out of bounds: "+e);else{f=[];c=0;for(g=n;cthis.s.fixed-1&&eMath.pow(Math.pow(a.pageX-this.s.mouse.startX,2)+Math.pow(a.pageY-this.s.mouse.startY,2),0.5))return;this._fnCreateDragNode()}this.dom.drag.css({left:a.pageX-this.s.mouse.offsetX,top:a.pageY-this.s.mouse.offsetY});for(var b=!1,e=this.s.mouse.toIndex,d=1,c=this.s.aoTargets.length;d
").addClass("DTCR_pointer").css({position:"absolute",top:a?d("div.dataTables_scroll",this.s.dt.nTableWrapper).offset().top:d(this.s.dt.nTable).offset().top,height:a?d("div.dataTables_scroll",this.s.dt.nTableWrapper).height(): +d(this.s.dt.nTable).height()}).appendTo("body")},_fnDestroy:function(){var a,b;a=0;for(b=this.s.dt.aoDrawCallback.length;a
')[0], +g=c.childNodes[0],f=c.childNodes[1];this.dom.grid.dt.parentNode.insertBefore(c,this.dom.grid.dt);c.appendChild(this.dom.grid.dt);this.dom.grid.wrapper=c;0b.clientWidth&&(c.x=!0);a.offsetHeight>b.clientHeight&&(c.y=!0);return c},_fnDraw:function(a){this._fnGridLayout();this._fnCloneLeft(a);this._fnCloneRight(a);null!==this.s.fnDrawCallback&&this.s.fnDrawCallback.call(this,this.dom.clone.left,this.dom.clone.right);d(this).trigger("draw.dtfc",{leftClone:this.dom.clone.left,rightClone:this.dom.clone.right})},_fnCloneRight:function(a){if(!(0>= +this.s.iRightColumns)){var b,c=[];for(b=this.s.iTableColumns-this.s.iRightColumns;b=this.s.iLeftColumns)){var b,c=[];for(b=0;bthead",a.header);k.empty();e=0;for(h=n.length;ethead",a.header)[0]);e=0;for(h=n.length;etbody>tr",f.dom.body).css("height","auto");null!==a.body&&(a.body.parentNode.removeChild(a.body),a.body=null);a.body=d(this.dom.body).clone(!0)[0];a.body.className+=" DTFC_Cloned";a.body.style.paddingBottom=l.oScroll.iBarWidth+"px";a.body.style.marginBottom=2*l.oScroll.iBarWidth+"px";null!==a.body.getAttribute("id")&&a.body.removeAttribute("id");d(">thead>tr",a.body).empty();d(">tfoot", +a.body).remove();var p=d("tbody",a.body)[0];d(p).empty();if(0thead>tr",a.body)[0];for(o=0;otbody>tr",f.dom.body).each(function(a){var b=this.cloneNode(false);b.removeAttribute("id");a=f.s.dt.aoData[f.s.dt.oFeatures.bServerSide===false?f.s.dt.aiDisplay[f.s.dt._iDisplayStart+ +a]:a].anCells||d(this).children("td, th");for(o=0;o0){m=d(a[j]).clone(true,true)[0];b.appendChild(m)}}p.appendChild(b)})}else d(">tbody>tr",f.dom.body).each(function(){m=this.cloneNode(true);m.className=m.className+" DTFC_NoData";d("td",m).html("");p.appendChild(m)});a.body.style.width="100%";a.body.style.margin="0";a.body.style.padding="0";l.oScroller!==t&&(h=l.oScroller.dom.force,b.forcer?b.forcer.style.height=h.style.height:(b.forcer=h.cloneNode(!0),b.liner.appendChild(b.forcer))); +b.liner.appendChild(a.body);this._fnEqualiseHeights("tbody",f.dom.body,a.body);if(null!==l.nTFoot){if(g){null!==a.footer&&a.footer.parentNode.removeChild(a.footer);a.footer=d(this.dom.footer).clone(!0,!0)[0];a.footer.className+=" DTFC_Cloned";a.footer.style.width="100%";b.foot.appendChild(a.footer);n=this._fnCopyLayout(l.aoFooter,c);b=d(">tfoot",a.footer);b.empty();e=0;for(h=n.length;etfoot",a.footer)[0]);e=0;for(h=n.length;ethead",a.header)[0]);d(b).each(function(a){j=c[a];this.style.width=f.s.aiInnerWidths[j]+"px"});null!==f.s.dt.nTFoot&&(b=l.oApi._fnGetUniqueThs(l,d(">tfoot",a.footer)[0]),d(b).each(function(a){j=c[a];this.style.width=f.s.aiInnerWidths[j]+"px"}))},_fnGetTrNodes:function(a){for(var b= +[],c=0,d=a.childNodes.length;c"+a+">tr:eq(0)",b).children(":first");a.outerHeight();a.height();for(var e=this._fnGetTrNodes(e),b=this._fnGetTrNodes(c),h=[],c=0,a=b.length;cg?f:g,"semiauto"==this.s.sHeightMatch&& +(e[c]._DTTC_iHeight=g),h.push(g);c=0;for(a=b.length;ctfoot', s.nTable).length > 0) ? true : false; + + /* Add the 'sides' that are fixed */ + if ( s.oSides.top ) + { + s.aoCache.push( that._fnCloneTable( "fixedHeader", "FixedHeader_Header", that._fnCloneThead ) ); + } + if ( s.oSides.bottom ) + { + s.aoCache.push( that._fnCloneTable( "fixedFooter", "FixedHeader_Footer", that._fnCloneTfoot ) ); + } + if ( s.oSides.left ) + { + s.aoCache.push( that._fnCloneTable( "fixedLeft", "FixedHeader_Left", that._fnCloneTLeft, s.oSides.left ) ); + } + if ( s.oSides.right ) + { + s.aoCache.push( that._fnCloneTable( "fixedRight", "FixedHeader_Right", that._fnCloneTRight, s.oSides.right ) ); + } + + /* Event listeners for window movement */ + FixedHeader.afnScroll.push( function () { + that._fnUpdatePositions.call(that); + } ); + + $(window).resize( function () { + FixedHeader.fnMeasure(); + that._fnUpdateClones.call(that); + that._fnUpdatePositions.call(that); + } ); + + $(s.nTable) + .on('column-reorder.dt', function () { + FixedHeader.fnMeasure(); + that._fnUpdateClones( true ); + that._fnUpdatePositions(); + } ) + .on('column-visibility.dt', function () { + FixedHeader.fnMeasure(); + that._fnUpdateClones( true ); + that._fnUpdatePositions(); + } ); + + /* Get things right to start with */ + FixedHeader.fnMeasure(); + that._fnUpdateClones(); + that._fnUpdatePositions(); + + s.bInitComplete = true; + }, + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Support functions + */ + + /* + * Function: fnInitSettings + * Purpose: Take the user's settings and copy them to our local store + * Returns: - + * Inputs: object:s - the local settings object + * object:oInit - the user's settings object + */ + fnInitSettings: function ( s, oInit ) + { + if ( oInit !== undefined ) + { + if ( oInit.top !== undefined ) { + s.oSides.top = oInit.top; + } + if ( oInit.bottom !== undefined ) { + s.oSides.bottom = oInit.bottom; + } + if ( typeof oInit.left == 'boolean' ) { + s.oSides.left = oInit.left ? 1 : 0; + } + else if ( oInit.left !== undefined ) { + s.oSides.left = oInit.left; + } + if ( typeof oInit.right == 'boolean' ) { + s.oSides.right = oInit.right ? 1 : 0; + } + else if ( oInit.right !== undefined ) { + s.oSides.right = oInit.right; + } + + if ( oInit.zTop !== undefined ) { + s.oZIndexes.top = oInit.zTop; + } + if ( oInit.zBottom !== undefined ) { + s.oZIndexes.bottom = oInit.zBottom; + } + if ( oInit.zLeft !== undefined ) { + s.oZIndexes.left = oInit.zLeft; + } + if ( oInit.zRight !== undefined ) { + s.oZIndexes.right = oInit.zRight; + } + + if ( oInit.offsetTop !== undefined ) { + s.oOffset.top = oInit.offsetTop; + } + if ( oInit.alwaysCloneTop !== undefined ) { + s.oCloneOnDraw.top = oInit.alwaysCloneTop; + } + if ( oInit.alwaysCloneBottom !== undefined ) { + s.oCloneOnDraw.bottom = oInit.alwaysCloneBottom; + } + if ( oInit.alwaysCloneLeft !== undefined ) { + s.oCloneOnDraw.left = oInit.alwaysCloneLeft; + } + if ( oInit.alwaysCloneRight !== undefined ) { + s.oCloneOnDraw.right = oInit.alwaysCloneRight; + } + } + }, + + /* + * Function: _fnCloneTable + * Purpose: Clone the table node and do basic initialisation + * Returns: - + * Inputs: - + */ + _fnCloneTable: function ( sType, sClass, fnClone, iCells ) + { + var s = this.fnGetSettings(); + var nCTable; + + /* We know that the table _MUST_ has a DIV wrapped around it, because this is simply how + * DataTables works. Therefore, we can set this to be relatively position (if it is not + * alreadu absolute, and use this as the base point for the cloned header + */ + if ( $(s.nTable.parentNode).css('position') != "absolute" ) + { + s.nTable.parentNode.style.position = "relative"; + } + + /* Just a shallow clone will do - we only want the table node */ + nCTable = s.nTable.cloneNode( false ); + nCTable.removeAttribute( 'id' ); + + var nDiv = document.createElement( 'div' ); + nDiv.style.position = "absolute"; + nDiv.style.top = "0px"; + nDiv.style.left = "0px"; + nDiv.className += " FixedHeader_Cloned "+sType+" "+sClass; + + /* Set the zIndexes */ + if ( sType == "fixedHeader" ) + { + nDiv.style.zIndex = s.oZIndexes.top; + } + if ( sType == "fixedFooter" ) + { + nDiv.style.zIndex = s.oZIndexes.bottom; + } + if ( sType == "fixedLeft" ) + { + nDiv.style.zIndex = s.oZIndexes.left; + } + else if ( sType == "fixedRight" ) + { + nDiv.style.zIndex = s.oZIndexes.right; + } + + /* remove margins since we are going to position it absolutely */ + nCTable.style.margin = "0"; + + /* Insert the newly cloned table into the DOM, on top of the "real" header */ + nDiv.appendChild( nCTable ); + document.body.appendChild( nDiv ); + + return { + "nNode": nCTable, + "nWrapper": nDiv, + "sType": sType, + "sPosition": "", + "sTop": "", + "sLeft": "", + "fnClone": fnClone, + "iCells": iCells + }; + }, + + /* + * Function: _fnMeasure + * Purpose: Get the current positioning of the table in the DOM + * Returns: - + * Inputs: - + */ + _fnMeasure: function () + { + var + s = this.fnGetSettings(), + m = s.oMes, + jqTable = $(s.nTable), + oOffset = jqTable.offset(), + iParentScrollTop = this._fnSumScroll( s.nTable.parentNode, 'scrollTop' ), + iParentScrollLeft = this._fnSumScroll( s.nTable.parentNode, 'scrollLeft' ); + + m.iTableWidth = jqTable.outerWidth(); + m.iTableHeight = jqTable.outerHeight(); + m.iTableLeft = oOffset.left + s.nTable.parentNode.scrollLeft; + m.iTableTop = oOffset.top + iParentScrollTop; + m.iTableRight = m.iTableLeft + m.iTableWidth; + m.iTableRight = FixedHeader.oDoc.iWidth - m.iTableLeft - m.iTableWidth; + m.iTableBottom = FixedHeader.oDoc.iHeight - m.iTableTop - m.iTableHeight; + }, + + /* + * Function: _fnSumScroll + * Purpose: Sum node parameters all the way to the top + * Returns: int: sum + * Inputs: node:n - node to consider + * string:side - scrollTop or scrollLeft + */ + _fnSumScroll: function ( n, side ) + { + var i = n[side]; + while ( n = n.parentNode ) + { + if ( n.nodeName == 'HTML' || n.nodeName == 'BODY' ) + { + break; + } + i = n[side]; + } + return i; + }, + + /* + * Function: _fnUpdatePositions + * Purpose: Loop over the fixed elements for this table and update their positions + * Returns: - + * Inputs: - + */ + _fnUpdatePositions: function () + { + var s = this.fnGetSettings(); + this._fnMeasure(); + + for ( var i=0, iLen=s.aoCache.length ; i oWin.iScrollTop + s.oOffset.top ) + { + /* Above the table */ + this._fnUpdateCache( oCache, 'sPosition', "absolute", 'position', nTable.style ); + this._fnUpdateCache( oCache, 'sTop', oMes.iTableTop+"px", 'top', nTable.style ); + this._fnUpdateCache( oCache, 'sLeft', oMes.iTableLeft+"px", 'left', nTable.style ); + } + else if ( oWin.iScrollTop + s.oOffset.top > oMes.iTableTop+iTbodyHeight ) + { + /* At the bottom of the table */ + this._fnUpdateCache( oCache, 'sPosition', "absolute", 'position', nTable.style ); + this._fnUpdateCache( oCache, 'sTop', (oMes.iTableTop+iTbodyHeight)+"px", 'top', nTable.style ); + this._fnUpdateCache( oCache, 'sLeft', oMes.iTableLeft+"px", 'left', nTable.style ); + } + else + { + /* In the middle of the table */ + this._fnUpdateCache( oCache, 'sPosition', 'fixed', 'position', nTable.style ); + this._fnUpdateCache( oCache, 'sTop', s.oOffset.top+"px", 'top', nTable.style ); + this._fnUpdateCache( oCache, 'sLeft', (oMes.iTableLeft-oWin.iScrollLeft)+"px", 'left', nTable.style ); + } + }, + + /* + * Function: _fnUpdateCache + * Purpose: Check the cache and update cache and value if needed + * Returns: - + * Inputs: object:oCache - local cache object + * string:sCache - cache property + * string:sSet - value to set + * string:sProperty - object property to set + * object:oObj - object to update + */ + _fnUpdateCache: function ( oCache, sCache, sSet, sProperty, oObj ) + { + if ( oCache[sCache] != sSet ) + { + oObj[sProperty] = sSet; + oCache[sCache] = sSet; + } + }, + + + + /** + * Copy the classes of all child nodes from one element to another. This implies + * that the two have identical structure - no error checking is performed to that + * fact. + * @param {element} source Node to copy classes from + * @param {element} dest Node to copy classes too + */ + _fnClassUpdate: function ( source, dest ) + { + var that = this; + + if ( source.nodeName.toUpperCase() === "TR" || source.nodeName.toUpperCase() === "TH" || + source.nodeName.toUpperCase() === "TD" || source.nodeName.toUpperCase() === "SPAN" ) + { + dest.className = source.className; + } + + $(source).children().each( function (i) { + that._fnClassUpdate( $(source).children()[i], $(dest).children()[i] ); + } ); + }, + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Cloning functions + */ + + /* + * Function: _fnCloneThead + * Purpose: Clone the thead element + * Returns: - + * Inputs: object:oCache - the cached values for this fixed element + */ + _fnCloneThead: function ( oCache ) + { + var s = this.fnGetSettings(); + var nTable = oCache.nNode; + + if ( s.bInitComplete && !s.oCloneOnDraw.top ) + { + this._fnClassUpdate( $('thead', s.nTable)[0], $('thead', nTable)[0] ); + return; + } + + /* Set the wrapper width to match that of the cloned table */ + var iDtWidth = $(s.nTable).outerWidth(); + oCache.nWrapper.style.width = iDtWidth+"px"; + nTable.style.width = iDtWidth+"px"; + + /* Remove any children the cloned table has */ + while ( nTable.childNodes.length > 0 ) + { + $('thead th', nTable).unbind( 'click' ); + nTable.removeChild( nTable.childNodes[0] ); + } + + /* Clone the DataTables header */ + var nThead = $('thead', s.nTable).clone(true)[0]; + nTable.appendChild( nThead ); + + /* Copy the widths across - apparently a clone isn't good enough for this */ + var a = []; + var b = []; + + $("thead>tr th", s.nTable).each( function (i) { + a.push( $(this).width() ); + } ); + + $("thead>tr td", s.nTable).each( function (i) { + b.push( $(this).width() ); + } ); + + $("thead>tr th", s.nTable).each( function (i) { + $("thead>tr th:eq("+i+")", nTable).width( a[i] ); + $(this).width( a[i] ); + } ); + + $("thead>tr td", s.nTable).each( function (i) { + $("thead>tr td:eq("+i+")", nTable).width( b[i] ); + $(this).width( b[i] ); + } ); + + // Stop DataTables 1.9 from putting a focus ring on the headers when + // clicked to sort + $('th.sorting, th.sorting_desc, th.sorting_asc', nTable).bind( 'click', function () { + this.blur(); + } ); + }, + + /* + * Function: _fnCloneTfoot + * Purpose: Clone the tfoot element + * Returns: - + * Inputs: object:oCache - the cached values for this fixed element + */ + _fnCloneTfoot: function ( oCache ) + { + var s = this.fnGetSettings(); + var nTable = oCache.nNode; + + /* Set the wrapper width to match that of the cloned table */ + oCache.nWrapper.style.width = $(s.nTable).outerWidth()+"px"; + + /* Remove any children the cloned table has */ + while ( nTable.childNodes.length > 0 ) + { + nTable.removeChild( nTable.childNodes[0] ); + } + + /* Clone the DataTables footer */ + var nTfoot = $('tfoot', s.nTable).clone(true)[0]; + nTable.appendChild( nTfoot ); + + /* Copy the widths across - apparently a clone isn't good enough for this */ + $("tfoot:eq(0)>tr th", s.nTable).each( function (i) { + $("tfoot:eq(0)>tr th:eq("+i+")", nTable).width( $(this).width() ); + } ); + + $("tfoot:eq(0)>tr td", s.nTable).each( function (i) { + $("tfoot:eq(0)>tr td:eq("+i+")", nTable).width( $(this).width() ); + } ); + }, + + /* + * Function: _fnCloneTLeft + * Purpose: Clone the left column(s) + * Returns: - + * Inputs: object:oCache - the cached values for this fixed element + */ + _fnCloneTLeft: function ( oCache ) + { + var s = this.fnGetSettings(); + var nTable = oCache.nNode; + var nBody = $('tbody', s.nTable)[0]; + + /* Remove any children the cloned table has */ + while ( nTable.childNodes.length > 0 ) + { + nTable.removeChild( nTable.childNodes[0] ); + } + + /* Is this the most efficient way to do this - it looks horrible... */ + nTable.appendChild( $("thead", s.nTable).clone(true)[0] ); + nTable.appendChild( $("tbody", s.nTable).clone(true)[0] ); + if ( s.bFooter ) + { + nTable.appendChild( $("tfoot", s.nTable).clone(true)[0] ); + } + + /* Remove unneeded cells */ + var sSelector = 'gt(' + (oCache.iCells - 1) + ')'; + $('thead tr', nTable).each( function (k) { + $('th:' + sSelector, this).remove(); + } ); + + $('tfoot tr', nTable).each( function (k) { + $('th:' + sSelector, this).remove(); + } ); + + $('tbody tr', nTable).each( function (k) { + $('td:' + sSelector, this).remove(); + } ); + + this.fnEqualiseHeights( 'thead', nBody.parentNode, nTable ); + this.fnEqualiseHeights( 'tbody', nBody.parentNode, nTable ); + this.fnEqualiseHeights( 'tfoot', nBody.parentNode, nTable ); + + var iWidth = 0; + for (var i = 0; i < oCache.iCells; i++) { + iWidth += $('thead tr th:eq(' + i + ')', s.nTable).outerWidth(); + } + nTable.style.width = iWidth+"px"; + oCache.nWrapper.style.width = iWidth+"px"; + }, + + /* + * Function: _fnCloneTRight + * Purpose: Clone the right most column(s) + * Returns: - + * Inputs: object:oCache - the cached values for this fixed element + */ + _fnCloneTRight: function ( oCache ) + { + var s = this.fnGetSettings(); + var nBody = $('tbody', s.nTable)[0]; + var nTable = oCache.nNode; + var iCols = $('tbody tr:eq(0) td', s.nTable).length; + + /* Remove any children the cloned table has */ + while ( nTable.childNodes.length > 0 ) + { + nTable.removeChild( nTable.childNodes[0] ); + } + + /* Is this the most efficient way to do this - it looks horrible... */ + nTable.appendChild( $("thead", s.nTable).clone(true)[0] ); + nTable.appendChild( $("tbody", s.nTable).clone(true)[0] ); + if ( s.bFooter ) + { + nTable.appendChild( $("tfoot", s.nTable).clone(true)[0] ); + } + $('thead tr th:lt('+(iCols-oCache.iCells)+')', nTable).remove(); + $('tfoot tr th:lt('+(iCols-oCache.iCells)+')', nTable).remove(); + + /* Remove unneeded cells */ + $('tbody tr', nTable).each( function (k) { + $('td:lt('+(iCols-oCache.iCells)+')', this).remove(); + } ); + + this.fnEqualiseHeights( 'thead', nBody.parentNode, nTable ); + this.fnEqualiseHeights( 'tbody', nBody.parentNode, nTable ); + this.fnEqualiseHeights( 'tfoot', nBody.parentNode, nTable ); + + var iWidth = 0; + for (var i = 0; i < oCache.iCells; i++) { + iWidth += $('thead tr th:eq('+(iCols-1-i)+')', s.nTable).outerWidth(); + } + nTable.style.width = iWidth+"px"; + oCache.nWrapper.style.width = iWidth+"px"; + }, + + + /** + * Equalise the heights of the rows in a given table node in a cross browser way. Note that this + * is more or less lifted as is from FixedColumns + * @method fnEqualiseHeights + * @returns void + * @param {string} parent Node type - thead, tbody or tfoot + * @param {element} original Original node to take the heights from + * @param {element} clone Copy the heights to + * @private + */ + "fnEqualiseHeights": function ( parent, original, clone ) + { + var that = this; + var originals = $(parent +' tr', original); + var height; + + $(parent+' tr', clone).each( function (k) { + height = originals.eq( k ).css('height'); + + // This is nasty :-(. IE has a sub-pixel error even when setting + // the height below (the Firefox fix) which causes the fixed column + // to go out of alignment. Need to add a pixel before the assignment + // Can this be feature detected? Not sure how... + if ( navigator.appName == 'Microsoft Internet Explorer' ) { + height = parseInt( height, 10 ) + 1; + } + + $(this).css( 'height', height ); + + // For Firefox to work, we need to also set the height of the + // original row, to the value that we read from it! Otherwise there + // is a sub-pixel rounding error + originals.eq( k ).css( 'height', height ); + } ); + } +}; + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Static properties and methods + * We use these for speed! This information is common to all instances of FixedHeader, so no + * point if having them calculated and stored for each different instance. + */ + +/* + * Variable: oWin + * Purpose: Store information about the window positioning + * Scope: FixedHeader + */ +FixedHeader.oWin = { + "iScrollTop": 0, + "iScrollRight": 0, + "iScrollBottom": 0, + "iScrollLeft": 0, + "iHeight": 0, + "iWidth": 0 +}; + +/* + * Variable: oDoc + * Purpose: Store information about the document size + * Scope: FixedHeader + */ +FixedHeader.oDoc = { + "iHeight": 0, + "iWidth": 0 +}; + +/* + * Variable: afnScroll + * Purpose: Array of functions that are to be used for the scrolling components + * Scope: FixedHeader + */ +FixedHeader.afnScroll = []; + +/* + * Function: fnMeasure + * Purpose: Update the measurements for the window and document + * Returns: - + * Inputs: - + */ +FixedHeader.fnMeasure = function () +{ + var + jqWin = $(window), + jqDoc = $(document), + oWin = FixedHeader.oWin, + oDoc = FixedHeader.oDoc; + + oDoc.iHeight = jqDoc.height(); + oDoc.iWidth = jqDoc.width(); + + oWin.iHeight = jqWin.height(); + oWin.iWidth = jqWin.width(); + oWin.iScrollTop = jqWin.scrollTop(); + oWin.iScrollLeft = jqWin.scrollLeft(); + oWin.iScrollRight = oDoc.iWidth - oWin.iScrollLeft - oWin.iWidth; + oWin.iScrollBottom = oDoc.iHeight - oWin.iScrollTop - oWin.iHeight; +}; + + +FixedHeader.version = "2.1.2"; + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Global processing + */ + +/* + * Just one 'scroll' event handler in FixedHeader, which calls the required components. This is + * done as an optimisation, to reduce calculation and proagation time + */ +$(window).scroll( function () { + FixedHeader.fnMeasure(); + + for ( var i=0, iLen=FixedHeader.afnScroll.length ; itfoot",c.nTable).length?!0:!1,c.oSides.top&&c.aoCache.push(d._fnCloneTable("fixedHeader","FixedHeader_Header",d._fnCloneThead)),c.oSides.bottom&&c.aoCache.push(d._fnCloneTable("fixedFooter","FixedHeader_Footer",d._fnCloneTfoot)),c.oSides.left&&c.aoCache.push(d._fnCloneTable("fixedLeft","FixedHeader_Left",d._fnCloneTLeft,c.oSides.left)), +c.oSides.right&&c.aoCache.push(d._fnCloneTable("fixedRight","FixedHeader_Right",d._fnCloneTRight,c.oSides.right)),FixedHeader.afnScroll.push(function(){d._fnUpdatePositions.call(d)}),e(j).resize(function(){FixedHeader.fnMeasure();d._fnUpdateClones.call(d);d._fnUpdatePositions.call(d)}),e(c.nTable).on("column-reorder.dt",function(){FixedHeader.fnMeasure();d._fnUpdateClones(!0);d._fnUpdatePositions()}).on("column-visibility.dt",function(){FixedHeader.fnMeasure();d._fnUpdateClones(!0);d._fnUpdatePositions()}), +FixedHeader.fnMeasure(),d._fnUpdateClones(),d._fnUpdatePositions(),c.bInitComplete=!0)},fnInitSettings:function(a,b){if(b!==h&&(b.top!==h&&(a.oSides.top=b.top),b.bottom!==h&&(a.oSides.bottom=b.bottom),"boolean"==typeof b.left?a.oSides.left=b.left?1:0:b.left!==h&&(a.oSides.left=b.left),"boolean"==typeof b.right?a.oSides.right=b.right?1:0:b.right!==h&&(a.oSides.right=b.right),b.zTop!==h&&(a.oZIndexes.top=b.zTop),b.zBottom!==h&&(a.oZIndexes.bottom=b.zBottom),b.zLeft!==h&&(a.oZIndexes.left=b.zLeft),b.zRight!== +h&&(a.oZIndexes.right=b.zRight),b.offsetTop!==h&&(a.oOffset.top=b.offsetTop),b.alwaysCloneTop!==h&&(a.oCloneOnDraw.top=b.alwaysCloneTop),b.alwaysCloneBottom!==h&&(a.oCloneOnDraw.bottom=b.alwaysCloneBottom),b.alwaysCloneLeft!==h&&(a.oCloneOnDraw.left=b.alwaysCloneLeft),b.alwaysCloneRight!==h))a.oCloneOnDraw.right=b.alwaysCloneRight},_fnCloneTable:function(a,b,c,d){var f=this.fnGetSettings(),g;"absolute"!=e(f.nTable.parentNode).css("position")&&(f.nTable.parentNode.style.position="relative");g=f.nTable.cloneNode(!1); +g.removeAttribute("id");var i=k.createElement("div");i.style.position="absolute";i.style.top="0px";i.style.left="0px";i.className+=" FixedHeader_Cloned "+a+" "+b;"fixedHeader"==a&&(i.style.zIndex=f.oZIndexes.top);"fixedFooter"==a&&(i.style.zIndex=f.oZIndexes.bottom);"fixedLeft"==a?i.style.zIndex=f.oZIndexes.left:"fixedRight"==a&&(i.style.zIndex=f.oZIndexes.right);g.style.margin="0";i.appendChild(g);k.body.appendChild(i);return{nNode:g,nWrapper:i,sType:a,sPosition:"",sTop:"",sLeft:"",fnClone:c,iCells:d}}, +_fnMeasure:function(){var a=this.fnGetSettings(),b=a.oMes,c=e(a.nTable),d=c.offset(),f=this._fnSumScroll(a.nTable.parentNode,"scrollTop");this._fnSumScroll(a.nTable.parentNode,"scrollLeft");b.iTableWidth=c.outerWidth();b.iTableHeight=c.outerHeight();b.iTableLeft=d.left+a.nTable.parentNode.scrollLeft;b.iTableTop=d.top+f;b.iTableRight=b.iTableLeft+b.iTableWidth;b.iTableRight=FixedHeader.oDoc.iWidth-b.iTableLeft-b.iTableWidth;b.iTableBottom=FixedHeader.oDoc.iHeight-b.iTableTop-b.iTableHeight},_fnSumScroll:function(a, +b){for(var c=a[b];(a=a.parentNode)&&!("HTML"==a.nodeName||"BODY"==a.nodeName);)c=a[b];return c},_fnUpdatePositions:function(){var a=this.fnGetSettings();this._fnMeasure();for(var b=0,c=a.aoCache.length;bd.iScrollTop+b.oOffset.top?(this._fnUpdateCache(a,"sPosition","absolute","position",e.style),this._fnUpdateCache(a,"sTop",c.iTableTop+"px","top",e.style),this._fnUpdateCache(a,"sLeft",c.iTableLeft+"px","left",e.style)):d.iScrollTop+b.oOffset.top>c.iTableTop+ +g?(this._fnUpdateCache(a,"sPosition","absolute","position",e.style),this._fnUpdateCache(a,"sTop",c.iTableTop+g+"px","top",e.style),this._fnUpdateCache(a,"sLeft",c.iTableLeft+"px","left",e.style)):(this._fnUpdateCache(a,"sPosition","fixed","position",e.style),this._fnUpdateCache(a,"sTop",b.oOffset.top+"px","top",e.style),this._fnUpdateCache(a,"sLeft",c.iTableLeft-d.iScrollLeft+"px","left",e.style))},_fnUpdateCache:function(a,b,c,d,e){a[b]!=c&&(e[d]=c,a[b]=c)},_fnClassUpdate:function(a,b){var c=this; +if("TR"===a.nodeName.toUpperCase()||"TH"===a.nodeName.toUpperCase()||"TD"===a.nodeName.toUpperCase()||"SPAN"===a.nodeName.toUpperCase())b.className=a.className;e(a).children().each(function(d){c._fnClassUpdate(e(a).children()[d],e(b).children()[d])})},_fnCloneThead:function(a){var b=this.fnGetSettings(),c=a.nNode;if(b.bInitComplete&&!b.oCloneOnDraw.top)this._fnClassUpdate(e("thead",b.nTable)[0],e("thead",c)[0]);else{var d=e(b.nTable).outerWidth();a.nWrapper.style.width=d+"px";for(c.style.width=d+ +"px";0tr th",b.nTable).each(function(){f.push(e(this).width())});e("thead>tr td",b.nTable).each(function(){g.push(e(this).width())});e("thead>tr th",b.nTable).each(function(a){e("thead>tr th:eq("+a+")",c).width(f[a]);e(this).width(f[a])});e("thead>tr td",b.nTable).each(function(a){e("thead>tr td:eq("+a+")",c).width(g[a]);e(this).width(g[a])}); +e("th.sorting, th.sorting_desc, th.sorting_asc",c).bind("click",function(){this.blur()})}},_fnCloneTfoot:function(a){var b=this.fnGetSettings(),c=a.nNode;for(a.nWrapper.style.width=e(b.nTable).outerWidth()+"px";0tr th",b.nTable).each(function(a){e("tfoot:eq(0)>tr th:eq("+a+")",c).width(e(this).width())});e("tfoot:eq(0)>tr td",b.nTable).each(function(a){e("tfoot:eq(0)>tr td:eq("+ +a+")",c).width(e(this).width())})},_fnCloneTLeft:function(a){for(var b=this.fnGetSettings(),c=a.nNode,d=e("tbody",b.nTable)[0];0= oSettings.fnDisplayEnd() ) + { + if ( oSettings._iDisplayLength >= 0 ) + { + /* Make sure we are not over running the display array */ + if ( oSettings._iDisplayStart + oSettings._iDisplayLength < oSettings.fnRecordsDisplay() ) + { + oSettings._iDisplayStart += oSettings._iDisplayLength; + } + } + else + { + oSettings._iDisplayStart = 0; + } + _oDatatable.oApi._fnCalculateEnd( oSettings ); + } + + /* Page backwards */ + while ( iRow < oSettings._iDisplayStart ) + { + oSettings._iDisplayStart = oSettings._iDisplayLength>=0 ? + oSettings._iDisplayStart - oSettings._iDisplayLength : + 0; + + if ( oSettings._iDisplayStart < 0 ) + { + oSettings._iDisplayStart = 0; + } + _oDatatable.oApi._fnCalculateEnd( oSettings ); + } + + /* Re-draw the table */ + _oDatatable.oApi._fnDraw( oSettings ); + + /* Restore the key capture */ + _bKeyCapture = bKeyCaptureCache; + } + + /* Cache the information that we are interested in */ + var aNewPos = _fnCoordsFromCell( nTarget ); + _nOldFocus = nTarget; + _iOldX = aNewPos[0]; + _iOldY = aNewPos[1]; + + var iViewportHeight, iViewportWidth, iScrollTop, iScrollLeft, iHeight, iWidth, aiPos; + if ( bAutoScroll ) + { + /* Scroll the viewport such that the new cell is fully visible in the rendered window */ + iViewportHeight = $(window).height(); + iViewportWidth = $(window).width(); + iScrollTop = $(document).scrollTop(); + iScrollLeft = $(document).scrollLeft(); + iHeight = nTarget.offsetHeight; + iWidth = nTarget.offsetWidth; + aiPos = _fnGetPos( nTarget ); + + /* Take account of scrolling in DataTables 1.7 - remove scrolling since that would add to + * the positioning calculation + */ + if ( _oDatatable && typeof oSettings.oScroll != 'undefined' && + (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") ) + { + aiPos[1] -= $(oSettings.nTable.parentNode).scrollTop(); + aiPos[0] -= $(oSettings.nTable.parentNode).scrollLeft(); + } + + /* Correct viewport positioning for vertical scrolling */ + if ( aiPos[1]+iHeight > iScrollTop+iViewportHeight ) + { + /* Displayed element if off the bottom of the viewport */ + _fnSetScrollTop( aiPos[1]+iHeight - iViewportHeight ); + } + else if ( aiPos[1] < iScrollTop ) + { + /* Displayed element if off the top of the viewport */ + _fnSetScrollTop( aiPos[1] ); + } + + /* Correct viewport positioning for horizontal scrolling */ + if ( aiPos[0]+iWidth > iScrollLeft+iViewportWidth ) + { + /* Displayed element is off the bottom of the viewport */ + _fnSetScrollLeft( aiPos[0]+iWidth - iViewportWidth ); + } + else if ( aiPos[0] < iScrollLeft ) + { + /* Displayed element if off the Left of the viewport */ + _fnSetScrollLeft( aiPos[0] ); + } + } + + /* Take account of scrolling in DataTables 1.7 */ + if ( _oDatatable && typeof oSettings.oScroll != 'undefined' && + (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") ) + { + var dtScrollBody = oSettings.nTable.parentNode; + iViewportHeight = dtScrollBody.clientHeight; + iViewportWidth = dtScrollBody.clientWidth; + iScrollTop = dtScrollBody.scrollTop; + iScrollLeft = dtScrollBody.scrollLeft; + iHeight = nTarget.offsetHeight; + iWidth = nTarget.offsetWidth; + + /* Correct for vertical scrolling */ + if ( nTarget.offsetTop + iHeight > iViewportHeight+iScrollTop ) + { + dtScrollBody.scrollTop = (nTarget.offsetTop + iHeight) - iViewportHeight; + } + else if ( nTarget.offsetTop < iScrollTop ) + { + dtScrollBody.scrollTop = nTarget.offsetTop; + } + + /* Correct for horizontal scrolling */ + if ( nTarget.offsetLeft + iWidth > iViewportWidth+iScrollLeft ) + { + dtScrollBody.scrollLeft = (nTarget.offsetLeft + iWidth) - iViewportWidth; + } + else if ( nTarget.offsetLeft < iScrollLeft ) + { + dtScrollBody.scrollLeft = nTarget.offsetLeft; + } + } + + /* Focused - so we want to capture the keys */ + _fnCaptureKeys(); + + /* Fire of the focus event if there is one */ + _fnEventFire( "focus", _iOldX, _iOldY ); + } + + + /* + * Function: _fnBlur + * Purpose: Blur focus from the whole table + * Returns: - + * Inputs: - + */ + function _fnBlur() + { + _fnRemoveFocus( _nOldFocus ); + _iOldX = null; + _iOldY = null; + _nOldFocus = null; + _fnReleaseKeys(); + } + + + /* + * Function: _fnRemoveFocus + * Purpose: Remove focus from a cell and fire any blur events which are attached + * Returns: - + * Inputs: node:nTarget - cell of interest + */ + function _fnRemoveFocus( nTarget ) + { + $(nTarget).removeClass( _sFocusClass ); + $(nTarget).parent().removeClass( _sFocusClass ); + _fnEventFire( "blur", _iOldX, _iOldY ); + } + + + /* + * Function: _fnClick + * Purpose: Focus on the element that has been clicked on by the user + * Returns: - + * Inputs: event:e - click event + */ + function _fnClick ( e ) + { + var nTarget = this; + while ( nTarget.nodeName != "TD" ) + { + nTarget = nTarget.parentNode; + } + + _fnSetFocus( nTarget ); + _fnCaptureKeys(); + } + + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Key events + */ + + /* + * Function: _fnKey + * Purpose: Deal with a key events, be it moving the focus or return etc. + * Returns: bool: - allow browser default action + * Inputs: event:e - key event + */ + function _fnKey ( e ) + { + /* If user or system has blocked KeyTable from doing anything, just ignore this event */ + if ( _that.block || !_bKeyCapture ) + { + return true; + } + + /* If a modifier key is pressed (exapct shift), ignore the event */ + if ( e.metaKey || e.altKey || e.ctrlKey ) + { + return true; + } + var + x, y, + iTableWidth = _nBody.getElementsByTagName('tr')[0].getElementsByTagName('td').length, + iTableHeight; + + /* Get table height and width - done here so as to be dynamic (if table is updated) */ + if ( _oDatatable ) + { + /* + * Locate the current node in the DataTable overriding the old positions - the reason for + * is is that there might have been some DataTables interaction between the last focus and + * now + */ + iTableHeight = _oDatatable.aiDisplay.length; + + var aDtPos = _fnFindDtCell( _nOldFocus ); + if ( aDtPos === null ) + { + /* If the table has been updated such that the focused cell can't be seen - do nothing */ + return; + } + _iOldX = aDtPos[ 0 ]; + _iOldY = aDtPos[ 1 ]; + } + else + { + iTableHeight = _nBody.getElementsByTagName('tr').length; + } + + /* Capture shift+tab to match the left arrow key */ + var iKey = (e.keyCode == 9 && e.shiftKey) ? -1 : e.keyCode; + + switch( iKey ) + { + case 13: /* return */ + e.preventDefault(); + e.stopPropagation(); + _fnEventFire( "action", _iOldX, _iOldY ); + return true; + + case 27: /* esc */ + if ( !_fnEventFire( "esc", _iOldX, _iOldY ) ) + { + /* Only lose focus if there isn't an escape handler on the cell */ + _fnBlur(); + return; + } + x = _iOldX; + y = _iOldY; + break; + + case -1: + case 37: /* left arrow */ + if ( _iOldX > 0 ) { + x = _iOldX - 1; + y = _iOldY; + } else if ( _iOldY > 0 ) { + x = iTableWidth-1; + y = _iOldY - 1; + } else { + /* at start of table */ + if ( iKey == -1 && _bForm ) + { + /* If we are in a form, return focus to the 'input' element such that tabbing will + * follow correctly in the browser + */ + _bInputFocused = true; + _nInput.focus(); + + /* This timeout is a little nasty - but IE appears to have some asyhnc behaviour for + * focus + */ + setTimeout( function(){ _bInputFocused = false; }, 0 ); + _bKeyCapture = false; + _fnBlur(); + return true; + } + else + { + return false; + } + } + break; + + case 38: /* up arrow */ + if ( _iOldY > 0 ) { + x = _iOldX; + y = _iOldY - 1; + } else { + return false; + } + break; + + case 36: /* home */ + x = _iOldX; + y = 0; + break; + + case 33: /* page up */ + x = _iOldX; + y = _iOldY - 10; + if (y < 0) { + y = 0; + } + break; + + case 9: /* tab */ + case 39: /* right arrow */ + if ( _iOldX < iTableWidth-1 ) { + x = _iOldX + 1; + y = _iOldY; + } else if ( _iOldY < iTableHeight-1 ) { + x = 0; + y = _iOldY + 1; + } else { + /* at end of table */ + if ( iKey == 9 && _bForm ) + { + /* If we are in a form, return focus to the 'input' element such that tabbing will + * follow correctly in the browser + */ + _bInputFocused = true; + _nInput.focus(); + + /* This timeout is a little nasty - but IE appears to have some asyhnc behaviour for + * focus + */ + setTimeout( function(){ _bInputFocused = false; }, 0 ); + _bKeyCapture = false; + _fnBlur(); + return true; + } + else + { + return false; + } + } + break; + + case 40: /* down arrow */ + if ( _iOldY < iTableHeight-1 ) { + x = _iOldX; + y = _iOldY + 1; + } else { + return false; + } + break; + + case 35: /* end */ + x = _iOldX; + y = iTableHeight-1; + break; + + case 34: /* page down */ + x = _iOldX; + y = _iOldY+10; + if (y > iTableHeight-1) { + y = iTableHeight-1; + } + break; + + default: /* Nothing we are interested in */ + return true; + } + + _fnSetFocus( _fnCellFromCoords(x, y) ); + return false; + } + + + /* + * Function: _fnCaptureKeys + * Purpose: Start capturing key events for this table + * Returns: - + * Inputs: - + */ + function _fnCaptureKeys( ) + { + if ( !_bKeyCapture ) + { + _bKeyCapture = true; + } + } + + + /* + * Function: _fnReleaseKeys + * Purpose: Stop capturing key events for this table + * Returns: - + * Inputs: - + */ + function _fnReleaseKeys( ) + { + _bKeyCapture = false; + } + + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Support functions + */ + + /* + * Function: _fnCellFromCoords + * Purpose: Calulate the target TD cell from x and y coordinates + * Returns: node: - TD target + * Inputs: int:x - x coordinate + * int:y - y coordinate + */ + function _fnCellFromCoords( x, y ) + { + if ( _oDatatable ) + { + if ( typeof _oDatatable.aoData[ _oDatatable.aiDisplay[ y ] ] != 'undefined' ) + { + return _oDatatable.aoData[ _oDatatable.aiDisplay[ y ] ].nTr.getElementsByTagName('td')[x]; + } + else + { + return null; + } + } + else + { + return $('tr:eq('+y+')>td:eq('+x+')', _nBody )[0]; + } + } + + + /* + * Function: _fnCoordsFromCell + * Purpose: Calculate the x and y position in a table from a TD cell + * Returns: array[2] int: [x, y] + * Inputs: node:n - TD cell of interest + * Notes: Not actually interested in this for DataTables since it might go out of date + */ + function _fnCoordsFromCell( n ) + { + if ( _oDatatable ) + { + return [ + $('td', n.parentNode).index(n), + $('tr', n.parentNode.parentNode).index(n.parentNode) + _oDatatable._iDisplayStart + ]; + } + else + { + return [ + $('td', n.parentNode).index(n), + $('tr', n.parentNode.parentNode).index(n.parentNode) + ]; + } + } + + + /* + * Function: _fnSetScrollTop + * Purpose: Set the vertical scrolling position + * Returns: - + * Inputs: int:iPos - scrolltop + * Notes: This is so nasty, but without browser detection you can't tell which you should set + * So on browsers that support both, the scroll top will be set twice. I can live with + * that :-) + */ + function _fnSetScrollTop( iPos ) + { + document.documentElement.scrollTop = iPos; + document.body.scrollTop = iPos; + } + + + /* + * Function: _fnSetScrollLeft + * Purpose: Set the horizontal scrolling position + * Returns: - + * Inputs: int:iPos - scrollleft + */ + function _fnSetScrollLeft( iPos ) + { + document.documentElement.scrollLeft = iPos; + document.body.scrollLeft = iPos; + } + + + /* + * Function: _fnGetPos + * Purpose: Get the position of an object on the rendered page + * Returns: array[2] int: [left, right] + * Inputs: node:obj - element of interest + */ + function _fnGetPos ( obj ) + { + var iLeft = 0; + var iTop = 0; + + if (obj.offsetParent) + { + iLeft = obj.offsetLeft; + iTop = obj.offsetTop; + obj = obj.offsetParent; + while (obj) + { + iLeft += obj.offsetLeft; + iTop += obj.offsetTop; + obj = obj.offsetParent; + } + } + return [iLeft,iTop]; + } + + + /* + * Function: _fnFindDtCell + * Purpose: Get the coords. of a cell from the DataTables internal information + * Returns: array[2] int: [x, y] coords. or null if not found + * Inputs: node:nTarget - the node of interest + */ + function _fnFindDtCell( nTarget ) + { + for ( var i=0, iLen=_oDatatable.aiDisplay.length ; i
for filtering data. - * - * - * Note that as of v1.9, it is typically preferable to use mData to prepare data for - * the different uses that DataTables can put the data to. Specifically mData when - * used as a function will give you a 'type' (sorting, filtering etc) that you can use to - * prepare the data as required for the different types. As such, this method is deprecated. - * @type object - * @default {} - * @deprecated - * - * @example - * $.fn.dataTableExt.ofnSearch['title-numeric'] = function ( sData ) { - * return sData.replace(/\n/g," ").replace( /<.*?>/g, "" ); - * } - */ - "ofnSearch": {}, - - - /** - * Container for all private functions in DataTables so they can be exposed externally - * @type object - * @default {} - */ - "oApi": {}, - - - /** - * Storage for the various classes that DataTables uses - * @type object - * @default {} - */ - "oStdClasses": {}, - - - /** - * Storage for the various classes that DataTables uses - jQuery UI suitable - * @type object - * @default {} - */ - "oJUIClasses": {}, - - - /** - * Pagination plug-in methods - The style and controls of the pagination can significantly - * impact on how the end user interacts with the data in your table, and DataTables allows - * the addition of pagination controls by extending this object, which can then be enabled - * through the sPaginationType initialisation parameter. Each pagination type that - * is added is an object (the property name of which is what sPaginationType refers - * to) that has two properties, both methods that are used by DataTables to update the - * control's state. - * - * @type object - * @default {} - * - * @example - * $.fn.dataTableExt.oPagination.four_button = { - * "fnInit": function ( oSettings, nPaging, fnCallbackDraw ) { - * nFirst = document.createElement( 'span' ); - * nPrevious = document.createElement( 'span' ); - * nNext = document.createElement( 'span' ); - * nLast = document.createElement( 'span' ); - * - * nFirst.appendChild( document.createTextNode( oSettings.oLanguage.oPaginate.sFirst ) ); - * nPrevious.appendChild( document.createTextNode( oSettings.oLanguage.oPaginate.sPrevious ) ); - * nNext.appendChild( document.createTextNode( oSettings.oLanguage.oPaginate.sNext ) ); - * nLast.appendChild( document.createTextNode( oSettings.oLanguage.oPaginate.sLast ) ); - * - * nFirst.className = "paginate_button first"; - * nPrevious.className = "paginate_button previous"; - * nNext.className="paginate_button next"; - * nLast.className = "paginate_button last"; - * - * nPaging.appendChild( nFirst ); - * nPaging.appendChild( nPrevious ); - * nPaging.appendChild( nNext ); - * nPaging.appendChild( nLast ); - * - * $(nFirst).click( function () { - * oSettings.oApi._fnPageChange( oSettings, "first" ); - * fnCallbackDraw( oSettings ); - * } ); - * - * $(nPrevious).click( function() { - * oSettings.oApi._fnPageChange( oSettings, "previous" ); - * fnCallbackDraw( oSettings ); - * } ); - * - * $(nNext).click( function() { - * oSettings.oApi._fnPageChange( oSettings, "next" ); - * fnCallbackDraw( oSettings ); - * } ); - * - * $(nLast).click( function() { - * oSettings.oApi._fnPageChange( oSettings, "last" ); - * fnCallbackDraw( oSettings ); - * } ); - * - * $(nFirst).bind( 'selectstart', function () { return false; } ); - * $(nPrevious).bind( 'selectstart', function () { return false; } ); - * $(nNext).bind( 'selectstart', function () { return false; } ); - * $(nLast).bind( 'selectstart', function () { return false; } ); - * }, - * - * "fnUpdate": function ( oSettings, fnCallbackDraw ) { - * if ( !oSettings.aanFeatures.p ) { - * return; - * } - * - * // Loop over each instance of the pager - * var an = oSettings.aanFeatures.p; - * for ( var i=0, iLen=an.length ; i - *
  • - * Function input parameters: - *
      - *
    • {*} Data to compare to the second parameter
    • - *
    • {*} Data to compare to the first parameter
    • - *
    - *
  • - *
  • - * Function return: - *
      - *
    • {int} Sorting match: <0 if first parameter should be sorted lower than - * the second parameter, ===0 if the two parameters are equal and >0 if - * the first parameter should be sorted height than the second parameter.
    • - *
    - * - * - * @type object - * @default {} - * - * @example - * // Case-sensitive string sorting, with no pre-formatting method - * $.extend( $.fn.dataTableExt.oSort, { - * "string-case-asc": function(x,y) { - * return ((x < y) ? -1 : ((x > y) ? 1 : 0)); - * }, - * "string-case-desc": function(x,y) { - * return ((x < y) ? 1 : ((x > y) ? -1 : 0)); - * } - * } ); - * - * @example - * // Case-insensitive string sorting, with pre-formatting - * $.extend( $.fn.dataTableExt.oSort, { - * "string-pre": function(x) { - * return x.toLowerCase(); - * }, - * "string-asc": function(x,y) { - * return ((x < y) ? -1 : ((x > y) ? 1 : 0)); - * }, - * "string-desc": function(x,y) { - * return ((x < y) ? 1 : ((x > y) ? -1 : 0)); - * } - * } ); - */ - "oSort": {}, - - - /** - * Version string for plug-ins to check compatibility. Allowed format is - * a.b.c.d.e where: a:int, b:int, c:int, d:string(dev|beta), e:int. d and - * e are optional - * @type string - * @default Version number - */ - "sVersion": DataTable.version, - - - /** - * How should DataTables report an error. Can take the value 'alert' or 'throw' - * @type string - * @default alert - */ - "sErrMode": "alert", - - - /** - * Store information for DataTables to access globally about other instances - * @namespace - * @private - */ - "_oExternConfig": { - /* int:iNextUnique - next unique number for an instance */ - "iNextUnique": 0 - } - }; - - - - - /** - * Template object for the way in which DataTables holds information about - * search information for the global filter and individual column filters. - * @namespace - */ - DataTable.models.oSearch = { - /** - * Flag to indicate if the filtering should be case insensitive or not - * @type boolean - * @default true - */ - "bCaseInsensitive": true, - - /** - * Applied search term - * @type string - * @default Empty string - */ - "sSearch": "", - - /** - * Flag to indicate if the search term should be interpreted as a - * regular expression (true) or not (false) and therefore and special - * regex characters escaped. - * @type boolean - * @default false - */ - "bRegex": false, - - /** - * Flag to indicate if DataTables is to use its smart filtering or not. - * @type boolean - * @default true - */ - "bSmart": true - }; - - - - - /** - * Template object for the way in which DataTables holds information about - * each individual row. This is the object format used for the settings - * aoData array. - * @namespace - */ - DataTable.models.oRow = { - /** - * TR element for the row - * @type node - * @default null - */ - "nTr": null, - - /** - * Data object from the original data source for the row. This is either - * an array if using the traditional form of DataTables, or an object if - * using mData options. The exact type will depend on the passed in - * data from the data source, or will be an array if using DOM a data - * source. - * @type array|object - * @default [] - */ - "_aData": [], - - /** - * Sorting data cache - this array is ostensibly the same length as the - * number of columns (although each index is generated only as it is - * needed), and holds the data that is used for sorting each column in the - * row. We do this cache generation at the start of the sort in order that - * the formatting of the sort data need be done only once for each cell - * per sort. This array should not be read from or written to by anything - * other than the master sorting methods. - * @type array - * @default [] - * @private - */ - "_aSortData": [], - - /** - * Array of TD elements that are cached for hidden rows, so they can be - * reinserted into the table if a column is made visible again (or to act - * as a store if a column is made hidden). Only hidden columns have a - * reference in the array. For non-hidden columns the value is either - * undefined or null. - * @type array nodes - * @default [] - * @private - */ - "_anHidden": [], - - /** - * Cache of the class name that DataTables has applied to the row, so we - * can quickly look at this variable rather than needing to do a DOM check - * on className for the nTr property. - * @type string - * @default Empty string - * @private - */ - "_sRowStripe": "" - }; - - - - /** - * Template object for the column information object in DataTables. This object - * is held in the settings aoColumns array and contains all the information that - * DataTables needs about each individual column. - * - * Note that this object is related to {@link DataTable.defaults.columns} - * but this one is the internal data store for DataTables's cache of columns. - * It should NOT be manipulated outside of DataTables. Any configuration should - * be done through the initialisation options. - * @namespace - */ - DataTable.models.oColumn = { - /** - * A list of the columns that sorting should occur on when this column - * is sorted. That this property is an array allows multi-column sorting - * to be defined for a column (for example first name / last name columns - * would benefit from this). The values are integers pointing to the - * columns to be sorted on (typically it will be a single integer pointing - * at itself, but that doesn't need to be the case). - * @type array - */ - "aDataSort": null, - - /** - * Define the sorting directions that are applied to the column, in sequence - * as the column is repeatedly sorted upon - i.e. the first value is used - * as the sorting direction when the column if first sorted (clicked on). - * Sort it again (click again) and it will move on to the next index. - * Repeat until loop. - * @type array - */ - "asSorting": null, - - /** - * Flag to indicate if the column is searchable, and thus should be included - * in the filtering or not. - * @type boolean - */ - "bSearchable": null, - - /** - * Flag to indicate if the column is sortable or not. - * @type boolean - */ - "bSortable": null, - - /** - * Deprecated When using fnRender, you have two options for what - * to do with the data, and this property serves as the switch. Firstly, you - * can have the sorting and filtering use the rendered value (true - default), - * or you can have the sorting and filtering us the original value (false). - * - * Please note that this option has now been deprecated and will be removed - * in the next version of DataTables. Please use mRender / mData rather than - * fnRender. - * @type boolean - * @deprecated - */ - "bUseRendered": null, - - /** - * Flag to indicate if the column is currently visible in the table or not - * @type boolean - */ - "bVisible": null, - - /** - * Flag to indicate to the type detection method if the automatic type - * detection should be used, or if a column type (sType) has been specified - * @type boolean - * @default true - * @private - */ - "_bAutoType": true, - - /** - * Developer definable function that is called whenever a cell is created (Ajax source, - * etc) or processed for input (DOM source). This can be used as a compliment to mRender - * allowing you to modify the DOM element (add background colour for example) when the - * element is available. - * @type function - * @param {element} nTd The TD node that has been created - * @param {*} sData The Data for the cell - * @param {array|object} oData The data for the whole row - * @param {int} iRow The row index for the aoData data store - * @default null - */ - "fnCreatedCell": null, - - /** - * Function to get data from a cell in a column. You should never - * access data directly through _aData internally in DataTables - always use - * the method attached to this property. It allows mData to function as - * required. This function is automatically assigned by the column - * initialisation method - * @type function - * @param {array|object} oData The data array/object for the array - * (i.e. aoData[]._aData) - * @param {string} sSpecific The specific data type you want to get - - * 'display', 'type' 'filter' 'sort' - * @returns {*} The data for the cell from the given row's data - * @default null - */ - "fnGetData": null, - - /** - * Deprecated Custom display function that will be called for the - * display of each cell in this column. - * - * Please note that this option has now been deprecated and will be removed - * in the next version of DataTables. Please use mRender / mData rather than - * fnRender. - * @type function - * @param {object} o Object with the following parameters: - * @param {int} o.iDataRow The row in aoData - * @param {int} o.iDataColumn The column in question - * @param {array} o.aData The data for the row in question - * @param {object} o.oSettings The settings object for this DataTables instance - * @returns {string} The string you which to use in the display - * @default null - * @deprecated - */ - "fnRender": null, - - /** - * Function to set data for a cell in the column. You should never - * set the data directly to _aData internally in DataTables - always use - * this method. It allows mData to function as required. This function - * is automatically assigned by the column initialisation method - * @type function - * @param {array|object} oData The data array/object for the array - * (i.e. aoData[]._aData) - * @param {*} sValue Value to set - * @default null - */ - "fnSetData": null, - - /** - * Property to read the value for the cells in the column from the data - * source array / object. If null, then the default content is used, if a - * function is given then the return from the function is used. - * @type function|int|string|null - * @default null - */ - "mData": null, - - /** - * Partner property to mData which is used (only when defined) to get - * the data - i.e. it is basically the same as mData, but without the - * 'set' option, and also the data fed to it is the result from mData. - * This is the rendering method to match the data method of mData. - * @type function|int|string|null - * @default null - */ - "mRender": null, - - /** - * Unique header TH/TD element for this column - this is what the sorting - * listener is attached to (if sorting is enabled.) - * @type node - * @default null - */ - "nTh": null, - - /** - * Unique footer TH/TD element for this column (if there is one). Not used - * in DataTables as such, but can be used for plug-ins to reference the - * footer for each column. - * @type node - * @default null - */ - "nTf": null, - - /** - * The class to apply to all TD elements in the table's TBODY for the column - * @type string - * @default null - */ - "sClass": null, - - /** - * When DataTables calculates the column widths to assign to each column, - * it finds the longest string in each column and then constructs a - * temporary table and reads the widths from that. The problem with this - * is that "mmm" is much wider then "iiii", but the latter is a longer - * string - thus the calculation can go wrong (doing it properly and putting - * it into an DOM object and measuring that is horribly(!) slow). Thus as - * a "work around" we provide this option. It will append its value to the - * text that is found to be the longest string for the column - i.e. padding. - * @type string - */ - "sContentPadding": null, - - /** - * Allows a default value to be given for a column's data, and will be used - * whenever a null data source is encountered (this can be because mData - * is set to null, or because the data source itself is null). - * @type string - * @default null - */ - "sDefaultContent": null, - - /** - * Name for the column, allowing reference to the column by name as well as - * by index (needs a lookup to work by name). - * @type string - */ - "sName": null, - - /** - * Custom sorting data type - defines which of the available plug-ins in - * afnSortData the custom sorting will use - if any is defined. - * @type string - * @default std - */ - "sSortDataType": 'std', - - /** - * Class to be applied to the header element when sorting on this column - * @type string - * @default null - */ - "sSortingClass": null, - - /** - * Class to be applied to the header element when sorting on this column - - * when jQuery UI theming is used. - * @type string - * @default null - */ - "sSortingClassJUI": null, - - /** - * Title of the column - what is seen in the TH element (nTh). - * @type string - */ - "sTitle": null, - - /** - * Column sorting and filtering type - * @type string - * @default null - */ - "sType": null, - - /** - * Width of the column - * @type string - * @default null - */ - "sWidth": null, - - /** - * Width of the column when it was first "encountered" - * @type string - * @default null - */ - "sWidthOrig": null - }; - - - - /** - * Initialisation options that can be given to DataTables at initialisation - * time. - * @namespace - */ - DataTable.defaults = { - /** - * An array of data to use for the table, passed in at initialisation which - * will be used in preference to any data which is already in the DOM. This is - * particularly useful for constructing tables purely in Javascript, for - * example with a custom Ajax call. - * @type array - * @default null - * @dtopt Option - * - * @example - * // Using a 2D array data source - * $(document).ready( function () { - * $('#example').dataTable( { - * "aaData": [ - * ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'], - * ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'], - * ], - * "aoColumns": [ - * { "sTitle": "Engine" }, - * { "sTitle": "Browser" }, - * { "sTitle": "Platform" }, - * { "sTitle": "Version" }, - * { "sTitle": "Grade" } - * ] - * } ); - * } ); - * - * @example - * // Using an array of objects as a data source (mData) - * $(document).ready( function () { - * $('#example').dataTable( { - * "aaData": [ - * { - * "engine": "Trident", - * "browser": "Internet Explorer 4.0", - * "platform": "Win 95+", - * "version": 4, - * "grade": "X" - * }, - * { - * "engine": "Trident", - * "browser": "Internet Explorer 5.0", - * "platform": "Win 95+", - * "version": 5, - * "grade": "C" - * } - * ], - * "aoColumns": [ - * { "sTitle": "Engine", "mData": "engine" }, - * { "sTitle": "Browser", "mData": "browser" }, - * { "sTitle": "Platform", "mData": "platform" }, - * { "sTitle": "Version", "mData": "version" }, - * { "sTitle": "Grade", "mData": "grade" } - * ] - * } ); - * } ); - */ - "aaData": null, - - - /** - * If sorting is enabled, then DataTables will perform a first pass sort on - * initialisation. You can define which column(s) the sort is performed upon, - * and the sorting direction, with this variable. The aaSorting array should - * contain an array for each column to be sorted initially containing the - * column's index and a direction string ('asc' or 'desc'). - * @type array - * @default [[0,'asc']] - * @dtopt Option - * - * @example - * // Sort by 3rd column first, and then 4th column - * $(document).ready( function() { - * $('#example').dataTable( { - * "aaSorting": [[2,'asc'], [3,'desc']] - * } ); - * } ); - * - * // No initial sorting - * $(document).ready( function() { - * $('#example').dataTable( { - * "aaSorting": [] - * } ); - * } ); - */ - "aaSorting": [[0,'asc']], - - - /** - * This parameter is basically identical to the aaSorting parameter, but - * cannot be overridden by user interaction with the table. What this means - * is that you could have a column (visible or hidden) which the sorting will - * always be forced on first - any sorting after that (from the user) will - * then be performed as required. This can be useful for grouping rows - * together. - * @type array - * @default null - * @dtopt Option - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "aaSortingFixed": [[0,'asc']] - * } ); - * } ) - */ - "aaSortingFixed": null, - - - /** - * This parameter allows you to readily specify the entries in the length drop - * down menu that DataTables shows when pagination is enabled. It can be - * either a 1D array of options which will be used for both the displayed - * option and the value, or a 2D array which will use the array in the first - * position as the value, and the array in the second position as the - * displayed options (useful for language strings such as 'All'). - * @type array - * @default [ 10, 25, 50, 100 ] - * @dtopt Option - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "aLengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]] - * } ); - * } ); - * - * @example - * // Setting the default display length as well as length menu - * // This is likely to be wanted if you remove the '10' option which - * // is the iDisplayLength default. - * $(document).ready( function() { - * $('#example').dataTable( { - * "iDisplayLength": 25, - * "aLengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]] - * } ); - * } ); - */ - "aLengthMenu": [ 10, 25, 50, 100 ], - - - /** - * The aoColumns option in the initialisation parameter allows you to define - * details about the way individual columns behave. For a full list of - * column options that can be set, please see - * {@link DataTable.defaults.columns}. Note that if you use aoColumns to - * define your columns, you must have an entry in the array for every single - * column that you have in your table (these can be null if you don't which - * to specify any options). - * @member - */ - "aoColumns": null, - - /** - * Very similar to aoColumns, aoColumnDefs allows you to target a specific - * column, multiple columns, or all columns, using the aTargets property of - * each object in the array. This allows great flexibility when creating - * tables, as the aoColumnDefs arrays can be of any length, targeting the - * columns you specifically want. aoColumnDefs may use any of the column - * options available: {@link DataTable.defaults.columns}, but it _must_ - * have aTargets defined in each object in the array. Values in the aTargets - * array may be: - *
      - *
    • a string - class name will be matched on the TH for the column
    • - *
    • 0 or a positive integer - column index counting from the left
    • - *
    • a negative integer - column index counting from the right
    • - *
    • the string "_all" - all columns (i.e. assign a default)
    • - *
    - * @member - */ - "aoColumnDefs": null, - - - /** - * Basically the same as oSearch, this parameter defines the individual column - * filtering state at initialisation time. The array must be of the same size - * as the number of columns, and each element be an object with the parameters - * "sSearch" and "bEscapeRegex" (the latter is optional). 'null' is also - * accepted and the default will be used. - * @type array - * @default [] - * @dtopt Option - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoSearchCols": [ - * null, - * { "sSearch": "My filter" }, - * null, - * { "sSearch": "^[0-9]", "bEscapeRegex": false } - * ] - * } ); - * } ) - */ - "aoSearchCols": [], - - - /** - * An array of CSS classes that should be applied to displayed rows. This - * array may be of any length, and DataTables will apply each class - * sequentially, looping when required. - * @type array - * @default null Will take the values determined by the oClasses.sStripe* - * options - * @dtopt Option - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "asStripeClasses": [ 'strip1', 'strip2', 'strip3' ] - * } ); - * } ) - */ - "asStripeClasses": null, - - - /** - * Enable or disable automatic column width calculation. This can be disabled - * as an optimisation (it takes some time to calculate the widths) if the - * tables widths are passed in using aoColumns. - * @type boolean - * @default true - * @dtopt Features - * - * @example - * $(document).ready( function () { - * $('#example').dataTable( { - * "bAutoWidth": false - * } ); - * } ); - */ - "bAutoWidth": true, - - - /** - * Deferred rendering can provide DataTables with a huge speed boost when you - * are using an Ajax or JS data source for the table. This option, when set to - * true, will cause DataTables to defer the creation of the table elements for - * each row until they are needed for a draw - saving a significant amount of - * time. - * @type boolean - * @default false - * @dtopt Features - * - * @example - * $(document).ready( function() { - * var oTable = $('#example').dataTable( { - * "sAjaxSource": "sources/arrays.txt", - * "bDeferRender": true - * } ); - * } ); - */ - "bDeferRender": false, - - - /** - * Replace a DataTable which matches the given selector and replace it with - * one which has the properties of the new initialisation object passed. If no - * table matches the selector, then the new DataTable will be constructed as - * per normal. - * @type boolean - * @default false - * @dtopt Options - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "sScrollY": "200px", - * "bPaginate": false - * } ); - * - * // Some time later.... - * $('#example').dataTable( { - * "bFilter": false, - * "bDestroy": true - * } ); - * } ); - */ - "bDestroy": false, - - - /** - * Enable or disable filtering of data. Filtering in DataTables is "smart" in - * that it allows the end user to input multiple words (space separated) and - * will match a row containing those words, even if not in the order that was - * specified (this allow matching across multiple columns). Note that if you - * wish to use filtering in DataTables this must remain 'true' - to remove the - * default filtering input box and retain filtering abilities, please use - * {@link DataTable.defaults.sDom}. - * @type boolean - * @default true - * @dtopt Features - * - * @example - * $(document).ready( function () { - * $('#example').dataTable( { - * "bFilter": false - * } ); - * } ); - */ - "bFilter": true, - - - /** - * Enable or disable the table information display. This shows information - * about the data that is currently visible on the page, including information - * about filtered data if that action is being performed. - * @type boolean - * @default true - * @dtopt Features - * - * @example - * $(document).ready( function () { - * $('#example').dataTable( { - * "bInfo": false - * } ); - * } ); - */ - "bInfo": true, - - - /** - * Enable jQuery UI ThemeRoller support (required as ThemeRoller requires some - * slightly different and additional mark-up from what DataTables has - * traditionally used). - * @type boolean - * @default false - * @dtopt Features - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "bJQueryUI": true - * } ); - * } ); - */ - "bJQueryUI": false, - - - /** - * Allows the end user to select the size of a formatted page from a select - * menu (sizes are 10, 25, 50 and 100). Requires pagination (bPaginate). - * @type boolean - * @default true - * @dtopt Features - * - * @example - * $(document).ready( function () { - * $('#example').dataTable( { - * "bLengthChange": false - * } ); - * } ); - */ - "bLengthChange": true, - - - /** - * Enable or disable pagination. - * @type boolean - * @default true - * @dtopt Features - * - * @example - * $(document).ready( function () { - * $('#example').dataTable( { - * "bPaginate": false - * } ); - * } ); - */ - "bPaginate": true, - - - /** - * Enable or disable the display of a 'processing' indicator when the table is - * being processed (e.g. a sort). This is particularly useful for tables with - * large amounts of data where it can take a noticeable amount of time to sort - * the entries. - * @type boolean - * @default false - * @dtopt Features - * - * @example - * $(document).ready( function () { - * $('#example').dataTable( { - * "bProcessing": true - * } ); - * } ); - */ - "bProcessing": false, - - - /** - * Retrieve the DataTables object for the given selector. Note that if the - * table has already been initialised, this parameter will cause DataTables - * to simply return the object that has already been set up - it will not take - * account of any changes you might have made to the initialisation object - * passed to DataTables (setting this parameter to true is an acknowledgement - * that you understand this). bDestroy can be used to reinitialise a table if - * you need. - * @type boolean - * @default false - * @dtopt Options - * - * @example - * $(document).ready( function() { - * initTable(); - * tableActions(); - * } ); - * - * function initTable () - * { - * return $('#example').dataTable( { - * "sScrollY": "200px", - * "bPaginate": false, - * "bRetrieve": true - * } ); - * } - * - * function tableActions () - * { - * var oTable = initTable(); - * // perform API operations with oTable - * } - */ - "bRetrieve": false, - - - /** - * Indicate if DataTables should be allowed to set the padding / margin - * etc for the scrolling header elements or not. Typically you will want - * this. - * @type boolean - * @default true - * @dtopt Options - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "bScrollAutoCss": false, - * "sScrollY": "200px" - * } ); - * } ); - */ - "bScrollAutoCss": true, - - - /** - * When vertical (y) scrolling is enabled, DataTables will force the height of - * the table's viewport to the given height at all times (useful for layout). - * However, this can look odd when filtering data down to a small data set, - * and the footer is left "floating" further down. This parameter (when - * enabled) will cause DataTables to collapse the table's viewport down when - * the result set will fit within the given Y height. - * @type boolean - * @default false - * @dtopt Options - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "sScrollY": "200", - * "bScrollCollapse": true - * } ); - * } ); - */ - "bScrollCollapse": false, - - - /** - * Enable infinite scrolling for DataTables (to be used in combination with - * sScrollY). Infinite scrolling means that DataTables will continually load - * data as a user scrolls through a table, which is very useful for large - * dataset. This cannot be used with pagination, which is automatically - * disabled. Note - the Scroller extra for DataTables is recommended in - * in preference to this option. - * @type boolean - * @default false - * @dtopt Features - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "bScrollInfinite": true, - * "bScrollCollapse": true, - * "sScrollY": "200px" - * } ); - * } ); - */ - "bScrollInfinite": false, - - - /** - * Configure DataTables to use server-side processing. Note that the - * sAjaxSource parameter must also be given in order to give DataTables a - * source to obtain the required data for each draw. - * @type boolean - * @default false - * @dtopt Features - * @dtopt Server-side - * - * @example - * $(document).ready( function () { - * $('#example').dataTable( { - * "bServerSide": true, - * "sAjaxSource": "xhr.php" - * } ); - * } ); - */ - "bServerSide": false, - - - /** - * Enable or disable sorting of columns. Sorting of individual columns can be - * disabled by the "bSortable" option for each column. - * @type boolean - * @default true - * @dtopt Features - * - * @example - * $(document).ready( function () { - * $('#example').dataTable( { - * "bSort": false - * } ); - * } ); - */ - "bSort": true, - - - /** - * Allows control over whether DataTables should use the top (true) unique - * cell that is found for a single column, or the bottom (false - default). - * This is useful when using complex headers. - * @type boolean - * @default false - * @dtopt Options - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "bSortCellsTop": true - * } ); - * } ); - */ - "bSortCellsTop": false, - - - /** - * Enable or disable the addition of the classes 'sorting_1', 'sorting_2' and - * 'sorting_3' to the columns which are currently being sorted on. This is - * presented as a feature switch as it can increase processing time (while - * classes are removed and added) so for large data sets you might want to - * turn this off. - * @type boolean - * @default true - * @dtopt Features - * - * @example - * $(document).ready( function () { - * $('#example').dataTable( { - * "bSortClasses": false - * } ); - * } ); - */ - "bSortClasses": true, - - - /** - * Enable or disable state saving. When enabled a cookie will be used to save - * table display information such as pagination information, display length, - * filtering and sorting. As such when the end user reloads the page the - * display display will match what thy had previously set up. - * @type boolean - * @default false - * @dtopt Features - * - * @example - * $(document).ready( function () { - * $('#example').dataTable( { - * "bStateSave": true - * } ); - * } ); - */ - "bStateSave": false, - - - /** - * Customise the cookie and / or the parameters being stored when using - * DataTables with state saving enabled. This function is called whenever - * the cookie is modified, and it expects a fully formed cookie string to be - * returned. Note that the data object passed in is a Javascript object which - * must be converted to a string (JSON.stringify for example). - * @type function - * @param {string} sName Name of the cookie defined by DataTables - * @param {object} oData Data to be stored in the cookie - * @param {string} sExpires Cookie expires string - * @param {string} sPath Path of the cookie to set - * @returns {string} Cookie formatted string (which should be encoded by - * using encodeURIComponent()) - * @dtopt Callbacks - * - * @example - * $(document).ready( function () { - * $('#example').dataTable( { - * "fnCookieCallback": function (sName, oData, sExpires, sPath) { - * // Customise oData or sName or whatever else here - * return sName + "="+JSON.stringify(oData)+"; expires=" + sExpires +"; path=" + sPath; - * } - * } ); - * } ); - */ - "fnCookieCallback": null, - - - /** - * This function is called when a TR element is created (and all TD child - * elements have been inserted), or registered if using a DOM source, allowing - * manipulation of the TR element (adding classes etc). - * @type function - * @param {node} nRow "TR" element for the current row - * @param {array} aData Raw data array for this row - * @param {int} iDataIndex The index of this row in aoData - * @dtopt Callbacks - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "fnCreatedRow": function( nRow, aData, iDataIndex ) { - * // Bold the grade for all 'A' grade browsers - * if ( aData[4] == "A" ) - * { - * $('td:eq(4)', nRow).html( 'A' ); - * } - * } - * } ); - * } ); - */ - "fnCreatedRow": null, - - - /** - * This function is called on every 'draw' event, and allows you to - * dynamically modify any aspect you want about the created DOM. - * @type function - * @param {object} oSettings DataTables settings object - * @dtopt Callbacks - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "fnDrawCallback": function( oSettings ) { - * alert( 'DataTables has redrawn the table' ); - * } - * } ); - * } ); - */ - "fnDrawCallback": null, - - - /** - * Identical to fnHeaderCallback() but for the table footer this function - * allows you to modify the table footer on every 'draw' even. - * @type function - * @param {node} nFoot "TR" element for the footer - * @param {array} aData Full table data (as derived from the original HTML) - * @param {int} iStart Index for the current display starting point in the - * display array - * @param {int} iEnd Index for the current display ending point in the - * display array - * @param {array int} aiDisplay Index array to translate the visual position - * to the full data array - * @dtopt Callbacks - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "fnFooterCallback": function( nFoot, aData, iStart, iEnd, aiDisplay ) { - * nFoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+iStart; - * } - * } ); - * } ) - */ - "fnFooterCallback": null, - - - /** - * When rendering large numbers in the information element for the table - * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers - * to have a comma separator for the 'thousands' units (e.g. 1 million is - * rendered as "1,000,000") to help readability for the end user. This - * function will override the default method DataTables uses. - * @type function - * @member - * @param {int} iIn number to be formatted - * @returns {string} formatted string for DataTables to show the number - * @dtopt Callbacks - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "fnFormatNumber": function ( iIn ) { - * if ( iIn < 1000 ) { - * return iIn; - * } else { - * var - * s=(iIn+""), - * a=s.split(""), out="", - * iLen=s.length; - * - * for ( var i=0 ; i<iLen ; i++ ) { - * if ( i%3 === 0 && i !== 0 ) { - * out = "'"+out; - * } - * out = a[iLen-i-1]+out; - * } - * } - * return out; - * }; - * } ); - * } ); - */ - "fnFormatNumber": function ( iIn ) { - if ( iIn < 1000 ) - { - // A small optimisation for what is likely to be the majority of use cases - return iIn; - } - - var s=(iIn+""), a=s.split(""), out="", iLen=s.length; - - for ( var i=0 ; iA' ); - * } - * } - * } ); - * } ); - */ - "fnRowCallback": null, - - - /** - * This parameter allows you to override the default function which obtains - * the data from the server ($.getJSON) so something more suitable for your - * application. For example you could use POST data, or pull information from - * a Gears or AIR database. - * @type function - * @member - * @param {string} sSource HTTP source to obtain the data from (sAjaxSource) - * @param {array} aoData A key/value pair object containing the data to send - * to the server - * @param {function} fnCallback to be called on completion of the data get - * process that will draw the data on the page. - * @param {object} oSettings DataTables settings object - * @dtopt Callbacks - * @dtopt Server-side - * - * @example - * // POST data to server - * $(document).ready( function() { - * $('#example').dataTable( { - * "bProcessing": true, - * "bServerSide": true, - * "sAjaxSource": "xhr.php", - * "fnServerData": function ( sSource, aoData, fnCallback, oSettings ) { - * oSettings.jqXHR = $.ajax( { - * "dataType": 'json', - * "type": "POST", - * "url": sSource, - * "data": aoData, - * "success": fnCallback - * } ); - * } - * } ); - * } ); - */ - "fnServerData": function ( sUrl, aoData, fnCallback, oSettings ) { - oSettings.jqXHR = $.ajax( { - "url": sUrl, - "data": aoData, - "success": function (json) { - if ( json.sError ) { - oSettings.oApi._fnLog( oSettings, 0, json.sError ); - } - - $(oSettings.oInstance).trigger('xhr', [oSettings, json]); - fnCallback( json ); - }, - "dataType": "json", - "cache": false, - "type": oSettings.sServerMethod, - "error": function (xhr, error, thrown) { - if ( error == "parsererror" ) { - oSettings.oApi._fnLog( oSettings, 0, "DataTables warning: JSON data from "+ - "server could not be parsed. This is caused by a JSON formatting error." ); - } - } - } ); - }, - - - /** - * It is often useful to send extra data to the server when making an Ajax - * request - for example custom filtering information, and this callback - * function makes it trivial to send extra information to the server. The - * passed in parameter is the data set that has been constructed by - * DataTables, and you can add to this or modify it as you require. - * @type function - * @param {array} aoData Data array (array of objects which are name/value - * pairs) that has been constructed by DataTables and will be sent to the - * server. In the case of Ajax sourced data with server-side processing - * this will be an empty array, for server-side processing there will be a - * significant number of parameters! - * @returns {undefined} Ensure that you modify the aoData array passed in, - * as this is passed by reference. - * @dtopt Callbacks - * @dtopt Server-side - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "bProcessing": true, - * "bServerSide": true, - * "sAjaxSource": "scripts/server_processing.php", - * "fnServerParams": function ( aoData ) { - * aoData.push( { "name": "more_data", "value": "my_value" } ); - * } - * } ); - * } ); - */ - "fnServerParams": null, - - - /** - * Load the table state. With this function you can define from where, and how, the - * state of a table is loaded. By default DataTables will load from its state saving - * cookie, but you might wish to use local storage (HTML5) or a server-side database. - * @type function - * @member - * @param {object} oSettings DataTables settings object - * @return {object} The DataTables state object to be loaded - * @dtopt Callbacks - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "bStateSave": true, - * "fnStateLoad": function (oSettings) { - * var o; - * - * // Send an Ajax request to the server to get the data. Note that - * // this is a synchronous request. - * $.ajax( { - * "url": "/state_load", - * "async": false, - * "dataType": "json", - * "success": function (json) { - * o = json; - * } - * } ); - * - * return o; - * } - * } ); - * } ); - */ - "fnStateLoad": function ( oSettings ) { - var sData = this.oApi._fnReadCookie( oSettings.sCookiePrefix+oSettings.sInstance ); - var oData; - - try { - oData = (typeof $.parseJSON === 'function') ? - $.parseJSON(sData) : eval( '('+sData+')' ); - } catch (e) { - oData = null; - } - - return oData; - }, - - - /** - * Callback which allows modification of the saved state prior to loading that state. - * This callback is called when the table is loading state from the stored data, but - * prior to the settings object being modified by the saved state. Note that for - * plug-in authors, you should use the 'stateLoadParams' event to load parameters for - * a plug-in. - * @type function - * @param {object} oSettings DataTables settings object - * @param {object} oData The state object that is to be loaded - * @dtopt Callbacks - * - * @example - * // Remove a saved filter, so filtering is never loaded - * $(document).ready( function() { - * $('#example').dataTable( { - * "bStateSave": true, - * "fnStateLoadParams": function (oSettings, oData) { - * oData.oSearch.sSearch = ""; - * } - * } ); - * } ); - * - * @example - * // Disallow state loading by returning false - * $(document).ready( function() { - * $('#example').dataTable( { - * "bStateSave": true, - * "fnStateLoadParams": function (oSettings, oData) { - * return false; - * } - * } ); - * } ); - */ - "fnStateLoadParams": null, - - - /** - * Callback that is called when the state has been loaded from the state saving method - * and the DataTables settings object has been modified as a result of the loaded state. - * @type function - * @param {object} oSettings DataTables settings object - * @param {object} oData The state object that was loaded - * @dtopt Callbacks - * - * @example - * // Show an alert with the filtering value that was saved - * $(document).ready( function() { - * $('#example').dataTable( { - * "bStateSave": true, - * "fnStateLoaded": function (oSettings, oData) { - * alert( 'Saved filter was: '+oData.oSearch.sSearch ); - * } - * } ); - * } ); - */ - "fnStateLoaded": null, - - - /** - * Save the table state. This function allows you to define where and how the state - * information for the table is stored - by default it will use a cookie, but you - * might want to use local storage (HTML5) or a server-side database. - * @type function - * @member - * @param {object} oSettings DataTables settings object - * @param {object} oData The state object to be saved - * @dtopt Callbacks - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "bStateSave": true, - * "fnStateSave": function (oSettings, oData) { - * // Send an Ajax request to the server with the state object - * $.ajax( { - * "url": "/state_save", - * "data": oData, - * "dataType": "json", - * "method": "POST" - * "success": function () {} - * } ); - * } - * } ); - * } ); - */ - "fnStateSave": function ( oSettings, oData ) { - this.oApi._fnCreateCookie( - oSettings.sCookiePrefix+oSettings.sInstance, - this.oApi._fnJsonString(oData), - oSettings.iCookieDuration, - oSettings.sCookiePrefix, - oSettings.fnCookieCallback - ); - }, - - - /** - * Callback which allows modification of the state to be saved. Called when the table - * has changed state a new state save is required. This method allows modification of - * the state saving object prior to actually doing the save, including addition or - * other state properties or modification. Note that for plug-in authors, you should - * use the 'stateSaveParams' event to save parameters for a plug-in. - * @type function - * @param {object} oSettings DataTables settings object - * @param {object} oData The state object to be saved - * @dtopt Callbacks - * - * @example - * // Remove a saved filter, so filtering is never saved - * $(document).ready( function() { - * $('#example').dataTable( { - * "bStateSave": true, - * "fnStateSaveParams": function (oSettings, oData) { - * oData.oSearch.sSearch = ""; - * } - * } ); - * } ); - */ - "fnStateSaveParams": null, - - - /** - * Duration of the cookie which is used for storing session information. This - * value is given in seconds. - * @type int - * @default 7200 (2 hours) - * @dtopt Options - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "iCookieDuration": 60*60*24; // 1 day - * } ); - * } ) - */ - "iCookieDuration": 7200, - - - /** - * When enabled DataTables will not make a request to the server for the first - * page draw - rather it will use the data already on the page (no sorting etc - * will be applied to it), thus saving on an XHR at load time. iDeferLoading - * is used to indicate that deferred loading is required, but it is also used - * to tell DataTables how many records there are in the full table (allowing - * the information element and pagination to be displayed correctly). In the case - * where a filtering is applied to the table on initial load, this can be - * indicated by giving the parameter as an array, where the first element is - * the number of records available after filtering and the second element is the - * number of records without filtering (allowing the table information element - * to be shown correctly). - * @type int | array - * @default null - * @dtopt Options - * - * @example - * // 57 records available in the table, no filtering applied - * $(document).ready( function() { - * $('#example').dataTable( { - * "bServerSide": true, - * "sAjaxSource": "scripts/server_processing.php", - * "iDeferLoading": 57 - * } ); - * } ); - * - * @example - * // 57 records after filtering, 100 without filtering (an initial filter applied) - * $(document).ready( function() { - * $('#example').dataTable( { - * "bServerSide": true, - * "sAjaxSource": "scripts/server_processing.php", - * "iDeferLoading": [ 57, 100 ], - * "oSearch": { - * "sSearch": "my_filter" - * } - * } ); - * } ); - */ - "iDeferLoading": null, - - - /** - * Number of rows to display on a single page when using pagination. If - * feature enabled (bLengthChange) then the end user will be able to override - * this to a custom setting using a pop-up menu. - * @type int - * @default 10 - * @dtopt Options - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "iDisplayLength": 50 - * } ); - * } ) - */ - "iDisplayLength": 10, - - - /** - * Define the starting point for data display when using DataTables with - * pagination. Note that this parameter is the number of records, rather than - * the page number, so if you have 10 records per page and want to start on - * the third page, it should be "20". - * @type int - * @default 0 - * @dtopt Options - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "iDisplayStart": 20 - * } ); - * } ) - */ - "iDisplayStart": 0, - - - /** - * The scroll gap is the amount of scrolling that is left to go before - * DataTables will load the next 'page' of data automatically. You typically - * want a gap which is big enough that the scrolling will be smooth for the - * user, while not so large that it will load more data than need. - * @type int - * @default 100 - * @dtopt Options - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "bScrollInfinite": true, - * "bScrollCollapse": true, - * "sScrollY": "200px", - * "iScrollLoadGap": 50 - * } ); - * } ); - */ - "iScrollLoadGap": 100, - - - /** - * By default DataTables allows keyboard navigation of the table (sorting, paging, - * and filtering) by adding a tabindex attribute to the required elements. This - * allows you to tab through the controls and press the enter key to activate them. - * The tabindex is default 0, meaning that the tab follows the flow of the document. - * You can overrule this using this parameter if you wish. Use a value of -1 to - * disable built-in keyboard navigation. - * @type int - * @default 0 - * @dtopt Options - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "iTabIndex": 1 - * } ); - * } ); - */ - "iTabIndex": 0, - - - /** - * All strings that DataTables uses in the user interface that it creates - * are defined in this object, allowing you to modified them individually or - * completely replace them all as required. - * @namespace - */ - "oLanguage": { - /** - * Strings that are used for WAI-ARIA labels and controls only (these are not - * actually visible on the page, but will be read by screenreaders, and thus - * must be internationalised as well). - * @namespace - */ - "oAria": { - /** - * ARIA label that is added to the table headers when the column may be - * sorted ascending by activing the column (click or return when focused). - * Note that the column header is prefixed to this string. - * @type string - * @default : activate to sort column ascending - * @dtopt Language - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "oLanguage": { - * "oAria": { - * "sSortAscending": " - click/return to sort ascending" - * } - * } - * } ); - * } ); - */ - "sSortAscending": ": activate to sort column ascending", - - /** - * ARIA label that is added to the table headers when the column may be - * sorted descending by activing the column (click or return when focused). - * Note that the column header is prefixed to this string. - * @type string - * @default : activate to sort column ascending - * @dtopt Language - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "oLanguage": { - * "oAria": { - * "sSortDescending": " - click/return to sort descending" - * } - * } - * } ); - * } ); - */ - "sSortDescending": ": activate to sort column descending" - }, - - /** - * Pagination string used by DataTables for the two built-in pagination - * control types ("two_button" and "full_numbers") - * @namespace - */ - "oPaginate": { - /** - * Text to use when using the 'full_numbers' type of pagination for the - * button to take the user to the first page. - * @type string - * @default First - * @dtopt Language - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "oLanguage": { - * "oPaginate": { - * "sFirst": "First page" - * } - * } - * } ); - * } ); - */ - "sFirst": "First", - - - /** - * Text to use when using the 'full_numbers' type of pagination for the - * button to take the user to the last page. - * @type string - * @default Last - * @dtopt Language - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "oLanguage": { - * "oPaginate": { - * "sLast": "Last page" - * } - * } - * } ); - * } ); - */ - "sLast": "Last", - - - /** - * Text to use for the 'next' pagination button (to take the user to the - * next page). - * @type string - * @default Next - * @dtopt Language - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "oLanguage": { - * "oPaginate": { - * "sNext": "Next page" - * } - * } - * } ); - * } ); - */ - "sNext": "Next", - - - /** - * Text to use for the 'previous' pagination button (to take the user to - * the previous page). - * @type string - * @default Previous - * @dtopt Language - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "oLanguage": { - * "oPaginate": { - * "sPrevious": "Previous page" - * } - * } - * } ); - * } ); - */ - "sPrevious": "Previous" - }, - - /** - * This string is shown in preference to sZeroRecords when the table is - * empty of data (regardless of filtering). Note that this is an optional - * parameter - if it is not given, the value of sZeroRecords will be used - * instead (either the default or given value). - * @type string - * @default No data available in table - * @dtopt Language - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sEmptyTable": "No data available in table" - * } - * } ); - * } ); - */ - "sEmptyTable": "No data available in table", - - - /** - * This string gives information to the end user about the information that - * is current on display on the page. The _START_, _END_ and _TOTAL_ - * variables are all dynamically replaced as the table display updates, and - * can be freely moved or removed as the language requirements change. - * @type string - * @default Showing _START_ to _END_ of _TOTAL_ entries - * @dtopt Language - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sInfo": "Got a total of _TOTAL_ entries to show (_START_ to _END_)" - * } - * } ); - * } ); - */ - "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries", - - - /** - * Display information string for when the table is empty. Typically the - * format of this string should match sInfo. - * @type string - * @default Showing 0 to 0 of 0 entries - * @dtopt Language - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sInfoEmpty": "No entries to show" - * } - * } ); - * } ); - */ - "sInfoEmpty": "Showing 0 to 0 of 0 entries", - - - /** - * When a user filters the information in a table, this string is appended - * to the information (sInfo) to give an idea of how strong the filtering - * is. The variable _MAX_ is dynamically updated. - * @type string - * @default (filtered from _MAX_ total entries) - * @dtopt Language - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sInfoFiltered": " - filtering from _MAX_ records" - * } - * } ); - * } ); - */ - "sInfoFiltered": "(filtered from _MAX_ total entries)", - - - /** - * If can be useful to append extra information to the info string at times, - * and this variable does exactly that. This information will be appended to - * the sInfo (sInfoEmpty and sInfoFiltered in whatever combination they are - * being used) at all times. - * @type string - * @default Empty string - * @dtopt Language - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sInfoPostFix": "All records shown are derived from real information." - * } - * } ); - * } ); - */ - "sInfoPostFix": "", - - - /** - * DataTables has a build in number formatter (fnFormatNumber) which is used - * to format large numbers that are used in the table information. By - * default a comma is used, but this can be trivially changed to any - * character you wish with this parameter. - * @type string - * @default , - * @dtopt Language - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sInfoThousands": "'" - * } - * } ); - * } ); - */ - "sInfoThousands": ",", - - - /** - * Detail the action that will be taken when the drop down menu for the - * pagination length option is changed. The '_MENU_' variable is replaced - * with a default select list of 10, 25, 50 and 100, and can be replaced - * with a custom select box if required. - * @type string - * @default Show _MENU_ entries - * @dtopt Language - * - * @example - * // Language change only - * $(document).ready( function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sLengthMenu": "Display _MENU_ records" - * } - * } ); - * } ); - * - * @example - * // Language and options change - * $(document).ready( function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sLengthMenu": 'Display records' - * } - * } ); - * } ); - */ - "sLengthMenu": "Show _MENU_ entries", - - - /** - * When using Ajax sourced data and during the first draw when DataTables is - * gathering the data, this message is shown in an empty row in the table to - * indicate to the end user the the data is being loaded. Note that this - * parameter is not used when loading data by server-side processing, just - * Ajax sourced data with client-side processing. - * @type string - * @default Loading... - * @dtopt Language - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sLoadingRecords": "Please wait - loading..." - * } - * } ); - * } ); - */ - "sLoadingRecords": "Loading...", - - - /** - * Text which is displayed when the table is processing a user action - * (usually a sort command or similar). - * @type string - * @default Processing... - * @dtopt Language - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sProcessing": "DataTables is currently busy" - * } - * } ); - * } ); - */ - "sProcessing": "Processing...", - - - /** - * Details the actions that will be taken when the user types into the - * filtering input text box. The variable "_INPUT_", if used in the string, - * is replaced with the HTML text box for the filtering input allowing - * control over where it appears in the string. If "_INPUT_" is not given - * then the input box is appended to the string automatically. - * @type string - * @default Search: - * @dtopt Language - * - * @example - * // Input text box will be appended at the end automatically - * $(document).ready( function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sSearch": "Filter records:" - * } - * } ); - * } ); - * - * @example - * // Specify where the filter should appear - * $(document).ready( function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sSearch": "Apply filter _INPUT_ to table" - * } - * } ); - * } ); - */ - "sSearch": "Search:", - - - /** - * All of the language information can be stored in a file on the - * server-side, which DataTables will look up if this parameter is passed. - * It must store the URL of the language file, which is in a JSON format, - * and the object has the same properties as the oLanguage object in the - * initialiser object (i.e. the above parameters). Please refer to one of - * the example language files to see how this works in action. - * @type string - * @default Empty string - i.e. disabled - * @dtopt Language - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sUrl": "http://www.sprymedia.co.uk/dataTables/lang.txt" - * } - * } ); - * } ); - */ - "sUrl": "", - - - /** - * Text shown inside the table records when the is no information to be - * displayed after filtering. sEmptyTable is shown when there is simply no - * information in the table at all (regardless of filtering). - * @type string - * @default No matching records found - * @dtopt Language - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sZeroRecords": "No records to display" - * } - * } ); - * } ); - */ - "sZeroRecords": "No matching records found" - }, - - - /** - * This parameter allows you to have define the global filtering state at - * initialisation time. As an object the "sSearch" parameter must be - * defined, but all other parameters are optional. When "bRegex" is true, - * the search string will be treated as a regular expression, when false - * (default) it will be treated as a straight string. When "bSmart" - * DataTables will use it's smart filtering methods (to word match at - * any point in the data), when false this will not be done. - * @namespace - * @extends DataTable.models.oSearch - * @dtopt Options - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "oSearch": {"sSearch": "Initial search"} - * } ); - * } ) - */ - "oSearch": $.extend( {}, DataTable.models.oSearch ), - - - /** - * By default DataTables will look for the property 'aaData' when obtaining - * data from an Ajax source or for server-side processing - this parameter - * allows that property to be changed. You can use Javascript dotted object - * notation to get a data source for multiple levels of nesting. - * @type string - * @default aaData - * @dtopt Options - * @dtopt Server-side - * - * @example - * // Get data from { "data": [...] } - * $(document).ready( function() { - * var oTable = $('#example').dataTable( { - * "sAjaxSource": "sources/data.txt", - * "sAjaxDataProp": "data" - * } ); - * } ); - * - * @example - * // Get data from { "data": { "inner": [...] } } - * $(document).ready( function() { - * var oTable = $('#example').dataTable( { - * "sAjaxSource": "sources/data.txt", - * "sAjaxDataProp": "data.inner" - * } ); - * } ); - */ - "sAjaxDataProp": "aaData", - - - /** - * You can instruct DataTables to load data from an external source using this - * parameter (use aData if you want to pass data in you already have). Simply - * provide a url a JSON object can be obtained from. This object must include - * the parameter 'aaData' which is the data source for the table. - * @type string - * @default null - * @dtopt Options - * @dtopt Server-side - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "sAjaxSource": "http://www.sprymedia.co.uk/dataTables/json.php" - * } ); - * } ) - */ - "sAjaxSource": null, - - - /** - * This parameter can be used to override the default prefix that DataTables - * assigns to a cookie when state saving is enabled. - * @type string - * @default SpryMedia_DataTables_ - * @dtopt Options - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "sCookiePrefix": "my_datatable_", - * } ); - * } ); - */ - "sCookiePrefix": "SpryMedia_DataTables_", - - - /** - * This initialisation variable allows you to specify exactly where in the - * DOM you want DataTables to inject the various controls it adds to the page - * (for example you might want the pagination controls at the top of the - * table). DIV elements (with or without a custom class) can also be added to - * aid styling. The follow syntax is used: - *
      - *
    • The following options are allowed: - *
        - *
      • 'l' - Length changing
      • 'f' - Filtering input - *
      • 't' - The table!
      • - *
      • 'i' - Information
      • - *
      • 'p' - Pagination
      • - *
      • 'r' - pRocessing
      • - *
      - *
    • - *
    • The following constants are allowed: - *
        - *
      • 'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')
      • - *
      • 'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')
      • - *
      - *
    • - *
    • The following syntax is expected: - *
        - *
      • '<' and '>' - div elements
      • - *
      • '<"class" and '>' - div with a class
      • - *
      • '<"#id" and '>' - div with an ID
      • - *
      - *
    • - *
    • Examples: - *
        - *
      • '<"wrapper"flipt>'
      • - *
      • '<lf<t>ip>'
      • - *
      - *
    • - *
    - * @type string - * @default lfrtip (when bJQueryUI is false) or - * <"H"lfr>t<"F"ip> (when bJQueryUI is true) - * @dtopt Options - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "sDom": '<"top"i>rt<"bottom"flp><"clear">' - * } ); - * } ); - */ - "sDom": "lfrtip", - - - /** - * DataTables features two different built-in pagination interaction methods - * ('two_button' or 'full_numbers') which present different page controls to - * the end user. Further methods can be added using the API (see below). - * @type string - * @default two_button - * @dtopt Options - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "sPaginationType": "full_numbers" - * } ); - * } ) - */ - "sPaginationType": "two_button", - - - /** - * Enable horizontal scrolling. When a table is too wide to fit into a certain - * layout, or you have a large number of columns in the table, you can enable - * x-scrolling to show the table in a viewport, which can be scrolled. This - * property can be any CSS unit, or a number (in which case it will be treated - * as a pixel measurement). - * @type string - * @default blank string - i.e. disabled - * @dtopt Features - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "sScrollX": "100%", - * "bScrollCollapse": true - * } ); - * } ); - */ - "sScrollX": "", - - - /** - * This property can be used to force a DataTable to use more width than it - * might otherwise do when x-scrolling is enabled. For example if you have a - * table which requires to be well spaced, this parameter is useful for - * "over-sizing" the table, and thus forcing scrolling. This property can by - * any CSS unit, or a number (in which case it will be treated as a pixel - * measurement). - * @type string - * @default blank string - i.e. disabled - * @dtopt Options - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "sScrollX": "100%", - * "sScrollXInner": "110%" - * } ); - * } ); - */ - "sScrollXInner": "", - - - /** - * Enable vertical scrolling. Vertical scrolling will constrain the DataTable - * to the given height, and enable scrolling for any data which overflows the - * current viewport. This can be used as an alternative to paging to display - * a lot of data in a small area (although paging and scrolling can both be - * enabled at the same time). This property can be any CSS unit, or a number - * (in which case it will be treated as a pixel measurement). - * @type string - * @default blank string - i.e. disabled - * @dtopt Features - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "sScrollY": "200px", - * "bPaginate": false - * } ); - * } ); - */ - "sScrollY": "", - - - /** - * Set the HTTP method that is used to make the Ajax call for server-side - * processing or Ajax sourced data. - * @type string - * @default GET - * @dtopt Options - * @dtopt Server-side - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "bServerSide": true, - * "sAjaxSource": "scripts/post.php", - * "sServerMethod": "POST" - * } ); - * } ); - */ - "sServerMethod": "GET" - }; - - - - /** - * Column options that can be given to DataTables at initialisation time. - * @namespace - */ - DataTable.defaults.columns = { - /** - * Allows a column's sorting to take multiple columns into account when - * doing a sort. For example first name / last name columns make sense to - * do a multi-column sort over the two columns. - * @type array - * @default null Takes the value of the column index automatically - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "aDataSort": [ 0, 1 ], "aTargets": [ 0 ] }, - * { "aDataSort": [ 1, 0 ], "aTargets": [ 1 ] }, - * { "aDataSort": [ 2, 3, 4 ], "aTargets": [ 2 ] } - * ] - * } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumns": [ - * { "aDataSort": [ 0, 1 ] }, - * { "aDataSort": [ 1, 0 ] }, - * { "aDataSort": [ 2, 3, 4 ] }, - * null, - * null - * ] - * } ); - * } ); - */ - "aDataSort": null, - - - /** - * You can control the default sorting direction, and even alter the behaviour - * of the sort handler (i.e. only allow ascending sorting etc) using this - * parameter. - * @type array - * @default [ 'asc', 'desc' ] - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "asSorting": [ "asc" ], "aTargets": [ 1 ] }, - * { "asSorting": [ "desc", "asc", "asc" ], "aTargets": [ 2 ] }, - * { "asSorting": [ "desc" ], "aTargets": [ 3 ] } - * ] - * } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumns": [ - * null, - * { "asSorting": [ "asc" ] }, - * { "asSorting": [ "desc", "asc", "asc" ] }, - * { "asSorting": [ "desc" ] }, - * null - * ] - * } ); - * } ); - */ - "asSorting": [ 'asc', 'desc' ], - - - /** - * Enable or disable filtering on the data in this column. - * @type boolean - * @default true - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "bSearchable": false, "aTargets": [ 0 ] } - * ] } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumns": [ - * { "bSearchable": false }, - * null, - * null, - * null, - * null - * ] } ); - * } ); - */ - "bSearchable": true, - - - /** - * Enable or disable sorting on this column. - * @type boolean - * @default true - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "bSortable": false, "aTargets": [ 0 ] } - * ] } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumns": [ - * { "bSortable": false }, - * null, - * null, - * null, - * null - * ] } ); - * } ); - */ - "bSortable": true, - - - /** - * Deprecated When using fnRender() for a column, you may wish - * to use the original data (before rendering) for sorting and filtering - * (the default is to used the rendered data that the user can see). This - * may be useful for dates etc. - * - * Please note that this option has now been deprecated and will be removed - * in the next version of DataTables. Please use mRender / mData rather than - * fnRender. - * @type boolean - * @default true - * @dtopt Columns - * @deprecated - */ - "bUseRendered": true, - - - /** - * Enable or disable the display of this column. - * @type boolean - * @default true - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "bVisible": false, "aTargets": [ 0 ] } - * ] } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumns": [ - * { "bVisible": false }, - * null, - * null, - * null, - * null - * ] } ); - * } ); - */ - "bVisible": true, - - - /** - * Developer definable function that is called whenever a cell is created (Ajax source, - * etc) or processed for input (DOM source). This can be used as a compliment to mRender - * allowing you to modify the DOM element (add background colour for example) when the - * element is available. - * @type function - * @param {element} nTd The TD node that has been created - * @param {*} sData The Data for the cell - * @param {array|object} oData The data for the whole row - * @param {int} iRow The row index for the aoData data store - * @param {int} iCol The column index for aoColumns - * @dtopt Columns - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ { - * "aTargets": [3], - * "fnCreatedCell": function (nTd, sData, oData, iRow, iCol) { - * if ( sData == "1.7" ) { - * $(nTd).css('color', 'blue') - * } - * } - * } ] - * }); - * } ); - */ - "fnCreatedCell": null, - - - /** - * Deprecated Custom display function that will be called for the - * display of each cell in this column. - * - * Please note that this option has now been deprecated and will be removed - * in the next version of DataTables. Please use mRender / mData rather than - * fnRender. - * @type function - * @param {object} o Object with the following parameters: - * @param {int} o.iDataRow The row in aoData - * @param {int} o.iDataColumn The column in question - * @param {array} o.aData The data for the row in question - * @param {object} o.oSettings The settings object for this DataTables instance - * @param {object} o.mDataProp The data property used for this column - * @param {*} val The current cell value - * @returns {string} The string you which to use in the display - * @dtopt Columns - * @deprecated - */ - "fnRender": null, - - - /** - * The column index (starting from 0!) that you wish a sort to be performed - * upon when this column is selected for sorting. This can be used for sorting - * on hidden columns for example. - * @type int - * @default -1 Use automatically calculated column index - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "iDataSort": 1, "aTargets": [ 0 ] } - * ] - * } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumns": [ - * { "iDataSort": 1 }, - * null, - * null, - * null, - * null - * ] - * } ); - * } ); - */ - "iDataSort": -1, - - - /** - * This parameter has been replaced by mData in DataTables to ensure naming - * consistency. mDataProp can still be used, as there is backwards compatibility - * in DataTables for this option, but it is strongly recommended that you use - * mData in preference to mDataProp. - * @name DataTable.defaults.columns.mDataProp - */ - - - /** - * This property can be used to read data from any JSON data source property, - * including deeply nested objects / properties. mData can be given in a - * number of different ways which effect its behaviour: - *
      - *
    • integer - treated as an array index for the data source. This is the - * default that DataTables uses (incrementally increased for each column).
    • - *
    • string - read an object property from the data source. Note that you can - * use Javascript dotted notation to read deep properties / arrays from the - * data source.
    • - *
    • null - the sDefaultContent option will be used for the cell (null - * by default, so you will need to specify the default content you want - - * typically an empty string). This can be useful on generated columns such - * as edit / delete action columns.
    • - *
    • function - the function given will be executed whenever DataTables - * needs to set or get the data for a cell in the column. The function - * takes three parameters: - *
        - *
      • {array|object} The data source for the row
      • - *
      • {string} The type call data requested - this will be 'set' when - * setting data or 'filter', 'display', 'type', 'sort' or undefined when - * gathering data. Note that when undefined is given for the type - * DataTables expects to get the raw data for the object back
      • - *
      • {*} Data to set when the second parameter is 'set'.
      • - *
      - * The return value from the function is not required when 'set' is the type - * of call, but otherwise the return is what will be used for the data - * requested.
    • - *
    - * - * Note that prior to DataTables 1.9.2 mData was called mDataProp. The name change - * reflects the flexibility of this property and is consistent with the naming of - * mRender. If 'mDataProp' is given, then it will still be used by DataTables, as - * it automatically maps the old name to the new if required. - * @type string|int|function|null - * @default null Use automatically calculated column index - * @dtopt Columns - * - * @example - * // Read table data from objects - * $(document).ready( function() { - * var oTable = $('#example').dataTable( { - * "sAjaxSource": "sources/deep.txt", - * "aoColumns": [ - * { "mData": "engine" }, - * { "mData": "browser" }, - * { "mData": "platform.inner" }, - * { "mData": "platform.details.0" }, - * { "mData": "platform.details.1" } - * ] - * } ); - * } ); - * - * @example - * // Using mData as a function to provide different information for - * // sorting, filtering and display. In this case, currency (price) - * $(document).ready( function() { - * var oTable = $('#example').dataTable( { - * "aoColumnDefs": [ { - * "aTargets": [ 0 ], - * "mData": function ( source, type, val ) { - * if (type === 'set') { - * source.price = val; - * // Store the computed dislay and filter values for efficiency - * source.price_display = val=="" ? "" : "$"+numberFormat(val); - * source.price_filter = val=="" ? "" : "$"+numberFormat(val)+" "+val; - * return; - * } - * else if (type === 'display') { - * return source.price_display; - * } - * else if (type === 'filter') { - * return source.price_filter; - * } - * // 'sort', 'type' and undefined all just use the integer - * return source.price; - * } - * } ] - * } ); - * } ); - */ - "mData": null, - - - /** - * This property is the rendering partner to mData and it is suggested that - * when you want to manipulate data for display (including filtering, sorting etc) - * but not altering the underlying data for the table, use this property. mData - * can actually do everything this property can and more, but this parameter is - * easier to use since there is no 'set' option. Like mData is can be given - * in a number of different ways to effect its behaviour, with the addition of - * supporting array syntax for easy outputting of arrays (including arrays of - * objects): - *
      - *
    • integer - treated as an array index for the data source. This is the - * default that DataTables uses (incrementally increased for each column).
    • - *
    • string - read an object property from the data source. Note that you can - * use Javascript dotted notation to read deep properties / arrays from the - * data source and also array brackets to indicate that the data reader should - * loop over the data source array. When characters are given between the array - * brackets, these characters are used to join the data source array together. - * For example: "accounts[, ].name" would result in a comma separated list with - * the 'name' value from the 'accounts' array of objects.
    • - *
    • function - the function given will be executed whenever DataTables - * needs to set or get the data for a cell in the column. The function - * takes three parameters: - *
        - *
      • {array|object} The data source for the row (based on mData)
      • - *
      • {string} The type call data requested - this will be 'filter', 'display', - * 'type' or 'sort'.
      • - *
      • {array|object} The full data source for the row (not based on mData)
      • - *
      - * The return value from the function is what will be used for the data - * requested.
    • - *
    - * @type string|int|function|null - * @default null Use mData - * @dtopt Columns - * - * @example - * // Create a comma separated list from an array of objects - * $(document).ready( function() { - * var oTable = $('#example').dataTable( { - * "sAjaxSource": "sources/deep.txt", - * "aoColumns": [ - * { "mData": "engine" }, - * { "mData": "browser" }, - * { - * "mData": "platform", - * "mRender": "[, ].name" - * } - * ] - * } ); - * } ); - * - * @example - * // Use as a function to create a link from the data source - * $(document).ready( function() { - * var oTable = $('#example').dataTable( { - * "aoColumnDefs": [ - * { - * "aTargets": [ 0 ], - * "mData": "download_link", - * "mRender": function ( data, type, full ) { - * return 'Download'; - * } - * ] - * } ); - * } ); - */ - "mRender": null, - - - /** - * Change the cell type created for the column - either TD cells or TH cells. This - * can be useful as TH cells have semantic meaning in the table body, allowing them - * to act as a header for a row (you may wish to add scope='row' to the TH elements). - * @type string - * @default td - * @dtopt Columns - * - * @example - * // Make the first column use TH cells - * $(document).ready( function() { - * var oTable = $('#example').dataTable( { - * "aoColumnDefs": [ { - * "aTargets": [ 0 ], - * "sCellType": "th" - * } ] - * } ); - * } ); - */ - "sCellType": "td", - - - /** - * Class to give to each cell in this column. - * @type string - * @default Empty string - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "sClass": "my_class", "aTargets": [ 0 ] } - * ] - * } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumns": [ - * { "sClass": "my_class" }, - * null, - * null, - * null, - * null - * ] - * } ); - * } ); - */ - "sClass": "", - - /** - * When DataTables calculates the column widths to assign to each column, - * it finds the longest string in each column and then constructs a - * temporary table and reads the widths from that. The problem with this - * is that "mmm" is much wider then "iiii", but the latter is a longer - * string - thus the calculation can go wrong (doing it properly and putting - * it into an DOM object and measuring that is horribly(!) slow). Thus as - * a "work around" we provide this option. It will append its value to the - * text that is found to be the longest string for the column - i.e. padding. - * Generally you shouldn't need this, and it is not documented on the - * general DataTables.net documentation - * @type string - * @default Empty string - * @dtopt Columns - * - * @example - * // Using aoColumns - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumns": [ - * null, - * null, - * null, - * { - * "sContentPadding": "mmm" - * } - * ] - * } ); - * } ); - */ - "sContentPadding": "", - - - /** - * Allows a default value to be given for a column's data, and will be used - * whenever a null data source is encountered (this can be because mData - * is set to null, or because the data source itself is null). - * @type string - * @default null - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { - * "mData": null, - * "sDefaultContent": "Edit", - * "aTargets": [ -1 ] - * } - * ] - * } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumns": [ - * null, - * null, - * null, - * { - * "mData": null, - * "sDefaultContent": "Edit" - * } - * ] - * } ); - * } ); - */ - "sDefaultContent": null, - - - /** - * This parameter is only used in DataTables' server-side processing. It can - * be exceptionally useful to know what columns are being displayed on the - * client side, and to map these to database fields. When defined, the names - * also allow DataTables to reorder information from the server if it comes - * back in an unexpected order (i.e. if you switch your columns around on the - * client-side, your server-side code does not also need updating). - * @type string - * @default Empty string - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "sName": "engine", "aTargets": [ 0 ] }, - * { "sName": "browser", "aTargets": [ 1 ] }, - * { "sName": "platform", "aTargets": [ 2 ] }, - * { "sName": "version", "aTargets": [ 3 ] }, - * { "sName": "grade", "aTargets": [ 4 ] } - * ] - * } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumns": [ - * { "sName": "engine" }, - * { "sName": "browser" }, - * { "sName": "platform" }, - * { "sName": "version" }, - * { "sName": "grade" } - * ] - * } ); - * } ); - */ - "sName": "", - - - /** - * Defines a data source type for the sorting which can be used to read - * real-time information from the table (updating the internally cached - * version) prior to sorting. This allows sorting to occur on user editable - * elements such as form inputs. - * @type string - * @default std - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "sSortDataType": "dom-text", "aTargets": [ 2, 3 ] }, - * { "sType": "numeric", "aTargets": [ 3 ] }, - * { "sSortDataType": "dom-select", "aTargets": [ 4 ] }, - * { "sSortDataType": "dom-checkbox", "aTargets": [ 5 ] } - * ] - * } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumns": [ - * null, - * null, - * { "sSortDataType": "dom-text" }, - * { "sSortDataType": "dom-text", "sType": "numeric" }, - * { "sSortDataType": "dom-select" }, - * { "sSortDataType": "dom-checkbox" } - * ] - * } ); - * } ); - */ - "sSortDataType": "std", - - - /** - * The title of this column. - * @type string - * @default null Derived from the 'TH' value for this column in the - * original HTML table. - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "sTitle": "My column title", "aTargets": [ 0 ] } - * ] - * } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumns": [ - * { "sTitle": "My column title" }, - * null, - * null, - * null, - * null - * ] - * } ); - * } ); - */ - "sTitle": null, - - - /** - * The type allows you to specify how the data for this column will be sorted. - * Four types (string, numeric, date and html (which will strip HTML tags - * before sorting)) are currently available. Note that only date formats - * understood by Javascript's Date() object will be accepted as type date. For - * example: "Mar 26, 2008 5:03 PM". May take the values: 'string', 'numeric', - * 'date' or 'html' (by default). Further types can be adding through - * plug-ins. - * @type string - * @default null Auto-detected from raw data - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "sType": "html", "aTargets": [ 0 ] } - * ] - * } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumns": [ - * { "sType": "html" }, - * null, - * null, - * null, - * null - * ] - * } ); - * } ); - */ - "sType": null, - - - /** - * Defining the width of the column, this parameter may take any CSS value - * (3em, 20px etc). DataTables apples 'smart' widths to columns which have not - * been given a specific width through this interface ensuring that the table - * remains readable. - * @type string - * @default null Automatic - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "sWidth": "20%", "aTargets": [ 0 ] } - * ] - * } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoColumns": [ - * { "sWidth": "20%" }, - * null, - * null, - * null, - * null - * ] - * } ); - * } ); - */ - "sWidth": null - }; - - - - /** - * DataTables settings object - this holds all the information needed for a - * given table, including configuration, data and current application of the - * table options. DataTables does not have a single instance for each DataTable - * with the settings attached to that instance, but rather instances of the - * DataTable "class" are created on-the-fly as needed (typically by a - * $().dataTable() call) and the settings object is then applied to that - * instance. - * - * Note that this object is related to {@link DataTable.defaults} but this - * one is the internal data store for DataTables's cache of columns. It should - * NOT be manipulated outside of DataTables. Any configuration should be done - * through the initialisation options. - * @namespace - * @todo Really should attach the settings object to individual instances so we - * don't need to create new instances on each $().dataTable() call (if the - * table already exists). It would also save passing oSettings around and - * into every single function. However, this is a very significant - * architecture change for DataTables and will almost certainly break - * backwards compatibility with older installations. This is something that - * will be done in 2.0. - */ - DataTable.models.oSettings = { - /** - * Primary features of DataTables and their enablement state. - * @namespace - */ - "oFeatures": { - - /** - * Flag to say if DataTables should automatically try to calculate the - * optimum table and columns widths (true) or not (false). - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bAutoWidth": null, - - /** - * Delay the creation of TR and TD elements until they are actually - * needed by a driven page draw. This can give a significant speed - * increase for Ajax source and Javascript source data, but makes no - * difference at all fro DOM and server-side processing tables. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bDeferRender": null, - - /** - * Enable filtering on the table or not. Note that if this is disabled - * then there is no filtering at all on the table, including fnFilter. - * To just remove the filtering input use sDom and remove the 'f' option. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bFilter": null, - - /** - * Table information element (the 'Showing x of y records' div) enable - * flag. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bInfo": null, - - /** - * Present a user control allowing the end user to change the page size - * when pagination is enabled. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bLengthChange": null, - - /** - * Pagination enabled or not. Note that if this is disabled then length - * changing must also be disabled. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bPaginate": null, - - /** - * Processing indicator enable flag whenever DataTables is enacting a - * user request - typically an Ajax request for server-side processing. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bProcessing": null, - - /** - * Server-side processing enabled flag - when enabled DataTables will - * get all data from the server for every draw - there is no filtering, - * sorting or paging done on the client-side. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bServerSide": null, - - /** - * Sorting enablement flag. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bSort": null, - - /** - * Apply a class to the columns which are being sorted to provide a - * visual highlight or not. This can slow things down when enabled since - * there is a lot of DOM interaction. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bSortClasses": null, - - /** - * State saving enablement flag. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bStateSave": null - }, - - - /** - * Scrolling settings for a table. - * @namespace - */ - "oScroll": { - /** - * Indicate if DataTables should be allowed to set the padding / margin - * etc for the scrolling header elements or not. Typically you will want - * this. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bAutoCss": null, - - /** - * When the table is shorter in height than sScrollY, collapse the - * table container down to the height of the table (when true). - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bCollapse": null, - - /** - * Infinite scrolling enablement flag. Now deprecated in favour of - * using the Scroller plug-in. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bInfinite": null, - - /** - * Width of the scrollbar for the web-browser's platform. Calculated - * during table initialisation. - * @type int - * @default 0 - */ - "iBarWidth": 0, - - /** - * Space (in pixels) between the bottom of the scrolling container and - * the bottom of the scrolling viewport before the next page is loaded - * when using infinite scrolling. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type int - */ - "iLoadGap": null, - - /** - * Viewport width for horizontal scrolling. Horizontal scrolling is - * disabled if an empty string. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type string - */ - "sX": null, - - /** - * Width to expand the table to when using x-scrolling. Typically you - * should not need to use this. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type string - * @deprecated - */ - "sXInner": null, - - /** - * Viewport height for vertical scrolling. Vertical scrolling is disabled - * if an empty string. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type string - */ - "sY": null - }, - - /** - * Language information for the table. - * @namespace - * @extends DataTable.defaults.oLanguage - */ - "oLanguage": { - /** - * Information callback function. See - * {@link DataTable.defaults.fnInfoCallback} - * @type function - * @default null - */ - "fnInfoCallback": null - }, - - /** - * Browser support parameters - * @namespace - */ - "oBrowser": { - /** - * Indicate if the browser incorrectly calculates width:100% inside a - * scrolling element (IE6/7) - * @type boolean - * @default false - */ - "bScrollOversize": false - }, - - /** - * Array referencing the nodes which are used for the features. The - * parameters of this object match what is allowed by sDom - i.e. - *
      - *
    • 'l' - Length changing
    • - *
    • 'f' - Filtering input
    • - *
    • 't' - The table!
    • - *
    • 'i' - Information
    • - *
    • 'p' - Pagination
    • - *
    • 'r' - pRocessing
    • - *
    - * @type array - * @default [] - */ - "aanFeatures": [], - - /** - * Store data information - see {@link DataTable.models.oRow} for detailed - * information. - * @type array - * @default [] - */ - "aoData": [], - - /** - * Array of indexes which are in the current display (after filtering etc) - * @type array - * @default [] - */ - "aiDisplay": [], - - /** - * Array of indexes for display - no filtering - * @type array - * @default [] - */ - "aiDisplayMaster": [], - - /** - * Store information about each column that is in use - * @type array - * @default [] - */ - "aoColumns": [], - - /** - * Store information about the table's header - * @type array - * @default [] - */ - "aoHeader": [], - - /** - * Store information about the table's footer - * @type array - * @default [] - */ - "aoFooter": [], - - /** - * Search data array for regular expression searching - * @type array - * @default [] - */ - "asDataSearch": [], - - /** - * Store the applied global search information in case we want to force a - * research or compare the old search to a new one. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @namespace - * @extends DataTable.models.oSearch - */ - "oPreviousSearch": {}, - - /** - * Store the applied search for each column - see - * {@link DataTable.models.oSearch} for the format that is used for the - * filtering information for each column. - * @type array - * @default [] - */ - "aoPreSearchCols": [], - - /** - * Sorting that is applied to the table. Note that the inner arrays are - * used in the following manner: - *
      - *
    • Index 0 - column number
    • - *
    • Index 1 - current sorting direction
    • - *
    • Index 2 - index of asSorting for this column
    • - *
    - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type array - * @todo These inner arrays should really be objects - */ - "aaSorting": null, - - /** - * Sorting that is always applied to the table (i.e. prefixed in front of - * aaSorting). - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type array|null - * @default null - */ - "aaSortingFixed": null, - - /** - * Classes to use for the striping of a table. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type array - * @default [] - */ - "asStripeClasses": null, - - /** - * If restoring a table - we should restore its striping classes as well - * @type array - * @default [] - */ - "asDestroyStripes": [], - - /** - * If restoring a table - we should restore its width - * @type int - * @default 0 - */ - "sDestroyWidth": 0, - - /** - * Callback functions array for every time a row is inserted (i.e. on a draw). - * @type array - * @default [] - */ - "aoRowCallback": [], - - /** - * Callback functions for the header on each draw. - * @type array - * @default [] - */ - "aoHeaderCallback": [], - - /** - * Callback function for the footer on each draw. - * @type array - * @default [] - */ - "aoFooterCallback": [], - - /** - * Array of callback functions for draw callback functions - * @type array - * @default [] - */ - "aoDrawCallback": [], - - /** - * Array of callback functions for row created function - * @type array - * @default [] - */ - "aoRowCreatedCallback": [], - - /** - * Callback functions for just before the table is redrawn. A return of - * false will be used to cancel the draw. - * @type array - * @default [] - */ - "aoPreDrawCallback": [], - - /** - * Callback functions for when the table has been initialised. - * @type array - * @default [] - */ - "aoInitComplete": [], - - - /** - * Callbacks for modifying the settings to be stored for state saving, prior to - * saving state. - * @type array - * @default [] - */ - "aoStateSaveParams": [], - - /** - * Callbacks for modifying the settings that have been stored for state saving - * prior to using the stored values to restore the state. - * @type array - * @default [] - */ - "aoStateLoadParams": [], - - /** - * Callbacks for operating on the settings object once the saved state has been - * loaded - * @type array - * @default [] - */ - "aoStateLoaded": [], - - /** - * Cache the table ID for quick access - * @type string - * @default Empty string - */ - "sTableId": "", - - /** - * The TABLE node for the main table - * @type node - * @default null - */ - "nTable": null, - - /** - * Permanent ref to the thead element - * @type node - * @default null - */ - "nTHead": null, - - /** - * Permanent ref to the tfoot element - if it exists - * @type node - * @default null - */ - "nTFoot": null, - - /** - * Permanent ref to the tbody element - * @type node - * @default null - */ - "nTBody": null, - - /** - * Cache the wrapper node (contains all DataTables controlled elements) - * @type node - * @default null - */ - "nTableWrapper": null, - - /** - * Indicate if when using server-side processing the loading of data - * should be deferred until the second draw. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - * @default false - */ - "bDeferLoading": false, - - /** - * Indicate if all required information has been read in - * @type boolean - * @default false - */ - "bInitialised": false, - - /** - * Information about open rows. Each object in the array has the parameters - * 'nTr' and 'nParent' - * @type array - * @default [] - */ - "aoOpenRows": [], - - /** - * Dictate the positioning of DataTables' control elements - see - * {@link DataTable.model.oInit.sDom}. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type string - * @default null - */ - "sDom": null, - - /** - * Which type of pagination should be used. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type string - * @default two_button - */ - "sPaginationType": "two_button", - - /** - * The cookie duration (for bStateSave) in seconds. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type int - * @default 0 - */ - "iCookieDuration": 0, - - /** - * The cookie name prefix. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type string - * @default Empty string - */ - "sCookiePrefix": "", - - /** - * Callback function for cookie creation. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type function - * @default null - */ - "fnCookieCallback": null, - - /** - * Array of callback functions for state saving. Each array element is an - * object with the following parameters: - *
      - *
    • function:fn - function to call. Takes two parameters, oSettings - * and the JSON string to save that has been thus far created. Returns - * a JSON string to be inserted into a json object - * (i.e. '"param": [ 0, 1, 2]')
    • - *
    • string:sName - name of callback
    • - *
    - * @type array - * @default [] - */ - "aoStateSave": [], - - /** - * Array of callback functions for state loading. Each array element is an - * object with the following parameters: - *
      - *
    • function:fn - function to call. Takes two parameters, oSettings - * and the object stored. May return false to cancel state loading
    • - *
    • string:sName - name of callback
    • - *
    - * @type array - * @default [] - */ - "aoStateLoad": [], - - /** - * State that was loaded from the cookie. Useful for back reference - * @type object - * @default null - */ - "oLoadedState": null, - - /** - * Source url for AJAX data for the table. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type string - * @default null - */ - "sAjaxSource": null, - - /** - * Property from a given object from which to read the table data from. This - * can be an empty string (when not server-side processing), in which case - * it is assumed an an array is given directly. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type string - */ - "sAjaxDataProp": null, - - /** - * Note if draw should be blocked while getting data - * @type boolean - * @default true - */ - "bAjaxDataGet": true, - - /** - * The last jQuery XHR object that was used for server-side data gathering. - * This can be used for working with the XHR information in one of the - * callbacks - * @type object - * @default null - */ - "jqXHR": null, - - /** - * Function to get the server-side data. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type function - */ - "fnServerData": null, - - /** - * Functions which are called prior to sending an Ajax request so extra - * parameters can easily be sent to the server - * @type array - * @default [] - */ - "aoServerParams": [], - - /** - * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if - * required). - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type string - */ - "sServerMethod": null, - - /** - * Format numbers for display. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type function - */ - "fnFormatNumber": null, - - /** - * List of options that can be used for the user selectable length menu. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type array - * @default [] - */ - "aLengthMenu": null, - - /** - * Counter for the draws that the table does. Also used as a tracker for - * server-side processing - * @type int - * @default 0 - */ - "iDraw": 0, - - /** - * Indicate if a redraw is being done - useful for Ajax - * @type boolean - * @default false - */ - "bDrawing": false, - - /** - * Draw index (iDraw) of the last error when parsing the returned data - * @type int - * @default -1 - */ - "iDrawError": -1, - - /** - * Paging display length - * @type int - * @default 10 - */ - "_iDisplayLength": 10, - - /** - * Paging start point - aiDisplay index - * @type int - * @default 0 - */ - "_iDisplayStart": 0, - - /** - * Paging end point - aiDisplay index. Use fnDisplayEnd rather than - * this property to get the end point - * @type int - * @default 10 - * @private - */ - "_iDisplayEnd": 10, - - /** - * Server-side processing - number of records in the result set - * (i.e. before filtering), Use fnRecordsTotal rather than - * this property to get the value of the number of records, regardless of - * the server-side processing setting. - * @type int - * @default 0 - * @private - */ - "_iRecordsTotal": 0, - - /** - * Server-side processing - number of records in the current display set - * (i.e. after filtering). Use fnRecordsDisplay rather than - * this property to get the value of the number of records, regardless of - * the server-side processing setting. - * @type boolean - * @default 0 - * @private - */ - "_iRecordsDisplay": 0, - - /** - * Flag to indicate if jQuery UI marking and classes should be used. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bJUI": null, - - /** - * The classes to use for the table - * @type object - * @default {} - */ - "oClasses": {}, - - /** - * Flag attached to the settings object so you can check in the draw - * callback if filtering has been done in the draw. Deprecated in favour of - * events. - * @type boolean - * @default false - * @deprecated - */ - "bFiltered": false, - - /** - * Flag attached to the settings object so you can check in the draw - * callback if sorting has been done in the draw. Deprecated in favour of - * events. - * @type boolean - * @default false - * @deprecated - */ - "bSorted": false, - - /** - * Indicate that if multiple rows are in the header and there is more than - * one unique cell per column, if the top one (true) or bottom one (false) - * should be used for sorting / title by DataTables. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bSortCellsTop": null, - - /** - * Initialisation object that is used for the table - * @type object - * @default null - */ - "oInit": null, - - /** - * Destroy callback functions - for plug-ins to attach themselves to the - * destroy so they can clean up markup and events. - * @type array - * @default [] - */ - "aoDestroyCallback": [], - - - /** - * Get the number of records in the current record set, before filtering - * @type function - */ - "fnRecordsTotal": function () - { - if ( this.oFeatures.bServerSide ) { - return parseInt(this._iRecordsTotal, 10); - } else { - return this.aiDisplayMaster.length; - } - }, - - /** - * Get the number of records in the current record set, after filtering - * @type function - */ - "fnRecordsDisplay": function () - { - if ( this.oFeatures.bServerSide ) { - return parseInt(this._iRecordsDisplay, 10); - } else { - return this.aiDisplay.length; - } - }, - - /** - * Set the display end point - aiDisplay index - * @type function - * @todo Should do away with _iDisplayEnd and calculate it on-the-fly here - */ - "fnDisplayEnd": function () - { - if ( this.oFeatures.bServerSide ) { - if ( this.oFeatures.bPaginate === false || this._iDisplayLength == -1 ) { - return this._iDisplayStart+this.aiDisplay.length; - } else { - return Math.min( this._iDisplayStart+this._iDisplayLength, - this._iRecordsDisplay ); - } - } else { - return this._iDisplayEnd; - } - }, - - /** - * The DataTables object for this table - * @type object - * @default null - */ - "oInstance": null, - - /** - * Unique identifier for each instance of the DataTables object. If there - * is an ID on the table node, then it takes that value, otherwise an - * incrementing internal counter is used. - * @type string - * @default null - */ - "sInstance": null, - - /** - * tabindex attribute value that is added to DataTables control elements, allowing - * keyboard navigation of the table and its controls. - */ - "iTabIndex": 0, - - /** - * DIV container for the footer scrolling table if scrolling - */ - "nScrollHead": null, - - /** - * DIV container for the footer scrolling table if scrolling - */ - "nScrollFoot": null - }; - - /** - * Extension object for DataTables that is used to provide all extension options. - * - * Note that the DataTable.ext object is available through - * jQuery.fn.dataTable.ext where it may be accessed and manipulated. It is - * also aliased to jQuery.fn.dataTableExt for historic reasons. - * @namespace - * @extends DataTable.models.ext - */ - DataTable.ext = $.extend( true, {}, DataTable.models.ext ); - - $.extend( DataTable.ext.oStdClasses, { - "sTable": "dataTable", - - /* Two buttons buttons */ - "sPagePrevEnabled": "paginate_enabled_previous", - "sPagePrevDisabled": "paginate_disabled_previous", - "sPageNextEnabled": "paginate_enabled_next", - "sPageNextDisabled": "paginate_disabled_next", - "sPageJUINext": "", - "sPageJUIPrev": "", - - /* Full numbers paging buttons */ - "sPageButton": "paginate_button", - "sPageButtonActive": "paginate_active", - "sPageButtonStaticDisabled": "paginate_button paginate_button_disabled", - "sPageFirst": "first", - "sPagePrevious": "previous", - "sPageNext": "next", - "sPageLast": "last", - - /* Striping classes */ - "sStripeOdd": "odd", - "sStripeEven": "even", - - /* Empty row */ - "sRowEmpty": "dataTables_empty", - - /* Features */ - "sWrapper": "dataTables_wrapper", - "sFilter": "dataTables_filter", - "sInfo": "dataTables_info", - "sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */ - "sLength": "dataTables_length", - "sProcessing": "dataTables_processing", - - /* Sorting */ - "sSortAsc": "sorting_asc", - "sSortDesc": "sorting_desc", - "sSortable": "sorting", /* Sortable in both directions */ - "sSortableAsc": "sorting_asc_disabled", - "sSortableDesc": "sorting_desc_disabled", - "sSortableNone": "sorting_disabled", - "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */ - "sSortJUIAsc": "", - "sSortJUIDesc": "", - "sSortJUI": "", - "sSortJUIAscAllowed": "", - "sSortJUIDescAllowed": "", - "sSortJUIWrapper": "", - "sSortIcon": "", - - /* Scrolling */ - "sScrollWrapper": "dataTables_scroll", - "sScrollHead": "dataTables_scrollHead", - "sScrollHeadInner": "dataTables_scrollHeadInner", - "sScrollBody": "dataTables_scrollBody", - "sScrollFoot": "dataTables_scrollFoot", - "sScrollFootInner": "dataTables_scrollFootInner", - - /* Misc */ - "sFooterTH": "", - "sJUIHeader": "", - "sJUIFooter": "" - } ); - - - $.extend( DataTable.ext.oJUIClasses, DataTable.ext.oStdClasses, { - /* Two buttons buttons */ - "sPagePrevEnabled": "fg-button ui-button ui-state-default ui-corner-left", - "sPagePrevDisabled": "fg-button ui-button ui-state-default ui-corner-left ui-state-disabled", - "sPageNextEnabled": "fg-button ui-button ui-state-default ui-corner-right", - "sPageNextDisabled": "fg-button ui-button ui-state-default ui-corner-right ui-state-disabled", - "sPageJUINext": "ui-icon ui-icon-circle-arrow-e", - "sPageJUIPrev": "ui-icon ui-icon-circle-arrow-w", - - /* Full numbers paging buttons */ - "sPageButton": "fg-button ui-button ui-state-default", - "sPageButtonActive": "fg-button ui-button ui-state-default ui-state-disabled", - "sPageButtonStaticDisabled": "fg-button ui-button ui-state-default ui-state-disabled", - "sPageFirst": "first ui-corner-tl ui-corner-bl", - "sPageLast": "last ui-corner-tr ui-corner-br", - - /* Features */ - "sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi "+ - "ui-buttonset-multi paging_", /* Note that the type is postfixed */ - - /* Sorting */ - "sSortAsc": "ui-state-default", - "sSortDesc": "ui-state-default", - "sSortable": "ui-state-default", - "sSortableAsc": "ui-state-default", - "sSortableDesc": "ui-state-default", - "sSortableNone": "ui-state-default", - "sSortJUIAsc": "css_right ui-icon ui-icon-triangle-1-n", - "sSortJUIDesc": "css_right ui-icon ui-icon-triangle-1-s", - "sSortJUI": "css_right ui-icon ui-icon-carat-2-n-s", - "sSortJUIAscAllowed": "css_right ui-icon ui-icon-carat-1-n", - "sSortJUIDescAllowed": "css_right ui-icon ui-icon-carat-1-s", - "sSortJUIWrapper": "DataTables_sort_wrapper", - "sSortIcon": "DataTables_sort_icon", - - /* Scrolling */ - "sScrollHead": "dataTables_scrollHead ui-state-default", - "sScrollFoot": "dataTables_scrollFoot ui-state-default", - - /* Misc */ - "sFooterTH": "ui-state-default", - "sJUIHeader": "fg-toolbar ui-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix", - "sJUIFooter": "fg-toolbar ui-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix" - } ); - - /* - * Variable: oPagination - * Purpose: - * Scope: jQuery.fn.dataTableExt - */ - $.extend( DataTable.ext.oPagination, { - /* - * Variable: two_button - * Purpose: Standard two button (forward/back) pagination - * Scope: jQuery.fn.dataTableExt.oPagination - */ - "two_button": { - /* - * Function: oPagination.two_button.fnInit - * Purpose: Initialise dom elements required for pagination with forward/back buttons only - * Returns: - - * Inputs: object:oSettings - dataTables settings object - * node:nPaging - the DIV which contains this pagination control - * function:fnCallbackDraw - draw function which must be called on update - */ - "fnInit": function ( oSettings, nPaging, fnCallbackDraw ) - { - var oLang = oSettings.oLanguage.oPaginate; - var oClasses = oSettings.oClasses; - var fnClickHandler = function ( e ) { - if ( oSettings.oApi._fnPageChange( oSettings, e.data.action ) ) - { - fnCallbackDraw( oSettings ); - } - }; - - var sAppend = (!oSettings.bJUI) ? - ''+oLang.sPrevious+''+ - ''+oLang.sNext+'' - : - ''+ - ''; - $(nPaging).append( sAppend ); - - var els = $('a', nPaging); - var nPrevious = els[0], - nNext = els[1]; - - oSettings.oApi._fnBindAction( nPrevious, {action: "previous"}, fnClickHandler ); - oSettings.oApi._fnBindAction( nNext, {action: "next"}, fnClickHandler ); - - /* ID the first elements only */ - if ( !oSettings.aanFeatures.p ) - { - nPaging.id = oSettings.sTableId+'_paginate'; - nPrevious.id = oSettings.sTableId+'_previous'; - nNext.id = oSettings.sTableId+'_next'; - - nPrevious.setAttribute('aria-controls', oSettings.sTableId); - nNext.setAttribute('aria-controls', oSettings.sTableId); - } - }, - - /* - * Function: oPagination.two_button.fnUpdate - * Purpose: Update the two button pagination at the end of the draw - * Returns: - - * Inputs: object:oSettings - dataTables settings object - * function:fnCallbackDraw - draw function to call on page change - */ - "fnUpdate": function ( oSettings, fnCallbackDraw ) - { - if ( !oSettings.aanFeatures.p ) - { - return; - } - - var oClasses = oSettings.oClasses; - var an = oSettings.aanFeatures.p; - var nNode; - - /* Loop over each instance of the pager */ - for ( var i=0, iLen=an.length ; i'+oLang.sFirst+''+ - ''+oLang.sPrevious+''+ - ''+ - ''+oLang.sNext+''+ - ''+oLang.sLast+'' - ); - var els = $('a', nPaging); - var nFirst = els[0], - nPrev = els[1], - nNext = els[2], - nLast = els[3]; - - oSettings.oApi._fnBindAction( nFirst, {action: "first"}, fnClickHandler ); - oSettings.oApi._fnBindAction( nPrev, {action: "previous"}, fnClickHandler ); - oSettings.oApi._fnBindAction( nNext, {action: "next"}, fnClickHandler ); - oSettings.oApi._fnBindAction( nLast, {action: "last"}, fnClickHandler ); - - /* ID the first elements only */ - if ( !oSettings.aanFeatures.p ) - { - nPaging.id = oSettings.sTableId+'_paginate'; - nFirst.id =oSettings.sTableId+'_first'; - nPrev.id =oSettings.sTableId+'_previous'; - nNext.id =oSettings.sTableId+'_next'; - nLast.id =oSettings.sTableId+'_last'; - } - }, - - /* - * Function: oPagination.full_numbers.fnUpdate - * Purpose: Update the list of page buttons shows - * Returns: - - * Inputs: object:oSettings - dataTables settings object - * function:fnCallbackDraw - draw function to call on page change - */ - "fnUpdate": function ( oSettings, fnCallbackDraw ) - { - if ( !oSettings.aanFeatures.p ) - { - return; - } - - var iPageCount = DataTable.ext.oPagination.iFullNumbersShowPages; - var iPageCountHalf = Math.floor(iPageCount / 2); - var iPages = Math.ceil((oSettings.fnRecordsDisplay()) / oSettings._iDisplayLength); - var iCurrentPage = Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength) + 1; - var sList = ""; - var iStartButton, iEndButton, i, iLen; - var oClasses = oSettings.oClasses; - var anButtons, anStatic, nPaginateList, nNode; - var an = oSettings.aanFeatures.p; - var fnBind = function (j) { - oSettings.oApi._fnBindAction( this, {"page": j+iStartButton-1}, function(e) { - /* Use the information in the element to jump to the required page */ - oSettings.oApi._fnPageChange( oSettings, e.data.page ); - fnCallbackDraw( oSettings ); - e.preventDefault(); - } ); - }; - - /* Pages calculation */ - if ( oSettings._iDisplayLength === -1 ) - { - iStartButton = 1; - iEndButton = 1; - iCurrentPage = 1; - } - else if (iPages < iPageCount) - { - iStartButton = 1; - iEndButton = iPages; - } - else if (iCurrentPage <= iPageCountHalf) - { - iStartButton = 1; - iEndButton = iPageCount; - } - else if (iCurrentPage >= (iPages - iPageCountHalf)) - { - iStartButton = iPages - iPageCount + 1; - iEndButton = iPages; - } - else - { - iStartButton = iCurrentPage - Math.ceil(iPageCount / 2) + 1; - iEndButton = iStartButton + iPageCount - 1; - } - - - /* Build the dynamic list */ - for ( i=iStartButton ; i<=iEndButton ; i++ ) - { - sList += (iCurrentPage !== i) ? - ''+oSettings.fnFormatNumber(i)+'' : - ''+oSettings.fnFormatNumber(i)+''; - } - - /* Loop over each instance of the pager */ - for ( i=0, iLen=an.length ; i y) ? 1 : 0)); - }, - - "string-desc": function ( x, y ) - { - return ((x < y) ? 1 : ((x > y) ? -1 : 0)); - }, - - - /* - * html sorting (ignore html tags) - */ - "html-pre": function ( a ) - { - return a.replace( /<.*?>/g, "" ).toLowerCase(); - }, - - "html-asc": function ( x, y ) - { - return ((x < y) ? -1 : ((x > y) ? 1 : 0)); - }, - - "html-desc": function ( x, y ) - { - return ((x < y) ? 1 : ((x > y) ? -1 : 0)); - }, - - - /* - * date sorting - */ - "date-pre": function ( a ) - { - var x = Date.parse( a ); - - if ( isNaN(x) || x==="" ) - { - x = Date.parse( "01/01/1970 00:00:00" ); - } - return x; - }, - - "date-asc": function ( x, y ) - { - return x - y; - }, - - "date-desc": function ( x, y ) - { - return y - x; - }, - - - /* - * numerical sorting - */ - "numeric-pre": function ( a ) - { - return (a=="-" || a==="") ? 0 : a*1; - }, - - "numeric-asc": function ( x, y ) - { - return x - y; - }, - - "numeric-desc": function ( x, y ) - { - return y - x; - } - } ); - - - $.extend( DataTable.ext.aTypes, [ - /* - * Function: - - * Purpose: Check to see if a string is numeric - * Returns: string:'numeric' or null - * Inputs: mixed:sText - string to check - */ - function ( sData ) - { - /* Allow zero length strings as a number */ - if ( typeof sData === 'number' ) - { - return 'numeric'; - } - else if ( typeof sData !== 'string' ) - { - return null; - } - - var sValidFirstChars = "0123456789-"; - var sValidChars = "0123456789."; - var Char; - var bDecimal = false; - - /* Check for a valid first char (no period and allow negatives) */ - Char = sData.charAt(0); - if (sValidFirstChars.indexOf(Char) == -1) - { - return null; - } - - /* Check all the other characters are valid */ - for ( var i=1 ; i') != -1 ) - { - return 'html'; - } - return null; - } - ] ); - - - // jQuery aliases - $.fn.DataTable = DataTable; - $.fn.dataTable = DataTable; - $.fn.dataTableSettings = DataTable.settings; - $.fn.dataTableExt = DataTable.ext; - - - // Information about events fired by DataTables - for documentation. - /** - * Draw event, fired whenever the table is redrawn on the page, at the same point as - * fnDrawCallback. This may be useful for binding events or performing calculations when - * the table is altered at all. - * @name DataTable#draw - * @event - * @param {event} e jQuery event object - * @param {object} o DataTables settings object {@link DataTable.models.oSettings} - */ - - /** - * Filter event, fired when the filtering applied to the table (using the build in global - * global filter, or column filters) is altered. - * @name DataTable#filter - * @event - * @param {event} e jQuery event object - * @param {object} o DataTables settings object {@link DataTable.models.oSettings} - */ - - /** - * Page change event, fired when the paging of the table is altered. - * @name DataTable#page - * @event - * @param {event} e jQuery event object - * @param {object} o DataTables settings object {@link DataTable.models.oSettings} - */ - - /** - * Sort event, fired when the sorting applied to the table is altered. - * @name DataTable#sort - * @event - * @param {event} e jQuery event object - * @param {object} o DataTables settings object {@link DataTable.models.oSettings} - */ - - /** - * DataTables initialisation complete event, fired when the table is fully drawn, - * including Ajax data loaded, if Ajax data is required. - * @name DataTable#init - * @event - * @param {event} e jQuery event object - * @param {object} oSettings DataTables settings object - * @param {object} json The JSON object request from the server - only - * present if client-side Ajax sourced data is used
  • - */ - - /** - * State save event, fired when the table has changed state a new state save is required. - * This method allows modification of the state saving object prior to actually doing the - * save, including addition or other state properties (for plug-ins) or modification - * of a DataTables core property. - * @name DataTable#stateSaveParams - * @event - * @param {event} e jQuery event object - * @param {object} oSettings DataTables settings object - * @param {object} json The state information to be saved - */ - - /** - * State load event, fired when the table is loading state from the stored data, but - * prior to the settings object being modified by the saved state - allowing modification - * of the saved state is required or loading of state for a plug-in. - * @name DataTable#stateLoadParams - * @event - * @param {event} e jQuery event object - * @param {object} oSettings DataTables settings object - * @param {object} json The saved state information - */ - - /** - * State loaded event, fired when state has been loaded from stored data and the settings - * object has been modified by the loaded data. - * @name DataTable#stateLoaded - * @event - * @param {event} e jQuery event object - * @param {object} oSettings DataTables settings object - * @param {object} json The saved state information - */ - - /** - * Processing event, fired when DataTables is doing some kind of processing (be it, - * sort, filter or anything else). Can be used to indicate to the end user that - * there is something happening, or that something has finished. - * @name DataTable#processing - * @event - * @param {event} e jQuery event object - * @param {object} oSettings DataTables settings object - * @param {boolean} bShow Flag for if DataTables is doing processing or not - */ - - /** - * Ajax (XHR) event, fired whenever an Ajax request is completed from a request to - * made to the server for new data (note that this trigger is called in fnServerData, - * if you override fnServerData and which to use this event, you need to trigger it in - * you success function). - * @name DataTable#xhr - * @event - * @param {event} e jQuery event object - * @param {object} o DataTables settings object {@link DataTable.models.oSettings} - * @param {object} json JSON returned from the server - */ - - /** - * Destroy event, fired when the DataTable is destroyed by calling fnDestroy or passing - * the bDestroy:true parameter in the initialisation object. This can be used to remove - * bound events, added DOM nodes, etc. - * @name DataTable#destroy - * @event - * @param {event} e jQuery event object - * @param {object} o DataTables settings object {@link DataTable.models.oSettings} - */ -})); - -}(window, document)); - diff --git a/htdocs/includes/jquery/plugins/datatables/js/jquery.dataTables.min.js b/htdocs/includes/jquery/plugins/datatables/js/jquery.dataTables.min.js deleted file mode 100644 index 02694a4a56e..00000000000 --- a/htdocs/includes/jquery/plugins/datatables/js/jquery.dataTables.min.js +++ /dev/null @@ -1,155 +0,0 @@ -/* - * File: jquery.dataTables.min.js - * Version: 1.9.4 - * Author: Allan Jardine (www.sprymedia.co.uk) - * Info: www.datatables.net - * - * Copyright 2008-2012 Allan Jardine, all rights reserved. - * - * This source file is free software, under either the GPL v2 license or a - * BSD style license, available at: - * http://datatables.net/license_gpl2 - * http://datatables.net/license_bsd - * - * This source file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. - */ -(function(X,l,n){var L=function(h){var j=function(e){function o(a,b){var c=j.defaults.columns,d=a.aoColumns.length,c=h.extend({},j.models.oColumn,c,{sSortingClass:a.oClasses.sSortable,sSortingClassJUI:a.oClasses.sSortJUI,nTh:b?b:l.createElement("th"),sTitle:c.sTitle?c.sTitle:b?b.innerHTML:"",aDataSort:c.aDataSort?c.aDataSort:[d],mData:c.mData?c.oDefaults:d});a.aoColumns.push(c);if(a.aoPreSearchCols[d]===n||null===a.aoPreSearchCols[d])a.aoPreSearchCols[d]=h.extend({},j.models.oSearch);else if(c=a.aoPreSearchCols[d], -c.bRegex===n&&(c.bRegex=!0),c.bSmart===n&&(c.bSmart=!0),c.bCaseInsensitive===n)c.bCaseInsensitive=!0;m(a,d,null)}function m(a,b,c){var d=a.aoColumns[b];c!==n&&null!==c&&(c.mDataProp&&!c.mData&&(c.mData=c.mDataProp),c.sType!==n&&(d.sType=c.sType,d._bAutoType=!1),h.extend(d,c),p(d,c,"sWidth","sWidthOrig"),c.iDataSort!==n&&(d.aDataSort=[c.iDataSort]),p(d,c,"aDataSort"));var i=d.mRender?Q(d.mRender):null,f=Q(d.mData);d.fnGetData=function(a,b){var c=f(a,b);return d.mRender&&b&&""!==b?i(c,b,a):c};d.fnSetData= -L(d.mData);a.oFeatures.bSort||(d.bSortable=!1);!d.bSortable||-1==h.inArray("asc",d.asSorting)&&-1==h.inArray("desc",d.asSorting)?(d.sSortingClass=a.oClasses.sSortableNone,d.sSortingClassJUI=""):-1==h.inArray("asc",d.asSorting)&&-1==h.inArray("desc",d.asSorting)?(d.sSortingClass=a.oClasses.sSortable,d.sSortingClassJUI=a.oClasses.sSortJUI):-1!=h.inArray("asc",d.asSorting)&&-1==h.inArray("desc",d.asSorting)?(d.sSortingClass=a.oClasses.sSortableAsc,d.sSortingClassJUI=a.oClasses.sSortJUIAscAllowed):-1== -h.inArray("asc",d.asSorting)&&-1!=h.inArray("desc",d.asSorting)&&(d.sSortingClass=a.oClasses.sSortableDesc,d.sSortingClassJUI=a.oClasses.sSortJUIDescAllowed)}function k(a){if(!1===a.oFeatures.bAutoWidth)return!1;da(a);for(var b=0,c=a.aoColumns.length;bj[f])d(a.aoColumns.length+j[f],b[i]);else if("string"===typeof j[f]){e=0;for(w=a.aoColumns.length;eb&&a[d]--; -1!=c&&a.splice(c,1)}function S(a,b,c){var d=a.aoColumns[c];return d.fnRender({iDataRow:b,iDataColumn:c,oSettings:a,aData:a.aoData[b]._aData,mDataProp:d.mData},v(a,b,c,"display"))}function ea(a,b){var c=a.aoData[b],d;if(null===c.nTr){c.nTr=l.createElement("tr");c.nTr._DT_RowIndex=b;c._aData.DT_RowId&&(c.nTr.id=c._aData.DT_RowId);c._aData.DT_RowClass&& -(c.nTr.className=c._aData.DT_RowClass);for(var i=0,f=a.aoColumns.length;i=a.fnRecordsDisplay()?0:a.iInitDisplayStart,a.iInitDisplayStart=-1,y(a));if(a.bDeferLoading)a.bDeferLoading=!1,a.iDraw++;else if(a.oFeatures.bServerSide){if(!a.bDestroying&&!wa(a))return}else a.iDraw++;if(0!==a.aiDisplay.length){var g= -a._iDisplayStart;d=a._iDisplayEnd;a.oFeatures.bServerSide&&(g=0,d=a.aoData.length);for(;g")[0];a.nTable.parentNode.insertBefore(b,a.nTable);a.nTableWrapper=h('
    ')[0];a.nTableReinsertBefore=a.nTable.nextSibling;for(var c=a.nTableWrapper,d=a.sDom.split(""),i,f,g,e,w,o,k,m=0;m")[0];w=d[m+ -1];if("'"==w||'"'==w){o="";for(k=2;d[m+k]!=w;)o+=d[m+k],k++;"H"==o?o=a.oClasses.sJUIHeader:"F"==o&&(o=a.oClasses.sJUIFooter);-1!=o.indexOf(".")?(w=o.split("."),e.id=w[0].substr(1,w[0].length-1),e.className=w[1]):"#"==o.charAt(0)?e.id=o.substr(1,o.length-1):e.className=o;m+=k}c.appendChild(e);c=e}else if(">"==g)c=c.parentNode;else if("l"==g&&a.oFeatures.bPaginate&&a.oFeatures.bLengthChange)i=ya(a),f=1;else if("f"==g&&a.oFeatures.bFilter)i=za(a),f=1;else if("r"==g&&a.oFeatures.bProcessing)i=Aa(a),f= -1;else if("t"==g)i=Ba(a),f=1;else if("i"==g&&a.oFeatures.bInfo)i=Ca(a),f=1;else if("p"==g&&a.oFeatures.bPaginate)i=Da(a),f=1;else if(0!==j.ext.aoFeatures.length){e=j.ext.aoFeatures;k=0;for(w=e.length;k'):""===c?'':c+' ',d=l.createElement("div");d.className=a.oClasses.sFilter;d.innerHTML="";a.aanFeatures.f||(d.id=a.sTableId+"_filter");c=h('input[type="text"]',d);d._DT_Input=c[0];c.val(b.sSearch.replace('"',"""));c.bind("keyup.DT",function(){for(var c=a.aanFeatures.f,d=this.value===""?"":this.value, -g=0,e=c.length;g=b.length)a.aiDisplay.splice(0,a.aiDisplay.length),a.aiDisplay=a.aiDisplayMaster.slice();else if(a.aiDisplay.length==a.aiDisplayMaster.length||i.sSearch.length>b.length||1==c||0!==b.indexOf(i.sSearch)){a.aiDisplay.splice(0, -a.aiDisplay.length);la(a,1);for(b=0;b").html(c).text()); -return c.replace(/[\n\r]/g," ")}function ma(a,b,c,d){if(c)return a=b?a.split(" "):oa(a).split(" "),a="^(?=.*?"+a.join(")(?=.*?")+").*$",RegExp(a,d?"i":"");a=b?a:oa(a);return RegExp(a,d?"i":"")}function Ja(a,b){return"function"===typeof j.ext.ofnSearch[b]?j.ext.ofnSearch[b](a):null===a?"":"html"==b?a.replace(/[\r\n]/g," ").replace(/<.*?>/g,""):"string"===typeof a?a.replace(/[\r\n]/g," "):a}function oa(a){return a.replace(RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\|\\$|\\^|\\-)","g"), -"\\$1")}function Ca(a){var b=l.createElement("div");b.className=a.oClasses.sInfo;a.aanFeatures.i||(a.aoDrawCallback.push({fn:Ka,sName:"information"}),b.id=a.sTableId+"_info");a.nTable.setAttribute("aria-describedby",a.sTableId+"_info");return b}function Ka(a){if(a.oFeatures.bInfo&&0!==a.aanFeatures.i.length){var b=a.oLanguage,c=a._iDisplayStart+1,d=a.fnDisplayEnd(),i=a.fnRecordsTotal(),f=a.fnRecordsDisplay(),g;g=0===f?b.sInfoEmpty:b.sInfo;f!=i&&(g+=" "+b.sInfoFiltered);g+=b.sInfoPostFix;g=ja(a,g); -null!==b.fnInfoCallback&&(g=b.fnInfoCallback.call(a.oInstance,a,c,d,i,f,g));a=a.aanFeatures.i;b=0;for(c=a.length;b",c,d,i=a.aLengthMenu;if(2==i.length&&"object"===typeof i[0]&&"object"===typeof i[1]){c=0;for(d=i[0].length;c'+i[1][c]+""}else{c=0;for(d=i.length;c'+i[c]+""}b+="";i=l.createElement("div");a.aanFeatures.l|| -(i.id=a.sTableId+"_length");i.className=a.oClasses.sLength;i.innerHTML="";h('select option[value="'+a._iDisplayLength+'"]',i).attr("selected",!0);h("select",i).bind("change.DT",function(){var b=h(this).val(),i=a.aanFeatures.l;c=0;for(d=i.length;ca.aiDisplay.length||-1==a._iDisplayLength?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength}function Da(a){if(a.oScroll.bInfinite)return null;var b=l.createElement("div");b.className=a.oClasses.sPaging+a.sPaginationType;j.ext.oPagination[a.sPaginationType].fnInit(a, -b,function(a){y(a);x(a)});a.aanFeatures.p||a.aoDrawCallback.push({fn:function(a){j.ext.oPagination[a.sPaginationType].fnUpdate(a,function(a){y(a);x(a)})},sName:"pagination"});return b}function qa(a,b){var c=a._iDisplayStart;if("number"===typeof b)a._iDisplayStart=b*a._iDisplayLength,a._iDisplayStart>a.fnRecordsDisplay()&&(a._iDisplayStart=0);else if("first"==b)a._iDisplayStart=0;else if("previous"==b)a._iDisplayStart=0<=a._iDisplayLength?a._iDisplayStart-a._iDisplayLength:0,0>a._iDisplayStart&&(a._iDisplayStart= -0);else if("next"==b)0<=a._iDisplayLength?a._iDisplayStart+a._iDisplayLengthh(a.nTable).height()-a.oScroll.iLoadGap&&a.fnDisplayEnd()d.offsetHeight||"scroll"==h(d).css("overflow-y")))a.nTable.style.width=q(h(a.nTable).outerWidth()-a.oScroll.iBarWidth)}else""!==a.oScroll.sXInner?a.nTable.style.width= -q(a.oScroll.sXInner):i==h(d).width()&&h(d).height()i-a.oScroll.iBarWidth&&(a.nTable.style.width=q(i))):a.nTable.style.width=q(i);i=h(a.nTable).outerWidth();C(s,e);C(function(a){p.push(q(h(a).width()))},e);C(function(a,b){a.style.width=p[b]},g);h(e).height(0);null!==a.nTFoot&&(C(s,j),C(function(a){n.push(q(h(a).width()))},j),C(function(a,b){a.style.width=n[b]},o),h(j).height(0));C(function(a,b){a.innerHTML= -"";a.style.width=p[b]},e);null!==a.nTFoot&&C(function(a,b){a.innerHTML="";a.style.width=n[b]},j);if(h(a.nTable).outerWidth()d.offsetHeight||"scroll"==h(d).css("overflow-y")?i+a.oScroll.iBarWidth:i;if(r&&(d.scrollHeight>d.offsetHeight||"scroll"==h(d).css("overflow-y")))a.nTable.style.width=q(g-a.oScroll.iBarWidth);d.style.width=q(g);a.nScrollHead.style.width=q(g);null!==a.nTFoot&&(a.nScrollFoot.style.width=q(g));""===a.oScroll.sX?D(a,1,"The table cannot fit into the current element which will cause column misalignment. The table has been drawn at its minimum possible width."): -""!==a.oScroll.sXInner&&D(a,1,"The table cannot fit into the current element which will cause column misalignment. Increase the sScrollXInner value or remove it to allow automatic calculation")}else d.style.width=q("100%"),a.nScrollHead.style.width=q("100%"),null!==a.nTFoot&&(a.nScrollFoot.style.width=q("100%"));""===a.oScroll.sY&&r&&(d.style.height=q(a.nTable.offsetHeight+a.oScroll.iBarWidth));""!==a.oScroll.sY&&a.oScroll.bCollapse&&(d.style.height=q(a.oScroll.sY),r=""!==a.oScroll.sX&&a.nTable.offsetWidth> -d.offsetWidth?a.oScroll.iBarWidth:0,a.nTable.offsetHeightd.clientHeight||"scroll"==h(d).css("overflow-y");b.style.paddingRight=c?a.oScroll.iBarWidth+"px":"0px";null!==a.nTFoot&&(R.style.width=q(r),l.style.width=q(r),l.style.paddingRight=c?a.oScroll.iBarWidth+"px":"0px");h(d).scroll();if(a.bSorted||a.bFiltered)d.scrollTop=0}function C(a,b,c){for(var d= -0,i=0,f=b.length,g,e;itd",b));j=N(a,f);for(f=d=0;fc)return null;if(null===a.aoData[c].nTr){var d=l.createElement("td");d.innerHTML=v(a,c,b,"");return d}return J(a,c)[b]}function Pa(a,b){for(var c=-1,d=-1,i=0;i/g,"");e.length>c&&(c=e.length,d=i)}return d}function q(a){if(null===a)return"0px";if("number"==typeof a)return 0>a?"0px":a+"px";var b=a.charCodeAt(a.length-1); -return 48>b||57/g,""),i=q[c].nTh,i.removeAttribute("aria-sort"),i.removeAttribute("aria-label"),q[c].bSortable?0d&&d++;f=RegExp(f+"[123]");var o;b=0;for(c=a.length;b
    ')[0];l.body.appendChild(b);a.oBrowser.bScrollOversize= -100===h("#DT_BrowserTest",b)[0].offsetWidth?!0:!1;l.body.removeChild(b)}function Va(a){return function(){var b=[s(this[j.ext.iApiIndex])].concat(Array.prototype.slice.call(arguments));return j.ext.oApi[a].apply(this,b)}}var U=/\[.*?\]$/,Wa=X.JSON?JSON.stringify:function(a){var b=typeof a;if("object"!==b||null===a)return"string"===b&&(a='"'+a+'"'),a+"";var c,d,e=[],f=h.isArray(a);for(c in a)d=a[c],b=typeof d,"string"===b?d='"'+d+'"':"object"===b&&null!==d&&(d=Wa(d)),e.push((f?"":'"'+c+'":')+d);return(f? -"[":"{")+e+(f?"]":"}")};this.$=function(a,b){var c,d,e=[],f;d=s(this[j.ext.iApiIndex]);var g=d.aoData,o=d.aiDisplay,k=d.aiDisplayMaster;b||(b={});b=h.extend({},{filter:"none",order:"current",page:"all"},b);if("current"==b.page){c=d._iDisplayStart;for(d=d.fnDisplayEnd();c=d.fnRecordsDisplay()&&(d._iDisplayStart-=d._iDisplayLength,0>d._iDisplayStart&&(d._iDisplayStart=0));if(c===n||c)y(d),x(d);return g};this.fnDestroy=function(a){var b=s(this[j.ext.iApiIndex]),c=b.nTableWrapper.parentNode,d=b.nTBody,i,f,a=a===n?!1:a;b.bDestroying=!0;A(b,"aoDestroyCallback","destroy",[b]);if(!a){i=0;for(f=b.aoColumns.length;itr>td."+b.oClasses.sRowEmpty,b.nTable).parent().remove();b.nTable!=b.nTHead.parentNode&&(h(b.nTable).children("thead").remove(),b.nTable.appendChild(b.nTHead));b.nTFoot&&b.nTable!=b.nTFoot.parentNode&&(h(b.nTable).children("tfoot").remove(),b.nTable.appendChild(b.nTFoot));b.nTable.parentNode.removeChild(b.nTable);h(b.nTableWrapper).remove();b.aaSorting=[];b.aaSortingFixed=[];P(b);h(T(b)).removeClass(b.asStripeClasses.join(" "));h("th, td",b.nTHead).removeClass([b.oClasses.sSortable,b.oClasses.sSortableAsc, -b.oClasses.sSortableDesc,b.oClasses.sSortableNone].join(" "));b.bJUI&&(h("th span."+b.oClasses.sSortIcon+", td span."+b.oClasses.sSortIcon,b.nTHead).remove(),h("th, td",b.nTHead).each(function(){var a=h("div."+b.oClasses.sSortJUIWrapper,this),c=a.contents();h(this).append(c);a.remove()}));!a&&b.nTableReinsertBefore?c.insertBefore(b.nTable,b.nTableReinsertBefore):a||c.appendChild(b.nTable);i=0;for(f=b.aoData.length;i=t(d);if(!m)for(e=a;et<"F"ip>')):h.extend(g.oClasses,j.ext.oStdClasses);h(this).addClass(g.oClasses.sTable);if(""!==g.oScroll.sX||""!==g.oScroll.sY)g.oScroll.iBarWidth=Qa();g.iInitDisplayStart===n&&(g.iInitDisplayStart=e.iDisplayStart, -g._iDisplayStart=e.iDisplayStart);e.bStateSave&&(g.oFeatures.bStateSave=!0,Sa(g,e),z(g,"aoDrawCallback",ra,"state_save"));null!==e.iDeferLoading&&(g.bDeferLoading=!0,a=h.isArray(e.iDeferLoading),g._iRecordsDisplay=a?e.iDeferLoading[0]:e.iDeferLoading,g._iRecordsTotal=a?e.iDeferLoading[1]:e.iDeferLoading);null!==e.aaData&&(f=!0);""!==e.oLanguage.sUrl?(g.oLanguage.sUrl=e.oLanguage.sUrl,h.getJSON(g.oLanguage.sUrl,null,function(a){pa(a);h.extend(true,g.oLanguage,e.oLanguage,a);ba(g)}),i=!0):h.extend(!0, -g.oLanguage,e.oLanguage);null===e.asStripeClasses&&(g.asStripeClasses=[g.oClasses.sStripeOdd,g.oClasses.sStripeEven]);b=g.asStripeClasses.length;g.asDestroyStripes=[];if(b){c=!1;d=h(this).children("tbody").children("tr:lt("+b+")");for(a=0;a=g.aoColumns.length&&(g.aaSorting[a][0]=0);var k=g.aoColumns[g.aaSorting[a][0]];g.aaSorting[a][2]===n&&(g.aaSorting[a][2]=0);e.aaSorting===n&&g.saved_aaSorting===n&&(g.aaSorting[a][1]= -k.asSorting[0]);c=0;for(d=k.asSorting.length;c=parseInt(n,10)};j.fnIsDataTable=function(e){for(var h=j.settings,m=0;me)return e;for(var h=e+"",e=h.split(""),j="",h=h.length,k=0;k'+k.sPrevious+''+k.sNext+"":'';h(j).append(k);var l=h("a",j), -k=l[0],l=l[1];e.oApi._fnBindAction(k,{action:"previous"},n);e.oApi._fnBindAction(l,{action:"next"},n);e.aanFeatures.p||(j.id=e.sTableId+"_paginate",k.id=e.sTableId+"_previous",l.id=e.sTableId+"_next",k.setAttribute("aria-controls",e.sTableId),l.setAttribute("aria-controls",e.sTableId))},fnUpdate:function(e){if(e.aanFeatures.p)for(var h=e.oClasses,j=e.aanFeatures.p,k,l=0,n=j.length;l'+k.sFirst+''+k.sPrevious+''+k.sNext+''+k.sLast+"");var t=h("a",j),k=t[0],l=t[1],r=t[2],t=t[3];e.oApi._fnBindAction(k,{action:"first"},n);e.oApi._fnBindAction(l,{action:"previous"},n);e.oApi._fnBindAction(r,{action:"next"},n);e.oApi._fnBindAction(t,{action:"last"},n);e.aanFeatures.p||(j.id=e.sTableId+"_paginate",k.id=e.sTableId+"_first",l.id=e.sTableId+"_previous",r.id=e.sTableId+"_next",t.id=e.sTableId+"_last")}, -fnUpdate:function(e,o){if(e.aanFeatures.p){var m=j.ext.oPagination.iFullNumbersShowPages,k=Math.floor(m/2),l=Math.ceil(e.fnRecordsDisplay()/e._iDisplayLength),n=Math.ceil(e._iDisplayStart/e._iDisplayLength)+1,t="",r,B=e.oClasses,u,M=e.aanFeatures.p,L=function(h){e.oApi._fnBindAction(this,{page:h+r-1},function(h){e.oApi._fnPageChange(e,h.data.page);o(e);h.preventDefault()})};-1===e._iDisplayLength?n=k=r=1:l=l-k?(r=l-m+1,k=l):(r=n-Math.ceil(m/2)+1,k=r+m-1);for(m=r;m<=k;m++)t+= -n!==m?''+e.fnFormatNumber(m)+"":''+e.fnFormatNumber(m)+"";m=0;for(k=M.length;mh?1:0},"string-desc":function(e,h){return eh?-1:0},"html-pre":function(e){return e.replace(/<.*?>/g,"").toLowerCase()},"html-asc":function(e,h){return eh?1:0},"html-desc":function(e,h){return e< -h?1:e>h?-1:0},"date-pre":function(e){e=Date.parse(e);if(isNaN(e)||""===e)e=Date.parse("01/01/1970 00:00:00");return e},"date-asc":function(e,h){return e-h},"date-desc":function(e,h){return h-e},"numeric-pre":function(e){return"-"==e||""===e?0:1*e},"numeric-asc":function(e,h){return e-h},"numeric-desc":function(e,h){return h-e}});h.extend(j.ext.aTypes,[function(e){if("number"===typeof e)return"numeric";if("string"!==typeof e)return null;var h,j=!1;h=e.charAt(0);if(-1=="0123456789-".indexOf(h))return null; -for(var k=1;k")?"html":null}]);h.fn.DataTable=j;h.fn.dataTable=j;h.fn.dataTableSettings=j.settings;h.fn.dataTableExt=j.ext};"function"===typeof define&&define.amd?define(["jquery"],L):jQuery&&!jQuery.fn.dataTable&& -L(jQuery)})(window,document); diff --git a/htdocs/includes/jquery/plugins/datatables/license-bsd.txt b/htdocs/includes/jquery/plugins/datatables/license-bsd.txt deleted file mode 100644 index cdb85aaaa34..00000000000 --- a/htdocs/includes/jquery/plugins/datatables/license-bsd.txt +++ /dev/null @@ -1,10 +0,0 @@ -Copyright (c) 2008-2010, Allan Jardine -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Allan Jardine nor SpryMedia UK may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/htdocs/includes/jquery/plugins/datatables/license-gpl2.txt b/htdocs/includes/jquery/plugins/datatables/license-gpl2.txt deleted file mode 100644 index d511905c164..00000000000 --- a/htdocs/includes/jquery/plugins/datatables/license-gpl2.txt +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/htdocs/includes/jquery/plugins/datatables/license.txt b/htdocs/includes/jquery/plugins/datatables/license.txt new file mode 100644 index 00000000000..48dee1865bc --- /dev/null +++ b/htdocs/includes/jquery/plugins/datatables/license.txt @@ -0,0 +1,20 @@ +Copyright (c) 2008-2013 SpryMedia Limited +http://datatables.net + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/htdocs/includes/jquery/plugins/datatables/media/css/jquery.dataTables.css b/htdocs/includes/jquery/plugins/datatables/media/css/jquery.dataTables.css new file mode 100644 index 00000000000..eec02ef59b5 --- /dev/null +++ b/htdocs/includes/jquery/plugins/datatables/media/css/jquery.dataTables.css @@ -0,0 +1,455 @@ +/* + * Table styles + */ +table.dataTable { + width: 100%; + margin: 0 auto; + clear: both; + border-collapse: separate; + border-spacing: 0; + /* + * Header and footer styles + */ + /* + * Body styles + */ +} +table.dataTable thead th, +table.dataTable tfoot th { + font-weight: bold; +} +table.dataTable thead th, +table.dataTable thead td { + padding: 10px 18px; + border-bottom: 1px solid #111; +} +table.dataTable thead th:active, +table.dataTable thead td:active { + outline: none; +} +table.dataTable tfoot th, +table.dataTable tfoot td { + padding: 10px 18px 6px 18px; + border-top: 1px solid #111; +} +table.dataTable thead .sorting, +table.dataTable thead .sorting_asc, +table.dataTable thead .sorting_desc { + cursor: pointer; + *cursor: hand; +} +table.dataTable thead .sorting, +table.dataTable thead .sorting_asc, +table.dataTable thead .sorting_desc, +table.dataTable thead .sorting_asc_disabled, +table.dataTable thead .sorting_desc_disabled { + background-repeat: no-repeat; + background-position: center right; +} +table.dataTable thead .sorting { + background-image: url("../images/sort_both.png"); +} +table.dataTable thead .sorting_asc { + background-image: url("../images/sort_asc.png"); +} +table.dataTable thead .sorting_desc { + background-image: url("../images/sort_desc.png"); +} +table.dataTable thead .sorting_asc_disabled { + background-image: url("../images/sort_asc_disabled.png"); +} +table.dataTable thead .sorting_desc_disabled { + background-image: url("../images/sort_desc_disabled.png"); +} +table.dataTable tbody tr { + background-color: #ffffff; +} +table.dataTable tbody tr.selected { + background-color: #B0BED9; +} +table.dataTable tbody th, +table.dataTable tbody td { + padding: 8px 10px; +} +table.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td { + border-top: 1px solid #ddd; +} +table.dataTable.row-border tbody tr:first-child th, +table.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th, +table.dataTable.display tbody tr:first-child td { + border-top: none; +} +table.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td { + border-top: 1px solid #ddd; + border-right: 1px solid #ddd; +} +table.dataTable.cell-border tbody tr th:first-child, +table.dataTable.cell-border tbody tr td:first-child { + border-left: 1px solid #ddd; +} +table.dataTable.cell-border tbody tr:first-child th, +table.dataTable.cell-border tbody tr:first-child td { + border-top: none; +} +table.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd { + background-color: #f9f9f9; +} +table.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected { + background-color: #abb9d3; +} +table.dataTable.hover tbody tr:hover, table.dataTable.display tbody tr:hover { + background-color: whitesmoke; +} +table.dataTable.hover tbody tr:hover.selected, table.dataTable.display tbody tr:hover.selected { + background-color: #a9b7d1; +} +table.dataTable.order-column tbody tr > .sorting_1, +table.dataTable.order-column tbody tr > .sorting_2, +table.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1, +table.dataTable.display tbody tr > .sorting_2, +table.dataTable.display tbody tr > .sorting_3 { + background-color: #f9f9f9; +} +table.dataTable.order-column tbody tr.selected > .sorting_1, +table.dataTable.order-column tbody tr.selected > .sorting_2, +table.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1, +table.dataTable.display tbody tr.selected > .sorting_2, +table.dataTable.display tbody tr.selected > .sorting_3 { + background-color: #acbad4; +} +table.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 { + background-color: #f1f1f1; +} +table.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 { + background-color: #f3f3f3; +} +table.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 { + background-color: whitesmoke; +} +table.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 { + background-color: #a6b3cd; +} +table.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 { + background-color: #a7b5ce; +} +table.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 { + background-color: #a9b6d0; +} +table.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 { + background-color: #f9f9f9; +} +table.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 { + background-color: #fbfbfb; +} +table.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 { + background-color: #fdfdfd; +} +table.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 { + background-color: #acbad4; +} +table.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 { + background-color: #adbbd6; +} +table.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 { + background-color: #afbdd8; +} +table.dataTable.display tbody tr:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1 { + background-color: #eaeaea; +} +table.dataTable.display tbody tr:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2 { + background-color: #ebebeb; +} +table.dataTable.display tbody tr:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3 { + background-color: #eeeeee; +} +table.dataTable.display tbody tr:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1 { + background-color: #a1aec7; +} +table.dataTable.display tbody tr:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2 { + background-color: #a2afc8; +} +table.dataTable.display tbody tr:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3 { + background-color: #a4b2cb; +} +table.dataTable.no-footer { + border-bottom: 1px solid #111; +} +table.dataTable.nowrap th, table.dataTable.nowrap td { + white-space: nowrap; +} +table.dataTable.compact thead th, +table.dataTable.compact thead td { + padding: 4px 17px 4px 4px; +} +table.dataTable.compact tfoot th, +table.dataTable.compact tfoot td { + padding: 4px; +} +table.dataTable.compact tbody th, +table.dataTable.compact tbody td { + padding: 4px; +} +table.dataTable th.dt-left, +table.dataTable td.dt-left { + text-align: left; +} +table.dataTable th.dt-center, +table.dataTable td.dt-center, +table.dataTable td.dataTables_empty { + text-align: center; +} +table.dataTable th.dt-right, +table.dataTable td.dt-right { + text-align: right; +} +table.dataTable th.dt-justify, +table.dataTable td.dt-justify { + text-align: justify; +} +table.dataTable th.dt-nowrap, +table.dataTable td.dt-nowrap { + white-space: nowrap; +} +table.dataTable thead th.dt-head-left, +table.dataTable thead td.dt-head-left, +table.dataTable tfoot th.dt-head-left, +table.dataTable tfoot td.dt-head-left { + text-align: left; +} +table.dataTable thead th.dt-head-center, +table.dataTable thead td.dt-head-center, +table.dataTable tfoot th.dt-head-center, +table.dataTable tfoot td.dt-head-center { + text-align: center; +} +table.dataTable thead th.dt-head-right, +table.dataTable thead td.dt-head-right, +table.dataTable tfoot th.dt-head-right, +table.dataTable tfoot td.dt-head-right { + text-align: right; +} +table.dataTable thead th.dt-head-justify, +table.dataTable thead td.dt-head-justify, +table.dataTable tfoot th.dt-head-justify, +table.dataTable tfoot td.dt-head-justify { + text-align: justify; +} +table.dataTable thead th.dt-head-nowrap, +table.dataTable thead td.dt-head-nowrap, +table.dataTable tfoot th.dt-head-nowrap, +table.dataTable tfoot td.dt-head-nowrap { + white-space: nowrap; +} +table.dataTable tbody th.dt-body-left, +table.dataTable tbody td.dt-body-left { + text-align: left; +} +table.dataTable tbody th.dt-body-center, +table.dataTable tbody td.dt-body-center { + text-align: center; +} +table.dataTable tbody th.dt-body-right, +table.dataTable tbody td.dt-body-right { + text-align: right; +} +table.dataTable tbody th.dt-body-justify, +table.dataTable tbody td.dt-body-justify { + text-align: justify; +} +table.dataTable tbody th.dt-body-nowrap, +table.dataTable tbody td.dt-body-nowrap { + white-space: nowrap; +} + +table.dataTable, +table.dataTable th, +table.dataTable td { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} + +/* + * Control feature layout + */ +.dataTables_wrapper { + position: relative; + clear: both; + *zoom: 1; + zoom: 1; +} +.dataTables_wrapper .dataTables_length { + float: left; +} +.dataTables_wrapper .dataTables_filter { + float: right; + text-align: right; +} +.dataTables_wrapper .dataTables_filter input { + margin-left: 0.5em; +} +.dataTables_wrapper .dataTables_info { + clear: both; + float: left; + padding-top: 0.755em; +} +.dataTables_wrapper .dataTables_paginate { + float: right; + text-align: right; + padding-top: 0.25em; +} +.dataTables_wrapper .dataTables_paginate .paginate_button { + box-sizing: border-box; + display: inline-block; + min-width: 1.5em; + padding: 0.5em 1em; + margin-left: 2px; + text-align: center; + text-decoration: none !important; + cursor: pointer; + *cursor: hand; + color: #333 !important; + border: 1px solid transparent; +} +.dataTables_wrapper .dataTables_paginate .paginate_button.current, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover { + color: #333 !important; + border: 1px solid #cacaca; + background-color: white; + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, #dcdcdc)); + /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, white 0%, #dcdcdc 100%); + /* Chrome10+,Safari5.1+ */ + background: -moz-linear-gradient(top, white 0%, #dcdcdc 100%); + /* FF3.6+ */ + background: -ms-linear-gradient(top, white 0%, #dcdcdc 100%); + /* IE10+ */ + background: -o-linear-gradient(top, white 0%, #dcdcdc 100%); + /* Opera 11.10+ */ + background: linear-gradient(to bottom, white 0%, #dcdcdc 100%); + /* W3C */ +} +.dataTables_wrapper .dataTables_paginate .paginate_button.disabled, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active { + cursor: default; + color: #666 !important; + border: 1px solid transparent; + background: transparent; + box-shadow: none; +} +.dataTables_wrapper .dataTables_paginate .paginate_button:hover { + color: white !important; + border: 1px solid #111; + background-color: #585858; + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111)); + /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #585858 0%, #111 100%); + /* Chrome10+,Safari5.1+ */ + background: -moz-linear-gradient(top, #585858 0%, #111 100%); + /* FF3.6+ */ + background: -ms-linear-gradient(top, #585858 0%, #111 100%); + /* IE10+ */ + background: -o-linear-gradient(top, #585858 0%, #111 100%); + /* Opera 11.10+ */ + background: linear-gradient(to bottom, #585858 0%, #111 100%); + /* W3C */ +} +.dataTables_wrapper .dataTables_paginate .paginate_button:active { + outline: none; + background-color: #2b2b2b; + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c)); + /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); + /* Chrome10+,Safari5.1+ */ + background: -moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); + /* FF3.6+ */ + background: -ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); + /* IE10+ */ + background: -o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); + /* Opera 11.10+ */ + background: linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%); + /* W3C */ + box-shadow: inset 0 0 3px #111; +} +.dataTables_wrapper .dataTables_paginate .ellipsis { + padding: 0 1em; +} +.dataTables_wrapper .dataTables_processing { + position: absolute; + top: 50%; + left: 50%; + width: 100%; + height: 40px; + margin-left: -50%; + margin-top: -25px; + padding-top: 20px; + text-align: center; + font-size: 1.2em; + background-color: white; + background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0))); + /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); + /* Chrome10+,Safari5.1+ */ + background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); + /* FF3.6+ */ + background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); + /* IE10+ */ + background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); + /* Opera 11.10+ */ + background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); + /* W3C */ +} +.dataTables_wrapper .dataTables_length, +.dataTables_wrapper .dataTables_filter, +.dataTables_wrapper .dataTables_info, +.dataTables_wrapper .dataTables_processing, +.dataTables_wrapper .dataTables_paginate { + color: #333; +} +.dataTables_wrapper .dataTables_scroll { + clear: both; +} +.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody { + *margin-top: -1px; + -webkit-overflow-scrolling: touch; +} +.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th > div.dataTables_sizing, +.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td > div.dataTables_sizing { + height: 0; + overflow: hidden; + margin: 0 !important; + padding: 0 !important; +} +.dataTables_wrapper.no-footer .dataTables_scrollBody { + border-bottom: 1px solid #111; +} +.dataTables_wrapper.no-footer div.dataTables_scrollHead table, +.dataTables_wrapper.no-footer div.dataTables_scrollBody table { + border-bottom: none; +} +.dataTables_wrapper:after { + visibility: hidden; + display: block; + content: ""; + clear: both; + height: 0; +} + +@media screen and (max-width: 767px) { + .dataTables_wrapper .dataTables_info, + .dataTables_wrapper .dataTables_paginate { + float: none; + text-align: center; + } + .dataTables_wrapper .dataTables_paginate { + margin-top: 0.5em; + } +} +@media screen and (max-width: 640px) { + .dataTables_wrapper .dataTables_length, + .dataTables_wrapper .dataTables_filter { + float: none; + text-align: center; + } + .dataTables_wrapper .dataTables_filter { + margin-top: 0.5em; + } +} diff --git a/htdocs/includes/jquery/plugins/datatables/media/css/jquery.dataTables.min.css b/htdocs/includes/jquery/plugins/datatables/media/css/jquery.dataTables.min.css new file mode 100644 index 00000000000..2edb32f7c7a --- /dev/null +++ b/htdocs/includes/jquery/plugins/datatables/media/css/jquery.dataTables.min.css @@ -0,0 +1 @@ +table.dataTable{width:100%;margin:0 auto;clear:both;border-collapse:separate;border-spacing:0}table.dataTable thead th,table.dataTable tfoot th{font-weight:bold}table.dataTable thead th,table.dataTable thead td{padding:10px 18px;border-bottom:1px solid #111}table.dataTable thead th:active,table.dataTable thead td:active{outline:none}table.dataTable tfoot th,table.dataTable tfoot td{padding:10px 18px 6px 18px;border-top:1px solid #111}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc{cursor:pointer;*cursor:hand}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc,table.dataTable thead .sorting_asc_disabled,table.dataTable thead .sorting_desc_disabled{background-repeat:no-repeat;background-position:center right}table.dataTable thead .sorting{background-image:url("../images/sort_both.png")}table.dataTable thead .sorting_asc{background-image:url("../images/sort_asc.png")}table.dataTable thead .sorting_desc{background-image:url("../images/sort_desc.png")}table.dataTable thead .sorting_asc_disabled{background-image:url("../images/sort_asc_disabled.png")}table.dataTable thead .sorting_desc_disabled{background-image:url("../images/sort_desc_disabled.png")}table.dataTable tbody tr{background-color:#fff}table.dataTable tbody tr.selected{background-color:#B0BED9}table.dataTable tbody th,table.dataTable tbody td{padding:8px 10px}table.dataTable.row-border tbody th,table.dataTable.row-border tbody td,table.dataTable.display tbody th,table.dataTable.display tbody td{border-top:1px solid #ddd}table.dataTable.row-border tbody tr:first-child th,table.dataTable.row-border tbody tr:first-child td,table.dataTable.display tbody tr:first-child th,table.dataTable.display tbody tr:first-child td{border-top:none}table.dataTable.cell-border tbody th,table.dataTable.cell-border tbody td{border-top:1px solid #ddd;border-right:1px solid #ddd}table.dataTable.cell-border tbody tr th:first-child,table.dataTable.cell-border tbody tr td:first-child{border-left:1px solid #ddd}table.dataTable.cell-border tbody tr:first-child th,table.dataTable.cell-border tbody tr:first-child td{border-top:none}table.dataTable.stripe tbody tr.odd,table.dataTable.display tbody tr.odd{background-color:#f9f9f9}table.dataTable.stripe tbody tr.odd.selected,table.dataTable.display tbody tr.odd.selected{background-color:#abb9d3}table.dataTable.hover tbody tr:hover,table.dataTable.display tbody tr:hover{background-color:#f5f5f5}table.dataTable.hover tbody tr:hover.selected,table.dataTable.display tbody tr:hover.selected{background-color:#a9b7d1}table.dataTable.order-column tbody tr>.sorting_1,table.dataTable.order-column tbody tr>.sorting_2,table.dataTable.order-column tbody tr>.sorting_3,table.dataTable.display tbody tr>.sorting_1,table.dataTable.display tbody tr>.sorting_2,table.dataTable.display tbody tr>.sorting_3{background-color:#f9f9f9}table.dataTable.order-column tbody tr.selected>.sorting_1,table.dataTable.order-column tbody tr.selected>.sorting_2,table.dataTable.order-column tbody tr.selected>.sorting_3,table.dataTable.display tbody tr.selected>.sorting_1,table.dataTable.display tbody tr.selected>.sorting_2,table.dataTable.display tbody tr.selected>.sorting_3{background-color:#acbad4}table.dataTable.display tbody tr.odd>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd>.sorting_1{background-color:#f1f1f1}table.dataTable.display tbody tr.odd>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd>.sorting_2{background-color:#f3f3f3}table.dataTable.display tbody tr.odd>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd>.sorting_3{background-color:#f5f5f5}table.dataTable.display tbody tr.odd.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_1{background-color:#a6b3cd}table.dataTable.display tbody tr.odd.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_2{background-color:#a7b5ce}table.dataTable.display tbody tr.odd.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_3{background-color:#a9b6d0}table.dataTable.display tbody tr.even>.sorting_1,table.dataTable.order-column.stripe tbody tr.even>.sorting_1{background-color:#f9f9f9}table.dataTable.display tbody tr.even>.sorting_2,table.dataTable.order-column.stripe tbody tr.even>.sorting_2{background-color:#fbfbfb}table.dataTable.display tbody tr.even>.sorting_3,table.dataTable.order-column.stripe tbody tr.even>.sorting_3{background-color:#fdfdfd}table.dataTable.display tbody tr.even.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_1{background-color:#acbad4}table.dataTable.display tbody tr.even.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_2{background-color:#adbbd6}table.dataTable.display tbody tr.even.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_3{background-color:#afbdd8}table.dataTable.display tbody tr:hover>.sorting_1,table.dataTable.order-column.hover tbody tr:hover>.sorting_1{background-color:#eaeaea}table.dataTable.display tbody tr:hover>.sorting_2,table.dataTable.order-column.hover tbody tr:hover>.sorting_2{background-color:#ebebeb}table.dataTable.display tbody tr:hover>.sorting_3,table.dataTable.order-column.hover tbody tr:hover>.sorting_3{background-color:#eee}table.dataTable.display tbody tr:hover.selected>.sorting_1,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_1{background-color:#a1aec7}table.dataTable.display tbody tr:hover.selected>.sorting_2,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_2{background-color:#a2afc8}table.dataTable.display tbody tr:hover.selected>.sorting_3,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_3{background-color:#a4b2cb}table.dataTable.no-footer{border-bottom:1px solid #111}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}table.dataTable.compact thead th,table.dataTable.compact thead td{padding:4px 17px 4px 4px}table.dataTable.compact tfoot th,table.dataTable.compact tfoot td{padding:4px}table.dataTable.compact tbody th,table.dataTable.compact tbody td{padding:4px}table.dataTable th.dt-left,table.dataTable td.dt-left{text-align:left}table.dataTable th.dt-center,table.dataTable td.dt-center,table.dataTable td.dataTables_empty{text-align:center}table.dataTable th.dt-right,table.dataTable td.dt-right{text-align:right}table.dataTable th.dt-justify,table.dataTable td.dt-justify{text-align:justify}table.dataTable th.dt-nowrap,table.dataTable td.dt-nowrap{white-space:nowrap}table.dataTable thead th.dt-head-left,table.dataTable thead td.dt-head-left,table.dataTable tfoot th.dt-head-left,table.dataTable tfoot td.dt-head-left{text-align:left}table.dataTable thead th.dt-head-center,table.dataTable thead td.dt-head-center,table.dataTable tfoot th.dt-head-center,table.dataTable tfoot td.dt-head-center{text-align:center}table.dataTable thead th.dt-head-right,table.dataTable thead td.dt-head-right,table.dataTable tfoot th.dt-head-right,table.dataTable tfoot td.dt-head-right{text-align:right}table.dataTable thead th.dt-head-justify,table.dataTable thead td.dt-head-justify,table.dataTable tfoot th.dt-head-justify,table.dataTable tfoot td.dt-head-justify{text-align:justify}table.dataTable thead th.dt-head-nowrap,table.dataTable thead td.dt-head-nowrap,table.dataTable tfoot th.dt-head-nowrap,table.dataTable tfoot td.dt-head-nowrap{white-space:nowrap}table.dataTable tbody th.dt-body-left,table.dataTable tbody td.dt-body-left{text-align:left}table.dataTable tbody th.dt-body-center,table.dataTable tbody td.dt-body-center{text-align:center}table.dataTable tbody th.dt-body-right,table.dataTable tbody td.dt-body-right{text-align:right}table.dataTable tbody th.dt-body-justify,table.dataTable tbody td.dt-body-justify{text-align:justify}table.dataTable tbody th.dt-body-nowrap,table.dataTable tbody td.dt-body-nowrap{white-space:nowrap}table.dataTable,table.dataTable th,table.dataTable td{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.dataTables_wrapper{position:relative;clear:both;*zoom:1;zoom:1}.dataTables_wrapper .dataTables_length{float:left}.dataTables_wrapper .dataTables_filter{float:right;text-align:right}.dataTables_wrapper .dataTables_filter input{margin-left:0.5em}.dataTables_wrapper .dataTables_info{clear:both;float:left;padding-top:0.755em}.dataTables_wrapper .dataTables_paginate{float:right;text-align:right;padding-top:0.25em}.dataTables_wrapper .dataTables_paginate .paginate_button{box-sizing:border-box;display:inline-block;min-width:1.5em;padding:0.5em 1em;margin-left:2px;text-align:center;text-decoration:none !important;cursor:pointer;*cursor:hand;color:#333 !important;border:1px solid transparent}.dataTables_wrapper .dataTables_paginate .paginate_button.current,.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover{color:#333 !important;border:1px solid #cacaca;background-color:#fff;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #fff), color-stop(100%, #dcdcdc));background:-webkit-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-moz-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-ms-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-o-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:linear-gradient(to bottom, #fff 0%, #dcdcdc 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button.disabled,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active{cursor:default;color:#666 !important;border:1px solid transparent;background:transparent;box-shadow:none}.dataTables_wrapper .dataTables_paginate .paginate_button:hover{color:white !important;border:1px solid #111;background-color:#585858;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));background:-webkit-linear-gradient(top, #585858 0%, #111 100%);background:-moz-linear-gradient(top, #585858 0%, #111 100%);background:-ms-linear-gradient(top, #585858 0%, #111 100%);background:-o-linear-gradient(top, #585858 0%, #111 100%);background:linear-gradient(to bottom, #585858 0%, #111 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button:active{outline:none;background-color:#2b2b2b;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));background:-webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);box-shadow:inset 0 0 3px #111}.dataTables_wrapper .dataTables_paginate .ellipsis{padding:0 1em}.dataTables_wrapper .dataTables_processing{position:absolute;top:50%;left:50%;width:100%;height:40px;margin-left:-50%;margin-top:-25px;padding-top:20px;text-align:center;font-size:1.2em;background-color:white;background:-webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255,255,255,0)), color-stop(25%, rgba(255,255,255,0.9)), color-stop(75%, rgba(255,255,255,0.9)), color-stop(100%, rgba(255,255,255,0)));background:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-moz-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-ms-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-o-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%)}.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter,.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_processing,.dataTables_wrapper .dataTables_paginate{color:#333}.dataTables_wrapper .dataTables_scroll{clear:both}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody{*margin-top:-1px;-webkit-overflow-scrolling:touch}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td>div.dataTables_sizing{height:0;overflow:hidden;margin:0 !important;padding:0 !important}.dataTables_wrapper.no-footer .dataTables_scrollBody{border-bottom:1px solid #111}.dataTables_wrapper.no-footer div.dataTables_scrollHead table,.dataTables_wrapper.no-footer div.dataTables_scrollBody table{border-bottom:none}.dataTables_wrapper:after{visibility:hidden;display:block;content:"";clear:both;height:0}@media screen and (max-width: 767px){.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_paginate{float:none;text-align:center}.dataTables_wrapper .dataTables_paginate{margin-top:0.5em}}@media screen and (max-width: 640px){.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter{float:none;text-align:center}.dataTables_wrapper .dataTables_filter{margin-top:0.5em}} diff --git a/htdocs/includes/jquery/plugins/datatables/media/css/jquery.dataTables_themeroller.css b/htdocs/includes/jquery/plugins/datatables/media/css/jquery.dataTables_themeroller.css new file mode 100644 index 00000000000..1426a44a18b --- /dev/null +++ b/htdocs/includes/jquery/plugins/datatables/media/css/jquery.dataTables_themeroller.css @@ -0,0 +1,416 @@ +/* + * Table styles + */ +table.dataTable { + width: 100%; + margin: 0 auto; + clear: both; + border-collapse: separate; + border-spacing: 0; + /* + * Header and footer styles + */ + /* + * Body styles + */ +} +table.dataTable thead th, +table.dataTable thead td, +table.dataTable tfoot th, +table.dataTable tfoot td { + padding: 4px 10px; +} +table.dataTable thead th, +table.dataTable tfoot th { + font-weight: bold; +} +table.dataTable thead th:active, +table.dataTable thead td:active { + outline: none; +} +table.dataTable thead .sorting_asc, +table.dataTable thead .sorting_desc, +table.dataTable thead .sorting { + cursor: pointer; + *cursor: hand; +} +table.dataTable thead th div.DataTables_sort_wrapper { + position: relative; + padding-right: 10px; +} +table.dataTable thead th div.DataTables_sort_wrapper span { + position: absolute; + top: 50%; + margin-top: -8px; + right: -5px; +} +table.dataTable thead th.ui-state-default { + border-right-width: 0; +} +table.dataTable thead th.ui-state-default:last-child { + border-right-width: 1px; +} +table.dataTable tbody tr { + background-color: #ffffff; +} +table.dataTable tbody tr.selected { + background-color: #B0BED9; +} +table.dataTable tbody th, +table.dataTable tbody td { + padding: 8px 10px; +} +table.dataTable th.center, +table.dataTable td.center, +table.dataTable td.dataTables_empty { + text-align: center; +} +table.dataTable th.right, +table.dataTable td.right { + text-align: right; +} +table.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td { + border-top: 1px solid #ddd; +} +table.dataTable.row-border tbody tr:first-child th, +table.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th, +table.dataTable.display tbody tr:first-child td { + border-top: none; +} +table.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td { + border-top: 1px solid #ddd; + border-right: 1px solid #ddd; +} +table.dataTable.cell-border tbody tr th:first-child, +table.dataTable.cell-border tbody tr td:first-child { + border-left: 1px solid #ddd; +} +table.dataTable.cell-border tbody tr:first-child th, +table.dataTable.cell-border tbody tr:first-child td { + border-top: none; +} +table.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd { + background-color: #f9f9f9; +} +table.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected { + background-color: #abb9d3; +} +table.dataTable.hover tbody tr:hover, +table.dataTable.hover tbody tr.odd:hover, +table.dataTable.hover tbody tr.even:hover, table.dataTable.display tbody tr:hover, +table.dataTable.display tbody tr.odd:hover, +table.dataTable.display tbody tr.even:hover { + background-color: whitesmoke; +} +table.dataTable.hover tbody tr:hover.selected, +table.dataTable.hover tbody tr.odd:hover.selected, +table.dataTable.hover tbody tr.even:hover.selected, table.dataTable.display tbody tr:hover.selected, +table.dataTable.display tbody tr.odd:hover.selected, +table.dataTable.display tbody tr.even:hover.selected { + background-color: #a9b7d1; +} +table.dataTable.order-column tbody tr > .sorting_1, +table.dataTable.order-column tbody tr > .sorting_2, +table.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1, +table.dataTable.display tbody tr > .sorting_2, +table.dataTable.display tbody tr > .sorting_3 { + background-color: #f9f9f9; +} +table.dataTable.order-column tbody tr.selected > .sorting_1, +table.dataTable.order-column tbody tr.selected > .sorting_2, +table.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1, +table.dataTable.display tbody tr.selected > .sorting_2, +table.dataTable.display tbody tr.selected > .sorting_3 { + background-color: #acbad4; +} +table.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 { + background-color: #f1f1f1; +} +table.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 { + background-color: #f3f3f3; +} +table.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 { + background-color: whitesmoke; +} +table.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 { + background-color: #a6b3cd; +} +table.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 { + background-color: #a7b5ce; +} +table.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 { + background-color: #a9b6d0; +} +table.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 { + background-color: #f9f9f9; +} +table.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 { + background-color: #fbfbfb; +} +table.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 { + background-color: #fdfdfd; +} +table.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 { + background-color: #acbad4; +} +table.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 { + background-color: #adbbd6; +} +table.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 { + background-color: #afbdd8; +} +table.dataTable.display tbody tr:hover > .sorting_1, +table.dataTable.display tbody tr.odd:hover > .sorting_1, +table.dataTable.display tbody tr.even:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1, +table.dataTable.order-column.hover tbody tr.odd:hover > .sorting_1, +table.dataTable.order-column.hover tbody tr.even:hover > .sorting_1 { + background-color: #eaeaea; +} +table.dataTable.display tbody tr:hover > .sorting_2, +table.dataTable.display tbody tr.odd:hover > .sorting_2, +table.dataTable.display tbody tr.even:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2, +table.dataTable.order-column.hover tbody tr.odd:hover > .sorting_2, +table.dataTable.order-column.hover tbody tr.even:hover > .sorting_2 { + background-color: #ebebeb; +} +table.dataTable.display tbody tr:hover > .sorting_3, +table.dataTable.display tbody tr.odd:hover > .sorting_3, +table.dataTable.display tbody tr.even:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3, +table.dataTable.order-column.hover tbody tr.odd:hover > .sorting_3, +table.dataTable.order-column.hover tbody tr.even:hover > .sorting_3 { + background-color: #eeeeee; +} +table.dataTable.display tbody tr:hover.selected > .sorting_1, +table.dataTable.display tbody tr.odd:hover.selected > .sorting_1, +table.dataTable.display tbody tr.even:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1, +table.dataTable.order-column.hover tbody tr.odd:hover.selected > .sorting_1, +table.dataTable.order-column.hover tbody tr.even:hover.selected > .sorting_1 { + background-color: #a1aec7; +} +table.dataTable.display tbody tr:hover.selected > .sorting_2, +table.dataTable.display tbody tr.odd:hover.selected > .sorting_2, +table.dataTable.display tbody tr.even:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2, +table.dataTable.order-column.hover tbody tr.odd:hover.selected > .sorting_2, +table.dataTable.order-column.hover tbody tr.even:hover.selected > .sorting_2 { + background-color: #a2afc8; +} +table.dataTable.display tbody tr:hover.selected > .sorting_3, +table.dataTable.display tbody tr.odd:hover.selected > .sorting_3, +table.dataTable.display tbody tr.even:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3, +table.dataTable.order-column.hover tbody tr.odd:hover.selected > .sorting_3, +table.dataTable.order-column.hover tbody tr.even:hover.selected > .sorting_3 { + background-color: #a4b2cb; +} +table.dataTable.nowrap th, table.dataTable.nowrap td { + white-space: nowrap; +} +table.dataTable.compact thead th, +table.dataTable.compact thead td { + padding: 5px 9px; +} +table.dataTable.compact tfoot th, +table.dataTable.compact tfoot td { + padding: 5px 9px 3px 9px; +} +table.dataTable.compact tbody th, +table.dataTable.compact tbody td { + padding: 4px 5px; +} +table.dataTable th.dt-left, +table.dataTable td.dt-left { + text-align: left; +} +table.dataTable th.dt-center, +table.dataTable td.dt-center, +table.dataTable td.dataTables_empty { + text-align: center; +} +table.dataTable th.dt-right, +table.dataTable td.dt-right { + text-align: right; +} +table.dataTable th.dt-justify, +table.dataTable td.dt-justify { + text-align: justify; +} +table.dataTable th.dt-nowrap, +table.dataTable td.dt-nowrap { + white-space: nowrap; +} +table.dataTable thead th.dt-head-left, +table.dataTable thead td.dt-head-left, +table.dataTable tfoot th.dt-head-left, +table.dataTable tfoot td.dt-head-left { + text-align: left; +} +table.dataTable thead th.dt-head-center, +table.dataTable thead td.dt-head-center, +table.dataTable tfoot th.dt-head-center, +table.dataTable tfoot td.dt-head-center { + text-align: center; +} +table.dataTable thead th.dt-head-right, +table.dataTable thead td.dt-head-right, +table.dataTable tfoot th.dt-head-right, +table.dataTable tfoot td.dt-head-right { + text-align: right; +} +table.dataTable thead th.dt-head-justify, +table.dataTable thead td.dt-head-justify, +table.dataTable tfoot th.dt-head-justify, +table.dataTable tfoot td.dt-head-justify { + text-align: justify; +} +table.dataTable thead th.dt-head-nowrap, +table.dataTable thead td.dt-head-nowrap, +table.dataTable tfoot th.dt-head-nowrap, +table.dataTable tfoot td.dt-head-nowrap { + white-space: nowrap; +} +table.dataTable tbody th.dt-body-left, +table.dataTable tbody td.dt-body-left { + text-align: left; +} +table.dataTable tbody th.dt-body-center, +table.dataTable tbody td.dt-body-center { + text-align: center; +} +table.dataTable tbody th.dt-body-right, +table.dataTable tbody td.dt-body-right { + text-align: right; +} +table.dataTable tbody th.dt-body-justify, +table.dataTable tbody td.dt-body-justify { + text-align: justify; +} +table.dataTable tbody th.dt-body-nowrap, +table.dataTable tbody td.dt-body-nowrap { + white-space: nowrap; +} + +table.dataTable, +table.dataTable th, +table.dataTable td { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} + +/* + * Control feature layout + */ +.dataTables_wrapper { + position: relative; + clear: both; + *zoom: 1; + zoom: 1; +} +.dataTables_wrapper .dataTables_length { + float: left; +} +.dataTables_wrapper .dataTables_filter { + float: right; + text-align: right; +} +.dataTables_wrapper .dataTables_filter input { + margin-left: 0.5em; +} +.dataTables_wrapper .dataTables_info { + clear: both; + float: left; + padding-top: 0.55em; +} +.dataTables_wrapper .dataTables_paginate { + float: right; + text-align: right; +} +.dataTables_wrapper .dataTables_paginate .fg-button { + box-sizing: border-box; + display: inline-block; + min-width: 1.5em; + padding: 0.5em; + margin-left: 2px; + text-align: center; + text-decoration: none !important; + cursor: pointer; + *cursor: hand; + color: #333 !important; + border: 1px solid transparent; +} +.dataTables_wrapper .dataTables_paginate .fg-button:active { + outline: none; +} +.dataTables_wrapper .dataTables_paginate .fg-button:first-child { + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; +} +.dataTables_wrapper .dataTables_paginate .fg-button:last-child { + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} +.dataTables_wrapper .dataTables_processing { + position: absolute; + top: 50%; + left: 50%; + width: 100%; + height: 40px; + margin-left: -50%; + margin-top: -25px; + padding-top: 20px; + text-align: center; + font-size: 1.2em; + background-color: white; + background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0))); + /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); + /* Chrome10+,Safari5.1+ */ + background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); + /* FF3.6+ */ + background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); + /* IE10+ */ + background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); + /* Opera 11.10+ */ + background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%); + /* W3C */ +} +.dataTables_wrapper .dataTables_length, +.dataTables_wrapper .dataTables_filter, +.dataTables_wrapper .dataTables_info, +.dataTables_wrapper .dataTables_processing, +.dataTables_wrapper .dataTables_paginate { + color: #333; +} +.dataTables_wrapper .dataTables_scroll { + clear: both; +} +.dataTables_wrapper .dataTables_scrollBody { + *margin-top: -1px; + -webkit-overflow-scrolling: touch; +} +.dataTables_wrapper .ui-widget-header { + font-weight: normal; +} +.dataTables_wrapper .ui-toolbar { + padding: 8px; +} +.dataTables_wrapper:after { + visibility: hidden; + display: block; + content: ""; + clear: both; + height: 0; +} + +@media screen and (max-width: 767px) { + .dataTables_wrapper .dataTables_length, + .dataTables_wrapper .dataTables_filter, + .dataTables_wrapper .dataTables_info, + .dataTables_wrapper .dataTables_paginate { + float: none; + text-align: center; + } + .dataTables_wrapper .dataTables_filter, + .dataTables_wrapper .dataTables_paginate { + margin-top: 0.5em; + } +} diff --git a/htdocs/includes/jquery/plugins/datatables/media/images/Sorting icons.psd b/htdocs/includes/jquery/plugins/datatables/media/images/Sorting icons.psd new file mode 100644 index 00000000000..53b2e068507 Binary files /dev/null and b/htdocs/includes/jquery/plugins/datatables/media/images/Sorting icons.psd differ diff --git a/htdocs/includes/jquery/plugins/datatables/media/images/favicon.ico b/htdocs/includes/jquery/plugins/datatables/media/images/favicon.ico new file mode 100644 index 00000000000..6eeaa2a0d39 Binary files /dev/null and b/htdocs/includes/jquery/plugins/datatables/media/images/favicon.ico differ diff --git a/htdocs/includes/jquery/plugins/datatables/media/images/sort_asc.png b/htdocs/includes/jquery/plugins/datatables/media/images/sort_asc.png new file mode 100644 index 00000000000..e1ba61a8055 Binary files /dev/null and b/htdocs/includes/jquery/plugins/datatables/media/images/sort_asc.png differ diff --git a/htdocs/includes/jquery/plugins/datatables/media/images/sort_asc_disabled.png b/htdocs/includes/jquery/plugins/datatables/media/images/sort_asc_disabled.png new file mode 100644 index 00000000000..fb11dfe24a6 Binary files /dev/null and b/htdocs/includes/jquery/plugins/datatables/media/images/sort_asc_disabled.png differ diff --git a/htdocs/includes/jquery/plugins/datatables/media/images/sort_both.png b/htdocs/includes/jquery/plugins/datatables/media/images/sort_both.png new file mode 100644 index 00000000000..af5bc7c5a10 Binary files /dev/null and b/htdocs/includes/jquery/plugins/datatables/media/images/sort_both.png differ diff --git a/htdocs/includes/jquery/plugins/datatables/media/images/sort_desc.png b/htdocs/includes/jquery/plugins/datatables/media/images/sort_desc.png new file mode 100644 index 00000000000..0e156deb5f6 Binary files /dev/null and b/htdocs/includes/jquery/plugins/datatables/media/images/sort_desc.png differ diff --git a/htdocs/includes/jquery/plugins/datatables/media/images/sort_desc_disabled.png b/htdocs/includes/jquery/plugins/datatables/media/images/sort_desc_disabled.png new file mode 100644 index 00000000000..c9fdd8a1502 Binary files /dev/null and b/htdocs/includes/jquery/plugins/datatables/media/images/sort_desc_disabled.png differ diff --git a/htdocs/includes/jquery/plugins/datatables/media/js/jquery.dataTables.js b/htdocs/includes/jquery/plugins/datatables/media/js/jquery.dataTables.js new file mode 100644 index 00000000000..2a9bdb36e7b --- /dev/null +++ b/htdocs/includes/jquery/plugins/datatables/media/js/jquery.dataTables.js @@ -0,0 +1,14951 @@ +/*! DataTables 1.10.7 + * ©2008-2014 SpryMedia Ltd - datatables.net/license + */ + +/** + * @summary DataTables + * @description Paginate, search and order HTML tables + * @version 1.10.7 + * @file jquery.dataTables.js + * @author SpryMedia Ltd (www.sprymedia.co.uk) + * @contact www.sprymedia.co.uk/contact + * @copyright Copyright 2008-2014 SpryMedia Ltd. + * + * This source file is free software, available under the following license: + * MIT license - http://datatables.net/license + * + * This source file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. + * + * For details please refer to: http://www.datatables.net + */ + +/*jslint evil: true, undef: true, browser: true */ +/*globals $,require,jQuery,define,_selector_run,_selector_opts,_selector_first,_selector_row_indexes,_ext,_Api,_api_register,_api_registerPlural,_re_new_lines,_re_html,_re_formatted_numeric,_re_escape_regex,_empty,_intVal,_numToDecimal,_isNumber,_isHtml,_htmlNumeric,_pluck,_pluck_order,_range,_stripHtml,_unique,_fnBuildAjax,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAjaxDataSrc,_fnAddColumn,_fnColumnOptions,_fnAdjustColumnSizing,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnVisbleColumns,_fnGetColumns,_fnColumnTypes,_fnApplyColumnDefs,_fnHungarianMap,_fnCamelToHungarian,_fnLanguageCompat,_fnBrowserDetect,_fnAddData,_fnAddTr,_fnNodeToDataIndex,_fnNodeToColumnIndex,_fnGetCellData,_fnSetCellData,_fnSplitObjNotation,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnGetDataMaster,_fnClearTable,_fnDeleteIndex,_fnInvalidate,_fnGetRowElements,_fnCreateTr,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAddOptionsHtml,_fnDetectHeader,_fnGetUniqueThs,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnFilterCreateSearch,_fnEscapeRegex,_fnFilterData,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnInfoMacros,_fnInitialise,_fnInitComplete,_fnLengthChange,_fnFeatureHtmlLength,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnFeatureHtmlTable,_fnScrollDraw,_fnApplyToChildren,_fnCalculateColumnWidths,_fnThrottle,_fnConvertToWidth,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnScrollBarWidth,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/ + +(/** @lends */function( window, document, undefined ) { + +(function( factory ) { + "use strict"; + + if ( typeof define === 'function' && define.amd ) { + // Define as an AMD module if possible + define( 'datatables', ['jquery'], factory ); + } + else if ( typeof exports === 'object' ) { + // Node/CommonJS + module.exports = factory( require( 'jquery' ) ); + } + else if ( jQuery && !jQuery.fn.dataTable ) { + // Define using browser globals otherwise + // Prevent multiple instantiations if the script is loaded twice + factory( jQuery ); + } +} +(/** @lends */function( $ ) { + "use strict"; + + /** + * DataTables is a plug-in for the jQuery Javascript library. It is a highly + * flexible tool, based upon the foundations of progressive enhancement, + * which will add advanced interaction controls to any HTML table. For a + * full list of features please refer to + * [DataTables.net](href="http://datatables.net). + * + * Note that the `DataTable` object is not a global variable but is aliased + * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may + * be accessed. + * + * @class + * @param {object} [init={}] Configuration object for DataTables. Options + * are defined by {@link DataTable.defaults} + * @requires jQuery 1.7+ + * + * @example + * // Basic initialisation + * $(document).ready( function { + * $('#example').dataTable(); + * } ); + * + * @example + * // Initialisation with configuration options - in this case, disable + * // pagination and sorting. + * $(document).ready( function { + * $('#example').dataTable( { + * "paginate": false, + * "sort": false + * } ); + * } ); + */ + var DataTable; + + + /* + * It is useful to have variables which are scoped locally so only the + * DataTables functions can access them and they don't leak into global space. + * At the same time these functions are often useful over multiple files in the + * core and API, so we list, or at least document, all variables which are used + * by DataTables as private variables here. This also ensures that there is no + * clashing of variable names and that they can easily referenced for reuse. + */ + + + // Defined else where + // _selector_run + // _selector_opts + // _selector_first + // _selector_row_indexes + + var _ext; // DataTable.ext + var _Api; // DataTable.Api + var _api_register; // DataTable.Api.register + var _api_registerPlural; // DataTable.Api.registerPlural + + var _re_dic = {}; + var _re_new_lines = /[\r\n]/g; + var _re_html = /<.*?>/g; + var _re_date_start = /^[\w\+\-]/; + var _re_date_end = /[\w\+\-]$/; + + // Escape regular expression special characters + var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' ); + + // http://en.wikipedia.org/wiki/Foreign_exchange_market + // - \u20BD - Russian ruble. + // - \u20a9 - South Korean Won + // - \u20BA - Turkish Lira + // - \u20B9 - Indian Rupee + // - R - Brazil (R$) and South Africa + // - fr - Swiss Franc + // - kr - Swedish krona, Norwegian krone and Danish krone + // - \u2009 is thin space and \u202F is narrow no-break space, both used in many + // standards as thousands separators. + var _re_formatted_numeric = /[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfk]/gi; + + + var _empty = function ( d ) { + return !d || d === true || d === '-' ? true : false; + }; + + + var _intVal = function ( s ) { + var integer = parseInt( s, 10 ); + return !isNaN(integer) && isFinite(s) ? integer : null; + }; + + // Convert from a formatted number with characters other than `.` as the + // decimal place, to a Javascript number + var _numToDecimal = function ( num, decimalPoint ) { + // Cache created regular expressions for speed as this function is called often + if ( ! _re_dic[ decimalPoint ] ) { + _re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' ); + } + return typeof num === 'string' && decimalPoint !== '.' ? + num.replace( /\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) : + num; + }; + + + var _isNumber = function ( d, decimalPoint, formatted ) { + var strType = typeof d === 'string'; + + // If empty return immediately so there must be a number if it is a + // formatted string (this stops the string "k", or "kr", etc being detected + // as a formatted number for currency + if ( _empty( d ) ) { + return true; + } + + if ( decimalPoint && strType ) { + d = _numToDecimal( d, decimalPoint ); + } + + if ( formatted && strType ) { + d = d.replace( _re_formatted_numeric, '' ); + } + + return !isNaN( parseFloat(d) ) && isFinite( d ); + }; + + + // A string without HTML in it can be considered to be HTML still + var _isHtml = function ( d ) { + return _empty( d ) || typeof d === 'string'; + }; + + + var _htmlNumeric = function ( d, decimalPoint, formatted ) { + if ( _empty( d ) ) { + return true; + } + + var html = _isHtml( d ); + return ! html ? + null : + _isNumber( _stripHtml( d ), decimalPoint, formatted ) ? + true : + null; + }; + + + var _pluck = function ( a, prop, prop2 ) { + var out = []; + var i=0, ien=a.length; + + // Could have the test in the loop for slightly smaller code, but speed + // is essential here + if ( prop2 !== undefined ) { + for ( ; i') + .css( { + position: 'absolute', + top: 0, + left: 0, + height: 1, + width: 1, + overflow: 'hidden' + } ) + .append( + $('
    ') + .css( { + position: 'absolute', + top: 1, + left: 1, + width: 100, + overflow: 'scroll' + } ) + .append( + $('
    ') + .css( { + width: '100%', + height: 10 + } ) + ) + ) + .appendTo( 'body' ); + + var test = n.find('.test'); + + // IE6/7 will oversize a width 100% element inside a scrolling element, to + // include the width of the scrollbar, while other browsers ensure the inner + // element is contained without forcing scrolling + browser.bScrollOversize = test[0].offsetWidth === 100; + + // In rtl text layout, some browsers (most, but not all) will place the + // scrollbar on the left, rather than the right. + browser.bScrollbarLeft = Math.round( test.offset().left ) !== 1; + + n.remove(); + } + + + /** + * Array.prototype reduce[Right] method, used for browsers which don't support + * JS 1.6. Done this way to reduce code size, since we iterate either way + * @param {object} settings dataTables settings object + * @memberof DataTable#oApi + */ + function _fnReduce ( that, fn, init, start, end, inc ) + { + var + i = start, + value, + isSet = false; + + if ( init !== undefined ) { + value = init; + isSet = true; + } + + while ( i !== end ) { + if ( ! that.hasOwnProperty(i) ) { + continue; + } + + value = isSet ? + fn( value, that[i], i, that ) : + that[i]; + + isSet = true; + i += inc; + } + + return value; + } + + /** + * Add a column to the list used for the table with default values + * @param {object} oSettings dataTables settings object + * @param {node} nTh The th element for this column + * @memberof DataTable#oApi + */ + function _fnAddColumn( oSettings, nTh ) + { + // Add column to aoColumns array + var oDefaults = DataTable.defaults.column; + var iCol = oSettings.aoColumns.length; + var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, { + "nTh": nTh ? nTh : document.createElement('th'), + "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '', + "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol], + "mData": oDefaults.mData ? oDefaults.mData : iCol, + idx: iCol + } ); + oSettings.aoColumns.push( oCol ); + + // Add search object for column specific search. Note that the `searchCols[ iCol ]` + // passed into extend can be undefined. This allows the user to give a default + // with only some of the parameters defined, and also not give a default + var searchCols = oSettings.aoPreSearchCols; + searchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] ); + + // Use the default column options function to initialise classes etc + _fnColumnOptions( oSettings, iCol, $(nTh).data() ); + } + + + /** + * Apply options for a column + * @param {object} oSettings dataTables settings object + * @param {int} iCol column index to consider + * @param {object} oOptions object with sType, bVisible and bSearchable etc + * @memberof DataTable#oApi + */ + function _fnColumnOptions( oSettings, iCol, oOptions ) + { + var oCol = oSettings.aoColumns[ iCol ]; + var oClasses = oSettings.oClasses; + var th = $(oCol.nTh); + + // Try to get width information from the DOM. We can't get it from CSS + // as we'd need to parse the CSS stylesheet. `width` option can override + if ( ! oCol.sWidthOrig ) { + // Width attribute + oCol.sWidthOrig = th.attr('width') || null; + + // Style attribute + var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%]+)/); + if ( t ) { + oCol.sWidthOrig = t[1]; + } + } + + /* User specified column options */ + if ( oOptions !== undefined && oOptions !== null ) + { + // Backwards compatibility + _fnCompatCols( oOptions ); + + // Map camel case parameters to their Hungarian counterparts + _fnCamelToHungarian( DataTable.defaults.column, oOptions ); + + /* Backwards compatibility for mDataProp */ + if ( oOptions.mDataProp !== undefined && !oOptions.mData ) + { + oOptions.mData = oOptions.mDataProp; + } + + if ( oOptions.sType ) + { + oCol._sManualType = oOptions.sType; + } + + // `class` is a reserved word in Javascript, so we need to provide + // the ability to use a valid name for the camel case input + if ( oOptions.className && ! oOptions.sClass ) + { + oOptions.sClass = oOptions.className; + } + + $.extend( oCol, oOptions ); + _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" ); + + /* iDataSort to be applied (backwards compatibility), but aDataSort will take + * priority if defined + */ + if ( oOptions.iDataSort !== undefined ) + { + oCol.aDataSort = [ oOptions.iDataSort ]; + } + _fnMap( oCol, oOptions, "aDataSort" ); + } + + /* Cache the data get and set functions for speed */ + var mDataSrc = oCol.mData; + var mData = _fnGetObjectDataFn( mDataSrc ); + var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null; + + var attrTest = function( src ) { + return typeof src === 'string' && src.indexOf('@') !== -1; + }; + oCol._bAttrSrc = $.isPlainObject( mDataSrc ) && ( + attrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter) + ); + + oCol.fnGetData = function (rowData, type, meta) { + var innerData = mData( rowData, type, undefined, meta ); + + return mRender && type ? + mRender( innerData, type, rowData, meta ) : + innerData; + }; + oCol.fnSetData = function ( rowData, val, meta ) { + return _fnSetObjectDataFn( mDataSrc )( rowData, val, meta ); + }; + + // Indicate if DataTables should read DOM data as an object or array + // Used in _fnGetRowElements + if ( typeof mDataSrc !== 'number' ) { + oSettings._rowReadObject = true; + } + + /* Feature sorting overrides column specific when off */ + if ( !oSettings.oFeatures.bSort ) + { + oCol.bSortable = false; + th.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called + } + + /* Check that the class assignment is correct for sorting */ + var bAsc = $.inArray('asc', oCol.asSorting) !== -1; + var bDesc = $.inArray('desc', oCol.asSorting) !== -1; + if ( !oCol.bSortable || (!bAsc && !bDesc) ) + { + oCol.sSortingClass = oClasses.sSortableNone; + oCol.sSortingClassJUI = ""; + } + else if ( bAsc && !bDesc ) + { + oCol.sSortingClass = oClasses.sSortableAsc; + oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed; + } + else if ( !bAsc && bDesc ) + { + oCol.sSortingClass = oClasses.sSortableDesc; + oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed; + } + else + { + oCol.sSortingClass = oClasses.sSortable; + oCol.sSortingClassJUI = oClasses.sSortJUI; + } + } + + + /** + * Adjust the table column widths for new data. Note: you would probably want to + * do a redraw after calling this function! + * @param {object} settings dataTables settings object + * @memberof DataTable#oApi + */ + function _fnAdjustColumnSizing ( settings ) + { + /* Not interested in doing column width calculation if auto-width is disabled */ + if ( settings.oFeatures.bAutoWidth !== false ) + { + var columns = settings.aoColumns; + + _fnCalculateColumnWidths( settings ); + for ( var i=0 , iLen=columns.length ; i