DotNetNuke - Opening and closing trees - dotnetnuke

I inherited a DNN site and am trying to figure it out. I have a page with a clickable header and then it branches into categories which are also clickable and show a name (it is a directory of people working at this company). The issue is that there is a small + and - to open and close these categories, but only these symbols work. Is there a way to make the symbol and the category title clickable to open or close the branch?
Here is the code from the page I am referring to:
<%# Control language="C#" Inherits="Modules.PeopleNav.PeopleByDept" CodeFile="PeopleByDept.ascx.cs" AutoEventWireup="true"%>
<%# Register TagPrefix="dnn" TagName="Audit" Src="~/controls/ModuleAuditControl.ascx" %>
<asp:TreeView ID="TreeView1" runat="server" DataSourceID="XmlDataSource1"
ExpandDepth="1"
onselectednodechanged="TreeView1_SelectedNodeChanged">
<DataBindings>
<asp:TreeNodeBinding DataMember="Person" ValueField="Value" TextField="Name">
</asp:TreeNodeBinding>
<asp:TreeNodeBinding DataMember="Department" TextField="Name" >
</asp:TreeNodeBinding>
</DataBindings>
</asp:TreeView><br />
<asp:XmlDataSource ID="XmlDataSource1" runat="server" DataFile="~/Portals/0/Docs/Department.xml"></asp:XmlDataSource>
I don't even know where the linking is taking place, as I am both a new programmer and brand new to DotNetNuke. If I need to post more code I will, I just don't want to go overboard with it. Thanks in advance!

Use the TreeView's OnTreeNodeDataBound event to change the selection action.
protected void TreeView1_NodeDataBound(object sender, TreeNodeEventArgs e)
{
e.Node.SelectAction = TreeNodeSelectAction.Expand;
}

Related

Issue opening an Abp Modal that has scripts inside, it clear the below page

I have a strange issue with Abp.Io and opening a modal that has a script file inside (which loads data). The issue is that is clears the below grid. I've understood that the problem is with the Layout = null of the modal.
Here's what's happening.
Modal with Layout not null: (so it takes the scripts section):
Then I click the lens
You see the popup opens and load data correctly (now they're mocked), but below the Grid disappeared.
Instead if I put the layout of the modal to null:
You see in this case that it keep the grid below , but It doesn't load any data (since I think it doesn't know what to do with #script section.
Here's my modal:
#page
#using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
#model IlDiamante.Web.Pages.Shared.MetalliUtilizzatiInSemilavoratiModel
#{
Layout = null;
string headerName = $"Semilavorati che utilizzano il metallo '{Model.NomeMetallo}'";
}
#section scripts
{
<abp-script src="/Pages/Shared/MetalliUtilizzatiInSemilavorati.js" />
}
<input id="metalloGuid" hidden="true" value="#this.Model.Id"/>
<abp-modal>
<abp-modal-header title="#headerName"></abp-modal-header>
<abp-modal-body>
<abp-table striped-rows="true" id="SemilavoratiTable"></abp-table>
</abp-modal-body>
<abp-modal-footer buttons="#(AbpModalButtons.Close)"></abp-modal-footer>
</abp-modal>
Any advice?
Thanks
Layout should be null for modals, there is no problem there. However, if you want the script to be loaded, you must declare it where you opened the modal.
For instance:
When opening the modal, you need to specify a modal class as below:
var productInfoModal = new abp.ModalManager({
viewUrl: '/Products/ProductInfoModal',
modalClass: 'ProductInfo' //Matches to the abp.modals.ProductInfo
});
Then the modal class you specify should match inside your modal script as in the code below:
abp.modals.ProductInfo = function () {
function initModal(modalManager, args) {
// your logic
};
return {
initModal: initModal
};
};
Then add the modal to the script of the page you opened as follows:
#section scripts{
<abp-script-bundle>
<abp-script src="/Pages/Products/ProductInfoModal.js"/> // modal script
<abp-script src="/Pages/Products/Index.js"/> // page script
</abp-script-bundle>
}
For more information see here: https://docs.abp.io/en/abp/latest/UI/AspNetCore/Modals#modals-with-script-files
Since script files are loaded while opening the page, it is normal that it does not work even if you declare the script in the modal.cshtml(ProductInfo.cshtml) file. However, you can still use lazy load if you want. For that, I recommend you look here.

How to access Another Module's Content and Presentation Items after 2sxc v10.20+

