Re: validation and #updateModel
I haven't done that before, so I'll have to figure out how to do it. Thanks for the adviceI'll look into doing that, because I have seen this recommendation made to others, so I should probably learn. However, in the meantime, I think I may have a theory as to why this is happening. When the error was reproduced for me, it seems to happen only during certain errors uploading attachments using the MultiFileUploadField. Now that certain other issues were fixed with this control, I can only reproduce this problem by trying to upload a file larger than the maximum set in Form#setMaxSize. What you said earlier, about how only fields that failed validation should fail to be retained in the form, got me to thinking: since this restriction is set in the Form object, does that block the model update for ALL fields? That would make sense, but it would also make this method nearly unusable except on a dedicated form (i.e. a form used only for uploading files). In that case, I'm better off manually validating upload size. On Tue, Jul 20, 2010 at 5:13 PM, Jeremy Thomerson jer...@wickettraining.com wrote: On Tue, Jul 20, 2010 at 1:22 PM, Ray Weidner ray.weidner.develo...@gmail.com wrote: Back to the original question, when you say all changes to the form are lost - do you mean that the form rerenders with absolutely no values filled out? Only the fields that failed conversion or validation should be blank. See, that throws me off, too. Yes, the supposedly valid fields are not being preserved after submit and fail validation. I would have thought that they should have been preserved, LDM be damned, but they aren't, so that was my theory as to what was causing this. So if that's not causing it, what could be causing such a thing? I'd including source code here, but I'm not even sure what part is causing the problem, so that would be a lot of code. Any ideas? Best thing to do is try to create a quickstart that reproduces it. Typically, you find your error while doing this. If not, you have something you can give us that we can quickly run to debug your problem. -- Jeremy Thomerson http://www.wickettraining.com
Re: validation and #updateModel
Update: I was able to confirm my theory below. It was specifically MultiFileUploadField's validation of file size via Form#setMaxSize that was causing the problem. Again, I question the value of this method if this is the result. It sounds like you have to put attachment uploading in its own separate form. Is this supposed to be standard practice? On Wed, Jul 21, 2010 at 2:25 AM, Ray Weidner ray.weidner.develo...@gmail.com wrote: I haven't done that before, so I'll have to figure out how to do it. Thanks for the adviceI'll look into doing that, because I have seen this recommendation made to others, so I should probably learn. However, in the meantime, I think I may have a theory as to why this is happening. When the error was reproduced for me, it seems to happen only during certain errors uploading attachments using the MultiFileUploadField. Now that certain other issues were fixed with this control, I can only reproduce this problem by trying to upload a file larger than the maximum set in Form#setMaxSize. What you said earlier, about how only fields that failed validation should fail to be retained in the form, got me to thinking: since this restriction is set in the Form object, does that block the model update for ALL fields? That would make sense, but it would also make this method nearly unusable except on a dedicated form (i.e. a form used only for uploading files). In that case, I'm better off manually validating upload size. On Tue, Jul 20, 2010 at 5:13 PM, Jeremy Thomerson jer...@wickettraining.com wrote: On Tue, Jul 20, 2010 at 1:22 PM, Ray Weidner ray.weidner.develo...@gmail.com wrote: Back to the original question, when you say all changes to the form are lost - do you mean that the form rerenders with absolutely no values filled out? Only the fields that failed conversion or validation should be blank. See, that throws me off, too. Yes, the supposedly valid fields are not being preserved after submit and fail validation. I would have thought that they should have been preserved, LDM be damned, but they aren't, so that was my theory as to what was causing this. So if that's not causing it, what could be causing such a thing? I'd including source code here, but I'm not even sure what part is causing the problem, so that would be a lot of code. Any ideas? Best thing to do is try to create a quickstart that reproduces it. Typically, you find your error while doing this. If not, you have something you can give us that we can quickly run to debug your problem. -- Jeremy Thomerson http://www.wickettraining.com
validation and #updateModel
Hi all, I have what I would think to be a fairly common usecase that I'd like to solve. I have a form with a model that is a LoadableDetachableModel wrapped in a CompoundPropertyModel. I wouldn't expect that to be unusual. However, when a form submit is failing validation for , all changes to the form are lost. I'm guessing that the LoadableDetachableModel, when combined with the blocked update to the model, is causing this. For the most part, I've been able to get around this by deferring most validation checks until #onSubmit, at which point I manually run through them and call #error on the appropriate components. Two problems: First, I can't defer all validation. Type conversions and the size of uploaded files are validated automatically, and you wouldn't want to have to rewrite that for yourself. Second, I don't want to defer all the validation. In so doing, I lose the benefits of Wicket handling all that stuff in the back end for me. I'm wondering if there's a possible work-around. What if, during the call to #onError, I was to call #updateModel? The javadoc gives a rather significant warning against using this method, but I'm wondering if it has some value here. The point is, if I force the model to be updated despite the validation failure, then changes will not be lost upon submission. Any thoughts?
Re: validation and #updateModel
That would certainly simplify things, but I find it indispensable when it comes to handling persistent entities, which you wouldn't want to serialize with the page. Taking a step back, how can a form map to persistent entities without resorting to LoadableDetachableModels? Not that I'm necessarily in a position to perform such a drastic refactoring at this stage in my project (I'm not). I'm just curious. But if anyone has an answer to my first problem, I'm still quite interested. Because I can't really replace LoadableDetachableModels at this stage of development. On Tue, Jul 20, 2010 at 2:59 AM, Jeremy Thomerson jer...@wickettraining.com wrote: On Tue, Jul 20, 2010 at 1:55 AM, Ray Weidner ray.weidner.develo...@gmail.com wrote: Hi all, I have what I would think to be a fairly common usecase that I'd like to solve. I have a form with a model that is a LoadableDetachableModel wrapped in a CompoundPropertyModel. I wouldn't expect that to be unusual. However, when a form submit is failing validation for , all changes to the form are lost. I'm guessing that the LoadableDetachableModel, when combined with the blocked update to the model, is causing this. For the most part, I've been able to get around this by deferring most validation checks until #onSubmit, at which point I manually run through them and call #error on the appropriate components. Two problems: First, I can't defer all validation. Type conversions and the size of uploaded files are validated automatically, and you wouldn't want to have to rewrite that for yourself. Second, I don't want to defer all the validation. In so doing, I lose the benefits of Wicket handling all that stuff in the back end for me. I'm wondering if there's a possible work-around. What if, during the call to #onError, I was to call #updateModel? The javadoc gives a rather significant warning against using this method, but I'm wondering if it has some value here. The point is, if I force the model to be updated despite the validation failure, then changes will not be lost upon submission. Any thoughts? Don't use a LoadableDetachableModel for a form. -- Jeremy Thomerson http://www.wickettraining.com
Re: validation and #updateModel
Back to the original question, when you say all changes to the form are lost - do you mean that the form rerenders with absolutely no values filled out? Only the fields that failed conversion or validation should be blank. See, that throws me off, too. Yes, the supposedly valid fields are not being preserved after submit and fail validation. I would have thought that they should have been preserved, LDM be damned, but they aren't, so that was my theory as to what was causing this. So if that's not causing it, what could be causing such a thing? I'd including source code here, but I'm not even sure what part is causing the problem, so that would be a lot of code. Any ideas? On Tue, Jul 20, 2010 at 11:55 AM, Jeremy Thomerson jer...@wickettraining.com wrote: On Tue, Jul 20, 2010 at 10:20 AM, Igor Vaynberg igor.vaynb...@gmail.com wrote: On Tue, Jul 20, 2010 at 12:53 AM, Jeremy Thomerson jer...@wickettraining.com wrote: Typically, I use LDM's for every place that I am viewing data, and a regular serializable model for places that I'm editing data. You must be able to persist changes across requests (without persisting to the long-term storage), which means that you'll need to be able to serialize things. this is not true :) the formcomponents themselves preserve the state so using an LDM for a form is feasible. the sequence is basically * load entity - model * call setters - form component models * flush/close session - somewhere Right, which is why I said in the second paragraph: Only the fields that failed conversion or validation should be blank. Others should have their data still in them in an unconverted form even though the converted / validated form has not been pushed to the model yet In the first paragraph I should have been more clear - I use serializable models for where I'm editing data and passing it to other pages (i.e. multi-step wizards). But, in this case, he seems to be in a single form, so the components should still have state unless he's reinitializing them somehow (redirecting to new page, etc). -- Jeremy Thomerson http://www.wickettraining.com
Re: extending AbstractFormValidator as a validation adapter
Thanks for your reply, Jeremy. I just got around to reading it. I had been under the impression that I'd have to call something from the #onSubmit to trigger the feedback, but I tried it out based on your suggestion, and it fits the bill. This deferred validation is actually pretty useful in a number of situations, so thanks. It would be nice if Wicket had a built-in way of turning off validation for certain buttons without turning off the form-to-model update, i.e. not #setDefaultFormProcessing, which precludes the latter. On Wed, Jun 30, 2010 at 12:08 AM, Jeremy Thomerson jer...@wickettraining.com wrote: If you need to validate after the data has been pushed to the model, then just validate in the onSubmit and call error on the individual components for the form. Leave the form validator out of it. On Tue, Jun 29, 2010 at 11:03 PM, Ray Weidner ray.weidner.develo...@gmail.com wrote: Igor (or anyone else who knows the answer), There is one problem with my implementation of the FormValidator in the code that I included earlier. It performs validation using the Form's model object, which is a problem because the input hasn't been mapped onto it at this stage of validation. What I'd like to do now is somehow perform this validation from within the #onSubmit call. I don't know if this is even possible. I am hoping that perhaps I could register the errors by calling error(String) as you mentioned, and then redirecting the form back to processing these validation errors as it normally would. Below is a simplification of the code I'd like to execute in this situation. Note the text // TODO: ??? That's the part that I need to fill in, ideally redirecting back down the 'invalid' pathway. The HTML here is just a form with some fields and a submit button, so I'll omit. *public interface BusinessValidator { public ValidationResult validate (Record record, Action action); } public interface BusinessValidationResult { public boolean isValid (); public Set String getGeneralErrorMessages (); public Set String getFieldErrorFieldNames (); public Set String getFieldErrorMessage (String fieldName); } public interface BusinessService { public List Action getAllActions (); public BusinessValidator getValidator (Action action); public void save (Record record); [lots of other stuff] ... } public class RecordUpdatePage extends WebPage { private Record theRecord = null; private Form Record theForm = null; private BusinessService theService = null; private Action selectedAction = null; public RecordEditPage (BusinessService service, Record record) { theService = service; theRecord = record; createForm (); } public Record getRecord () { return theRecord; } private void createForm () { theForm = new Form Record (recordUpdateForm); theForm.setModel (new CompoundPropertyModel Record (theRecord)); theForm.add (new DropDownChoice Action (action, new PropertyModel Action (this, selectedAction), new LoadableDetachableModel List Action () { @Override protected List Action load () { return new ArrayList Action (theService.getAllActions ()); } }, ) ); ... [add a bunch of fields] ... theForm.add (new Button (save)) { @Override public void onSubmit () { save (); } }; } private void save () { if (! validate ()) { // TODO: ??? } else { theService.save (record); setResponsePage (MainPage.class); } } public boolean validate () { BusinessValidator validator = theService.getValidator (selectedAction); Record record = ((Form Record) form).getModel ().getObject (); BusinessValidation result = validator.validate (theRecord, selectedAction); if (result.isValid ()) { return true; } for (String generalErrorMessage : result.getGeneralErrorMessages ()) { theForm.error (generalErrorMessage); } Map String, Set String fieldErrorMap = result.getErrorMessageMap (); for (String fieldName : fieldErrorMap.keySet ()) { for (String fieldErrorMessage : fieldErrorMap.get (fieldName)) { Component field = theForm.get (fieldName); if (field != null) { field.error (fieldErrorMessage); } else { theForm.error (fieldErrorMessage); } } } return false; } }* On Tue, Jun 29, 2010 at 10:29 AM, Ray Weidner ray.weidner.develo...@gmail.com wrote: Thanks, Igor, I now see the methods you are talking about, and your explanation makes perfect sense. On Tue, Jun 29, 2010 at 1:16 AM, Igor Vaynberg igor.vaynb...@gmail.com wrote: On Mon, Jun 28, 2010 at 9:27 PM, Ray Weidner ray.weidner.develo...@gmail.com wrote: Hi all, The application that I'm current writing already has its own validation logic, but I would like to integrate its results into the existing Wicket form validation so as to unify the feedback. To this end, I'm trying to extend AbstractFormValidator to wrap my system's logic. The way my system's validation works is pretty simple and self
Re: extending AbstractFormValidator as a validation adapter
Thanks, Igor, I now see the methods you are talking about, and your explanation makes perfect sense. On Tue, Jun 29, 2010 at 1:16 AM, Igor Vaynberg igor.vaynb...@gmail.comwrote: On Mon, Jun 28, 2010 at 9:27 PM, Ray Weidner ray.weidner.develo...@gmail.com wrote: Hi all, The application that I'm current writing already has its own validation logic, but I would like to integrate its results into the existing Wicket form validation so as to unify the feedback. To this end, I'm trying to extend AbstractFormValidator to wrap my system's logic. The way my system's validation works is pretty simple and self-explanatory: *public interface Validator {* * **public ValidationResult validate (Record record, Action action);* *}* * * *public interface ValidationResult {* * **public boolean isValid ();* * * * **public Set String getGeneralErrorMessages ();* * * * **public Set String getFieldErrorFieldNames ();* * * * **public Set String getFieldErrorMessages (String fieldName);* *}* The ValidationResultImpl is pretty much a simple bean for setting and getting error messages, both general, and by field. Validator implementations are specific to the need, and the specifics aren't important here. For my adapter, I'm able to get to a certain point, and I'm not sure what call to make next: *public class RecordFormValidator extends AbstractFormValidator {* * **private Validator validator = null;* * **private Action action = null;* * * * **public RecordFormValidator (Validator validator, Action action) {* * **this.validator = validator;* * **this.action = action;* * **}* * * * *...@override* * **public FormComponent ? [] getDependentFormComponents () {* * **return new FormComponent [0];* * **}* * * * *...@override* * **public void validate (Form ? arg0) {* * **Record record = ((Form Record) arg0).getModel ().getObject ();* * **Validation result = validator.validate (record, action);* * * * **for (String generalErrorMessage : result.getGeneralErrorMessages ()) {* * **// TODO: ???* * **}* * **for (String fieldName : result.getFieldErrorFieldNames ()) {* * **for (String fieldErrorMessage : result.getFieldErrorMessages (fieldName)) {* * **// TODO: ???* * **}* * **}* * **}* *}* * * In examples I see online, validation errors seem to be registered by calls of the #error method. It seems like I should be doing that here, too, but what I don't know is: - Which object's #error method should be called? The validator's? The FormComponent corresponding to the field in question? I want field-specific errors appropriately associated with their fields, so I can use filters for field-specific feedback, etc. if you want formcomponent specific errors then you have to map the errors from your business logic to the wicket components and call error on them. - I already have my actual error strings, so how do I skip around the resource logic to just set the error message? there is error(IValidationError) but there is also error(String), call the latter. - What should I do with my generalErrorMessages, which aren't tied to any specific field? i usually report these kinds of errors on the form itself and have a special feedbackpanel that filters those. -igor Any help would be appreciated, thanks! Ray Weidner - To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org For additional commands, e-mail: users-h...@wicket.apache.org
Re: extending AbstractFormValidator as a validation adapter
Igor (or anyone else who knows the answer), There is one problem with my implementation of the FormValidator in the code that I included earlier. It performs validation using the Form's model object, which is a problem because the input hasn't been mapped onto it at this stage of validation. What I'd like to do now is somehow perform this validation from within the #onSubmit call. I don't know if this is even possible. I am hoping that perhaps I could register the errors by calling error(String) as you mentioned, and then redirecting the form back to processing these validation errors as it normally would. Below is a simplification of the code I'd like to execute in this situation. Note the text // TODO: ??? That's the part that I need to fill in, ideally redirecting back down the 'invalid' pathway. The HTML here is just a form with some fields and a submit button, so I'll omit. *public interface BusinessValidator { public ValidationResult validate (Record record, Action action); } public interface BusinessValidationResult { public boolean isValid (); public Set String getGeneralErrorMessages (); public Set String getFieldErrorFieldNames (); public Set String getFieldErrorMessage (String fieldName); } public interface BusinessService { public List Action getAllActions (); public BusinessValidator getValidator (Action action); public void save (Record record); [lots of other stuff] ... } public class RecordUpdatePage extends WebPage { private Record theRecord = null; private Form Record theForm = null; private BusinessService theService = null; private Action selectedAction = null; public RecordEditPage (BusinessService service, Record record) { theService = service; theRecord = record; createForm (); } public Record getRecord () { return theRecord; } private void createForm () { theForm = new Form Record (recordUpdateForm); theForm.setModel (new CompoundPropertyModel Record (theRecord)); theForm.add (new DropDownChoice Action (action, new PropertyModel Action (this, selectedAction), new LoadableDetachableModel List Action () { @Override protected List Action load () { return new ArrayList Action (theService.getAllActions ()); } }, ) ); ... [add a bunch of fields] ... theForm.add (new Button (save)) { @Override public void onSubmit () { save (); } }; } private void save () { if (! validate ()) { // TODO: ??? } else { theService.save (record); setResponsePage (MainPage.class); } } public boolean validate () { BusinessValidator validator = theService.getValidator (selectedAction); Record record = ((Form Record) form).getModel ().getObject (); BusinessValidation result = validator.validate (theRecord, selectedAction); if (result.isValid ()) { return true; } for (String generalErrorMessage : result.getGeneralErrorMessages ()) { theForm.error (generalErrorMessage); } Map String, Set String fieldErrorMap = result.getErrorMessageMap (); for (String fieldName : fieldErrorMap.keySet ()) { for (String fieldErrorMessage : fieldErrorMap.get (fieldName)) { Component field = theForm.get (fieldName); if (field != null) { field.error (fieldErrorMessage); } else { theForm.error (fieldErrorMessage); } } } return false; } }* On Tue, Jun 29, 2010 at 10:29 AM, Ray Weidner ray.weidner.develo...@gmail.com wrote: Thanks, Igor, I now see the methods you are talking about, and your explanation makes perfect sense. On Tue, Jun 29, 2010 at 1:16 AM, Igor Vaynberg igor.vaynb...@gmail.comwrote: On Mon, Jun 28, 2010 at 9:27 PM, Ray Weidner ray.weidner.develo...@gmail.com wrote: Hi all, The application that I'm current writing already has its own validation logic, but I would like to integrate its results into the existing Wicket form validation so as to unify the feedback. To this end, I'm trying to extend AbstractFormValidator to wrap my system's logic. The way my system's validation works is pretty simple and self-explanatory: *public interface Validator {* * **public ValidationResult validate (Record record, Action action);* *}* * * *public interface ValidationResult {* * **public boolean isValid ();* * * * **public Set String getGeneralErrorMessages ();* * * * **public Set String getFieldErrorFieldNames ();* * * * **public Set String getFieldErrorMessages (String fieldName);* *}* The ValidationResultImpl is pretty much a simple bean for setting and getting error messages, both general, and by field. Validator implementations are specific to the need, and the specifics aren't important here. For my adapter, I'm able to get to a certain point, and I'm not sure what call to make next: *public class RecordFormValidator extends AbstractFormValidator {* * **private Validator validator = null;* * **private Action action = null;* * * * **public RecordFormValidator (Validator validator, Action action) {* * **this.validator = validator;* * **this.action = action;* * **}* * * * *...@override* * **public FormComponent
extending AbstractFormValidator as a validation adapter
Hi all, The application that I'm current writing already has its own validation logic, but I would like to integrate its results into the existing Wicket form validation so as to unify the feedback. To this end, I'm trying to extend AbstractFormValidator to wrap my system's logic. The way my system's validation works is pretty simple and self-explanatory: *public interface Validator {* * **public ValidationResult validate (Record record, Action action);* *}* * * *public interface ValidationResult {* * **public boolean isValid ();* * * * **public Set String getGeneralErrorMessages ();* * * * **public Set String getFieldErrorFieldNames ();* * * * **public Set String getFieldErrorMessages (String fieldName);* *}* The ValidationResultImpl is pretty much a simple bean for setting and getting error messages, both general, and by field. Validator implementations are specific to the need, and the specifics aren't important here. For my adapter, I'm able to get to a certain point, and I'm not sure what call to make next: *public class RecordFormValidator extends AbstractFormValidator {* * **private Validator validator = null;* * **private Action action = null;* * * * **public RecordFormValidator (Validator validator, Action action) {* * **this.validator = validator;* * **this.action = action;* * **}* * * * *...@override* * **public FormComponent ? [] getDependentFormComponents () {* * **return new FormComponent [0];* * **}* * * * *...@override* * **public void validate (Form ? arg0) {* * **Record record = ((Form Record) arg0).getModel ().getObject ();* * **Validation result = validator.validate (record, action);* * * * **for (String generalErrorMessage : result.getGeneralErrorMessages ()) {* * **// TODO: ???* * **}* * **for (String fieldName : result.getFieldErrorFieldNames ()) {* * **for (String fieldErrorMessage : result.getFieldErrorMessages (fieldName)) {* * **// TODO: ???* * **}* * **}* * **}* *}* * * In examples I see online, validation errors seem to be registered by calls of the #error method. It seems like I should be doing that here, too, but what I don't know is: - Which object's #error method should be called? The validator's? The FormComponent corresponding to the field in question? I want field-specific errors appropriately associated with their fields, so I can use filters for field-specific feedback, etc. - I already have my actual error strings, so how do I skip around the resource logic to just set the error message? - What should I do with my generalErrorMessages, which aren't tied to any specific field? Any help would be appreciated, thanks! Ray Weidner
Re: passing a map into PageParameters
I haven't had any success storing anything other than Strings in PageParameters objects. It makes sense, since these are supposed to represent bookmarkable (i.e. GET) parameters. If you're hoping to throw arbitrary Maps into a PageParameters, you're going to be disappointed. But if you have an idea what kind of data is going to be in the Map (especially if you're using generics, unlike your example), then you can write a pair of methods to translate between Map and String for this purpose. I'm not sure what limitations on characters that you might run into due to the fact that they have to be embedded in a URL, so you have to try it out. However, I wouldn't be surprised if Wicket escapes everything cleanly, meaning that you don't have to worry about such things. Of course, you don't have to embed your Map within a PageParameters if the page that you want to go to doesn't need to be bookmarkable. In that case, just pass your Map to the destination page object through a constructor of your design, and call #setResponsePage on the page object. On Mon, Jun 28, 2010 at 3:23 PM, Fernando Wermus fernando.wer...@gmail.comwrote: This is not what I want to achieve. I need to pass a map of parameters as just an entry into PageParameters and other entries too. For instance, Map swfParameters=new HashMap(); swfParameteres.put(a, 1); swfParameteres.put(b, 2); PageParameters p=new PageParameters(); p.put(swfParameters, swfParameters); p.put(other, other); On Mon, Jun 28, 2010 at 4:15 PM, jammyjohn jchinnas...@yahoo.com wrote: PageParameters parameters = new PageParameters(swfParameters); This is how the hashmap is constructed in PageParameters.. Thanks, J -- View this message in context: http://apache-wicket.1842946.n4.nabble.com/passing-a-map-into-PageParameters-tp2271341p2271351.html Sent from the Wicket - User mailing list archive at Nabble.com. - To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org For additional commands, e-mail: users-h...@wicket.apache.org -- Fernando Wermus. www.linkedin.com/in/fernandowermus
Re: Making rows of DefaultDataTable into links
Thanks, Jeremy, I think having a real link outweighs having the whole row being a pseudo link, so I'm going to just have the ID column value be a link. But thanks for the advice; it's still informative. On Wed, Jun 16, 2010 at 2:20 AM, Jeremy Thomerson jer...@wickettraining.com wrote: On Wed, Jun 16, 2010 at 1:17 AM, Ray Weidner ray.weidner.develo...@gmail.com wrote: Hi all, Forgive my ignorance if this is too obvious. I'm using DefaultDataTable to display search results, and that's working fine. What I'd like to do is make each row of the table a hyperlink to the view/edit page of the record in question. How can I do this? I was able to add links to a column, although they don't show up in the browser as actual links. Rather, they appear as text with associate javascript to process an onclick event. Here's the custom column I created for this purpose: private class IncidentLinkPropertyColumn extends PropertyColumn IncidentReport { public IncidentLinkPropertyColumn (IModel String nameModel, String propertyName) { super (nameModel, propertyName); } @Override public void populateItem (Item ICellPopulator IncidentReport item, String componentId, IModel IncidentReport model) { PageParameters params = new PageParameters (); params.put (incidentId, model.getObject ().getRecordId ()); item.add (new LabelLink (componentId, CreateOrEditIncidentPage.class, params)); } private class LabelLink extends BookmarkablePageLink Object { private static final long serialVersionUID = 3429331456890689136L; public LabelLink (String componentId, Class ? extends Page pageType, PageParameters parameters) { super (componentId, pageType, parameters); } @Override protected void onComponentTagBody (MarkupStream markupStream, ComponentTag openTag) { replaceComponentTagBody (markupStream, openTag, click here!); } } } As I said, I'd like the rows to be links to the IncidentReport, but barring that, it would be nice if the link column actually appeared as links, so users can right-click to open in a separate tab. If necessary, I can draft an informational column (like ID) to serve as a link, as long as it is a true link (so it will be visually obvious, as well as retaining right-click functionality). Any ideas? Thanks in advance. to make the rows into links, override newItem (or whatever the name is - it starts with new) that creates a new row. then you could add an onclick to the row item, or even an ajaxeventbehavior(onclick) to do some ajax behavior to make the column into a real link, you'll need to use a fragment since the default html for a cell is just a span. -- Jeremy Thomerson http://www.wickettraining.com
Making rows of DefaultDataTable into links
Hi all, Forgive my ignorance if this is too obvious. I'm using DefaultDataTable to display search results, and that's working fine. What I'd like to do is make each row of the table a hyperlink to the view/edit page of the record in question. How can I do this? I was able to add links to a column, although they don't show up in the browser as actual links. Rather, they appear as text with associate javascript to process an onclick event. Here's the custom column I created for this purpose: private class IncidentLinkPropertyColumn extends PropertyColumn IncidentReport { public IncidentLinkPropertyColumn (IModel String nameModel, String propertyName) { super (nameModel, propertyName); } @Override public void populateItem (Item ICellPopulator IncidentReport item, String componentId, IModel IncidentReport model) { PageParameters params = new PageParameters (); params.put (incidentId, model.getObject ().getRecordId ()); item.add (new LabelLink (componentId, CreateOrEditIncidentPage.class, params)); } private class LabelLink extends BookmarkablePageLink Object { private static final long serialVersionUID = 3429331456890689136L; public LabelLink (String componentId, Class ? extends Page pageType, PageParameters parameters) { super (componentId, pageType, parameters); } @Override protected void onComponentTagBody (MarkupStream markupStream, ComponentTag openTag) { replaceComponentTagBody (markupStream, openTag, click here!); } } } As I said, I'd like the rows to be links to the IncidentReport, but barring that, it would be nice if the link column actually appeared as links, so users can right-click to open in a separate tab. If necessary, I can draft an informational column (like ID) to serve as a link, as long as it is a true link (so it will be visually obvious, as well as retaining right-click functionality). Any ideas? Thanks in advance.
back button and page expiration
Hi all, The web app I've been working on has some issues with the back button. For instance, when using DefaultDataView, if a user goes back a page after clicking a column heading, and then clicks a different link on the page, it would cause an error. This problem was easily solved manually by refreshing the page, so my objective was to force the browser to reload a page upon using the back button. This was accomplished by directing the browser to cache/store nothing with the following code: @Override protected void configureResponse() { super.configureResponse(); final WebResponse response = getWebRequestCycle().getWebResponse(); response.setHeader(Cache-Control, no-cache, max-age=0, must-revalidate, no-store); } Basically, the equivalent of certain meta tags in the html header. However, now I'm running into a different issue. When hitting back and revisiting an old page, users now get the message that the page has expired. While this is much better than displaying a runtime exception stack trace, I'd like to actually just refresh certain pages in this case, rather than expiring them. In fact, it would be good to flag some pages as expired, while reloading others. So how can I do this? And why are stale pages now showing up as expired in the first place, when previously, reloading a stale page worked fine? Ray Weidner
Re: Can I develop without recompiling/restarting after every change?
Nobody seems to have mentioned it, but I have been developing with Eclipse's Dynamic Web Projects, and it has greatly shortened my development cycle from when I was loading the project into Tomcat through the manager web interface. Basically, a DWP is able to run the server itself, and it automatically republishes a new build and restarts the server in the background. Even when I have to start it myself, it is fast, and I don't have to leave the Eclipse interface. More importantly, I am able to run my code in debug, allowing me to set breakpoints etc. I don't have enough experience with the other solutions to compare it, but it sure beats manual deployment and restarting the server every time you want to try a new build. DWP is built into Eclipse, not requiring any additional plug-ins. You just create the project as a DWP and take it from there. I ported a different project's web code into the DWP simply by copying over the relevant code, and making changes needed to build. The directory layout corresponds roughly to the internal structure of the resulting WAR file, so it's pretty easy to figure out where different files should go. When you want to create a WAR file for use outside the project, you just export the project to a WAR. Debugging and building can all be performed using Eclipses standard menu options. The only trick is that you have to create a server for your DWP, and you want to point that instance to an actual installed instance of Tomcat or JBoss. This presents you with new artifact on the Package View, and you might want to open up the Server View window for control over it (start, stop and publish are the main things to do here). That's all there is to it. On Fri, May 21, 2010 at 11:53 AM, ekallevig e...@ekallevig.com wrote: I'm a front-end developer trying to learn Java (total n00b) and working on a wicket application at work. The whole process feels very slow primarily because I have to recompile and restart JBoss every time I make a change. So I'm wondering what the best way is to avoid having to do this when editing .java/.js/.css/.html files during development? I'd like to just make changes and then refresh the browser to test -- is this possible?
statefulness, and multiple tabs
I have a question about how to approach a certain kind of problem. Let me first explain what I'm doing, and then what the problem is with that. For the web app I'm creating, a user can, using a web form, edit data which is backed by a model that fetches the persistent object being modified. When the OK button is clicked, the changes are committed, and then show up in the database. So far, so good. While editing a given record called Issue, the user may choose to edit other records that it references (AffectedParty, in this case). To do this, we switch to the new page without performing any commit. When the referenced record is updated, the user returns to the original Issue record. So far, nothing has been committed. All changes will committed when editing is complete for the Issue record. The problem occurs when users open multiple tabs to multiple Issues. In this case, my persistence framework (Hibernate) is using one session for all updates, so a commit to one will affect all the others. This can cause all kinds of complex problems when the user is editing multiple unrelated records at the same time. I would like this application to be able to support working on multiple records at once. One place this can be fixed is in the persistence layer, by associating unrelated records with separate Sessions. However, this can get complicated, fast. Another thing that I might try is to detach the record from Hibernate at the end of each page being rendered, and reattach it at the time of update. Right now, this seems like the most reasonable solution. Is there a standard Wicket solution for this problem? A friend of mine who uses Seam suggested that I check out whether or not Wicket supports conversations, a concept with which I'm only partly familiar (they're like transactions, but can comprise multiple individual transactions...right?). So far, it looks to me like Wicket doesn't directly support this concept, and I'm not even sure how it would help me, anyway. Any suggestions?
Date components
Hi All, Does anyone have any good suggestions for date/time entry components? Does Wicket offer a standard solution for this common case? Thanks, Ray Weidner
Re: Date components
Thanks, I'll give that one a try. On Mon, Apr 19, 2010 at 10:59 AM, moèz ben rhouma benrhouma.m...@gmail.comwrote: You just add the following code to your java page: *add(dateTimeField = new DateTimeField(dateEnvoi, new PropertyModel(this, date)) {});* Which dateEnvoi defined in the markup file (the key of the component). And date defined in java like : private Date date = new Date(); 2010/4/19 Ray Weidner ray.weidner.wic...@gmail.com Hi All, Does anyone have any good suggestions for date/time entry components? Does Wicket offer a standard solution for this common case? Thanks, Ray Weidner
problem populating ListMultipleChoice selection model
Hi All, I'm trying to do something pretty simple: create a choice list with multi-select, which I iterate through upon clicking a button. Unfortunately, it looks like my selections aren't being recorded in the model that's supposed to receive them. Here's what the pertinent code looks like: - Java: public EditIssuePage extends WebPage { // I've tried removing the 'transient' keyword, but that doesn't change anything transient private Set Party selectedParties = new HashMap Party (); ... public EditIssuePage () { ... Form form = new Form (editIssueForm); add (form); ... ListMultipleChoice Party partyChoice = new ListMultipleChoice Party ( parties, new PropertyModel (this, selectedParties), new LoadableDetachableModel List Party () { @Override public List Party load () { return new Vector Party (retrieveAllPartiesFromDAO ()); } }, new IChoiceRenderer Party () { public Object getDisplayValue (Party object) { return object.getFullName (); } public String getIdValue (Party object, int index) { return object.getId (); } } ); Button addPartiesButton = new Button (addPartiesButton) { @Override public void onSubmit () { logger.debug (Number of selected parties: + selectedParties.size ()); // always reporting zero! for (Party selectedParty : selectedParties) { ... } } }; form.add (partyChoice); form.add (addPartiesButton); } private Set Party retrieveAllPartiesFromDAO () { // does what it sounds like } } - HTML: (My memory is a bit hazy here; I don't have any of this code in front of me as I write this) ... select multiple wicket:id=parties option[A party should be here]/option /select submit wicket:id=addPartiesButton name=Add Selected Parties/ ... The page renders fine, with all Party objects listed for selection. But when I select one or more of the rows and click the button, the log message I see is Number of selected parties: 0, no matter what. I have very similar logic working on another page, so I'm pretty confused about what's the problem here. All advice is much appreciated. Thanks, Ray Weidner
Re: problem populating ListMultipleChoice selection model
Hi Moez, I'll give that a try when I have the code in front of me. But I'd be surprised if that works, because I am doing precisely the same thing on another page, including using a Set for the selected item model. In that instance, there's no problem. On Mon, Apr 19, 2010 at 11:55 AM, moèz ben rhouma benrhouma.m...@gmail.comwrote: Try to change the type of selectedParties from set to List selectedParties = new ArrayList(); 2010/4/19 Ray Weidner ray.weidner.wic...@gmail.com Hi All, I'm trying to do something pretty simple: create a choice list with multi-select, which I iterate through upon clicking a button. Unfortunately, it looks like my selections aren't being recorded in the model that's supposed to receive them. Here's what the pertinent code looks like: - Java: public EditIssuePage extends WebPage { // I've tried removing the 'transient' keyword, but that doesn't change anything transient private Set Party selectedParties = new HashMap Party (); ... public EditIssuePage () { ... Form form = new Form (editIssueForm); add (form); ... ListMultipleChoice Party partyChoice = new ListMultipleChoice Party ( parties, new PropertyModel (this, selectedParties), new LoadableDetachableModel List Party () { @Override public List Party load () { return new Vector Party (retrieveAllPartiesFromDAO ()); } }, new IChoiceRenderer Party () { public Object getDisplayValue (Party object) { return object.getFullName (); } public String getIdValue (Party object, int index) { return object.getId (); } } ); Button addPartiesButton = new Button (addPartiesButton) { @Override public void onSubmit () { logger.debug (Number of selected parties: + selectedParties.size ()); // always reporting zero! for (Party selectedParty : selectedParties) { ... } } }; form.add (partyChoice); form.add (addPartiesButton); } private Set Party retrieveAllPartiesFromDAO () { // does what it sounds like } } - HTML: (My memory is a bit hazy here; I don't have any of this code in front of me as I write this) ... select multiple wicket:id=parties option[A party should be here]/option /select submit wicket:id=addPartiesButton name=Add Selected Parties/ ... The page renders fine, with all Party objects listed for selection. But when I select one or more of the rows and click the button, the log message I see is Number of selected parties: 0, no matter what. I have very similar logic working on another page, so I'm pretty confused about what's the problem here. All advice is much appreciated. Thanks, Ray Weidner
Trying to do something complicated with ListMultipleChoice model
Hi, I'm pretty new to Wicket and trying to get a better understanding of how models work. That's probably why this is such a tricky problem for me. On my site, users are submitting a form for a new Issue to be created. One of the fields of this Issue is affectedParties; in the data model, this is represented by a collection of PartyIssue objects, which associate a Party with an Issue. Here's the simplified code: public class Issue { ... private Set PartyIssue affectedParties; public Set PartyIssue getAffectedParties () { ... } public void setAffectedParties (Set PartyIssue affectedParties) { ... } ... } public class Party { ... } public class PartyIssue { private Issue issue; private Party party; ... } The new Issue Form uses a new Issue object as the argument for the CompoundPropertyModel. What I want to do is allow users to specify the affected parties by multi-selecting from a list of Parties. Then, at the time of submission, we should iterate through this list and construct corresponding PartyIssues, which are associated with the Issue and then created by the service layer (with validation etc.). So, how would I do this? This is how I've been trying to construct the ListMultipleChoice: private Set Party affectedParties = new HashSet Party (); private ListMultipleChoice Party buildPartyDropdown (String property) { IModel Collection Party affectedPartyModel = new IModel Collection Party () { @Override public Collection Party getObject () { return affectedParties; } @Override public void setObject (Collection Party arg0) { affectedParties.clear (); affectedParties.addAll (arg0); } @Override public void detach () { // Nothing to do here } }; IChoiceRenderer Party partyListRenderer = new IChoiceRenderer Party () { private static final long serialVersionUID = -1588547331340300417L; @Override public Object getDisplayValue (Party arg0) { return arg0.getFullName (); } @Override public String getIdValue (Party arg0, int arg1) { return Long.toString (arg0.getRecordId ()); } }; ListMultipleChoice Party choice = new ListMultipleChoice Party (property, affectedPartyModel, new Vector Party (getAllParties ()), partyListRenderer); return choice; } In my onSubmit() code for the Form, I attempt to iterate through the affectedParties Set to create the Set of PartyIssues. However, this is always turning out to be empty no matter what is selected on the form. The problem isn't in the onSubmit() code because the rest of the form is processed and persisted properly, and log messages show that affectedParties is empty at that point. Note that the list choices are being rendered properly. I'm sure I'm doing something very wrong so I'd appreciate any guidance.
Re: Trying to do something complicated with ListMultipleChoice model
Hi Sven, Thanks, that did the trick. I thought that the Collection argument was being generated by the framework, but now I understand what's happening. On Sat, Apr 10, 2010 at 4:00 PM, Sven Meier s...@meiers.net wrote: Hi, ListMultipleChoice puts all selected parties into the model object you're returning in #getObject(). Either you should return a copy of your collection in #getObject() or just do nothing in #setObject(). Your current call to #clear() is effectively clearing the new selection (i.e. affectedParties and arg0 are identical). Regards Sven Ray Weidner wrote: Hi, I'm pretty new to Wicket and trying to get a better understanding of how models work. That's probably why this is such a tricky problem for me. On my site, users are submitting a form for a new Issue to be created. One of the fields of this Issue is affectedParties; in the data model, this is represented by a collection of PartyIssue objects, which associate a Party with an Issue. Here's the simplified code: public class Issue { ... private Set PartyIssue affectedParties; public Set PartyIssue getAffectedParties () { ... } public void setAffectedParties (Set PartyIssue affectedParties) { ... } ... } public class Party { ... } public class PartyIssue { private Issue issue; private Party party; ... } The new Issue Form uses a new Issue object as the argument for the CompoundPropertyModel. What I want to do is allow users to specify the affected parties by multi-selecting from a list of Parties. Then, at the time of submission, we should iterate through this list and construct corresponding PartyIssues, which are associated with the Issue and then created by the service layer (with validation etc.). So, how would I do this? This is how I've been trying to construct the ListMultipleChoice: private Set Party affectedParties = new HashSet Party (); private ListMultipleChoice Party buildPartyDropdown (String property) { IModel Collection Party affectedPartyModel = new IModel Collection Party () { @Override public Collection Party getObject () { return affectedParties; } @Override public void setObject (Collection Party arg0) { affectedParties.clear (); affectedParties.addAll (arg0); } @Override public void detach () { // Nothing to do here } }; IChoiceRenderer Party partyListRenderer = new IChoiceRenderer Party () { private static final long serialVersionUID = -1588547331340300417L; @Override public Object getDisplayValue (Party arg0) { return arg0.getFullName (); } @Override public String getIdValue (Party arg0, int arg1) { return Long.toString (arg0.getRecordId ()); } }; ListMultipleChoice Party choice = new ListMultipleChoice Party (property, affectedPartyModel, new Vector Party (getAllParties ()), partyListRenderer); return choice; } In my onSubmit() code for the Form, I attempt to iterate through the affectedParties Set to create the Set of PartyIssues. However, this is always turning out to be empty no matter what is selected on the form. The problem isn't in the onSubmit() code because the rest of the form is processed and persisted properly, and log messages show that affectedParties is empty at that point. Note that the list choices are being rendered properly. I'm sure I'm doing something very wrong so I'd appreciate any guidance. - To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org For additional commands, e-mail: users-h...@wicket.apache.org