ESG, climate & biodiversity

Dalgas is an international company with broad expertise in the green sector. With headquarters in Denmark, there are services offered exclusively within Danish borders. Here on this page, you will find an overview of the services we offer in Denmark within ESG, climate, and biodiversity. 

Nature-based solutions 

The world is facing an acute climate and biodiversity crisis that threatens our ecosystems, livelihoods, and the well-being of future generations. These challenges require action and innovative solutions to ensure a sustainable future.

At Dalgas, we work with companies to take active leadership that makes a real difference by restoring ecosystems – we call it nature-based solutions. 

Biodiversity 

Biodiversity is an essential part of our work at Dalgas. To ensure high professionalism, biodiversity is always supported by measurements, documentation, and evidence. We have experts working broadly with biodiversity in urban areas, landscapes, forests, and the sea.

Therefore, we make professional, intelligent choices about elements, native species, initiatives, and management so that biodiversity projects achieves the desired effect on the area's natural value. 

ESG reporting 

We help realise ambitious nature projects and create visible results that strengthen the company's ESG profile.

We also work with monitoring and data collection so that your company has a reliable data basis for use in ESG reporting. 

End-to-end project solutions 

We offer a complete end-to-end service covering all phases of ecosystem restoration projects. And our commitment does not stop at the project's conclusion.

We offer long-term maintenance and follow-up strategies, ensuring sustainable results over time and the flexibility to adapt projects based on monitoring data and new research findings. 

Space for more life 

We enhance natural value and create space for more life throughout Denmark. We offer strategic and practical solutions for green areas, where we combine recreational spaces with natural habitats.

We assist in converting, managing, or establishing new areas with native plants, insect hotels, and rainwater basins. This makes room for more life. 

