Four rows of four cells
<instance> <game xmlns=""> <row><cell>1</cell><cell>5</cell><cell>8</cell><cell>12</cell></row> <row><cell>2</cell><cell>6</cell><cell>9</cell><cell>13</cell></row> <row><cell>3</cell><cell>7</cell><cell>10</cell><cell>14</cell></row> <row><cell>4</cell><cell>.</cell><cell>11</cell><cell>15</cell></row> </game> </instance>
Four rows of four cells
<instance> <game xmlns=""> <row><cell>1</cell><cell>5</cell><cell>8</cell><cell>12</cell></row> <row><cell>2</cell><cell>6</cell><cell>9</cell><cell>13</cell></row> <row><cell>3</cell><cell>7</cell><cell>10</cell><cell>14</cell></row> <row><cell>4</cell><cell>.</cell><cell>11</cell><cell>15</cell></row> </game> </instance>
<repeat ref="row"> <repeat ref="cell" > <output value="."/> </repeat> </repeat>
Four rows of four cells
<instance> <game xmlns=""> <row><cell>1</cell><cell>5</cell><cell>8</cell><cell>12</cell></row> <row><cell>2</cell><cell>6</cell><cell>9</cell><cell>13</cell></row> <row><cell>3</cell><cell>7</cell><cell>10</cell><cell>14</cell></row> <row><cell>4</cell><cell>.</cell><cell>11</cell><cell>15</cell></row> </game> </instance>
<repeat ref="row"> <repeat ref="cell" > <output value="."/> </repeat> </repeat>
Add a dash of CSS.
Of course, this doesn't do anything yet.
<repeat ref="row"> <repeat ref="cell" > <trigger appearance="minimal"> <label><output value="."/></label> </trigger> </repeat> </repeat>
trigger
is the XForms version of HTML's button
,
but XForms tries to be device-neutral.
"appearance="minimal"
" means it isn't displayed as a button.
It still doesn't do anything.
<repeat ref="row"> <repeat ref="cell" > <trigger appearance="minimal"> <label><output value="."/></label> <action ev:event="DOMActivate"> ... </action> </trigger> </repeat> </repeat>
This says to respond to the trigger being activated (eg a click).
<repeat ref="row"> <repeat ref="cell" > <trigger appearance="minimal"> <label><output value="."/></label> <action ev:event="DOMActivate"> <setvalue ref="//cell[.='.']" value="context()"/> <setvalue ref="." value="'.'"/> </action> </trigger> </repeat> </repeat>
If you click on any of the squares, it will swap the value there with the square holding "."
We only want to allow swapping the empty square with an adjacent one.
Add a condition to the action.
<repeat ref="row"> <repeat ref="cell" > <trigger appearance="minimal"> <label><output value="."/></label> <action ev:event="DOMActivate" if="..."> <setvalue ref="//cell[.='.']" value="context()"/> <setvalue ref="." value="'.'"/> </action> </trigger> </repeat> </repeat>
Only do the action if the next or previous cell, or the cell at the same position in the previous/next row is ".".
following-sibling::cell[1]='.' or preceding-sibling::cell[1]='.' or ../following-sibling::row[1]/ cell[1+count(context()/preceding-sibling::cell)]='.' or ../preceding-sibling::row[1]/ cell[1+count(context()/preceding-sibling::cell)]='.'
<trigger appearance="minimal"> <label><output mediatype="image/*" value="."/></label>
This says: Interpret the value as a URL and display it as an image.
Only problem: you may not have a file called ".".
<trigger appearance="minimal"> <label><output mediatype="image/*" value="if(.='.', 'blank', .)" /> </label> </trigger>