How do you add a new attribute to a dataset node in OpenLaszlo platform? - openlaszlo

How do you add a brand new attribute to a node in an OpenLaszlo XML dataset?

The way to do this is to use the lz.datapointer.setNodeAttribute() function. If you use the setNodeAttribute() function with an attribute name that does not already appear on the node, a new one will be created.
In the sample OpenLaszlo application below, if you press the button titled [displayXML] after you compile the program, you will see the XML dataset before any changes are made does not contain any "fav_saying" attribute.
After you click the [updateAttribute] button to add the favorite saying for Homer via the setNodeAttribute() method, you can then click the [displayXML] button again and you will see that an attribute called 'fav_saying' has been added to the XML dataset.
<canvas height="665" width="1000" layout="axis: x" debug="true">
<dataset name="myData">
<myXML>
<person firstname="Homer" lastname="Simpson" />
<person firstname="Marge" lastname="Simpson" />
<person firstname="Montgomery" lastname="Burns" />
</myXML>
</dataset>
<button text="displayXML">
<handler name="onclick">
Debug.write(canvas.myData.serialize());
</handler>
</button>
<button text="updateAttribute">
<handler name="onclick">
var dp = canvas.myData.getPointer(); // get datapointer to XML data
dp.setXPath('myXML/person[#firstname="Homer"]'); // set xpath to Homer Simpson
dp.setNodeAttribute('fav_saying', 'DOH!');
</handler>
</button>
</canvas>
You will also see that multiple calls to setNodeAttribute() will not add additional 'fav_saying' attributes. If the program used a different value for the saying every time then the value in the 'fav_saying' attribute would change but there would still only be one 'fav_saying' attribute.

Related

Add or Append text in p:textEditor

I have p:textEditor like the following
<p:textEditor
id="editor"
widgetVar="editor"
value="#{xxxController.editorText}"
height="300"
placeholder="Enter your content"
toolbarVisible="false"/>
Have the following command button to add/append values to p:textEditor
<p:commandButton onclick="insertTag('[myValue]')" value="myValue" type="button" />
JavaScript
<script>
function insertTag( t )
{
PF( 'editor' ).insertText( t ) ;
}
</script>
But i get SCRIPT5007: Unable to get property 'insertText' of undefined or null reference when i try to click the <p:commandButton.
So how do we insert/append text using widgetVar or JavaScript to p:textEditor?
Version details
JSF 2.2,
PrimeFaces 6.2
You need to do this... Once you have the widget the "editor" variable is QuillJS object.
PF('editor').editor.insertText(0, 'Hello', 'bold', true);
See: https://quilljs.com/docs/api/#inserttext
See: https://quilljs.com/docs/api/#getlength
See Using the component ID as widgetVar name
[...] This will cause all original widget var functions to be completely unavailable because the variable editor is now referencing a HTMLDivElement instance which doesn't have the same functions as the original widget var like show(), etc. [...]
(Append a _vw to every widgetvar name, to eliminate that issue)
SCRIPT5007: Unable to get property 'insertText' of undefined or null reference
guess, that's exactly the cause, your code is not referencing the "editor"-widgetVar, but the "editor" html element, which does not know "insertText".

Lotus Notes and C#: NotesRichTextItem how to recreate content or loop through elements in respective order

