I'm writing a tag that keeps track of how many time it was called, in order to generate unique ids for its elements:
%{
try {
coolTagId++;
} catch (Exception) {
coolTagId = 0;
}
}%
<div id='cool-tag-${coolTagId}'></div>
...
$('#cool-tag-${coolTagId}').click(function(){alert("Cool Tag ${coolTagId} clicked")});
When I include this tag in a page multiple times, to my surprise, I see that coolTagId is 0 every time it's evaluated. Why is this happening?
(I'll be using some sort of UID in the meantime, I just want to understand why the above snippet doesn't work)
I don't know why that is but it doesn't surprise me. Play is a stateless framework, so it seems natural that it doesn't share state between two instances of the same tags.
It's interesting, even setting the value beforehand using #{set coolTagId:0 /} does not work.
What does work however is setting the value in your tag. Put this at the end of your tag: #{set coolTagId:coolTagId /}. This way you manually push the value to the base template.
It is a simple matter of scope.
Imagine writing this in pure Java, a tag is effectively calling a method. Everything defined in your tag (i.e. method) is locally scoped to that tag, so it would not exist once the tag has been executed, as it would have left the scope.
The reason for this, is to make sure that anything outside of your tag is not broken or modified by the execution of your tag. Everything is self contained, except for the parameters that you pass in.
Related
I could do with some help once again...
We built our own forms in XPages. Forms are defined by a user in Notes, and they are used through XPages/web. We added several managed beans to get more grip on the data used by the page and controls that are on it. The whole thing is heavily nested, the form control can be used more than once on a page, repeat controls are used as well, and now I need to partially refresh a panel.
Some of the code:
<xp:panel id="ccAnyForm">
<xp:this.dataContexts>
<xp:dataContext var="formulaire">
<xp:this.value><![CDATA[#{javascript:compositeData.formName || compositeData.dataSource.getItemValueString("Formulaire")}]]></xp:this.value>
</xp:dataContext>
<xp:dataContext var="formdata">
<xp:this.value><![CDATA[#{javascript:PageData.getForm(formulaire, compositeData.dataSource)}]]></xp:this.value>
</xp:dataContext>
</xp:this.dataContexts>
<xp:panel id="aFormulaire${javascript:compositeData.name}">
<xe:switchFacet id="switchFacet1">
<xe:this.selectedFacet><![CDATA[#{javascript:formdata.isTabbed()? "tabbed": "flat"}]]></xe:this.selectedFacet>
PageData is a Java bean, and I lose formdata when doing a partial refresh. If I set partial execution mode in the EventHandler (data validation is disabled), I get the error that says formdata not found on the last line of the snippet. If I clear partial execution mode, I get nothing at all: no error, no Java error, no SSJS error, nothing.
It must be my lack of understanding the life-cycle of objects and variables, for I prbably have to use ValueBindings or so, but I don't know how.
Help...
I've seen dataContexts recalculate as null, particularly when dependent on other dataContexts. I think in Apply Request Values phase. When I had that I changed the code to only calculate in Render Response phase.
However, I don't think that work for you, because the Switch control will need the value before Render Response, and there's no easy way to get hold of which other phase is running.
The approach I'd take is to have a property in your bean (e.g. showTabbed) that holds which Switch facet to show. Call a bean method to set that property on page load. Then in your partial refresh, call the method again, checking whether the Formulaire field has changed to determine whether or not to call setShowTabbed(boolean) again. That will minimise the number of calls even more and should prevent the problem.
We have a tool that generates the source code (for C#, Java, IOS, etc.) from a given model. The code is manually edited for any feature that is missing by the code generator. Whenever any changes made to the model and needs to generate the source code out of it, the manual changes that performed on the previous version are lost.
In order to minimize the loss, the user edited code blocks (methods, classes, properties, etc.) are marked with a custom attribute (say CUSTCODE). While generating the source for the new version, if a path for previous version is mentioned (by user), system will compare the two source codes and merge the contents as follows (previous version is considered as the base in this case):
Remove any code blocks that are available in previous version and not available in new version, which are not marked as CUSTCODE.
Replace any code blocks that are available in both the versions, and not marked as CUSTCODE with latest version code.
Add the missing code blocks from the latest code.
For this, we are using Microsoft Roslyn and is working as expected for C# (of course additional checks like usings are performed)
[Note: I can use Java / C# for the merger app. The system is going to invoke any app by passing params. The same is achieved using ASTRewriter for Java]
Now the challenge is for the JS and HTML. Currently We are focusing at JS.
We have checked several AST JavaScript parsers like Rhino, IronJS, astify etc. But I am blocked at some point in using them.
So I want to build a custom merger. Since JavaScript is so dynamic, we are (going to) setting up the guidelines for JS code.
Enclose all the code within a named function, which acts as unique identifier to match and merge.
Add a comment with "CUSTCODE" on top of the method when system need to keep the function intact while merge.
Our intention is to follow the following approach:
Move the anonymous functions found in jQuery into named functions and call them in jQuery
Name any anonymous function like var v = function()...
Wrap all jQueries and standalone pieces of code into named self executable functions while keeping the order intact.
Move all global variables to top of the JS file. (Do not enclose in any function)
The merging process works as follows:
Capture all strings (single quote, double quote), comments (inline, block) and replace with some unique identifiers. (Except the ones tagged with "CUSTCODE"
Capture the function body (based on the count of '{' and '}') and replace with unique identifier. Read the previous line, mark the method if it is "CUSTCODE"
Compare and replace the captured function bodies with latest version content appropriately.
Restore all captures to generate the final output.
I am wondering if anything else I need to consider.
I have the following problem, we might even call it a classic one:
public void myMethod(Map<Object, Object> parameter){
someOtherObject.method(parameter);
.
.
.
someOtherThirdPartyObject.method(parameter);
}
And suddenly, in the end some method touched the input parameter Map, and I don't know where and how. Now, I know it would be desirable to make the parameter immutable, but it is not and that is the root of the problem. For instance, the methods inside myMethod are intended to perform some validations, but they do some more as well, which is wrong by design.
So, the question is how to create a breakpoint in this method where the execution pauses if an attribute of this parameter Map changes? It might be a good idea to put a conditional breakpoint after each method call, but if you have 20-odd methods, it's rather painful.
How can I debug when this input parameter is changing?
What you want appears to be called a "watchpoint". I actually didn't know this functionality existed and I used to work on the Eclipse Project!
http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.cdt.doc.user%2Ftasks%2Fcdt_t_add_watch.htm
It looks like you'll have to figure out what fields are being editted and then set a "Write" watchpoint using the help document above.
Additionally, Eclipse highlights variables which are modified, so if you step over your method calls one by one you will be able to see which one is modifying the value (and which field is being modified) because it will be highlighted (bright yellow, by default) in the "variables" tab in the "debug" perspective. Once you know which method if modifying the data you can run debug again, but this time debug the method that changes the value and just keep repeating until you find the problem.
This is a classic problem solving scenario where you start with a very large search space and systematically and methodologically narrow it down until the search space is small enough for you to locate the problem.
If you're trying to locate a spot where your map is being modified incorrectly, you might want to first start at the higher levels of the myMethod. Put breakpoints around the methods called inside the myMethod method. At each breakpoint, look at the contents of the Map. Eclipse has a variable watch panel where you can see the contents of every variable at a specific moment in time.
When you hit the breakpoint where you notice something is wrong. Stop. You now know to dig into someOtherObject.method(parameter); assuming the data was changed at it's breakpoint.
Now, someotherObject.method will likely have other methods inside it. Put your breakpoints inside this method around all of it's function calls and repeat the process. Continue repeating until there are no more methods left. Eventually, you will narrow down the problem and have the answer.
Unfortunately, there is no magic "fix my code" button for these types of problems. It just takes good, old fashioned Sherlock Holmes style investigative skills and reasoning to eliminate areas of the code that you know aren't the problem until you're left with a smaller section that allows you to get at the root cause.
If no code modification is allowed, you can
use the watchpoints method described by acattle to watch changes at this specific map instance or
have breakpoints in the Map methods modifying its state (if you want to do that for multiple instances). It does not matter that the Map code is binary only, you can still open it using Ctrl-Shift-T (Open Type), select the methods like put(...) or remove(...) in the outline view and add breakpoints using the context menu in the outline view.
Working on a large Web app, I have houndresds of JSPs.
Each JSP includes (ONLY) a set of internal tags, for instance:
<AAA:INPUT value="bbb" state="<%=getPageState()"/>
This tag is rendered into an HTML input field, with a readonly/enabled state, based on the return value from getPageState().
This basically allows me to set the complete page as enabled/disabled from a single entry point.
I don't like this (mainly because it drives me away from writing the HTML I want and I need to maintain attributes for each HTML attribute I want), I know I can something similar on client side with JavaScript.
Are there other approachs to control the state of a complete JSP form in a single point on the web-server side?
The way I would go about this would be to convert the getPageState() method into a tag, and then use this tag within your custom tags. That way, you don't need to explicitly pass in the page-state on every invocation of your custom tag.
Of course, this means that you would have to modify all your custom tags to use this new tag, but I think that's better than having your code littered with explicit calls to get the page state. Not to mention, an opening for inconsistencies if a developer forgot to check the page state.
Also, now the decision as to how the element needs to be rendered rests in the custom tag itself (where it belongs).
The only problem I see is that now you have to make multiple (redundant) calls per element to get the page state, which is not that efficient. To get around this problem, you can have your custom tag (that gets the page state) set a page attribute, and have your custom tags inspect this page attribute to decide if the form element should be disabled or not (another way would be to create a variable with the scope AT_END).
We are currently developing a project with Struts2. We have a module on which we display a large amount of data on read-only fields from a group of beans via the "property" Struts 2 data tag (i.e. <s:property value="aBeanProperty" />) on a jsp file. In some cases most of the fields might come empty, so a blank is being displayed on screen.
Our customer is now requesting us to display default string (i.e. "N/A") whenever a property comes empty, so that it is displayed in place of the blank spaces currently shown.
We are looking for a way to achieve this in a clean and maintainable way. The 'property' tag comes with a 'default' attribute on which one can define a default value in cases when the accessed property comes as null. However, most of our properties are empty strings, therefore it does not work in our case.
Another solution we are thinking of is to define a base class for all of our beans, and define a util method which will validate if a string is null or empty and then return the default value. Then we would call this method from each bean getter. And yes this would be tiresome and kind of ugly :), therefore we are holding out on this one in case of a better solution.
Now, we have in mind a solution which we think would be the best but have not had luck on how implement it. We are planning on extending the 'property' tag some way, defining a new 'default' attribute so that besides working on null properties, it also do so on empty strings ("", " ", etc). Therefore we would only need to replace the original s:property tag with our new custom tag, and the desired result would be achieved without touching java code.
Do you have an idea on how to do this? Also, any other clever solution (maybe some sort of design pattern?) on how to default the values of a large amount of property beans are welcome too!
(Or maybe, even there might be some tag that does this already in Struts2??)
Thanks in advance.
Shorter version in case you don't want to read all of the above! :)
Currently Struts2 provides a property tag (<s:property value="someValue" />), it is used to display the content of a value, e.g. a String variable on an Action class. This tag contains an attribute called "default" where you can define a default value to be displayed IF the variable is set to NULL, e.g. you can set it to display "N/D" for these values.
We now need to do the same, but that it also works on empty Strings ("", " ", etc), not only on nulls. We plan on extending this tag so that we have our own (maybe something like <s:propertyEmpty value="someValue" />) and accomplish this behavior. Can you guide how to accomplish this?
Your help is greatly appreciated. Thanks!
Interesting. I believe you are on the right track.
Only that I would try to extend/modify the property tag so that the new behaviour is explicitly set in the jsp code. I mean, I would not like that each in the web app automatically gets the new behaviour, because perhaps there are some bean properties for which I want the original struts2 behaviour.
I would prefer to have a new tag nane (eg: ... or something shorter) or a new attribute (eg )
Perhaps this helps: http://bodez.wordpress.com/2009/03/13/customising-struts2-jsp-tags/