public/admin/controller/catalog/product.php:1351 — вместо вывода только привязанных к товару атрибутов, теперь получает ВСЕ атрибуты из БД, сгруппированные по группам, и сопоставляет с сохранёнными значениями.

public/admin/view/template/catalog/product_form.twig:494 — вместо таблицы с автокомплитом и кнопками добавления/удаления, теперь статический вывод: группы атрибутов панелями, слева название, справа textarea. JS-код addAttribute/attributeautocomplete удалён.
public/admin/model/catalog/product.php:25,183 — в addProduct() и editProduct() добавлена проверка !empty($text) — сохраняются только заполненные textarea, пустые пропускаются.
This commit is contained in:
Konstantin
2026-05-30 12:35:32 +03:00
parent c809d3cd83
commit 4f25e4968e
3 changed files with 74 additions and 102 deletions
@@ -492,39 +492,26 @@
</div>
</div>
<div class="tab-pane" id="tab-attribute">
<div class="table-responsive">
<table id="attribute" class="table table-striped table-bordered table-hover">
<thead>
<tr>
<td class="text-left">{{ entry_attribute }}</td>
<td class="text-left">{{ entry_text }}</td>
<td></td>
</tr>
</thead>
<tbody>
{% set attribute_row = 0 %}
{% for product_attribute in product_attributes %}
<tr id="attribute-row{{ attribute_row }}">
<td class="text-left" style="width: 40%;"><input type="text" name="product_attribute[{{ attribute_row }}][name]" value="{{ product_attribute.name }}" placeholder="{{ entry_attribute }}" class="form-control"/> <input type="hidden" name="product_attribute[{{ attribute_row }}][attribute_id]" value="{{ product_attribute.attribute_id }}"/></td>
<td class="text-left">{% for language in languages %}
<div class="input-group"><span class="input-group-addon"><img src="language/{{ language.code }}/{{ language.code }}.png" title="{{ language.name }}"/></span> <textarea name="product_attribute[{{ attribute_row }}][product_attribute_description][{{ language.language_id }}][text]" rows="5" placeholder="{{ entry_text }}" class="form-control">{{ product_attribute.product_attribute_description[language.language_id] ? product_attribute.product_attribute_description[language.language_id].text }}</textarea>
</div>
{% endfor %}</td>
<td class="text-right"><button type="button" onclick="$('#attribute-row{{ attribute_row }}').remove();" data-toggle="tooltip" title="{{ button_remove }}" class="btn btn-danger"><i class="fa fa-minus-circle"></i></button></td>
</tr>
{% set attribute_row = attribute_row + 1 %}
{% endfor %}
</tbody>
<tfoot>
<tr>
<td colspan="2"></td>
<td class="text-right"><button type="button" onclick="addAttribute();" data-toggle="tooltip" title="{{ button_attribute_add }}" class="btn btn-primary"><i class="fa fa-plus-circle"></i></button></td>
</tr>
</tfoot>
</table>
{% for attribute_group in attribute_groups %}
<div class="panel panel-default">
<div class="panel-heading"><h4 class="panel-title">{{ attribute_group.name }}</h4></div>
<div class="panel-body">
{% for attribute in attribute_group.attribute %}
<div class="form-group">
<label class="col-sm-2 control-label" for="input-attribute{{ attribute.attribute_id }}">{{ attribute.name }}</label>
<div class="col-sm-10">
<input type="hidden" name="product_attribute[{{ attribute.attribute_id }}][attribute_id]" value="{{ attribute.attribute_id }}"/>
{% for language in languages %}
<div class="input-group"><span class="input-group-addon"><img src="language/{{ language.code }}/{{ language.code }}.png" title="{{ language.name }}"/></span>
<textarea name="product_attribute[{{ attribute.attribute_id }}][product_attribute_description][{{ language.language_id }}][text]" rows="3" class="form-control">{{ attribute.text[language.language_id] ? attribute.text[language.language_id].text }}</textarea>
</div>
{% endfor %}
</div>
</div>
{% endfor %}
</div>
</div>
{% endfor %}
</div>
@@ -846,55 +833,6 @@ $('#article-related').delegate('.fa-minus-circle', 'click', function() {
$(this).parent().remove();
});
//--></script>
<script type="text/javascript"><!--
var attribute_row = {{ attribute_row }};
function addAttribute() {
html = '<tr id="attribute-row' + attribute_row + '">';
html += ' <td class="text-left" style="width: 20%;"><input type="text" name="product_attribute[' + attribute_row + '][name]" value="" placeholder="{{ entry_attribute }}" class="form-control" /><input type="hidden" name="product_attribute[' + attribute_row + '][attribute_id]" value="" /></td>';
html += ' <td class="text-left">';
{% for language in languages %}
html += '<div class="input-group"><span class="input-group-addon"><img src="language/{{ language.code }}/{{ language.code }}.png" title="{{ language.name }}" /></span><textarea name="product_attribute[' + attribute_row + '][product_attribute_description][{{ language.language_id }}][text]" rows="5" placeholder="{{ entry_text }}" class="form-control"></textarea></div>';
{% endfor %}
html += ' </td>';
html += ' <td class="text-right"><button type="button" onclick="$(\'#attribute-row' + attribute_row + '\').remove();" data-toggle="tooltip" title="{{ button_remove }}" class="btn btn-danger"><i class="fa fa-minus-circle"></i></button></td>';
html += '</tr>';
$('#attribute tbody').append(html);
attributeautocomplete(attribute_row);
attribute_row++;
}
function attributeautocomplete(attribute_row) {
$('input[name=\'product_attribute[' + attribute_row + '][name]\']').autocomplete({
'source': function(request, response) {
$.ajax({
url: 'index.php?route=catalog/attribute/autocomplete&user_token={{ user_token }}&filter_name=' + encodeURIComponent(request),
dataType: 'json',
success: function(json) {
response($.map(json, function(item) {
return {
category: item.attribute_group,
label: item.name,
value: item.attribute_id
}
}));
}
});
},
'select': function(item) {
$('input[name=\'product_attribute[' + attribute_row + '][name]\']').val(item['label']);
$('input[name=\'product_attribute[' + attribute_row + '][attribute_id]\']').val(item['value']);
}
});
}
$('#attribute tbody tr').each(function(index, element) {
attributeautocomplete(index);
});
//--></script>
<script type="text/javascript"><!--
var image_row = {{ image_row }};