Orbeon 4.2 switch case - switch-statement

I am trying to upgrade my orbeon to using the new orbeon 4.2. But I have a problem in the switch case that I used in my source code. It is having problem trying to toggle the case.
<xforms:action ev:event="xxforms-invalid" ev:observer="main">
<xforms:toggle case="invalid-form-case" if="instance('main')/current_session/student_module_regn_status = 'Close'"/>
</xforms:action>
<xforms:action ev:event="xxforms-valid" ev:observer="main">
<xforms:toggle case="valid-form-case" if="instance('main')/current_session/student_module_regn_status = 'Open'"/>
</xforms:action>
Below is the code for the switch case :
<xforms:switch>
<xforms:case id="invalid-form-case">
Closed
</xforms:case>
<xforms:case id="valid-form-case">
Open
</xforms:case>
Thanks
Here is a example that would reproduce the problem :
<html xmlns:xxforms="http://orbeon.org/oxf/xml/xforms"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xforms="http://www.w3.org/2002/xforms"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xxi="http://orbeon.org/oxf/xml/xinclude"
xmlns:widget="http://orbeon.org/oxf/xml/widget"
xmlns:xdt="http://www.w3.org/2005/02/xpath-datatypes"
xmlns:f="http://orbeon.org/oxf/xml/formatting"
xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>test</title>
<xhtml:link rel="stylesheet" href="/apps/uis-common/css/app-form.css" type="text/css"/>
<xforms:model>
<xforms:instance id="main">
<mains>
<test1>Open</test1>
</mains>
</xforms:instance>
<xforms:action ev:event="xxforms-invalid" ev:observer="main">
<xforms:toggle case="invalid-form-case" if="instance('main')/test1 = 'Close'"/>
</xforms:action>
<xforms:action ev:event="xxforms-valid" ev:observer="main">
<xforms:toggle case="valid-form-case" if="instance('main')/test1 = 'Open'"/>
</xforms:action>
</xforms:model>
</head>
<body dir="ltr">
<div>
<table width="100%" id="wrapper" border="0" cellspacing="0" cellpadding="0">
<tr>
<td>
<xforms:switch>
<xforms:case id="invalid-form-case">
CLOSE
</xforms:case>
<xforms:case id="valid-form-case">
OPEN
</xforms:case>
</xforms:switch>
</td>
</tr>
</table>
</div>
</body>
</html>
it suppose to show "OPEN" as the "test1" is Open but no matter what the "test1" is, it just show "CLOSE"

The reason for the change is as follows:
In previous versions, the xxforms-valid and xxforms-invalid events dispatched to xforms:instance were dispatched during each revalidation. In recent versions, this behavior has changed, as mentioned in the compatibility notes.
As per the XForms processing model, upon XForms initialization, the following is done:
creation of models and instances
initial recalculate and revalidate
creation of the control tree
In your example, the first xxforms-valid or xxforms-invalid event is dispatched before the control tree is created. This means that your event handler doesn't find controls to toggle. Before 4.0, you would probably get at least one dispatch of xxforms-valid or xxforms-invalid after the control tree got created, so the toggle would work.
The better fix is probably to do something like this:
<xf:toggle
ev:event="xforms-ready"
if="xxf:valid(instance('main'), true())"
case="...">

Related

Automating click to image-mapped actions/links using Node/Nightwatch

