On Nov 8, 2009, at 5:21 PM, Mark Wardle wrote:
Ramsey: Thank you. It is very satisfying deleting my old custom components, although there's a steep learning curve here. I don't think it helps that I've started by rewriting user management using d2w instead of regular WO. It needs special handling to deal with users editing their own information (but avoiding privilege escalation), uploading photos and changing passwords. Once I crack all of that then perhaps the rest will be easier... maybe....
I've done some of that already in R2D2W (^_^)What I do is stick the user entity on session.objectStore.user. That way, I can conditionally show the edit user link in the menu header based on whether or not that's null. The edit user link just loads an EditUser configuration and passes the object from session.objectStore.user to it. So, if there is a session.objectStore.user, then it shows edit and logout. If not, it shows create new account and login.
Create new account is a CreateUser config. It works with a new user object and sets the user on the session when the save is complete. Login is just a QueryUser configuration with a nextPageDelegate that handles the special login logic. And of course, the user entity and page configurations are set dynamically with the rule system, so you can use whatever existing user entity you've modeled. It's set up so you can flag your user entity in the model with a userInfo key/value pair, or you can just set it in the rule system.
It's really simplistic right now, but you might find some of the code useful. It should do what you've mentioned above. If you're interested, feel free to grab a copy off the SVN at
https://r2d2w.svn.sourceforge.net/svnroot/r2d2wWord of warning though: It's not for the faint of heart. You'll need to be working with Wonder source in your workspace, apply a few patches I've got up on Jira, and stay on Head. Plus it only compiles with 5.4.x. It might also help if you already understand migrations, ERAttachment, and ERCoreBusinessLogic as well.
So ... you've been warned. (^_^) Ramsey
Again, thank you for your help. I'm starting to see things a bit more clearly [*]. Best wishes, Mark [*] : this may be an overstatement 2009/11/8 Ramsey Lee Gurley <rgur...@mac.com>:On Nov 8, 2009, at 2:17 AM, Mark Wardle wrote:Hi Ramsey. Thank you for your help here. I think the best thing I did was to create my own look as it's forced me to spend time reading the source code and wod files to try and work out why stuff happens! Someis *still* magic but I'm starting to see the hands moving under the table now!That's how I learned it.On Sunday, November 8, 2009, Ramsey Lee Gurley <rgur...@mac.wrote:On Nov 7, 2009, at 4:58 PM, Mark Wardle wrote: Hi all. This may be a stupid question... I've embedded a D2WQuery within a ListPage. It acts as a filter for the list; in fact I use ERDQueryAnyKey exclusively to allow a google-like search of the listed entities. Thank you to all whohelped me make the mental leap to D2W - I don't think I'm quite there*yet* - and getting me this far.... It's actually working quite well BUT! If I type text and click submit, then the list (displaygroup) is filtered appropriately. However, the text is cleared from the textfield. I wish to visually indicate that a filter is applied - Iassumed the text would remain within the textfield for the query, butthis is not the case.I'm guessing when you reload your page, you're loading a fresh embedded query page which loads a fresh ERDQueryAnyKey which wipes out your entered value. ERDQueryAnyKey is not stateless so I think it should be storing thevalue.In addition, every time I click submit, I get a wholly new page, eventhough I've bound the action binding to a method that returns null. Therefore, my list page "Back" button (Cancel) no longer returns to the calling page but to the previous search.What action binding? The one on the button? The one on the D2WQuery?What is your cancel button bound to?I originally bound the d2w to displaygroup.filter and changing to thisan action within the customised list page didn't help. The "cancel" button is set to the nextpage which becomes the last search page instead of my main landing page. presumably this isbecause somehow a new list page is being generated? I hadn't expectedthat.The action binding of a D2WQuery ends up as the nextPage() of the embeddedquery page. If that is where you see the cancel button, then that isprobably the reason you're going back to the previous search instead of theback page you expected.As always, I'm in danger of being too specific and asking the wrong questions! You'll need to be more specific (^_^)ha! But the danger is one misses the wo way!1. Is there any way of getting a D2WQuery to maintain input state after submission? If you use the showListInSamePage, and set up a specific pageconfiguration for this, it should work with no additional effort. No? You would just have your list embedded in your query instead of your queryembedded in your list.I did try that originally but I would like to have a list displayed immediately for users. I don't wish to force a query.Sounds perfectly reasonable.Maybe I should look at a way of showing all objects in an embedded d2wlist before a query is set? I suppose there are two alternatives. Copy the methods used in thefilter button and try to do the same with Ajax. Otherwise, forego theemedded filter idea and simply use the filter button as is.Ajax? Feature creep? (^_^)Anyway, it depends on how you bind it. If you store something in acomponent's local var, then you're subject to that var being wiped out with a reload. If you store the value in a place you can find it outside of the component (On the displayGroup or something) then you can reload it from that known place, even if your component is stateless. I think this is moreof a WO question than a D2W one though.I thought of that. AFAICS, I couldn't persist input state as there wasn't a public binding for the input state.So you write a replacement (^_^) That component appears to be a propertylevel component and you need something very similar, but a page levelcomponent. So, starting with ERDQueryAnyKey as an example, create a newone.2. Is it possible to pass the cancelAction to the *next* page, or somehow keep the same list page instance? 3. Am I still making things overly complicated? Should I use an aboveDisplayPropertyKey and use an embedded component there rather than customising my list page?Won't work without modification, because aboveDisplayPropertyKeys in ERNeu doesn't give you a displayGroup or dataSource binding to filter against. You only get your property keys and d2wContext there. Given what you want to do, I think I would still go with the filter field in the batchnavigation bar rather than an entire embedded query page.I think you are right. Thank you MarkOk, so let's do it. Starting with the ERNeu list page template (Since Ican't see your code) change the FilterDisplayGroupButton bindings to FilterDisplayGroupButton: WOSwitchComponent { WOComponentName = d2wContext.filterListComponentName; displayGroup = displayGroup; localContext = d2wContext; allowsFiltering = d2wContext.allowsFiltering; } Create Rules: 0: *true* => filterListComponentName = ERDFilterDisplayGroupButton [Assignment]100: entity.name = 'Car' and task = 'list' => filterListComponentName =WardleFilterAnyKey [Assignment]100: entity.name = 'Car' and task = 'list' => filterAttributes = ("make","model", "color") [Assignment] 100: entity.name = 'Car' and task = 'list' => allowsFiltering = true [BooleanAssignment] New filter component. WardleFilterAnyKey.html <webobject name="AllowsFiltering"><label>Matches <webobject name = "FilterField"/></label></webobject> WardleFilterAnyKey.wod AllowsFiltering: WOConditional { condition = allowsFiltering; } FilterField: WOTextField { value = value; } WardleFilterAnyKey.java public class WardleFilterAnyKey extends ERDQueryAnyKey { /** logging support */private static final Logger log = Logger.getLogger (ERDQueryAnyKey.class);private Object _value; /** * Public constructor * @param context the context */ public WardleFilterAnyKey(WOContext context) { super(context); } public boolean allowsFiltering() { boolean result = booleanValueForBinding("allowsFiltering"); return result; } public NSArray filterAttributes() { NSArray result = (NSArray)valueForBinding("filterAttributes"); return result; } public void setValue(Object newValue) { _value = newValue; ERXDisplayGroup dg = (ERXDisplayGroup)displayGroup(); EOQualifier q = null; if(newValue != null) {if(newValue != null && newValue.toString().indexOf("*") == 0) {newValue = newValue.toString().substring(1); } q = ERXEOControlUtilities.qualifierMatchingAnyKey(filterAttributes(), ERXRegExQualifier.MatchesSelector, newValue); } } dg.setQualifierForKey(q, "filterQualifier"); } } Something like that. I didn't test any of it, but you get the idea. Ramsey-- Dr. Mark Wardle Specialist registrar, Neurology Cardiff, UK
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com