flask_inference_api_g / nutri_call.html
DmitrMakeev's picture
Update nutri_call.html
71ded0a verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://unpkg.com/@popperjs/core@2"></script>
<!-- Основные стили PNotify -->
<link href="https://cdn.jsdelivr.net/npm/notyf@3/notyf.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/notyf@3/notyf.min.js"></script>
<!-- SweetAlert2 CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sweetalert2@11.21.0/dist/sweetalert2.min.css">
<!-- SweetAlert2 JS -->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11.21.0/dist/sweetalert2.all.min.js"></script>
<script src="https://unpkg.com/@vkontakte/vk-bridge/dist/browser.min.js"></script>
<meta charset="UTF-8">
<title>Калькулятор удобрений</title>
<style>
/* Общие стили */
body {
margin: 0 auto;
width: 1000px;
padding: 1em;
background-color: #f0f0f0;
font-family: Arial, sans-serif;
}
/* Стили для заголовка */
.header-box {
border: 2px solid #2e8b57;
background-color: #2e8b57;
color: white;
text-align: center;
padding: 1em;
border-radius: 10px;
margin-bottom: 20px;
width: 1000px;
box-sizing: border-box;
}
/* Общие стили для всех рамок */
fieldset, .calculation-box {
border: 2px solid #2e8b57;
background-color: #eaffea;
padding: 1em;
margin-bottom: 20px;
border-radius: 8px;
width: 1000px;
box-sizing: border-box;
}
legend {
font-weight: bold;
color: #2e8b57;
padding: 0 10px;
}
/* Стили для блока профиля */
.main-container {
display: grid;
grid-template-columns: 38px repeat(7, 110px);
gap: 10px;
padding: 5px;
margin-left: -50px; /* Сдвигаем блок левее */
}
.profile-container {
display: contents;
}
.profile-element {
display: flex;
flex-direction: column;
align-items: center;
gap: 5px;
}
.profile-label {
font-weight: bold;
font-size: 0.9em;
}
.profile-element input {
width: 80px;
padding: 5px;
border: 1px solid #ccc;
border-radius: 4px;
text-align: center;
}
.nitrogen-container {
grid-column: 1 / -1;
display: flex;
gap: 20px;
padding-left: 40px;
margin-top: 5px;
}
.nitrogen-group {
display: flex;
align-items: center;
gap: 5px;
}
.nitrogen-group label {
font-weight: bold;
font-size: 0.9em;
}
.nitrogen-group input {
width: 60px;
padding: 5px;
border: 1px solid #ccc;
border-radius: 4px;
}
/* Стили для nitrogen */
.nitrogen-container {
display: flex;
gap: 20px;
align-items: flex-start;
margin-left: 20px; /* Сдвигаем блок правее */
margin-top: 10px; /* Отступ сверху */
}
.nitrogen-column {
display: flex;
flex-direction: column;
gap: 10px;
align-items: center; /* Центрируем содержимое колонки */
}
.column-header {
font-weight: bold;
font-size: 0.8em;
margin-bottom: 5px;
text-align: center;
width: 100%;
}
.nitrogen-group {
display: flex;
justify-content: center; /* Центрируем поля ввода */
}
.nitrogen-group input {
width: 80px;
padding: 5px;
border: 1px solid #ccc;
border-radius: 4px;
}
.square-button {
width: 60px;
height: 30px;
font-size: 18px; /* Увеличенный размер текста */
font-weight: bold; /* Жирный шрифт */
border: none; /* Убираем границы */
border-radius: 5px; /* Легкое скругление углов */
background-color: #28a745; /* Зеленый цвет фона */
color: white; /* Белый текст */
cursor: pointer; /* Курсор при наведении */
align-items: center; /* Вертикальное центрирование */
justify-content: center; /* Горизонтальное центрирование */
margin-bottom: 10px; /* Отступ снизу */
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); /* Тень для объема */
}
/* Стили для контейнера первого блока (NPK) */
.npk-container {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 10px; /* Отступ между заголовком и основным блоком */
margin-left: 15px; /* Общий отступ слева */
margin-top: 10px; /* Отступ сверху */
}
/* Стили для заголовка NPK */
.header-npk {
font-weight: bold;
font-size: 0.9em;
text-align: center;
width: 65px; /* Ширина заголовка совпадает с шириной блока */
margin-bottom: 5px; /* Отступ между заголовком и основным блоком */
margin-left: -5px; /* Сдвигаем строки влево */
margin-bottom: 5px; /* Отступ между заголовком и основным блоком */
}
/* Стили для основного блока NPK */
.block-npk {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 5px;
padding: 10px;
background-color: #eaffea;
border: 1px solid #2e8b57;
border-radius: 8px;
width: 65px; /* Ширина блока */
}
/* Стили для внутреннего контейнера строк (NPK) */
.inner-block-npk {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 5px;
margin-left: -33px; /* Сдвигаем строки влево */
margin-right: 0px; /* Добавляем внешний отступ справа */
padding-bottom: 26px; /* Добавляем внешний отступ справа */
}
.row-npk {
display: flex;
align-items: center;
gap: 5px;
}
.label-npk {
font-weight: bold;
min-width: 50px; /* Минимальная ширина меток */
text-align: right;
}
.row-npk span {
font-size: 0.9em;
}
/* Стили для контейнера второго блока (Ca-Mg-S) */
.camgs-container {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 10px; /* Отступ между заголовком и основным блоком */
margin-left: 8px; /* Общий отступ слева */
margin-top: 10px; /* Отступ сверху */
}
/* Стили для заголовка Ca-Mg-S */
.header-camgs {
font-weight: bold;
font-size: 0.9em;
text-align: center;
width: 75px; /* Ширина заголовка совпадает с шириной блока */
margin-bottom: 5px; /* Отступ между заголовком и основным блоком */
}
/* Стили для основного блока Ca-Mg-S */
.block-camgs {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 5px;
padding: 10px;
background-color: #eaffea;
border: 1px solid #2e8b57;
border-radius: 8px;
width: 85px; /* Ширина блока */
}
/* Стили для внутреннего контейнера строк (Ca-Mg-S) */
.inner-block-camgs {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 5px;
margin-left: -31px; /* Сдвигаем строки влево */
margin-right: 0px; /* Добавляем внешний отступ справа */
padding-bottom: 26px; /* Добавляем внешний отступ*/
}
.row-camgs {
display: flex;
align-items: center;
gap: 5px;
}
.label-camgs {
font-weight: bold;
min-width: 65px; /* Минимальная ширина меток */
text-align: right;
}
.row-camgs span {
font-size: 0.9em;
}
/* Стили для контейнера блока N1 */
.n1-container {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 10px; /* Отступ между заголовком и основным блоком */
margin-left: 8px; /* Общий отступ слева */
margin-top: 10px; /* Отступ сверху */
}
/* Стили для заголовка N1 */
.header-n1 {
font-weight: bold;
font-size: 0.9em;
text-align: left;
width: 100%; /* Ширина заголовка */
margin-bottom: 5px; /* Отступ между заголовком и основным блоком */
}
.header-n1 span {
margin-right: 5px; /* Отступ между "N1=" и значением */
}
#n1-value {
font-weight: normal;
color: #333;
min-width: 100px; /* Место для значения */
}
/* Стили для основного блока N1 */
.block-n1 {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 5px;
padding: 10px;
background-color: #eaffea;
border: 1px solid #2e8b57;
border-radius: 8px;
width: 200px; /* Ширина блока */
}
/* Стили для строки с меткой и индикатором */
.n1-row {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 5px;
width: 100%;
}
.label-n1 {
font-weight: bold;
font-size: 0.9em;
text-align: left;
width: 100%;
}
/* Стили для контейнера индикатора */
.indicator-container {
width: 150px; /* Ширина индикатора */
height: 10px; /* Высота индикатора */
background-color: #f0f0f0; /* Фон индикатора */
border-radius: 5px;
overflow: hidden;
position: relative;
}
/* Стили для индикатора */
.indicator {
height: 100%;
position: absolute;
top: 0;
left: 0;
transition: width 0.3s ease; /* Плавное изменение ширины */
}
.red-indicator {
background-color: red;
}
.blue-indicator {
background-color: blue;
}
/* Стили для таблицы удобрений */
.fertilisers-container {
display: flex;
flex-direction: column;
margin-left: 20px; /* Сдвигаем блок */
}
.fert-row {
display: flex;
align-items: center;
margin-bottom: 8px;
}
.fert-header {
font-weight: bold;
text-align: center;
width: 80px;
padding: 5px;
font-size: 0.9em;
}
.fert-name {
font-weight: bold;
width: 120px;
text-align: left;
font-size: 0.9em;
}
.fert-cell {
text-align: center;
width: 80px;
padding: 5px;
font-size: 0.9em;
}
.fert-input {
width: 70px;
padding: 5px;
border: 1px solid #ccc;
border-radius: 4px;
text-align: center;
margin: 0 5px;
font-size: 0.9em;
}
/* Стили для блока расчета */
.calculation-container {
display: flex;
gap: 40px; /* Расстояние между левым и правым блоками */
align-items: flex-start;
}
/* Левый блок */
.left-section {
display: flex;
flex-direction: column;
gap: 20px; /* Расстояние между элементами */
width: 100%; /* Занимает всю ширину */
}
.left-section label {
font-weight: bold;
font-size: 0.9em;
}
.left-section select {
width: 100%; /* Выпадающий список занимает всю ширину */
padding: 5px;
border: 1px solid #ccc;
border-radius: 4px;
}
.button-group {
display: flex;
gap: 10px; /* Расстояние между кнопками */
}
.button-group button {
flex: 1; /* Кнопки занимают одинаковое пространство */
padding: 8px;
border: none;
border-radius: 5px;
cursor: pointer;
font-weight: bold;
transition: background-color 0.3s;
}
#save-profile {
background-color: #28a745; /* Зелёная кнопка */
color: white;
}
#delete-profile {
background-color: #dc3545; /* Красная кнопка */
color: white;
}
/* Правый блок */
.right-section {
display: flex;
flex-direction: column;
gap: 10px;
}
.input-group {
display: flex;
align-items: center;
gap: 10px;
}
.input-group label {
width: 120px; /* Ширина меток */
text-align: right;
font-weight: bold;
font-size: 0.9em;
}
.input-group input {
width: 70px;
padding: 5px;
border: 1px solid #ccc;
border-radius: 4px;
}
#calculate-btn {
background-color: #2e8b57;
color: white;
border: none;
padding: 8px 16px;
font-size: 16px;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s;
margin-bottom: 5px;
font-weight: bold;
}
#calculate-btn:hover {
background-color: #3cb371;
}
/* micro контейнер */
.micro-container {
padding: 10px;
}
.micro-row {
display: flex;
gap: 20px;
}
.micro-group {
display: flex;
align-items: center;
gap: 5px;
}
.micro-group label {
min-width: 120px;
}
.micro-group input {
width: 80px;
text-align: right;
}
</style>
<script>
vkBridge.send('VKWebAppInit');
</script>
<body>
<div class="header-box">
<h1>Калькулятор удобрений</h1>
</div>
<fieldset>
<legend>Макропрофиль в мг/л (ppm)</legend>
<div class="main-container">
<!-- Основные элементы -->
<div class="profile-container">
<div class="profile-element" style="grid-column: 2">
<span class="profile-label">N</span>
<input id="profile_n" type="number" value="125.000" step="0.001"/>
</div>
<div class="profile-element" style="grid-column: 3">
<span class="profile-label">P</span>
<input id="profile_p" type="number" value="31.000" step="0.001"/>
</div>
<div class="profile-element" style="grid-column: 4">
<span class="profile-label">K</span>
<input id="profile_k" type="number" value="210.000" step="0.001"/>
</div>
<div class="profile-element" style="grid-column: 5">
<span class="profile-label">Ca</span>
<input id="profile_ca" type="number" value="82.000" step="0.001"/>
</div>
<div class="profile-element" style="grid-column: 6">
<span class="profile-label">Mg</span>
<input id="profile_mg" type="number" value="24.000" step="0.001"/>
</div>
<div class="profile-element" style="grid-column: 7">
<span class="profile-label">S</span>
<input id="profile_s" type="number" value="57.5" step="0.001"/>
</div>
<div class="profile-element" style="grid-column: 8">
<span class="profile-label">EC</span>
<input id="profile_ec" type="number" value="0.0" step="0.001"/>
</div>
<div class="profile-element" style="grid-column: 9">
<span class="profile-label">t°C</span>
<input id="profile_temp" type="number" value="25.0" step="0.01"/>
</div>
</div>
<!-- NH4 -- NO3 -->
<!-- Азотные элементы и блок NPK -->
<div style="display: flex; align-items: flex-start; gap: 20px;">
<!-- Колонки азотных элементов -->
<div class="nitrogen-container" style="display: flex; gap: 20px;">
<!-- Колонка 1: NH4 -->
<div class="nitrogen-column">
<button class="square-button" id="minus-button" style="font-weight: bold;">-</button>
<div class="column-header">NH4</div>
<div class="nitrogen-group">
<input id="profile_nh4" type="number" value="1.0" step="1.0" readonly style="background-color: #f0f0f0; color: #666;">
</div>
<div class="nitrogen-group">
<input id="calculated_nh4" type="number" value="0.000" step="0.001" readonly style="background-color: #f0f0f0; color: #666;">
</div>
</div>
<!-- Колонка 2: NO3 -->
<div class="nitrogen-column">
<button class="square-button" id="plus-button" style="font-weight: bold;">+</button>
<div class="column-header">NO3</div>
<div class="nitrogen-group">
<input id="profile_no3" type="number" value="8.25" step="0.01" min="0" max="100.001"/>
</div>
<div class="nitrogen-group">
<input id="calculated_no3" type="number" value="0.000" step="0.001" readonly style="background-color: #f0f0f0; color: #666;">
</div>
</div>
</div>
<!-- Первый блок NPK -->
<div class="npk-container">
<!-- Заголовок NPK -->
<div class="header-npk">N-P-K</div>
<!-- Основной блок с содержимым -->
<div class="block-npk">
<!-- Дополнительный контейнер для строк -->
<div class="inner-block-npk">
<div class="row-npk">
<span class="label-npk">N:</span>
<span id="npk-n-value">0</span>
</div>
<div class="row-npk">
<span class="label-npk">P:</span>
<span id="npk-p-value">0</span>
</div>
<div class="row-npk">
<span class="label-npk">K:</span>
<span id="npk-k-value">0</span>
</div>
</div>
</div>
</div>
<!-- Второй блок Ca-Mg-S -->
<div class="camgs-container">
<!-- Заголовок Ca-Mg-S -->
<div class="header-camgs">Ca-Mg-S</div>
<!-- Основной блок с содержимым -->
<div class="block-camgs">
<!-- Дополнительный контейнер для строк -->
<div class="inner-block-camgs">
<div class="row-camgs">
<span class="label-camgs">CaO:</span>
<span id="caMaS-ca-value">0</span>
</div>
<div class="row-camgs">
<span class="label-camgs">MgO:</span>
<span id="caMaS-mg-value">0</span>
</div>
<div class="row-camgs">
<span class="label-camgs">SO:</span>
<span id="caMaS-so-value">0</span>
</div>
</div>
</div>
</div>
<!-- Блок N1 -->
<div class="n1-container">
<!-- Заголовок N1 -->
<div class="header-n1">
<span>N1:</span>
<span id="n1-value">0.00:0.00:0.00:0.00:0.00 PPM=0.00</span>
</div>
<!-- Основной блок с содержимым -->
<div class="block-n1">
<!-- Катионы -->
<div class="n1-row">
<span class="label-n1">Катионы:</span>
<div class="indicator-container">
<div class="indicator red-indicator" id="cation-indicator"></div>
</div>
</div>
<!-- Анионы -->
<div class="n1-row">
<span class="label-n1">Анионы:</span>
<div class="indicator-container">
<div class="indicator blue-indicator" id="anion-indicator"></div>
</div>
</div>
</div>
</div>
</div>
</fieldset>
<fieldset>
<legend>Составы солей</legend>
<div class="fertilisers-container">
<!-- Заголовки -->
<div class="fert-row">
<span class="fert-name">Удобрение</span>
<span class="fert-header">NH4</span>
<span class="fert-header">NO3</span>
<span class="fert-header">P</span>
<span class="fert-header">K</span>
<span class="fert-header">Ca</span>
<span class="fert-header">Mg</span>
<span class="fert-header">S</span>
<span class="fert-header">Cl</span>
<span class="fert-header">Грамм</span>
</div>
<!-- Строки с удобрениями -->
<div class="fert-row">
<span id="ca_no" class="fert-name" style="cursor: pointer;">Ca(NO₃)₂</span>
<span class="fert-cell">-</span>
<input class="fert-input" type="number" value="11.863" step="0.001" id="fert_ca_no3"/>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<input class="fert-input" type="number" value="16.972" step="0.001" id="fert_ca_ca"/>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<input class="fert-input" type="number" step="0.001" id="calcium_nitrate" readonly style="background-color: #d1e7fd;" />
</div>
<div class="fert-row">
<span id="kno" class="fert-name" style="cursor: pointer;">KNO₃</span>
<span class="fert-cell">-</span>
<input class="fert-input" type="number" value="13.854" step="0.001" id="fert_kno3_no3"/>
<span class="fert-cell">-</span>
<input class="fert-input" type="number" value="36.672" step="0.001" id="fert_kno3_k"/>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<input class="fert-input" type="number" step="0.001" id="potassium_nitrate" readonly style="background-color: #d1e7fd;" />
</div>
<div class="fert-row">
<span class="fert-name">NH₄NO₃</span>
<input class="fert-input" type="number" value="17.499" step="0.001" id="fert_nh4no3_nh4"/>
<input class="fert-input" type="number" value="17.499" step="0.001" id="fert_nh4no3_no3"/>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<input class="fert-input" type="number" step="0.001" id="ammonium_nitrate" readonly style="background-color: #d1e7fd;" />
</div>
<div class="fert-row">
<span class="fert-name">MgSO₄</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<input class="fert-input" type="number" value="10.22" step="0.001" id="fert_mgso4_mg" />
<input class="fert-input" type="number" value="13.483" step="0.001" id="fert_mgso4_s" />
<span class="fert-cell">-</span>
<input class="fert-input" type="number" step="0.001" id="magnesium_sulfate" readonly style="background-color: #d4f5d4;" />
</div>
<div class="fert-row">
<span class="fert-name">KH₂PO₄</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<input class="fert-input" type="number" value="22.761" step="0.001" id="fert_kh2po4_p" />
<input class="fert-input" type="number" value="28.731" step="0.001" id="fert_kh2po4_k"/>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<input class="fert-input" type="number" step="0.001" id="monopotassium_phosphate" readonly style="background-color: #d4f5d4;" />
</div>
<div class="fert-row">
<span class="fert-name">K₂SO₄</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<input class="fert-input" type="number" value="44.874" step="0.001" id="fert_k2so4_k"/>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<input class="fert-input" type="number" value="18.401" step="0.001" id="fert_k2so4_s" />
<span class="fert-cell">-</span>
<input class="fert-input" type="number" step="0.001" id="potassium_sulfate" readonly style="background-color: #d4f5d4;" />
</div>
</div>
</fieldset>
<fieldset>
<legend>Микроэлементы в мг/л (ppm)</legend>
<div class="fertilisers-container">
<!-- Заголовки -->
<div class="fert-row">
<span class="fert-name">Элемент</span>
<span class="fert-header">Fe</span>
<span class="fert-header">Zn</span>
<span class="fert-header">Cu</span>
<span class="fert-header">Mn</span>
<span class="fert-header">B</span>
<span class="fert-header">Mo</span>
<span class="fert-header">Fe (11%)</span>
<span class="fert-header">Аквамикс<sup>&reg;</sup></span>
</div>
<!-- Строки с микроэлементами -->
<div class="fert-row">
<span class="fert-name">Железо</span>
<input class="fert-input ppm-output" type="number" step="0.001" id="ppm_fe" readonly />
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<input class="fert-input" type="number" value="2.00" step="0.01" id="fert_fe_chelate_mass"/>
<input class="fert-input" type="number" value="1.00" step="0.01" id="fert_fe_complex_mass" />
</div>
<div class="fert-row">
<span class="fert-name">Цинк</span>
<span class="fert-cell">-</span>
<input class="fert-input ppm-output" type="number" step="0.001" id="ppm_zn" readonly />
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
</div>
<div class="fert-row">
<span class="fert-name">Медь</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<input class="fert-input ppm-output" type="number" step="0.001" id="ppm_cu" readonly />
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
</div>
<div class="fert-row">
<span class="fert-name">Марганец</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<input class="fert-input ppm-output" type="number" step="0.001" id="ppm_mn" readonly />
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
</div>
<div class="fert-row">
<span class="fert-name">Бор</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<input class="fert-input ppm-output" type="number" step="0.001" id="ppm_b" readonly />
<span class="fert-cell">-</span>
</div>
<div class="fert-row">
<span class="fert-name">Молибден</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<span class="fert-cell">-</span>
<input class="fert-input ppm-output" type="number" step="0.001" id="ppm_mo" readonly />
<span class="fert-cell">-</span>
</div>
</div>
</fieldset>
<fieldset class="calculation-box">
<legend>Расчёт удобрений</legend>
<div class="calculation-container">
<!-- Левый блок -->
<div class="left-section">
<!-- Выпадающий список -->
<label for="profile-selector">Выберите профиль:</label>
<select id="profile-selector"></select>
<!-- Кнопки сохранения и удаления -->
<div class="button-group">
<button id="save-profile">Сохранить текущий профиль</button>
<button id="delete-profile">Удалить выбранный профиль</button>
</div>
</div>
<!-- Правый блок -->
<div class="right-section">
<div class="input-column">
<div class="input-group">
<label for="liters-input">Литры:</label>
<input type="number" id="liters-input" value="100" min="1" step="1">
</div>
<div class="input-group">
<label for="rounding-precision">Точность:</label>
<input type="number" id="rounding-precision" value="3" min="0" max="3" step="1">
</div>
<button id="calculate-btn">Рассчитать</button>
</div>
</div>
</div>
</fieldset>
<!-- Кастомные стили -->
<style>
.pnotify-success {
background: linear-gradient(135deg, #4CAF50, #2E7D32) !important;
border-left: 5px solid #1B5E20 !important;
}
.pnotify-error {
background: linear-gradient(135deg, #F44336, #C62828) !important;
border-left: 5px solid #B71C1C !important;
}
.deficit-item {
margin: 8px 0;
display: flex;
align-items: center;
}
.deficit-item i {
margin-right: 10px;
font-size: 1.2em;
}
</style>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/toastify-js"></script>
<script>
let call_data;
const ecConstants = {
'P': 0.0012, 'K': 0.0018, 'Mg': 0.0015,
'Ca': 0.0016, 'S': 0.0014,
'N (NO3-)': 0.0017, 'N (NH4+)': 0.0019
};
document.getElementById('calculate-btn').addEventListener('click', function () {
console.log("=== НАЧАЛО ОБРАБОТКИ ===");
// 1. Получаем значение точности округления
const roundingInput = document.getElementById('rounding-precision');
const initialRounding = parseInt(roundingInput.value);
const roundingPrecision = Math.min(Math.max(initialRounding || 3, 0), 6);
// 2. Функция для безопасного получения числового значения
const getValue = (id) => {
const element = document.getElementById(id);
if (!element) {
console.error(`Элемент с ID ${id} не найден!`);
return 0;
}
const value = parseFloat(element.value);
return isNaN(value) ? 0 : value;
};
// 3. Формируем данные для сервера
const fertilizerConstants = {
"Кальциевая селитра": {
"N (NO3-)": getValue('fert_ca_no3') / 100,
"Ca": getValue('fert_ca_ca') / 100
},
"Калий азотнокислый": {
"N (NO3-)": getValue('fert_kno3_no3') / 100,
"K": getValue('fert_kno3_k') / 100
},
"Аммоний азотнокислый": {
"N (NO3-)": getValue('fert_nh4no3_no3') / 100,
"N (NH4+)": getValue('fert_nh4no3_nh4') / 100
},
"Сульфат магния": {
"Mg": getValue('fert_mgso4_mg') / 100,
"S": getValue('fert_mgso4_s') / 100
},
"Монофосфат калия": {
"P": getValue('fert_kh2po4_p') / 100,
"K": getValue('fert_kh2po4_k') / 100
},
"Калий сернокислый": {
"K": getValue('fert_k2so4_k') / 100,
"S": getValue('fert_k2so4_s') / 100
}
};
const profileSettings = {
'P': getValue('profile_p'),
'K': getValue('profile_k'),
'Mg': getValue('profile_mg'),
'Ca': getValue('profile_ca'),
'S': getValue('profile_s'),
'NO3_RAT': getValue('profile_no3'),
'TOTAL_NITROG': getValue('profile_n'),
'liters': parseInt(document.getElementById('liters-input').value) || 1,
'rounding_precision': roundingPrecision
};
const requestData = {
fertilizerConstants: fertilizerConstants,
profileSettings: profileSettings
};
console.log("=== ПОЛНЫЙ ОБЪЕКТ ДЛЯ ОТПРАВКИ ===", JSON.stringify(requestData, null, 2));
// 4. Отправка данных на сервер
fetch('/calculation', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(requestData),
})
.then(response => {
console.log("Получен ответ от сервера. Статус:", response.status);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then(data => {
call_data = data;
console.log("=== УСПЕШНЫЙ ОТВЕТ ОТ СЕРВЕРА ===", call_data);
// Обновляем только поля вывода
data_out(call_data);
// Обновляем поля NH4 и NO3
updateNitrogenFields(call_data);
// Показываем статус расчёта
showCalculationStatus(call_data);
// Вызываем функцию для расчета катионов и анионов
calculateCationsAndAnions(data);
calculateAndUpdate(call_data);
calculateMicroElements();
calculateN1Ratio(call_data);
// Рассчитываем EC
const temperature = parseFloat(document.getElementById('profile_temp').value) || 25;
const ecValue = calculateEC(call_data, temperature);
const ecInput = document.getElementById('profile_ec');
if (ecInput) {
ecInput.value = ecValue.toFixed(2);
console.log(`Установлено значение EC: ${ecValue.toFixed(2)}`);
}
})
.catch(error => {
console.error("=== ОШИБКА ПРИ ОБРАБОТКЕ ===", error);
alert("Ошибка при расчете: " + error.message);
});
});
function data_out(data) {
console.log("=== ЗАПИСЬ ДАННЫХ В ФОРМУ ===");
// Сопоставление названий удобрений с их идентификаторами
const fertilizerIdMap = {
"Кальциевая селитра": "calcium_nitrate",
"Калий азотнокислый": "potassium_nitrate",
"Аммоний азотнокислый": "ammonium_nitrate",
"Сульфат магния": "magnesium_sulfate",
"Монофосфат калия": "monopotassium_phosphate",
"Калий сернокислый": "potassium_sulfate"
};
// Записываем массы удобрений
for (const [fertilizer, grams] of Object.entries(data.fertilizers)) {
const inputId = fertilizerIdMap[fertilizer];
const inputElement = document.getElementById(inputId);
if (inputElement) {
inputElement.value = grams.toFixed(3); // Записываем значение в поле вывода
console.log(`Записано значение для ${fertilizer}: ${grams.toFixed(3)} г`);
} else {
console.warn(`Поле для удобрения ${fertilizer} не найдено`);
}
}
// Логика для CaCl больше не нужна
console.log("Логика для Кальция хлористого удалена.");
}
function updateNitrogenFields(data) {
console.log("=== ОБНОВЛЕНИЕ ЗНАЧЕНИЙ NH4 И NO3 ===");
// Извлекаем значения NH4 и NO3 из actual_profile
const nh4Value = data.actual_profile["N (NH4+)"] || 0;
const no3Value = data.actual_profile["N (NO3-)"] || 0;
// Обновляем поля NH4
document.getElementById("calculated_nh4").value = nh4Value.toFixed(3); // Расчетное значение NH4
// Обновляем поля NO3
document.getElementById("calculated_no3").value = no3Value.toFixed(3); // Расчетное значение NO3
console.log(`Значения NH4 и NO3 обновлены: NH4=${nh4Value}, NO3=${no3Value}`);
}
function calculateAndUpdate(data) {
console.log("=== РАСЧЕТ И ОБНОВЛЕНИЕ ДАННЫХ ===");
// Извлекаем значения из actual_profile
const nValue = (data.actual_profile["N (NH4+)"] || 0) + (data.actual_profile["N (NO3-)"] || 0);
const pValue = data.actual_profile["P"] || 0;
const kValue = data.actual_profile["K"] || 0;
const caValue = data.actual_profile["Ca"] || 0;
const mgValue = data.actual_profile["Mg"] || 0;
const sValue = data.actual_profile["S"] || 0;
// Динамический расчет процента азота
const totalNitrogen = data.nitrogen_ratios.TOTAL_NITROGEN || 0; // Берем TOTAL_NITROGEN из ответа
const nPercent = totalNitrogen / 10; // Делим на 10, как предложено
// Рассчитываем общую массу раствора
const totalMass = nValue / (nPercent / 100); // Общая масса = N / (nPercent / 100)
// Переводим элементы в оксидную форму
const pOxide = pValue * 2.29; // P → P2O5
const kOxide = kValue * 1.2; // K → K2O
const caOxide = caValue * 1.4; // Ca → CaO
const mgOxide = mgValue * 1.67; // Mg → MgO
const sOxide = sValue * 2.5; // S → SO3
// Рассчитываем проценты от общей массы
const pPercent = (pOxide / totalMass) * 100;
const kPercent = (kOxide / totalMass) * 100;
const caPercent = (caOxide / totalMass) * 100;
const mgPercent = (mgOxide / totalMass) * 100;
const sPercent = (sOxide / totalMass) * 100;
console.log(`Результаты расчета:
N: ${nPercent.toFixed(2)}%,
P2O5: ${pPercent.toFixed(2)}%,
K2O: ${kPercent.toFixed(2)}%,
CaO: ${caPercent.toFixed(2)}%,
MgO: ${mgPercent.toFixed(2)}%,
SO3: ${sPercent.toFixed(2)}%`);
// Обновляем HTML-элементы
document.getElementById("npk-n-value").textContent = nPercent.toFixed(2);
document.getElementById("npk-p-value").textContent = pPercent.toFixed(2);
document.getElementById("npk-k-value").textContent = kPercent.toFixed(2);
document.getElementById("caMaS-ca-value").textContent = caPercent.toFixed(2);
document.getElementById("caMaS-mg-value").textContent = mgPercent.toFixed(2);
document.getElementById("caMaS-so-value").textContent = sPercent.toFixed(2);
}
function calculateCationsAndAnions() {
console.log("=== ДИНАМИЧЕСКИЙ РАСЧЕТ КАТИОНОВ И АНИОНОВ ===");
// 1. Получаем текущие значения из формы
const getValue = (id) => parseFloat(document.getElementById(id).value) || 0;
const profile = {
'N (NO3-)': getValue('calculated_no3'),
'N (NH4+)': getValue('calculated_nh4'),
'P': getValue('profile_p'),
'K': getValue('profile_k'),
'Ca': getValue('profile_ca'),
'Mg': getValue('profile_mg'),
'S': getValue('profile_s')
// Убрали 'Cl', так как больше не учитываем кальций хлористый
};
// 2. Константы из вашей формы (упрощенные)
const FERTILIZER_CONSTANTS = {
'Кальциевая селитра': { 'N (NO3-)': 0.11863, 'Ca': 0.16972 },
'Калий азотнокислый': { 'N (NO3-)': 0.13854, 'K': 0.36672 },
'Аммоний азотнокислый': { 'N (NO3-)': 0.17499, 'N (NH4+)': 0.17499 },
'Сульфат магния': { 'Mg': 0.10220, 'S': 0.13483 },
'Монофосфат калия': { 'P': 0.22761, 'K': 0.28731 },
'Калий сернокислый': { 'K': 0.44874, 'S': 0.18401 }
// Убрали 'Кальций хлорид'
};
// 3. Молярные массы и валентности
const ION_DATA = {
'Ca': { mass: 40.08, charge: 2 },
'Mg': { mass: 24.305, charge: 2 },
'K': { mass: 39.098, charge: 1 },
'NH4': { mass: 18.038, charge: 1 },
'NO3': { mass: 62.004, charge: 1 },
'SO4': { mass: 96.06, charge: 2 },
'H2PO4': { mass: 96.99, charge: 1 }
// Убрали 'Cl', так как больше не учитываем хлор
};
// 4. Пересчет серы (S → SO4²⁻)
const so4 = profile['S'] * (96.06 / 32.06);
// 5. Расчет mEq/L для каждого иона
const ions = {
'Ca': profile['Ca'] * ION_DATA['Ca'].charge / ION_DATA['Ca'].mass,
'Mg': profile['Mg'] * ION_DATA['Mg'].charge / ION_DATA['Mg'].mass,
'K': profile['K'] * ION_DATA['K'].charge / ION_DATA['K'].mass,
'NH4': profile['N (NH4+)'] * ION_DATA['NH4'].charge / ION_DATA['NH4'].mass,
'NO3': profile['N (NO3-)'] * ION_DATA['NO3'].charge / ION_DATA['NO3'].mass,
'SO4': so4 * ION_DATA['SO4'].charge / ION_DATA['SO4'].mass,
'H2PO4': profile['P'] * ION_DATA['H2PO4'].charge / ION_DATA['H2PO4'].mass
// Убрали 'Cl', так как больше не учитываем хлор
};
// 6. Суммирование
const totalCations = ions['Ca'] + ions['Mg'] + ions['K'] + ions['NH4'];
const totalAnions = ions['NO3'] + ions['SO4'] + ions['H2PO4'];
// Убрали 'Cl' из суммы анионов
// 7. Расчет процентов
const total = totalCations + totalAnions;
const cationPercent = total > 0 ? (totalCations / total * 100).toFixed(1) : 0;
const anionPercent = total > 0 ? (totalAnions / total * 100).toFixed(1) : 0;
// 8. Вывод результатов
console.log(`Катионы: ${totalCations.toFixed(2)} mEq/L (${cationPercent}%)`);
console.log(`Анионы: ${totalAnions.toFixed(2)} mEq/L (${anionPercent}%)`);
console.log(`Дисбаланс: ${(totalCations - totalAnions).toFixed(2)} mEq/L`);
// 9. Обновление UI
document.getElementById("n1-value").textContent =
`Катионы: ${totalCations.toFixed(2)} mEq/L | Анионы: ${totalAnions.toFixed(2)} mEq/L`;
// Обновление ширины индикаторов
document.getElementById("cation-indicator").style.width = `${cationPercent}%`;
document.getElementById("anion-indicator").style.width = `${anionPercent}%`;
}
function calculateEC(data, temperature, alpha = 0.019) {
console.log("=== РАСЧЕТ ЭЛЕКТРОПРОВОДНОСТИ (EC) ===");
const profile = data.actual_profile;
let totalEC = 0;
const ecConstants = {
'P': 0.0012, 'K': 0.0018, 'Mg': 0.0015,
'Ca': 0.0016, 'S': 0.0014,
'N (NO3-)': 0.0017, 'N (NH4+)': 0.0019
};
const significantElements = Object.keys(ecConstants);
for (const element of significantElements) {
const ppm = profile[element] || 0;
const ecFactor = ecConstants[element];
const elementEC = ppm * ecFactor;
totalEC += elementEC;
console.log(`EC для ${element}: ${elementEC.toFixed(5)} (ppm=${ppm}, const=${ecFactor})`);
}
console.log(`Общая EC без компенсации: ${totalEC.toFixed(5)}`);
const compensatedEC = totalEC * (1 + alpha * (temperature - 25));
console.log(`Компенсированная EC: ${compensatedEC.toFixed(5)} (T=${temperature}°C, α=${alpha})`);
return compensatedEC;
}
function calculateMicroElements() {
// 1. Получаем объем раствора (в литрах)
const litersInput = document.getElementById('liters-input');
if (!litersInput) {
console.error("Элемент с id='liters-input' не найден!");
return;
}
const solutionVolume = parseFloat(litersInput.value);
if (!solutionVolume || solutionVolume <= 0) {
alert("Введите корректный объем раствора!");
return;
}
// 2. Получаем массы удобрений (в граммах)
const feChelateInput = document.getElementById('fert_fe_chelate_mass');
const complexPowderInput = document.getElementById('fert_fe_complex_mass');
if (!feChelateInput || !complexPowderInput) {
console.error("Один из элементов для ввода масс удобрений не найден!");
return;
}
const feChelateMass = parseFloat(feChelateInput.value) || 0;
const complexPowderMass = parseFloat(complexPowderInput.value) || 0;
// 3. Содержание микроэлементов в удобрениях (%)
const feChelateContent = {
Fe: 0.11 // Хелат железа (11%)
};
const complexPowderContent = {
Fe: 0.0384, // Fe (ДТПА + ЭДТА) = 3.84%
Zn: 0.0053, // Zn (ЭДТА) = 0.53%
Cu: 0.0053, // Cu (ЭДТА) = 0.53%
Mn: 0.0257, // Mn (ЭДТА) = 2.57%
B: 0.0052, // B = 0.52%
Mo: 0.0013 // Mo = 0.13%
};
// 4. Рассчитываем чистые количества микроэлементов (в граммах)
const pureElements = {
Fe: (feChelateMass * feChelateContent.Fe) + (complexPowderMass * complexPowderContent.Fe),
Zn: complexPowderMass * complexPowderContent.Zn,
Cu: complexPowderMass * complexPowderContent.Cu,
Mn: complexPowderMass * complexPowderContent.Mn,
B: complexPowderMass * complexPowderContent.B,
Mo: complexPowderMass * complexPowderContent.Mo
};
// 5. Рассчитываем концентрации в PPM (мг/л)
const ppm = {};
for (const element in pureElements) {
ppm[element] = (pureElements[element] * 1000) / solutionVolume; // Переводим граммы в мг/л
}
// 6. Выводим результаты в соответствующие поля матрицы
const outputFields = ['ppm_fe', 'ppm_zn', 'ppm_cu', 'ppm_mn', 'ppm_b', 'ppm_mo'];
outputFields.forEach((field, index) => {
const element = document.getElementById(field);
if (element) {
element.value = ppm[Object.keys(ppm)[index]]?.toFixed(3) || 0;
} else {
console.error(`Элемент с id='${field}' не найден!`);
}
});
console.log("=== РАСЧЕТ PPM ===", ppm);
}
// Функция для расчета соотношений и формирования строки
function calculateN1Ratio(data) {
// Получаем значения элементов из ответа сервера
const { actual_profile, total_ppm } = data;
const { P, K, Ca, Mg, S } = actual_profile;
// Общий азот (N_total) = N (NH4+) + N (NO3-)
const N_total = actual_profile["N (NH4+)"] + actual_profile["N (NO3-)"];
// Вычисляем соотношения относительно общего азота (принимаем его за единицу)
const P_ratio = (P / N_total).toFixed(2);
const K_ratio = (K / N_total).toFixed(2);
const CaO_ratio = (Ca / N_total).toFixed(2); // Предполагается, что Ca - это оксид кальция
const MgO_ratio = (Mg / N_total).toFixed(2); // Предполагается, что Mg - это оксид магния
const SO_ratio = (S / N_total).toFixed(2); // Предполагается, что S - это оксид серы
// Формируем строку в требуемом формате
const n1String = `${P_ratio}:${K_ratio}:${CaO_ratio}:${MgO_ratio}:${SO_ratio} PPM=${total_ppm.toFixed(2)}`;
// Вставляем строку в HTML
document.getElementById("n1-value").textContent = n1String;
}
</script>
<script>
// Инициализация
const notyf = new Notyf({
duration: 5000,
position: {x: 'right', y: 'top'},
types: [
{type: 'success', background: '#4CAF50'},
{type: 'error', background: '#F44336'}
]
});
// Модифицированная функция
function showCalculationStatus(response) {
if (Object.keys(response.deficits || {}).length === 0) {
notyf.success('Расчёт успешен! Все элементы сбалансированы');
} else {
notyf.error('Дефициты: ' +
Object.entries(response.deficits)
.map(([el, val]) => `${el}: ${val.toFixed(2)} ppm`)
.join(', '));
}
}
</script>
<script>
// Функция для увеличения значений на 10%
function increaseValues() {
const fields = [
"profile_n", "profile_p", "profile_k",
"profile_ca", "profile_mg", "profile_s"
];
fields.forEach(id => {
const input = document.getElementById(id);
let value = parseFloat(input.value); // Берём текущее значение
if (!isNaN(value)) { // Проверяем, что значение является числом
value *= 1.1; // Увеличиваем на 10%
input.value = value.toFixed(3); // Округляем до 3 знаков после запятой
}
});
}
// Функция для уменьшения значений на 10%
function decreaseValues() {
const fields = [
"profile_n", "profile_p", "profile_k",
"profile_ca", "profile_mg", "profile_s"
];
fields.forEach(id => {
const input = document.getElementById(id);
let value = parseFloat(input.value); // Берём текущее значение
if (!isNaN(value)) { // Проверяем, что значение является числом
value *= 0.9; // Уменьшаем на 10%
value = Math.max(value, 0); // Не позволяем значению стать отрицательным
input.value = value.toFixed(3); // Округляем до 3 знаков после запятой
}
});
}
// Привязываем функции к кнопкам
document.getElementById("plus-button").addEventListener("click", increaseValues);
document.getElementById("minus-button").addEventListener("click", decreaseValues);
</script>
<script src="https://unpkg.com/tippy.js@6"></script>
<script>
tippy('#ca_no', {
content: 'Нитрат Кальция (кальциевая селитра)',
placement: 'top', // Расположение: top, bottom, left, right
arrow: true, // Добавить стрелку
});
</script>
<script>
tippy('#kno', {
content: 'Нитрат калия (калиевая селитра)',
placement: 'top', // Расположение: top, bottom, left, right
arrow: true, // Добавить стрелку
});
</script>
<script>
// Предустановленные профили (JSON)
// Предустановленные профили (JSON)
const predefinedProfiles = {
profiles: [
{
name: "Профиль 1",
values: {
profile_p: 31,
profile_k: 210,
profile_mg: 24,
profile_ca: 82,
profile_s: 57.5,
profile_no3: 8.25, // Соотношение азотов
profile_n: 125,
liters: 100, // Литры
rounding_precision: 3, // Точность
fert_fe_chelate_mass: 2.0,
fert_fe_complex_mass: 1.0
}
},
{
name: "Профиль 2",
values: {
profile_p: 40,
profile_k: 250,
profile_mg: 30,
profile_ca: 90,
profile_s: 60,
profile_no3: 10, // Соотношение азотов
profile_n: 150,
liters: 150, // Литры
rounding_precision: 2, // Точность
fert_fe_chelate_mass: 3.0,
fert_fe_complex_mass: 2.0
}
}
]
};
// Загрузка всех профилей (предустановленные + пользовательские)
function loadAllProfiles() {
const userProfiles = JSON.parse(localStorage.getItem("userProfiles")) || [];
return [...predefinedProfiles.profiles, ...userProfiles];
}
// Создание выпадающего списка
function populateProfileSelector() {
const profiles = loadAllProfiles();
const selector = document.getElementById("profile-selector");
// Очищаем предыдущие опции
selector.innerHTML = "";
// Добавляем предустановленные профили
const predefinedGroup = document.createElement("optgroup");
predefinedGroup.label = "Предустановленные профили";
predefinedProfiles.profiles.forEach(profile => {
const option = document.createElement("option");
option.value = profile.name;
option.textContent = profile.name;
predefinedGroup.appendChild(option);
});
selector.appendChild(predefinedGroup);
// Добавляем пользовательские профили
const userProfiles = JSON.parse(localStorage.getItem("userProfiles")) || [];
if (userProfiles.length > 0) {
const userGroup = document.createElement("optgroup");
userGroup.label = "Пользовательские профили";
userProfiles.forEach(profile => {
const option = document.createElement("option");
option.value = profile.name;
option.textContent = profile.name;
userGroup.appendChild(option);
});
selector.appendChild(userGroup);
}
// Выбираем первый профиль по умолчанию
if (profiles.length > 0) {
selector.value = profiles[0].name;
updateProfileFields(profiles[0]);
}
}
// Обновление полей при выборе профиля
function updateProfileFields(selectedProfile) {
document.getElementById("profile_p").value = selectedProfile.values.profile_p || 0;
document.getElementById("profile_k").value = selectedProfile.values.profile_k || 0;
document.getElementById("profile_mg").value = selectedProfile.values.profile_mg || 0;
document.getElementById("profile_ca").value = selectedProfile.values.profile_ca || 0;
document.getElementById("profile_s").value = selectedProfile.values.profile_s || 0;
document.getElementById("profile_no3").value = selectedProfile.values.profile_no3 || 0; // Соотношение азотов
document.getElementById("profile_n").value = selectedProfile.values.profile_n || 0;
document.getElementById("liters-input").value = selectedProfile.values.liters || 100; // Литры
document.getElementById("rounding-precision").value = selectedProfile.values.rounding_precision || 3; // Точность
document.getElementById("fert_fe_chelate_mass").value = selectedProfile.values.fert_fe_chelate_mass || 0;
document.getElementById("fert_fe_complex_mass").value = selectedProfile.values.fert_fe_complex_mass || 0;
}
// Слушатель события изменения выбранного профиля
document.getElementById("profile-selector").addEventListener("change", function () {
const selectedProfileName = this.value;
const allProfiles = loadAllProfiles();
const selectedProfile = allProfiles.find(profile => profile.name === selectedProfileName);
if (selectedProfile) {
updateProfileFields(selectedProfile);
}
});
// Сохранение нового профиля
document.getElementById("save-profile").addEventListener("click", async function () {
// Используем SweetAlert2 для ввода имени профиля
const { value: profileName } = await Swal.fire({
title: "Введите название профиля",
input: "text",
inputPlaceholder: "Название профиля",
showCancelButton: true,
confirmButtonText: "Сохранить",
cancelButtonText: "Отмена",
confirmButtonColor: "#28a745", // Зелёная кнопка
cancelButtonColor: "#dc3545", // Красная кнопка
inputValidator: (value) => {
if (!value) {
return "Название профиля не может быть пустым!";
}
}
});
if (!profileName) return;
// Создаём новый профиль
const newProfile = {
name: profileName,
values: {
profile_p: parseFloat(document.getElementById("profile_p").value) || 0,
profile_k: parseFloat(document.getElementById("profile_k").value) || 0,
profile_mg: parseFloat(document.getElementById("profile_mg").value) || 0,
profile_ca: parseFloat(document.getElementById("profile_ca").value) || 0,
profile_s: parseFloat(document.getElementById("profile_s").value) || 0,
profile_no3: parseFloat(document.getElementById("profile_no3").value) || 0, // Соотношение азотов
profile_n: parseFloat(document.getElementById("profile_n").value) || 0,
liters: parseFloat(document.getElementById("liters-input").value) || 100, // Литры
rounding_precision: parseInt(document.getElementById("rounding-precision").value) || 3, // Точность
fert_fe_chelate_mass: parseFloat(document.getElementById("fert_fe_chelate_mass").value) || 0,
fert_fe_complex_mass: parseFloat(document.getElementById("fert_fe_complex_mass").value) || 0
}
};
// Добавляем профиль в localStorage
let userProfiles = JSON.parse(localStorage.getItem("userProfiles")) || [];
userProfiles.push(newProfile);
localStorage.setItem("userProfiles", JSON.stringify(userProfiles));
// Обновляем выпадающий список
populateProfileSelector();
});
// Удаление выбранного профиля
document.getElementById("delete-profile").addEventListener("click", async function () {
const selectedProfileName = document.getElementById("profile-selector").value;
if (!selectedProfileName) {
Swal.fire({
icon: "error",
title: "Ошибка",
text: "Выберите профиль для удаления!"
});
return;
}
// Находим индекс профиля в localStorage
let userProfiles = JSON.parse(localStorage.getItem("userProfiles")) || [];
const profileIndex = userProfiles.findIndex(profile => profile.name === selectedProfileName);
if (profileIndex === -1) {
Swal.fire({
icon: "error",
title: "Ошибка",
text: "Невозможно удалить предустановленный профиль!"
});
return;
}
// Показываем SweetAlert2 для подтверждения удаления
const result = await Swal.fire({
title: "Вы уверены?",
text: "Это действие нельзя отменить!",
icon: "warning",
showCancelButton: true,
confirmButtonText: "Да, удалить!",
cancelButtonText: "Нет, отмена!",
confirmButtonColor: "#dc3545", // Красная кнопка
cancelButtonColor: "#28a745", // Зелёная кнопка
reverseButtons: true
});
if (result.isConfirmed) {
// Удаляем профиль
userProfiles.splice(profileIndex, 1);
localStorage.setItem("userProfiles", JSON.stringify(userProfiles));
// Обновляем выпадающий список
populateProfileSelector();
// Выбираем первый профиль по умолчанию
const allProfiles = loadAllProfiles();
if (allProfiles.length > 0) {
document.getElementById("profile-selector").value = allProfiles[0].name;
updateProfileFields(allProfiles[0]);
}
// Показываем сообщение об успешном удалении
Swal.fire({
title: "Удалено!",
text: "Профиль успешно удалён.",
icon: "success"
});
} else if (result.dismiss === Swal.DismissReason.cancel) {
// Показываем сообщение об отмене
Swal.fire({
title: "Отменено",
text: "Профиль не был удалён.",
icon: "error"
});
}
});
// Инициализация выпадающего списка при загрузке страницы
populateProfileSelector();
</script>
</body>
</html>