Typo3 Fluid: elseif inline notation - fluid

Is there an inline notation for the following example?
<f:if condition="{value}==1">
<f:then>Value is 1</f:then>
<f:else if="{value}==2">Value is 2</f:else>
</f:if>
Thanks for your help

probably it will be the cascading of if-viewhelpers:
{f:if(condition:'{value}==1',
then:'Value is 1',
else:'{f:if(condition:\'{value}=2\', then:\'Value is 2\')}'
)}
with the usual drawback of escaping string-delimiter for stacked inline viewhelpers.

your condition will default to 'Value is 2' although the value might not be ... this is not true, anyhow a bit more complete:
<f:if condition="{value}==1">
<f:then>Value is 1</f:then>
<f:else if="{value}==2">Value is 2</f:else>
<f:else>Value is not valid</f:else>
</f:if>
simple inline annotation that does not output anything if the two conditions are not met:
{f:if(condition:'{value}==1',
then: 'Value is 1',
else: '{f:if(condition:\'{value}==2\',then: \'Value is 2\')}'
)}
add the else clause in the second condition:
{f:if(condition:'{value}==1',
then: 'Value is 1',
else: '{f:if(condition:\'{value}==2\',
then: \'Value is 2\',
else: \'Value is not valid\'
)}'
)}

Related

xQuery: test for two specific children with 'and'

Assume I have the following snippet
<persName>
<forename>Gaius</forename>
<surname>Iulius</surname>
<addName>Caesar</addName>
</persName>
I need a result like [surname], [forename] where the comma should only be present if necessary.
In XSLT, I'd simply use
<xsl:value-of select="surname" />
<xsl:if test="surname and forename"><xsl:text>, </xsl:text></xsl:if>
<xsl:value-of select="forename" />
Now I naively thought I could transfer this to XQuery – and failed.
I was slightly puzzled that
if ($node/forename) then "1" else "0"
if ($node/surname) then "1" else "0"
if ($node/surname and $node/forename) then "1" else "0"
will give 1, 1, 0, respectively.
I worked around this by counting the number of children in one of these cases but I'm still puzzled why this is the way it is.
Tanks for any input!
Edit: here's the code I've been using:
declare function habe:shortName($node) {
<span>{
if ($node/tei:name) then $node/tei:name
else
let $tr := if ($node/tei:surname and count($node/tei:forename)>0) then ", " else ""
return concat($node/tei:surname, $tr, $node/tei:forename)
}</span>
};
which, when given the above snippet, returned IuliusGaius.
I then tried the three tests above and got the stated result.
I'm doing this on eXist – maybe their implementation is faulty?
Edit: Thanks to #MichaelKay and #joewiz for hinting at misleading typos!
The following code returns the expected results, (1, 1, 1), using eXide on http://exist-db.org/exist/apps/eXide/index.html:
xquery version "3.0";
let $node :=
<persName>
<forename>Gaius</forename>
<surname>Iulius</surname>
<addName>Caesar</addName>
</persName>
return
(
if ($node/forename) then "1" else "0",
if ($node/surname) then "1" else "0",
if ($node/surname and $node/forename) then "1" else "0"
)
One solution to your original problem (adding a ', ' if both forename and surname exist) is to use string-join($strs as xs:string*, $joiner as xs:string) instead of concat($string as xs:string[...]):
let $name :=
<persName>
<forename>Gaius</forename>
<surname>Iulius</surname>
<addName>Caesar</addName>
</persName>
return string-join(($name/surname, $name/forename), ', ')
This returns Iulius, Gaius.
You can also check for presence of nodes directly in boolean expressions:
let $name :=
<persName>
<forename>Gaius</forename>
<surname>Iulius</surname>
<addName>Caesar</addName>
</persName>
return (
$name/surname and $name/forename,
$name/surname and $name/foo
)
This returns true false.

Inline notation of TYPO3 Fluid view helper `f:for`