Here is code that worked up through 2sxc 10.9.1. Though I am able to get the CmsBlock for the TabID, ModuleID and get that to .Render(), I need more. Here is the old code. Not sure it makes any difference, but this View is using the normal Link content-type and is running in an older version of the Content App (appx 3.03=ish). 2sxc has been upgraded and is now 11.22.0 LTS.
I have removed unnecessary stuff, so I doubt this runs as is...
#using ToSic.Razor.Blade
#using ToSic.SexyContent.Environment.Dnn7
#{
var Helpers = CreateInstance("_Helpers.cshtml");
// Display the items from the Manage Links module, we go in 'sideways'
// this gives us just the Content items with their Presentations settings, etc.
var sxci = Factory.SxcInstanceForModule(3360, 606); // ModuleID of Manage Links
var dyn = Factory.CodingHelpers(sxci);
var allLinks = dyn.AsDynamic(dyn.Data["Default"]);
}
#* other stuff *#
<div class="row co-documents justify-content-center align-items-center">
#foreach (var linkItem in allLinks) {
var linkInfo = Helpers.LinkInfos(linkItem.Link, linkItem.Window, linkItem.Icon);
string iconStyle = linkItem.IconStyle ?? "fas";
int linkColumns = (int)linkItem.Presentation.Columns;
string linkIconAlign = linkItem.Presentation.IconAlign;
string linkIconBGColor = linkItem.Presentation.IconBGColor;
#* other stuff *#
}
</div>
So the easy thing to figure out was how to get the module as a CmsBlock which I can Render() as is (below), but what I need to do instead is get proper access to the List of Content Items AND their Presentation data (like above, allLinks).
ToSic.Sxc.Dnn.Factory.CmsBlock(606, 3360).Render();
What am I missing? How can I get access to the other module's data like I was doing before? In this case, I do this in 3 different places on the website. So to outline this in English, I have a module that the client manages a few special links that get displayed in MegaMenus, other special nav, and directly on a couple of pages. In each place they render differently. In their "home" module, where they get edited, they just look boring like this:
I realize its something like this:
var allLinks = something1.AsList(something2.Data["Default"]);
I understand that something2 is an app instance, but how do I create it in the context of the other module?
And what is something1 nowadays? And how do instantiate it? Looks like its a new ToSic.Sxc.Code.DynamicCode() but I can't figure out how to construct that in a way that I can use or doesn't just throw errors.
Thanks in advance for any insight!!
Okay, it took a little testing, trial and error. And also I missed that DynamicCode() was a Method of the Factory class. In retrospect it does seem easy now.
So first you get the BlockBuilder
var block = Factory.CmsBlock(606, 3360);
Then you get the DynamicCode instance (Code.DnnDynamicCodeRoot) from that
var dc = Factory.DynamicCode(block);
And then things are normal
var allLinks = AsList(dc.Data["Default"]);
The rest of the code works like it did before; I can foreach through the links with Header (renamed from ListContent) and Presentation (now Content.Presentation) working just as expected.
The above answer works fine if you are inside the C# Razor template of the 2sxc View. But what if you are outside, for example in a Razor template for a DDR Menu?
Same two steps as above (get the block and the dc), but then you do NOT have access to AsList() or the App. Thankfully, you already have DynamicCode, so you could just get all the records in the Bibliography content-type like this:
<ul>
var items = dc.AsList(dc.App.Data["Bibliography"]);
foreach (var item in items)
{
<li>#item.EntityTitle</li>
}
</ul>
So once you've got your dc you've got access to all the usual 2sxc toys.

Displaying taxonomy on DotNetNuke Page

I've added tags to the pages on my dnn site and I would like to display a simple list of the tags that the page is assigned to at the bottom of the page.
I'm using DNN 6 and I've read that this is possible by adding some lines to the skin file.
I've added
<%# Register TagPrefix="dnn" TagName="TAGS" Src="~/Admin/Skins/Tags.ascx" %>
and <dnn:tags runat="server" id="dnnTags" /> as per online suggestions
When I view the page there are no tags, and in the source the only thing outputted is an empty div <div class="horizontal"></div>
This does suggest that the tags.acsx is being called ok
I thought maybe tags weren't working, but when I put a ContentList module on the page and visit the page with ?Tag=test appended to the link it does pick up all the pages and modules with that tag, including the page I am testing.
Has anyone experienced anything like this before?
Thanks
I've now found that removing the below section of code from tags.ascx.cs allows the page to display the list of tags
string resultsUrl = Null.NullString;
var objModules = new ModuleController();
int searchTabId = 0;
ModuleInfo SearchModule = objModules.GetModuleByDefinition(PortalSettings.PortalId, "Search Results");
if (SearchModule == null)
{
return;
}
else
{
searchTabId = SearchModule.TabID;
}
There are two parts to the addition of the skin object. Part 1
<%# Register TagPrefix="dnn" TagName="TAGS" Src="~/Admin/Skins/Tags.ascx" %>
Then you need to actually add it to the page where you need it.
<dnn:TAGS id="mytags" runat="server" />

