RealMæglerne Virum og Holte v/ Oliver Rannje
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&deg;")</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&deg;")</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&deg;")</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&sup2") 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&sup2") 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&sup2")</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&sup2")</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&sup2")</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&sup2")</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&sup2")</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&reg;") 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.%+-]+&#64;[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.%+-]+&#64;[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.%+-]+&#64;[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 }
Fandt du ikke det du søgte? - Opret dig som bruger og få mere ud af din boligsøgning
Dit RealMæglerne

Log ind på RealMæglernes Boligagent

Med Mit RealMæglerne er det nemt at følge boligmarkedet. Leder du efter nyt, kan du gemme dine favorit boliger og målrette din søgning ned til mindste detalje. Skal du sælge, kan du løbende følge interessen for din bolig og meget mere.


Kontakt Mægler

Din bolig

* 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 info@realmaeglerne.dk. Læs mere på privatlivspolitikkerne.

Tilmeld til åbent hus

Adresse:
Dato:
Tidspunkt:

Kontakt Mægler

* 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 info@realmaeglerne.dk. Læs mere på privatlivspolitikkerne.

Bestil gratis salgsvurdering

Din bolig

Send salgsvurdering til:

Vælg mægler

* 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 info@realmaeglerne.dk. Læs mere på privatlivspolitikkerne.

Bestil gratis salgsvurdering

Din bolig

Send salgsvurdering til:

Vælg mægler

* 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 info@realmaeglerne.dk. Læs mere på privatlivspolitikkerne.