I would like to fill an attribute value in a TYPO3 Fluid template with a loop (f:for) by using its inline notation:
<div class="one two three">[...]</div>
Does anybody know how to do that?
In the meanwhile I found a solution for my problem. To print all items of an array you could do something like {x -> f:for(each: {0: 'one', 1: 'two', 2: 'three'}, as: 'x')}. But this will result in: onetwothree. To fix that the view helper f:if helps:
<div class="{f:if(condition: i.isLast, then: '{x}', else: '{x} ')
-> f:for(each: {0: 'one', 1: 'two', 2: 'three'}, as: 'x', iteration: 'i')}">
[...]
</div>
You can tweak the solution of #witrin a litte more and write ind completely inline:
{f:if(condition: i.isLast, then: '{x}', else: '{x} ') -> f:for(each: '{item.thing}', as: 'x', iteration: 'i')}
Please find following inline notations,
It helps you lot.
Inline Notation for for loop
Original -> `<f:for each="{data.title}" as="title"> {title} </f:for>`
Inline Notation -> {title -> f:for(each: '{data.title}', as: 'title')}
Inline Notation for date
Date :-> `<f:format.date cldrFormat="MMMM y" forceLocale="{true}" localeFormatType="date">1-{calendar.month}-{calendar.year} 00:00:00</f:format.date>`
Inline Notation :-> {f:format.date(date:'1-{calendar.month}-{calendar.year} 00:00:00',cldrFormat:'MMMM y',localeFormatType: 'date', forceLocale: true)}
so on...
I guess you are looking for some 'advanced' array handeling in fluid?
have a look at https://fluidtypo3.org/viewhelpers/vhs/master.html.

MVC 4 WebGrid Checkbox in a column with Condition

