How to configure the CKEditor under XPages? - xpages

My goal is to add some custom-styles to the CKEditor (Version 3.6.6.2).
I already got a solution, but they interfere with the build-in image-upload functionality.
The feature to add an image, which is then stored in the current document, is gone.
So i am afraid that there are more, currently undiscovered, problems with it.
My Current Solution
<xp:inputRichText value="#{document1.Body}" id="html1" htmlFilter="identity" htmlFilterIn="identity" />
<xp:scriptBlock id="scriptBlock1" type="text/javascript">
<xp:this.value><![CDATA[
var ckEditorClientId = "#{javascript: getClientId("html1")}";
CKEDITOR.replace( ckEditorClientId,
{stylesSet: [
{ name : 'MyStyle', element : 'span', attributes : { 'class' : 'myStyle' } }
],
toolbar : CKEDITOR.config.toolbar_Full
}
);
]]></xp:this.value>
</xp:scriptBlock>
I haved tried to achieve that via dojoAttributes and/or config.js all day long -
nothing worked out for me, but that.
I would be so happy, if anybody can tell me the right way to configure the CKEditor under XPages.

Is this still relevant? intec.co.uk/xpages-8-5-2-rich-text-extending-the-ckeditor It may not be, now a lot of the resources are in a plugin
[Edit by Dennis K.]
Solution
<xp:inputRichText value="#{document1.html}" id="html1" htmlFilter="identity" htmlFilterIn="identity">
<xp:this.dojoAttributes>
<xp:dojoAttribute name="extraPlugins" value="stylesheetparser"></xp:dojoAttribute>
<xp:dojoAttribute name="toolbarType" value="Full"></xp:dojoAttribute>
<xp:dojoAttribute name="contentsCss" value="CKStyles.css"></xp:dojoAttribute>
</xp:this.dojoAttributes>
</xp:inputRichText>
CKStyles.css
//Example
span.myClass {
color: #00A6C7;
font-size: 1.8em;
font-weight:normal;
}

Related

Dynamically binding vuetify layout

I'm trying to dynamically bind the layout of one part of my component. I'm just not seeing an exact prop to bind to for this.
I tried to use a v-bind hooked to the justify as well as used v-bind:style but am not seeing a direct way to to do this.
<v-layout v-bind="{justify: setLayout(isPdfLoaded)}" style="margin-top: 5.5%">
setLayout(bool: boolean): string{
if(bool === true){
return 'justify-start'
} else {
return 'justify-center'
}
},
<v-layout :justify-center="!isPdfLoaded" :justify-start="isPdfLoaded" style="margin-top: 5.5%">
ended up going with this and it works.
Using a ternary operator also works
<v-layout :class="isPdfLoaded ? 'justify-start' : 'justify-center'" style="margin-top: 5.5%">

Kentico 9 cms:cmsTextBox placeholder localization

I've duplicated the search box webpart so i can make changes. I'm trying to add a localization string to the placeholder attribute.
This isn't working:
<cms:CMSTextBox ID="txtWord" runat="server" EnableViewState="false" MaxLength="1000"
ProcessMacroSecurity="false" placeholder="<%= CMS.Helpers.ResHelper.GetString("kff.Search--PlaceHolderCopy")%>" />
nor does this:
<cms:CMSTextBox ID="txtWord" runat="server" EnableViewState="false" MaxLength="1000"
ProcessMacroSecurity="false" placeholder='<%= CMS.Helpers.ResHelper.GetString("kff.Search--PlaceHolderCopy")%>' />
I have a JS Snippet that does work, but i'm hoping to avoid copy in JS files.
var $searchField = $('.searchTextbox');
if ($('body').hasClass('ENCA')) {
// search field placeholder copy
$searchField.attr('placeholder', 'Search For Stuff');
}
else {
$searchField.attr('placeholder', 'Recherche');
}
Can I add the localization string to the server tag, or should it be done in the code behind. I'm not sure the best location in the code behind for this either, I can't see a Page_Load block.
You could add the following line in the SetupControl method in the codebehind:
txtWord.Attributes.Add("placeholder", ResHelper.GetString("kff.Search--PlaceHolderCopy"));
You cannot really use the <%= syntax to set properties of server-side controls.
Also, please note that the CMSTextBox control has a WatermarkText property, which might be what you are looking for. It uses the TextBoxWatermarkExtender control from the AjaxControlToolkit library.
There is no need to duplicate the webpart and have duplicate code just for something this simple. Just create a different webpart layout for that webpart and add the following code above the Panel:
<script runat="server">
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
txtWord.Attributes.Add("placeholder", ResHelper.GetString("yourstring"));
}
</script>

