I have a file download control that lists attachments from some documents in my database.
I want to display an icon next to each row and make it a link to the attachment of the row.
If not sure how to do it for each row, let's assume that i have only 1 row. How can i get the link of the attachment so as to declare it as href in a link control?
As i already mentioned in my Comment if you are using a <xp:fileDownload> you can add a Icon if you set displayType="true" and because you didnt add code to your question i guess your code could look something like this:
//..your code
<xp:panel id="row">
<xp:this.data>
<xp:dominoDocument
var="document1"
action="openDocument"
documentId="#{javascript://example... viewEntry.getDocument().getUniversalId()}">
</xp:dominoDocument>
</xp:this.data>
<xp:fileDownload
rows="30"
id="fileDownload1"
displayLastModified="false"
value="#{document1.Body}"
displayType="true">
</xp:fileDownload>
</xp:panel>
//..your code
or if you dont use a <xp:fileDownload> and maby just Display rows with the attachment Name you could use something like this:
//... your code
<xp:panel id="row">
<xp:repeat
id="repeat1"
rows="30"
value="#{javascript:#AttachmentNames()}"
indexVar="attachmentIndex"
var="attachment">
<xp:link
escape="true"
text="#{javascript:attachment;}"
id="link1"
target="_blank">
<xp:this.value><![CDATA[#{javascript:
var url = facesContext.getExternalContext().getRequest().getContextPath() + "/0/" +
/*in my case: viewEntry.getDocument().getUniversalID()*/
+ "/$File/"+ AttachmentName;
return url;}]]></xp:this.value>
<xp:image id="image1">
<xp:this.url><![CDATA[#{javascript://
var pdfImage = 'pdf.gif';
if(attachment.indexOf("pdf")> 0)
return pdfImage;
}]]></xp:this.url>
</xp:image>
</xp:link>
<br></br>
</xp:repeat>
</xp:panel>//...your code
The <xp:repeat> inside your row will create a link for each attachment inside of your document you can remove it if you only have one attachment per document.
Related
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.
I would like to have a File Download control display the attachments with the newest (latest) Created On date at the top. The default is to display the newest last.
<xp:fileDownload rows="30" id="FD"
displayLastModified="false" value="#{document1.files}"
style="width:98%" hideWhen="false"
displayType="true" allowDelete="false" displayCreated="true">
</xp:fileDownload>
As there's currently no better answer, I'll post one here.
Actually, the <xp:fileDownload> component lists file attachments in order they appear in document's Rich Text field, not the newest last:
You can't change this behavior with any of the properties, so the one possible way is to obtain the list of attachments, sort it like you need, and then feed the sorted list to <xp:repeat> component, where you can draw the attachment table that will just slightly or even not differ from that displayed by <xp:fileDownload>. It's not that hard, just look at created HTML markup in your browser debug tool and recreate that inside your <xp:repeat>.
Suppose you have dominoData declared on your page:
<xp:this.data>
<xp:dominoDocument var="document1"
documentId="9CAA72D47AEA7C8D462582FB005AB525"
action="openDocument" />
</xp:this.data>
Then create the <xp:panel> where your <xp:repeat> will reside. Create the dataContext for your panel:
<xp:panel>
<xp:this.dataContexts>
<xp:dataContext var="attachments">
<xp:this.value><![CDATA[
#{javascript:
var sourceList:java.util.List = document1.getAttachmentList('files');
if (sourceList.size() == 0) {
return sourceList;
}
java.util.Collections.sort(sourceList, createdComparator);
return sourceList;
}
]]></xp:this.value>
</xp:dataContext>
</xp:this.dataContexts>
</xp:panel>
There you get a list of com.ibm.xsp.model.domino.wrapped.DominoDocument.AttachmentValueHolder objects, then sort the list with declared Comparator (see update below) using the created file attribute, and return the sorted list as attachments variable.
Then you create <xp:repeat> and nest it inside your <xp:panel> after <xp:dataContexts>. Give it the dataContext's variable name as a value:
<xp:repeat value="#{attachments}" var="attachment">
<xp:text value="#{attachment.type}" />
<xp:label value=" - " />
<xp:text>
<xp:this.value><![CDATA[
#{javascript:
var rawSize = attachment.getLength();
return (rawSize < 1024 ? 1 : (rawSize / 1024).toFixed(0)) + " KB";
}
]]></xp:this.value>
</xp:text>
<xp:label value = " - " />
<xp:link text="#{attachment.name}" value="#{attachment.href}" />
<xp:label value = " - " />
<xp:text>
<xp:this.value>
#{javascript:
return new java.util.Date(attachment.getCreated());
}
</xp:this.value>
<xp:this.converter>
<xp:convertDateTime type="both" timeStyle="short" />
</xp:this.converter>
</xp:text>
<xp:br />
</xp:repeat>
Here's the result of <xp:repeat> output compared to <xp:fileDownload>:
Just create the markup that looks like fileDownload's table, and you're done.
Update
It's worth the effort to create a request scoped Managed Bean that will serve as the Comparator instead of implementing some good sorting algorithm right inside SSJS code block.
Create a Java class inside Code/Java folder under some existing or new package. If the package name is e.g. com.benway.util and the class name is CreatedComparator:
package com.benway.util;
import java.util.Comparator;
import com.ibm.xsp.model.FileRowData;
public class CreatedComparator implements Comparator<FileRowData> {
public int compare(FileRowData file1, FileRowData file2) {
if (file1 == null || file2 == null) return 0;
return (int)(file2.getCreated() - file1.getCreated());
}
}
Register your new class as a managed bean in your faces-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config>
<managed-bean>
<managed-bean-name>createdComparator</managed-bean-name>
<managed-bean-class>
com.benway.util.CreatedComparator
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
...etc...
</faces-config>
Now you're really done :)
Can any one please guide me how I can copy content from one site and migrate to other side with the help of selenium WebDriver ?
Just to be clear, you want to perform an copy/paste of the website directory to another folder ?
Or do you want to parse the html contents, and save that in an external file ?
The former is not really selenium friendly.
So an simple example of what you want is this :
Website 1:
<span id="spanID"> content in here </span>
Website 2:
<form id="inputID"> [ you want content in here ] </form>
Please note the pseudo html.
What you need to do in order to make this work is..
browser.get("http://www.website1.com);
var tempElement = $("spanID");
tempElement .getText().then(function (contentOfSpan) {
console.log(contentOfSpan); // will print the content of the span... now you want to save this value somewhere in your scope.
});
/////////////////////////////////////////////////
browser.get("http://www.website2.com);
var tempElement = $("inputID");
tempElement.sendKeys(RefferenceTocontentOfSpan)
this is my problem...
I have some of images and links that I want to load different joomla modules when user click on them.
mean each hyperlink can load another module|position
thanks all
In case that you just want to call a module's content from a url the following answer will help you.
If you just want to show / hide a module in the same page you could use something similar to my previous answer: Joomla 3 Show different modules on same position depending on toggler
Joomla provides the functionality to call a specific file of the active template by adding the tmpl=FILENAME key/value to the url's query string.
All built-in templates have a component.php file if user wants to load the template with the component only. You could check the following link for more details: Adding print pop-up functionality to a component.
You could do something similar to only show the modules that you want to load.
You could copy the component.php to a new file (I have used custom.php) and added the following php code in the <body> ... </body> part.
<?php
$jinput = JFactory::getApplication()->input;
$selectedPosition = $jinput->getString("position", "");
$selectedModule = $jinput->getString("module", "");
$selectedModuleTitle = $jinput->getString("title");
if($selectedPosition !== "") {
$modules = JModuleHelper::getModules($selectedPosition);
foreach ($modules as $module) {
echo JModuleHelper::renderModule($module);
}
} elseif ($selectedModule !== "") {
$module = JModuleHelper::getModule($selectedModule, $selectedModuleTitle);
echo JModuleHelper::renderModule($module);
}
?>
So with a similar way as loadposition / loadmodule works you could call the new template file using:
index.php?tmpl=custom&position=MODULE_POSITION
or
index.php?tmpl=custom&module=MODULE_TYPE
or
index.php?tmpl=custom&module=MODULE_TYPE&title=MODULE_TITLE
Optionally if you want to load the module with a specific style, you could pass it to the second paramter of the renderModule method like:
echo JModuleHelper::renderModule($module, array("style" => "xhtml"));
Hope this helps
Is it possible to add a teaser image to the default Composite.News package? Out of the box the news ext. brings all I need but a teaser image for the list view is missing in my case.
Yes, but this require modifications with package.
Edit News data type: go to Data -> Page Datafolders -> locate Composite.News.NewsItem -> right click -> Edit -> on the Fields tab add new field for example named "TeaserImage", Field Type = Data Reference, Reference Type = C1 Image File, Optional = Yes -> Save data type.
Modify the News Form Markup:
The News data item contains custom Form Markup, so the new added field will be not automatically appear there, so you should manually add the markup for the new field: go to Data -> Page Datafolders -> locate Composite.News.NewsItem -> right click -> Edit Form Markup -> add markup for the new TeaserImage field:
<cms:binding name="TeaserImage" type="System.String" optional="true" />
</cms:bindings>
<cms:layout>
<cms:layout.label>
<cms:read source="Title" />
</cms:layout.label>
<TabPanels>
<PlaceHolder Label="Settings">
<FieldGroup>
...
<TextArea Label="Teaser" Help="The short description of the news item">
<TextArea.Text>
<cms:bind source="Teaser" />
</TextArea.Text>
</TextArea>
<DataReferenceTreeSelector Label="TeaserImage" Help="" Handle="Composite.Management.ImageSelectorDialog" SearchToken="Composite.Plugins.Elements.ElementProviders.MediaFileProviderElementProvider.MediaFileSearchToken,Composite|MimeTypes=',\ \'image/gif\',\ \'image/jpeg\',\ \'image/png\',\ \'image/bmp\'', Extensions=null, Folder=null, HideSubfolders='False', Keyword=null" DataType="Composite.Data.Types.IImageFile,Composite" NullValueAllowed="true">
<DataReferenceTreeSelector.Selected>
<cms:bind source="TeaserImage" />
</DataReferenceTreeSelector.Selected>
</DataReferenceTreeSelector>
</FieldGroup>
</PlaceHolder>
<XhtmlEditor Label="News Story" Help="News Story" ClassConfigurationName="common">
...
</XhtmlEditor>
</TabPanels>
</cms:layout>
Modify the XSLT function Composite.News.NewsList -> edit the function call "GetNewsItemXml" -> modify Selected fields (select the new TeaserImage field), -> edit function Template and add the code where you want to render the Tease Image.