NEW : Display extrafields (for lines/det into line tr instead of ugly other tr

This commit is contained in:
Florian HENRY 2020-12-22 12:52:01 +01:00
parent 3deed4678c
commit fefc9040ab
6 changed files with 293 additions and 31 deletions

View File

@ -59,4 +59,4 @@
"ext-zip" : "ODT, Excel and file compression support",
"ext-xml" : "Excel support"
}
}
}

View File

@ -100,4 +100,255 @@ abstract class CommonObjectLine extends CommonObject
// Currently we need function at end of file CommonObject for all object lines. Should find a way to avoid duplicate code.
// For the moment we use the extends on CommonObject until PHP min is 5.4 so use Traits.
/**
* Function to show lines of extrafields with output datas.
* This function is responsible to output the <tr> and <td> according to correct number of columns received into $params['colspan']
*
* @param Extrafields $extrafields Extrafield Object
* @param string $mode Show output ('view') or input ('create' or 'edit') for extrafield
* @param array $params Optional parameters. Example: array('style'=>'class="oddeven"', 'colspan'=>$colspan)
* @param string $keysuffix Suffix string to add after name and id of field (can be used to avoid duplicate names)
* @param string $keyprefix Prefix string to add before name and id of field (can be used to avoid duplicate names)
* @param string $onetrtd All fields in same tr td. Used by objectline_create.tpl.php for example.
* @return string
*/
public function showOptionals($extrafields, $mode = 'view', $params = null, $keysuffix = '', $keyprefix = '', $onetrtd = 0)
{
global $db, $conf, $langs, $action, $form, $hookmanager;
if (!is_object($form)) $form = new Form($db);
$out = '';
$parameters = array();
$reshook = $hookmanager->executeHooks('showOptionals', $parameters, $this, $action); // Note that $action and $object may have been modified by hook
if (empty($reshook))
{
if (is_array($extrafields->attributes[$this->table_element]['label']) && count($extrafields->attributes[$this->table_element]['label']) > 0)
{
$out .= "\n";
$out .= '<!-- showOptionals --> ';
$out .= "\n";
$extrafields_collapse_num = '';
$e = 0;
foreach ($extrafields->attributes[$this->table_element]['label'] as $key=>$label)
{
// Show only the key field in params
if (is_array($params) && array_key_exists('onlykey', $params) && $key != $params['onlykey']) continue;
// Test on 'enabled' ('enabled' is different than 'list' = 'visibility')
$enabled = 1;
if ($enabled && isset($extrafields->attributes[$this->table_element]['enabled'][$key]))
{
$enabled = dol_eval($extrafields->attributes[$this->table_element]['enabled'][$key], 1);
}
if (empty($enabled)) continue;
$visibility = 1;
if ($visibility && isset($extrafields->attributes[$this->table_element]['list'][$key]))
{
$visibility = dol_eval($extrafields->attributes[$this->table_element]['list'][$key], 1);
}
$perms = 1;
if ($perms && isset($extrafields->attributes[$this->table_element]['perms'][$key]))
{
$perms = dol_eval($extrafields->attributes[$this->table_element]['perms'][$key], 1);
}
if (($mode == 'create') && abs($visibility) != 1 && abs($visibility) != 3) continue; // <> -1 and <> 1 and <> 3 = not visible on forms, only on list
elseif (($mode == 'edit') && abs($visibility) != 1 && abs($visibility) != 3 && abs($visibility) != 4) continue; // <> -1 and <> 1 and <> 3 = not visible on forms, only on list and <> 4 = not visible at the creation
elseif ($mode == 'view' && empty($visibility)) continue;
if (empty($perms)) continue;
// Load language if required
if (!empty($extrafields->attributes[$this->table_element]['langfile'][$key])) {
$langs->load($extrafields->attributes[$this->table_element]['langfile'][$key]);
}
switch ($mode) {
case "view":
$value = $this->array_options["options_".$key.$keysuffix]; // Value may be clean or formated later
break;
case "create":
case "edit":
// We get the value of property found with GETPOST so it takes into account:
// default values overwrite, restore back to list link, ... (but not 'default value in database' of field)
$check = 'alphanohtml';
if (in_array($extrafields->attributes[$this->table_element]['type'][$key], array('html', 'text'))) {
$check = 'restricthtml';
}
$getposttemp = GETPOST($keyprefix.'options_'.$key.$keysuffix, $check, 3); // GETPOST can get value from GET, POST or setup of default values overwrite.
// GETPOST("options_" . $key) can be 'abc' or array(0=>'abc')
if (is_array($getposttemp) || $getposttemp != '' || GETPOSTISSET($keyprefix.'options_'.$key.$keysuffix))
{
if (is_array($getposttemp)) {
// $getposttemp is an array but following code expects a comma separated string
$value = implode(",", $getposttemp);
} else {
$value = $getposttemp;
}
} else {
$value = $this->array_options["options_".$key]; // No GET, no POST, no default value, so we take value of object.
}
//var_dump($keyprefix.' - '.$key.' - '.$keysuffix.' - '.$keyprefix.'options_'.$key.$keysuffix.' - '.$this->array_options["options_".$key.$keysuffix].' - '.$getposttemp.' - '.$value);
break;
}
if ($extrafields->attributes[$this->table_element]['type'][$key] == 'separate')
{
$extrafields_collapse_num = '';
$extrafield_param = $extrafields->attributes[$this->table_element]['param'][$key];
if (!empty($extrafield_param) && is_array($extrafield_param)) {
$extrafield_param_list = array_keys($extrafield_param['options']);
if (count($extrafield_param_list) > 0) {
$extrafield_collapse_display_value = intval($extrafield_param_list[0]);
if ($extrafield_collapse_display_value == 1 || $extrafield_collapse_display_value == 2) {
$extrafields_collapse_num = $extrafields->attributes[$this->table_element]['pos'][$key];
}
}
}
$out .= $extrafields->showSeparator($key, $this, 0, 'line');
} else {
$class = (!empty($extrafields->attributes[$this->table_element]['hidden'][$key]) ? 'hideobject ' : '');
$csstyle = '';
if (is_array($params) && count($params) > 0) {
if (array_key_exists('class', $params)) {
$class .= $params['class'].' ';
}
if (array_key_exists('style', $params)) {
$csstyle = $params['style'];
}
}
// add html5 elements
$domData = ' data-element="extrafield"';
$domData .= ' data-targetelement="'.$this->element.'"';
$domData .= ' data-targetid="'.$this->id.'"';
$html_id = (empty($this->id) ? '' : 'extrarow-'.$this->element.'_'.$key.'_'.$this->id);
// Convert date into timestamp format (value in memory must be a timestamp)
if (in_array($extrafields->attributes[$this->table_element]['type'][$key], array('date', 'datetime')))
{
$datenotinstring = $this->array_options['options_'.$key];
if (!is_numeric($this->array_options['options_'.$key])) // For backward compatibility
{
$datenotinstring = $this->db->jdate($datenotinstring);
}
$value = (GETPOSTISSET($keyprefix.'options_'.$key.$keysuffix)) ? dol_mktime(GETPOST($keyprefix.'options_'.$key.$keysuffix."hour", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."min", 'int', 3), 0, GETPOST($keyprefix.'options_'.$key.$keysuffix."month", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."day", 'int', 3), GETPOST($keyprefix.'options_'.$key.$keysuffix."year", 'int', 3)) : $datenotinstring;
}
// Convert float submited string into real php numeric (value in memory must be a php numeric)
if (in_array($extrafields->attributes[$this->table_element]['type'][$key], array('price', 'double')))
{
$value = (GETPOSTISSET($keyprefix.'options_'.$key.$keysuffix) || $value) ? price2num($value) : $this->array_options['options_'.$key];
}
// HTML, text, select, integer and varchar: take into account default value in database if in create mode
if (in_array($extrafields->attributes[$this->table_element]['type'][$key], array('html', 'text', 'varchar', 'select', 'int')))
{
if ($action == 'create') $value = (GETPOSTISSET($keyprefix.'options_'.$key.$keysuffix) || $value) ? $value : $extrafields->attributes[$this->table_element]['default'][$key];
}
$labeltoshow = $langs->trans($label);
$helptoshow = $langs->trans($extrafields->attributes[$this->table_element]['help'][$key]);
$out .= '<div '.($html_id ? 'id="'.$html_id.'" ' : '').$csstyle.' class="'.$class.$this->element.'_extras_'.$key.' trextrafields_collapse'.$extrafields_collapse_num.(!empty($this->id)?'_'.$this->id:'').'" '.$domData.' >';
$out .= '<div style="display: inline-block; padding-right:4px" class="wordbreak';
//$out .= "titlefield";
//if (GETPOST('action', 'restricthtml') == 'create') $out.='create';
// BUG #11554 : For public page, use red dot for required fields, instead of bold label
$tpl_context = isset($params["tpl_context"]) ? $params["tpl_context"] : "none";
if ($tpl_context == "public") { // Public page : red dot instead of fieldrequired characters
$out .= '">';
if (!empty($extrafields->attributes[$this->table_element]['help'][$key])) $out .= $form->textwithpicto($labeltoshow, $helptoshow);
else $out .= $labeltoshow;
if ($mode != 'view' && !empty($extrafields->attributes[$this->table_element]['required'][$key])) $out .= '&nbsp;<font color="red">*</font>';
} else {
if ($mode != 'view' && !empty($extrafields->attributes[$this->table_element]['required'][$key])) $out .= ' fieldrequired';
$out .= '">';
if (!empty($extrafields->attributes[$this->table_element]['help'][$key])) $out .= $form->textwithpicto($labeltoshow, $helptoshow);
else $out .= $labeltoshow;
}
$out .= '</div>';
$html_id = !empty($this->id) ? $this->element.'_extras_'.$key.'_'.$this->id : '';
$out .= '<div '.($html_id ? 'id="'.$html_id.'" ' : '').'style="display: inline-block" class="'.$this->element.'_extras_'.$key.'">';
switch ($mode) {
case "view":
$out .= $extrafields->showOutputField($key, $value);
break;
case "create":
$out .= $extrafields->showInputField($key, $value, '', $keysuffix, '', 0, $this->id, $this->table_element);
break;
case "edit":
$out .= $extrafields->showInputField($key, $value, '', $keysuffix, '', 0, $this->id, $this->table_element);
break;
}
$out .= '</div>';
/*for($ii = 0; $ii < ($colspan - 1); $ii++)
{
$out .='<td class="'.$this->element.'_extras_'.$key.'"></td>';
}*/
if (!empty($conf->global->MAIN_EXTRAFIELDS_USE_TWO_COLUMS) && (($e % 2) == 1)) $out .= '</div>';
else $out .= '</div>';
$e++;
}
}
$out .= "\n";
// Add code to manage list depending on others
if (!empty($conf->use_javascript_ajax)) {
$out .= '
<script>
jQuery(document).ready(function() {
function showOptions(child_list, parent_list, orig_select)
{
var val = $("select[name=\""+parent_list+"\"]").val();
var parentVal = parent_list + ":" + val;
if(val > 0) {
var options = orig_select.find("option[parent=\""+parentVal+"\"]").clone();
$("select[name=\""+child_list+"\"] option[parent]").remove();
$("select[name=\""+child_list+"\"]").append(options);
} else {
var options = orig_select.find("option[parent]").clone();
$("select[name=\""+child_list+"\"] option[parent]").remove();
$("select[name=\""+child_list+"\"]").append(options);
}
}
function setListDependencies() {
jQuery("select option[parent]").parent().each(function() {
var orig_select = {};
var child_list = $(this).attr("name");
orig_select[child_list] = $(this).clone();
var parent = $(this).find("option[parent]:first").attr("parent");
var infos = parent.split(":");
var parent_list = infos[0];
$("select[name=\""+parent_list+"\"]").change(function() {
showOptions(child_list, parent_list, orig_select[child_list]);
});
});
}
setListDependencies();
});
</script>'."\n";
}
$out .= '<!-- /showOptionals --> '."\n";
}
}
$out .= $hookmanager->resPrint;
return $out;
}
}