Xpage error message - Engine Exception name can't be null IBM WebSphere Application Server

I have created a simple xpage in Domino Designer/Server 9. When opening it, it give following error message:
Engine Exception
name can't be null
IBM WebSphere Application Server
I am not able to locate the source of this error. And strange thing is why IBM Websphere message is coming here!!
<xp:this.beforePageLoad>
<![CDATA[#{javascript:var catDb:NotesDatabase = session.getDatabase("<server name>","catalog.nsf");
requestScope.DocCol = catDb.search("Form='Notefile'"); }]]>
</xp:this.beforePageLoad>
<xp:dataTable id="dataTable1" rows="30" value="#{javascript:return requestScope.DocCol;}" var="repCol" indexVar="repIndex">
<xp:column id="column1">
<xp:text escape="true" id="computedField1" value="#{repCol.Pathname}">
</xp:text>
</xp:column>
</xp:dataTable>
You might want to rework your code a little bit. Along this lines:
<xp:dataTable id="dataTable1" rows="30"
value="#{javascript:return requestTools.getDocumentsByForm('Notefile');}"
var="repCol" indexVar="repIndex">
<xp:column id="column1">
<xp:text escape="true" id="computedField1" value="#{repCol.Pathname}">
</xp:text>
</xp:column>
</xp:dataTable>
Create a script library where you then implement the function. Something like:
var requestTools = {
"isDebug" : function() { return false; },
"debugDocumentsByForm" : function(formName) { return {"PathName" : "DemoPath"},
"getDocumentsByForm" : function(formName) {
if (requestTools.isDebug()) {
return requestTools.debugDocumentsByForm(formName);
} else if (!requestScope.DocCol) {
// optimize this, add only the fields needed to JSON objects, so
// recycling can happen
var catDb:NotesDatabase = session.getDatabase("<server name>","catalog.nsf");
requestScope.DocCol = catDb.search("Form='"+formName+"'");
}
return requestScope.DocCol;
}
}
This will allow you to tune the function without touching all XPages that use it. db.search is the slowest way to perform a search, so you only might use it for testing.
There is no code in the beforePageLoad event. You want to keep the data acquisition confined to your dataTable. Also consider to use a JSON object instead of a document collection and a view or at least an FTSearch. db.Search is way to slow.

Domino 9 / Dojo 1.8 - Date Time Picker without default value

I want a Date Time Picker control WITHOUT a default value. Doesn't seem to be possible anymore :-(
To reproduce, create a blank XPage and place a Date Time Picker control. Open the XPage in the browser and you will see that it defaults to today.
I didn't found any way to set the default to an empty value. I tried setting all properties/data/default to 0, null, empty string and so on - no luck.
I tried the data-dojo-probs attribute with value:'', this sets the default to 1970-1-1, but not to blank.
Any ideas?
This is a known issue in ND9, reported as SPR DEGN966F5V.
A work around for the issue (from SPR) is to modify the widget prototype in the postCreate function to prevent the value from being reset.
require([
"dojo/_base/lang",
"ibm/xsp/widget/layout/DateTextBox",
"ibm/xsp/widget/layout/TimeTextBox",
"ibm/xsp/widget/layout/DateTimeTextBox"
], function(lang, DateTextBox, TimeTextBox, DateTimeTextBox){
var a = {};
lang.mixin(a, {
postCreate: function(){
this.inherited(arguments);
}
});
DateTextBox.extend(a);
TimeTextBox.extend(a);
DateTimeTextBox.extend(a);
});
Here is an example of it working.
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:this.resources>
<xp:script clientSide="true">
<xp:this.contents><![CDATA[
require([
"dojo/_base/lang",
"ibm/xsp/widget/layout/DateTextBox"
], function(lang, DateTextBox){
var a = {};
lang.mixin(a, {
startup: function(){
this.inherited(arguments);
this.set("value", null);
}
});
DateTextBox.extend(a);
});
]]></xp:this.contents>
</xp:script>
</xp:this.resources>
<xp:inputText id="inputText1" value="#{sessionScope.inputText1}">
<xp:this.converter>
<xp:convertDateTime type="date" />
</xp:this.converter>
<xp:dateTimeHelper />
</xp:inputText>
</xp:view>
i dont know how it works in notes 9 but you could remove it with a CSJS like:
var field= dojo.byId('#{id:field}')
field.value ="";
hope it helps..
In applications I've previously applied a dojoType on the dateTimeHelper with this code:
<xp:dateTimeHelper id="dateTimeHelper1" dojoType="dijit.form.DateTextBox">
</xp:dateTimeHelper>
That was to address a problem in previous Domino versions where the page refreshed as soon as the picker was selected in certain flavours of IE.
This code seems to work fine on R9 without needing the workaround.

How to update Beans or Scoped Variables when transitioning in XPages Mobile Controls

I'm having a problem trying to set values on a mobile page before transition into that page.
I have a scriptblock based on Tony McGuckin's OpenNTF XSnippet. http://openntf.org/XSnippets.nsf/snippet.xsp?id=calling-server-side-jscode-during-mobile-page-transitions
So when I transition to a page with the ID of "appPage3" I call the method "facilityCheckIn" if the JSON-RPC service.
I'm trying to set the value in a viewScoped managed bean and for testing am trying to set a normal viewScope variable.
As best as I can tell the Mobile Page is not picking up the changes. It's not showing the viewScope at all. I'm not sure what's up with that.
I believe the managed bean is getting it's value but it's like the page is getting rendered first. The value on the Mobile page is blank the first time
and then if I either refresh, or exit and go back to the page it does display. I tried accessing the bean via SSJS and EL.
I really need to be able to set values for mobile pages as I transition into and out of a page.
Any advice would be appreciated.
Thanks!!
I've updated the code below to show the complete Mobile Page. I've not included anything for the custom control that should be displaying the fields but can if necessary.
I've created a 6ish minute video demonstrating the problem and that also shows all the relevant code.
http://traffic.libsyn.com/notesin9/SO-Question.mp4
Thanks!!!
<xp:this.resources>
<xp:styleSheet href="/.ibmxspres/dojoroot/dijit/themes/tundra/tundra.css"></xp:styleSheet>
<xp:styleSheet href="/mobile.css"></xp:styleSheet>
</xp:this.resources>
<xc:ccDebugToolbar defaultCollapsed="false"
collapseTo="left"></xc:ccDebugToolbar>
<xe:singlePageApp id="singlePageApp1"
selectedPageName="home">
<xe:djxmHeading id="djxmHeading1" label="My Inventory"></xe:djxmHeading>
<xe:appPage id="homeID" pageName="home">
<xe:djxmHeading id="djxmHeading2" label="My Inventory">
</xe:djxmHeading>
<xc:mob_menu_home></xc:mob_menu_home>
</xe:appPage>
<xe:appPage id="appPage2" pageName="facility" resetContent="true">
<xc:mob_menu_facility></xc:mob_menu_facility>
</xe:appPage>
<xe:appPage id="appPage8" pageName="show" resetContent="true">
<xc:mob_menu_show></xc:mob_menu_show>
</xe:appPage>
<xe:appPage id="appPage3" pageName="facilityCheckIn"
resetContent="true">
<xc:mob_page_CheckInOut header="Check In at Facility"
scanType="Receiving" scanLocation="Facility">
</xc:mob_page_CheckInOut>
</xe:appPage>
<xe:appPage id="appPage5" pageName="facilityCheckOut"
resetContent="true">
<xc:mob_page_CheckInOut header="Check Out from Facility"
scanType="Shipping" scanLocation="Facility">
</xc:mob_page_CheckInOut>
</xe:appPage>
<xe:appPage id="appPage6" pageName="showCheckOut"
resetContent="true">
<xc:mob_page_CheckInOut header="Check Out from Show"
scanType="Shipping" scanLocation="Show">
</xc:mob_page_CheckInOut>
</xe:appPage>
<xe:appPage id="appPage7" pageName="showCheckIn"
resetContent="true">
<xc:mob_page_CheckInOut header="Check In at Show"
scanType="Receiving" scanLocation="Show">
</xc:mob_page_CheckInOut>
</xe:appPage>
<!-- SUB PAGES -->
<!-- GET MANIFEST Page -->
<xe:appPage id="appPage4" pageName="manifest" resetContent="true">
<xc:mob_page_Manifest></xc:mob_page_Manifest>
</xe:appPage>
</xe:singlePageApp>
<xe:jsonRpcService id="jsonRpcService1" serviceName="appService">
<xe:this.methods>
<xe:remoteMethod name="setCurrentPage">
<xe:this.arguments>
<xe:remoteMethodArg name="pageName"></xe:remoteMethodArg>
<xe:remoteMethodArg name="direction"></xe:remoteMethodArg>
</xe:this.arguments>
<xe:this.script><![CDATA[print("PageName " + pageName);
print("Direction " + direction);
viewScope.put("vsPage", "test");
App.setCurrentPage(pageName);
App.setCurrentDirection(direction);
return "";]]></xe:this.script>
</xe:remoteMethod>
</xe:this.methods>
</xe:jsonRpcService>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:scriptBlock id="scriptBlock1">
<xp:this.value><![CDATA[
XSP.addOnLoad(function(){
// Begin App Page 1
var newPage = dijit.byId("#{id:appPage3}");
if(null != newPage){
dojo.connect(newPage, "onBeforeTransitionIn", function(){
var deferred = appService.setCurrentPage("facilityCheckIn", "onBeforeTransitionIn");
deferred.addCallback(function(result) {
console.log(result);
});
});
dojo.connect(newPage, "onBeforeTransitionOut", function(){
var deferred = appService.setCurrentPage("facilityCheckIn", "onBeforeTransitionOut");
deferred.addCallback(function(result) {
console.log(result);
});
});
dojo.connect(newPage, "onAfterTransitionIn", function(){
var deferred = appService.setCurrentPage("facilityCheckIn", "onAfterTransitionIn");
deferred.addCallback(function(result) {
console.log(result);
});
});
dojo.connect(newPage, "onAfterTransitionOut", function(){
var deferred =appService.setCurrentPage("facilityCheckIn", "onAfterTransitionOut");
deferred.addCallback(function(result) {
console.log(result);
});
});
}
// End App Page 1
// Begin Home Page
var newPage = dijit.byId("#{id:homeID}");
if(null != newPage){
//console.log("Inside home Page")
dojo.connect(newPage, "onBeforeTransitionIn", function(){
var deferred = appService.homePageReset();
deferred.addCallback(function(result) {
console.log(result);
});
});
dojo.connect(newPage, "onBeforeTransitionOut", function(){
var deferred = appService.homePageReset();
deferred.addCallback(function(result) {
console.log(result);
});
});
}
// END Home Page
// Insert new Code ABOVE THIS LINE
}); // This ends the block that holds all the functions
]]></xp:this.value>
</xp:scriptBlock>
I was faced with a similar problem some time ago and I had to create another XPage (with a SingleApplication) to navigate to instead of just jumping to an appPage within the same SingleApplication.
Not ideal, however, it also solved another issue for me since I wanted to be able to jump directly to the page in question (using a QR code).. ;-)
/John
PS. Will follow your findings here to see if it can be done. This kind of issues with the mobile controls (I had some with typeahead as well) sort of pushed me in direction of other frameworks, for now, anyway...
David.... You said that doing a refresh did correct the issue, also Stephan mentioned that the transition to the new page happens before the result comes back from the RPC which I think is correct. So in your callback, while not optimal but may at least get you moving forward, you could fire off a partial refresh by using:
XSP.partialRefreshGet("#{id:appPage3}",{});
//I've had partial success with the "#{id:appPage3}" call, so I usually use a full
// dojo query like:
var appPageId = dojo.query("[id$='appPage3']")[0].id
I don't know if that will correct your issue, but it appears everything is working as it should with the exception of that value being populated.
Ok I believe I have this solved. I had no luck using the RPC control stuff from Tony's XSnippet. That works of you're leaving the page but not if your entering. This seems to work as desired.
To deal with entering you need to put your code in the Rendering event of the header.

Resources