I'm trying to add a new column to a .Net MVC WebGrid that includes a checkbox that is there if a specific condition is met and not there if the condition is false.
The below code works to correctly display X or Y (placeholder):
grid.Column("ID", header: "",
style: "labelcolumn",
format: (item) => item.ID != null ? "X" : "Y"),
I can't seem to get the syntax right to include the checkbox instead of X.
grid.Column("ID", header: "",
style: "labelcolumn",
format: (item) => item.ID != null ? #<text><input class="check-box" id="cbSelectedBranch" name="cbSelectedBranch" type="checkbox" value="#item.ID" /></text> : "Y"),
On this second snippet, the "(item)" variable causes this error:
CS0136: A local variable named 'item' cannot be declared in this scope
because it would give a different meaning to 'item', which is already
used in a 'parent or current' scope to denote something else
Adding the # when using the if null condition seems to cause item to throw this error. The below code, without the conditional, works correctly:
grid.Column(header: "",
style: "labelcolumn",
format: #<text><input class="check-box" id="cbSelectedBranch" name="cbSelectedBranch" type="checkbox" value="#item.ID" /></text>),
Any idea how I can make this work with a conditional and checkbox input?
try like this:
format: (item) => item.ID != null ? Html.Raw("<input class='check-box' id='cbSelectedBranch' name='cbSelectedBranch' type='checkbox' value='#item.ID' />") : "Y")

Ember.js input fields

Is it possible to use standard HTML5 input fields in an Ember.js view, or are you forced to use the limited selection of built in fields like Ember.TextField, Ember.CheckBox, Ember.TextArea, and Ember.select? I can't seem to figure out how to bind the input values to the views without using the built in views like:
Input: {{view Ember.TextField valueBinding="objectValue" }}
Specifically, I'm in need of a numeric field. Any suggestions?
EDIT: This is now out of date you can achieve everything above with the following:
{{input value=objectValue type="number" min="2"}}
Outdated answer
You can just specify the type for a TextField
Input: {{view Ember.TextField valueBinding="objectValue" type="number"}}
If you want to access the extra attributes of a number field, you can just subclass Ember.TextField.
App.NumberField = Ember.TextField.extend({
type: 'number',
attributeBindings: ['min', 'max', 'step']
})
Input: {{view App.NumberField valueBinding="objectValue" min="1"}}
#Bradley Priest's answer above is correct, adding type=number does work. I found out however that you need to add some attributes to the Ember.TextField object if you need decimal numbers input or want to specify min/max input values. I just extended Ember.TextField to add some attributes to the field:
//Add a number field
App.NumberField = Ember.TextField.extend({
attributeBindings: ['name', 'min', 'max', 'step']
});
In the template:
{{view App.NumberField type="number" valueBinding="view.myValue" min="0.0" max="1.0" step="0.01" }}
et voile!
Here is my well typed take on it :
App.NumberField = Ember.TextField.extend({
type: 'number',
attributeBindings: ['min', 'max', 'step'],
numericValue: function (key, v) {
if (arguments.length === 1)
return parseFloat(this.get('value'));
else
this.set('value', v !== undefined ? v+'' : '');
}.property('value')
});
I use it that way:
{{view App.NumberField type="number" numericValueBinding="prop" min="0.0" max="1.0" step="0.01" }}
The other systems where propagating strings into number typed fields.
You may also wish to prevent people from typing any old letters in there:
App.NumberField = App.TextField.extend({
type: 'number',
attributeBindings: ['min', 'max', 'step'],
numbericValue : function (key,v) {
if (arguments.length === 1)
return parseFloat(this.get('value'));
else
this.set('value', v !== undefined ? v+'' : '');
}.property('value'),
didInsertElement: function() {
this.$().keypress(function(key) {
if((key.charCode!=46)&&(key.charCode!=45)&&(key.charCode < 48 || key.charCode > 57)) return false;
})
}
})
Credit where its due: I extended nraynaud's answer
This is how I would do this now (currently Ember 1.6-beta5) using components (using the ideas from #nraynaud & #nont):
App.NumberFieldComponent = Ember.TextField.extend
tagName: "input"
type: "number"
numericValue: ((key, value) ->
if arguments.length is 1
parseFloat #get "value"
else
#set "value", (if value isnt undefined then "#{value}" else "")
).property "value"
didInsertElement: ->
#$().keypress (key) ->
false if (key.charCode isnt 46) and (key.charCode isnt 45) and (key.charCode < 48 or key.charCode > 57)
Then, to include it in a template:
number-field numericValue=someProperty

Searching with CDbCriteria

Is there any way to make a CDbCriteria search (as in compare()) in the fields I'm selecting, but using the model's search() method instead of having to manually add the compare() conditions?
Note that I'm aiming at a solution that will let me write some fewer lines, nothing more and nothing less. So, if the solution is something really hacky and/or mesy, I'll just go for the "add-a-few-compares()" method.
My current code:
$criteria = new CDbCriteria;
$criteria->with = array('A', 'B', 'C', 'D', 'E');
$criteria->compare("A.field1", "test", false, 'OR');
$criteria->compare("A.field2", "test", false, 'OR');
$criteria->compare("B.field1", "test", false, 'OR');
$criteria->compare("B.field2", "test", false, 'OR');
$dataProvider = new CActiveDataProvider('Z', array(
'criteria'=>$criteria,
//pagination...
//more options...
));
Update: It seems that you are actually looking(from comments below this answer) for partial matches, and for that you will have to pass true to your compare calls:
$criteria->compare("A.field1", "test", true, 'OR');
Even that can be passed to addCondition:
$criteria->addCondition('A.field1 LIKE "%test"','OR');
// or with params as below
$criteria->addCondition('A.field2 LIKE :test','OR');
$criteria->params=array(
':test'=>'%test%',
);
As i have already mentioned in the comments, i don't think it'll be possible to use each model's default search() method. There are other alternatives though, for instance you can use addCondition instead:
$criteria = new CDbCriteria;
$criteria->with = array('A', 'B', 'C', 'D', 'E');
$criteria->together = true; // you'll need together so that the other tables are joined in the same query
$criteria->addCondition('A.field1 = "test"','OR');
$criteria->addCondition('A.field2 = "test"','OR');
// and so on
I would suggest going with the above, because compare (doc-link) should actually be used in cases when you want to "intelligently" determine the operator for comparision, for example: if you are taking the test values from user input and the user is allowed to use operators (<,>,<= etc). After determining the operator to be used in the condition, compare calls other functions accordingly, including addCondition. So using addCondition will atleast avoid those unnecessary checks.
Further if all you have to do is check equality only, i.e if your sql's WHERE is supposed to be:
WHERE A.field1 = "test" OR A.field2 = "test"
then you don't even need addCondition, and you can simply use a more complex condition (doc) :
$criteria->condition='A.field1 = "test" OR A.field2 = "test"';
// or even better if you use params
$criteria->condition='A.field1 =:test1 OR A.field2 =:test2 OR B.field1 =:test3 OR B.field2 =:test3';
$criteria->params=array(
':test1'=>'test',
':test2'=>'anothertest',
'test3'=>'tests' // omitting ':' here for params also works
);