can someone suggest how possible to interpret <c:set> body?
<c:set var="movieList">One,Two,Three</c:set>
<c:set var="movieList">"One","Two","Three"</c:set>
in the first case movieList is a string and in the second it is an array {"One", "Two", "Three"}
what is movieList in these examples:
<c:set var="movieList">"On"e","Tw"o","Thr"ee"</c:set>
<c:set var="movieList">"On\"e","Tw"o","Thr\"ee"</c:set>
There's no difference in the interpreted Java type of the c:set's body. It are in all cases just String.
Even when you set a non-String type as c:set's body using EL such as
<c:set var="foo">${bean.someInteger}</c:set>
it'll be converted to String anyway by String#valueOf().
Only when you process the variable afterwards, there may be difference, depending on how you processed it. For example,
<c:set var="movieList">One,Two,Three</c:set>
<c:set var="realMovieArray" value="${fn:split(movieList, ',')}" />
will result ${realMovieArray} being a String[] with values of One, Two and Three.
<c:set var="alphabet">A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z</c:set>
<c:forTokens items="${alphabet}" delims="," var="letter">
${letter}
</c:forTokens>
Related
I'd like to use an "Array" in JSTL that looks like this
<c:set var="hideMe" value="${['A','B','C','D']}" scope="application" />
I also have a global VAR called ${checkPageName} which has the name of the current page I am on in it, so I can check against it, as part of the logic (e.g. <c:if test="${checkPageName != hideMe}"> ... </c:if>)
The logic behind this is that if A, B, C or D exist then I will prevent a specific piece of information from being displayed to the user.
Does anyone know how I loop through a JSTL array?
The logic should then decide that if A, B, C or D DO NOT exist, then we display specific information to the user.
I have tried;
<c:forEach items="${hideMe}">
<c:set var="hide" value="true" />
</c:forEach>
<c:if test="${hide != 'true'}">
<div class="showMe">
<h1>Hello Sweetie</h1>
</div>
</c:if>
Could someone please point me in the right direction?
UPDATE: I have now fixed this myself using <c:forTokens>, see the solution below
So I figured it out in the end;
<c:set var="hideMe" value="false" />
<c:forTokens items="A,B,C,D" delims="," var="excludeDisplay">
<c:if test="${checkPageName == excludeDisplay}">
<c:set var="hideMe" value="true" />
</c:if>
</c:forTokens>
<c:if test="${hideMe == 'false}">
DO SOMETHING
</c:if>
checkPageName is a global variable I am checking against in my code to validate well, page names...
So I set a default VAR called hideMe with a value of false, I then use forTokens to create a VAR called excludeDisplay for values A, B, C or D.
I then check these values against my global variable and if they match overwrite the var hideMe with a value of true, this is then used to trigger the content I want to show. If the VAR is false show the content, if it is true, do nothing.
I hope this helps someone else, and I am happy to elaborate on some of the murkier points if anyone wants any more information...
I need to modify an array element given the position in FreeMarker.
var arr = [];
arr[0] = "Jani";
arr[1] = "Hege";
arr[2] = "Stale";
arr[3] = "Kai Jim";
arr[4] = "Borge";
is possible to do this in freemarker, you can teach me an example
<#macro cuenta d >
<#assign posicion=0>
<#assign arregloCuenta=[]>
<#list args.array?split(",") as value>
<#assign posicion=posicion+1>
<#if d.properties["bchile:tipodoc"]?exists >
<#if d.properties["bchile:tipodoc"] == value>
<#assign arregloCuenta=["juan"]>
<#assign arregloCuenta= arregloCuenta + ["felipe"]> ${args.array[0]} ${posicion} ${arregloCuenta[1]} </#if> </#if> </#list> </#macro>
From FAQ of FreeMarker:
The FreeMarker Template Language doesn't support the modification of sequences/hashes. It's for displaying already calculated things, not for calculating data. Keep templates simple. But don't give up, you will see some advice and tricks below.
And a little more below:
For example, you want to display a keyword index on some very smart way, whose algorithm need you to create and write some sequence variables. Then you should do something like this (ugly situations has ugly solutions...):
<#assign calculatedResults =
'com.example.foo.SmartKeywordIndexHelper'?new().calculate(keywords)>
<#-- some simple algorithms comes here, like: -->
<ul>
<#list calculatedResults as kw>
<li>${kw.word}
</#list>
</ul>
That is, you move out the complex part of the presentation task from the template into Java code. Note that it doesn't affect the data-model, so the presentation is still kept separated from the other application logic. Of course, the drawback is that for this the template author will need the help of a Java programmer, but for complex algorithms that's probably needed anyway.
Also it said that is better to try to use sequence concatenation and sequence slice than this trick.
For slice and concatenation you can think in something like:
seq[0..pos-1] + ["New element"] + seq[pos+1..]
You can read the complete entry in http://freemarker.org/docs/app_faq.html#faq_modify_seq_and_map
Can anybody please tell me the exact difference between these two syntax ,
I found it by co-incidence
Structre is like this :
-> NSMutableArray (CategoryAry)
...> NSMutableDictionary (multiple number of dictionaries)
NSLog(#"%#",[(NSMutableDictionary *)[CategoryAry objectAtIndex:indexPath.row+1] valueForKey:#"status"]);
NSLog(#"%#",(NSMutableDictionary *)[[CategoryAry objectAtIndex:indexPath.row+1] valueForKey:#"status"]);
Although both print the same results .
[(NSMutableDictionary *)[CategoryAry objectAtIndex:indexPath.row+1] valueForKey:#"status"]);
the "objectAtIndex" is casted to an NSMutableDictionary*, then a value "status" is searched inside it.
(NSMutableDictionary *)[[CategoryAry objectAtIndex:indexPath.row+1] valueForKey:#"status"]);
The "status" object is casted to an NSMutableDictionary*
The first call is just the right syntax.
For the second one, why does it works ?
valueForKey method is called on an id, and as it seems to be a dictionary, it works and returns a comprehensive result. Then on that result, the "description" method is called (#"%#"), and as that method exists on any object, casting the result to a NSMutableDictionary does not bug. The method is called on the subclass returned, and that return is displayed into the NSLog.
I guess that for the second call, you may have a compiler-warning ?
I'm working through the Stanford iPhone podcasts and have some basic questions.
The first: why is there no easy string concatenation? (or am I just missing it?)
I needed help with the NSLog below, and have no idea what it's currently doing (the %# part). Do you just substitute those in wherever you need concatenation, and then comma separate the values at the end?
NSString *path = #"~";
NSString *absolutePath = [path stringByExpandingTildeInPath];
NSLog(#"My home folder is at '%#'", absolutePath);
whereas with any other programing language I'd have done it like this:
NSLog(#"My home folder is at " + absolutePath);
Thanks! (Additionally, any good guides/references for someone familiar with Java/C#/etc style syntax transitioning to Objective-C?)
%# is a placeholder in a format string, for a NSString instance.
When you do something like:
NSLog(#"My home folder is at '%#'", absolutePath);
You are telling NSLog to replace the %# placeholder with the string called absolutePath.
Likewise, if you put more placeholders, you can specify more values to replace those placeholders like this:
NSString *absolutePath = #"/home/whatever";
NSLog(#"My home #%d folder is at '%#'", 5, absolutePath);
Will print:
My home #5 is at /home/whatever
An easy way to do string concatenation:
NSString *s1 = #"Hello, ";
NSString *s2 = #"world.";
NSString *s = [NSString stringWithFormat:#"%#%#", s1, s2];
// s will be "Hello, world."
You can't have a + sign as a string concatenate operator, since there is no operator overloading in Objective-C.
Hope it helps.
That is a string format specifier. Basically it allows you to specify a placeholder in the string and the values that are to be inserted into the placeholder's spot. The link I reference above lists the different notations for the placeholders and each placeholder's specific format.
It's just like C#'s String.Format method:
NSLog(String.Format("My home folder is at '{0}'", absolutePath));
You can use NSString +stringWithFormat to do concatenation:
NSString* a = // ...
NSString* b = // ...
NSString* a_concatenated_with_b = [NSString stringWithFormat:#"%#%#",a,b];
The reason for the "%#" is that the string formatting is based off of and extends the printf format strings syntax. These functions take a variable number of arguments, and anything beginning with a percent sign (%) is interpreted as a place holder. The subsequent characters determine the type of the place holder. The standard printf does not use "%#", and since "#" is the symbol commonly used for things that Objective-C adds to the C language, it makes sense that the "#" would symbolize "an Objective-C object".
There is no automatic concatentation using the plus sign (+), because NSString* is a pointer type, and Objective-C is a strict superset of C, and so, consequently, adding to an NSString* object does pointer manipulation. Objective-C does not have any operator overloading feature as in the C++ language.
Also, %# is fairly versatile, as it actually inserts the result of the argument's description method into the result string. For NSString, that's the string's value, other classes can provide useful overrides. Similar to toString in Java, for example.
I am presently using
<parameterMap class="map" id="param1">
<parameter property="result" jdbcType="BOOLEAN" javaType="boolean" mode="OUT"/>
<parameter property="arg1" jdbcType="VARCHAR" mode="IN"/>
<parameter property="resultCode" jdbcType="INTEGER" javaType="int" mode="OUT"/>
</parameterMap>
<procedure id="contAvail" parameterMap="param1">
<![CDATA[
{ ? = call pkg.func(?,?)}
]]>
</procedure>
what is missing ?
You have two parameters in your CALL but a parameterMap with three parameters. You have one result but no resultMap.
Not sure if the CDATA hurts anything, but it shouldn't be needed.
See the online help for details. Also check out this and this.
It turns out there is nothing wrong with the code above. It works if we change the return data type from boolean to anything else. It seems boolean is not supported properly.
Also as Jim rightfully suggested, CDATA is not imp. It works with or without it.
An important thing to note is that ibatis returns the result in the input parameter map itself even for function call. In this case param1 will hold the result of the function call (and null is returned in the java method queryForObject()..)