View File

@ -1912,15 +1912,28 @@ class ExtraFields
* @param string $key Key of attribute
* @param string $object Object
* @param int $colspan Value of colspan to use (it must includes the first column with title)
* @param string $typeform "card" for from display, "line" for docuement line display (exstraiedls on propal line, order line, etc...)
* @return string HTML code with line for separator
*/
public function showSeparator($key, $object, $colspan = 2)
public function showSeparator($key, $object, $colspan = 2, $typeform='card')
{
global $langs;
$out = '<tr id="trextrafieldseparator'.$key.'" class="trextrafieldseparator trextrafieldseparator'.$key.'"><td colspan="'.$colspan.'"><strong>';
if ($typeform=='card') {
$tagtype='tr';
$tagtype_dyn='td';
}elseif ($typeform=='line') {
$tagtype='div';
$tagtype_dyn='span';
}
$out = '<'.$tagtype.' id="trextrafieldseparator'.$key.(!empty($object->id)?'_'.$object->id:'').'" class="trextrafieldseparator trextrafieldseparator'.$key.(!empty($object->id)?'_'.$object->id:'').'">';
$out .= '<'.$tagtype_dyn.' '.(!empty($colspan)?'colspan="' . $colspan . '"':'').'>';
$out .='<strong>';
$out .= $langs->trans($this->attributes[$object->table_element]['label'][$key]);
$out .= '</strong></td></tr>';
$out .= '</strong>';
$out .= '</'.$tagtype_dyn.'>';
$out .= '</'.$tagtype.'>';
$extrafield_param = $this->attributes[$object->table_element]['param'][$key];
if (!empty($extrafield_param) && is_array($extrafield_param)) {
@ -1930,27 +1943,27 @@ class ExtraFields
$extrafield_collapse_display_value = intval($extrafield_param_list[0]);
if ($extrafield_collapse_display_value == 1 || $extrafield_collapse_display_value == 2) {
// Set the collapse_display status to cookie in priority or if ignorecollapsesetup is 1, if cookie and ignorecollapsesetup not defined, use the setup.
$collapse_display = ((isset($_COOKIE['DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key]) || GETPOST('ignorecollapsesetup', 'int')) ? ($_COOKIE['DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key] ? true : false) : ($extrafield_collapse_display_value == 2 ? false : true));
$extrafields_collapse_num = $this->attributes[$object->table_element]['pos'][$key];
$collapse_display = ((isset($_COOKIE['DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key.(!empty($object->id)?'_'.$object->id:'')]) || GETPOST('ignorecollapsesetup', 'int')) ? ($_COOKIE['DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key.(!empty($object->id)?'_'.$object->id:'')] ? true : false) : ($extrafield_collapse_display_value == 2 ? false : true));
$extrafields_collapse_num = $this->attributes[$object->table_element]['pos'][$key].(!empty($object->id)?'_'.$object->id:'');
$out .= '<!-- Add js script to manage the collpase/uncollapse of extrafields separators '.$key.' -->';
$out .= '<script type="text/javascript">';
$out .= 'jQuery(document).ready(function(){';
if ($collapse_display === false) {
$out .= ' jQuery("#trextrafieldseparator'.$key.' td").prepend("<span class=\"cursorpointer far fa-plus-square\"></span>&nbsp;");'."\n";
$out .= ' jQuery("#trextrafieldseparator'.$key.(!empty($object->id)?'_'.$object->id:'').' '.$tagtype_dyn.'").prepend("<span class=\"cursorpointer far fa-plus-square\"></span>&nbsp;");'."\n";
$out .= ' jQuery(".trextrafields_collapse'.$extrafields_collapse_num.'").hide();'."\n";
} else {
$out .= ' jQuery("#trextrafieldseparator'.$key.' td").prepend("<span class=\"cursorpointer far fa-minus-square\"></span>&nbsp;");'."\n";
$out .= ' jQuery("#trextrafieldseparator'.$key.(!empty($object->id)?'_'.$object->id:'').' '.$tagtype_dyn.'").prepend("<span class=\"cursorpointer far fa-minus-square\"></span>&nbsp;");'."\n";
$out .= ' document.cookie = "DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key.'=1; path='.$_SERVER["PHP_SELF"].'"'."\n";
}
$out .= ' jQuery("#trextrafieldseparator'.$key.'").click(function(){'."\n";
$out .= ' jQuery("#trextrafieldseparator'.$key.(!empty($object->id)?'_'.$object->id:'').'").click(function(){'."\n";
$out .= ' jQuery(".trextrafields_collapse'.$extrafields_collapse_num.'").toggle(300, function(){'."\n";
$out .= ' if (jQuery(".trextrafields_collapse'.$extrafields_collapse_num.'").is(":hidden")) {'."\n";
$out .= ' jQuery("#trextrafieldseparator'.$key.' td span").addClass("fa-plus-square").removeClass("fa-minus-square");'."\n";
$out .= ' document.cookie = "DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key.'=0; path='.$_SERVER["PHP_SELF"].'"'."\n";
$out .= ' jQuery("#trextrafieldseparator'.$key.(!empty($object->id)?'_'.$object->id:'').' '.$tagtype_dyn.' span").addClass("fa-plus-square").removeClass("fa-minus-square");'."\n";
$out .= ' document.cookie = "DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key.(!empty($object->id)?'_'.$object->id:'').'=0; path='.$_SERVER["PHP_SELF"].'"'."\n";
$out .= ' } else {'."\n";
$out .= ' jQuery("#trextrafieldseparator'.$key.' td span").addClass("fa-minus-square").removeClass("fa-plus-square");'."\n";
$out .= ' document.cookie = "DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key.'=1; path='.$_SERVER["PHP_SELF"].'"'."\n";
$out .= ' jQuery("#trextrafieldseparator'.$key.(!empty($object->id)?'_'.$object->id:'').' '.$tagtype_dyn.' span").addClass("fa-minus-square").removeClass("fa-plus-square");'."\n";
$out .= ' document.cookie = "DOLCOLLAPSE_'.$object->table_element.'_extrafields_'.$key.(!empty($object->id)?'_'.$object->id:'').'=1; path='.$_SERVER["PHP_SELF"].'"'."\n";
$out .= ' }'."\n";
$out .= ' });';
$out .= ' });';

View File

@ -319,6 +319,9 @@ if ($nolinesbefore) {
echo $form->selectyesno('date_end_fill', $line->date_end_fill, 1);
echo '</div>';
}
if (is_object($objectline)) {
print $objectline->showOptionals($extrafields, 'edit', array(), '', '', 1);
}
echo '</td>';
if ($object->element == 'supplier_proposal' || $object->element == 'order_supplier' || $object->element == 'invoice_supplier') // We must have same test in printObjectLines
{
@ -412,10 +415,6 @@ if ($nolinesbefore) {
</tr>
<?php
if (is_object($objectline)) {
print $objectline->showOptionals($extrafields, 'edit', array('colspan'=>$coldisplay), '', '', 1);
}
if ((!empty($conf->service->enabled) || ($object->element == 'contrat')) && $dateSelector && GETPOST('type') != '0') // We show date field if required
{
print '<tr id="trlinefordates" class="oddeven">'."\n";

View File

@ -125,6 +125,12 @@ $coldisplay++;
print '<textarea id="product_desc" class="flat" name="product_desc" readonly style="width: 200px; height:80px;">'.$line->description.'</textarea>';
}
//Line extrafield
if (!empty($extrafields))
{
print $line->showOptionals($extrafields, 'edit', array('class'=>'tredited'), '', '', 1);
}
// Show autofill date for recuring invoices
if (!empty($conf->service->enabled) && $line->product_type == 1 && $line->element == 'facturedetrec')
{
@ -260,14 +266,6 @@ $coldisplay++;
</td>
</tr>
<?php
//Line extrafield
if (!empty($extrafields))
{
print $line->showOptionals($extrafields, 'edit', array('class'=>'tredited', 'colspan'=>$coldisplay), '', '', 1);
}
?>
<?php if (!empty($conf->service->enabled) && $line->product_type == 1 && $dateSelector) { ?>
<tr id="service_duration_area" class="treditedlinefordate">
<?php if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { ?>

View File

@ -158,6 +158,13 @@ if (($line->info_bits & 2) == 2) {
{
print (!empty($line->description) && $line->description != $line->product_label) ? '<br>'.dol_htmlentitiesbr($line->description) : '';
}
//Line extrafield
if (!empty($extrafields))
{
print '<div style="padding-top: 10px" id="extrafield_lines_area_'.$line->id.'" name="extrafield_lines_area_'.$line->id.'">';
print $line->showOptionals($extrafields, 'view', array(), '', '', 1);
print '</div>';
}
}
if ($user->rights->fournisseur->lire && $line->fk_fournprice > 0)
@ -361,10 +368,4 @@ if ($action == 'selectlines') { ?>
print "</tr>\n";
//Line extrafield
if (!empty($extrafields))
{
print $line->showOptionals($extrafields, 'view', array('style'=>'class="drag drop oddeven"', 'colspan'=>$coldisplay), '', '', 1);
}
print "<!-- END PHP TEMPLATE objectline_view.tpl.php -->\n";