Error executing template "/Designs/Swift/Grid/Page/RowTemplates/Dalgas_Slider.cshtml"
System.ArgumentException: An item with the same key has already been added.
   at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at Dalgas.Custom.Services.ContentRelationService.GetRelatedPagesByUrlAndParameters(String url, List`1 parameters, Int32 pageSize) in D:\a\1\s\Custom\Services\ContentRelationService.cs:line 81
   at Dalgas.Custom.Services.ContentRelationService.GetCaseCustomerStoriesByCurrentPage(Int32 pageSize) in D:\a\1\s\Custom\Services\ContentRelationService.cs:line 631
   at CompiledRazorTemplates.Dynamic.RazorEngine_763d294069f74252964c7daaece1d669.Execute() in D:\solutions\dalgas-production\Files\Templates\Designs\Swift\Grid\Page\RowTemplates\Dalgas_Slider.cshtml:line 140
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<GridRowViewModel> 2 @using System 3 @using System.Collections.Generic 4 @using System.Linq 5 @using System.Web 6 @using Dalgas.Custom.Models.Content 7 @using Dalgas.Custom.Services 8 @using Dalgas.Custom.ViewModels.UI 9 @using Dynamicweb.Content 10 @using Dynamicweb.Frontend 11 @using Dynamicweb.Ecommerce.ProductCatalog 12 @using Page = Dynamicweb.Content.Page 13 14 @using System 15 @using System.Collections.Generic 16 @using System.Linq 17 @using Dalgas.Custom.ViewModels.UI 18 @using Dynamicweb.Content 19 @using Dynamicweb.Ecommerce.ProductCatalog 20 @using Dynamicweb.Frontend 21 @using ParagraphService = Dalgas.Custom.Services.ParagraphService 22 23 @*TODO: Move these functions onto the model *@ 24 25 @functions 26 { 27 28 public string GetSectionClassList(GridRowViewModel model, string overwriteTheme = "") 29 { 30 var returnValues = new List<string> 31 { 32 $"item_{model.Item.SystemName.ToLower()}" 33 }; 34 35 if (Services.Grids.GetGridRowById(model.Id).Sort == 1) 36 { 37 returnValues.Add("dalgas-section-first-on-page"); 38 } 39 40 var sectionBackgroundTheme = model.Item.GetItem("ColorScheme")?.GetString("ColorScheme") ?? string.Empty; 41 42 if (!string.IsNullOrEmpty(overwriteTheme)) 43 { 44 sectionBackgroundTheme = overwriteTheme; 45 } 46 47 // Add theme class if it exists 48 if (!string.IsNullOrWhiteSpace(sectionBackgroundTheme)) 49 { 50 if (sectionBackgroundTheme.Contains("default")) 51 { 52 returnValues.Add("theme theme-light"); 53 } 54 else 55 { 56 returnValues.Add($"theme {sectionBackgroundTheme.Replace(" ", "").Trim().ToLower()}"); 57 } 58 } 59 60 // Determine if top padding should be removed 61 62 string removeTopPadding = model.Item.GetItem("ColorScheme")?.GetString("RemoveTopPadding"); 63 64 returnValues.Add("pb-6"); 65 if (removeTopPadding != "enable") 66 { 67 returnValues.Add("pt-6"); 68 } 69 70 return string.Join(" ", returnValues); 71 } 72 73 } 74 75 76 @{ 77 IEnumerable<HeadingViewModel> headings = ParagraphService.Instance.GetHeadingsByItems(Model.Item?.GetItem("Paragraph_Text")?.GetItems("Headings")); 78 string text = Model.Item.GetItem("Paragraph_Text")?.GetString("Text"); 79 string lead = Model.Item.GetItem("Paragraph_Text")?.GetString("Lead"); 80 IEnumerable<ButtonViewModel> buttons = ParagraphService.Instance.GetButtonsByItems(Model.Item?.GetItem("Paragraph_Text")?.GetItems("Buttons")); 81 82 bool hasImage = Model.Item.GetItem("Paragraph_Image")?.GetFile("Image") != null; 83 bool hasText = !string.IsNullOrEmpty(Model.Item?.GetItem("Paragraph_Text")?.GetString("Text")); 84 bool hasLead = !string.IsNullOrEmpty(Model.Item?.GetItem("Paragraph_Text")?.GetString("Lead")); 85 bool hasHeading = headings.Any(); 86 bool hasButton = buttons.Any(); 87 88 var theme = Model.Item.GetItem("ColorScheme")?.GetString("ColorScheme"); 89 var fifthElementTheme = "fifth-element-color-" + Model.Item?.GetItem("ColorScheme")?.GetString("FifthElementColor"); 90 91 var sectionClassList = GetSectionClassList(Model); 92 93 var image = string.Empty; 94 var imageParameters = new Dictionary<string, object>(); 95 96 string layout = string.Empty; 97 Boolean enableFifthElement = false; 98 if (Model?.Item != null) 99 { 100 var paragraphLayout = Model.Item.GetItem("Paragraph_Layout"); 101 102 if (paragraphLayout != null) 103 { 104 layout = paragraphLayout.GetString("Layout"); 105 106 enableFifthElement = !string.IsNullOrEmpty(paragraphLayout.GetString("Layout_FifthElement")); 107 } 108 } 109 110 if (!string.IsNullOrEmpty(Model.Item?.GetItem("Paragraph_Image")?.GetFile("Image")?.Path)) 111 { 112 image = Model.Item.GetItem("Paragraph_Image").GetFile("Image").Path; 113 imageParameters.Add("alt", Model.Item.GetItem("Paragraph_Image")?.GetString("ImageAltText")); 114 int xPos = Model.Item.GetItem("Paragraph_Image").GetFile("Image")?.FocalPositionFromLeft ?? 50; 115 int yPos = Model.Item.GetItem("Paragraph_Image").GetFile("Image")?.FocalPositionFromTop ?? 50; 116 string cssPosition = $"{xPos}% {yPos}%"; 117 imageParameters.Add("style", "object-position:" + cssPosition); 118 } 119 120 LinkViewModel imageLink = new LinkViewModel(); 121 if (Model.Item?.GetItem("Paragraph_Image")?.GetItem("Link") != null && !string.IsNullOrEmpty(Model?.Item?.GetItem("Paragraph_Image")?.GetItem("Link").GetString("ButtonLink"))) 122 { 123 imageLink = ParagraphService.Instance.GetLinkByItem(Model?.Item?.GetItem("Paragraph_Image")?.GetItem("Link")); 124 } 125 126 string fifthElementIconPath = "/Files/Templates/Designs/Swift/Assets/Images/DalgasFifthElements/"; 127 } 128 129 130 @{ 131 string strTitle = string.Empty; 132 string strSummary = string.Empty; 133 string strImage = string.Empty; 134 string strLink = string.Empty; 135 DateTime strDate = new DateTime(); 136 137 var sliderTheme = Model.Item.GetString("SliderColorScheme"); 138 Page currentPage = PageView.Current().Page; 139 140 var queryResult = ContentRelationService.Instance.GetCaseCustomerStoriesByCurrentPage(); 141 142 var contentType = Model.Item.GetItem("Content")?.GetString("Content"); 143 144 if (contentType == "news") 145 { 146 queryResult = ContentRelationService.Instance.GetNewsByCurrentPage(); 147 } 148 149 object pageParentPageIdValue = null; 150 151 IList<ItemViewModel> sliderItems = Model.Item?.GetItem("Content")?.GetItems("Items") ?? Enumerable.Empty<ItemViewModel>().ToList(); 152 153 // Fetch PageParentPageId from queryResult 154 if (!sliderItems.Any() && queryResult != null && queryResult.Results.Any()) 155 { 156 pageParentPageIdValue = queryResult.Results.FirstOrDefault(dict => dict.ContainsKey("PageParentPageId"))?["PageParentPageId"]; 157 } 158 159 // Fetch PageParentPageId from sliderItems if it wasn't set by queryResult 160 if (pageParentPageIdValue == null && Model.Item != null && sliderItems.Any()) 161 { 162 string linkString = sliderItems?.FirstOrDefault()?.GetString("Link"); 163 164 if (!string.IsNullOrEmpty(linkString) && int.TryParse(linkString, out int sliderItemLink)) 165 { 166 int sliderItemParentPage = Services.Pages.GetPage(sliderItemLink).ParentPageId; 167 pageParentPageIdValue = sliderItemParentPage; 168 } 169 else 170 { 171 // Handle the case where linkString is not a valid integer or is null/empty 172 pageParentPageIdValue = null; // or assign a default value or handle error 173 } 174 } 175 176 ButtonViewModel btnViewModelViewAll = new ButtonViewModel 177 { 178 Id = "pageId_", 179 Url = "/Default.aspx?ID=" + pageParentPageIdValue, 180 Text = Translate("View all"), 181 Type = ButtonType.Link, 182 DisplayType = ButtonDisplayType.Secondary 183 }; 184 } 185 186 @{ 187 bool showImageOnly = true; // Assume showImageOnly is true initially 188 189 List<FileViewModel> imageList = new List<FileViewModel>(); // List to hold images for the modal 190 191 // Check if any title exists 192 var items = sliderItems.Any() ? sliderItems.Cast<object>() : queryResult.Results.Cast<object>(); 193 194 foreach (var item in items) 195 { 196 var resultDictionary = item as Dictionary<string, object>; 197 Page page = null; 198 if (resultDictionary != null && resultDictionary.TryGetValue("PageId", out object pageIdObj)) 199 { 200 if (int.TryParse(pageIdObj.ToString(), out int resultPageId)) 201 { 202 page = Services.Pages.GetPage(resultPageId); 203 } 204 } 205 206 string title = item is ItemViewModel sliderItem 207 ? sliderItem.GetString("Title") 208 : page?.Item["Title"].ToString(); 209 210 if (!string.IsNullOrEmpty(title)) 211 { 212 showImageOnly = false; 213 break; 214 } 215 } 216 217 FileViewModel sliderImage; 218 } 219 220 @if (queryResult.Results.Any() || sliderItems.Count > 0) 221 { 222 <section id="section-@Model.Id" class="@sectionClassList" data-swift-gridrow> 223 <div class="container-xl"> 224 <div class="row justify-content-center"> 225 <div class="col-12 col-lg-10"> 226 <div class="row"> 227 <div class="col-12 col-lg-6 mb-4"> 228 @if (!string.IsNullOrEmpty(Model.Item.GetItem("Content").GetString("Title"))) 229 { 230 <h2 class="mb-0 mb-lg-5">@Model.Item.GetItem("Content").GetString("Title")</h2> 231 } 232 @if (queryResult.Results.Count > 1 || sliderItems.Count > 1) 233 { 234 <div class="d-none d-lg-flex gap-3"> 235 <button type="button" title="@Translate("Previous slide")" class="dalgas-swiper-button-prev" style="z-index:1;"> 236 <span class="visually-hidden">@Translate("Previous slide")</span> 237 </button> 238 <button type="button" title="@Translate("Next slide")" class="dalgas-swiper-button-next" style="z-index:1;"> 239 <span class="visually-hidden">@Translate("Next slide")</span> 240 </button> 241 @if (showImageOnly) 242 { 243 <button type="button" class="btn btn-link no-arrow ms-2" data-bs-toggle="modal" data-bs-target="#imageOnlyModal"> 244 @Translate("View all images", "Se alle billeder") 245 </button> 246 } 247 </div> 248 } 249 </div> 250 <div class="col-12 col-lg-6 mb-4 d-inline-flex justify-content-end align-items-end d-none d-lg-flex"> 251 252 @if (sliderItems.Any() && !showImageOnly && contentType != "manual" || queryResult.Results.Any() && !showImageOnly && contentType != "manual") 253 { 254 @RenderModel(btnViewModelViewAll) 255 } 256 </div> 257 <div class="swiper-container row" data-show-image-only="@showImageOnly.ToString().ToLower()" data-normal-slider="true" data-initialized="false"> 258 <div class="swiper-wrapper"> 259 @{ 260 string slideButtonText = Translate("View the case story"); 261 if (contentType == "news") 262 { 263 slideButtonText = Translate("Read this news", "Læs nyheden"); 264 } else if (contentType == "manual") 265 { 266 slideButtonText = Translate("Read more", "Read more"); 267 } 268 269 ButtonViewModel btnViewResult = new ButtonViewModel 270 { 271 Text = slideButtonText, 272 Type = ButtonType.Link, 273 DisplayType = ButtonDisplayType.Secondary 274 }; 275 276 foreach (var result in items.Select((item, index) => new {Item = item, Index = index + 1})) 277 { 278 strTitle = string.Empty; 279 strSummary = string.Empty; 280 strImage = string.Empty; 281 strLink = string.Empty; 282 283 if (sliderItems.Any()) 284 { 285 var sliderItem = result.Item as ItemViewModel; 286 strTitle = sliderItem.GetString("Title"); 287 strSummary = sliderItem.GetString("Summary"); 288 strImage = sliderItem.GetString("Image"); 289 strLink = sliderItem.GetString("Link"); 290 btnViewResult.Id = "pageId_" + strLink; 291 if (strLink.Contains("https")) 292 { 293 btnViewResult.Url = strLink; 294 } 295 else 296 { 297 btnViewResult.Url = "/Default.aspx?ID=" + strLink; 298 } 299 } 300 else if (queryResult.Results.Any()) 301 { 302 var resultDictionary = result.Item as Dictionary<string, object>; 303 if (resultDictionary != null && resultDictionary.TryGetValue("PageId", out var pageIdObj) && int.TryParse(pageIdObj.ToString(), out int resultPageId)) 304 { 305 Page page = Services.Pages.GetPage(resultPageId); 306 strTitle = page.Item["Title"]?.ToString(); 307 strSummary = page.Item["Summary"]?.ToString(); 308 strImage = page.Item["CoverImage"] == null ? string.Empty : page.Item["CoverImage"]?.ToString(); 309 btnViewResult.Id = "pageId_" + resultPageId; 310 btnViewResult.Url = "/Default.aspx?ID=" + resultPageId; 311 if (page.Item["Date"] != null) 312 { 313 strDate = (DateTime) page.Item["Date"]; 314 } 315 } 316 } 317 318 int jpgIndex = strImage.IndexOf(".jpg", StringComparison.OrdinalIgnoreCase); 319 if (jpgIndex != -1) 320 { 321 strImage = strImage.Substring(0, jpgIndex + 4); 322 } 323 324 sliderImage = ViewModelFactory.CreateFieldFileValueView(strImage); 325 326 imageList.Add(sliderImage); // Add image to the list for the modal 327 328 329 <div class="swiper-slide d-flex flex-column"> 330 <div class="d-flex flex-column flex-column-reverse flex-md-row h-100"> 331 @if (showImageOnly == false) 332 { 333 <div class="col-md-6 theme @sliderTheme p-4 pt-5 p-lg-5 d-flex flex-column justify-content-between h-100"> 334 335 <div class="theme"> 336 @if (Model.Item.GetItem("Content").GetString("Content") == "news") 337 { 338 if (strDate != null) 339 { 340 var date = strDate; 341 var formattedDate = date.ToLongDateString(); 342 343 <div class="badge mb-5"> 344 @formattedDate 345 </div> 346 } 347 } 348 <h3> 349 <a class="text-decoration-none" href="@btnViewResult.Url">@strTitle</a> 350 </h3> 351 <p class="small">@strSummary</p> 352 </div> 353 <div> 354 @RenderModel(btnViewResult) 355 </div> 356 </div> 357 } 358 <div class="@(showImageOnly == false ? "col-md-6" : "col-md-12")"> 359 @if (showImageOnly) 360 { 361 <a href="#" data-bs-toggle="modal" data-bs-target="#imageOnlyModal"> 362 <figure class="ratio ratio-16x9 ratio-lg-4x3 h-100"> 363 @RenderPartial("Components/Image.cshtml", sliderImage ?? new FileViewModel()) 364 </figure> 365 </a> 366 } 367 else 368 { 369 <a href="@btnViewResult.Url"> 370 <figure class="ratio ratio-16x9 ratio-lg-4x3 h-100"> 371 @RenderPartial("Components/Image.cshtml", sliderImage ?? new FileViewModel()) 372 </figure> 373 </a> 374 } 375 </div> 376 </div> 377 <div class="d-flex pagination mt-3"> 378 @result.Index/@items.Count() 379 </div> 380 </div> 381 } 382 } 383 </div> 384 </div> 385 </div> 386 </div> 387 </div> 388 </div> 389 </section> 390 } 391 else 392 { 393 if (Pageview.IsVisualEditorMode) 394 { 395 <div class="container-xl alert alert-danger" role="alert"> 396 This <strong>@Model.Item.SystemName</strong> is empty 397 </div> 398 } 399 } 400 401 @if (showImageOnly) 402 { 403 <div class="modal fade" id="imageOnlyModal" tabindex="-1" aria-labelledby="imageOnlyModalLabel" aria-hidden="true" data-lenis-prevent> 404 <div class="modal-dialog modal-fullscreen"> 405 <div class="modal-content"> 406 <div class="modal-header"> 407 <h4 class="modal-title">@PageView.Current().Item["Title"]</h4> 408 <button type="button" class="btn" data-bs-dismiss="modal" aria-label="Close"> 409 @{ 410 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/dalgas/x.svg"; 411 412 if (!iconPath.ToLower().Contains("none") && iconPath != "") 413 { 414 <span class="icon-3 pe-none"> 415 @ReadFile(iconPath) 416 </span> 417 } 418 } 419 </button> 420 </div> 421 <div class="modal-body"> 422 <div class="masonry-container"> 423 @for (int i = 0; i < imageList.Count; i++) 424 { 425 <figure class="masonry-item"> 426 @RenderPartial("Components/Image.cshtml", imageList[i]) 427 </figure> 428 } 429 </div> 430 </div> 431 </div> 432 </div> 433 </div> 434 } 435
Error executing template "/Designs/Swift/Grid/Page/RowTemplates/Dalgas_Contact.cshtml"
System.ArgumentException: An item with the same key has already been added.
   at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at Dalgas.Custom.Services.ContentRelationService.GetRelatedContactsByUrlAndParameters(String url, List`1 parameters, Int32 pageSize) in D:\a\1\s\Custom\Services\ContentRelationService.cs:line 274
   at CompiledRazorTemplates.Dynamic.RazorEngine_1b6bf2805152485cb56967df9f7aef6d.Execute() in D:\solutions\dalgas-production\Files\Templates\Designs\Swift\Grid\Page\RowTemplates\Dalgas_Contact.cshtml:line 179
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.GridRowViewModel> 2 @using System 3 @using System.Collections.Generic 4 @using System.Linq 5 @using System.Text.RegularExpressions 6 @using Dalgas.Custom.Extensions 7 @using Dalgas.Custom.Models.Content 8 @using Dalgas.Custom.Services 9 @using Dalgas.Custom.ViewModels.UI 10 @using Dynamicweb.Core.Encoders 11 @using Dynamicweb.Core.Json 12 @using Dynamicweb.Ecommerce.ProductCatalog 13 @using Dynamicweb.Frontend 14 @using Dynamicweb.Security.UserManagement 15 16 @using System 17 @using System.Collections.Generic 18 @using System.Linq 19 @using Dalgas.Custom.ViewModels.UI 20 @using Dynamicweb.Content 21 @using Dynamicweb.Ecommerce.ProductCatalog 22 @using Dynamicweb.Frontend 23 @using ParagraphService = Dalgas.Custom.Services.ParagraphService 24 25 @*TODO: Move these functions onto the model *@ 26 27 @functions 28 { 29 30 public string GetSectionClassList(GridRowViewModel model, string overwriteTheme = "") 31 { 32 var returnValues = new List<string> 33 { 34 $"item_{model.Item.SystemName.ToLower()}" 35 }; 36 37 if (Services.Grids.GetGridRowById(model.Id).Sort == 1) 38 { 39 returnValues.Add("dalgas-section-first-on-page"); 40 } 41 42 var sectionBackgroundTheme = model.Item.GetItem("ColorScheme")?.GetString("ColorScheme") ?? string.Empty; 43 44 if (!string.IsNullOrEmpty(overwriteTheme)) 45 { 46 sectionBackgroundTheme = overwriteTheme; 47 } 48 49 // Add theme class if it exists 50 if (!string.IsNullOrWhiteSpace(sectionBackgroundTheme)) 51 { 52 if (sectionBackgroundTheme.Contains("default")) 53 { 54 returnValues.Add("theme theme-light"); 55 } 56 else 57 { 58 returnValues.Add($"theme {sectionBackgroundTheme.Replace(" ", "").Trim().ToLower()}"); 59 } 60 } 61 62 // Determine if top padding should be removed 63 64 string removeTopPadding = model.Item.GetItem("ColorScheme")?.GetString("RemoveTopPadding"); 65 66 returnValues.Add("pb-6"); 67 if (removeTopPadding != "enable") 68 { 69 returnValues.Add("pt-6"); 70 } 71 72 return string.Join(" ", returnValues); 73 } 74 75 } 76 77 78 @{ 79 IEnumerable<HeadingViewModel> headings = ParagraphService.Instance.GetHeadingsByItems(Model.Item?.GetItem("Paragraph_Text")?.GetItems("Headings")); 80 string text = Model.Item.GetItem("Paragraph_Text")?.GetString("Text"); 81 string lead = Model.Item.GetItem("Paragraph_Text")?.GetString("Lead"); 82 IEnumerable<ButtonViewModel> buttons = ParagraphService.Instance.GetButtonsByItems(Model.Item?.GetItem("Paragraph_Text")?.GetItems("Buttons")); 83 84 bool hasImage = Model.Item.GetItem("Paragraph_Image")?.GetFile("Image") != null; 85 bool hasText = !string.IsNullOrEmpty(Model.Item?.GetItem("Paragraph_Text")?.GetString("Text")); 86 bool hasLead = !string.IsNullOrEmpty(Model.Item?.GetItem("Paragraph_Text")?.GetString("Lead")); 87 bool hasHeading = headings.Any(); 88 bool hasButton = buttons.Any(); 89 90 var theme = Model.Item.GetItem("ColorScheme")?.GetString("ColorScheme"); 91 var fifthElementTheme = "fifth-element-color-" + Model.Item?.GetItem("ColorScheme")?.GetString("FifthElementColor"); 92 93 var sectionClassList = GetSectionClassList(Model); 94 95 var image = string.Empty; 96 var imageParameters = new Dictionary<string, object>(); 97 98 string layout = string.Empty; 99 Boolean enableFifthElement = false; 100 if (Model?.Item != null) 101 { 102 var paragraphLayout = Model.Item.GetItem("Paragraph_Layout"); 103 104 if (paragraphLayout != null) 105 { 106 layout = paragraphLayout.GetString("Layout"); 107 108 enableFifthElement = !string.IsNullOrEmpty(paragraphLayout.GetString("Layout_FifthElement")); 109 } 110 } 111 112 if (!string.IsNullOrEmpty(Model.Item?.GetItem("Paragraph_Image")?.GetFile("Image")?.Path)) 113 { 114 image = Model.Item.GetItem("Paragraph_Image").GetFile("Image").Path; 115 imageParameters.Add("alt", Model.Item.GetItem("Paragraph_Image")?.GetString("ImageAltText")); 116 int xPos = Model.Item.GetItem("Paragraph_Image").GetFile("Image")?.FocalPositionFromLeft ?? 50; 117 int yPos = Model.Item.GetItem("Paragraph_Image").GetFile("Image")?.FocalPositionFromTop ?? 50; 118 string cssPosition = $"{xPos}% {yPos}%"; 119 imageParameters.Add("style", "object-position:" + cssPosition); 120 } 121 122 LinkViewModel imageLink = new LinkViewModel(); 123 if (Model.Item?.GetItem("Paragraph_Image")?.GetItem("Link") != null && !string.IsNullOrEmpty(Model?.Item?.GetItem("Paragraph_Image")?.GetItem("Link").GetString("ButtonLink"))) 124 { 125 imageLink = ParagraphService.Instance.GetLinkByItem(Model?.Item?.GetItem("Paragraph_Image")?.GetItem("Link")); 126 } 127 128 string fifthElementIconPath = "/Files/Templates/Designs/Swift/Assets/Images/DalgasFifthElements/"; 129 } 130 131 132 @{ 133 QueryResult queryResult = new QueryResult(); 134 int numberOfPersons = Convert.ToInt32(Model.Item.GetItem("Paragraph_Layout").GetString("NumberOfPersons")); 135 bool showForm = Model.Item.GetItem("Paragraph_Layout").GetBoolean("ShowForm"); 136 bool showFacets = Model.Item.GetItem("Paragraph_Layout").GetBoolean("ShowFacets"); 137 bool showSearch = Model.Item.GetItem("Paragraph_Layout").GetBoolean("ShowSearch"); 138 139 string cardInformationLayout = Model.Item.GetItem("Paragraph_Layout").GetString("Layout"); 140 141 bool allowAllQueryItems = showFacets || showSearch; 142 int formParagraphId = Pageview.AreaSettings.GetLink("FormGetContacted").PageId; 143 string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; 144 145 string formType = Model.Item.GetItem("Paragraph_Layout").GetString("FormType"); //Default or Microsoft 146 string formBlockId = Model.Item.GetItem("Paragraph_Layout").GetString("FormId"); // Microsoft form 147 string formContainerId = Model.Item.GetItem("Paragraph_Layout").GetString("ContainerId"); // Microsoft form 148 149 ButtonViewModel btnOpenForm = new ButtonViewModel 150 { 151 Id = "formParagraphId_" + formParagraphId, 152 Text = Translate("Contact me"), 153 Type = ButtonType.Button, 154 DisplayType = ButtonDisplayType.Primary, 155 Classes = new ClassList("js-show-paragraph-form") 156 }; 157 158 IList<UserViewModel> contactPersonListItems = Model.Item?.GetItem("Paragraph_Layout")?.GetUsers("ContactPersonSelector") ?? Enumerable.Empty<UserViewModel>().ToList(); 159 bool hasContactPersonListItems = contactPersonListItems.Any(); 160 List<User> users = new List<User>(); 161 List<string> userIds = new List<string>(); 162 163 if (hasContactPersonListItems) 164 { 165 userIds.AddRange(contactPersonListItems.Select(cp => cp.ID.ToString())); 166 allowAllQueryItems = false; 167 showFacets = false; 168 showSearch = false; 169 } 170 else 171 { 172 if (showFacets) 173 { 174 numberOfPersons = 12; 175 queryResult = ContentRelationService.Instance.GetAllContacts(numberOfPersons); 176 } 177 else 178 { 179 queryResult = ContentRelationService.Instance.GetRelatedContactsByCurrentPage(numberOfPersons); 180 } 181 182 userIds.AddRange(queryResult.Results.Select(qrr => qrr["UserID"]?.ToString())); 183 } 184 185 bool showPersons = Model.Item.GetItem("Paragraph_Layout").GetBoolean("showPersons") && userIds.Any(); 186 int pageNum = int.TryParse(Dynamicweb.Context.Current.Request["PageNum"], out int pageNumResult) ? pageNumResult : 1; 187 string searchTerm = Dynamicweb.Context.Current.Request["q"]; 188 List<FacetOption> selectedFacetOptions = new List<FacetOption>(); 189 int totaleCount = 0; 190 bool enableShowZeroResultMsg = true; 191 192 bool showAlternativeLayout = false; 193 194 if (showFacets && showSearch || showPersons && numberOfPersons >= 2 && userIds.Count >= 2 && showForm || showPersons && numberOfPersons >= 3 && userIds.Count >= 3 && !showForm) 195 { 196 showAlternativeLayout = true; 197 } 198 } 199 200 201 @if (queryResult.FacetGroups.Any() || hasContactPersonListItems || showForm) 202 { 203 <section id="section-@Model.Id" class="@sectionClassList item_@Model.Item.SystemName.ToLower()" data-swift-gridrow> 204 <div class=""> 205 206 <div class="container-xl"> 207 <div class="row justify-content-center"> 208 <div class="col-12"> 209 <div class="row"> 210 211 <div 212 class="col-12 @(showAlternativeLayout ? "flex-column flex-lg-row mb-5" : "col-lg-4 flex-column") d-flex justify-content-between"> 213 <div 214 class="js-content-container content-container col-12 @(showAlternativeLayout ? "col-lg-5" : string.Empty)"> 215 216 <span> 217 @string.Join("", headings.Select(h => h.ToString())) 218 </span> 219 220 @if (!string.IsNullOrEmpty(lead)) 221 { 222 <p class="lead">@lead</p> 223 } 224 225 @text 226 227 </div> 228 <div 229 class="js-content-container content-container @(showAlternativeLayout ? "col-lg-5 d-inline-flex justify-content-lg-end align-items-end" : string.Empty)"> 230 <div 231 class="d-flex flex-wrap gap-3 @(showAlternativeLayout ? "mb-4" : "mb-4 mb-lg-0")"> 232 @foreach (ButtonViewModel button in buttons) 233 { 234 @button 235 } 236 </div> 237 </div> 238 </div> 239 240 <div class="col"> 241 <div 242 class="position-relative g-4 js-card-person-container js-dalgas-queryresult-container" 243 id="@($"query-result-{Model.Id}")"> 244 245 @if (allowAllQueryItems) 246 { 247 totaleCount = queryResult.TotalCount; 248 } 249 250 <form method="post" action="@Pageview.SearchFriendlyUrl" 251 data-response-target-element="content" tabindex="-1" aria-hidden="false" 252 class="d-flex js-dalgas-facets-form dalgas-facets-form" 253 data-total-count="@totaleCount" data-page-size="@numberOfPersons"> 254 <input type="hidden" name="LayoutTemplate" 255 value="Designs/Swift/Swift_PageClean.cshtml"/> 256 <input type="hidden" name="PageNum" value="@pageNum"/> 257 @if (showFacets) 258 { 259 foreach (FacetGroup facetGroup in queryResult.FacetGroups) 260 { 261 foreach (Facet facet in facetGroup.Facets) 262 { 263 string showClass = " show"; 264 string ariaExpanded = "true"; 265 string facetGroupId = Regex.Replace(Convert.ToBase64String(Guid.NewGuid().ToByteArray()), "[/+=]", string.Empty); 266 267 268 if (facet.Options.Any()) 269 { 270 int selectedFacetsInGroup = 0; 271 272 foreach (FacetOption option in facet.Options) 273 { 274 if (option.Selected) 275 { 276 selectedFacetsInGroup++; 277 } 278 } 279 280 string label = selectedFacetsInGroup > 0 ? Translate(facet.Name) + "<span style=\"padding: 0.3em 0.6em\" class=\"badge ms-2\">" + selectedFacetsInGroup + "</span>" : Translate(facet.Name); 281 282 <div class="dropdown js-facets-selector"> 283 <button class="btn dropdown-toggle" type="button" 284 id="FacetGroup_@facetGroupId" 285 data-bs-toggle="dropdown" aria-expanded="false"> 286 @label 287 </button> 288 <div data-lenis-prevent class="dropdown-menu p-3" 289 aria-labelledby="FacetGroup_@facetGroupId" 290 style="min-width: 280px"> 291 @foreach (FacetOption facetOption in facet.Options.OrderBy(fo => fo.Label)) 292 { 293 string facetLabel = HtmlEncoder.HtmlEncode(facetOption.Label); 294 string disabled = facetOption.Count <= 0 ? "disabled" : string.Empty; 295 string selected = facetOption.Selected ? "checked" : string.Empty; 296 string facetValue = Uri.UnescapeDataString(facetOption.Value); 297 string optionValue = $"[{facetValue}]"; 298 299 facetLabel = facetLabel.ToLower() == "true" ? facetLabel = Translate("Yes") : facetLabel; 300 facetLabel = facetLabel.ToLower() == "false" ? facetLabel = Translate("No") : facetLabel; 301 302 <label class="form-check mt-1" @disabled> 303 <input type="checkbox" 304 onclick="custom.QueryResult.update(event)" 305 class="form-check-input" 306 name="@facet.QueryParameter" 307 value="@optionValue" 308 data-filter-value="@facetLabel" 309 @selected> 310 <span 311 class="form-check-label d-flex align-items-center"> 312 <span class="flex-fill">@facetLabel </span> 313 <small 314 class="opacity-85">@facetOption.Count</small> 315 </span> 316 </label> 317 318 if (facetOption.Selected) 319 { 320 FacetOption selectFacetOption = facetOption; 321 selectFacetOption.Name = facet.QueryParameter; 322 selectedFacetOptions.Add(selectFacetOption); 323 } 324 } 325 </div> 326 </div> 327 } 328 } 329 } 330 331 if (!string.IsNullOrEmpty(searchTerm)) 332 { 333 selectedFacetOptions.Add(new FacetOption() 334 { 335 Count = 1, 336 Label = searchTerm, 337 Name = "q", 338 Selected = true, 339 Value = searchTerm 340 }); 341 } 342 } 343 344 @if (showSearch) 345 { 346 <div class="type-ahead-dropdown"> 347 <div class="position-relative suggest-form"> 348 <span 349 class="position-absolute top-0 end-0 icon-3 px-3 d-flex align-items-center h-100 search-icon"> 350 @ReadFile(iconPath + "search.svg") 351 </span> 352 353 <input id="searchField_@Model.Id" 354 class="form-control custom-header-searchbar js-custom-facets-search-field pe-5 ps-3 js-" 355 type="search" 356 placeholder="@Translate("Enter postcode or name of person")" 357 autocomplete="off" 358 maxlength="255" 359 name="q" 360 minlength="3" 361 value="@searchTerm" 362 data-original="@searchTerm"> 363 364 <button type="button" 365 onclick="custom.QueryResult.clearSearchField(event)" 366 class="btn h-100 icon-2 reset-search" 367 aria-label="@Translate("Clear search")" 368 style="opacity: 0; position: absolute; top: 0; right: 0; visibility: hidden;"> 369 @ReadFile(iconPath + "x.svg") 370 </button> 371 </div> 372 </div> 373 <input type="submit" onclick="custom.QueryResult.update(event)" 374 class="btn btn-primary col-md-2" 375 value="@Translate("Search", "Search")"> 376 } 377 </form> 378 379 @if (showFacets && selectedFacetOptions.Any()) 380 { 381 <div 382 class="mt-3 d-flex gap-3 mb-4 js-dalgas-queryresult-selectedfacets-container dalgas-queryresult-selectedfacets-container"> 383 @foreach (FacetOption facetOption in selectedFacetOptions) 384 { 385 string facetValue = Uri.UnescapeDataString(facetOption.Value); 386 string optionValue = $"[{facetValue}]"; 387 <input class="visually-hidden" 388 id="Selected_@(Model.Id)_@facetOption.Value.Replace("#", string.Empty)" 389 name="@facetOption.Name" 390 onclick="custom.QueryResult.deselectFacetOption(event)" 391 type="checkbox" value="@optionValue" title="@facetOption.Label" 392 checked> 393 <label class="badge theme border border-dark" 394 for="Selected_@(Model.Id)_@facetOption.Value.Replace("#", string.Empty)"> 395 <span class="text-nowrap">@(facetOption.Label)</span> 396 <span class="icon-2 ms-2"> 397 @ReadFile(iconPath + "x.svg") 398 </span> 399 </label> 400 } 401 402 @if (selectedFacetOptions.Count >= 3) 403 { 404 <input class="visually-hidden" id="ClearAll" name="ClearAll" 405 onclick="custom.QueryResult.clearAll(event)" type="checkbox" 406 value="" title="" checked> 407 <label class="badge text-nowrap dalgas-btn-clear-all" for="ClearAll"> 408 <span class="text-nowrap">@Translate("Clear all")</span> 409 <span class="icon-2 ms-2"> 410 @ReadFile(iconPath + "x.svg") 411 </span> 412 </label> 413 } 414 </div> 415 } 416 417 @if (showFacets && selectedFacetOptions.Any() == false && string.IsNullOrEmpty(searchTerm)) 418 { 419 enableShowZeroResultMsg = false; 420 userIds = new List<string>(); 421 } 422 423 @if (showFacets && enableShowZeroResultMsg && userIds.Any() == false) 424 { 425 <div class="mt-4">@Translate("Your search returned no results...")</div> 426 } 427 428 429 @if (showPersons && userIds.Any() || showPersons && hasContactPersonListItems) 430 { 431 <div 432 class="row @(showAlternativeLayout ? "g-4" : "mt-3") js-dalgas-queryresult-itemlist dalgas-queryresult-itemlist"> 433 434 @foreach (string userId in userIds) 435 { 436 if (!int.TryParse(userId, out int intUserId)) 437 { 438 continue; 439 } 440 441 //UserViewModel result = new UserViewModel(); 442 443 User result = User.GetUserByID(intUserId); 444 445 if (result == null) 446 { 447 continue; 448 } 449 450 UserViewModel resultViewModel = result.ToViewModel(); 451 452 <div 453 class="col-12 js-col-card-person col-lg @(showAlternativeLayout ? "col-lg-4" : "")"> 454 455 @{ 456 FileViewModel imageFile = ViewModelFactory.CreateFieldFileValueView(result.Image); 457 } 458 459 <div class="theme theme-light h-100"> 460 <div class="p-img-container d-flex"> 461 <figure 462 class="ratio ratio-1x1 @(!string.IsNullOrEmpty(result.Image) ? "has-image" : string.Empty)"> 463 @RenderPartial("Components/Image.cshtml", imageFile ?? new FileViewModel()) 464 </figure> 465 <figure class="ratio ratio-1x1"> 466 <span 467 class="fifth-element @fifthElementTheme opacity-50"> 468 @ReadFile(fifthElementIconPath + "canopy.svg") 469 </span> 470 </figure> 471 </div> 472 <div class="p-txt-container p-4 pt-5"> 473 <h4>@resultViewModel.Name</h4> 474 475 @if (cardInformationLayout == "title-and-description") 476 { 477 string linkedIn = resultViewModel.GetCustomFieldValue<string>("AccessUser_LinkedIn"); 478 479 <div class="small d-flex flex-column mb-3 opacity-75"> 480 <span>@resultViewModel.GetJobTitle()</span> 481 482 @if (!string.IsNullOrEmpty(linkedIn)) 483 { 484 <a href="@linkedIn" class="mt-1" 485 target="_blank">LinkedIn</a> 486 } 487 488 @if (!string.IsNullOrEmpty(resultViewModel.GetDescription())) 489 { 490 <span 491 class="mt-3">@resultViewModel.GetDescription()</span> 492 } 493 </div> 494 } 495 else 496 { 497 <div class="small d-flex flex-column mb-3 opacity-75"> 498 <span>@resultViewModel.GetJobTitle()</span> 499 <span>@Translate("Contact Department", "Afdeling"): @resultViewModel.GetDepartment()</span> 500 501 @if (resultViewModel.GetLocations().Any()) 502 { 503 <span> 504 <span>@Translate("Office", "Kontor"): </span> 505 @foreach (Location location in resultViewModel.GetLocations()) 506 { 507 <span>@location.Text</span> 508 } 509 </span> 510 } 511 512 <span>@resultViewModel.GetComment()</span> 513 </div> 514 515 516 if (!string.IsNullOrEmpty(resultViewModel.GetContactEmail())) 517 { 518 <div class="d-flex gap-3 small opacity-75"> 519 <span>E.</span> 520 <a style="font-size: 1em" 521 class="text-decoration-none" 522 href="mailto:@resultViewModel.GetContactEmail()">@resultViewModel.GetContactEmail().ToLower()</a> 523 </div> 524 } 525 526 if (!string.IsNullOrEmpty(resultViewModel.Phone)) 527 { 528 <div class="d-flex gap-3 small opacity-75"> 529 <span>T.</span> 530 <span>@resultViewModel.Phone</span> 531 </div> 532 } 533 } 534 </div> 535 </div> 536 537 </div> 538 } 539 @if (showForm) 540 { 541 <div class="col-12 js-col-card-person col-lg"> 542 543 <div class="h-100 contact-person-card js-contact-person-card"> 544 545 <div class="card-front theme theme-light "> 546 <div class="p-img-container d-none d-lg-flex"> 547 <figure class="ratio ratio-1x1"> 548 @* Empty space *@ 549 </figure> 550 <figure class="ratio ratio-1x1"> 551 <span 552 class="fifth-element @fifthElementTheme opacity-50"> 553 @ReadFile(fifthElementIconPath + "canopy.svg") 554 </span> 555 </figure> 556 </div> 557 <div class="p-txt-container p-4 pt-6"> 558 <h4>@Translate("Get Contacted")</h4> 559 560 <div class="small d-flex flex-column mb-3 opacity-75"> 561 @Translate("Dalgas - Get Contacted - Card Text", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. Proin gravida dolor sit amet lacus accumsan et viverra justo commodo.") 562 </div> 563 564 @RenderModel(btnOpenForm) 565 </div> 566 </div> 567 <div class="card-back theme theme-light "> 568 569 @if (formParagraphId != null) 570 { 571 <div 572 class="contact-person-form-container js-contact-person-form-container theme p-4"> 573 574 575 @if (formType == "microsoft") 576 { 577 <div 578 class="js-remove-microsoft-form-styling microsoft-form-container"> 579 <script 580 src="https://cxppusa1formui01cdnsa01-endpoint.azureedge.net/eur/FormLoader/FormLoader.bundle.js" 581 crossorigin="anonymous" defer></script> 582 <div 583 data-cached-form-url="https://assets-eur.mkt.dynamics.com/@formBlockId/digitalassets/forms/@formContainerId" 584 data-form-api-url="https://public-eur.mkt.dynamics.com/api/v1.0/orgs/@formBlockId/landingpageforms" 585 data-form-id="@formContainerId"></div> 586 </div> 587 } 588 else 589 { 590 @RenderParagraphContent(formParagraphId) 591 } 592 593 594 </div> 595 } 596 597 </div> 598 599 </div> 600 </div> 601 } 602 </div> 603 604 if (allowAllQueryItems && totaleCount > numberOfPersons) 605 { 606 <div class="row mt-4"> 607 <div class="col-12 text-center"> 608 <button onclick="custom.QueryResult.getNextPage(event)" 609 class="btn btn-primary">@Translate("Vis flere")</button> 610 </div> 611 </div> 612 } 613 } 614 else 615 { 616 if (showForm) 617 { 618 <div class="col-12 col-lg"> 619 620 @if (formParagraphId != null) 621 { 622 if (formType == "microsoft") 623 { 624 if (Pageview.IsVisualEditorMode) 625 { 626 <div class="container-xl alert alert-danger" role="alert"> 627 <h4>Use the "Microsoft Form" Paragraph instead</h4> 628 <p>Due to technical limitations within Microsoft Form 629 Markup & Styling, we prefer that you use the 630 "Microsoft Form" item instead, when you have no 631 contact persons attatched this Contact 632 Paragraph.</p> 633 <p>We are showing the default form in the frontend.</p> 634 </div> 635 } 636 else 637 { 638 @RenderParagraphContent(formParagraphId) 639 } 640 } 641 else 642 { 643 @RenderParagraphContent(formParagraphId) 644 } 645 } 646 </div> 647 } 648 } 649 </div> 650 </div> 651 </div> 652 </div> 653 </div> 654 </div> 655 </div> 656 </section> 657 } 658 else 659 { 660 if (Pageview.IsVisualEditorMode) 661 { 662 <div class="container-xl alert alert-danger" role="alert"> 663 This <strong>@Model.Item.SystemName</strong> is empty 664 </div> 665 } 666 } 667

Hedeselskabet – partnering with nature

Dalgas is part of Hedeselskabet – founded in 1866 and still growing. Hedeselskabet is an association of people working for a sustainable future. And who have the necessary knowledge and experience to lead the way. 

Hedeselskabet supports

Working for a sustainable future requires resources. Hedeselskabet participates in the development of nature and the environment, and we take responsibility. Therefore, we allocate funds to relevant development projects and member-driven projects, as well as award scholarships. For the benefit of all of us – now and in the future. 

We create value for your industry

Dalgas solves all types of green tasks in a range of different industries and sectors across services. We have the experience, machinery, and references that ensure you the best possible solution. 

Hedeselskabet – med naturen som partner

Dalgas er en del af Hedeselskabet – grundlagt i 1866 og stadig i vækst. Hedeselskabet er en forening af mennesker, der arbejder for en bæredygtig fremtid. Og som har den nødvendige viden og erfaring til at gå forrest.

Hedeselskabet støtter

Arbejdet for en bæredygtig fremtid kræver ressourcer. Hedeselskabet tager del i udviklingen af naturen og miljøet, og vi tager ansvar. Derfor uddeler vi midler til relevante udviklingsprojekter og til medlemsdrevne projekter, ligesom vi uddeler legater. Til gavn for os alle – nu og i fremtiden.

No products in cart