How does one use NightwatchJs to automate clicking a specific part of an image? My naive approach is to select the coords attribute that matches the specific area of the image I'd like to trigger; but it doesn't work.
<img src="..." usemap="#example">
<map name="example" id="example">
<area shape="rect" coords="336,10,401,32" href="...">
<area shape="rect" coords="25,171,97,198" href="...">
...
</map>
Anyone encounter this issue or know of a work around? Thanks!
If I were you, I would play with the position of area elements inside the map element using CSS selectors like :first-child or :first-of-type. Here is a minimal working example:
PNG (map.png)
HTML/JS (index.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Nightwatch</title>
</head>
<body>
<img src="map.png" usemap="#map">
<map name="map">
<area shape="circle" coords="51,51,29">
</map>
<script>
// When the red area is clicked, we should display an alert.
var area = document.querySelector('area');
area.addEventListener('click', function () {
alert('OK');
}, false);
</script>
</body>
</html>
Nightwatch (script.js)
module.exports = {
'Clickable image map': function (browser) {
browser
.url('http://localhost:8000/index.html')
.waitForElementPresent('map', 1000)
.click('map > area:first-child');
// ...
},
};
Command
If your environment is properly set up, you can run the script with nightwatch -t tests/script.js. You will see the alert, meaning that the red area has been clicked by Nightwatch.

Hammerjs events order for nested elements

Consider two nested divs with "click" event handlers:
var parent = document.getElementById("parent");
parent.addEventListener("click", function() {
console.log("parent click");
});
var child = document.getElementById("child");
child.addEventListener("click", function() {
console.log("child click");
});
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div id="parent" style="width:150px;height:100px;border: 1px solid black">
<div id="child" style="width:75px;height:50px;border: 1px solid black"></div>
</div>
</body>
</html>
When one clicks on the nested element the "click" event "bubbles", so the output in the console looks like this:
child click
parent click
Now consider similar example with Hammerjs involved:
var parent = document.getElementById("parent");
var hammer1 = new Hammer(parent).on("tap", function() {
console.log("parent click");
});
var child = document.getElementById("child");
var hammer2 = new Hammer(child).on("tap", function() {
console.log("child click");
});
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.js"></script>
</head>
<body>
<div id="parent" style="width:150px;height:100px;border: 1px solid black">
<div id="child" style="width:75px;height:50px;border: 1px solid black">
</div>
</div>
</body>
</html>
When one clicks on the nested element the console output is the opposite (parent's event handled first):
parent click
child click
To get the "bubble" event order one has to register child event handler before the parent's one.
Is there any way to achieve the same effect without messing with the order of event handler registrations?
Using jQuery, here's one trick I used successfully:
Normally you would do something like this:
$("some_selector").hammer().on('press', handlePress);
But to get the order right with Hammer events, this works:
$($("some_selector").get().reverse()).hammer().on('press', handlePress);
It's just a trick to get jQuery to assign the events in the reverse order (from the leaf children up the tree to the parents and parents parents etc.)
I looked into this because I ran into the very same issue.
To understand the problem you need to know how hammerjs recognizes gestures (consisting of several events); in this case the "tap"-gesture.
Hammer installs so-called recognizers that get activated when certain events travel (bubble) along the DOM.
The "tap"-event gets triggered when the "pointerup"-event bubbles up to the window.
When the "pointerup"-event reaches the window (event.currentTarget is window) all registered recognizers get actived on that node's event and that is in the order of installation.
To respect the propagation line the "tap"-recognizer would have to fire on their respective element's "pointerup" event rather than on window.
Hope that is a somewhat consistent explanation.

Riot-tag inside of a loop

I have a xxx component, which when used with the riot-tag attribute and a standard HTML5 tag, works correctly: <article riot-tag="xxx"></article>. However when I use the riot-tag attribute inside of a loop, the tag is empty: <article each="{xxxTags}" riot-tag="{xxx}"></article>. Is using riot-tag in a loop possible at all? How can I make it work?
Additional explanation:
I have to generate several different, albeit similar components one by one. So I have an array to store them:
var xxxTags = [{tag: 'xxx'}, {tag: 'yyy'}, {tag: 'zzz'}];
Putting any of the textareas one by one manually for all of: xxx, yyy, zzz works fine and generates the respective components. However when I try to do it with each, they end up empty (no children) in chrome devtools, BUT otherwise identical to the ones put manually.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<my-tag></my-tag>
<!-- inlined tag definition -->
<script type="riot/tag">
<my-tag>
/*Standard, manual addition of different components (works)*/
<xxx></xxx>
<yyy></yyy>
<zzz></zzz>
/*Standard addition of same components in a loop (works)*/
<div each={myTags}>{tag}</div>
<br>
/*Addition of different components with "riot-tag" manually (works)*/
<div riot-tag="xxx"></div>
<div riot-tag="yyy"></div>
<div riot-tag="zzz"></div>
/*Addition of different components with "riot-tag" in a loop (DOESN'T WORK should look like the example above)*/
<div each={myTags} riot-tag="{tag}"></div>
this.myTags = [{tag: 'xxx'}, {tag: 'yyy'}, {tag: 'zzz'}];
</my-tag>
<xxx>
<p>X content</p>
</xxx>
<yyy>
<p>Y content</p>
</yyy>
<zzz>
<p>Z content</p>
</zzz>
</script>
<!-- include riot.js and the compiler -->
<script src="//cdn.jsdelivr.net/g/riot#2.2(riot.min.js+compiler.min.js)"></script>
<!-- mount normally -->
<script>
riot.mount('*');
</script>
</body>
</html>
Okay, looks, like the tags with riot-tag attribute are not mounted when generated with an each-loop (still looks like a bug?). For the above-mentioned code, adding this does the job:
this.on('mount', function() {
for(var i = 0; i < this.myTags.length; i++) riot.mount(this.myTags[i].tag);
});

notifyjs notification is not working with position of an element

<script src="js/jquery-2.1.1.js"></script>
<script src="notify/js/notify.js"></script>
<script src="notify/js/notify-bootstrap.js"></script>
<form>
<div id="userInfoDiv" name="userInfoDiv" style="padding-top:100px;padding-left:100px;">
<span class="box pos-demo">Notifyjs position div</span>
</div>
</form>
<script type="text/javascript">
$(".pos-demo").notify(
"Welcome Guest",
{ position:"right" }
);
$.notify("This notofication is working ","success");
</script>
Note : The notification is not displayed.Where as $,notify("") without position is working fine.
I have the same problem. Though I cannot confirm this the cause I think its because at the time of the notification, the elements do not actually exist in the DOM (the web page), so there is nothing for the element to tie to. It fails silently, I used the Google developer tools and could see no error being generated.
My solution. If you create a function and call in body.onload the element appears. e.g
<body onload="notifyme();">
And then somewhere in the page (at the bottom perhaps)
<script>
function notifyme() {
var s = "Hello";
$("#myelem").notify(s);
}
</script>
I know this works a I have just tried it. Works every time, every page.

Sitemesh layout doesn't work with g.include tag in Grails

I am rendering a view that combines a g.include invocation and a sitemesh layout.
The view would be something like this:
myview.gsp
<html>
<head>
<meta name="layout" content="checkout" />
</head>
<body>...
within the body there is an invocation to:
g.include(controller:"mycontroller", action:"myaction")
The problem is the sitemesh layout is never applied. If I remove the include invocation things work just fine.
I haven't found references to this problem in the site yet.
Has anyone found a workaround to this issue or a tip, will be much appreciated!
Thanks
-Pablo Duranti
My index file is like underlying:
<html>
<head>
<title>App Store For Publish, Download Android Apps</title>
<meta name="layout" content="main" />
<parameter name="sideBarSetting" value="main"/>
</head>
<body>
<g:if test="${flash.message}">
<div class="message">${flash.message}</div>
</g:if>
<g:announcements/>
<g:include controller="cache" action="showFeatured"/>
<g:include controller="cache" action="latestProducts"/>
<div class="push"></div>
<g:include controller="cache" action="mostPopular"/>
<div class="push"></div>
<g:include controller="cache" action="allCategories"/>
</body>
It works in Grails 1.0, 1.2.2 and now 1.3.7.
In each of actions you try to include, you can not render the view, but render the template instead. The template file can ONLY has fragments of HTML, it can NOT include the head, meta for layout, etc.
In my cache controller
def latestProducts = {
cache shared:true, validFor: 300
def htmlCacheManager = HtmlCacheManager.getInstance()
def key = 'latestProducts'
def content = htmlCacheManager.getHtmlContent(key)
if (!content) {
def products = productService.get5LatestProducts(params)
if (products){
content = g.render(template:'/common/product/productLatestListTemplate', model:['productInstanceList' : products, 'type':'latest'])
htmlCacheManager.store(key, content, Boolean.TRUE)
} else {
log.debug('No latest product found')
}
}
render content ?: ''
}
The template file:
<div class="list">
<fieldset>
<legend><g:message code="product.latest"/> <g:link action="feed" controller="product" params="['type':type]" target="_blank"><img src="${resource(dir:'images', file:'feed-icon.gif')}" height='16' width='16' alt="Feeds"/></g:link></legend>
<g:each in="${productInstanceList}" var="product">
<div class="product">
<g:render template="/common/product/productSingleListTemplate" model="['product':product]" />
</div>
</g:each>
</fieldset>
</div>

Resources