mirror of
https://github.com/wasrusgen/zov-tech.git
synced 2026-06-03 15:44:47 +00:00
feat: адрес замера — 6 раздельных полей (город/улица/дом/кв/подъезд/этаж)
- measurements.js: renderClientPicker — одно поле адреса заменено на addr-grid - добавлен локальный _splitAddr() — разбирает строку адреса обратно в поля - при выборе клиента из пикера адрес автоматически раскладывается по полям - каждое поле собирает state.address через readAndSaveAddr() - index.html: cache bump → v=20260514l Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
016e3becdd
commit
0d2973ea77
@ -369,26 +369,94 @@ const Measurements = (function () {
|
||||
/* ===================== Пикер клиента ===================== */
|
||||
|
||||
function renderClientPicker() {
|
||||
// Разбивает строку адреса на поля (локальная копия splitAddress из clients.js)
|
||||
function _splitAddr(s) {
|
||||
if (!s) return { city: "Санкт-Петербург", street: "", house: "", apt: "", entrance: "", floor: "" };
|
||||
s = s.trim();
|
||||
const grab = (re) => { const m = s.match(re); if (m) { s = s.replace(m[0], ""); return m[1]; } return ""; };
|
||||
const floor = grab(/,\s*этаж\s+([^\s,]+)/i);
|
||||
const entrance = grab(/,\s*подъезд\s+([^\s,]+)/i);
|
||||
const apt = grab(/,\s*кв\.?\s*([^\s,]+)/i);
|
||||
const house = grab(/,\s*д\.?\s*([^\s,]+)/i);
|
||||
s = s.replace(/,$/, "").trim();
|
||||
const parts = s.split(",").map(p => p.trim()).filter(Boolean);
|
||||
let city = "", street = "";
|
||||
if (parts.length >= 2) { city = parts[0]; street = parts.slice(1).join(", "); }
|
||||
else if (parts.length === 1) { city = parts[0]; }
|
||||
if (!city) city = "Санкт-Петербург";
|
||||
return { city, street, house, apt, entrance, floor };
|
||||
}
|
||||
|
||||
const initParts = _splitAddr(state.address || "");
|
||||
|
||||
const wrap = el(`
|
||||
<div class="client-picker-wrap">
|
||||
<div class="form-row" id="pcChoiceRow"></div>
|
||||
<div class="form-row">
|
||||
<label class="field">
|
||||
<span class="field-label">Адрес объекта</span>
|
||||
<input type="text" data-bind="address" id="pcAddr"
|
||||
value="${escAttr(state.address)}"
|
||||
placeholder="СПб, пр. Просвещения, д. 87, кв. 12">
|
||||
<div class="addr-grid">
|
||||
<label class="field">
|
||||
<span class="field-sublabel">Город</span>
|
||||
<input type="text" id="pcCity" value="${escAttr(initParts.city)}" placeholder="Санкт-Петербург" autocomplete="address-level2">
|
||||
</label>
|
||||
<label class="field">
|
||||
<span class="field-sublabel">Улица</span>
|
||||
<input type="text" id="pcStreet" value="${escAttr(initParts.street)}" placeholder="пр. Просвещения" autocomplete="street-address">
|
||||
</label>
|
||||
<label class="field addr-house">
|
||||
<span class="field-sublabel">Дом</span>
|
||||
<input type="text" id="pcHouse" value="${escAttr(initParts.house)}" placeholder="87" inputmode="text">
|
||||
</label>
|
||||
<label class="field addr-apt">
|
||||
<span class="field-sublabel">Кв./офис</span>
|
||||
<input type="text" id="pcApt" value="${escAttr(initParts.apt)}" placeholder="12" inputmode="numeric">
|
||||
</label>
|
||||
<label class="field addr-entrance">
|
||||
<span class="field-sublabel">Подъезд</span>
|
||||
<input type="text" id="pcEntrance" value="${escAttr(initParts.entrance)}" placeholder="1" inputmode="numeric">
|
||||
</label>
|
||||
<label class="field addr-floor">
|
||||
<span class="field-sublabel">Этаж</span>
|
||||
<input type="text" id="pcFloor" value="${escAttr(initParts.floor)}" placeholder="3" inputmode="numeric">
|
||||
</label>
|
||||
</div>
|
||||
<span class="field-error" id="pcAddrErr"></span>
|
||||
</div>
|
||||
</div>
|
||||
`);
|
||||
|
||||
const choiceRow = wrap.querySelector("#pcChoiceRow");
|
||||
const addrInput = wrap.querySelector("#pcAddr");
|
||||
|
||||
addrInput.addEventListener("input", e => {
|
||||
state.address = e.target.value;
|
||||
function readAndSaveAddr() {
|
||||
const city = (wrap.querySelector("#pcCity").value || "").trim();
|
||||
const street = (wrap.querySelector("#pcStreet").value || "").trim();
|
||||
const house = (wrap.querySelector("#pcHouse").value || "").trim();
|
||||
const apt = (wrap.querySelector("#pcApt").value || "").trim();
|
||||
const entrance = (wrap.querySelector("#pcEntrance").value || "").trim();
|
||||
const floor = (wrap.querySelector("#pcFloor").value || "").trim();
|
||||
state.address = [
|
||||
city, street,
|
||||
house ? "д. " + house : "",
|
||||
apt ? "кв. " + apt : "",
|
||||
entrance ? "подъезд " + entrance : "",
|
||||
floor ? "этаж " + floor : "",
|
||||
].filter(Boolean).join(", ");
|
||||
saveState();
|
||||
}
|
||||
|
||||
function fillAddrFields(address) {
|
||||
const p = _splitAddr(address || "");
|
||||
wrap.querySelector("#pcCity").value = p.city;
|
||||
wrap.querySelector("#pcStreet").value = p.street;
|
||||
wrap.querySelector("#pcHouse").value = p.house;
|
||||
wrap.querySelector("#pcApt").value = p.apt;
|
||||
wrap.querySelector("#pcEntrance").value = p.entrance;
|
||||
wrap.querySelector("#pcFloor").value = p.floor;
|
||||
readAndSaveAddr();
|
||||
}
|
||||
|
||||
["#pcCity","#pcStreet","#pcHouse","#pcApt","#pcEntrance","#pcFloor"].forEach(sel => {
|
||||
wrap.querySelector(sel).addEventListener("input", readAndSaveAddr);
|
||||
});
|
||||
|
||||
function refresh() {
|
||||
@ -407,10 +475,8 @@ const Measurements = (function () {
|
||||
`);
|
||||
card.querySelector(".picker-change-btn").addEventListener("click", openOverlay);
|
||||
choiceRow.appendChild(card);
|
||||
if (!addrInput.value && pickedClient.address) {
|
||||
addrInput.value = pickedClient.address;
|
||||
state.address = pickedClient.address;
|
||||
saveState();
|
||||
if (!state.address && pickedClient.address) {
|
||||
fillAddrFields(pickedClient.address);
|
||||
}
|
||||
} else {
|
||||
const empty = el(`
|
||||
|
||||
@ -12,14 +12,14 @@
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Geist:wght@400;500;600&family=Newsreader:ital,wght@0,400..600;1,400..600&family=Instrument+Serif:ital@0;1&family=JetBrains+Mono:wght@400;500&family=Cormorant+Garamond:ital,wght@1,400;1,500;1,600&family=Caveat:wght@500;700&display=swap">
|
||||
<script src="https://telegram.org/js/telegram-web-app.js"></script>
|
||||
<link rel="stylesheet" href="assets/styles.css?v=20260514k">
|
||||
<link rel="stylesheet" href="assets/podbor.css?v=20260514k">
|
||||
<link rel="stylesheet" href="assets/styles.css?v=20260514l">
|
||||
<link rel="stylesheet" href="assets/podbor.css?v=20260514l">
|
||||
</head>
|
||||
<body>
|
||||
<!-- Splash — лого @wasrusgen1 + опилки (16) + вращающийся диск -->
|
||||
<div class="loader splash" id="splash">
|
||||
<div class="brand-logo-wrap">
|
||||
<img class="brand-logo" src="assets/wasrusgen-logo.svg?v=20260514k" alt="@wasrusgen1">
|
||||
<img class="brand-logo" src="assets/wasrusgen-logo.svg?v=20260514l" alt="@wasrusgen1">
|
||||
<div class="splash-dust" aria-hidden="true">
|
||||
<span class="dust d1"></span> <span class="dust d2"></span>
|
||||
<span class="dust d3"></span> <span class="dust d4"></span>
|
||||
@ -35,15 +35,15 @@
|
||||
<div class="brand-tagline-gold">CRM</div>
|
||||
</div>
|
||||
<main id="app"></main>
|
||||
<script src="assets/icons.js?v=20260514k"></script>
|
||||
<script src="assets/podbor.config.js?v=20260514k"></script>
|
||||
<script src="assets/podbor.picts.js?v=20260514k"></script>
|
||||
<script src="assets/podbor.js?v=20260514k"></script>
|
||||
<script src="assets/clients.js?v=20260514k"></script>
|
||||
<script src="assets/zamer-picts.js?v=20260514k"></script>
|
||||
<script src="assets/measurements.js?v=20260514k"></script>
|
||||
<script src="assets/request.js?v=20260514k"></script>
|
||||
<script src="assets/assembly.js?v=20260514k"></script>
|
||||
<script src="assets/app.js?v=20260514k"></script>
|
||||
<script src="assets/icons.js?v=20260514l"></script>
|
||||
<script src="assets/podbor.config.js?v=20260514l"></script>
|
||||
<script src="assets/podbor.picts.js?v=20260514l"></script>
|
||||
<script src="assets/podbor.js?v=20260514l"></script>
|
||||
<script src="assets/clients.js?v=20260514l"></script>
|
||||
<script src="assets/zamer-picts.js?v=20260514l"></script>
|
||||
<script src="assets/measurements.js?v=20260514l"></script>
|
||||
<script src="assets/request.js?v=20260514l"></script>
|
||||
<script src="assets/assembly.js?v=20260514l"></script>
|
||||
<script src="assets/app.js?v=20260514l"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user