What is a "template" good for in CakePHPs E-Mailcomponent?

I'm a bit confused using the Cake's (2.3) Email-Class. It appears that we are able to define a "template", a "layout" and a "theme" whereas I only understand the usage of Layouts (located in /app/View/Layouts/Emails).
It seems that everything can be defined in the Layout, but the Template seems do be necessary (at least an empty file) but I don't understand the context because to me it seems that it does not matter what I put in there.
The concept of the theme is even more nebulous to me. Maybe someone can give me a hint here. I found a discussin in a mailing-list which was not really enlightning. The documentation does not reveal this too.
http://book.cakephp.org/2.0/en/core-utility-libraries/email.html
--
Edit: Fixed confusing typo.
Edit2: CakeEmail is used directly - not the component.
template is view (in terms of ordinary pages)
layout for emails is as layout for views (in terms of ordinary pages)
layout should contain some common elements like logo and etc
and you can push data to templates like push data to view from controller
Please, check following example:
from custom EmailComponent
public function restore_password($user_to_send_restore_link) {
$email = new CakeEmail('default');
$email->emailFormat('both');
$email->template('restore_password', 'emaillayout');
$email->to(array($user_to_send_restore_link['User']['email']));
$email->from(array(GENERAL_FROM_EMAIL => 'seqrd support team'));
$subject = 'Restore password link';
$email->subject($subject);
$email_data = array(
'hash' => $user_to_send_restore_link['User']['hash']);
$email->viewVars($email_data);
return $email->send();
}
app/View/Emails/html/restore_password.ctp
<p> Please, follow link <?php echo $this->Html->link('restore password link', Router::url(array('controller' => 'users', 'action' => 'restore_password_form', $hash), true)); ?> to restore password</p>
app/View/Layouts/Emails/html/emaillayout.ctp
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title><?php echo $title_for_layout;?></title>
</head>
<body>
<?php echo $this->fetch('content');?>
</body>
</html>
Theme it's next step of abstraction, there you can fast change whole styles of all emails, but not change code significantly.
Notes: viewVars method pass variables not only into template, but in email layout too.

Telerik MVC ComboBox in Grid not posting the right value

I have set up a ComboBox in grid. It shows everything fine but when I select anything in the ComboBox it is not posting the right value to the server, I debugged it and found out that it always posts value 0.
Any idea why is that and how to fix it?
Here's the important code:
**Controller**
//lista za stvaratelje (ComboBox)
var stvaratelji = newStvarateljiService.GetAllStvaratelje();
//za combobox
ViewBag.stvaratelji = stvaratelji;
//za selectlist
var listaStvaratelja = new SelectList(stvaratelji, "IdStvaratelj", "Naziv");
ViewData["stvaratelji"] = listaStvaratelja;
**View**
columns.ForeignKey(b => b.StvarateljId, (SelectList)ViewData["stvaratelji"]).Title("Stvaratelji").EditorTemplateName("Stvaratelji").Width("30%");
**EditorTemplate**
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%= Html.Telerik().ComboBoxFor(m => m)
.Name("Stvaratelji")
.Filterable(filtering =>
filtering.FilterMode(AutoCompleteFilterMode.Contains)
)
.Encode(false)
.AutoFill(true)
.BindTo((SelectList)ViewData["stvaratelji"])
%>
I am using selectList with foreignKey because when the grid is not in edit mode it shows value (ID) instead of the name, but that's a completely different issue and one not so important. Nevertheless if someone knows how to set ComboBox to show the name when the grid is not in edit mode it would be also appreciated.
I figured out what is the problem.
I changed the name of EditorTemplate's ComboBoxFor in "StvarateljId" because ComboBoxFor is not bound to the Title in the Grid but the name of the property in "ForeignKey" part.
Dario,
To address the question in the comment of your answer ("not to use SelectList"):
Have you tried changing from a ForeignKey to a simple Bound column with a DisplayTemplates/StvarateljId similar to the EditorTemplates? I have had some success with this setup instead of using the ForeignKey.
Here is a link to the demos at Telerik showing this exact setup.

Resources