package hu.sch.web.profile.edit; import hu.sch.domain.user.Gender; import hu.sch.domain.user.IMAccount; import hu.sch.domain.user.IMProtocol; import hu.sch.domain.user.ProfileImage; import hu.sch.domain.user.User; import hu.sch.domain.user.UserAttributeName; import hu.sch.services.UserManagerLocal; import hu.sch.util.PatternHolder; import hu.sch.services.exceptions.NotImplementedException; import hu.sch.services.exceptions.PekEJBException; import hu.sch.web.profile.show.ShowPersonPage; import hu.sch.web.wicket.behaviors.ValidationStyleBehavior; import hu.sch.web.wicket.components.ProfileImageResource; import hu.sch.web.wicket.components.ValidationSimpleFormComponentLabel; import hu.sch.web.wicket.components.customlinks.AttributeAjaxFallbackLink; import java.util.*; import javax.inject.Inject; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.AjaxFallbackLink; import org.apache.wicket.ajax.markup.html.form.AjaxFallbackButton; import org.apache.wicket.datetime.StyleDateConverter; import org.apache.wicket.datetime.markup.html.form.DateTextField; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.*; import org.apache.wicket.markup.html.form.upload.FileUpload; import org.apache.wicket.markup.html.form.upload.FileUploadField; import org.apache.wicket.markup.html.image.NonCachingImage; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.RefreshingView; import org.apache.wicket.markup.repeater.ReuseIfModelsEqualStrategy; import org.apache.wicket.markup.repeater.util.ModelIteratorAdapter; import org.apache.wicket.model.*; import org.apache.wicket.validation.validator.EmailAddressValidator; import org.apache.wicket.validation.validator.PatternValidator; import org.apache.wicket.validation.validator.StringValidator; import org.apache.wicket.validation.validator.UrlValidator; /** * * @author konvergal */ class PersonForm extends Form<User> { private final User user; private List<FileUpload> upload; private final RefreshingView<IMAccount> refreshView; private static final int NAMES_MIN_LENGTH = 2; private static final int NAMES_MAX_LENGTH = 40; @Inject private UserManagerLocal userManager; public PersonForm(final String componentName, final User user) { super(componentName); this.user = user; setModel(new CompoundPropertyModel<>(user)); setMultiPart(true); createNameFields(); createGenderField(); createAdditionalFields(); createDormitoryFields(); //Ezt muszáj a konstruktorban csinálni a final kulcsszó miatt. final WebMarkupContainer rowPanel = new WebMarkupContainer("rowPanel"); final IModel<Set<IMAccount>> model = new PropertyModel<>(user, "imAccounts"); refreshView = new RefreshingView<IMAccount>("ims", model) { @Override protected Iterator<IModel<IMAccount>> getItemModels() { return new ModelIteratorAdapter<IMAccount>(model.getObject().iterator()) { @Override protected IModel<IMAccount> model(IMAccount object) { return Model.of(object); } }; } @Override protected void populateItem(final Item<IMAccount> item) { final IMAccount acc = item.getModelObject(); final Set<IMAccount> currObj = (Set<IMAccount>) getDefaultModelObject(); item.add(new DropDownChoice("imProtocol", new PropertyModel(acc, "protocol"), Arrays.asList(IMProtocol.values()))); item.add(new TextField("imPresenceID", new PropertyModel(acc, "accountName"))); item.add(new AjaxFallbackButton("imRemove", PersonForm.this) { @Override protected void onError(AjaxRequestTarget target, Form<?> form) { } @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form) { currObj.remove(acc); if (target != null) { target.add(rowPanel); } } }.setDefaultFormProcessing(false)); } }.setItemReuseStrategy(new ReuseIfModelsEqualStrategy()); rowPanel.add(refreshView); rowPanel.add(new AjaxFallbackButton("imAdd", PersonForm.this) { @Override protected void onError(AjaxRequestTarget target, Form<?> form) { } @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form) { ((Set<IMAccount>) refreshView.getDefaultModelObject()).add(new IMAccount(IMProtocol.gtalk, "")); if (target != null) { target.add(rowPanel); } for (IMAccount iMAccount : ((Set<IMAccount>) refreshView.getDefaultModelObject())) { System.out.println(iMAccount.toString()); } } }.setDefaultFormProcessing(false)); rowPanel.setOutputMarkupId(true); add(rowPanel); createPhotoField(); add(new Label("neptunLabel", new PropertyModel(user, "neptunCode"))); initAjaxPrivateLinks(); //nem szabad használni a Form#onSubmit() függvényt, mindenképp szükség //van erre a gombra, különben az IM listás Ajax elromlik! A setResponsePage //true flag miatt készül ki valamiért. //Bővebben: http://osdir.com/ml/users-wicket.apache.org/2009-08/msg00836.html final Button submitButton = new Button("submitButton") { @Override public void onSubmit() { if (hasError()) { error("Hiba a formon!"); return; // TODO: proper error message } ProfileImage image = null; if (upload != null && !upload.isEmpty()) { FileUpload fu = upload.get(0); image = new ProfileImage(fu.getContentType(), fu.getBytes(), fu.getSize()); } try { userManager.updateUser(user, image); } catch (PekEJBException ex) { error(new StringResourceModel(ex.getErrorCode().getMessageKey(), this, null, ex.getParameters()).getString()); return; } getSession().info("Sikeres adatmódosítás. :)"); setResponsePage(ShowPersonPage.class); } }; add(submitButton); setDefaultButton(submitButton); } private void createNameFields() { final RequiredTextField<String> lastNameTF = new RequiredTextField<String>("lastName"); lastNameTF.add(StringValidator.lengthBetween(NAMES_MIN_LENGTH, NAMES_MAX_LENGTH)); lastNameTF.add(new ValidationStyleBehavior()); add(lastNameTF); lastNameTF.setLabel(new Model<String>("Vezetéknév *")); add(new ValidationSimpleFormComponentLabel("lastNameLabel", lastNameTF)); final RequiredTextField<String> firstNameTF = new RequiredTextField<String>("firstName"); firstNameTF.add(StringValidator.lengthBetween(NAMES_MIN_LENGTH, NAMES_MAX_LENGTH)); firstNameTF.add(new ValidationStyleBehavior()); add(firstNameTF); firstNameTF.setLabel(new Model<String>("Keresztnév *")); add(new ValidationSimpleFormComponentLabel("firstNameLabel", firstNameTF)); final TextField<String> nickNameTF = new TextField<String>("nickName"); nickNameTF.add(StringValidator.lengthBetween(NAMES_MIN_LENGTH, NAMES_MAX_LENGTH)); nickNameTF.add(new ValidationStyleBehavior()); add(nickNameTF); nickNameTF.setLabel(new Model<String>("Becenév")); add(new ValidationSimpleFormComponentLabel("nickNameLabel", nickNameTF)); } private void createGenderField() { DropDownChoice<Gender> genderChoice = new DropDownChoice<>("gender", Arrays.asList(Gender.values())); // genderChoice.setModel(new PropertyModel<Gender>(user, "gender")); genderChoice.setChoiceRenderer(new EnumChoiceRenderer<Gender>(this)); add(genderChoice); genderChoice.setLabel(Model.of("Nem")); add(new SimpleFormComponentLabel("genderLabel", genderChoice)); } private void createAdditionalFields() { DateTextField dateTF = new DateTextField("dateOfBirth", new StyleDateConverter("S-", true)) { @Override public Locale getLocale() { return new Locale("hu"); } }; dateTF.add(new ValidationStyleBehavior()); dateTF.setLabel(new Model<String>("Születési dátum")); add(new ValidationSimpleFormComponentLabel("dateOfBirthLabel", dateTF)); add(dateTF); TextField<String> homePostalAddressTF = new TextField<String>("homeAddress"); add(homePostalAddressTF); homePostalAddressTF.setLabel(new Model<String>("Cím")); add(new SimpleFormComponentLabel("homePostalAddressLabel", homePostalAddressTF)); RequiredTextField<String> mailTF = new RequiredTextField<String>("emailAddress"); mailTF.add(EmailAddressValidator.getInstance()); mailTF.add(new ValidationStyleBehavior()); add(mailTF); mailTF.setLabel(new Model<String>("E-mail *")); add(new ValidationSimpleFormComponentLabel("mailLabel", mailTF)); TextField<String> mobileTF = new TextField<String>("cellPhone"); add(mobileTF); mobileTF.setLabel(new Model<String>("Mobil")); mobileTF.add(new PatternValidator(PatternHolder.PHONE_NUMBER_PATTERN)); add(new ValidationSimpleFormComponentLabel("mobileLabel", mobileTF)); TextField<String> webpageTF = new TextField<String>("webpage") { @Override public String[] getInputAsArray() { //lásd: http://www.mail-archive.com/users@wicket.apache.org/msg29215.html String[] inputArray = super.getInputAsArray(); if (inputArray != null && inputArray.length != 0 && inputArray[0] != null) { String value = inputArray[0]; if (!value.startsWith("http") && !value.isEmpty()) { value = "http://" + value; inputArray[0] = value; } } return inputArray; } }; webpageTF.add(new UrlValidator()); webpageTF.add(new ValidationStyleBehavior()); add(webpageTF); webpageTF.setLabel(new Model<String>("Weboldal")); add(new ValidationSimpleFormComponentLabel("webpageLabel", webpageTF)); } private void createDormitoryFields() { TextField<String> rNumberTF = new TextField<String>("room"); add(rNumberTF); rNumberTF.setLabel(new Model<String>("Szobaszám")); add(new SimpleFormComponentLabel("rNumberLabel", rNumberTF)); List<String> dormitories = Arrays.asList(new String[]{"Schönherz", "Tétény", "Kármán", "Vásárhelyi"}); DropDownChoice<String> dormitory = new DropDownChoice<String>("dormitory", dormitories); dormitory.setNullValid(true); add(dormitory); dormitory.setLabel(new Model<String>("Kollégium")); add(new SimpleFormComponentLabel("dormitoryLabel", dormitory)); } private void createPhotoField() { final NonCachingImage photo = new NonCachingImage("photo", new AbstractReadOnlyModel<ProfileImageResource>() { @Override public ProfileImageResource getObject() { return new ProfileImageResource(user); } }); photo.setOutputMarkupId(true); add(photo); AjaxFallbackLink photoRemoveLink = new AjaxFallbackLink("photoRemoveLink") { @Override public void onClick(AjaxRequestTarget target) { try { userManager.removeProfileImage(user); } catch (PekEJBException ex) { // error(new StringResourceModel(ex.getErrorCode().getMessageKey(), // null, ex.getParameters())); // TODO: report error to user throw new NotImplementedException("report error to user"); } setVisible(false); photo.setVisible(false); target.add(this); target.add(photo); } }; photoRemoveLink.setOutputMarkupId(true); add(photoRemoveLink); if (!user.hasPhoto()) { photo.setVisible(false); photoRemoveLink.setVisible(false); } add(new FileUploadField("fileInput", new PropertyModel<List<FileUpload>>(this, "upload"))); } private void initAjaxPrivateLinks() { add(new AttributeAjaxFallbackLink("mailAttributeLink", "mailAttributeImg", UserAttributeName.EMAIL, user)); add(new AttributeAjaxFallbackLink("mobileAttributeLink", "mobileAttributeImg", UserAttributeName.CELL_PHONE, user)); add(new AttributeAjaxFallbackLink("roomNumberAttributeLink", "roomNumberAttributeImg", UserAttributeName.ROOM_NUMBER, user)); add(new AttributeAjaxFallbackLink("homePostalAddressAttributeLink", "homePostalAddressAttributeImg", UserAttributeName.HOME_ADDRESS, user)); add(new AttributeAjaxFallbackLink("webpageAttributeLink", "webpageAttributeImg", UserAttributeName.WEBPAGE, user)); add(new AttributeAjaxFallbackLink("dateOfBirthAttributeLink", "dateOfBirthAttributeImg", UserAttributeName.DATE_OF_BIRTH, user)); } }