I am currently exporting a lotus notes database using the C# Interop Domino assembly from NuGet,
I haven't found a way to identify objects or elements in a NotesRichTextItem in the order they were entered, for example, maybe I enter a paragraph first, then a table , then an attachment.
Is there a way to loop through the elements in their respect order ?
I have found a way to find elements with FindFirstElement, but you have to pass what element type you are looking for, this is very difficult as extracting all elements without order would make the content to lose its context.
thanks
There is a way to analyze Notes document's RichText items using DXL - a special XML format for Notes. Use DxlExporter to export a Notes document to DXL format. You can "walk" then through XML and get the content of RichText item with elements in right order.
For this RichText item e.g.
you'd get this DXL
<item name='Body'>
<richtext>
<pardef id='1'/>
<par def='1'>aaaaaaa</par>
<table widthtype='fixedleft' refwidth='1.0667in'>
<tablecolumn width='0.6729in'/>
<tablecolumn width='0.3938in'/>
<tablerow>
<tablecell>
<pardef id='3' keepwithnext='true' keeptogether='true'/>
<par def='3'>111</par></tablecell>
<tablecell>
<pardef id='4' keepwithnext='true' keeptogether='true'/>
<par def='4'>222</par></tablecell>
</tablerow>
<tablerow>
<tablecell><par def='3'>333</par></tablecell>
<tablecell><par def='4'>444</par></tablecell>
</tablerow>
</table>
<pardef id='5' leftmargin='1.2500in' list='bullet'/>
<par def='5'>xxx</par>
<par def='5'>yyy</par>
<par def='5'>zzz</par>
<pardef id='6' leftmargin='1in'/>
<par def='6'>
<attachmentref name='icon16.gif' displayname='icon16.gif'>
<picture height='34px' width='61px'>
<notesbitmap>lQAmAAAAAAAAAAAAA...</notesbitmap>
<caption>icon16.gif</caption>
</picture>
</attachmentref>
</par>
</richtext>
</item>
Here is a Java agent which exports selected documents to a file.
import lotus.domino.*;
public class JavaAgent extends AgentBase {
#Override
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
DocumentCollection dc = agentContext.getUnprocessedDocuments();
String filename = "c:/temp/exportDocs.dxl";
Stream stream = session.createStream();
if (stream.open(filename)) {
stream.truncate();
DxlExporter exporter = session.createDxlExporter();
exporter.setRichTextOption(0);
exporter.setMIMEOption(0);
stream.writeText(exporter.exportDxl(dc));
} else {
System.out.println("Cannot open " + filename);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Unfortunately the API gives you no way to do this:
Navigation is within elements of the same type. You can find or get
the first element of a type, the next element of a type, and the nth
element of a type. You cannot find or get an element regardless of
type.
http://publib.boulder.ibm.com/infocenter/domhelp/v8r0/topic/com.ibm.designer.domino.main.doc/H_NOTESRICHTEXTNAVIGATOR_CLASS.html
UPDATE: I forgot to mention that you may want to check out a third-party tool from Genii Software called MidasLSX that possibly could help you. http://www.geniisoft.com/showcase.nsf/MidasLSX

How to get the value of Radiobutton Listitem using Javascript

I want to get the value of the selected item of a radiobutton List using javascript.
My code is:
<asp:RadioButtonList runat="server" ID="Radio" RepeatColumns="3" CssClass="textfont">
<asp:ListItem Value="1" Selected="True">First</asp:ListItem>
<asp:ListItem Value="2">Second</asp:ListItem>
<asp:ListItem Value="3">Third</asp:ListItem>
</asp:RadioButtonList>
And this is my Javascript code:
<script type="text/javascript">
function sendParameters() {
var Id = '<%=HiddenField1.Value%>';
var ddl1 = document.getElementById("Radio").checked;
</script>
How to proceed?
First of all please view the source of the resulting web page and post the resulting radio button html. This will make it easier to answer because then the question comes down to plain HTML and jQuery.
The Reason is asp often changes the name of the ID, unless you add ClientIDMode="Static" to your control.
Once that is done this should do it:
var chosenValue = $('input:radio[id="Radio"]:checked').val();
alert(chosenValue);

Is it possible to have a while loop connected to the mouseover state in an OpenLaszlo app?

Is it possible to do something like this
while (view.mouseover == true) {
preform action
}
I want to have an action repeat for as long as the mouse is over a specific view.
(asked on the laszlo-user mailing list)
Well, it looks like you answered your own question while I was testing my solution to make sure it worked correctly, but here is an alternative solution that works under OpenLaszlo 4.9.0 SWF10 and OpenLaszlo 4.9.0 DHTML run-times:
<canvas width="1000" height="665" debug="true">
<view id="v" bgcolor="0xcccccc" width="200" height="200">
<!--- #param boolean mouseisover: true when the mouse is over -->
<attribute name="mouseisover" type="boolean" value="false" />
<!--- #keywords private -->
<!--- #param lz.Delegate dlgt_repeat: stores the lz.Delegate object -->
<attribute name="dlgt_repeat" type="expression" />
<!--
Called when the 'onmouseover' event occurs
-->
<handler name="onmouseover">
// Step 1) unregister any existing delegate
// mark it for garbage collection
// and prevent its event from triggering:
if (this['dlgt_repeat'])
this.dlgt_repeat.unregisterAll();
// Step 2) update this.mouseisover flag:
if (!this.mouseisover)
this.setAttribute('mouseisover', true);
// Step 3) create an event Delegate and call it
// on the next application idle event:
var objDlgt = new lz.Delegate(this, 'doSomething');
this.setAttribute('dlgt_repeat', objDlgt);
lz.Idle.callOnIdle(this.dlgt_repeat);
</handler>
<!--
Called when the 'onmouseout' event occurs
-->
<handler name="onmouseout">
// Step 1) unregister any existing delegate
// mark it for garbage collection
// and prevent its event from triggering:
if (this['dlgt_repeat'])
this.dlgt_repeat.unregisterAll();
// Step 2) Update this.mouseisover flag:
if (this.mouseisover)
this.setAttribute('mouseisover', false);
</handler>
<!--- #keywords private -->
<!---
Called on application idle event by lz.Idle repeatedly
when the mouse is down.
#param ??? objDummy: required for SWF9+ run-times for methods
called by delegates due to AS3 (ActionScript3 compiler
requirements). Just set default to null to make compiler
happy and ignore...
-->
<method name="doSomething" args="objDummy=null">
<![CDATA[
// Note: CDATA allows '&&' to be used in script below,
// alternatively omit CDATA and use '&&' instead
// of '&&'
// Step 1) Execute your code you want to run here:
if ($debug) Debug.debug('Do something...');
// Step 2): If mouse is still over and the event
// delegate exists then schedule the event to be
// executed upon the next application idle state:
if (this.mouseisover && this['dlgt_repeat'] != null)
lz.Idle.callOnIdle(this.dlgt_repeat);
]]>
</method>
<text text="Move mouse over" />
</view>
</canvas>
Since both ActionScript and JavaScript are single threaded, it's not possible to have a while loop with pauses between each loop iteration. In the SWF10/11 runtime, you need to make sure that the code within each method or function can be executed within one frame (duration depends on the framerate of the SWF clip) of your application.
As a workaround you can use a timer, here is an example:
<canvas debug="true">
<class name="mouseoverview" extends="view"> <attribute name="timer" type="object" value="null" />
<!-- lz.Delegate instance used by the timer -->
<attribute name="timerdel" type="object" value="null" />
<attribute name="timeractive" type="boolean" value="false" />
<!-- milliseconds to pause before each call to doWhileMouseover method -->
<attribute name="tick" type="number" value="500" />
<handler name="onmouseover">
Debug.info('mouseover');
if (this.timeractive == false) {
this.setAttribute('timeractive', true);
this.timerdel = new lz.Delegate( this, "timerCallback" );
this.timer = lz.Timer.addTimer( this.timerdel, this.tick );
// When the timer is activated, do one call to the method
// containing the loop logic. The following calls will be
// handled by the timer and delegate.
this.doWhileMouseover();
}
</handler>
<handler name="onmouseout">
Debug.info('mouseout');
if (this.timeractive) {
this.setAttribute('timeractive', false);
lz.Timer.removeTimer(this.timerdel);
}
</handler>
<method name="timerCallback" args="millis">
if (this.timeractive) {
lz.Timer.resetTimer(this.timerdel, this.tick);
this.doWhileMouseover();
}
</method>
<method name="doWhileMouseover">
Debug.info("This is your virtual while loop for mouseover");
</method>
</class>
<mouseoverview x="100"
y="100"
width="400"
height="400"
bgcolor="#33aaff"
tick="250">
</mouseoverview>
</canvas>
When a mouseover occurs, a timer is started using the timerdel (an instance of lz.Delegate). Then the doWhileMouseover() method is called once directly, and then repeatedly using the timer, as long as no onmouseout event happened.

Aggregating local events in SCXML

My state machine has a self loop every time some request event is created. I want to store these events in a local context list against a key and everytime this self loop is executed an element is appended to the list. Then this list after a certain expiry period ,of say 1 Hour , is added to global context of SCXML. How can I achieve this?
Basically I want to aggregate the requests before I trigger a particular action.
<state id="S02" label="REQUEST CREATED">
<onentry>
<action:trigger id="ACC1" name="EXPIRY_EVENT_expiry.sm00007" />
</onentry>
<transition event="expiry.sm00007" target="S03">
<action:trigger id="ACC2" name="TO_DO_SOMETHING" />
// add the local event list to global context
</transition>
<transition event=reqCreated" target="S02" >
// keep adding the event to local context like appending to list
</transition>
</state>
In the SCXML spec, all datamodel variables are global so there's not really a "local" context. But you could use a key to index into a JavaScript object. Something like:
<datamodel>
<data id="globalEventList"/>
<data id="localEventListMap" expr="{}"/>
<data id="localKey" expr="'foo'"/>
</datemodel>
<state id="init">
<onentry>
<script>
localEventListMap[localKey] = [];
</script>
</onentry>
<transition target="S02"/>
</state>
<state id="S02" label="REQUEST CREATED">
<onentry>
<action:trigger id="ACC1" name="EXPIRY_EVENT_expiry.sm00007" />
</onentry>
<transition event="expiry.sm00007" target="S03">
<action:trigger id="ACC2" name="TO_DO_SOMETHING" />
<script>
// add the local event list to global context
globalEventList = localEventListMap[key];
</script>
</transition>
<transition event="reqCreated" target="S02" >
<script>
// keep adding the event to local context like appending to list
localEventListMap[key].push(_event);
</script>
</transition>
</state>

Resources