Søg bolig
0 Boliger til salg
Error executing template "Designs/rm/eCom/Product/Boligvisning.cshtml" System.InvalidOperationException: Sequence contains no elements at System.Linq.ThrowHelper.ThrowNoElementsException() at System.Linq.Enumerable.First[TSource](IEnumerable`1 source) at CompiledRazorTemplates.Dynamic.RazorEngine_48439d8883ff438b8ffcccf2e3eb33fd.ExecuteAsync() at RazorEngine.Templating.TemplateBase.Run(ExecuteContext context, TextWriter reader) at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.DynamicWrapperService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass23_0.<Run>b__0(TextWriter writer) at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter) at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag) at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template) at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template) at Dynamicweb.Rendering.Template.RenderRazorTemplate()
1 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 2 @using Custom.Tracking; 3 @using Dynamicweb; 4 @using Dynamicweb.Content.Items; 5 @using Dynamicweb.Core; 6 @using Dynamicweb.Core.Encoders; 7 @using RealMaeglerne.Library; 8 @using RealMaeglerne.Library.Models 9 @using System 10 @using System.Linq; 11 12 @functions { 13 string FormatPrice(int price, bool currencyBefore = false) 14 { 15 return currencyBefore ? "kr. " + price.ToString("#,##0") : price.ToString("#,##0") + " kr."; 16 } 17 18 string GetFullAddress(Dynamicweb.Security.UserManagement.UserGroup user) 19 { 20 if (user == null) { return string.Empty; } 21 22 var hasAddress = !string.IsNullOrEmpty(user.Address); 23 var hasZip = !string.IsNullOrEmpty(user.ZipCode); 24 var hasCity = !string.IsNullOrEmpty(user.City); 25 26 if (!hasAddress && !hasZip && !hasCity) return string.Empty; 27 28 return $"{(hasAddress ? user.Address + ", " : "")}{(hasZip ? user.ZipCode + " " : "")}{(hasCity ? user.City : "")}".TrimEnd(' ', ','); 29 } 30 31 string SetMaxLength(string s, int length) 32 { 33 return s == null ? string.Empty : s.Substring(0, Math.Min(length, s.Length)); 34 } 35 36 string StripHtml(string input) 37 { 38 if (string.IsNullOrEmpty(input)) return string.Empty; 39 return System.Text.RegularExpressions.Regex.Replace(input, "<.*?>", string.Empty).Trim(); 40 } 41 } 42 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 43 @using Dynamicweb.Content.Items; 44 45 @functions{ 46 void RenderErhvervsTypeCheckboxes(string productGroupFilter) 47 { 48 <div class="col-xs-6 col-md-4"> 49 <div class="checkbox"> 50 <label> 51 <input type="checkbox" name="propertytype" value="bolig/erhverv, kombineret erhverv og bolig, byejendom (kontor, butik, beboelse)" /> 52 <span>Bolig/erhverv</span> 53 </label> 54 </div> 55 <div class="checkbox"> 56 <label> 57 <input type="checkbox" name="propertytype" value="erhvervsgrund" /> 58 <span>Erhvervsgrund</span> 59 </label> 60 </div> 61 <div class="checkbox"> 62 <label> 63 <input type="checkbox" name="propertytype" value="boligudlejning" /> 64 <span>Boligudlejningsejendom</span> 65 </label> 66 </div> 67 <div class="checkbox"> 68 <label> 69 <input type="checkbox" name="propertytype" value="kontor, klinik, kontorhotel, showroom, undervisningslokaler" /> 70 <span>Kontor</span> 71 </label> 72 </div> 73 </div> 74 <div class="col-xs-6 col-md-4"> 75 <div class="checkbox"> 76 <label> 77 <input type="checkbox" name="propertytype" value="butik / detail, butik / detailhandel" /> 78 <span>Butik/detailhandel</span> 79 </label> 80 </div> 81 <div class="checkbox"> 82 <label> 83 <input type="checkbox" name="propertytype" value="industri / logistik, håndværk, industri, kontor / lager, logistik" /> 84 <span>Produktion/lager</span> 85 </label> 86 </div> 87 <div class="checkbox"> 88 <label> 89 <input type="checkbox" name="propertytype" value="hotel - kursusejendom, restaurant" /> 90 <span>Hotel og restaurant</span> 91 </label> 92 </div> 93 <div class="checkbox"> 94 <label> 95 <input type="checkbox" name="propertytype" value="projekt ejendom" /> 96 <span>Projektejendom</span> 97 </label> 98 </div> 99 </div> 100 <div class="col-xs-6 col-md-4"> 101 <div class="checkbox"> 102 <label> 103 <input type="checkbox" name="propertytype" value="andet" /> 104 <span>Andet</span> 105 </label> 106 </div> 107 </div> 108 109 <input type="hidden" name="propertycategory" value="erhverv, udlejning" /> 110 <input type="hidden" name="filtrering" value="@productGroupFilter" /> 111 } 112 void RenderBoligtypeCheckboxes() 113 { 114 <div class="col-6 col-md-4"> 115 <div class="checkbox"> 116 <label> 117 <input type="checkbox" name="propertytype" value="villa" /> 118 <span>Villa</span> 119 </label> 120 </div> 121 <div class="checkbox"> 122 <label> 123 <input type="checkbox" name="propertytype" value="rækkehus" /> 124 <span>Rækkehus</span> 125 </label> 126 </div> 127 <div class="checkbox"> 128 <label> 129 <input type="checkbox" name="propertytype" value="villalejlighed" /> 130 <span>Villalejlighed</span> 131 </label> 132 </div> 133 <div class="checkbox"> 134 <label> 135 <input type="checkbox" name="propertytype" value="andelsbolig" /> 136 <span>Andelsbolig</span> 137 </label> 138 </div> 139 </div> 140 <div class="col-6 col-md-4"> 141 <div class="checkbox"> 142 <label> 143 <input type="checkbox" name="propertytype" value="fritidshus, fritidsbolig" /> 144 <span>Fritidsbolig</span> 145 </label> 146 </div> 147 <div class="checkbox"> 148 <label> 149 <input type="checkbox" name="propertytype" value="ejerlejlighed" class="specialOption" data-disable-slider="#grundareal" data-disable-slider-ranges="#grundarealmin,#grundarealmax" /> 150 <span>Ejerlejlighed</span> 151 </label> 152 </div> 153 <div class="checkbox"> 154 <label> 155 <input type="checkbox" name="propertytype" value="helårsgrund" class="specialOption" data-disable-slider="#boligareal,#roomsslider" data-disable-slider-ranges="#boligarealmin,#boligarealmax,#roomsmin" /> 156 <span>Helårsgrund</span> 157 </label> 158 </div> 159 <div class="checkbox"> 160 <label> 161 <input type="checkbox" name="propertytype" value="fritidsgrund" class="specialOption" data-disable-slider="#boligareal,#roomsslider" data-disable-slider-ranges="#boligarealmin,#boligarealmax,#roomsmin" /> 162 <span>Fritidsgrund</span> 163 </label> 164 </div> 165 </div> 166 <div class="col-6 col-md-4"> 167 <div class="checkbox"> 168 <label> 169 <input type="checkbox" name="propertytype" value="landejendom, lystejendom" class="specialOption" data-disable-checkbox="true" /> 170 <span>Landejendom</span> 171 </label> 172 </div> 173 <div class="checkbox"> 174 <label> 175 <input type="checkbox" name="propertytype" value="erhverv" class="specialOption" data-disable-checkbox="true" data-disable-slider="#roomsslider" data-disable-slider-ranges="#roomsmin" /> 176 <span>Erhverv</span> 177 </label> 178 </div> 179 </div> 180 } 181 182 void RenderChecked(string queryString) 183 { 184 if (Dynamicweb.Context.Current.Request.QueryString["propertytype"] == queryString) 185 { 186 @("checked") 187 } 188 } 189 190 void RenderBoligtypeCheckboxesDropdown() 191 { 192 Dictionary<string, string> propertyTypes = new Dictionary<string, string>(){ 193 { "Villa", "villa" }, { "Rækkehus", "rækkehus" }, { "Villalejlighed", "villalejlighed" }, 194 { "Andelsbolig", "andelsbolig" } 195 }; 196 foreach (KeyValuePair<string, string> type in propertyTypes) 197 { 198 bool ischecked = false; 199 string[] propertytypeSplit = new string[0]; 200 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["propertytype"])) 201 { 202 propertytypeSplit = Dynamicweb.Context.Current.Request.QueryString["propertytype"].Split(','); 203 } 204 foreach (var propertytypeParams in propertytypeSplit) 205 { 206 if (propertytypeParams == type.Value) 207 { 208 ischecked = true; 209 } 210 } 211 <li> 212 <label class="checkbox-container d-flex"> 213 @Translate("Smartpage:Search.DropDown." + type.Key + "", "" + type.Key + "") 214 <input type="checkbox" name="propertytype" value="@type.Value" class="js-input-check datavalue js-datavalue js-count" data-val="@type.Key" onchange="submitFilter()" checked="@ischecked" /> 215 <span class="checkmark grey"></span> 216 </label> 217 </li> 218 } 219 220 <li> 221 <label class="checkbox-container d-flex"> 222 @Translate("Smartpage:Search.DropDown.Blandet Bolig/Erhverv", "Blandet Bolig/Erhverv") 223 @{ 224 bool blboligcheck = false; 225 } 226 @if (Dynamicweb.Context.Current.Request.QueryString["propertycategory"] == "Blandet Bolig/Erhverv") 227 { 228 blboligcheck = true; 229 } 230 <input type="checkbox" name="propertycategory" value="Blandet Bolig/Erhverv" class="specialOption js-input-check js-datavalue js-count" data-disable-checkbox="true" data-disable-slider="#roomsslider" data-disable-slider-ranges="#roomsmin" checked="@blboligcheck" /> 231 <span class="checkmark grey"></span> 232 </label> 233 </li> 234 235 Dictionary<string, string> propertyTypes2 = new Dictionary<string, string>(){ 236 { "Fritidsbolig", "fritidshus, fritidsbolig" }, { "Ejerlejlighed", "ejerlejlighed" }, { "Helårsgrund", "helårsgrund" }, 237 { "Fritidsgrund", "fritidsgrund" }, { "Landejendom", "landejendom, lystejendom" } 238 }; 239 foreach (KeyValuePair<string, string> type in propertyTypes2) 240 { 241 bool ischecked = false; 242 string[] propertytypeSplit2 = new string[0]; 243 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["propertytype"])) 244 { 245 propertytypeSplit2 = Dynamicweb.Context.Current.Request.QueryString["propertytype"].Split(','); 246 } 247 foreach (var propertytypeParams in propertytypeSplit2) 248 { 249 if (propertytypeParams == type.Value) 250 { 251 ischecked = true; 252 } 253 } 254 <li> 255 <label class="checkbox-container d-flex"> 256 @Translate("Smartpage:Search.DropDown." + type.Key + "", "" + type.Key + "") 257 @if (type.Value == "ejerlejlighed") 258 { 259 <input type="checkbox" name="propertytype" value="@type.Value" class="js-input-check datavalue" data-disable-slider="#grundareal" data-disable-slider-ranges="#grundarealmin,#grundarealmax" data-val="@type.Key" onchange="submitFilter()" checked="@ischecked" /> 260 } 261 else if (type.Value == "helårsgrund") 262 { 263 <input type="checkbox" name="propertytype" value="@type.Value" class="js-input-check datavalue" data-disable-slider="#boligareal,#roomsslider" data-disable-slider-ranges="#boligarealmin,#boligarealmax,#roomsmin" data-val="@type.Key" onchange="submitFilter()" checked="@ischecked" /> 264 } 265 else if (type.Value == "fritidsgrund") 266 { 267 <input type="checkbox" name="propertytype" value="@type.Value" class="js-input-check datavalue" data-disable-slider="#boligareal,#roomsslider" data-disable-slider-ranges="#boligarealmin,#boligarealmax,#roomsmin" data-val="@type.Key" onchange="submitFilter()" checked="@ischecked" /> 268 } 269 else 270 { 271 <input type="checkbox" name="propertytype" value="@type.Value" class="js-input-check datavalue" data-val="@type.Key" onchange="submitFilter()" checked="@ischecked" /> 272 } 273 <span class="checkmark grey"></span> 274 </label> 275 </li> 276 } 277 } 278 279 void RenderBoligTypeErhverv(bool submitOnChange = false, bool frontpage = false) 280 { 281 Dictionary<string, string> erhverType = new Dictionary<string, string>(){ 282 { "Kontor", "OwnUseOffices" }, { "Lager + Produktion", "OwnUseStoresAndProductions" }, { "Detailhandel", "OwnUseRetailAndStores" }, 283 { "Grunde", "OwnUseParcel" }, { "Andre typer", "OwnUseOtherTypes" }, { "Hotel + Restaurant", "OwnUseHotelsAndRestaurants" } 284 }; 285 var submitonchange = ""; 286 if (submitOnChange) 287 { 288 submitonchange = "onchange='submitFilter()'"; 289 } 290 291 foreach (KeyValuePair<string, string> type in erhverType) 292 { 293 string ischecked = ""; 294 string[] olineParamsSplit = new string[0]; 295 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["olinecategory"])) 296 { 297 olineParamsSplit = Dynamicweb.Context.Current.Request.QueryString["olinecategory"].Split(','); 298 } 299 foreach (var olineParams in olineParamsSplit) 300 { 301 if (olineParams == type.Value) 302 { 303 ischecked = "checked"; 304 } 305 } 306 307 <li> 308 <label class="checkbox-container d-flex"> 309 @Translate("Smartpage:Search.DropDown." + type.Key + "", "" + type.Key + "") 310 <input type="checkbox" name="olinecategory" value="@type.Value" class="js-input-check datavalue" data-val="@type.Key" @submitonchange @ischecked /> 311 <span class="checkmark grey"></span> 312 </label> 313 </li> 314 } 315 316 317 bool ischeckedpropertycat = false; 318 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["propertycategory"])) 319 { 320 if (Dynamicweb.Context.Current.Request.QueryString["propertycategory"] == "Blandet Bolig/Erhverv") 321 { 322 ischeckedpropertycat = true; 323 } 324 } 325 <li> 326 <label class="checkbox-container"> 327 @Translate("Smartpage:Search.DropDown.Blandet Bolig/Erhverv", "Blandet Bolig/Erhverv") 328 <input type="checkbox" name="propertycategory" value="Blandet Bolig/Erhverv" class="js-input-check datavalue" data-val="Blandet Bolig/Erhverv" onchange="submitFilter()" checked="@ischeckedpropertycat" /> 329 <span class="checkmark grey"></span> 330 </label> 331 </li> 332 } 333 334 void RenderBoligTypeErhvervInvest(bool submitOnChange = false) 335 { 336 Dictionary<string, string> erhverType = new Dictionary<string, string>(){ 337 { "Kontor", "Kontor" }, { "Lager + Produktion", "InvestmentStoresAndProductions" }, { "Boligudlejning", "InvestmentHousingRental" }, 338 { "Detailhandel", "InvestmentRetailAndStores" }, { "Grunde", "InvestmentParcel" }, { "Hotel + Restaurant", "InvestmentHotelsAndRestaurants" }, { "Andre typer", "InvestmentOtherTypes" } 339 }; 340 341 foreach (KeyValuePair<string, string> type in erhverType) 342 { 343 bool ischecked = false; 344 string[] olineParamsSplit = new string[0]; 345 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["olinecategory"])) 346 { 347 olineParamsSplit = Dynamicweb.Context.Current.Request.QueryString["olinecategory"].Split(','); 348 } 349 foreach (var olineParams in olineParamsSplit) 350 { 351 if (olineParams == type.Value) 352 { 353 ischecked = true; 354 } 355 } 356 357 <li> 358 <label class="checkbox-container"> 359 @Translate("Smartpage:Search.DropDown." + type.Key + "", "" + type.Key + "") 360 <input type="checkbox" name="olinecategory" value="@type.Value" class="js-input-check datavalue" data-val="@type.Key" onchange="submitFilter()" checked="@ischecked" /> 361 <span class="checkmark grey"></span> 362 </label> 363 </li> 364 } 365 } 366 int GetWebsiteSettingsPageId(string pageSysName) 367 { 368 int sideId = 0; 369 370 var pw = Dynamicweb.Frontend.PageView.Current(); 371 372 string settingsItemId = "1"; 373 374 if ((pw.Area.Item.ContainsKey("Type") && pw.Area.Item["Type"].ToString() == "bone") || Dynamicweb.Context.Current.Request.QueryString["bone"] == "true") 375 { 376 settingsItemId = "2"; 377 } 378 379 var settingsItem = ItemManager.Storage.GetById("Delte_Egenskaber", settingsItemId); 380 381 if (settingsItem == null || !settingsItem.ContainsKey(pageSysName)) 382 { 383 return sideId; 384 } 385 386 string boligsideLink = settingsItem[pageSysName] as String; 387 string linkPrefix = "Default.aspx?ID="; 388 389 if (!String.IsNullOrEmpty(boligsideLink) && boligsideLink.ToLower().StartsWith(linkPrefix.ToLower())) 390 { 391 Int32.TryParse(boligsideLink.Substring(linkPrefix.Length), out sideId); 392 } 393 394 return sideId; 395 } 396 397 int GetPageSettingsPageId(string pageSysName) 398 { 399 int sideId = 0; 400 401 var pw = Dynamicweb.Frontend.PageView.Current(); 402 403 if (pw.Page == null || pw.Page.PropertyItem == null || !pw.Page.PropertyItem.ContainsKey(pageSysName)) 404 { 405 return sideId; 406 } 407 408 string boligsideLink = pw.Page.PropertyItem[pageSysName] as String; 409 string linkPrefix = "Default.aspx?ID="; 410 411 if (!String.IsNullOrEmpty(boligsideLink) && boligsideLink.ToLower().StartsWith(linkPrefix.ToLower())) 412 { 413 Int32.TryParse(boligsideLink.Substring(linkPrefix.Length), out sideId); 414 } 415 416 return sideId; 417 } 418 void RenderMobileSelectBox(string name, int max, int step, string className, string inputname) 419 { 420 <select class="form-control d-block d-lg-none mb-10 @className" onchange="submitFilter()" name="@inputname"> 421 <option selected="true" disabled="disabled">@Translate("Smartpage:Search.Placeholder." + name + "", "" + name + "")</option> 422 423 @for (var i = 0; i <= max; i += step) 424 { 425 var selected = string.Empty; 426 var current = string.Empty; 427 if (i == max) 428 { 429 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString[inputname]) && Dynamicweb.Context.Current.Request.QueryString[inputname] == Convert.ToString(i)) 430 { 431 <option value="@i" data-value='@Convert.ToInt32(i).ToString("N0")' selected="selected">@Convert.ToInt32(i).ToString("N0")+</option> 432 } 433 else 434 { 435 <option value="@i" data-value='@Convert.ToInt32(i).ToString("N0")'>@Convert.ToInt32(i).ToString("N0")+</option> 436 } 437 } 438 else 439 { 440 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString[inputname]) && Dynamicweb.Context.Current.Request.QueryString[inputname] == Convert.ToString(i)) 441 { 442 <option value="@i" data-value='@Convert.ToInt32(i).ToString("N0")' selected="selected">@Convert.ToInt32(i).ToString("N0")</option> 443 } 444 else 445 { 446 <option value="@i" data-value='@Convert.ToInt32(i).ToString("N0")'>@Convert.ToInt32(i).ToString("N0")</option> 447 } 448 } 449 } 450 </select> 451 } 452 453 void RenderTopFilter(string parameter) 454 { 455 if (parameter == "pricemin" || parameter == "pricemax") 456 { 457 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["pricemin"])) 458 { 459 if (parameter == "pricemin") 460 { 461 @("<div class='search-terms' id='priceFilter'>") 462 @("Pris ") @Dynamicweb.Context.Current.Request[parameter] 463 } 464 465 else 466 { 467 @(" - ") @Dynamicweb.Context.Current.Request[parameter] @(" kr.") <i class="fa fa-times ml-2 pointer" onclick="removeParams(this)" data-tag="pricemin,pricemax"></i> 468 @("</div>") 469 } 470 } 471 } 472 473 else if (parameter == "subsidymin" || parameter == "subsidymax") 474 { 475 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["subsidymin"])) 476 { 477 if (parameter == "subsidymin") 478 { 479 @("<div class='search-terms' id='subsidyFilter'>") 480 @("Årlig leje ") @Dynamicweb.Context.Current.Request[parameter] 481 } 482 483 else 484 { 485 @(" - ") @Dynamicweb.Context.Current.Request[parameter] @(" kr.") <i class="fa fa-times ml-2 pointer" onclick="removeParams(this)" data-tag="subsidymin,subsidymax"></i> 486 @("</div>") 487 } 488 } 489 } 490 else if (parameter == "etagearealmin" || parameter == "etagearealmax") 491 { 492 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["etagearealmin"])) 493 { 494 if (parameter == "etagearealmin") 495 { 496 @("<div class='search-terms' id='etagearealFilter'>") 497 @("Etageareal ") @Dynamicweb.Context.Current.Request[parameter] 498 } 499 500 else 501 { 502 @(" - ") @Dynamicweb.Context.Current.Request[parameter] @(" kvm.") <i class="fa fa-times ml-2 pointer" onclick="removeParams(this)" data-tag="etagearealmin,etagearealmax"></i> 503 @("</div>") 504 } 505 } 506 } 507 508 else if (parameter == "grundarealmin" || parameter == "grundarealmax") 509 { 510 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["grundarealmin"])) 511 { 512 if (parameter == "grundarealmin") 513 { 514 @("<div class='search-terms' id='grundarealFilter'>") 515 @("Grundareal ") @Dynamicweb.Context.Current.Request[parameter] 516 } 517 518 else 519 { 520 @(" - ") @Dynamicweb.Context.Current.Request[parameter] @(" kvm.") <i class="fa fa-times ml-2 pointer" onclick="removeParams(this)" data-tag="grundarealmin,grundarealmax"></i> 521 @("</div>") 522 } 523 } 524 } 525 526 else if (parameter == "subsidykvmmin" || parameter == "subsidykvmmax") 527 { 528 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["subsidykvmmin"])) 529 { 530 if (parameter == "subsidykvmmin") 531 { 532 @("<div class='search-terms' id='subsidykvmFilter'>") 533 @("Årlig leje kvm ") @Dynamicweb.Context.Current.Request[parameter] 534 } 535 536 else 537 { 538 @(" - ") @Dynamicweb.Context.Current.Request[parameter] @(" kr.") <i class="fa fa-times ml-2 pointer" onclick="removeParams(this)" data-tag="subsidykvmmin,subsidykvmmax"></i> 539 @("</div>") 540 } 541 } 542 } 543 544 else if (parameter == "olinecategory") 545 { 546 547 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["olinecategory"])) 548 { 549 Dictionary<string, string> erhverType = new Dictionary<string, string>(){ 550 {"OwnUseOffices", "Kontor" }, { "OwnUseStoresAndProductions","Lager + Produktion" }, { "OwnUseRetailAndStores","Detailhandel" }, 551 { "OwnUseParcel", "Grunde" }, { "OwnUseHotelsAndRestaurants", "Hotel + Restaurant" }, { "OwnUseOtherTypes", "Andre typer"}, 552 { "Kontor", "Kontor" }, { "InvestmentStoresAndProductions", "Lager + Produktion" }, { "InvestmentHousingRental", "Boligudlejning" }, 553 { "InvestmentRetailAndStores", "Detailhandel" }, { "InvestmentParcel", "Grunde" }, { "InvestmentHotelsAndRestaurants", "Hotel + Restaurant" }, { "InvestmentOtherTypes", "Andre typer" } 554 }; 555 556 557 foreach (var er in erhverType) 558 { 559 if (Dynamicweb.Context.Current.Request[parameter].Contains(er.Key)) 560 { 561 <div class="search-terms" id="@parameter"> 562 @er.Value <i class="fa fa-times ml-2 pointer" onclick="removeParams(this)" data-tag="@parameter" data-val="@er.Key"></i> 563 </div> 564 } 565 } 566 } 567 } 568 else if (parameter == "propertycategory") 569 { 570 571 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["propertycategory"])) 572 { 573 Dictionary<string, string> erhverType = new Dictionary<string, string>(){ 574 { "propertycategory", "Blandet Bolig/Erhverv" } 575 }; 576 577 foreach (var er in erhverType) 578 { 579 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request[parameter]) && Dynamicweb.Context.Current.Request[parameter] == er.Value) 580 { 581 <div class="search-terms" id="@parameter"> 582 @er.Value <i class="fa fa-times ml-2 pointer" onclick="removeParams(this)" data-tag="@parameter" data-val="@er.Key"></i> 583 </div> 584 } 585 } 586 } 587 } 588 else if (parameter == "search") 589 { 590 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["search"])) 591 { 592 <div class="search-terms" id="@parameter"> 593 @Dynamicweb.Context.Current.Request[parameter] <i class="fa fa-times ml-2 pointer" onclick="removeParams(this)" data-tag="@parameter"></i> 594 </div> 595 } 596 } 597 else 598 { 599 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request[parameter])) 600 { 601 Dictionary<string, string> 602 ubudsform = new Dictionary<string, string> 603 (){ 604 {"salg", "Salg" }, { "leje","Leje" } 605 }; 606 607 foreach (var er in ubudsform) 608 { 609 if (Dynamicweb.Context.Current.Request[parameter].Contains(er.Key)) 610 { 611 <div class="search-terms" id="@parameter"> 612 @er.Value <i class="fa fa-times ml-2 pointer" onclick="removeParams(this)" data-tag="@parameter" data-val="@er.Key"></i> 613 </div> 614 } 615 } 616 617 618 } 619 } 620 } 621 622 void RenderSelectValue(string dropdownname, string dropdownvalue, string queryString) 623 { 624 var selected = ""; 625 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString[queryString]) && Dynamicweb.Context.Current.Request.QueryString[queryString] == dropdownvalue) 626 { 627 selected = "selected"; 628 } 629 630 var current = string.Format("<option value='" + dropdownvalue + "'>" + dropdownname + "</option>", selected); 631 632 @current 633 } 634 635 void RenderSearchForHousing(int searchPageId, string querySearch, string querySearchNameAttr, string queryZipCodeFrom, string queryZipCodeTo, string template, Item SettingsItem, string cssClasses = "") 636 { 637 <div class="main-search-form frontpage @cssClasses"> 638 <div class="dropdown-overlay"></div> 639 <div class="row mb-3 align-items-center"> 640 <div class="col-xs-12 col-md-3 border-right"> 641 <h3>@Translate("Smartpage:Search.Søg bolig", "Søg bolig")</h3> 642 </div> 643 <div class="col-xs-12 col-md-9 home-count d-none d-md-block"> 644 <span class="search-count" id="searchCounter">0</span> <span>@Translate("Smartpage:Search.BoligerTilSalg", "Boliger til salg")</span> 645 </div> 646 </div> 647 648 <form id="main-search-frontpage" class="searchbar-wrapper" action="/Default.aspx" method="GET"> 649 <input type="hidden" name="ID" value='@searchPageId' id="searchPageId-frontpage" disabled="disabled" /> 650 <div class="row form-wrapper no-gutters"> 651 652 <div class="col-xs-12 col-md-5 col-searchbar"> 653 <div class="searchbar"> 654 <input type="text" name="@querySearchNameAttr" id="searchfield-frontpage" class="search-input" placeholder="Postnummer, by, vej eller sagsnummer" tabindex="1" value="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(querySearch)" /> 655 <input type="hidden" id="zipcodefrom-frontpage" name="zipcodefrom" value="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(queryZipCodeFrom)" /> 656 <input type="hidden" id="zipcodeto-frontpage" name="zipcodeto" value="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(queryZipCodeTo)" /> 657 </div> 658 </div> 659 <div class="col-xs-12 col-md-5"> 660 <div class="row no-gutters"> 661 <div class="col-xs-12 col-md-6 input-col"> 662 <div class="dropdown w-overlay"> 663 <button class="btn btn-dropdown dropdown-toggle reverse position-absolute-md" type="button" id="Boligtype-frontpage" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> 664 @Translate("Smartpage:Search.Boligtype", "Boligtype") 665 </button> 666 <div class="dropdown-menu box-shadow bolig-dropdown-container" aria-labelledby="Boligtype"> 667 <ul class="bolig-dropdown list-unstyled"> 668 @{ 669 RenderBoligtypeCheckboxesDropdown(); 670 } 671 </ul> 672 <span class="border-fat"></span> 673 <button class="btn btn-primary js-close-dropdown">@Translate("Smartpage:Search.Anvend", "Anvend")</button> 674 </div> 675 676 </div> 677 678 </div> 679 <div class="col-xs-12 col-md-6 input-col"> 680 <div class="dropdown w-overlay"> 681 <button class="btn btn-dropdown dropdown-toggle reverse position-absolute-md" type="button" id="Pris-frontpage" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> 682 @Translate("Smartpage:Search.Pris", "Pris") 683 </button> 684 <div class="dropdown-menu box-shadow dropdown-price" aria-labelledby="Pris"> 685 <input type="text" class="form-control mb-10 js-auto-thousand js-pricemin-frontpage-input" placeholder='@Translate("Smartpage:Search.Placeholder.MinPris","Min. pris")' /> 686 <select class="form-control js-pricemin-frontpage-select js-input-min-select mb-10"> 687 <option selected="true" disabled="disabled">@Translate("Smartpage:Search.Placeholder.MinPris", "Min. pris")</option> 688 @for (var i = 0; i <= 10000000; i += 100000) 689 { 690 if (i == 10000000) 691 { 692 <option value="@i" data-value='@Convert.ToInt32(i).ToString("N0")+'>@Convert.ToInt32(i).ToString("N0")+</option> 693 } 694 else 695 { 696 <option value="@i" data-value='@Convert.ToInt32(i).ToString("N0")'>@Convert.ToInt32(i).ToString("N0")</option> 697 } 698 } 699 </select> 700 <input type="hidden" id="pricemin-frontpage" name="pricemin" /> 701 702 <input type="text" class="form-control js-auto-thousand js-pricemax-frontpage-input" placeholder='@Translate("Smartpage:Search.Placeholder.MaxPris","Max. pris")' /> 703 <select class="form-control js-pricemax-frontpage-select js-input-max-select"> 704 <option selected="true" disabled="disabled">@Translate("Smartpage:Search.Placeholder.MaxPris", "Max. pris")</option> 705 @for (var i = 0; i <= 10000000; i += 100000) 706 { 707 if (i == 10000000) 708 { 709 <option value="@i" data-value='@Convert.ToInt32(i).ToString("N0")+'>@Convert.ToInt32(i).ToString("N0")+</option> 710 } 711 else 712 { 713 <option value="@i" data-value='@Convert.ToInt32(i).ToString("N0")'>@Convert.ToInt32(i).ToString("N0")</option> 714 } 715 } 716 </select> 717 <input type="hidden" id="pricemax-frontpage" name="pricemax" /> 718 <button class="btn btn-primary js-close-dropdown mt-3">@Translate("Smartpage:Search.Anvend", "Anvend")</button> 719 </div> 720 </div> 721 </div> 722 </div> 723 </div> 724 <div class="col-xs-12 col-md-2 d-none d-md-block"> 725 <button type="submit" class="btn btn-block btn-search"><i class="fa fa-search"></i> @Translate("Smartpage:Search.Søg", "Søg")</button> 726 </div> 727 </div> 728 729 <div class="row moresearch-btn no-gutters"> 730 <div class="col-sm-12"> 731 <div class="row align-items-center no-gutters"> 732 <div class="col-12 col-md-4"> 733 <button class="btn-blank js-search-collapse" type="button" data-toggle="collapse" data-target="#moreSearch" aria-expanded="false" aria-controls="moreSearch"> 734 <span class="moreSearch-text"><i class="fas fa-plus open-close"></i> <span class="not-open">@Translate("Smartpage:Search.Flere søgemuligheder", "Flere søgemuligheder")</span> <span class="open"><span class="js-filter-count">0</span> @Translate("Smartpage:Search.FiltreAnvendt", "filtre anvendt") </span></span> 735 </button> 736 </div> 737 <div class="col-6 col-md-2 mb-xs-4"> 738 <a class="js-reset reset-btn">@Translate("Smartpage:Search.NulstilValg", "Nulstil valg")</a> 739 </div> 740 </div> 741 742 <div class="collapse" id="moreSearch"> 743 <h4 class="mt-20"><b>@Translate("Smartpage:Search.Bolig", "Bolig")</b></h4> 744 <div class="row align-items-end mb-30"> 745 <div class="col-12 col-sm-6 col-lg-3 mb-3 mb-lg-0"> 746 <div class="filter-container row"> 747 <label class="d-block col-12">@Translate("Smartpage:Search.Boligareal", "Boligareal")</label> 748 <div class="col-6 pr-sm-0 pr-2"> 749 <input type="text" name="boligarealmin" id="boligarealmin-frontpage" class="form-control js-boligarealmin-frontpage-input js-count" placeholder='@Translate("Smartpage:Search.Placeholder.Minm2","Min. m2")' /> 750 <select class="form-control js-boligarealmin-frontpage-select js-count"> 751 <option selected="true" disabled="disabled">@Translate("Smartpage:Search.Placeholder.Minm2", "Min. m2")</option> 752 @for (var i = 0; i <= 300; i += 10) 753 { 754 if (i == 300) 755 { 756 <option value="@i">@i+</option> 757 } 758 else 759 { 760 <option value="@i">@i</option> 761 } 762 } 763 </select> 764 </div> 765 <div class="col-6 pl-sm-0 pl-2"> 766 <input type="text" name="boligarealmax" id="boligarealmax-frontpage" class="form-control js-boligarealmax-frontpage-input js-count" placeholder='@Translate("Smartpage:Search.Placeholder.Maxm2","Max. m2")' /> 767 <select class="form-control js-boligarealmax-frontpage-select js-count"> 768 <option selected="true" disabled="disabled">@Translate("Smartpage:Search.Placeholder.Maxm2", "Max. m2")</option> 769 @for (var i = 0; i <= 300; i += 10) 770 { 771 if (i == 300) 772 { 773 <option value="@i">@i+</option> 774 } 775 else 776 { 777 <option value="@i">@i</option> 778 } 779 } 780 </select> 781 </div> 782 </div> 783 </div> 784 <div class="col-12 col-sm-6 col-lg-3 mb-3 mb-lg-0"> 785 <div class="filter-container row"> 786 <label class="d-block col-12">@Translate("Smartpage:Search.Grundareal", "Grundareal")</label> 787 <div class="col-6 pr-sm-0 pr-2"> 788 <input type="text" name="grundarealmin" id="grundarealmin-frontpage" class="form-control js-grundarealmin-frontpage-input js-count" placeholder='@Translate("Smartpage:Search.Placeholder.Minm2","Min. m2")' /> 789 <select class="form-control js-grundarealmin-frontpage-select js-count"> 790 <option selected="true" disabled="disabled">@Translate("Smartpage:Search.Placeholder.Minm2", "Min. m2")</option> 791 @for (var i = 0; i <= 10000; i += 100) 792 { 793 if (i == 10000) 794 { 795 <option value="@i">@i+</option> 796 } 797 else 798 { 799 <option value="@i">@i</option> 800 } 801 } 802 </select> 803 </div> 804 <div class="col-6 pl-sm-0 pl-2"> 805 <input type="text" name="grundarealmax" id="grundarealmax-frontpage" class="form-control js-grundarealmax-frontpage-input js-count" placeholder='@Translate("Smartpage:Search.Placeholder.Maxm2","Max. m2")' /> 806 <select class="form-control js-grundarealmax-frontpage-select js-count"> 807 <option selected="true" disabled="disabled">@Translate("Smartpage:Search.Placeholder.Maxm2", "Max. m2")</option> 808 @for (var i = 0; i <= 10000; i += 100) 809 { 810 if (i == 10000) 811 { 812 <option value="@i">@i+</option> 813 } 814 else 815 { 816 <option value="@i">@i</option> 817 } 818 } 819 </select> 820 </div> 821 </div> 822 </div> 823 <div class="col-12 col-sm-6 col-lg-3 mb-3 mb-lg-0"> 824 <div class="filter-container row"> 825 <label class="d-block col-12">Antal rum</label> 826 827 <div class="col-6 pr-sm-0 pr-2"> 828 <select name="roomsmin" id="roomsmin-frontpage" class="form-control reverse js-count"> 829 <option selected="true" disabled="disabled">@Translate("Smartpage:Search.Placeholder.Min", "Min")</option> 830 <option value="1">1</option> 831 <option value="2">2</option> 832 <option value="3">3</option> 833 <option value="4">4</option> 834 <option value="5+">5+</option> 835 </select> 836 </div> 837 <div class="col-6 pl-sm-0 pl-2"> 838 <select name="roomsmax" id="roomsmax-frontpage" class="form-control reverse js-count"> 839 <option selected="true" disabled="disabled">@Translate("Smartpage:Search.Placeholder.Max", "Max")</option> 840 <option value="1">1</option> 841 <option value="2">2</option> 842 <option value="3">3</option> 843 <option value="4">4</option> 844 <option value="5+">@Translate("Smartpage:Rooms.5", "5")</option> 845 </select> 846 </div> 847 </div> 848 </div> 849 <div class="col-12 col-sm-6 col-lg-3 mb-3 mb-lg-0"> 850 <div class="row"> 851 <div class="col-12"> 852 <div class="filter-container"> 853 <label class="d-block">Energimærke</label> 854 <select name="energylabel" id="energylabel-frontpage" class="form-control reverse js-count"> 855 <option disabled selected="selected">@Translate("Smartpage:Search.Vælg", "Vælg")</option> 856 <option value="01">G</option> 857 <option value="02">F</option> 858 <option value="03">E</option> 859 <option value="04">D</option> 860 <option value="05">C</option> 861 <option value="06">B</option> 862 <option value="07">A</option> 863 <option value="08">A2010</option> 864 <option value="09">A2015</option> 865 <option value="10">A2020+</option> 866 </select> 867 </div> 868 </div> 869 </div> 870 </div> 871 <div class="col-12 col-sm-6 col-lg-3 mt-3"> 872 <h4 class=""><b>@Translate("Smartpage:Search.Økonomi", "Økonomi")</b></h4> 873 <div class="filter-container row"> 874 <label class="d-block col-12">@Translate("Smartpage:Search.Ejerudgift/boligydelse pr. måned", "Ejerudgift/boligydelse pr. måned")</label> 875 <div class="col-6 pr-sm-0 pr-2"> 876 <input type="text" name="subsidymin" id="subsidymin-frontpage" class="form-control js-subsidymin-frontpage-input js-count" placeholder='@Translate("Smartpage:Search.Placeholder.MinDKK","Min. DKK")' /> 877 <select class="form-control js-subsidymin-frontpage-select js-count"> 878 <option selected="true" disabled="disabled">@Translate("Smartpage:Search.Placeholder.MinDKK", "Min. DKK")</option> 879 @for (var i = 0; i <= 25000; i += 1250) 880 { 881 if (i == 25000) 882 { 883 <option>@Convert.ToInt32(i).ToString("N0")+</option> 884 } 885 else 886 { 887 <option>@Convert.ToInt32(i).ToString("N0")</option> 888 } 889 } 890 </select> 891 </div> 892 <div class="col-6 pl-sm-0 pl-2"> 893 <input type="text" name="subsidymax" id="subsidymax-frontpage" class="form-control js-subsidymax-frontpage-input js-count" placeholder='@Translate("Smartpage:Search.Placeholder.MaxDKK","Max. DKK")' /> 894 <select class="form-control js-subsidymax-frontpage-select js-count"> 895 <option selected="true" disabled="disabled">@Translate("Smartpage:Search.Placeholder.MaxDKK", "Max. DKK")</option> 896 @for (var i = 0; i <= 25000; i += 1250) 897 { 898 if (i == 25000) 899 { 900 <option value="@Convert.ToInt32(i)">@Convert.ToInt32(i).ToString("N0")+</option> 901 } 902 else 903 { 904 <option value="@Convert.ToInt32(i)">@Convert.ToInt32(i).ToString("N0")</option> 905 } 906 } 907 </select> 908 </div> 909 </div> 910 </div> 911 <div class="col-12 col-sm-6 col-lg-4 offset-lg-5 mt-3 mt-sm-0"> 912 <button type="submit" class="btn btn-block btn-search"><i class="fa fa-search"></i> @Translate("Smartpage:Search.AnvendFiltre", "Anvend filtre")</button> 913 </div> 914 </div> 915 </div> 916 </div> 917 </div> 918 919 <div class="row d-block d-md-none form-wrapper no-gutters"> 920 <div class="col-xs-12 col-md-2"> 921 <button type="submit" class="btn btn-block btn-search btn-mobile-search">@Translate("Smartpage:Search.SøgBolig", "Søg Bolig")<i class="fa fa-search cta-icon"></i></button> 922 </div> 923 </div> 924 </form> 925 <div class="front-page-actions d-md-none"> 926 <div> 927 <button class="btn btn-block btn-search btn-mobile-search js-search-mobile">@Translate("Smartpage:Search.SøgBolig", "Søg Bolig")<i class="fa fa-search cta-icon"></i></button> 928 </div> 929 <div> 930 @{ 931 string brokerSearchId = SettingsItem != null ? Dynamicweb.Core.Converter.ToString(SettingsItem["Maeglersogning"]).Replace("Default.aspx?Id=", "") : ""; 932 string ctaText = Translate("Smartpage.Frontpage.Mobile.FindBroker", "FIND EJENDOMSMÆGLER"); 933 <form method="GET" action="/Default.aspx"> 934 <input name="id" value="@brokerSearchId" type="hidden" /> 935 <div class="icon-wrapper-wclick"> 936 <i class="fas fa-search ta-submit-on-icon-click"></i> 937 <input class="box-cta-input ta-postnummer ta-submit-on-select ta-submit-on-enter" name="q" type="text" placeholder="@ctaText" onfocus="this.placeholder = ''" onblur="this.placeholder='@ctaText'" /> 938 </div> 939 </form> 940 } 941 </div> 942 <div> 943 <a href="javascript:panelSalgsvurdering('Hovedmenu')" class="btn btn-orange btn-block">@Translate("Smartpage:Frontpage.Mobile.GetFreeAppraisal", "BESTIL GRATIS VURDERING")<i class="cta-icon fa fa-angle-right"></i></a> 944 </div> 945 </div> 946 </div> 947 948 } 949 Custom.Integration.Brokers.Models.BrokerEmployee GetBrokerFromCurrentProduct() 950 { 951 string productId = Dynamicweb.Context.Current.Request["ProductId"]; 952 953 if (string.IsNullOrWhiteSpace(productId)) 954 { 955 return null; 956 } 957 958 var propertyProduct = Dynamicweb.Ecommerce.Services.Products.GetProductById(productId, string.Empty, true); 959 if (propertyProduct == null) 960 { 961 return null; 962 } 963 964 string employee = Dynamicweb.Core.Converter.ToString( 965 Dynamicweb.Ecommerce.Services.Products.GetProductFieldValue(propertyProduct, "xAktoererMaeglerKontaktEmail") 966 ); 967 string storeId = Dynamicweb.Core.Converter.ToString( 968 Dynamicweb.Ecommerce.Services.Products.GetProductFieldValue(propertyProduct, "xButikID") 969 ); 970 971 if (string.IsNullOrWhiteSpace(employee) || string.IsNullOrWhiteSpace(storeId)) 972 { 973 return null; 974 } 975 976 return Custom.Integration.Brokers.Search.GetEmployee(storeId, employee); 977 } 978 979 string GetAgentTitleFromCurrentProduct() 980 { 981 var propBroker = GetBrokerFromCurrentProduct(); 982 983 if (propBroker?.Broker == null) 984 { 985 return string.Empty; 986 } 987 988 if (!string.IsNullOrEmpty(propBroker.Broker.CompanyName)) 989 { 990 return propBroker.Broker.CompanyName; 991 } 992 993 return propBroker.Broker.Name ?? string.Empty; 994 } 995 996 string GetMasterBrokerUrlFromCurrentProduct() 997 { 998 var propBroker = GetBrokerFromCurrentProduct(); 999 1000 var itemId = propBroker?.Broker?.ItemId; 1001 var itemType = propBroker?.Broker?.ItemType; 1002 1003 if (string.IsNullOrWhiteSpace(itemId) || string.IsNullOrWhiteSpace(itemType)) 1004 { 1005 return string.Empty; 1006 } 1007 var brokerItem = Dynamicweb.Content.Items.ItemManager.Storage.GetById(itemType, itemId); 1008 1009 if (brokerItem == null) 1010 { 1011 return string.Empty; 1012 } 1013 1014 var websiteId = Dynamicweb.Core.Converter.ToInt32(brokerItem["WebsiteId"]); 1015 var page = Dynamicweb.Content.Services.Pages.GetFirstPageForArea(websiteId); 1016 return Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl("Default.aspx?Id=" + page?.ID); 1017 } 1018 } 1019 1020 @{ 1021 1022 var settingsItem = ItemManager.Storage.GetById("Delte_Egenskaber", "1"); 1023 var settingsActivateGreenMobility = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetBoolean("Activate_Green_Mobility"); 1024 1025 var iconPath = "/Files/Templates/Designs/rm/assets/images/svg/"; 1026 var imagePath = "/Files/Images/RM billeder/"; 1027 string fallbackImage = "/Files/Templates/Designs/rm/assets/images/na-real.png"; 1028 1029 string productId = GetString("Ecom:Product.ID"); 1030 var product = Dynamicweb.Ecommerce.Services.Products.GetProductById(productId, string.Empty, true); 1031 string propCategory = GetString("Ecom:Product:Field.xEjendomEjendomskategori"); 1032 string propType = GetString("Ecom:Product:Field.xEjendomEjendomstype"); 1033 string propTypeCategory = ""; 1034 if (!string.IsNullOrEmpty(propType)) 1035 { 1036 propTypeCategory = RealMaeglerne.Dynamicweb.PropertyClassification.GetCategoryByTypeName(propType).ToLower(); 1037 } 1038 1039 string propTypeDisplay = !string.IsNullOrWhiteSpace(propCategory) ? propCategory : propTypeCategory; 1040 bool isRental = (propCategory != null && GetString("Ecom:Product:Field.xUdbudsForm").ToLower() == "leje" && !propCategory.Contains("erhverv")) || Converter.ToBoolean(Dynamicweb.Context.Current.Request["Udlejning"]); 1041 1042 string Employee = GetString("Ecom:Product:Field.xAktoererMaeglerKontaktEmail"); 1043 Custom.Integration.Brokers.Models.BrokerEmployee propBroker = Custom.Integration.Brokers.Search.GetEmployee(GetString("Ecom:Product:Field.xButikID"), Employee); 1044 var employeeItem = Dynamicweb.Content.Items.ItemManager.Storage.GetById(propBroker?.Employee?.ItemType, propBroker?.Employee?.ItemId); 1045 var brokerItem = Dynamicweb.Content.Items.ItemManager.Storage.GetById(propBroker?.Broker?.ItemType, propBroker?.Broker?.ItemId); 1046 1047 var popularityMetrics = Custom.Tracking.Providers.TrackingProvider.GetPopularityMetrics(productId); 1048 1049 bool isValidForGreenMobility = false; 1050 1051 if (settingsActivateGreenMobility) 1052 { 1053 var settingsGreenMobilityPostalCodes = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItems("Green_Mobility_Postnumre"); 1054 int postalCode = GetInteger("Ecom:Product:Field.xEjendomAdressePostnummer"); 1055 1056 isValidForGreenMobility = settingsGreenMobilityPostalCodes.Any(range => 1057 { 1058 int start = Convert.ToInt32(range.GetRawValue("Start")); 1059 int end = Convert.ToInt32(range.GetValue("Slut")); 1060 1061 return end > 0 ? postalCode >= start && postalCode <= end : postalCode == start; 1062 }); 1063 } 1064 1065 Dictionary<string, string> edhFiles = RealMaeglerne.Library.BoligManager.GetEDHFilesCompact(product); 1066 1067 var origin = $"{Context.Current.Session["DP"]}Boligvisning (sektion: galleri)"; 1068 1069 } 1070 1071 <script> 1072 // Set RMAPI (defined in master) values relevant for this page 1073 if(RMAPI) { 1074 RMAPI.ButikId = "@GetString("Ecom:Product:Field.xButikID")"; 1075 RMAPI.Boligvisning = true; 1076 RMAPI.SagsNr = "@productId"; 1077 RMAPI.MarkerColor = "#F06F18"; 1078 } 1079 </script> 1080 1081 <div propertypage-top role="main" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.PropertyMain", "Ejendomsvisning hovedindhold"))"> 1082 @*SECTION: Breadcrumbs*@ 1083 1084 <nav class="container breadcrumbs" role="navigation" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.Breadcrumb", "Brødkrumme navigation"))"> 1085 <div class="divider-blue d-none d-md-block" aria-hidden="true"></div> 1086 <div class="row py-md-3 py-2"> 1087 <div class="col-6"> 1088 @{ 1089 int searchPageId = GetPageSettingsPageId("Boligside"); 1090 if (searchPageId == 0) 1091 { 1092 searchPageId = GetWebsiteSettingsPageId("Boligside"); 1093 } 1094 } 1095 <a href="/Default.aspx?ID=@searchPageId" class="breadcrumb-item" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.BackToSearch", "Tilbage til boligsøgning"))"> 1096 @Translate("Custom:Propertypage.Breadcrumbs.Search", "Søg bolig") 1097 </a> 1098 @if (propBroker != null) 1099 { 1100 <a href="/Default.aspx?ID=@searchPageId&search=@propBroker.Broker.City" class="breadcrumb-item" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.SearchInCity", "Søg boliger i")) @propBroker.Broker.City"> 1101 @propBroker.Broker.City 1102 </a> 1103 } 1104 </div> 1105 <div class="col-6 text-right"> 1106 <a class="breadcrumb-link cursor-pointer" data-share-text="@Translate("Custom:Propertypage.Sharelink.ShareText", "Se denne bolig")" data-alert-text="@Translate("Custom:Propertypage.Sharelink.AlertText", "Link kopieret til udklipsholder!")" onclick="shareProperty(event, this)" role="button" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ShareProperty", "Del denne bolig"))" onkeypress="if(event.key === 'Enter' || event.key === ' ') shareProperty(event, this)"> 1107 <img class="d-md-none d-inline mr-1" src="@(iconPath + "icon-share.svg")" alt="" aria-hidden="true" /> 1108 <img class="d-none d-md-inline mr-1" src="@(iconPath + "icon-share-desktop.svg")" alt="" aria-hidden="true" /> 1109 @Translate("Custom:Propertypage.Breadcrumbs.Share", "Del bolig") 1110 </a> 1111 </div> 1112 </div> 1113 <div class="divider-blue d-none d-md-block" aria-hidden="true"></div> 1114 </nav> 1115 1116 @*SECTION: Images*@ 1117 @{ 1118 var boligManager = new RealMaeglerne.Library.BoligManager(Pageview); 1119 RealMaeglerne.Library.Models.Bolig bolig = boligManager.CreateBolig(product, true); 1120 1121 1122 bool useEsoftImages = settingsItem != null ? Converter.ToBoolean(settingsItem["SpUseEsoftImages"]) : false; 1123 bool hasVideos = bolig.Videos != null && bolig.Videos.Any(); 1124 bool hasSlideShow = bolig.EsoftAssets != null && bolig.EsoftAssets.HasSlideShows; 1125 bool hasBlueprints = bolig.Plantegninger != null && bolig.Plantegninger.Any(); 1126 var panoramas = bolig.EsoftAssets?.PanoramasHtml5? 1127 .Where(x => Converter.ToInt32(x.ListOrder) > 0 && x.EmbedAssets?.Count > 0) 1128 .ToList() ?? new List<Custom.Esoft.Models.EsoftAssetContainer>(); 1129 bool hasPanorama = panoramas.Any(); 1130 1131 string mapLng = GetString("Ecom:Product:Field.xEjendomGeoinfoWGS84Y.Value.Raw").Replace(",", "."); 1132 string mapLat = GetString("Ecom:Product:Field.xEjendomGeoinfoWGS84X.Value.Raw").Replace(",", "."); 1133 bool hasMapCoordinates = !string.IsNullOrEmpty(mapLng) && !string.IsNullOrEmpty(mapLat); 1134 1135 1136 List<Bolig.CaseAsset> images = bolig.ImagesOfProperty != null ? bolig.ImagesOfProperty : new List<Bolig.CaseAsset>(); 1137 1138 @*Make sure we have 3 images to display on frontpage*@ 1139 while (images.Count < 3) 1140 { 1141 images.Add(new Bolig.CaseAsset() { ImageXs = fallbackImage, ImageSm = fallbackImage, ImageMd = fallbackImage, ImageLg = fallbackImage, ImageXl = fallbackImage }); 1142 } 1143 1144 var primaryImage = images.First(); 1145 1146 1147 string primaryVideo = string.Empty; 1148 1149 if (hasVideos) 1150 { 1151 primaryVideo = bolig.Videos.First(); 1152 } 1153 } 1154 1155 <section class="container image-section pt-3 pb-3" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ImageGallery", "Billedegalleri"))"> 1156 1157 <div class="image-wrapper position-relative h-100 w-100"> 1158 <div class="main-image position-relative"> 1159 @if (!string.IsNullOrEmpty(primaryVideo)) 1160 { 1161 <label for="video" class="cursor-pointer mb-0" data-toggle="modal" data-target="#assets-modal"> 1162 <video class="js-primary-video" width="100%" height="100%" autoplay muted loop playsinline preload="auto" poster="@HtmlEncoder.HtmlAttributeEncode(primaryImage.ImageMd)" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.PropertyVideo", "Ejendomsvideo for")) @HtmlEncoder.HtmlAttributeEncode(GetString("Ecom:Product:Field.xEjendomAdresseAdresseLinie"))"> 1163 <source src="@primaryVideo" type="video/mp4" /> 1164 @Translate("Custom:Accessibility.VideoNotSupported", "Din browser understøtter ikke HTML5 video.") 1165 </video> 1166 </label> 1167 } 1168 else 1169 { 1170 <img class="img-fluid w-100" src="@primaryImage.ImageLg" data-toggle="modal" data-target="#assets-modal" alt="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom.Propertypage.PrimaryImage.AltTag", "Image of realestate"))" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.OpenImageGallery", "Åbn billedegalleri"))" /> 1171 } 1172 </div> 1173 1174 @{ 1175 var imageCount = 0; 1176 int skip = !string.IsNullOrEmpty(primaryVideo) ? 0 : 1; 1177 } 1178 1179 @foreach (var image in images.Skip(skip).Take(2)) 1180 { 1181 <div class="cursor-pointer secondary-image position-relative" data-toggle="modal" data-target="#assets-modal" role="button" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.OpenImageGallery", "Åbn billedegalleri"))" onkeypress="if(event.key === 'Enter' || event.key === ' ') { $(this).click(); }"> 1182 <img class="img-fluid w-100 h-100" src="@image.ImageLg" alt="@Translate("Custom:Accessibility.PropertyImage", "Ejendomsbillede") @(imageCount + 2) @Translate("Custom:Accessibility.Of", "af") @(images.Count() + 1)" /> 1183 @if (imageCount == 1) 1184 { 1185 <button type="button" class="d-block d-lg-none btn btn-modal position-absolute" data-toggle="modal" data-target="#assets-modal" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ViewAllImages", "Vis alle billeder"))"> 1186 @string.Format(Translate("Custom:Propertypage.AssetsModal.Button.Mobile.Open", "+ {0} billeder"), images.Count()) 1187 </button> 1188 1189 <button type="button" class="d-none d-md-block btn btn-modal position-absolute" data-toggle="modal" data-target="#assets-modal" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ViewAllImages", "Vis alle billeder"))"> 1190 <img src="@(iconPath + "icon-images.svg")" alt="" aria-hidden="true" /> 1191 @string.Format(Translate("Custom:Propertypage.AssetsModal.Button.Desktop.Open", "Se alle {0} billeder"), images.Count()) 1192 </button> 1193 } 1194 @if (bolig.AabentHus && imageCount == 0) 1195 { 1196 var upcomingOpenHouses = boligManager.KommendeAabnehuse(bolig); 1197 1198 <div class="open-house position-absolute d-none d-md-flex" onclick="stopPropagation(event)" role="region" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.OpenHouseInfo", "Åbent hus information"))"> 1199 <div class="section-header semi-bold mb-0"> 1200 @Translate("Custom.Propertypage.OpenHouseSection.Header", "Åbent hus") 1201 </div> 1202 <div class="open-house-dates d-flex align-items-center"> 1203 @if (upcomingOpenHouses.Count() > 1) 1204 { 1205 <select id="openhouse-selector-desktop" class="open-house-selector js-aabenthus-liste-val" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.SelectOpenHouse", "Vælg åbent hus tidspunkt"))"> 1206 @foreach (var openHouse in upcomingOpenHouses) 1207 { 1208 var json = System.Text.Json.JsonSerializer.Serialize(openHouse); 1209 1210 <option class="open-house-selector__option" data-aabent-hus="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(json)"> 1211 @openHouse.Dato.ToString("d. MMM", Pageview.Area.CultureInfo) kl. @openHouse.FraKlokken.Substring(0, 5) 1212 </option> 1213 } 1214 </select> 1215 } 1216 else 1217 { 1218 var primaryOpenHouse = upcomingOpenHouses.First(); 1219 var json = System.Text.Json.JsonSerializer.Serialize(primaryOpenHouse); 1220 1221 <div class="open-house-text"> 1222 <span class="js-aabenthus-date-val">@primaryOpenHouse.Dato.ToString("d. MMM", Pageview.Area.CultureInfo)</span> 1223 1224 @if (!string.IsNullOrEmpty(primaryOpenHouse.TidspunktFormateret)) 1225 { 1226 <div class="d-inline-block js-aabenthus-time-val js-primary-open-house" data-aabent-hus="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(json)"> 1227 @Translate("Custom.Propertypage.OpenHouseSection.Kl", "kl.") @primaryOpenHouse.FraKlokken.Substring(0, 5)@(" - ")@primaryOpenHouse.TilKlokken.Substring(0, 5) 1228 </div> 1229 } 1230 </div> 1231 } 1232 @if (upcomingOpenHouses.Any(oh => oh.Tilmelding)) 1233 { 1234 <a class="btn btn-orange" href="javascript:panelAabenthus('@origin');"> 1235 @Translate("Custom.Propertypage.OpenHouseSection.SignupButton.Label", "Tilmeld") 1236 </a> 1237 } 1238 </div> 1239 </div> 1240 } 1241 @if (popularityMetrics.Any() && imageCount == 0) 1242 { 1243 <div class="popular position-absolute d-none d-md-flex" role="region" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.PopularityMetrics", "Popularitetsmålinger"))"> 1244 <div class="popular-header"> 1245 @Translate("Custom.Propertypage.PopularSection.Header", "Populær") 1246 </div> 1247 <div class="popular-metrics-wrapper js-popular-metrics-wrapper"> 1248 @foreach (var metric in popularityMetrics) 1249 { 1250 1251 <div class="popular-metric d-inline-flex align-items-center"> 1252 <div class="bold">@metric.Value</div> 1253 <div class="popular-metric-label">@Translate($"Custom.Propertypage.PopularSection.{metric.Key}.Label", "har interageret med denne bolig")</div> 1254 </div> 1255 } 1256 </div> 1257 </div> 1258 } 1259 </div> 1260 imageCount++; 1261 } 1262 1263 </div> 1264 <div class="image-wrapper__subtext d-md-block d-none"> 1265 @if (propBroker != null) 1266 { 1267 <div class="broker-card d-none d-md-flex align-items-center" role="complementary" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.BrokerInfo", "Mæglerinformation"))"> 1268 @if (employeeItem != null) 1269 { 1270 string image = Converter.ToString(employeeItem["BilledeUrl"]); 1271 <img src="@image" alt="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.BrokerImage", "Billede af mægler")) @HtmlEncoder.HtmlAttributeEncode(propBroker.Employee.Name))" /> 1272 } 1273 <div class="d-flex flex-column justify-content-around pl-2"> 1274 <div class="bold">@Translate("Custom:Propertypage.Images.Subtext.Broker.Text", "Har du nogle spørgsmål?")</div> 1275 @if (!string.IsNullOrEmpty(propBroker?.Employee?.PhoneMobile) && Converter.ToBoolean(employeeItem["VisMobilNrPaaSager"])) 1276 { 1277 <div class="regular"> 1278 @if (!string.IsNullOrEmpty(propBroker?.Employee?.Name)) 1279 { 1280 @Translate("Custom.Propertypage.Images.Subtext.Broker.CallName", "Ring til") 1281 <span class="pl-1">@propBroker.Employee.Name</span> 1282 } 1283 else 1284 { 1285 @Translate("Custom.Propertypage.Images.Subtext.Broker.Call", "Ring på") 1286 } 1287 <span class="pl-1">@RealMaeglerne.Library.Helper.FormatPhoneNumber(propBroker.Employee.PhoneMobile)</span> 1288 </div> 1289 } 1290 else if (!string.IsNullOrEmpty(propBroker?.Broker?.Telephone)) 1291 { 1292 <div class="regular"> 1293 @if (!string.IsNullOrEmpty(propBroker?.Employee?.Name)) 1294 { 1295 @Translate("Custom.Propertypage.Images.Subtext.Broker.CallName", "Ring til") 1296 <span class="pl-1">@propBroker.Employee.Name</span> 1297 } 1298 else 1299 { 1300 @Translate("Custom.Propertypage.Images.Subtext.Broker.Call", "Ring på") 1301 } 1302 <span class="pl-1">@RealMaeglerne.Library.Helper.FormatPhoneNumber(propBroker.Broker.Telephone)</span> 1303 </div> 1304 } 1305 </div> 1306 </div> 1307 } 1308 </div> 1309 1310 1311 <div class="modal fade images-modal" id="images-modal" tabindex="-1" aria-labelledby="images-modal-label" aria-hidden="true" aria-modal="true"> 1312 <div class="modal-dialog"> 1313 <div class="modal-content"> 1314 <div class="position-absolute d-flex flex-column images-navigation"> 1315 <button type="button" class="close-round mb-5" data-dismiss="modal" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.CloseModal", "Luk vindue"))"> 1316 <img src="@(iconPath + "icon-minimize.svg")" alt="" aria-hidden="true" /> 1317 </button> 1318 <div class="d-flex flex-column"> 1319 <button id="image-prev-images-modal" type="button" class="close-round mb-2" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.PreviousImage", "Forrige billede"))"> 1320 <img src="@(iconPath + "icon-arrow-narrow-up.svg")" alt="" aria-hidden="true" /> 1321 </button> 1322 <button id="image-next-images-modal" type="button" class="close-round" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.NextImage", "Næste billede"))"> 1323 <img src="@(iconPath + "icon-arrow-narrow-down.svg")" alt="" aria-hidden="true" /> 1324 </button> 1325 </div> 1326 </div> 1327 <div class="image-gallery large-images"> 1328 @{ 1329 int largeImageCounter = 0; 1330 } 1331 1332 @foreach (var image in images) 1333 { 1334 var largeImageId = "image_large_" + largeImageCounter; 1335 <img id="@largeImageId" class="img-fluid" src="@fallbackImage" data-src="@image.ImageXl" /> 1336 largeImageCounter++; 1337 } 1338 </div> 1339 </div> 1340 </div> 1341 </div> 1342 1343 <div class="modal fade" id="assets-modal" tabindex="-1" aria-labelledby="assets-modal-label" aria-hidden="true" aria-modal="true" role="dialog"> 1344 <div class="modal-dialog"> 1345 <div class="modal-content h-100 mh-100"> 1346 1347 @if (hasVideos || hasSlideShow) 1348 { 1349 <input type="radio" id="video" name="category" class="category-radio" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.SelectVideoCategory", "Vælg video kategori"))"> 1350 } 1351 1352 <input type="radio" id="images" name="category" class="category-radio" checked aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.SelectImagesCategory", "Vælg billeder kategori"))"> 1353 1354 @if (hasBlueprints) 1355 { 1356 <input type="radio" id="blueprint" name="category" class="category-radio" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.SelectBlueprintCategory", "Vælg plantegning kategori"))"> 1357 } 1358 1359 @if (hasMapCoordinates) 1360 { 1361 <input type="radio" id="mapradio" name="category" class="category-radio" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.SelectMapCategory", "Vælg kort kategori"))"> 1362 } 1363 1364 @if (hasPanorama) 1365 { 1366 <input type="radio" id="view360" name="category" class="category-radio" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.Select360Category", "Vælg 360 graders visning kategori"))"> 1367 } 1368 1369 <div class="modal-header"> 1370 1371 <div class="nav-wrapper"> 1372 <div class="category-scroll"> 1373 <div class="category-buttons"> 1374 @if (hasVideos || hasSlideShow) 1375 { 1376 <label for="video" class="category-btn" tabindex="0" role="button" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ShowVideoContent", "Vis video indhold"))" onkeypress="if(event.key === 'Enter' || event.key === ' ') { document.getElementById('video').click(); }"> 1377 <span class="category-icon icon-video" aria-hidden="true"></span> 1378 <span>@Translate("Custom.Propertypage.AssetsModal.Category.Video", "Video")</span> 1379 </label> 1380 } 1381 1382 <label for="images" class="category-btn" tabindex="0" role="button" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ShowImagesContent", "Vis billeder"))" onkeypress="if (event.key === 'Enter' || event.key === ' ') { document.getElementById('images').click(); }"> 1383 <span class="category-icon icon-image" aria-hidden="true"></span> 1384 <span>@Translate("Custom.Propertypage.AssetsModal.Category.Images", "Billeder")</span> 1385 </label> 1386 1387 @if (hasBlueprints) 1388 { 1389 <label for="blueprint" class="category-btn" tabindex="0" role="button" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ShowBlueprintContent", "Vis plantegning"))" onkeypress="if(event.key === 'Enter' || event.key === ' ') { document.getElementById('blueprint').click(); }"> 1390 <span class="category-icon icon-plan" aria-hidden="true"></span> 1391 <span>@Translate("Custom.Propertypage.AssetsModal.Category.Plan", "Plantegning")</span> 1392 </label> 1393 } 1394 1395 @if (hasMapCoordinates) 1396 { 1397 <label for="mapradio" class="js-init-map category-btn" tabindex="0" role="button" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ShowMapContent", "Vis kort"))" onkeypress="if(event.key === 'Enter' || event.key === ' ') { document.getElementById('mapradio').click(); }"> 1398 <span class="category-icon icon-map" aria-hidden="true"></span> 1399 <span>@Translate("Custom.Propertypage.AssetsModal.Category.Map", "Vis på kort")</span> 1400 </label> 1401 } 1402 1403 @if (hasPanorama) 1404 { 1405 <label for="view360" class="category-btn" tabindex="0" role="button" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.Show360Content", "Vis 360 graders visning"))" onkeypress="if(event.key === 'Enter' || event.key === ' ') { document.getElementById('view360').click(); }"> 1406 <span class="category-icon icon-360" aria-hidden="true"></span> 1407 <span>@Translate("Custom.Propertypage.AssetsModal.Category.Panorama", "360°")</span> 1408 </label> 1409 } 1410 </div> 1411 @if (!bolig.Solgt && !bolig.PurchaseAgreementSigned) { 1412 <div class="d-none d-md-block"> 1413 <a class="btn btn-orange" href="javascript:panelFremvisning('@origin');" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.BookViewing", "Bestil fremvisning"))">@Translate("Custom.Propertypage.AssetsModal.Header.Showing.ButtonLabel", "Bestil fremvisning")</a> 1414 </div> 1415 } 1416 </div> 1417 </div> 1418 <button type="button" class="close" data-dismiss="modal" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.CloseAssetModal", "Luk medie vindue"))"> 1419 @*Mobile*@ 1420 <div class="d-md-none d-block" aria-hidden="true"> 1421 <img src="@(iconPath + "icon-modal-close.svg")" alt="" aria-hidden="true" /> 1422 </div> 1423 <div class="d-md-none d-block pb-2" aria-hidden="true">@Translate("Custom:Propertypage.AssetsModal.Button.Close.Mobile", "Luk")</div> 1424 @*Desktop*@ 1425 <div class="d-none d-md-block pb-2" aria-hidden="true">@Translate("Custom:Propertypage.AssetsModal.Button.Close.Desktop", "Luk vindue")</div> 1426 <div class="d-none d-md-block" aria-hidden="true"> 1427 <img src="@(iconPath + "icon-modal-close-small.svg")" alt="" aria-hidden="true" /> 1428 </div> 1429 </button> 1430 </div> 1431 <div class="modal-body"> 1432 <!-- Video Content --> 1433 @if (hasVideos || hasSlideShow) 1434 { 1435 <div class="content-section video-content"> 1436 <div class="image-gallery" tabindex="-1"> 1437 @if (hasVideos) 1438 { 1439 @foreach (var video in bolig.Videos) 1440 { 1441 <video height="100%" controls="controls" muted loop preload="auto"> 1442 <source src="@video" type="video/mp4" /> 1443 Your browser does not support HTML5 video. 1444 </video> 1445 } 1446 } 1447 @if (hasSlideShow) 1448 { 1449 @foreach (var slide in bolig.EsoftAssets.ActiveSlideShows) 1450 { 1451 <div class="slide-show">@slide.EmbedAssets[0].EmbedCode.Replace("http://", "https://")</div> 1452 } 1453 } 1454 </div> 1455 </div> 1456 } 1457 1458 <!-- Billeder (Images) Content --> 1459 <div class="content-section images-content"> 1460 <div class="image-gallery" tabindex="-1"> 1461 @{ 1462 int imageCounter = 0; 1463 } 1464 1465 @foreach (var image in images) 1466 { 1467 var imageId = "image_" + imageCounter; 1468 <img id="@imageId" class="img-fluid" src="@fallbackImage" data-src="@image.ImageLg" /> 1469 imageCounter++; 1470 } 1471 </div> 1472 <div class="d-md-flex d-none flex-column"> 1473 <button type="button" class="btn btn-modal btn-modal__clean" data-toggle="modal" data-target="#images-modal" onclick="initImageNavigation('.images-modal', { imageSelector: '.large-images img', buttonIdPostFix: '-images-modal' })"> 1474 <div class="pb-2" aria-hidden="true">@Translate("Custom:Propertypage.AssetsModal.Button.LargeImages", "Vis som store billeder")</div> 1475 <div aria-hidden="true"> 1476 <img src="@(iconPath + "icon-expand.svg")" alt="" aria-hidden="true" /> 1477 </div> 1478 </button> 1479 <div class="image-thumbnails js-image-thumbnails"> 1480 @{ 1481 int imageThumbnailCounter = 0; 1482 } 1483 1484 @foreach (var image in images) 1485 { 1486 var imageId = "image_" + imageThumbnailCounter; 1487 <label class="thumbnail-radio js-thumbnail-radio" 1488 tabindex="0" 1489 role="button" 1490 aria-label="@Translate("Custom:Accessibility.ThumbnailImage", "Billede") @(imageThumbnailCounter + 1)" 1491 data-index="@imageThumbnailCounter" 1492 onclick="scrollGalleryToImage('@imageId');"> 1493 <input type="radio" id="@(imageId)_thumbnail" name="thumbnailradio" class="d-none" checked="@(imageThumbnailCounter == 0)" /> 1494 <img class="img-fluid" src="@fallbackImage" data-src="@image.ImageSm" alt="" /> 1495 </label> 1496 1497 imageThumbnailCounter++; 1498 } 1499 </div> 1500 </div> 1501 </div> 1502 1503 <!-- Plantegning (Floor Plan) Content --> 1504 @if (hasBlueprints) 1505 { 1506 <div class="content-section blueprint-content"> 1507 <div class="image-gallery" tabindex="-1"> 1508 @foreach (var plan in bolig.Plantegninger) 1509 { 1510 <img class="img-fluid" src="@fallbackImage" data-src="@plan.ImageXl" /> 1511 } 1512 </div> 1513 </div> 1514 } 1515 1516 <!-- Kort (Map) Content --> 1517 @if (hasMapCoordinates) 1518 { 1519 var mapFeedPageId = Converter.ToString(GetPageIdByNavigationTag("MapFeed")); 1520 string mapMarkerUrl = "Files/Templates/Designs/rm/assets/images/map-pin-real-maeglerne.svg"; 1521 int mapMarkerHeight = 32; 1522 int mapMarkerWidth = 32; 1523 1524 <div class="content-section map-content"> 1525 <div class="image-gallery" tabindex="-1"> 1526 <div class="map js-map" data-map-feed="@mapFeedPageId"> 1527 <div class="renderMap" id="map"></div> 1528 </div> 1529 </div> 1530 </div> 1531 1532 <input type="hidden" class="js-hasmapcoordinates" value="true" /> 1533 <input type="hidden" class="js-mapLng" value="@mapLng" /> 1534 <input type="hidden" class="js-mapLat" value="@mapLat" /> 1535 <input type="hidden" class="js-mapMarkerWidth" value="@mapMarkerWidth" /> 1536 <input type="hidden" class="js-mapMarkerHeight" value="@mapMarkerHeight" /> 1537 <input type="hidden" class="js-mapMarkerUrl" value="@mapMarkerUrl" /> 1538 1539 <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.4/dist/leaflet.css" integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA==" crossorigin="" /> 1540 <script src="https://unpkg.com/leaflet@1.3.4/dist/leaflet.js" integrity="sha512-nMMmRyTVoLYqjP9hrbed9S+FzjZHW5gY1TWCHA5ckwXZBadntCNs8kEqAWdrb9O7rxbCaA4lKTIWjDXZxflOcA==" crossorigin=""> 1541 </script> 1542 1543 } 1544 1545 <!-- 360 View Content --> 1546 @if (hasPanorama) 1547 { 1548 <div class="content-section view360-content"> 1549 <div class="image-gallery" tabindex="-1"> 1550 @{ 1551 string largeThumbnail = string.Empty; 1552 1553 foreach (var thumbnail in panoramas.First().Assets) 1554 { 1555 if (thumbnail.Width == "1920") 1556 { 1557 largeThumbnail = thumbnail.SecureUrl; 1558 } 1559 } 1560 <div class="panorama"> 1561 <div class="renderMap position-relative"> 1562 <img class="panorama-thumbnail" src="@largeThumbnail" /> 1563 <div class="js-clickme clickme"> 1564 <img src="@(iconPath + "icon-360.svg")" /> 1565 <span>@Translate("Custom.Propertypage.AssetsModal.ShowPanorama", "Vis 360°")</span> 1566 </div> 1567 <span class="js-panorama-encoded" style="display:none">@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlEncode(panoramas.First().EmbedAssets[0].EmbedCode.Replace("http://", "https://"))</span> 1568 </div> 1569 </div> 1570 } 1571 </div> 1572 </div> 1573 } 1574 </div> 1575 </div> 1576 </div> 1577 </div> 1578 </section> 1579 </div> 1580 1581 <div propertypage-anchor> 1582 @*SECTION: Subpage Navigation*@ 1583 @{ 1584 bool homePresentationOn = Converter.ToBoolean(GetString("Ecom:Product:Field.SpHomePresentationOn")); 1585 bool inspiireON = Converter.ToBoolean(GetString("Ecom:Product:Field.SPInspiireON")); 1586 } 1587 <section class="container subpage-navigation pb-0" role="navigation" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.PropertyNavigation", "Ejendomsnavigation"))"> 1588 <div class="subpage-links"> 1589 @if (hasVideos || hasSlideShow) 1590 { 1591 <label for="video" role="button" class="subpage-link cursor-pointer d-none d-md-flex order-md-0 order-8" data-toggle="modal" data-target="#assets-modal" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ViewVideo", "Se video"))" onkeypress="if(event.key === 'Enter' || event.key === ' ') { $(this).click(); }"> 1592 <img src="@(iconPath + "icon-video.svg")" alt="" aria-hidden="true" /> 1593 <span>@Translate("Custom.Propertypage.SubpageLink.Video", "Video")</span> 1594 </label> 1595 } 1596 1597 @if (images.Any()) 1598 { 1599 <label for="images" role="button" class="subpage-link cursor-pointer d-none d-md-flex order-md-1 order-9" data-toggle="modal" data-target="#assets-modal" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ViewImages", "Se billeder"))" onkeypress="if(event.key === 'Enter' || event.key === ' ') { $(this).click(); }"> 1600 <img src="@(iconPath + "icon-images.svg")" alt="" aria-hidden="true" /> 1601 <span>@Translate("Custom.Propertypage.SubpageLink.Images", "Billeder")</span> 1602 </label> 1603 } 1604 1605 <a class="subpage-link d-flex d-md-none order-2 order-md-2" onclick="scrollToElementById('information-section')" role="button" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ViewPropertyFacts", "Se boligfakta"))" onkeypress="if(event.key === 'Enter' || event.key === ' ') scrollToElementById('information-section')"> 1606 <img src="@(iconPath + "icon-house.svg")" alt="" aria-hidden="true" /> 1607 <span>@Translate("Custom.Propertypage.SubpageLink.Information", "Boligfakta")</span> 1608 </a> 1609 1610 @if (hasBlueprints) 1611 { 1612 <label for="blueprint" role="button" class="subpage-link cursor-pointer order-md-3 order-0" data-toggle="modal" data-target="#assets-modal" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ViewBlueprint", "Se plantegning"))" onkeypress="if(event.key === 'Enter' || event.key === ' ') { $(this).click(); }"> 1613 <img src="@(iconPath + "icon-blueprint.svg")" alt="" aria-hidden="true" /> 1614 <span>@Translate("Custom.Propertypage.SubpageLink.Blueprint", "Plantegning")</span> 1615 </label> 1616 } 1617 1618 @if (hasMapCoordinates) 1619 { 1620 <label for="mapradio" role="button" class="subpage-link cursor-pointer js-init-map order-1 order-md-4" data-toggle="modal" data-target="#assets-modal" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ViewMap", "Se kort"))" onkeypress="if(event.key === 'Enter' || event.key === ' ') { $(this).click(); }"> 1621 <img src="@(iconPath + "icon-map.svg")" alt="" aria-hidden="true" /> 1622 <span>@Translate("Custom.Propertypage.SubpageLink.Map", "Kort")</span> 1623 </label> 1624 } 1625 1626 @if (hasPanorama) 1627 { 1628 <label for="view360" role="button" class="subpage-link cursor-pointer order-3 order-md-5" data-toggle="modal" data-target="#assets-modal" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.View360", "Se 360 graders visning"))" onkeypress="if(event.key === 'Enter' || event.key === ' ') { $(this).click(); }"> 1629 <img src="@(iconPath + "icon-360.svg")" alt="" aria-hidden="true" /> 1630 <span>@Translate("Custom.Propertypage.SubpageLink.360view", "360°")</span> 1631 </label> 1632 } 1633 1634 @if (homePresentationOn) 1635 { 1636 string homePresentationLink = GetString("Ecom:Product:Field.SpHomePresentationLink"); 1637 1638 @if (!string.IsNullOrEmpty(homePresentationLink)) 1639 { 1640 <a class="subpage-link order-4 order-md-6" href="@homePresentationLink" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ViewPresentation", "Se boligpræsentation"))"> 1641 <img src="@(iconPath + "icon-presentation.svg")" alt="" aria-hidden="true" /> 1642 <span>@Translate("Custom.Propertypage.SubpageLink.Presentation", "Boligpræsentation")</span> 1643 </a> 1644 } 1645 } 1646 else if (inspiireON) 1647 { 1648 string inspiireLink = GetString("Ecom:Product:Field.SPInspiireLink"); 1649 1650 @if (!string.IsNullOrEmpty(inspiireLink)) 1651 { 1652 <a class="subpage-link order-4 order-md-6" href="@inspiireLink" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ViewInspiire", "Se Inspiire præsentation"))"> 1653 <img src="@(iconPath + "icon-presentation.svg")" alt="" aria-hidden="true" /> 1654 <span>@Translate("Custom.Propertypage.SubpageLink.Inspiire", "Inspiire")</span> 1655 </a> 1656 } 1657 } 1658 </div> 1659 <div class="broker-card d-none d-md-flex align-items-center" role="complementary" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.BrokerInfo", "Mæglerinformation"))"> 1660 @if (employeeItem != null) 1661 { 1662 string image = Converter.ToString(employeeItem["BilledeUrl"]); 1663 <img src="@image" alt="@Translate("Custom:Accessibility.BrokerImage", "Billede af mægler") @propBroker.Employee.Name" /> 1664 } 1665 <div class="d-flex flex-column justify-content-around"> 1666 @if (!string.IsNullOrEmpty(propBroker?.Employee?.Name)) 1667 { 1668 <div class="bold">@propBroker.Employee.Name</div> 1669 } 1670 else if (!string.IsNullOrEmpty(propBroker?.Broker?.Name)) 1671 { 1672 <div class="bold">@propBroker.Broker.Name</div> 1673 } 1674 @if (!string.IsNullOrEmpty(propBroker?.Employee?.JobTitle)) 1675 { 1676 <div class="regular">@propBroker.Employee.JobTitle</div> 1677 } 1678 else if (!string.IsNullOrEmpty(propBroker?.Broker?.JobTitle)) 1679 { 1680 <div class="regular">@propBroker.Broker.JobTitle</div> 1681 } 1682 @if (!string.IsNullOrEmpty(propBroker?.Employee?.PhoneMobile) && Converter.ToBoolean(employeeItem["VisMobilNrPaaSager"])) 1683 { 1684 <div class="regular">@Translate("Custom.Propertypage.BrokerCard.Call", "Ring på")<span class="pl-1">@RealMaeglerne.Library.Helper.FormatPhoneNumber(propBroker.Employee.PhoneMobile)</span></div> 1685 } 1686 else if (!string.IsNullOrEmpty(propBroker?.Broker?.Telephone)) 1687 { 1688 <div class="regular">@Translate("Custom.Propertypage.BrokerCard.Call", "Ring på")<span class="pl-1">@RealMaeglerne.Library.Helper.FormatPhoneNumber(propBroker.Broker.Telephone)</span></div> 1689 } 1690 </div> 1691 <div class="divider-blue__vertical mx-4" aria-hidden="true"></div> 1692 <div class="broker-interactions" aria-hidden="true"> 1693 <a class="btn btn-blue" aia-hidden="true" href="javascript:panelSalgsvurdering('@origin');">@Translate("Custom.Propertypage.BrokerCard.SalesAssessment.ButtonLabel", "Få vurdering")</a> 1694 @if (!bolig.Solgt && !bolig.PurchaseAgreementSigned) { 1695 <a class="btn btn-orange" aria-hidden="true" href="javascript:panelFremvisning('@origin');">@Translate("Custom.Propertypage.AssetsModal.Header.Showing.ButtonLabel", "Bestil fremvisning")</a> 1696 } 1697 </div> 1698 </div> 1699 @*SECTION: Open house/Popular section*@ 1700 @if (bolig.AabentHus || popularityMetrics.Any()) 1701 { 1702 <section class="container open-house-popular-section p-0 pt-3 d-block d-md-none"> 1703 <div class="open-house-popular-wrapper"> 1704 @if (bolig.AabentHus) 1705 { 1706 var upcomingOpenHouses = boligManager.KommendeAabnehuse(bolig); 1707 1708 <div class="open-house w-50 @(!popularityMetrics.Any() ? "w-100" : "")"> 1709 <h2 class="section-header section-header-md semi-bold mb-0"> 1710 @Translate("Custom.Propertypage.OpenHouseSection.Header", "Åbent hus") 1711 </h2> 1712 <div class="open-house-dates"> 1713 @if (upcomingOpenHouses.Count() > 1) 1714 { 1715 <select id="openhouse-selector-mobile" class="open-house-selector js-aabenthus-liste-val"> 1716 @foreach (var openHouse in upcomingOpenHouses) 1717 { 1718 var json = System.Text.Json.JsonSerializer.Serialize(openHouse); 1719 1720 <option class="open-house-selector__option" data-aabent-hus="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(json)"> 1721 @openHouse.Dato.ToString("d. MMM", Pageview.Area.CultureInfo) kl. @openHouse.FraKlokken.Substring(0, 5) 1722 </option> 1723 } 1724 </select> 1725 } 1726 else 1727 { 1728 var primaryOpenHouse = upcomingOpenHouses.First(); 1729 var json = System.Text.Json.JsonSerializer.Serialize(primaryOpenHouse); 1730 1731 <div class="open-house-text"> 1732 <span class="js-aabenthus-date-val">@primaryOpenHouse.Dato.ToString("d. MMM", Pageview.Area.CultureInfo)</span> 1733 1734 @if (!string.IsNullOrEmpty(primaryOpenHouse.TidspunktFormateret)) 1735 { 1736 <div class="d-inline-block js-aabenthus-time-val js-primary-open-house" data-aabent-hus="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(json)"> 1737 @Translate("Custom.Propertypage.OpenHouseSection.Kl", "kl.") @primaryOpenHouse.FraKlokken.Substring(0, 5)@(" - ")@primaryOpenHouse.TilKlokken.Substring(0, 5) 1738 </div> 1739 } 1740 </div> 1741 } 1742 </div> 1743 @if (upcomingOpenHouses.Any(oh => oh.Tilmelding)) 1744 { 1745 <a class="btn btn-orange" href="javascript:panelAabenthus('@origin');" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.SignUpOpenHouse", "Tilmeld til åbent hus"))"> 1746 @Translate("Custom.Propertypage.OpenHouseSection.SignupButton.Label", "Tilmeld") 1747 </a> 1748 } 1749 </div> 1750 } 1751 @if (popularityMetrics.Any()) 1752 { 1753 <div class="popular w-50 @(!bolig.AabentHus ? "w-100" : "")"> 1754 <div class="section-header section-header-md semi-bold mb-0"> 1755 @Translate("Custom.Propertypage.PopularSection.Header", "Populær") 1756 </div> 1757 <div class="divider-orange ml-auto mr-auto"></div> 1758 <div class="popular-metrics-wrapper"> 1759 @foreach (var metric in popularityMetrics) 1760 { 1761 <div class="popular-metric d-flex flex-column align-items-center justify-content-between"> 1762 <div class="bold">@metric.Value</div> 1763 <div>@Translate($"Custom.Propertypage.PopularSection.{metric.Key}.Label", "har interageret med denne bolig")</div> 1764 </div> 1765 } 1766 </div> 1767 </div> 1768 } 1769 </div> 1770 </section> 1771 } 1772 1773 @*SECTION: ADDRESS SECTION*@ 1774 <section id="address-section" class="container address-section p-0 pt-3 pb-3" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.AddressSection", "Adresse og pris information"))"> 1775 <div class="address-wrapper"> 1776 <h2 class="address-header d-flex align-items-center justify-content-between w-100 order-0"> 1777 <div class="d-flex flex-column"> 1778 <div class="js-aabenthus-address-val">@GetString("Ecom:Product:Field.xEjendomAdresseAdresseLinie")</div> 1779 <div class="js-aabenthus-zip-city-val">@GetString("Ecom:Product:Field.xEjendomAdressePostAdresseLinie")</div> 1780 </div> 1781 @{ 1782 var (cssColor, translationKey, defaultText) = bolig switch 1783 { 1784 { Solgt: true, UdbudsForm: "Leje" } => ("red", "Custom.Propertypage.Leased", "Udlejet"), 1785 { Solgt: true } => ("red", "Custom.Propertypage.Sold", "Solgt"), 1786 { PurchaseAgreementSigned: true } => ("blue", "Custom.Propertypage.PurchaseAgreementSigned", "Købsaftale underskrevet"), 1787 { Nyhed: true } => ("orange", "Custom.Propertypage.New", "Nyhed"), 1788 { NyPris: true } => ("orange", "Custom.Propertypage.NewPrice", "Ny pris"), 1789 _ => (null, null, null) 1790 }; 1791 1792 if (translationKey != null) 1793 { 1794 <div class="label" role="status" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.PropertyStatus", "Ejendomsstatus"))"><div class="label-icon @cssColor" aria-hidden="true"></div>@Translate(translationKey, defaultText)</div> 1795 } 1796 } 1797 </h2> 1798 <div class="divider-orange d-none d-md-block" aria-hidden="true"></div> 1799 <div class="address-price d-none d-md-flex flex-column w-100"> 1800 @if (bolig.Solgt || bolig.PurchaseAgreementSigned) 1801 { 1802 //Do Nothing 1803 } 1804 else 1805 { 1806 @if (isRental) 1807 { 1808 <div class="d-flex align-items-center justify-content-between"> 1809 <div>@Translate("Custom.Propertypage.Financing.RentPerMonth", "Leje pr. måned")</div> 1810 <div>@FormatPrice(GetInteger("Ecom:Product:Field.xEjendomBoligUdlejningLejeMaaned.Value.Clean"))</div> 1811 </div> 1812 1813 int usagePerMonth = GetInteger("Ecom:Product:Field.xEjendomBoligUdlejningAcVarmeMaaned.Value.Clean") + GetInteger("Ecom:Product:Field.xEjendomBoligUdlejningAcVandMaaned.Value.Clean") + GetInteger("Ecom:Product:Field.xEjendomBoligUdlejningAcontoForbrugFri01Beloeb.Value.Clean"); 1814 1815 if (usagePerMonth > 0) 1816 { 1817 <div class="d-flex align-items-center justify-content-between address-price-small"> 1818 <div>@Translate("Custom.Propertypage.Financing.UsagePerMonth", "Forbrugsudgift pr. md.")</div> 1819 <div>@FormatPrice(usagePerMonth)</div> 1820 </div> 1821 } 1822 } 1823 else 1824 { 1825 <div class="d-flex align-items-center justify-content-between"> 1826 @if (propCategory == "Andelsbolig") 1827 { 1828 <div>@Translate("Custom.Propertypage.Financing.Table.Deposit", "Indskud")</div> 1829 } 1830 else 1831 { 1832 <div>@Translate("Custom.Propertypage.Financing.Table.Price", "Kontantpris")</div> 1833 } 1834 <div>@FormatPrice(GetInteger("Ecom:Product.DBPrice"))</div> 1835 </div> 1836 <div class="d-flex align-items-center justify-content-between address-price-small"> 1837 <div>@Translate("Custom.Propertypage.Financing.Table.OwnerCost", "Ejerudgift")</div> 1838 <div>@FormatPrice(GetInteger("Ecom:Product:Field.xEjendomEjerudgifterMaanedSum"))</div> 1839 </div> 1840 } 1841 } 1842 </div> 1843 <div class="address-info d-flex flex-wrap d-md-none align-items-center order-1"> 1844 @if (!string.IsNullOrEmpty(propTypeDisplay)) 1845 { 1846 <div class="address-info-item"> 1847 @propTypeDisplay 1848 </div> 1849 } 1850 @if (GetInteger("Ecom:Product:Field.xEjendomArealerBoligAreal") > 0) 1851 { 1852 <div class="address-info-item"> 1853 @GetString("Ecom:Product:Field.xEjendomArealerBoligAreal") @Translate("Custom.Propertypage.Units.SquareMeters", "m²") 1854 </div> 1855 } 1856 @if (bolig.Solgt || bolig.PurchaseAgreementSigned) 1857 { 1858 //Do Nothing 1859 } 1860 else 1861 { 1862 <div class="address-info-item"> 1863 @if (isRental) 1864 { 1865 @GetInteger("Ecom:Product:Field.xEjendomBoligUdlejningLejeMaaned.Value.Clean").ToString("#,##0") @Translate("Custom.Propertypage.RentPerMonth", "pr. md.") 1866 } 1867 else 1868 { 1869 @FormatPrice(GetInteger("Ecom:Product.DBPrice"), true) 1870 } 1871 </div> 1872 } 1873 @if (!string.IsNullOrEmpty(GetString("Ecom:Product:Field.xEjendomEnergiklassifikation")) || !isRental) 1874 { 1875 <div class="address-info-item d-flex align-items-center"> 1876 1877 @{ 1878 var scenarioNumber = GetString("Ecom:Product:Field.EnergyLabelScenarioNumber"); 1879 var savings = GetInteger("Ecom:Product:Field.EnergyLabelSavings"); 1880 var energyLink = GetString("Ecom:Product:Field.EnergyLabelLink"); 1881 } 1882 1883 <div @(scenarioNumber == "3" ? "id='energi-kontrol-address-mobile'" : "")> 1884 @Translate("Custom.Propertypage.Information.Energy", "Energimærke") 1885 </div> 1886 1887 <div class="energylabel @(scenarioNumber == "2" ? "energy__hover" : "")" 1888 data-energylabel="@HtmlEncoder.HtmlAttributeEncode(GetString("Ecom:Product:Field.xEjendomEnergiklassifikation"))"> 1889 @if (scenarioNumber == "2") 1890 { 1891 <span id="energi-testgruppe-address-mobile" class="tooltiptext"> 1892 @if (savings > 0) 1893 { 1894 @string.Format(Translate("Smartpage:Boligvisning.Energimærketekst1-1", "OBS: du kan spare {0} årligt ved at renovere denne bolig - {1}"), savings.ToString("#,##0"), "") 1895 <a target="_blank" href="@(energyLink)&utm_source=realmaeglerne&utm_medium=energimaerke&utm_campaign=testgruppe1">@Translate("Custom.Propertypage.EnergyLabel.Tooltip.Linktext", "klik her")</a> 1896 } 1897 else 1898 { 1899 @string.Format(Translate("Smartpage:Boligvisning.Energimærketekst1-2", "OBS: du kan energi renovere denne bolig {0}"), "") 1900 <a target="_blank" href="@(energyLink)&utm_source=realmaeglerne&utm_medium=energimaerke&utm_campaign=testgruppe1">@Translate("Custom.Propertypage.EnergyLabel.Tooltip.Linktext", "klik her")</a> 1901 } 1902 </span> 1903 } 1904 </div> 1905 </div> 1906 } 1907 </div> 1908 @if (bolig.BudOenskes) 1909 { 1910 <div class="divider-blue order-2" aria-hidden="true"></div> 1911 <div class="address-offer d-flex align-items-center order-3"> 1912 <div> 1913 @Translate("Custom.Propertypage.Address.Offerlink.label", "Har du et bud i tankerne?") 1914 </div> 1915 <a class="btn-link" onclick="scrollToElementById('offer-section', 'center')" role="button" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.MakeOffer", "Gå til bud sektion"))" onkeypress="if(event.key === 'Enter' || event.key === ' ') scrollToElementById('offer-section', 'center')">@Translate("Custom.Propertypage.Address.Offerlink.linktext", "Giv et bud")</a> 1916 <img height="12px" width="12px" src="@(iconPath + "icon-arrow-narrow-down-white.svg")" alt="" aria-hidden="true" /> 1917 </div> 1918 <div class="divider-blue order-4" aria-hidden="true"></div> 1919 } 1920 1921 @if (bolig.Solgt || bolig.PurchaseAgreementSigned) 1922 { 1923 <div class="w-100 btn btn-light order-5 cursor-default"> 1924 @Translate(translationKey, defaultText) 1925 </div> 1926 } 1927 else 1928 { 1929 <a class="btn btn-orange w-100 order-6" href="javascript:panelFremvisning('@origin');" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.BookViewing", "Bestil fremvisning"))"> 1930 @Translate("Custom.Propertypage.AssetsModal.Header.Showing.ButtonLabel", "Bestil fremvisning") 1931 </a> 1932 1933 <div class="d-flex align-items-center justify-content-between flex-wrap order-7"> 1934 @if (edhFiles.Any() && !bolig.Solgt && !bolig.PurchaseAgreementSigned) 1935 { 1936 <a class="btn btn-link text-left d-flex align-items-center" href="javascript:panelSalgsopstilling('@origin');" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.DownloadDocuments", "Hent salgsdokumenter"))">@Translate("form-salgsopstilling-downloadbtn", "Hent salgsdokumenter") <img class="pl-1" src="@(iconPath + "icon-download-white.svg")" alt="" aria-hidden="true" /></a> 1937 } 1938 1939 <a class="btn btn-link text-left d-flex align-items-center" onclick="scrollToElementById('finance-section', 'center')" role="button" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ViewFinance", "Se økonomi og lån"))" onkeypress="if(event.key === 'Enter' || event.key === ' ') scrollToElementById('finance-section', 'center')">@Translate("Custom.Propertypage.Address.Financelink.linktext", "Økonomi & lån")<img height="12px" width="12px" src="@(iconPath + "icon-arrow-narrow-down-white.svg")" alt="" aria-hidden="true" /></a> 1940 </div> 1941 } 1942 </div> 1943 <div class="address-info d-none d-md-flex"> 1944 @if (!string.IsNullOrEmpty(propTypeDisplay)) 1945 { 1946 <div class="address-info-item d-flex align-items-center justify-content-between"> 1947 <div> 1948 @Translate("Custom.Propertypage.Address.PropertyType", "Type") 1949 </div> 1950 <div> 1951 @propTypeDisplay 1952 </div> 1953 </div> 1954 } 1955 @if (GetInteger("Ecom:Product:Field.xEjendomArealerBoligAreal") > 0) 1956 { 1957 <div class="address-info-item d-flex align-items-center justify-content-between"> 1958 <div> 1959 @Translate("Custom.Propertypage.Address.PropertyArea", "Boligareal") 1960 </div> 1961 <div> 1962 @GetString("Ecom:Product:Field.xEjendomArealerBoligAreal") @Translate("Custom.Propertypage.Units.SquareMeters", "m²") 1963 </div> 1964 </div> 1965 } 1966 @if (GetInteger("Ecom:Product:Field.xEjendomArealerVaerelser") != 0) 1967 { 1968 <div class="address-info-item d-md-flex justify-content-between"> 1969 <div>@Translate("Custom.Propertypage.Address.Rooms", "Rum")</div> 1970 <div>@GetString("Ecom:Product:Field.xEjendomArealerVaerelser")</div> 1971 </div> 1972 } 1973 @if (!string.IsNullOrEmpty(GetString("Ecom:Product:Field.xEjendomEnergiklassifikation")) || !isRental) 1974 { 1975 <div class="address-info-item d-flex justify-content-between align-items-center"> 1976 @{ 1977 var scenarioNumber = GetString("Ecom:Product:Field.EnergyLabelScenarioNumber"); 1978 var savings = GetInteger("Ecom:Product:Field.EnergyLabelSavings"); 1979 var energyLink = GetString("Ecom:Product:Field.EnergyLabelLink"); 1980 } 1981 1982 <div @(scenarioNumber == "3" ? "id='energi-kontrol-address-desktop'" : "") class="d-flex flex-column"> 1983 @Translate("Custom.Propertypage.Information.Energy", "Energimærke") 1984 @if (bolig.ShowClimateCalculator) 1985 { 1986 <a class="btn-link cursor-pointer" onclick="scrollToElementById('climate-calculator-section', 'center')" role="button" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ViewClimateCalcultor", "Prøv klimaberegner og spar penge"))" onkeypress="if(event.key === 'Enter' || event.key === ' ') scrollToElementById('climate-calculator-section', 'center')">@Translate("Custom.Propertypage.Address.ClimateLink.linktext", "Prøv klimaberegner og spar penge")</a> 1987 } 1988 </div> 1989 1990 <div class="energylabel @(scenarioNumber == "2" ? "energy__hover" : "")" 1991 data-energylabel="@HtmlEncoder.HtmlAttributeEncode(GetString("Ecom:Product:Field.xEjendomEnergiklassifikation"))"> 1992 @if (scenarioNumber == "2") 1993 { 1994 <span id="energi-testgruppe-address-desktop" class="tooltiptext"> 1995 @if (savings > 0) 1996 { 1997 @string.Format(Translate("Smartpage:Boligvisning.Energimærketekst1-1", "OBS: du kan spare {0} årligt ved at renovere denne bolig - {1}"), savings.ToString("#,##0"), "") 1998 <a target="_blank" href="@(energyLink)&utm_source=realmaeglerne&utm_medium=energimaerke&utm_campaign=testgruppe1">@Translate("Custom.Propertypage.EnergyLabel.Tooltip.Linktext", "klik her")</a> 1999 } 2000 else 2001 { 2002 @string.Format(Translate("Smartpage:Boligvisning.Energimærketekst1-2", "OBS: du kan energi renovere denne bolig {0}"), "") 2003 <a target="_blank" href="@(energyLink)&utm_source=realmaeglerne&utm_medium=energimaerke&utm_campaign=testgruppe1">@Translate("Custom.Propertypage.EnergyLabel.Tooltip.Linktext", "klik her")</a> 2004 } 2005 </span> 2006 } 2007 </div> 2008 </div> 2009 } 2010 <div class="d-flex align-items-center"> 2011 <a class="btn-link cursor-pointer" onclick="scrollToElementById('information-section', 'center')" role="button" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ViewAllFacts", "Vis alle fakta om boligen"))" onkeypress="if(event.key === 'Enter' || event.key === ' ') scrollToElementById('information-section', 'center')">@Translate("Custom.Propertypage.Address.InfoLink.linktext", "Vis alle fakta om boligen")</a> 2012 <img class="ml-1" height="12px" width="12px" src="@(iconPath + "icon-arrow-narrow-down.svg")" alt="" aria-hidden="true" /> 2013 </div> 2014 </div> 2015 </section> 2016 </section> 2017 </div> 2018 2019 <div propertypage-light> 2020 2021 @*SECTION USPs TODO*@ 2022 @{ 2023 bool hasUSPs = false; 2024 } 2025 @if (hasUSPs) 2026 { 2027 <section class="container usp-section"> 2028 <div class="usps d-flex position-relative"> 2029 <button id="image-prev-usps" type="button" class="prev-button btn-round d-none d-md-flex" aria-label="@HtmlEncoder.HtmlAttributeEncode(@Translate("Custom:Accessiblity.UpsBtn.Previous","Forrige"))"> 2030 </button> 2031 <button id="image-next-usps" type="button" class="next-button btn-round d-none d-md-flex" aria-label="@HtmlEncoder.HtmlAttributeEncode(@Translate("Custom:Accessiblity.UpsBtn.Next","Næste"))"> 2032 </button> 2033 <h2 class="usps-header d-flex flex-column align-items-start justify-content-center"> 2034 <div class="usps-header-number"> 2035 6 2036 </div> 2037 <div class="usps-header-text d-block d-md-none"> 2038 @Translate("Custom.Propertypage.USPSection.Header.Mobile", "gode grunde til at købe") 2039 </div> 2040 <div class="usps-header-text d-none d-md-block"> 2041 @Translate("Custom.Propertypage.USPSection.Header.Desktop", "gode grunde til at købe denne bolig") 2042 </div> 2043 <div class="divider-orange d-none d-md-block"></div> 2044 </h2> 2045 <div class="usps-wrapper d-flex"> 2046 <div class="usps-items d-flex"> 2047 <div class="usp-item d-flex flex-column"> 2048 <div class="circle-orange"> 2049 <img src="@(iconPath + "icon-check-small.svg")" /> 2050 </div> 2051 <div class="usp-text"> 2052 Her får du et trygt fundament for familien med både god plads og et roligt nabolag. 2053 </div> 2054 </div> 2055 <div class="divider-blue__vertical"></div> 2056 <div class="usp-item d-flex flex-column"> 2057 <div class="circle-orange"> 2058 <img src="@(iconPath + "icon-check-small.svg")" /> 2059 </div> 2060 <div class="usp-text"> 2061 Du får en bolig med lavt energiforbrug, hvilket både gavner økonomien og miljøet. Lorem ipsum dolor est. 2062 </div> 2063 </div> 2064 <div class="divider-blue__vertical"></div> 2065 <div class="usp-item d-flex flex-column"> 2066 <div class="circle-orange"> 2067 <img src="@(iconPath + "icon-check-small.svg")" /> 2068 </div> 2069 <div class="usp-text"> 2070 Dette hjem har de detaljer, som mange købere efterspørger – lys og luft. 2071 </div> 2072 </div> 2073 <div class="divider-blue__vertical"></div> 2074 <div class="usp-item d-flex flex-column"> 2075 <div class="circle-orange"> 2076 <img src="@(iconPath + "icon-check-small.svg")" /> 2077 </div> 2078 <div class="usp-text"> 2079 Her får du et trygt fundament for familien med både god plads og et roligt nabolag. 2080 </div> 2081 </div> 2082 <div class="divider-blue__vertical"></div> 2083 <div class="usp-item d-flex flex-column"> 2084 <div class="circle-orange"> 2085 <img src="@(iconPath + "icon-check-small.svg")" /> 2086 </div> 2087 <div class="usp-text"> 2088 Du får en bolig med lavt energiforbrug, hvilket både gavner økonomien og miljøet. Lorem ipsum dolor est. 2089 </div> 2090 </div> 2091 <div class="divider-blue__vertical"></div> 2092 <div class="usp-item d-flex flex-column"> 2093 <div class="circle-orange"> 2094 <img src="@(iconPath + "icon-check-small.svg")" /> 2095 </div> 2096 <div class="usp-text"> 2097 Dette hjem har de detaljer, som mange købere efterspørger – lys og luft. 2098 </div> 2099 </div> 2100 </div> 2101 </div> 2102 </div> 2103 </section> 2104 } 2105 @*SECTION: Description*@ 2106 <section id="description-section" class="container description-section" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.PropertyDescription", "Ejendomsbeskrivelse"))"> 2107 <div class="description js-description"> 2108 @{ 2109 string shortDesc = GetString("Ecom:Product.ShortDescription.Raw"); 2110 string longDesc = GetString("Ecom:Product.LongDescription"); 2111 2112 // Replace uplifted numbers with markup (the characters doesn't exist in the current font) 2113 shortDesc = shortDesc.Replace("²", "<sup>2</sup>").Replace("³", "<sup>3</sup>"); 2114 longDesc = longDesc.Replace("²", "<sup>2</sup>").Replace("³", "<sup>3</sup>"); 2115 } 2116 2117 <h2 class="display-sm semi-bold m-0">@shortDesc</h2> 2118 2119 @if (longDesc.Length > 300) 2120 { 2121 <div class="text-wrapper"> 2122 <div class="text-full @(hasUSPs ? "has-buying-reasons" : "")"> 2123 @longDesc 2124 </div> 2125 <button class="read-more btn--clean" type="button" role="button" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ReadMoreText", "Læs hele beskrivelsen"))" aria-expanded="false">@Translate("product-read-more", "Læs hele teksten")<img src="@(iconPath + "plus.svg")" alt="" aria-hidden="true" /></button> 2126 <button class="read-less d-none" type="button" role="button" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ReadLessText", "Skjul noget af beskrivelsen"))" aria-expanded="true">@Translate("product-read-less", "Læs mindre")<img src="@(iconPath + "minus.svg")" alt="" aria-hidden="true" /></button> 2127 </div> 2128 } 2129 else 2130 { 2131 <div>@longDesc</div> 2132 } 2133 </div> 2134 2135 </section> 2136 @*SECTION: BLueprints*@ 2137 @if (hasBlueprints) 2138 { 2139 <section class="container blueprint-section"> 2140 <div class="blueprints position-relative"> 2141 <h2 class="section-header semi-bold">@Translate("Custom.Propertypage.Blueprints.Header", "Plantegning")</h2> 2142 <div class="divider-orange mb-3 mb-md-5"></div> 2143 <div class="blueprints-wrapper js-blueprints-wrapper"> 2144 @foreach (var blueprint in bolig.Plantegninger) 2145 { 2146 <label for="blueprint" class="blueprint cursor-pointer mb-0" data-toggle="modal" data-target="#assets-modal"> 2147 <img class="blueprint img-fluid" src="@blueprint.ImageLg" /> 2148 </label> 2149 } 2150 </div> 2151 <button id="image-prev-blueprints" type="button" class="prev-button btn-round mb-2 d-none d-md-flex" aria-label="@HtmlEncoder.HtmlAttributeEncode(@Translate("Custom:Accessiblity.BlueprintsBtn.Previous","Forrige"))"> 2152 </button> 2153 <button id="image-next-blueprints" type="button" class="next-button btn-round d-none d-md-flex" aria-label="@HtmlEncoder.HtmlAttributeEncode(@Translate("Custom:Accessiblity.BlueprintsBtn.Next","Næste"))"> 2154 </button> 2155 </div> 2156 </section> 2157 } 2158 2159 @if (hasMapCoordinates) 2160 { 2161 <section class="container map-mobile-section d-md-none d-block js-init-map-onload" data-map-container="map-mobile" data-map-pois="false"> 2162 <h2 class="section-header semi-bold">@Translate("Custom.Propertypage.MobileMap.Header", "Kort")</h2> 2163 <div class="divider-orange mb-3" aria-hidden="true"></div> 2164 <div id="map-mobile" class="map-mobile"> 2165 <button type="button" class="btn btn-link" onclick="fullScreen('map-mobile', this)" data-text-open="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Propertypage.MobileMap.Button.FullScreen", "Fuld skærm"))" data-text-close="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Propertypage.MobileMap.Button.NormalScreen", "Luk"))" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ToggleFullscreen", "Skift til fuldskærm"))" tabindex="0" onkeypress="if(event.key === 'Enter' || event.key === ' ') fullScreen('map-mobile')"> 2166 <div class="js-button-label pb-2">@Translate("Custom:Propertypage.MobileMap.Button.FullScreen", "Fuld skærm")</div> 2167 <div> 2168 <img src="@(iconPath + "icon-expand.svg")" alt="" aria-hidden="true" /> 2169 </div> 2170 </button> 2171 <div class="map h-100 w-100 js-map" data-map-feed="@Converter.ToString(GetPageIdByNavigationTag("MapFeed"))" role="application" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.InteractiveMap", "Interaktivt kort"))"> 2172 <div class="renderMap" id="map-mobile"></div> 2173 </div> 2174 </div> 2175 </section> 2176 } 2177 2178 @*SECTION: Broker mobile*@ 2179 <section class="container broker-mobile d-block d-md-none"> 2180 <div class="broker-card d-flex align-items-center"> 2181 <div class="broker-info"> 2182 @if (employeeItem != null) 2183 { 2184 string image = Converter.ToString(employeeItem["BilledeUrl"]); 2185 <img src="@image" /> 2186 } 2187 <div class="d-flex flex-column justify-content-around"> 2188 @if (!string.IsNullOrEmpty(propBroker?.Employee?.Name)) 2189 { 2190 <div class="bold">@propBroker.Employee.Name</div> 2191 } 2192 else if (!string.IsNullOrEmpty(propBroker?.Broker?.Name)) 2193 { 2194 <div class="bold">@propBroker.Broker.Name</div> 2195 } 2196 @if (!string.IsNullOrEmpty(propBroker?.Employee?.JobTitle)) 2197 { 2198 <div class="regular">@propBroker.Employee.JobTitle</div> 2199 } 2200 else if (!string.IsNullOrEmpty(propBroker?.Broker?.JobTitle)) 2201 { 2202 <div class="regular">@propBroker.Broker.JobTitle</div> 2203 } 2204 </div> 2205 </div> 2206 <div class="broker-interactions"> 2207 @if (!bolig.Solgt && !bolig.PurchaseAgreementSigned) { 2208 <a class="btn btn-orange" href="javascript:panelFremvisning('@origin');">@Translate("Custom.Propertypage.AssetsModal.Header.Showing.ButtonLabel", "Bestil fremvisning")</a> 2209 } 2210 @if (!string.IsNullOrEmpty(propBroker?.Employee?.PhoneMobile) && Converter.ToBoolean(employeeItem["VisMobilNrPaaSager"])) 2211 { 2212 <div class="regular">@Translate("Custom.Propertypage.BrokerCard.Call", "Ring på")<a href="tel:@RealMaeglerne.Library.Helper.FormatPhoneNumber(propBroker.Employee.PhoneMobile)" class="phone-link pl-1">@RealMaeglerne.Library.Helper.FormatPhoneNumber(propBroker.Employee.PhoneMobile)</a></div> 2213 } 2214 else if (!string.IsNullOrEmpty(propBroker?.Broker?.Telephone)) 2215 { 2216 <div class="regular">@Translate("Custom.Propertypage.BrokerCard.Call", "Ring på")<a href="tel:@RealMaeglerne.Library.Helper.FormatPhoneNumber(propBroker.Broker.Telephone)" class="phone-link pl-1">@RealMaeglerne.Library.Helper.FormatPhoneNumber(propBroker.Broker.Telephone)</a></div> 2217 } 2218 </div> 2219 </div> 2220 </section> 2221 2222 @*SECTION: Information*@ 2223 <section id="information-section" class="container information-section" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.PropertyFactsSection", "Fakta om boligen"))"> 2224 @{ 2225 int garageArea = GetInteger("Ecom:Product:Field.xEjendomArealerHovedbygningIntegreredeArealerGarage"); 2226 int carportArea = GetInteger("Ecom:Product:Field.xEjendomArealerHovedbygningIntegreredeArealerCarport.Value"); 2227 bool altan = GetBoolean("Ecom:Product:Field.xEjendomFaciliteterAltan"); 2228 } 2229 <div class="information"> 2230 <h2 class="information-header semi-bold">@Translate("Custom.Propertypage.Information.Header", "Fakta om boligen")</h2> 2231 <div class="d-none d-md-block divider-orange mb-4" aria-hidden="true"></div> 2232 <div class="table-wrapper" role="table" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.PropertyFactsTable", "Boligfakta tabel"))"> 2233 <div class="table-item d-flex justify-content-between" role="row"> 2234 <div role="cell">@Translate("Custom.Propertypage.Information.Case", "Sagsnummer")</div> 2235 <div role="cell" class="js-sagsnr-val" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.CaseNumber", "Sagsnummer")) @productId">@productId</div> 2236 </div> 2237 @if (!string.IsNullOrEmpty(propTypeDisplay)) 2238 { 2239 <div class="table-item d-flex justify-content-between" role="row"> 2240 <div role="cell">@Translate("Custom.Propertypage.Information.PropertyType", "Boligtype")</div> 2241 <div role="cell" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.PropertyType", "Boligtype")) @propTypeDisplay">@propTypeDisplay</div> 2242 </div> 2243 } 2244 @if (GetInteger("Ecom:Product:Field.xEjendomArealerBoligAreal") > 0) 2245 { 2246 <div class="table-item d-flex justify-content-between" role="row"> 2247 <div role="cell">@Translate("Custom.Propertypage.Information.Residentialrea", "Boligareal")</div> 2248 <div role="cell" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ResidentialArea", "Boligareal")) @GetString("Ecom:Product:Field.xEjendomArealerBoligAreal") @HtmlEncoder.HtmlAttributeEncode(Translate("Custom.Propertypage.Units.SquareMeters", "kvadratmeter"))">@GetString("Ecom:Product:Field.xEjendomArealerBoligAreal") @Translate("Custom.Propertypage.Units.SquareMeters", "m²")</div> 2249 </div> 2250 } 2251 @if (GetInteger("Ecom:Product:Field.xEjendomArealerGrundAreal") > 0) 2252 { 2253 <div class="table-item d-flex justify-content-between" role="row"> 2254 <div role="cell">@Translate("Custom.Propertypage.Information.Landarea", "Grundareal")</div> 2255 <div role="cell" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.LandArea", "Grundareal")) @GetString("Ecom:Product:Field.xEjendomArealerGrundAreal") @HtmlEncoder.HtmlAttributeEncode(Translate("Custom.Propertypage.Units.SquareMeters", "kvadratmeter"))">@GetString("Ecom:Product:Field.xEjendomArealerGrundAreal") @Translate("Custom.Propertypage.Units.SquareMeters", "m²")</div> 2256 </div> 2257 } 2258 else if (GetInteger("Ecom:Product:Field.xEjendomArealerGrundArealHA") > 0) 2259 { 2260 <div class="table-item d-flex justify-content-between" role="row"> 2261 <div role="cell">@Translate("Custom.Propertypage.Information.Landarea", "Grundareal")</div> 2262 <div role="cell" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.LandArea", "Grundareal")) @GetString("Ecom:Product:Field.xEjendomArealerGrundArealHA") @HtmlEncoder.HtmlAttributeEncode(Translate("Custom.Propertypage.Units.Acres", "hektar"))">@GetString("Ecom:Product:Field.xEjendomArealerGrundArealHA") @Translate("Custom.Propertypage.Units.Acres", "hektar")</div> 2263 </div> 2264 } 2265 2266 2267 @if (garageArea > 0 || carportArea > 0) 2268 { 2269 if (garageArea > 0 && carportArea > 0) 2270 { 2271 <div class="table-item d-flex justify-content-between"> 2272 <div>@Translate("Custom.Propertypage.Information.GarageCarport", "Garage/Carport")</div> 2273 <div>@garageArea/@carportArea @Translate("Custom.Propertypage.Units.SquareMeters", "m²")</div> 2274 </div> 2275 } 2276 else if (garageArea > 0 && carportArea <= 0) 2277 { 2278 <div class="table-item d-flex justify-content-between"> 2279 <div>@Translate("Custom.Propertypage.Information.Garage", "Garage")</div> 2280 <div>@garageArea @Translate("Custom.Propertypage.Units.SquareMeters", "m²")</div> 2281 </div> 2282 } 2283 else 2284 { 2285 <div class="table-item d-flex justify-content-between"> 2286 <div>@Translate("Custom.Propertypage.Information.Carport", "Carport")</div> 2287 <div>@carportArea @Translate("Custom.Propertypage.Units.SquareMeters", "m²")</div> 2288 </div> 2289 } 2290 } 2291 @if (altan) 2292 { 2293 <div class="table-item d-flex justify-content-between" role="row"> 2294 <div role="cell">@Translate("Custom.Propertypage.Information.Balkony", "Altan")</div> 2295 <div role="cell" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.Balcony", "Altan")) @HtmlEncoder.HtmlAttributeEncode(Translate("Custom.Propertypage.Information.Yes", "Ja"))">@Translate("Custom.Propertypage.Information.Yes", "Ja")</div> 2296 </div> 2297 } 2298 @if (GetInteger("Ecom:Product:Field.xEjendomOpfoertAar") != 0) 2299 { 2300 <div class="table-item d-flex justify-content-between" role="row"> 2301 <div role="cell">@Translate("Custom.Propertypage.Information.BuildRebuild", "Bygget/ombygget")</div> 2302 <div role="cell" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.BuildYear", "Byggeår")) @GetInteger("Ecom:Product:Field.xEjendomOpfoertAar") @(GetInteger("Ecom:Product:Field.xEjendomOmbyggetAar") != 0 ? HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.RebuildYear", "Ombygget")) + " " + GetString("Ecom:Product:Field.xEjendomOmbyggetAar") : "")">@GetInteger("Ecom:Product:Field.xEjendomOpfoertAar") @(GetInteger("Ecom:Product:Field.xEjendomOmbyggetAar") != 0 ? "/ " + GetString("Ecom:Product:Field.xEjendomOmbyggetAar") : "")</div> 2303 </div> 2304 } 2305 @if (GetInteger("Ecom:Product:Field.xEjendomArealerVaerelser") != 0) 2306 { 2307 <div class="table-item d-flex justify-content-between" role="row"> 2308 <div role="cell">@Translate("Custom.Propertypage.Information.Rooms", "Antal rum")</div> 2309 <div role="cell" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.NumberOfRooms", "Antal rum")) @GetString("Ecom:Product:Field.xEjendomArealerVaerelser")">@GetString("Ecom:Product:Field.xEjendomArealerVaerelser")</div> 2310 </div> 2311 } 2312 @if (GetInteger("Ecom:Product:Field.xEjendomArealerEtager") != 0 && (propType != "Ejerlejlighed" && propType != "Andelsbolig")) 2313 { 2314 <div class="table-item d-flex justify-content-between" role="row"> 2315 <div role="cell">@Translate("Custom.Propertypage.Information.Stories", "Etager")</div> 2316 <div role="cell" tabindex="0" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.NumberOfFloors", "Antal etager")) @GetString("Ecom:Product:Field.xEjendomArealerEtager")">@GetString("Ecom:Product:Field.xEjendomArealerEtager")</div> 2317 </div> 2318 } 2319 @if (!string.IsNullOrEmpty(GetString("Ecom:Product:Field.xEjendomEnergiklassifikation"))) 2320 { 2321 <div class="table-item d-flex justify-content-between align-items-center"> 2322 @{ 2323 var scenarioNumber = GetString("Ecom:Product:Field.EnergyLabelScenarioNumber"); 2324 var savings = GetInteger("Ecom:Product:Field.EnergyLabelSavings"); 2325 var energyLink = GetString("Ecom:Product:Field.EnergyLabelLink"); 2326 } 2327 2328 <div @(scenarioNumber == "3" ? "id='energi-kontrol-information'" : "")> 2329 @Translate("Custom.Propertypage.Information.Energy", "Energimærke") 2330 </div> 2331 2332 <div class="energylabel @(scenarioNumber == "2" ? "energy__hover" : "")" 2333 data-energylabel="@HtmlEncoder.HtmlAttributeEncode(GetString("Ecom:Product:Field.xEjendomEnergiklassifikation"))"> 2334 @if (scenarioNumber == "2") 2335 { 2336 <span id="energi-testgruppe-information" class="tooltiptext"> 2337 @if (savings > 0) 2338 { 2339 @string.Format(Translate("Smartpage:Boligvisning.Energimærketekst1-1", "OBS: du kan spare {0} årligt ved at renovere denne bolig - {1}"), savings.ToString("#,##0"), "") 2340 <a target="_blank" href="@(energyLink)&utm_source=realmaeglerne&utm_medium=energimaerke&utm_campaign=testgruppe1">@Translate("Custom.Propertypage.EnergyLabel.Tooltip.Linktext", "klik her")</a> 2341 } 2342 else 2343 { 2344 @string.Format(Translate("Smartpage:Boligvisning.Energimærketekst1-2", "OBS: du kan energi renovere denne bolig {0}"), "") 2345 <a target="_blank" href="@(energyLink)&utm_source=realmaeglerne&utm_medium=energimaerke&utm_campaign=testgruppe1">@Translate("Custom.Propertypage.EnergyLabel.Tooltip.Linktext", "klik her")</a> 2346 } 2347 </span> 2348 } 2349 </div> 2350 </div> 2351 } 2352 </div> 2353 @if (edhFiles.Any() && !bolig.Solgt && !bolig.PurchaseAgreementSigned) 2354 { 2355 <div class="table-item"> 2356 <a class="btn btn-link text-left d-flex align-items-center" href="javascript:panelSalgsopstilling('@origin');" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.DownloadSalesDocuments", "Hent salgsdokumenter"))" tabindex="0">@Translate("form-salgsopstilling-downloadbtn", "Hent salgsdokumenter") <img class="pl-1" src="@(iconPath + "icon-download.svg")" alt="" aria-hidden="true" /></a> 2357 </div> 2358 } 2359 </div> 2360 </section> 2361 @*SECTION: Finance*@ 2362 @if (!bolig.Solgt && !bolig.PurchaseAgreementSigned) 2363 { 2364 string brfQuery = $"price={GetInteger("Ecom:Product.DBPrice")}"; 2365 2366 if (propCategory != null) 2367 { 2368 if (propCategory.Contains("Ejerlejlighed", StringComparison.InvariantCultureIgnoreCase)) 2369 { 2370 brfQuery += "&housingType=ejerlejlighed"; 2371 } 2372 else if (propCategory.Contains("Villa", StringComparison.InvariantCultureIgnoreCase) || 2373 propCategory.Contains("Boliglandbrug", StringComparison.InvariantCultureIgnoreCase)) 2374 { 2375 brfQuery += "&housingType=parcelhus"; 2376 } 2377 } 2378 2379 brfQuery += "&partnerID=REM100"; 2380 2381 2382 <section id="finance-section" class="container financing-section"> 2383 <div class="financing d-flex flex-column flex-md-row"> 2384 <div class="financing-bank d-flex flex-column justify-content-center"> 2385 <img src="@(imagePath + "Jyske_Bank_logo1.png")" class="img-fluid logo" /> 2386 <h2 class="section-header mb-0"> 2387 @Translate("Custom.Propertypage.Financing.Bank.Header", "Find den finansiering, der passer dig. Få din drømmebolig til at blive virkelighed") 2388 </h2> 2389 <div class="d-none d-md-block divider-orange mb-4"></div> 2390 <div> 2391 @Translate("Custom.Propertypage.Financing.Bank.SubHeader", "Med en hurtig online vurdering kender du bedre dine muligheder") 2392 </div> 2393 @if (propCategory == "Andelsbolig") 2394 { 2395 <a href="https://www.jyskebank.dk/bolig/boliglaan/andelsbolig" target="_blank" id="gtm-brf" class="btn btn-light">@Translate("Smartpage:Boligvisning.CalculatorContact", "Kontakt Jyske Bank")</a> 2396 } 2397 else 2398 { 2399 <a href="https://www.jyskebank.dk/bolig/regn-paa-bolig/beregn-laan-til-ny-bolig?@(brfQuery)" target="_blank" id="gtm-brf" class="btn btn-light w-100">@Translate("Smartpage:Boligvisning.CalculatorLink", "Hvor meget kan jeg købe for?")<img src="@(iconPath + "icon-link-external.svg")" /></a> 2400 } 2401 </div> 2402 <div class="financing-table d-flex flex-column"> 2403 <div class="section-header semi-bold mb-0"> 2404 @Translate("Custom.Propertypage.Financing.Table.Header", "Økonomi og boliglån") 2405 </div> 2406 <div class="d-none d-md-block divider-orange mb-4"></div> 2407 <div class="table-wrapper w-100"> 2408 @if (isRental) 2409 { 2410 <div class="table-item d-flex justify-content-between"> 2411 <div>@Translate("Custom.Propertypage.Financing.RentPerMonth", "Leje pr. måned")</div> 2412 <div>@FormatPrice(GetInteger("Ecom:Product:Field.xEjendomBoligUdlejningLejeMaaned.Value.Clean"))</div> 2413 </div> 2414 2415 int usagePerMonth = GetInteger("Ecom:Product:Field.xEjendomBoligUdlejningAcVarmeMaaned.Value.Clean") + GetInteger("Ecom:Product:Field.xEjendomBoligUdlejningAcVandMaaned.Value.Clean") + GetInteger("Ecom:Product:Field.xEjendomBoligUdlejningAcontoForbrugFri01Beloeb.Value.Clean"); 2416 2417 if (usagePerMonth > 0) 2418 { 2419 <div class="table-item d-flex justify-content-between"> 2420 <div>@Translate("Custom.Propertypage.Financing.UsagePerMonth", "Forbrugsudgift pr. md.")</div> 2421 <div>@FormatPrice(usagePerMonth)</div> 2422 </div> 2423 } 2424 2425 if (GetInteger("Ecom:Product:Field.xEjendomBoligUdlejningAcVarmeMaaned.Value.Clean") > 0) 2426 { 2427 <div class="table-item d-flex justify-content-between"> 2428 <div>@Translate("Custom.Propertypage.Financing.AcontoHeat", "Aconto varme pr. md.")</div> 2429 <div>@FormatPrice(GetInteger("Ecom:Product:Field.xEjendomBoligUdlejningAcVarmeMaaned.Value.Clean"))</div> 2430 </div> 2431 } 2432 2433 if (GetInteger("Ecom:Product:Field.xEjendomBoligUdlejningAcVandMaaned.Value.Clean") > 0) 2434 { 2435 <div class="table-item d-flex justify-content-between"> 2436 <div>@Translate("Custom.Propertypage.Financing.AcontoWater", "Aconto vand pr. md.")</div> 2437 <div>@FormatPrice(GetInteger("Ecom:Product:Field.xEjendomBoligUdlejningAcVandMaaned.Value.Clean"))</div> 2438 </div> 2439 } 2440 2441 if (GetInteger("Ecom:Product:Field.xEjendomBoligUdlejningDepositum") > 0) 2442 { 2443 <div class="table-item d-flex justify-content-between"> 2444 <div>@Translate("Custom.Propertypage.Financing.Deposit", "Depositum")</div> 2445 <div>@FormatPrice(GetInteger("Ecom:Product:Field.xEjendomBoligUdlejningDepositum"))</div> 2446 </div> 2447 } 2448 2449 if (GetInteger("Ecom:Product:Field.xEjendomBoligUdlejningForudbetaltLeje") > 0) 2450 { 2451 <div class="table-item d-flex justify-content-between"> 2452 <div>@Translate("Custom.Propertypage.Financing.Prepayment", "Forudbetalt leje")</div> 2453 <div>@FormatPrice(GetInteger("Ecom:Product:Field.xEjendomBoligUdlejningForudbetaltLeje"))</div> 2454 </div> 2455 } 2456 } 2457 else 2458 { 2459 <div class="table-item d-flex justify-content-between"> 2460 @if (propCategory == "Andelsbolig") 2461 { 2462 <div>@Translate("Custom.Propertypage.Financing.Table.Deposit", "Indskud")</div> 2463 } 2464 else 2465 { 2466 <div>@Translate("Custom.Propertypage.Financing.Table.Price", "Kontantpris")</div> 2467 } 2468 <div>@FormatPrice(GetInteger("Ecom:Product.DBPrice"))</div> 2469 </div> 2470 @if (propCategory != "Andelsbolig") 2471 { 2472 <div class="table-item d-flex justify-content-between"> 2473 <div>@Translate("Custom.Propertypage.Financing.Table.Payout", "Udbetaling")</div> 2474 <div>@FormatPrice(GetInteger("Ecom:Product:Field.xFinansieringUdbetaling"))</div> 2475 </div> 2476 } 2477 <div class="table-item d-flex justify-content-between"> 2478 <div>@Translate("Custom.Propertypage.Financing.Table.Brutto", "Brutto ekskl. ejerudgift")</div> 2479 <div>@FormatPrice(GetInteger("Ecom:Product:Field.xFinansieringBruttoMaaned"))</div> 2480 </div> 2481 <div class="table-item d-flex justify-content-between"> 2482 <div>@Translate("Custom.Propertypage.Financing.Table.Netto", "Netto ekskl. ejerudgift")</div> 2483 <div>@FormatPrice(GetInteger("Ecom:Product:Field.xFinansieringNettoMaaned"))</div> 2484 </div> 2485 <div class="table-item d-flex justify-content-between"> 2486 <div>@Translate("Custom.Propertypage.Financing.Table.OwnerCost", "Ejerudgift")</div> 2487 <div>@FormatPrice(GetInteger("Ecom:Product:Field.xEjendomEjerudgifterMaanedSum"))</div> 2488 </div> 2489 } 2490 </div> 2491 </div> 2492 </div> 2493 </section> 2494 } 2495 2496 @*SECTION: Offer*@ 2497 @if (bolig.BudOenskes) 2498 { 2499 <section id="offer-section" class="container offer-section"> 2500 <div class="offer"> 2501 <div class="offer-wrapper d-flex flex-column text-center"> 2502 <h2 class="section-header semi-bold"> 2503 @Translate("Custom.Propertypage.OfferSection.Header", "Har du et bud i tankerne?") 2504 </h2> 2505 <div class="divider-orange d-none d-md-block mx-auto mb-4"></div> 2506 <div class="offer-text d-block d-md-none"> 2507 @Translate("Custom.Propertypage.OfferSection.Text.Mobile", "Jeg vil gerne byde:") 2508 </div> 2509 <div class="offer-container"> 2510 <div class="offer-text d-none d-md-block"> 2511 @Translate("Custom.Propertypage.OfferSection.Text.Desktop", "Jeg byder") 2512 </div> 2513 <input class="form-control js-input-offer text-right" id="offer-input" type="text" /> 2514 <a class="btn btn-orange js-send-offer-to-form" href="javascript:panelMakeAnOffer('@origin');"> 2515 @Translate("Custom.Propertypage.OfferSection.Button.Send", "Send bud") 2516 <img height="20px" width="20px" src="@(iconPath + "icon-arrow-right.svg")" /> 2517 </a> 2518 </div> 2519 <div class="offer-subtext"> 2520 @Translate("Custom.Propertypage.OfferSection.Subtext", "Dit bud er helt uforpligtende") 2521 </div> 2522 </div> 2523 <img class="img-fluid d-none d-md-block" src="@(imagePath + "skriv_din_pris.jpg")" data-fallback="@fallbackImage" onerror="handleImageError(this)" /> 2524 </div> 2525 </section> 2526 } 2527 2528 @*SECTION: Map with filter*@ 2529 @if (hasMapCoordinates) 2530 { 2531 <section class="container map-filter-section js-init-map-onload" data-map-container="map-filter" data-map-pois="true"> 2532 <div id="map-filter-wrapper" class="map-filter-wrapper"> 2533 <h2 class="section-header semi-bold">@Translate("Custom.Propertypage.FilterMap.Header", "Hvor finder jeg?")</h2> 2534 <div class="divider-orange mb-3 d-none d-md-block"></div> 2535 <div class="map-filters d-flex flex-wrap"> 2536 <label class="mapfilter-btn"> 2537 <input type="checkbox" id="shopping" name="mapfilter" class="mapfilter-checkbox" onchange="toggleMapCategory(this.id, this)" checked> 2538 <span>@Translate("Custom.Propertypage.MapFilter.Filter.Shopping", "Indkøb")</span> 2539 </label> 2540 <label class="mapfilter-btn"> 2541 <input type="checkbox" id="schools" name="mapfilter" class="mapfilter-checkbox" onchange="toggleMapCategory(this.id, this)" checked> 2542 <span>@Translate("Custom.Propertypage.MapFilter.Filter.Schools", "Dagtilbud")</span> 2543 </label> 2544 <label class="mapfilter-btn"> 2545 <input type="checkbox" id="health" name="mapfilter" class="mapfilter-checkbox" onchange="toggleMapCategory(this.id, this)" checked> 2546 <span>@Translate("Custom.Propertypage.MapFilter.Filter.Health", "Helbred")</span> 2547 </label> 2548 <label class="mapfilter-btn"> 2549 <input type="checkbox" id="nature" name="mapfilter" class="mapfilter-checkbox" onchange="toggleMapCategory(this.id, this)" checked> 2550 <span>@Translate("Custom.Propertypage.MapFilter.Filter.Nature", "Natur")</span> 2551 </label> 2552 <label class="mapfilter-btn"> 2553 <input type="checkbox" id="transportation" name="mapfilter" class="mapfilter-checkbox" onchange="toggleMapCategory(this.id, this)" checked> 2554 <span>@Translate("Custom.Propertypage.MapFilter.Filter.Transportation", "Transport")</span> 2555 </label> 2556 </div> 2557 </div> 2558 <div id="map-filter-container" class="map-filter"> 2559 <button type="button" class="btn btn-link" onclick="fullScreen('map-filter-container', this)" data-text-open="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Propertypage.MobileMap.Button.FullScreen", "Fuld skærm"))" data-text-close="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Propertypage.MobileMap.Button.NormalScreen", "Luk"))"> 2560 <div class="js-button-label pb-2">@Translate("Custom:Propertypage.MobileMap.Button.FullScreen", "Fuld skærm")</div> 2561 <div> 2562 <img src="@(iconPath + "icon-expand.svg")" /> 2563 </div> 2564 </button> 2565 <div class="map h-100 w-100 js-map" data-map-feed="@Converter.ToString(GetPageIdByNavigationTag("MapFeed"))"> 2566 <div class="renderMap" id="map-filter"></div> 2567 </div> 2568 </div> 2569 </section> 2570 } 2571 2572 @*SECTION: Broker*@ 2573 @{ 2574 string brokerUrl = !string.IsNullOrEmpty(Converter.ToString(brokerItem["CBMedlemsnummer"])) ? Converter.ToString(brokerItem["CBMedlemsnummer"]).Substring(1) : string.Empty; 2575 string brokerAddress = GetFullAddress(propBroker.Broker); 2576 } 2577 2578 @if (employeeItem != null) 2579 { 2580 <input type="hidden" class="js-hasEmployee" value="true" /> 2581 <section class="container broker-section"> 2582 <div class="broker d-flex flex-column flex-md-row"> 2583 <div class="broker-wrapper d-flex flex-column"> 2584 <h2 class="section-header semi-bold mb-md-0"> 2585 @string.Format(Translate("Custom.Propertypage.BrokerSection.Header", "Har du spørgsmål? Spørg {0}"), propBroker.Employee.FirstName) 2586 </h2> 2587 <div class="divider-orange d-none d-md-block"></div> 2588 <img class="img-fluid d-block d-md-none" src="@employeeItem["BilledeUrl"]" data-fallback="@fallbackImage" onerror="handleImageError(this)" /> 2589 <div class="employee-info d-flex flex-column"> 2590 @if (!string.IsNullOrEmpty(propBroker?.Employee?.Name)) 2591 { 2592 <div class="bold js-maegler-employee-name-val">@propBroker.Employee.Name</div> 2593 } 2594 @if (!string.IsNullOrEmpty(propBroker?.Employee?.JobTitle)) 2595 { 2596 <div class="regular js-maegler-employee-title-val">@propBroker.Employee.JobTitle</div> 2597 } 2598 @if (!string.IsNullOrEmpty(propBroker?.Employee?.Email) && Converter.ToBoolean(employeeItem["VisEmailPaaSager"])) 2599 { 2600 <div class="regular js-maegler-mail-val">@Translate("Custom.Propertypage.BrokerSection.EmplyeeInfo.Emailprefix", "Mail:") <a class="btn-link regular" href="mailto:@propBroker.Employee.Email">@propBroker.Employee.Email</a></div> 2601 } 2602 @if (!string.IsNullOrEmpty(propBroker?.Employee?.PhoneMobile) && Converter.ToBoolean(employeeItem["VisMobilNrPaaSager"])) 2603 { 2604 <div class="regular">@Translate("Custom.Propertypage.BrokerSection.EmplyeeInfo.Phoneprefix", "Tlf:") <a class="btn-link regular js-maegler-mobile-val" href="tel:@propBroker.Employee.PhoneMobile">@RealMaeglerne.Library.Helper.FormatPhoneNumber(propBroker.Employee.PhoneMobile)</a></div> 2605 } 2606 </div> 2607 <div class="divider-grey"></div> 2608 2609 @if (brokerItem != null) 2610 { 2611 var brokerEmail = Converter.ToString(brokerItem["Email"]); 2612 2613 <div class="broker-info"> 2614 @if (!string.IsNullOrEmpty(propBroker?.Broker?.CompanyName)) 2615 { 2616 <div class="bold js-maegler-name-val">@propBroker.Broker.CompanyName</div> 2617 } 2618 else if (!string.IsNullOrEmpty(propBroker?.Broker?.Name)) 2619 { 2620 <div class="bold js-maegler-name-val">@propBroker.Broker.Name</div> 2621 } 2622 @if (!string.IsNullOrEmpty(brokerAddress)) 2623 { 2624 <div class="regular">@brokerAddress</div> 2625 } 2626 @if (!string.IsNullOrEmpty(brokerEmail)) 2627 { 2628 <div class="regular">@Translate("Custom.Propertypage.BrokerSection.EmployeeInfo.Emailprefix", "Mail:") <a class="btn-link regular" href="mailto:@brokerEmail">@brokerEmail</a></div> 2629 } 2630 @if (!string.IsNullOrEmpty(propBroker?.Broker?.Telephone)) 2631 { 2632 <div class="regular">@Translate("Custom.Propertypage.BrokerSection.EmployeeInfo.Phoneprefix", "Tlf:") <a class="btn-link regular js-maegler-phone-val" href="tel:@propBroker.Broker.Telephone">@RealMaeglerne.Library.Helper.FormatPhoneNumber(propBroker.Broker.Telephone)</a></div> 2633 } 2634 </div> 2635 <span class="js-butikId d-none">@Converter.ToString(employeeItem["CBMedlemsnummer"])</span> 2636 <span class="js-maegler-address-val d-none">@propBroker.Broker.Address</span> 2637 <span class="js-maegler-zip-city-val d-none">@propBroker.Broker.ZipCode @propBroker.Broker.City</span> 2638 } 2639 2640 <div class="broker-buttons d-flex flex-column flex-md-row"> 2641 @if (!string.IsNullOrEmpty(brokerUrl)) 2642 { 2643 brokerUrl = "/" + brokerUrl; 2644 <a href="@brokerUrl" class="btn btn-blue w-100"> 2645 @Translate("Custom.Propertypage.BrokerSection.BrokerLink.Label", "Vis mæglerens side") 2646 <img height="20px" width="20px" src="@(iconPath + "icon-arrow-right.svg")" /> 2647 </a> 2648 } 2649 @if (!bolig.Solgt && !bolig.PurchaseAgreementSigned) { 2650 <a class="btn btn-orange w-100" href="javascript:panelFremvisning('@origin');"> 2651 @Translate("Custom.Propertypage.AssetsModal.Header.Showing.ButtonLabel", "Bestil fremvisning") 2652 <img height="20px" width="20px" src="@(iconPath + "icon-arrow-right.svg")" /> 2653 </a> 2654 } 2655 </div> 2656 </div> 2657 <img class="img-fluid d-none d-md-block" src="@employeeItem["BilledeUrl"]" data-fallback="@fallbackImage" onerror="handleImageError(this)" /> 2658 </div> 2659 </section> 2660 } 2661 2662 @*SECTION: Silmilar properties*@ 2663 @{ 2664 int sliderFeedPageId = GetPageIdByNavigationTag("PropertySlider"); 2665 } 2666 @if (sliderFeedPageId > 0) 2667 { 2668 <section class="container property-slider-section"> 2669 <div class="d-flex flex-column justify-content-center align-content-center"> 2670 <h2 class="property-slider-header">@Translate("Custom.PropertySlider.Header", "Se lignende boliger")</h2> 2671 <div class="property-slider-subheader">@Translate("Custom.PropertySlider.Subheader", "- måske gemmer din drømmebolig sig her?")</div> 2672 </div> 2673 <div id="property-slider" class="property-slider" data-slider-feed="@Converter.ToString(sliderFeedPageId)" data-zip-code="@GetString("Ecom:Product:Field.xEjendomAdressePostnummer")" data-property-category="@propCategory" data-product-number="@product.Number"> 2674 <div class="property-slider-skeleton"> 2675 </div> 2676 </div> 2677 </section> 2678 } 2679 2680 @*SECTION: Climate*@ 2681 @if (bolig.ShowClimateCalculator) 2682 { 2683 <section id="climate-calculator-section" class="container climate-calculator-section"> 2684 <div class="climate-calculator"> 2685 <div class="climate-calculator-wrapper d-flex flex-column"> 2686 <h2 class="section-header semi-bold text-left mb-md-0"> 2687 @Translate("Custom.Propertypage.ClimateCalculatorSection.Header", "Prøv Klimaberegner") 2688 </h2> 2689 <div class="divider-orange d-none d-md-block"></div> 2690 <div class="climate-calculator-description"> 2691 @Translate("Custom.Propertypage.ClimateCalculatorSection.Description", "Lorem ipsum dolor sit amet consectetur adipiscing elit cubilia metus quam. Ullamcorper posuere arcu vel porta blandit auctor ad cubilia rhoncus ac mus quam, augue condi.") 2692 </div> 2693 <div class="climate-calculator-button-wrapper"> 2694 <div class="climate-calculator-button-text"> 2695 @Translate("Custom.Propertypage.ClimateCalculatorSection.Button.Text", "Forbedringer til") 2696 <span class="semi-bold">@bolig.Adresse.Replace(",", "")</span> 2697 </div> 2698 <div role="button" class="climate-calculator-button-label" onclick="document.getElementById('climate-calculator-frame').classList.toggle('active');"> 2699 @Translate("Custom.Propertypage.ClimateCalculatorSection.Button.Label", "Vis") 2700 <img src="@(iconPath + "plus-white.svg")" alt="" aria-hidden="true" /> 2701 </div> 2702 </div> 2703 </div> 2704 <img class="img-fluid d-none d-md-block" src="@(imagePath + "climate.png")" data-fallback="@fallbackImage" onerror="handleImageError(this)" alt="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom.Propertypage.ClimateCalculatorSection.ImageAlt", "Grafik med klimaberegnerikoner"))"/> 2705 <div id="climate-calculator-frame" class="climate-calculator-frame"> 2706 <div class="climate-calculator-divider"></div> 2707 <div id="climate_calculator" data-property-id="@productId" class="climate-calculator-frame-wrapper"></div> 2708 <script type="text/javascript" src="@Converter.ToString(Pageview.Area.Item["ClimateCalculatorScriptUrl"])"></script> 2709 </div> 2710 </div> 2711 </section> 2712 } 2713 2714 @*SECTION: Goldbuyer*@ 2715 @{ 2716 var becomeGoldBuyerLink = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetRawValueString("BecomeGoldBuyerLink", ""); 2717 } 2718 2719 @if (!string.IsNullOrEmpty(becomeGoldBuyerLink)) 2720 { 2721 <section class="container goldbuyer-section"> 2722 <div class="goldbuyer"> 2723 <div class="goldbuyer-wrapper d-flex flex-column"> 2724 <h2 class="section-header semi-bold text-left mb-md-0"> 2725 @Translate("Custom.Propertypage.GoldBuyerSection.Header", "Guldkøber®") 2726 </h2> 2727 <div class="divider-orange d-none d-md-block"></div> 2728 <div class="section-usps"> 2729 <div class="d-flex"> 2730 <img class="circle-gold mr-2" height="24px" width="24px" src="@(iconPath + "icon-check.svg")" /> 2731 @Translate("Custom.Propertypage.GoldBuyerSection.Usp1", "Få besked, når en bolig matcher dine ønsker.") 2732 </div> 2733 <div class="d-flex"> 2734 <img class="circle-gold mr-2" height="24px" width="24px" src="@(iconPath + "icon-check.svg")" /> 2735 @Translate("Custom.Propertypage.GoldBuyerSection.Usp2", "Vi overvåger markedet for dig.") 2736 </div> 2737 <div class="d-flex"> 2738 <img class="circle-gold mr-2" height="24px" width="24px" src="@(iconPath + "icon-check.svg")" /> 2739 @Translate("Custom.Propertypage.GoldBuyerSection.Usp3", "Få et nemt køb.") 2740 </div> 2741 </div> 2742 <a class="btn btn-gold align-self-center align-self-md-start" href="/Default.aspx?ID=@becomeGoldBuyerLink"> 2743 @Translate("Custom.Propertypage.GoldBuyerSection.ButtonLabel", "Bliv guldkøber") 2744 <img height="20px" width="20px" src="@(iconPath + "icon-arrow-right.svg")" /> 2745 </a> 2746 </div> 2747 <img class="img-fluid d-none d-md-block" src="@(imagePath + "goldbuyer.jpg")" data-fallback="@fallbackImage" onerror="handleImageError(this)" /> 2748 </div> 2749 </section> 2750 } 2751 2752 @*SECTION: Buyer Advice*@ 2753 @{ 2754 var rmBuyingAdvicePageId = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetRawValueString("RMBuyingAdviceMasterPageID", ""); 2755 } 2756 2757 @if (!string.IsNullOrEmpty(rmBuyingAdvicePageId)) 2758 { 2759 <section class="container buyeradvice-section"> 2760 <div class="buyeradvice"> 2761 <img class="img-fluid d-none d-md-block" src="@(imagePath + "buyeradvice.jpg")" data-fallback="@fallbackImage" onerror="handleImageError(this)" /> 2762 <div class="buyeradvice-wrapper d-flex flex-column"> 2763 <h2 class="section-header semi-bold text-left mb-md-0"> 2764 @Translate("Custom.Propertypage.BuyerAdviceSection.Header", "Køber du hos anden mægler? Få ærlig køberrådgivning") 2765 </h2> 2766 <div class="divider-orange d-none d-md-block"></div> 2767 <div class="section-usps"> 2768 <div class="d-flex"> 2769 <img class="circle-blue mr-2" height="24px" width="24px" src="@(iconPath + "icon-check.svg")" /> 2770 @Translate("Custom.Propertypage.BuyerAdviceSection.Usp1", "Vi gennemgår købsaftale, skøde og finansiering, så du undgår skjulte faldgruber og dyre fejl.") 2771 </div> 2772 <div class="d-flex"> 2773 <img class="circle-blue mr-2" height="24px" width="24px" src="@(iconPath + "icon-check.svg")" /> 2774 @Translate("Custom.Propertypage.BuyerAdviceSection.Usp2", "Du får en dedikeret køberrådgiver, som kun arbejder for dig – ikke sælger.") 2775 </div> 2776 <div class="d-flex"> 2777 <img class="circle-blue mr-2" height="24px" width="24px" src="@(iconPath + "icon-check.svg")" /> 2778 @Translate("Custom.Propertypage.BuyerAdviceSection.Usp3", "Vi kan forhandle på dine vegne og ofte skaffe bedre pris, vilkår eller overtagelsesdato.") 2779 </div> 2780 </div> 2781 <a class="btn btn-blue align-self-center align-self-md-start" href="/Default.aspx?ID=@rmBuyingAdvicePageId"> 2782 @Translate("Custom.Propertypage.BuyerAdviceSection.ButtonLabel", "Sådan hjælper køberrådgivning dig") 2783 <img height="20px" width="20px" src="@(iconPath + "icon-arrow-right.svg")" /> 2784 </a> 2785 </div> 2786 </div> 2787 </section> 2788 } 2789 <div id="sticky-sales-assessment-button" class="sales-assessment-mobile d-block d-md-none"> 2790 <a class="btn btn-blue" href="javascript:panelSalgsvurdering('@origin');">@Translate("Custom.Propertypage.SalesAssessment.ButtonLabel", "Bestil salgsvurdering")</a> 2791 </div> 2792 </div> 2793 <!--PANELS--> 2794 @{ 2795 var settingsPersondatapolitik = settingsItem != null ? settingsItem["Persondatapolitik"] : ""; 2796 var termsMail = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetRawValueString("TermsEmail", ""); 2797 var userId = Dynamicweb.Security.UserManagement.UserContext.Current.UserId; 2798 var user = Dynamicweb.Security.UserManagement.UserContext.Current.User; 2799 string brokerName = !string.IsNullOrEmpty(propBroker?.Broker?.CompanyName) ? propBroker.Broker.CompanyName : propBroker.Broker.Name; 2800 string butikId = brokerItem?["CBMedlemsnummer"] != null ? Converter.ToString(brokerItem["CBMedlemsnummer"]) : string.Empty; 2801 2802 } 2803 2804 <div id="panel-book-showing" class="panel panel-form" role="dialog" aria-modal="true" aria-labelledby="book-showing-title"> 2805 <button type="button" class="close" data-dismiss="panel-form" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.CloseForm", "Luk formular"))"> 2806 <b></b> 2807 </button> 2808 <h2 id="book-showing-title" class="js-showing-header">@Translate("form-fremvisning-titel", "Bestil fremvisning")</h2> 2809 <p>@Translate("form-fremvisning-beskrivelse", "")</p> 2810 <form id="book-showing" method="POST" action="/InboxHandler"> 2811 <div class="form-group"> 2812 <label><strong>@Translate("form-navn", "Navn")*</strong></label> 2813 <input class="form-control" type="text" name="navn" placeholder="@HtmlEncoder.HtmlAttributeEncode(Translate("Smartpage:Placeholder.Navn", "Indtast dit navn"))" value="@HtmlEncoder.HtmlAttributeEncode(user?.UserName)" required="required" aria-required="true" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.NameField", "Navn"))" /> 2814 </div> 2815 <div class="form-group"> 2816 <label><strong>@Translate("form-email", "E-mail")*</strong></label> 2817 <input class="form-control" type="email" pattern="[_a-z0-9.%+-]+@[a-z0-9.-]+.[a-z]{2,4}$" name="email" placeholder="@HtmlEncoder.HtmlAttributeEncode(Translate("Smartpage:Placeholder.Email", "Indtast din e-mail"))" value="@HtmlEncoder.HtmlAttributeEncode(user?.Email)" required="required" aria-required="true" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.EmailField", "E-mail adresse"))" /> 2818 </div> 2819 <div class="form-group row"> 2820 <div class="col-6"> 2821 <label><strong>@Translate("form-mobile", "Mobil nr.")*</strong></label> 2822 <input class="form-control" type="tel" pattern="^[0-9]*$" maxlength="20" name="mobile" placeholder="@HtmlEncoder.HtmlAttributeEncode(Translate("Smartpage:Salgsopstilling.Placeholder.Mobile", "Indtast mobil nr."))" value="@HtmlEncoder.HtmlAttributeEncode(user?.Phone)" required="required" aria-required="true" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.MobileField", "Mobilnummer"))" /> 2823 </div> 2824 <div class="col-6"> 2825 <label><strong>@Translate("form-telephone", "Telefon nr.")</strong></label> 2826 <input class="form-control" type="tel" pattern="^[0-9]*$" maxlength="20" name="telefonnummer" placeholder="@HtmlEncoder.HtmlAttributeEncode(Translate("Smartpage:Salgsopstilling.Placeholder.Telefon", "Indtast tlf nr."))" value="@HtmlEncoder.HtmlAttributeEncode(user?.Phone)" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.PhoneField", "Telefonnummer"))" /> 2827 </div> 2828 </div> 2829 2830 <div class="form-group"> 2831 <label><strong>@Translate("form-tidspunkt", "Tidspunkt")*</strong></label> 2832 <input class="form-control" type="text" name="tidspunkt" placeholder="@HtmlEncoder.HtmlAttributeEncode(Translate("form-tidspunkt", "Tidspunkt"))" required="required" aria-required="true" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.TimeField", "Tidspunkt for fremvisning"))" /> 2833 </div> 2834 <button class="form-control text-left js-collapse-focus" type="button" data-toggle="collapse" data-target="#bookshowing-collapse" aria-expanded="false" aria-controls="bookshowing-collapse" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.AddComment", "Tilføj kommentar"))"> 2835 <strong class="f-12"><i class="fas fa-plus"></i> @Translate("Smartpage:.Skrivenkommentar", "Skriv en kommentar")</strong> 2836 </button> 2837 <div class="collapse" id="bookshowing-collapse"> 2838 <div class="form-group"> 2839 <textarea class="form-control" name="besked" placeholder="@HtmlEncoder.HtmlAttributeEncode(Translate("form-besked", "Besked"))" maxlength="150" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.MessageField", "Besked til mægler"))"></textarea> 2840 </div> 2841 </div> 2842 2843 <div class="form-group"> 2844 <div class="row"> 2845 <div class="col-12"> 2846 <button type="submit" class="btn btn-green btn-block js-showing-btn">@Translate("form-fremvisning-submitbtn", "Bestil fremvisning")</button> 2847 </div> 2848 </div> 2849 </div> 2850 <div class="form-group form-group-terms"> 2851 @string.Format(Translate("Custom.Propertypage.PanelBookShowing.Terms", "Ved at indsende formularen, giver du dit samtykke til, at dine data samles og behandles af RealMæglerne A/S for at kunne kontakte dig.\r\n Du kan til enhver tid tilbagekalde dit samtykke. For at gøre dette skal du blot sende en meddelelse til <a href=\"mailto:{0}\">{0}</a>.\r\n Læs mere på <a href=\"{1}\">privatlivspolitikkerne</a>."), termsMail, settingsPersondatapolitik) 2852 </div> 2853 <input type="hidden" name="kontaktmigok" value="true" /> 2854 <input type="hidden" name="fn" value="bf" /> 2855 <input type="hidden" name="origin" value="" /> 2856 <input type="hidden" name="brugerId" value="@userId" /> 2857 <input type="hidden" name="sagsnr" value="@productId" /> 2858 <input type="hidden" name="productid" value="@productId" /> 2859 <input type="hidden" name="eadresse" value="@HtmlEncoder.HtmlAttributeEncode(GetString("Ecom:Product:Field.xEjendomAdresseAdresseLinie"))" /> 2860 <input type="hidden" name="epostnrby" value="@HtmlEncoder.HtmlAttributeEncode(GetString("Ecom:Product:Field.xEjendomAdressePostAdresseLinie"))" /> 2861 <input type="hidden" name="areaid" value="@Pageview.AreaID" /> 2862 <input type="hidden" name="bnavn" value="@HtmlEncoder.HtmlAttributeEncode(brokerName)" /> 2863 <input type="hidden" name="greenmobility" value="@Converter.ToString(isValidForGreenMobility)" /> 2864 <input class="js-online-showing" type="hidden" name="onlineShowing" value="" /> 2865 <input type="hidden" name="butikId" value="@HtmlEncoder.HtmlAttributeEncode(butikId)" /> 2866 @if (employeeItem != null) 2867 { 2868 2869 <input type="hidden" name="mnavn" value="@HtmlEncoder.HtmlAttributeEncode(propBroker.Employee.Name)" /> 2870 if (!string.IsNullOrEmpty(propBroker.Employee.PhoneMobile) && Converter.ToBoolean(employeeItem["VisMobilNrPaaSager"])) 2871 { 2872 <input type="hidden" name="mtelefonnummer" value="@HtmlEncoder.HtmlAttributeEncode(propBroker.Employee.PhoneMobile)" /> 2873 } 2874 else 2875 { 2876 2877 <input type="hidden" name="mtelefonnummer" value="@HtmlEncoder.HtmlAttributeEncode(propBroker.Broker.Telephone)" /> 2878 } 2879 2880 <input type="hidden" name="memail" value="@RealMaeglerne.Library.Helper.ExtractMaskedEmail(propBroker.Employee.Email)" /> 2881 2882 } 2883 </form> 2884 <div id="book-showing-thanks" style="display:none;" role="status" aria-live="polite" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.ThankYouMessage", "Tak besked"))"> 2885 <p>@Translate("form-fremvisning-tak", "Tak for din bestilling af fremvisning. Du vil hurtigst muligt blive kontaktet af din mægler, for at bekræfte jeres aftale. Tak for din interesse.")</p> 2886 </div> 2887 </div> 2888 2889 <div id="panel-sales-documents" class="panel panel-form" role="dialog" aria-modal="true" aria-labelledby="sales-documents-title"> 2890 <button type="button" class="close" data-dismiss="panel-form" aria-label="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Accessibility.CloseForm", "Luk formular"))"> 2891 <b></b> 2892 </button> 2893 2894 <h2 id="sales-documents-title">@Translate("form-salgsopstilling-titel", "Bestil Salgsopstilling")</h2> 2895 2896 <p>@Translate("form-salgsopstilling-beskrivelse", "")</p> 2897 <form id="order-sales-documents" method="POST" action="/InboxHandler"> 2898 <div class="form-group"> 2899 <label><strong>@Translate("form-navn", "Navn")*</strong></label> 2900 <input class="form-control" type="text" name="navn" placeholder="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Salgsopstilling.Placeholder.Navn", "Indtast dit navn"))" value="@HtmlEncoder.HtmlAttributeEncode(user?.UserName)" required=required /> 2901 </div> 2902 <div class="form-group"> 2903 <label><strong>@Translate("form-email", "E-mail")*</strong></label> 2904 <input class="form-control" type="email" pattern="[_a-z0-9.%+-]+@[a-z0-9.-]+.[a-z]{2,4}$" name="email" placeholder="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:.Salgsopstilling.Placeholder.Email", "Indtast din e-mail"))" value="@HtmlEncoder.HtmlAttributeEncode(user?.Email)" required=required /> 2905 </div> 2906 <div class="form-group row"> 2907 <div class="col-6"> 2908 <label><strong>@Translate("form-mobile", "Mobil nr.")*</strong></label> 2909 <input class="form-control" type="tel" pattern="^[0-9]*$" maxlength="20" name="mobile" placeholder="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Salgsopstilling.Placeholder.Mobile", "Indtast mobil nr."))" value="@HtmlEncoder.HtmlAttributeEncode(user?.Phone)" required=required /> 2910 </div> 2911 <div class="col-6"> 2912 <label><strong>@Translate("form-telephone", "Telefon nr.")</strong></label> 2913 <input class="form-control" type="tel" pattern="^[0-9]*$" maxlength="20" name="telefonnummer" placeholder="@HtmlEncoder.HtmlAttributeEncode(Translate("Custom:Salgsopstilling.Placeholder.Telefon", "Indtast tlf nr."))" value="@HtmlEncoder.HtmlAttributeEncode(user?.Phone)" /> 2914 </div> 2915 </div> 2916 <div class="form-group"> 2917 <div class="checkbox"> 2918 <label> 2919 <input type="checkbox" name="kontaktmigok" /> 2920 <span>@Translate("form-contactpermission-real", "Ja tak, RealMæglerne må gerne kontakte mig. *")</span> 2921 </label> 2922 </div> 2923 </div> 2924 <div class="form-group"> 2925 <div class="row"> 2926 <div class="col-12"> 2927 <button type="submit" class="btn btn-green btn-block">@Translate("form-salgsopstilling-submitbtn", "Bestil salgsopstilling")</button> 2928 </div> 2929 </div> 2930 </div> 2931 2932 2933 <div class="form-group form-group-terms"> 2934 @string.Format(Translate("Custom.Propertypage.PanelBookShowing.Terms", "Ved at indsende formularen, giver du dit samtykke til, at dine data samles og behandles af RealMæglerne A/S for at kunne kontakte dig.\r\n Du kan til enhver tid tilbagekalde dit samtykke. For at gøre dette skal du blot sende en meddelelse til <a href=\"mailto:{0}\">{0}</a>.\r\n Læs mere på <a href=\"{1}\">privatlivspolitikkerne</a>."), termsMail, settingsPersondatapolitik) 2935 </div> 2936 <input type="hidden" name="fn" value="bs" /> 2937 <input type="hidden" name="origin" value="" /> 2938 <input type="hidden" name="sagsnr" value="@productId" /> 2939 <input type="hidden" name="brugerId" value="@userId" /> 2940 <input type="hidden" name="areaid" value="@Pageview.AreaID" /> 2941 <input type="hidden" Fname="butikId" value="@HtmlEncoder.HtmlAttributeEncode(butikId)" /> 2942 <input type="hidden" name="productId" value="@productId" /> 2943 </form> 2944 <div id="download-sales-documents" style="display:none;"> 2945 <p>@Translate("form-salgsopstilling-downloadbeskrivelse", "Tak for din interesse")</p> 2946 <br /> 2947 @foreach (var item in edhFiles) 2948 { 2949 if (item.Value.ToLower() == "salgsopstilling") 2950 { 2951 <a href="@item.Key" class="btn btn-primary link" target="_blank">@Translate("form-salgsopstilling-download", "Hent") @item.Value</a> 2952 <br /><br /> 2953 } 2954 } 2955 </div> 2956 </div> 2957 2958 <div id="panel-makeanoffer" class="panel panel-form"> 2959 <button type="button" class="close" data-dismiss="panel-form" aria-label="@HtmlEncoder.HtmlAttributeEncode(@Translate("Custom:Accessiblity.OfferPanel.Close","Luk"))"> 2960 <b></b> 2961 </button> 2962 2963 <h2>@Translate("Smartpage:MakeAnOffer.Title", "Skriv din pris")</h2> 2964 2965 <form id="make-an-offer" method="POST" action="/InboxHandler"> 2966 <p>@Translate("Smartpage:MakeAnOffer.Subtitle", "Giv et uforpligtende bud. Dit bud er ikke bindende for dig, ligesom sælger ikke er forpligtet til at acceptere dit bud.")</p> 2967 <div class="form-group"> 2968 <label><strong>@Translate("Smartpage:MakeAnOffer.Price", "Prisforslag")*</strong></label> 2969 @*checkmark*@ 2970 <input class="form-control js-input-offer" id="form-offer" type="text" name="price" placeholder="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(Translate("Smartpage:MakeAnOffer.Price", "Prisforslag") )" /> 2971 </div> 2972 <div class="form-group"> 2973 <label><strong>@Translate("form-navn", "Navn")*</strong></label> 2974 <input class="form-control" type="text" name="navn" placeholder="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(Translate("form-navn", "Navn") )" value="@HtmlEncoder.HtmlAttributeEncode(user?.UserName)" /> 2975 </div> 2976 <div class="form-group"> 2977 <label><strong>@Translate("form-email", "E-mail")*</strong></label> 2978 <input class="form-control" type="email" pattern="[_a-z0-9.%+-]+@[a-z0-9.-]+.[a-z]{2,4}$" name="email" placeholder="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(Translate("form-email", "E-mail") )" value="@HtmlEncoder.HtmlAttributeEncode(user?.Email)" /> 2979 </div> 2980 <div class="form-group"> 2981 <label><strong>@Translate("form-telephone", "Telefon nr.")*</strong></label> 2982 <input class="form-control" type="tel" pattern="^[0-9]*$" maxlength="20" name="telefonnummer" placeholder="@Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(Translate("Smartpage:Salgsopstilling.Placeholder.Telefon", "Indtast tlf nr.") )" value="@HtmlEncoder.HtmlAttributeEncode(user?.Phone)" /> 2983 </div> 2984 <div class="form-group"> 2985 <div class="checkbox"> 2986 <label> 2987 <input type="checkbox" name="kontaktmigok" /> 2988 <span>@Translate("form-contactpermission-real", "Ja tak, RealMæglerne må gerne kontakte mig. *")</span> 2989 </label> 2990 </div> 2991 </div> 2992 <div class="form-group"> 2993 <div class="row"> 2994 <div class="col-12"> 2995 <button type="submit" class="btn btn-green btn-block">@Translate("Smartpage:MakeAnOffer.Button.Text", "Send mit bud")</button> 2996 </div> 2997 </div> 2998 </div> 2999 3000 3001 <div class="form-group form-group-terms"> 3002 @Translate("Smartpage:MakeAnOffer.TermsAndConditions", "* Der samles ingen personlige oplysninger uden dit udtrykkelige samtykke. Ved at klikke på denne checkboks giver du dit samtykke til, at dine data samles og behandles af RealMæglerne A/S for at kunne kontakte dig. Du kan til enhver tid tilbagekalde dit samtykke. For at gøre dette skal du blot sende en meddelelse til ") 3003 <a href="mailto:@termsMail">@termsMail</a>. 3004 @Translate("Smartpage:MakeAnOffer.TermsAndConditions.ReadMoreOn", "Læs mere på") <a href="@settingsPersondatapolitik">@Translate("Smartpage:MakeAnOffer.TermsAndConditions.PrivacyPolicy", "privatlivspolitikkerne")</a>. 3005 </div> 3006 <input type="hidden" name="fn" value="skp" /> 3007 <input type="hidden" name="origin" value="" /> 3008 <input type="hidden" name="sagsnr" value="@productId" /> 3009 <input type="hidden" name="brugerId" value="@userId" /> 3010 <input type="hidden" name="areaid" value="@Pageview.AreaID" /> 3011 <input type="hidden" name="butikId" value="@HtmlEncoder.HtmlAttributeEncode(butikId)" /> 3012 </form> 3013 <div class="js-thank-you-message" style="display:none;"> 3014 <p>@Translate("Smartpage:MakeAnOffer.ThankYouMessage", "Tak for dit bud. Du vil hurtigst muligt blive kontaktet af mægler. Tak for din interesse.")</p> 3015 </div> 3016 </div> 3017 3018 @{ 3019 string teaserDesc = System.Text.RegularExpressions.Regex.Replace(GetString("Ecom:Product.LongDescription"), "<[^>]*>", String.Empty); 3020 if (teaserDesc.Length > 300) 3021 { 3022 teaserDesc = teaserDesc.Substring(0, 300) + "..."; 3023 } 3024 string priceWithDecimal = GetInteger("Ecom:Product.DBPrice") + ".0"; 3025 } 3026 @SnippetStart("OpenGraphTags") 3027 3028 <meta property="og:type" content="website" /> 3029 <meta property="og:url" content="@Context.Current.Request.Url.AbsoluteUri" /> 3030 <meta property="og:image" content="@HtmlEncoder.HtmlAttributeEncode(primaryImage?.ImageXl)" /> 3031 <meta property="og:title" content="@HtmlEncoder.HtmlAttributeEncode(GetString("Ecom:Product:Field.xEjendomAdresseAdresseLinie")), @HtmlEncoder.HtmlAttributeEncode(GetString("Ecom:Product:Field.xEjendomAdressePostAdresseLinie"))" /> 3032 <meta property="og:description" content="@HtmlEncoder.HtmlAttributeEncode(teaserDesc)" /> 3033 3034 @{ 3035 if (!bolig.Solgt && !bolig.PurchaseAgreementSigned) 3036 { 3037 <meta property="og:price:amount" content="@priceWithDecimal" /> 3038 <meta property="og:price:currency" content="DKK" /> 3039 } 3040 } 3041 3042 @*TWITTER CARD*@ 3043 <!-- Twitter Card data --> 3044 <meta name="twitter:card" content="product" /> 3045 <meta name="twitter:site" content="@Context.Current.Request.Url.AbsoluteUri" /> 3046 <meta name="twitter:title" content="@HtmlEncoder.HtmlAttributeEncode(GetString("Ecom:Product:Field.xEjendomAdresseAdresseLinie")), @HtmlEncoder.HtmlAttributeEncode(GetString("Ecom:Product:Field.xEjendomAdressePostAdresseLinie"))" /> 3047 <meta name="twitter:description" content="@HtmlEncoder.HtmlAttributeEncode(teaserDesc)" /> 3048 <!-- Twitter summary card with large image must be at least 280x150px --> 3049 <meta name="twitter:image:src" content="@HtmlEncoder.HtmlAttributeEncode(primaryImage?.ImageLg)" /> 3050 @*TWITTER CARD END*@ 3051 3052 @SnippetEnd("OpenGraphTags") 3053 3054 @SnippetStart("StructuredData") 3055 <script type="application/ld+json"> 3056 { 3057 "@@context": "http://schema.org", 3058 "@@type": "Residence", 3059 "address": { 3060 "@@type": "PostalAddress", 3061 "addressCountry": "Denmark", 3062 "postalCode": "@GetString("Ecom:Product:Field.xEjendomAdressePostnummer")", 3063 "streetAddress": "@GetString("Ecom:Product:Field.xEjendomAdresseAdresseLinie")" 3064 } 3065 } 3066 </script> 3067 @SnippetEnd("StructuredData") 3068 3069 3070 @SnippetStart("GtmDatalayer") 3071 3072 @{ 3073 var settings_Google_Tag_Manager_ID = !string.IsNullOrEmpty(Converter.ToString(settingsItem["Google_Tag_Manager_ID"])) ? settingsItem["Google_Tag_Manager_ID"] : ""; 3074 } 3075 3076 <!-- GTM --> 3077 @if (!string.IsNullOrEmpty(Converter.ToString(settings_Google_Tag_Manager_ID))) 3078 { 3079 var gtmPropertyType = ""; 3080 3081 if (isRental) 3082 { 3083 gtmPropertyType = Translate("Smartpage:Boligsiden.Information.Type.Lejebolig", "Lejebolig"); 3084 } 3085 else 3086 { 3087 gtmPropertyType = propTypeDisplay; 3088 } 3089 3090 <script> 3091 // on load 3092 window.dataLayer.push({ 3093 'propertyID': '@product', 3094 'propertyType': '@gtmPropertyType', 3095 }); 3096 </script> 3097 3098 if (propBroker != null) 3099 { 3100 <script> 3101 // on load 3102 // MH: needs to be rewritten if it should support multiple brokers 3103 window.dataLayer.push({ 3104 'realEstateAgentId': '@butikId', 3105 }); 3106 </script> 3107 } 3108 } 3109 <!-- GTM end --> 3110 @SnippetEnd("GtmDatalayer") 3111 @SnippetStart("JavaScriptBottom") 3112 <script type="text/javascript" src="/Files/Templates/Designs/rm/assets/dist/bundle.boligside.min.js"></script> 3113 <script> 3114 3115 3116 document.addEventListener("DOMContentLoaded", () => { 3117 checkIfStuck("[propertypage-anchor]"); 3118 initHiddenStickyElements("sticky-sales-assessment-button", "address-section"); 3119 initImageNavigation('.blueprints', { imageSelector: '.blueprints-wrapper img', buttonIdPostFix: '-blueprints', threshold: 1, scrollDirection: 'horizontal', overflowWrapperSelector: '.js-blueprints-wrapper' }); 3120 initImageNavigation('.usps', { imageSelector: '.usp-item', buttonIdPostFix: '-usps', threshold: 1, scrollDirection: 'horizontal' }); 3121 syncSelectors('openhouse-selector-desktop', 'openhouse-selector-mobile'); 3122 initSliderObserver('property-slider'); 3123 initMetricsSlider('.js-popular-metrics-wrapper', '.popular-metric'); 3124 initThumbnailKeyboardNav(); 3125 }) 3126 3127 function initSliderObserver(sliderElementId) { 3128 3129 const sliderElement = document.getElementById(sliderElementId); 3130 3131 const observer = new IntersectionObserver((entries) => { 3132 entries.forEach(entry => { 3133 if (entry.isIntersecting) { 3134 addSlider(entry); 3135 observer.unobserve(entry.target); 3136 } 3137 }); 3138 }, { 3139 root: null, 3140 threshold: 0.1 3141 }); 3142 3143 // Observe elements 3144 observer.observe(sliderElement); 3145 } 3146 3147 async function addSlider(entry) { 3148 const sliderFeedId = entry.target.dataset.sliderFeed; 3149 3150 if (sliderFeedId != null) { 3151 const params = new URLSearchParams({ ID: sliderFeedId }); 3152 3153 const zipCode = entry.target.dataset.zipCode; 3154 if (zipCode) { 3155 params.set('zipcodefrom', zipCode); 3156 params.set('zipcodeto', zipCode); 3157 } 3158 3159 const propertyCategory = entry.target.dataset.propertyCategory; 3160 if (propertyCategory) { 3161 params.set('propertycategory', propertyCategory); 3162 } 3163 3164 const productNumber = entry.target.dataset.productNumber; 3165 if (productNumber) { 3166 params.set('ExcludeProductNumber', productNumber); 3167 } 3168 3169 const url = `/Default.aspx?${params}`; 3170 3171 try { 3172 const result = await fetch(url); 3173 if (!result.ok) throw new Error('Network response was not ok'); 3174 const response = await result.text(); 3175 entry.target.innerHTML = response; 3176 } catch (error) { 3177 console.error('Error loading slider:', error); 3178 entry.target.innerHTML = '<p>@Dynamicweb.Core.Encoders.HtmlEncoder.JavaScriptStringEncode(Translate("Custom.Propertypage.PropertySlider.ErrorMessage", "Failed to load content"))</p>'; 3179 } 3180 } 3181 3182 } 3183 3184 function initMetricsSlider(wrapperElement, children) { 3185 document.querySelectorAll(wrapperElement).forEach(wrapper => { 3186 const metrics = wrapper.querySelectorAll(children); 3187 3188 // Skip if only one metric 3189 if (metrics.length <= 1) return; 3190 3191 // Measure widths 3192 const widths = []; 3193 metrics.forEach(metric => { 3194 widths.push(metric.offsetWidth); 3195 }); 3196 3197 // Setup wrapper 3198 wrapper.style.width = widths[0] + 'px'; 3199 wrapper.style.transition = 'width 1s ease-in-out'; 3200 3201 // Setup metrics 3202 metrics.forEach((metric, index) => { 3203 metric.style.position = 'absolute'; 3204 metric.style.top = '0'; 3205 metric.style.left = '0'; 3206 metric.style.transition = 'opacity 1s ease-in-out'; 3207 metric.style.opacity = index === 0 ? '1' : '0'; 3208 }); 3209 3210 // Animation loop 3211 let current = 0; 3212 setInterval(() => { 3213 const next = (current + 1) % metrics.length; 3214 3215 // Fade out current, fade in next 3216 metrics[current].style.opacity = '0'; 3217 metrics[next].style.opacity = '1'; 3218 3219 // Change width 3220 wrapper.style.width = widths[next] + 'px'; 3221 3222 current = next; 3223 }, 4000); 3224 }); 3225 } 3226 3227 function syncSelectors(firstSelectorId, secondSelectorId) { 3228 const select1 = document.getElementById(firstSelectorId); 3229 const select2 = document.getElementById(secondSelectorId); 3230 3231 if (select1 && select2) { 3232 select1.addEventListener('change', function () { 3233 select2.value = this.value; 3234 }); 3235 3236 select2.addEventListener('change', function () { 3237 select1.value = this.value; 3238 }); 3239 } 3240 } 3241 3242 function stopPropagation(event) { 3243 event.stopPropagation(); 3244 } 3245 3246 function fullScreen(elementId, clickedButton) { 3247 const element = document.getElementById(elementId); 3248 3249 if (element) { 3250 const closeText = clickedButton.dataset.textClose; 3251 const openText = clickedButton.dataset.textOpen; 3252 3253 if (element.classList.contains('full-screen')) { 3254 const labelElement = clickedButton.querySelector('.js-button-label'); 3255 if (labelElement) { 3256 labelElement.innerText = openText; 3257 } 3258 element.classList.remove('full-screen'); 3259 } else { 3260 const labelElement = clickedButton.querySelector('.js-button-label'); 3261 if (labelElement) { 3262 labelElement.innerText = closeText; 3263 } 3264 element.classList.add('full-screen'); 3265 } 3266 } 3267 } 3268 3269 function checkIfStuck(stickyElementSelector) { 3270 const stickyElement = document.querySelector(stickyElementSelector); 3271 const stickyTop = parseInt(getComputedStyle(stickyElement).top) || 0; 3272 3273 const observer = new IntersectionObserver( 3274 ([entry]) => { 3275 const targetTop = entry.boundingClientRect.top; 3276 3277 if (targetTop <= stickyTop) { 3278 stickyElement.classList.add('is-stuck'); 3279 } else { 3280 stickyElement.classList.remove('is-stuck'); 3281 } 3282 }, 3283 { 3284 threshold: [1], 3285 rootMargin: `-${stickyTop + 1}px 0px 0px 0px` 3286 } 3287 ); 3288 3289 observer.observe(stickyElement); 3290 } 3291 3292 function initHiddenStickyElements(stickyElementId, triggerElementId) { 3293 const stickyElement = document.getElementById(stickyElementId); 3294 const sentinel = document.getElementById(triggerElementId); 3295 3296 if (stickyElement && sentinel) { 3297 const observer = new IntersectionObserver((entries) => { 3298 entries.forEach(entry => { 3299 if (entry.boundingClientRect.top <= 0) { 3300 stickyElement.classList.add('visible'); 3301 } else { 3302 stickyElement.classList.remove('visible'); 3303 } 3304 }); 3305 }, { 3306 threshold: 1, 3307 rootMargin: '0px' 3308 }); 3309 3310 observer.observe(sentinel); 3311 } 3312 else { 3313 console.debug("Elements not found in initHiddenStickyElements using stickyElementId: ", stickyElementId, " and triggerElementId: ", triggerElementId); 3314 } 3315 } 3316 3317 function shareProperty(event, clickedButton) { 3318 event.preventDefault(); 3319 3320 const shareData = { 3321 title: document.title, 3322 text: clickedButton.dataset.shareText, 3323 url: window.location.href 3324 }; 3325 3326 if (navigator.share && navigator.canShare && navigator.canShare(shareData)) { 3327 navigator.share(shareData); 3328 } else { 3329 navigator.clipboard.writeText(window.location.href).then(() => { 3330 const alertText = clickedButton.dataset.alertText || 'Link copied to clipboard!'; 3331 alert(alertText); 3332 }); 3333 } 3334 } 3335 3336 function scrollToElementById(id, block = "start") { 3337 var element = document.getElementById(id); 3338 if (element) { 3339 element.scrollIntoView({ behavior: "smooth", block: block, container: "nearest" }); 3340 } 3341 } 3342 3343 function scrollGalleryToImage(imageId) { 3344 const image = document.getElementById(imageId); 3345 if (!image) return; 3346 3347 const gallery = image.closest('.image-gallery'); 3348 if (!gallery) return; 3349 3350 // Get position relative to gallery 3351 const imageRect = image.getBoundingClientRect(); 3352 const galleryRect = gallery.getBoundingClientRect(); 3353 const scrollOffset = imageRect.top - galleryRect.top + gallery.scrollTop; 3354 3355 gallery.scrollTo({ 3356 top: scrollOffset, 3357 behavior: "smooth" 3358 }); 3359 } 3360 3361 function initImageNavigation(parentSelector, options = {}) { 3362 // Default configuration 3363 const config = { 3364 imageSelector: 'img', 3365 nextButtonId: 'image-next', 3366 prevButtonId: 'image-prev', 3367 buttonIdPostFix: '', 3368 storageKey: 'currentImageIndex_' + parentSelector, 3369 threshold: 0.8, 3370 scrollBehavior: 'smooth', 3371 scrollDirection: 'vertical', // 'vertical' or 'horizontal' 3372 overflowWrapperSelector: '', 3373 ...options 3374 }; 3375 3376 // Get parent element 3377 const parent = document.querySelector(parentSelector); 3378 3379 if (!parent) { 3380 console.warn(`Parent element "${parentSelector}" not found`); 3381 return null; 3382 } 3383 3384 // Get images within parent 3385 const images = parent.querySelectorAll(config.imageSelector); 3386 if (images.length === 0) { 3387 console.warn(`No images found in "${parentSelector}"`); 3388 return null; 3389 } 3390 3391 let currentVisibleIndex = 0; 3392 let lastDirection = null; // Track navigation direction: 'forward' or 'backward' 3393 let visibleIndices = new Set(); // Persistent set of all visible image indices 3394 3395 // Set up Intersection Observer 3396 const observer = new IntersectionObserver((entries) => { 3397 // Update the set based on what changed 3398 entries.forEach(entry => { 3399 const index = Array.from(images).indexOf(entry.target); 3400 3401 if (entry.isIntersecting) { 3402 visibleIndices.add(index); 3403 } else { 3404 visibleIndices.delete(index); 3405 } 3406 }); 3407 3408 if (visibleIndices.size > 0) { 3409 const visibleArray = Array.from(visibleIndices); 3410 3411 // Check for boundary cases first 3412 if (visibleIndices.has(images.length - 1)) { 3413 // Last image is visible - set to MIN (prepare for backward movement) 3414 currentVisibleIndex = Math.min(...visibleArray); 3415 lastDirection = 'backward'; 3416 } else if (visibleIndices.has(0)) { 3417 // First image is visible - set to MAX (prepare for forward movement) 3418 currentVisibleIndex = Math.max(...visibleArray); 3419 lastDirection = 'forward'; 3420 } else { 3421 // Middle of the list - use direction logic 3422 if (lastDirection === 'forward') { 3423 currentVisibleIndex = Math.max(...visibleArray); 3424 } else if (lastDirection === 'backward') { 3425 currentVisibleIndex = Math.min(...visibleArray); 3426 } else { 3427 // Default to min when no direction set (initial load) 3428 currentVisibleIndex = Math.min(...visibleArray); 3429 } 3430 } 3431 3432 if (config.storageKey) { 3433 localStorage.setItem(config.storageKey, currentVisibleIndex); 3434 } 3435 3436 updateButtonStates(); 3437 } 3438 }, { 3439 root: null, 3440 threshold: config.threshold 3441 }); 3442 3443 // Observe all images 3444 images.forEach(img => observer.observe(img)); 3445 3446 function updateButtonStates() { 3447 const wrapper = document.querySelector(config.overflowWrapperSelector); 3448 const hasOverflow = wrapper ? wrapper.scrollWidth > wrapper.clientWidth : true; 3449 3450 const nextButton = parent.querySelector('#' + config.nextButtonId + config.buttonIdPostFix); 3451 const prevButton = parent.querySelector('#' + config.prevButtonId + config.buttonIdPostFix); 3452 if (nextButton) { 3453 // Disable if last image is visible 3454 if (visibleIndices.has(images.length - 1) || !hasOverflow) { 3455 nextButton.classList.add('disabled'); 3456 } else { 3457 nextButton.classList.remove('disabled'); 3458 } 3459 } 3460 3461 if (prevButton) { 3462 // Disable if first image is visible 3463 if (visibleIndices.has(0) || !hasOverflow) { 3464 prevButton.classList.add('disabled'); 3465 } else { 3466 prevButton.classList.remove('disabled'); 3467 } 3468 } 3469 } 3470 3471 // Helper function to scroll to specific image 3472 function scrollToImage(index, direction) { 3473 if (index >= 0 && index < images.length) { 3474 lastDirection = direction; 3475 3476 const scrollOptions = { 3477 behavior: config.scrollBehavior 3478 }; 3479 3480 // Set scroll alignment based on direction 3481 if (config.scrollDirection === 'horizontal') { 3482 scrollOptions.inline = 'start'; 3483 scrollOptions.block = 'nearest'; 3484 } else { 3485 scrollOptions.block = 'start'; 3486 scrollOptions.inline = 'nearest'; 3487 } 3488 3489 images[index].scrollIntoView(scrollOptions); 3490 currentVisibleIndex = index; 3491 3492 if (config.storageKey) { 3493 localStorage.setItem(config.storageKey, index); 3494 } 3495 3496 updateButtonStates(); 3497 } 3498 } 3499 3500 // Set up navigation buttons 3501 const nextButton = parent.querySelector('#' + config.nextButtonId + config.buttonIdPostFix); 3502 const prevButton = parent.querySelector('#' + config.prevButtonId + config.buttonIdPostFix); 3503 3504 const handleNext = () => { 3505 const nextIndex = Math.min(currentVisibleIndex + 1, images.length - 1); 3506 scrollToImage(nextIndex, 'forward'); 3507 }; 3508 3509 const handlePrev = () => { 3510 const prevIndex = Math.max(currentVisibleIndex - 1, 0); 3511 scrollToImage(prevIndex, 'backward'); 3512 }; 3513 3514 if (nextButton) { 3515 nextButton.addEventListener('click', handleNext); 3516 } else { 3517 console.warn(`Next button "${config.nextButtonId}" not found`); 3518 } 3519 3520 if (prevButton) { 3521 prevButton.addEventListener('click', handlePrev); 3522 } else { 3523 console.warn(`Prev button "${config.prevButtonId}" not found`); 3524 } 3525 3526 // Initialize button states 3527 updateButtonStates(); 3528 } 3529 3530 /** 3531 * Initialize keyboard navigation for image thumbnails 3532 * Allows navigation with ArrowUp/ArrowDown keys 3533 * Wraps around from last to first and vice versa 3534 * Uses checked radio state and data-index for navigation 3535 */ 3536 function initThumbnailKeyboardNav() { 3537 const container = document.querySelector('.js-image-thumbnails'); 3538 if (!container) return; 3539 3540 const thumbnails = container.querySelectorAll('.js-thumbnail-radio'); 3541 if (!thumbnails.length) return; 3542 3543 // Get current index from checked radio button 3544 function getCurrentIndex() { 3545 const checkedRadio = container.querySelector('input[type="radio"]:checked'); 3546 if (checkedRadio) { 3547 const label = checkedRadio.closest('.js-thumbnail-radio'); 3548 return parseInt(label.dataset.index, 10) || 0; 3549 } 3550 return 0; 3551 } 3552 3553 // Navigate to thumbnail by index 3554 function navigateToIndex(index) { 3555 const targetLabel = container.querySelector('.js-thumbnail-radio[data-index="' + index + '"]'); 3556 if (targetLabel) { 3557 targetLabel.click(); 3558 } 3559 } 3560 3561 // Listen for keyboard navigation on the container 3562 container.addEventListener('keydown', (e) => { 3563 const currentIndex = getCurrentIndex(); 3564 const totalThumbnails = thumbnails.length; 3565 let newIndex; 3566 3567 if (e.key === 'ArrowDown' || e.key === 'ArrowRight') { 3568 e.preventDefault(); 3569 // Wrap to first if at end 3570 newIndex = currentIndex >= totalThumbnails - 1 ? 0 : currentIndex + 1; 3571 navigateToIndex(newIndex); 3572 } else if (e.key === 'ArrowUp' || e.key === 'ArrowLeft') { 3573 e.preventDefault(); 3574 // Wrap to last if at beginning 3575 newIndex = currentIndex <= 0 ? totalThumbnails - 1 : currentIndex - 1; 3576 navigateToIndex(newIndex); 3577 } else if (e.key === 'Home') { 3578 e.preventDefault(); 3579 navigateToIndex(0); 3580 } else if (e.key === 'End') { 3581 e.preventDefault(); 3582 navigateToIndex(totalThumbnails - 1); 3583 } 3584 }); 3585 } 3586 3587 function handleError(img) { 3588 const fallback = img.dataset.fallback; 3589 if (fallback.length) { 3590 img.src = fallback; 3591 } 3592 } 3593 </script> 3594 @*Video Autoplay fallback*@ 3595 <script defer> 3596 const video = document.querySelector('.js-primary-video'); 3597 if (video) { 3598 video.play().then(() => { 3599 // Autoplay worked 3600 }).catch((error) => { 3601 // Autoplay was blocked 3602 // Show a play button 3603 showPlayButton(); 3604 }); 3605 } 3606 </script> 3607 3608 @*INPUT FIELDS FOR SPECIFIC JAVASCRIPT*@ 3609 @if (!bolig.Solgt && propBroker != null && brokerItem != null) 3610 { 3611 <input type="hidden" class="js-broker-radio-val" value="@Converter.ToString(brokerItem["CBMedlemsnummer"])" /> 3612 <input type="hidden" class="js-broker-image-val js-maegler-img-val" value="@HtmlEncoder.HtmlAttributeEncode(propBroker.Broker.GeolocationIcon.ToString())" /> 3613 <input type="hidden" class="js-choose-broker-address-val" value="@HtmlEncoder.HtmlAttributeEncode(propBroker.Broker.Address)" /> 3614 <input type="hidden" class="js-choose-broker-zip-val" value="@propBroker.Broker.ZipCode" /> 3615 <input type="hidden" class="js-choose-broker-name-val js-maegler-name-val" value="@HtmlEncoder.HtmlAttributeEncode(propBroker.Broker.CompanyName)" /> 3616 <input type="hidden" class="js-maegler-mail-val" value="@Converter.ToString(brokerItem["Email"])" /> 3617 <input type="hidden" class="js-maegler-phone-val" value="@propBroker.Broker.Telephone" /> 3618 <input type="hidden" class="js-updatebroker-list-val" value="@GetString("Ecom:Product:Field.xEjendomAdressePostnummer")" /> 3619 } 3620 3621 @if (settingsItem != null && !string.IsNullOrEmpty(settingsItem["Leadhub_Pixel_ID"].ToString())) 3622 { 3623 string offeringType = "sale"; 3624 if (GetString("Ecom:Product:Field.xUdbudsForm") == "Leje") 3625 { 3626 offeringType = "rent"; 3627 } 3628 <script> 3629 lhi('viewContent', { 3630 content_name: '@HtmlEncoder.JavaScriptStringEncode(GetString("Ecom:Product:Field.xEjendomAdresseAdresseLinie")), @HtmlEncoder.JavaScriptStringEncode(GetString("Ecom:Product:Field.xEjendomAdressePostAdresseLinie"))', 3631 content_ids: ['@productId'], 3632 content_type: 'product', 3633 value: @priceWithDecimal, 3634 currency: 'DKK' 3635 }); 3636 lhi('addTag', { 3637 type: 'ViewProperty', 3638 price: @priceWithDecimal, 3639 propertyType: '@propTypeDisplay', 3640 city: '@GetString("Ecom:Product:Field.xEjendomAdressePostDistrikt")', 3641 offeringType: '@offeringType', 3642 @if (hasMapCoordinates) 3643 { 3644 @:lat: @mapLat, 3645 @:lon: @mapLng, 3646 } 3647 squareMeters: @GetString("Ecom:Product:Field.xEjendomArealerBoligAreal") 3648 }); 3649 </script> 3650 } 3651 3652 @if (settingsItem != null && Convert.ToBoolean(settingsItem["UseOptinMonster"])) 3653 { 3654 <!-- This site is converting visitors into subscribers and customers with OptinMonster - https://optinmonster.com --> 3655 <script type="text/javascript" src="https://a.optmnstr.com/app/js/api.min.js" data-campaign="x2jkobozynuz9fbczh7c" data-user="42632" async=async></script><!-- / https://optinmonster.com --> 3656 } 3657 @SnippetEnd("JavaScriptBottom") 3658 3659 @{ 3660 var productName = StripHtml(GetString("Ecom:Product.Name")); 3661 var shortDescription = StripHtml(GetString("Ecom:Product.ShortDescription")); 3662 var areaName = StripHtml(GetString("Ecom:Product:Area.Name")); 3663 3664 Pageview.Meta.Title = string.IsNullOrEmpty(shortDescription) 3665 ? $"{productName} - {areaName}" 3666 : $"{productName} - {SetMaxLength(shortDescription, 75)} - {areaName}"; 3667 }