So, i am trying to break out of tapestry loop here.
This is my -more or less- simplified scenario:
<ul>
<t:loop source="firstSource" value="firstValue">
<li>
<t:loop source="firstValue" value="secondValue">
<p>${secondValue}</p>
</t:loop>
<t:loop source="secondSource" value="thirdValue">
<p>${thirdValue}</p>
</t:loop>
</li>
</t:loop>
</ul>
What I do not want to have is:
Tapestry loops through all entries in firstValue - then loops through all entries in secondSource. I do not want to iterate through secondSource inside the loop of fristValue as this would iterate through all entries in secondSource - and I just want to do 1 iteration at a time.
What I want to have is:
Tapestry enters the loop for firstValue and does some printing or whatever, then breaks after the first iteration and jumps into secondSource to do the first iteration . After it has finished it jumps back to firstValue and repeats these steps.
This is what in Java the "break;" would do.
I did not find a clue in the Tapestry documentation on how to do this, nor in their forums.
But it has to be possible in some way. I can not imagine I am the only one trying to do this.
Just put an if statement around the logic, probably using an index variable:
<t:loop source="firstSource" value="firstValue">
<li>
<t:loop source="firstValue" value="secondValue" index="firstValueIndex">
<t:if test="firstCondition">
<p>${secondValue}</p>
</t:if>
</t:loop>
<t:loop source="secondSource" value="thirdValue">
<t:if test="secondCondition">
<p>${thirdValue}</p>
</t:if>
</t:loop>
</li>
</t:loop>
In the Java page:
#Property
private int firstValueIndex;
public boolean getFirstCondition() {
// logic to determine whether to break out
return firstValueIndex == 0;
}
public boolean getSecondCondition() {
// logic
}
My guess is that you have three sources of data and are trying to output three columns, is this right?
Sometimes you have to transform your data a little bit: For example, you might need to do some work to convert one value from each of the three inputs into a single value:
public class Row {
Object col1, col2, col2;
}
In your Java code, you would build up a List of Row objects.
In your template, you iterate over the Row objects, rendering the col1, col2 and col3 properties.
(In Tapestry 5.3 and above, a public field can be treated as a property.)
I've used similar techniques to output a calendar, which can be very tricky to manage using conditionals and the like inside the template.
Remember the role of the Controller in MVC: its job to mediate between the model and the view; sometimes that includes some simple transformations of the model data to fit in with the view.
Related
I have a static 2 dimensional array of objects in a Kotlin project:
class Tables {
companion object{
lateinit var finalTable: Array<Array<Any?>?>
}
}
It is a little clearer in Java:
public class Tables {
public static Object[][] finalTable;
}
The third element in one row of objects in the table, is a string boxed as an object. In other words: finalTable[*][2] is a string describing the item. When I add an item to the array in Kotlin, I want to sort the entire array in alphabetical order of the description.
In Java this is easy:
Arrays.sort(Tables.finalTable, Comparator.comparing(o -> (String) o[2]));
When I try to use Android Studio to translate the Java code into Kotlin, it produces the following:
Arrays.sort( Tables.finalTable, Comparator.comparing( Function { o: Array<Any?>? -> o[2] as String }) )
This does not work, you have change the String cast as follows:
Arrays.sort( Tables.finalTable, Comparator.comparing( Function { o: Array<Any?>? -> o[2].toString() }) )
This version will compile and run, but it totally messes up the sorting of the table, so it does not work. I have tried variations on this theme, without any success. To get my project to work, I had to create a Java class in the Kotlin project with the functional Java code listed above:
public class ArraySort {
public void sortArray(){
Arrays.sort(Tables.finalTable, Comparator.comparing(o -> (String) o[2]));
}
}
This sorts the table like a charm, but I would prefer to keep my project "pure Kotlin". Can anyone suggest a pure Kotlin method to sort such an array? Thanks!
Unless I'm missing something, you can just do this:
Tables.finalTable.sortBy { it[2] as String }
which sorts your array in place. sortedBy will produce a new copy of the original if that's what you want instead, and might be why the comment suggestions weren't working for you.
But this whole unstructured array situation isn't ideal, the solution is brittle because it would be easy to put the wrong type in that position for a row, or have a row without enough elements, etc. Creating a data structure (e.g. a data class) would allow you to have named parameters you can refer to (making the whole thing safer and more readable) and give you type checking too
Is there a way to remove a number from an attibute array in an update? For example, if I want to update all of an alchy's booze stashes if he runs out of a particular type of booze:
Alchy has_many :stashes
Stash.available_booze_types = [] (filled with booze.ids)
Booze is also a class
#booze.id = 7
if #booze.is_all_gone
#alchy.stashes.update(available_booze_types: "remove #booze.id")
end
update: #booze.id may or may not be present in the available_booze_types array
... so if #booze.id was in any of the Alchy.stash instances (in the available_booze_types attribute array), it would be removed.
I think you can do what you want in the following way:
if #booze.is_all_gone
#alchy.stashes.each do |stash|
stash.available_booze_types.delete(#booze.id)
end
end
However, it looks to me like there are better ways to do what you are trying to do. Rails gives you something like that array by using relations. Also, the data in the array will be lost if you reset the app (if as I understand available_booze_types is an attribute which is not stored in a database). If your application is correctly set up (an stash has many boozes), an scope like the following in Stash class seems to me like the correct approach:
scope :available_boozes, -> { joins(:boozes).where("number > ?", 0) }
You can use it in the following way:
#alchy.stashes.available_boozes
which would only return the ones that are available.
I have a requirement in which I have an af:query panel which after querying populates an af:table.
Now based on the table rows when any 1 row is selected, the graphs below it should be populated based on some columns.
Now my problem is that on search when the table is populated for the first time, no row is selected.
I need the first row to be selected automatically. I have searched multiple solutions from the net forums but till now haven't found any working solution.
Please help me what code should I use to select a row programmatically. and also where should I put this code in the backing bean.
As you've correctly mentioned, at the first render of the table no row is selected. I've encountered this problem too, and i've dealt with it by calling a getting the first row of the corresponding VO on BeforePhase (i.e: on the page first rendering or refresh).
I understand that you intend to do so for the first searching.
The af:query component has a property called QueryListener. You can link it with a method inside a backing bean. The content should be like:
private QueryEvent qEvent = null;
public void queryListener(QueryEvent queryEvent) {
setQEvent(queryEvent);
JSFUtils.invokeMethodExpression("#{bindings.YourViewObjectNameViewCriteriaQuery.processQuery}", Object.class,
QueryEvent.class, getQEvent());
BindingContainer bindings = BindingContext.getCurrent().getCurrentBindingsEntry(); //Edited
DCBindingContainer bc = (DCBindingContainer)bindings;
DCIteratorBinding iterator = bc.findIteratorBinding("YourViewObject1Iterator");
Row r = iterator.getCurrentRow(); //Here you've got the very first row, and can operate with it
.....
}
public void setQEvent(QueryEvent qEvent) {
this.qEvent = qEvent;
}
public QueryEvent getQEvent() {
return qEvent;
}
With this, you should be able to get the first row when the query is executed (i.e: when the search is done).
After getting the first row, you can programmatically the graph process execution or whatever you do.
NOTE: invokeMethodExpression can be found inside JSFUtils, which is a starndard class with static methods which source code you can download here: JSFUtils.java
Its quite a big task but ill try to explain.
I have an array with a list of 200 strings and I want to be able to randomly select one and add it to the stage using code. I have movieclips exported for actionscript with the same class name as the strings in the array. Also, if it is possible, would I be able to select the strings with predictability such as the first has a 0.7 chance the second a 0.1 etc. Here is what i have currently
var nameList:Array=["Jimmy","Bob","Fred"]
var instance:DisplayObject = createRandom(nameList);
addChild(instance);
function createRandom(typeArray:Array):*
{
// Select random String from typeArray.
var selection:String = typeArray[ int(Math.random() * typeArray.length) ];
// Create instance of relevant class.
var Type:Class = getDefinitionByName(selection) as Class;
// Return created instance.
return new Type();
}
All this throws me this error
ReferenceError: Error #1065: Variable [class Jimmy] is not defined.
Ive searched for other threads similar but none combine the three specific tasks of randomisation, predictability and addChild().
I think that you've got two problems: a language problem and a logic problem. In the .fla connected to your code above, in the Library find each symbol representing a name and write into the 'AS linkage' column for that symbol the associated name -- e.g., 'Bob,' 'Fred' -- just the name, no punctuation.
Now getDefinitionByName() will find your 'Class'
If you put a different graphic into each MovieClip -- say, a piece of fruit or a picture of Bob,Jim, Fred -- and run your program you'll get a random something on stage each time.
That should solve your language problem. But the logic problem is a little harder, no?
That's why I pointed you to Mr. Kelly's solution (the first one, which for me is easier to grasp).
I use the code below as an HTMLHelper which gets data from the database and loops over it to display a menu. This is fairly straightforward as you can see however, what if you have a database table using the adjacent model of hierarchies eg/ID, ParentID, OrderID. Easy to see whats going on but recursion is needed to get this data out properly. Is writing a C# recursive function acceptable? If so can someone help me with that? The expected output is something similar to this..
<ul>
<li>Item1
<ul>
<li>SubItem1</li>
</ul>
</li>
</ul>
SQL 2008 has a Hierarchy datatype now so I am not sure if this will help things?
I would also like some way of enabling users to decide what goes in a menu for example, a list of items that can go in the menu and then choosing these items and their positions in the hierarchy. Once a saved button is pressed it will store this heirarchy in the database.
Am I asking too much, I'm sure this must be quite a common scenario?
Here is my HTMLHelper code if anyone wants to use it...
public static string Menu(this HtmlHelper helper, int MenuCat)
{
string menuHTML = "<ul id=\"menu\">";
var route = helper.ViewContext.RequestContext.RouteData;
string currentPageName = route.GetRequiredString("id");
DB db = DB.CreateDB();
//var result = from p in db.WebPages where p.CategoryID == 9 select p;
var result = from p in db.WebPages select p;
foreach (var item in result)
{
if (item.Name == currentPageName)
{
menuHTML += "\n\t<li>" + helper.ActionLink(item.Name, "Details", "Dinner", new { id = item.ID }, new { #class = "selected" }) + "</li>";
}
else
{
menuHTML += "\n\t<li>" + helper.ActionLink(item.Name, "Details", "Dinner", new { id = item.ID }, null) + "</li>";
}
}
menuHTML += "\n</ul>\n";
return menuHTML;
}
I would do two things here: don't bother rendering this yourself: use jQuery. If you Google "jquery menu" you'll find hundreds of links.
Next, put the ordering logic on your app, you don't need the DB to do this as it soaks up cycles and (from what I've read) isn't terribly efficient. This is simple looping logic with a self-referencing join that Linq is perfect for.
Hand this off to jQuery, adn you're good to go without hard-coding HTML in code :)
If you are using Sql server 2005 take a look to Common Table Expression (CTE) (google with CTE hierarchical data). It allows you to create a view displaying the complete hierarchy.
But, how much depth level are you displaying in the menu? Usually you only need to show directy childs and go down in the hierarchy as the user clicks the links. (No recursion needed)
I always use recursive table-valued functions for fetching hierarchical data in SQL server.
See an example here:
blogs.conchango.com/christianwade/archive/2004/11/09/234.aspx
Unfortunately, there is a recursion limit (32 levels maximum) for SQL Server User Defined Functions (UDF) and Stored Procedures.
Note: If you use a table-valued function just drop it in your dbml file and you will be able to access it like any other table.
Another approach is to use the a new recursive queries syntax (in the form of the WITH clause and Common Table Expressions-CTE) introduced in SQL Server 2005.
Take a look here:
www.eggheadcafe.com/articles/sql_server_recursion_with_clause.asp
An approach of mixing CTE with Linq-To-SQL is presented here:
stackoverflow.com/questions/584841/common-table-expression-cte-in-linq-to-sql