r3178 - in branches/pollen-1.2.6-struts2: pollen-services/src/main/java/org/chorem/pollen/services/impl pollen-ui-struts2/src/main/java/org/chorem/pollen/ui pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll pollen-ui-struts2/src/main/resources/config pollen-ui-struts2/src/main/resources/i18n pollen-ui-struts2/src/main/webapp/WEB-INF/jsp pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll
Author: tchemit Date: 2012-03-13 15:06:19 +0100 (Tue, 13 Mar 2012) New Revision: 3178 Url: http://chorem.org/repositories/revision/pollen/3178 Log: page de creation de sondage presque finie :) Added: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayPersonToList.java branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayVotingList.java branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/personToList.jsp branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/votingList.jsp branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/votingListHelper.jsp Modified: branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollService.java branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/PollenSession.java branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/PollenTopiaTransactionFilter.java branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/CreatePoll.java branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/config/struts-poll.xml branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_en_GB.properties branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_fr_FR.properties branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/create.jsp branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/dateChoice.jsp branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/imageChoice.jsp branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/result.jsp branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/resume.jsp branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/textChoice.jsp branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/vote.jsp Modified: branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollService.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollService.java 2012-03-13 14:01:33 UTC (rev 3177) +++ branches/pollen-1.2.6-struts2/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollService.java 2012-03-13 14:06:19 UTC (rev 3178) @@ -251,9 +251,7 @@ // email notification EmailService emailService = newService(EmailService.class); - emailService.onPollCreated(poll, - pollVoteUrl, - pollEditUrl); + emailService.onPollCreated(poll, pollVoteUrl, pollEditUrl); // feed notification PollFeedService pollFeedService = newService(PollFeedService.class); Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/PollenSession.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/PollenSession.java 2012-03-13 14:01:33 UTC (rev 3177) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/PollenSession.java 2012-03-13 14:06:19 UTC (rev 3178) @@ -55,23 +55,35 @@ this.userAccount = userAccount; } - public Map<String, Object> getDynamicData() { - if (dynamicData == null) { - dynamicData = Maps.newHashMap(); - } - return dynamicData; + public <T> T getDynamicData(String token) { + Object result = getDynamicData().get(token); + return (T) result; } public void putDynamicData(String token, Object data) { getDynamicData().put(token, data); + if (log.isInfoEnabled()) { + log.info("Dynamic attributes size : " + getDynamicData().size()); + } } - public <T> T getDynamicData(String token) { - Object result = getDynamicData().get(token); - return (T) result; - } - public void removeDynamicData(String token) { getDynamicData().remove(token); + if (log.isInfoEnabled()) { + log.info("Dynamic attributes size : " + getDynamicData().size()); + } } + + public void clearDynamicData() { + if (dynamicData != null) { + dynamicData.clear(); + } + } + + protected Map<String, Object> getDynamicData() { + if (dynamicData == null) { + dynamicData = Maps.newHashMap(); + } + return dynamicData; + } } Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/PollenTopiaTransactionFilter.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/PollenTopiaTransactionFilter.java 2012-03-13 14:01:33 UTC (rev 3177) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/PollenTopiaTransactionFilter.java 2012-03-13 14:06:19 UTC (rev 3178) @@ -31,6 +31,8 @@ import org.nuiton.topia.TopiaRuntimeException; import org.nuiton.web.filter.TopiaTransactionFilter; +import javax.servlet.ServletRequest; + /** * EchoBase implementation of the {@link TopiaTransactionFilter}. * @@ -44,7 +46,7 @@ LogFactory.getLog(PollenTopiaTransactionFilter.class); @Override - protected TopiaContext beginTransaction() throws TopiaRuntimeException { + protected TopiaContext beginTransaction(ServletRequest request) throws TopiaRuntimeException { PollenApplicationContext applicationContext = PollenActionSupport.getPollenApplicationContext(); Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/CreatePoll.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/CreatePoll.java 2012-03-13 14:01:33 UTC (rev 3177) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/CreatePoll.java 2012-03-13 14:06:19 UTC (rev 3178) @@ -24,6 +24,7 @@ package org.chorem.pollen.ui.actions.poll; import com.google.common.base.Preconditions; +import com.google.common.base.Predicate; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; @@ -37,9 +38,15 @@ import org.chorem.pollen.bean.PollImageChoice; import org.chorem.pollen.business.persistence.Choice; import org.chorem.pollen.business.persistence.ChoiceImpl; +import org.chorem.pollen.business.persistence.PersonToList; +import org.chorem.pollen.business.persistence.PersonToListImpl; import org.chorem.pollen.business.persistence.Poll; +import org.chorem.pollen.business.persistence.PollAccount; +import org.chorem.pollen.business.persistence.PollAccountImpl; import org.chorem.pollen.business.persistence.PreventRule; import org.chorem.pollen.business.persistence.UserAccount; +import org.chorem.pollen.business.persistence.VotingList; +import org.chorem.pollen.business.persistence.VotingListImpl; import org.chorem.pollen.common.ChoiceType; import org.chorem.pollen.common.I18nAble; import org.chorem.pollen.common.PollType; @@ -47,6 +54,7 @@ import org.chorem.pollen.services.impl.PollService; import org.chorem.pollen.services.impl.PreventRuleService; import org.chorem.pollen.ui.actions.PollenActionSupport; +import org.nuiton.util.StringUtil; import java.io.File; import java.util.Collections; @@ -71,14 +79,17 @@ private static final Log log = LogFactory.getLog(CreatePoll.class); public static final Pattern TEXT_CHOICE_NAME_PATTERN = - Pattern.compile("textChoice_(\\d+).name"); + Pattern.compile("textChoice_(\\d+)\\.name"); public static final Pattern DATE_CHOICE_NAME_PATTERN = - Pattern.compile("dateChoice_(\\d+).name"); + Pattern.compile("dateChoice_(\\d+)\\.name"); public static final Pattern IMAGE_CHOICE_NAME_PATTERN = - Pattern.compile("imageChoice_(\\d+).name"); + Pattern.compile("imageChoice_(\\d+)\\.name"); + public static final Pattern VOTING_LIST_NAME_PATTERN = + Pattern.compile("votingList_(\\d+)\\.name"); + protected Poll poll; protected Map<String, String> pollTypes; @@ -101,12 +112,16 @@ private String imageChoiceTokenId; + private String votingListTokenId; + private int nbTextChoices; private int nbDateChoices; private int nbImageChoices; + private int nbVotingLists; + /** Uploaded images (for choice type poll). */ private List<File> imageChoice; @@ -122,6 +137,10 @@ */ private Map<String, String[]> parameters; + private boolean informationsError; + + private boolean optionsError; + protected transient PollService pollService; @Override @@ -162,6 +181,14 @@ return imageChoiceTokenId; } + public int getNbVotingLists() { + return nbVotingLists; + } + + public String getVotingListTokenId() { + return votingListTokenId; + } + public Map<String, String> getPollTypes() { return pollTypes; } @@ -239,6 +266,46 @@ addtoList(getImageChoiceFileName(), index, imageChoiceFileName); } + public boolean isInformationsError() { + return informationsError; + } + + public boolean isOptionsError() { + return optionsError; + } + + public boolean isFreePoll() { + PollType pollType = poll.getPollType(); + return pollType == PollType.FREE; + } + + public boolean isGroupPoll() { + PollType pollType = poll.getPollType(); + return pollType == PollType.GROUP; + } + + public String getPollVoteUrl() { + return getPollService().getPollVoteUrl(poll); + } + + public String getPollEditUrl() { + return getPollService().getPollEditUrl(poll); + } + + public int getSelectedTab() { + int result; + if (isInformationsError()) { + result = 0; + } else { + if (isOptionsError()) { + result = 1; + } else { + result = 0; + } + } + return result; + } + @Override public void prepare() throws Exception { @@ -248,6 +315,7 @@ //TODO tchemit-2012-03-05 use a default value from configuration nbTextChoices = nbDateChoices = nbImageChoices = 5; + nbVotingLists = 1; String tokenSuffix = getServiceContext().createPollenUrlId(); @@ -284,6 +352,13 @@ break; } getPollenSession().putDynamicData(tokenId, choices); + + // load votingLists + + votingListTokenId = DisplayVotingList.VOTING_LIST_TOKEN + "_" + + tokenSuffix; + Map<Integer, VotingList> votingLists = buildVotingLists(1); + getPollenSession().putDynamicData(votingListTokenId, votingLists); } @Override @@ -293,9 +368,11 @@ // poll must have a title if (StringUtils.isEmpty(poll.getTitle())) { - addFieldError("poll.title", _("poll.error.poll.required.title")); + addFieldError("poll.title", _("pollen.error.poll.required.title")); } + informationsError = false; + // validate choices Map<Integer, Choice> orderedChoices = getOrderedChoices(); @@ -303,7 +380,8 @@ // poll must have at least one choice addFieldError("poll.choices", - _("poll.error.poll.required.one.choice")); + _("pollen.error.poll.required.one.choice")); + informationsError = true; } else { //TODO tchemit improve this (from different cases text-date-image) @@ -319,12 +397,34 @@ } if (duplicateNameDetected) { addFieldError("poll.choices", - _("poll.error.poll.detected.duplicate.choice.name")); + _("pollen.error.poll.detected.duplicate.choice.name")); + informationsError = true; } } + optionsError = false; + // validate security stuff + if (isFreePoll()) { + + // nothing to validate + + } else { + Map<Integer, VotingList> votingLists = getOrderedVotingLists(); + + Set<String> groups = Sets.newHashSet(); + Set<String> voters = Sets.newHashSet(); + Set<String> emails = Sets.newHashSet(); + + for (Map.Entry<Integer, VotingList> entry : votingLists.entrySet()) { + optionsError |= validateVotingList(entry.getKey(), + entry.getValue(), + groups, + voters, + emails); + } + } } @Override @@ -337,6 +437,15 @@ poll.addChoice(choice); } + if (!isFreePoll()) { + + Map<Integer, VotingList> votingLists = getOrderedVotingLists(); + for (Integer index : votingLists.keySet()) { + VotingList votingList = votingLists.get(index); + poll.addVotingList(votingList); + } + } + PollService service = getPollService(); PreventRuleService preventRuleService = @@ -363,20 +472,183 @@ poll = service.createPoll(poll); // remove all stuff from session - getPollenSession().removeDynamicData(textChoiceTokenId); - getPollenSession().removeDynamicData(dateChoiceTokenId); - getPollenSession().removeDynamicData(imageChoiceTokenId); + getPollenSession().clearDynamicData(); - addActionMessage(_("poll.info.poll.created")); + addActionMessage(_("pollen.info.poll.created")); return SUCCESS; } - public String getPollVoteUrl() { - return getPollService().getPollVoteUrl(poll); + protected boolean validateVotingList(int votingListNumber, + VotingList votingList, + Set<String> groups, + Set<String> voters, + Set<String> emails) { + + boolean result = false; + Map<String, String> errors = Maps.newHashMap(); + + String votingListErrorPrefix = "poll.votingList_" + votingListNumber; + + if (isGroupPoll()) { + + // group poll + + // check there is at least one group + // check no doublon on group names + // check there is at least one voter on each group + // check no doublon on voter names + // check no doublon on voter emails + + { // validate votingList name + String votingListName = votingList.getName(); + + if (StringUtils.isEmpty(votingListName)) { + + errors.put(votingListErrorPrefix + ".name", + _("pollen.error.poll.required.votingList.name")); + } else { + + // check no votingList name doublon + boolean add = groups.add(votingListName); + if (!add) { + + // name doublon + errors.put( + votingListErrorPrefix + ".name", + _("pollen.error.poll.votingList.name.doublon")); + } + + } + } + + { // validate votingList weight + + if (votingList.getWeight() == 0) { + + // no weight filled (can be a bad conversion) + errors.put( + votingListErrorPrefix + ".weight", + _("pollen.error.poll.votingList.weight.not.valid")); + } + } + } + + // check there is at least one voter + + String persontoListToken = DisplayPersonToList.getPersonToListTokenId( + votingListTokenId, votingListNumber); + + Map<Integer, PersonToList> personToLists = + getPollenSession().getDynamicData(persontoListToken); + + if (MapUtils.isEmpty(personToLists)) { + + // no personToList found for unique votingList 0 + errors.put(votingListErrorPrefix, + _("pollen.error.poll.required.one.personToList")); + } else { + + // check no doublon on voter names + // check no doublon on voter emails + + for (Map.Entry<Integer, PersonToList> entry : + personToLists.entrySet()) { + + result |= validatePersonList(entry.getKey(), entry.getValue(), + voters, emails); + } + } + + if (MapUtils.isNotEmpty(errors)) { + + // keep errors to display them in correct action + String errorToken = DisplayVotingList.getVotingListErrorTokenId( + votingListTokenId, 0); + if (log.isInfoEnabled()) { + log.info("Add " + errors.size() + " errors to " + errorToken); + } + getPollenSession().putDynamicData(errorToken, errors); + result = true; + } + return result; } - public String getPollEditUrl() { - return getPollService().getPollEditUrl(poll); + protected boolean validatePersonList(int personToListNumber, + PersonToList personToList, + Set<String> voters, + Set<String> emails) { + + boolean result = false; + Map<String, String> errors = Maps.newHashMap(); + String fieldNamePrefix = + "personToList_0_" + personToListNumber; + PollAccount pollAccount = personToList.getPollAccount(); + + { // validate votingId + + String votingId = pollAccount.getVotingId(); + // check voter is not doublon + boolean add = voters.add(votingId); + if (!add) { + + // voter doublon + errors.put( + fieldNamePrefix + ".votingId", + _("pollen.error.poll.personToList.votingId.doublon")); + } + } + { // validate email + String email = pollAccount.getEmail(); + + if (StringUtils.isEmpty(email)) { + errors.put( + fieldNamePrefix + ".email", + _("pollen.error.poll.personToList.email.required")); + } else { + + + boolean validEmail = StringUtil.isEmail(email); + if (!validEmail) { + + // not a valid email + errors.put( + fieldNamePrefix + ".email", + _("pollen.error.poll.personToList.email.not.valid")); + } else { + + // check email not doublon + boolean add = emails.add(email); + if (!add) { + + // email doublon + errors.put( + fieldNamePrefix + ".email", + _("pollen.error.poll.personToList.email.doublon")); + } + } + } + } + { // validate weight + if (personToList.getWeight() == 0) { + + // no weight filled (can be a bad conversion) + errors.put( + fieldNamePrefix + ".weight", + _("pollen.error.poll.personToList.weight.not.valid")); + } + } + + if (MapUtils.isNotEmpty(errors)) { + String errorToken = + DisplayPersonToList.getPersonToListErrorTokenId( + votingListTokenId, 0, personToListNumber); + if (log.isInfoEnabled()) { + log.info("Add " + errors.size() + " errors to " + errorToken); + } + getPollenSession().putDynamicData(errorToken, errors); + result = true; + } + return result; } @Override @@ -392,27 +664,28 @@ } protected Map<Integer, Choice> getOrderedChoices() { - - Map<Integer, Choice> orderedChoices = null; + Map<Integer, Choice> result = null; switch (poll.getChoiceType()) { - case TEXT: - orderedChoices = getPollenSession().getDynamicData( - textChoiceTokenId); - + result = getPollenSession().getDynamicData(textChoiceTokenId); break; case DATE: - orderedChoices = getPollenSession().getDynamicData( - dateChoiceTokenId); + result = getPollenSession().getDynamicData(dateChoiceTokenId); break; case IMAGE: - orderedChoices = getPollenSession().getDynamicData( - imageChoiceTokenId); + result = getPollenSession().getDynamicData(imageChoiceTokenId); break; } - return orderedChoices; + return result; } + protected Map<Integer, VotingList> getOrderedVotingLists() { + + Map<Integer, VotingList> result = getPollenSession().getDynamicData( + votingListTokenId); + return result; + } + protected Map<Integer, Choice> buildTextChoices(int nbDefault) { Map<Integer, Choice> result = Maps.newTreeMap(); @@ -441,7 +714,7 @@ } } } - result = reindexChoices(result, maxNumber); + result = reindexMap(result, maxNumber); int size = result.size(); nbTextChoices = Math.max(nbDefault, size); @@ -478,7 +751,7 @@ } } } - result = reindexChoices(result, maxNumber); + result = reindexMap(result, maxNumber); int size = result.size(); nbDateChoices = Math.max(nbDefault, size); @@ -495,8 +768,11 @@ for (String fileName : getImageChoiceFileName()) { if (fileName != null) { - parameters.put("imageChoice_" + index + ".name", new String[]{fileName}); - parameters.put("imageChoice_" + index + ".location", new String[]{getImageChoice().get(index).getAbsolutePath()}); + parameters.put("imageChoice_" + index + ".name", + new String[]{fileName}); + parameters.put( + "imageChoice_" + index + ".location", + new String[]{getImageChoice().get(index).getAbsolutePath()}); } index++; } @@ -527,7 +803,7 @@ } } } - result = reindexChoices(result, maxNumber); + result = reindexMap(result, maxNumber); int size = result.size(); nbImageChoices = Math.max(nbDefault, size); log.info("nbImageChoices (from request) = " + size); @@ -535,18 +811,186 @@ return result; } - private void logChoice(Map<Integer, Choice> result) { - for (Map.Entry<Integer, Choice> e : result.entrySet()) { - Integer choiceId = e.getKey(); - Choice choice = e.getValue(); - if (log.isInfoEnabled()) { - log.info("Choice [" + choiceId + "] = " + - choice.getName() + " -- " + - choice.getDescription()); + protected Map<Integer, VotingList> buildVotingLists(int nbDefault) { + Map<Integer, VotingList> result = Maps.newTreeMap(); + + int maxNumber = 0; + + // get all votingList_ parameters + Set<String> votingListParameterNames = Sets.filter( + parameters.keySet(), + new StringStartWithPredicate("votingList_")); + + for (String paramName : votingListParameterNames) { + + Matcher matcher = VOTING_LIST_NAME_PATTERN.matcher(paramName); + + if (matcher.matches()) { + + // found a voting list name + + int votingListNumber = buildVotingList(paramName, + matcher, + result + ); + maxNumber = Math.max(maxNumber, votingListNumber); } } + + result = reindexMap(result, maxNumber); + + int size = result.size(); + nbVotingLists = Math.max(nbDefault, size); + log.info("nbVotingList (from request) = " + size); + + // add personToList maps to session (but just now, since votingList + // could have been reindex) + for (Map.Entry<Integer, VotingList> entry : result.entrySet()) { + Integer votingListNumber = entry.getKey(); + VotingList votingList = entry.getValue(); + + if (!votingList.isPollAccountPersonToListEmpty()) { + List<PersonToList> personToList = + votingList.getPollAccountPersonToList(); + + Map<Integer, PersonToList> personToListMap = Maps.newTreeMap(); + int index = 0; + for (PersonToList toList : personToList) { + personToListMap.put(index++, toList); + } + + String token = DisplayPersonToList.getPersonToListTokenId( + votingListTokenId, votingListNumber); + if (log.isInfoEnabled()) { + log.info("Add " + token + " with " + + personToListMap.size() + " personToList"); + } + getPollenSession().putDynamicData(token, personToListMap); + } + } + + return result; } + private double getDoubleValue(String parameterName) { + String parameterValue = getNonEmptyParameterValue(parameterName); + double result = 0; + if (StringUtils.isNotEmpty(parameterValue)) { + + try { + result = Double.valueOf(parameterValue); + } catch (NumberFormatException e) { + //bad conversion, will be treated later + if (log.isDebugEnabled()) { + log.debug("Bad double conversion from param [" + + parameterName + "] : " + parameterValue); + } + } + } + return result; + } + + private int buildVotingList(String votingListParameterName, + Matcher votingListMatcher, + Map<Integer, VotingList> result) { + + String paramValue = getNonEmptyParameterValue(votingListParameterName); + int votingListNumber = Integer.valueOf(votingListMatcher.group(1)); + + VotingList votingList = new VotingListImpl(); + + votingList.setName(paramValue); + + String prefix = "votingList_" + votingListNumber; + + double weight = getDoubleValue(prefix + ".weight"); + votingList.setWeight(weight); + + String topiaId = getNonEmptyParameterValue(prefix + ".topiaId"); + votingList.setTopiaId(topiaId); + + result.put(votingListNumber, votingList); + + String personToListPrefix = "personToList_" + votingListNumber + "_"; + + // get all personToList parameters + Set<String> votingListParameterNames = Sets.filter( + parameters.keySet(), new StringStartWithPredicate(personToListPrefix)); + + Pattern personToListNamePattern = Pattern.compile( + personToListPrefix + "(\\d+)\\.votingId"); + + Map<Integer, PersonToList> personToLists = Maps.newTreeMap(); + + int maxPersonToListNumber = 0; + + // let's build personToList list + for (String personToListNameParameter : votingListParameterNames) { + + Matcher matcher = personToListNamePattern.matcher( + personToListNameParameter); + + if (matcher.matches()) { + + int personToListNumber = buildPersonToList( + personToListPrefix, + personToListNameParameter, + matcher, + votingListNumber, + personToLists); + + maxPersonToListNumber = Math.max(maxPersonToListNumber, personToListNumber); + } + } + + personToLists = reindexMap(personToLists, maxPersonToListNumber); + + for (PersonToList personToList : personToLists.values()) { + votingList.addPollAccountPersonToList(personToList); + } + + return votingListNumber; + } + + private int buildPersonToList(String personToListPrefix, + String paramName, + Matcher personToListMatcher, + int votingListNumber, + Map<Integer, PersonToList> result) { + + String paramValue = getNonEmptyParameterValue(paramName); + + int personToListNumber = 0; + + if (paramValue != null) { + + // found a PersonToList none empty name, keep it + + personToListNumber = Integer.valueOf(personToListMatcher.group(1)); + + PersonToList personToList = new PersonToListImpl(); + + PollAccount account = new PollAccountImpl(); + personToList.setPollAccount(account); + + account.setVotingId(paramValue); + + String prefix = personToListPrefix + personToListNumber; + + double weight = getDoubleValue(prefix + ".weight"); + personToList.setWeight(weight); + + String topiaId = getNonEmptyParameterValue(prefix + ".topiaId"); + personToList.setTopiaId(topiaId); + + String email = getNonEmptyParameterValue(prefix + ".email"); + account.setEmail(email); + + result.put(personToListNumber, personToList); + } + return personToListNumber; + } + private Choice createImageChoice(PollImageChoice choice, String prefix, String name) { @@ -581,11 +1025,22 @@ return choice; } + private void logChoice(Map<Integer, Choice> result) { + for (Map.Entry<Integer, Choice> e : result.entrySet()) { + Integer choiceId = e.getKey(); + Choice choice = e.getValue(); + if (log.isInfoEnabled()) { + log.info("Choice [" + choiceId + "] = " + + choice.getName() + " -- " + + choice.getDescription()); + } + } + } - private Map<Integer, Choice> reindexChoices(Map<Integer, Choice> result, - int maxNumber) { - Map<Integer, Choice> result2; + private <T> Map<Integer, T> reindexMap(Map<Integer, T> result, int maxNumber) { + Map<Integer, T> result2; + if (maxNumber != result.size() - 1) { // means there is a hole inside the result (a empty choice was @@ -599,7 +1054,7 @@ result2 = Maps.newTreeMap(); int i = 0; for (Integer number : numbers) { - Choice choice = result.get(number); + T choice = result.get(number); result2.put(i++, choice); } } else { @@ -636,4 +1091,17 @@ } return result; } + + private static class StringStartWithPredicate implements Predicate<String> { + private final String prefix; + + public StringStartWithPredicate(String prefix) { + this.prefix = prefix; + } + + @Override + public boolean apply(String input) { + return input.startsWith(prefix); + } + } } Added: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayPersonToList.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayPersonToList.java (rev 0) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayPersonToList.java 2012-03-13 14:06:19 UTC (rev 3178) @@ -0,0 +1,158 @@ +/* + * #%L + * Pollen :: UI (strust2) + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.ui.actions.poll; + +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.chorem.pollen.business.persistence.PersonToList; +import org.chorem.pollen.business.persistence.PersonToListImpl; +import org.chorem.pollen.business.persistence.PollAccountImpl; +import org.chorem.pollen.ui.actions.PollenActionSupport; + +import java.util.Map; + +/** + * To display a personToList (use at a poll creation). + * + * @author tchemit <chemit@codelutin.com> + * @since 1.2.6 + */ +public class DisplayPersonToList extends PollenActionSupport { + + private static final long serialVersionUID = 1L; + + public static final String TOKEN = "personToList"; + + /** Logger. */ + private static final Log log = LogFactory.getLog(DisplayPersonToList.class); + + public static String getPersonToListTokenId(String votingListTokenId, + int votingListNumber) { + return votingListTokenId + "_" + votingListNumber + TOKEN; + } + + public static String getPersonToListErrorTokenId(String votingListTokenId, + int votingListNumber, + int personToListNumber) { + return getPersonToListErrorTokenId(getPersonToListTokenId(votingListTokenId, votingListNumber), personToListNumber); + } + + public static String getPersonToListErrorTokenId(String personToListTokenId, + int personToListNumber) { + return personToListTokenId + "_error_" + personToListNumber; + } + + /** Where to find dynamic data (says choices in this case). */ + protected String tokenId; + + /** Number of the vontingList container. */ + protected int votingListNumber; + + /** Number of person to display. */ + protected int personToListNumber; + + protected PersonToList personToList; + + public String getTokenId() { + return tokenId; + } + + public void setTokenId(String tokenId) { + this.tokenId = tokenId; + } + + public int getVotingListNumber() { + return votingListNumber; + } + + public void setVotingListNumber(int votingListNumber) { + this.votingListNumber = votingListNumber; + } + + public int getPersonToListNumber() { + return personToListNumber; + } + + public void setPersonToListNumber(int personToListNumber) { + this.personToListNumber = personToListNumber; + } + + public PersonToList getPersonToList() { + return personToList; + } + + @Override + public String execute() throws Exception { + if (StringUtils.isNotEmpty(tokenId)) { + + Map<Integer, PersonToList> personToLists = + getPollenSession().getDynamicData(tokenId); + + if (personToLists != null) { + + // get choices from datas + personToList = personToLists.get(personToListNumber); + + if (personToList != null) { + + // remove this choice from session + personToLists.remove(personToListNumber); + } + } + + if (MapUtils.isEmpty(personToLists)) { + + // remove it from session + getPollenSession().removeDynamicData(tokenId); + } + } + + if (personToList == null) { + personToList = new PersonToListImpl(); + personToList.setWeight(1); + PollAccountImpl pollAccount = new PollAccountImpl(); + personToList.setPollAccount(pollAccount); + } + + // consume personToList errors + String token = getPersonToListErrorTokenId(tokenId, personToListNumber); + Map<String, String> errors = getPollenSession().getDynamicData(token); + if (MapUtils.isNotEmpty(errors)) { + // transmit them as field errors + for (Map.Entry<String, String> e : errors.entrySet()) { + String fieldName = e.getKey(); + String errorMessage = e.getValue(); + if (log.isInfoEnabled()) { + log.info("Transmit error on " + fieldName + " [" + errorMessage + "]"); + } + addFieldError(fieldName, errorMessage); + } + } + getPollenSession().removeDynamicData(token); + return SUCCESS; + } + +} Property changes on: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayPersonToList.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayVotingList.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayVotingList.java (rev 0) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayVotingList.java 2012-03-13 14:06:19 UTC (rev 3178) @@ -0,0 +1,150 @@ +/* + * #%L + * Pollen :: UI (strust2) + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.ui.actions.poll; + +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.chorem.pollen.business.persistence.VotingList; +import org.chorem.pollen.business.persistence.VotingListImpl; +import org.chorem.pollen.ui.actions.PollenActionSupport; + +import java.util.Map; + +/** + * To display a voting list of a poll (use at a poll creation). + * + * @author tchemit <chemit@codelutin.com> + * @since 1.2.6 + */ +public class DisplayVotingList extends PollenActionSupport { + + private static final long serialVersionUID = 1L; + + public static final String VOTING_LIST_TOKEN = "votingList"; + + /** Logger. */ + private static final Log log = LogFactory.getLog(DisplayVotingList.class); + + public static String getVotingListErrorTokenId(String votingListTokenId, + int votingListNumber) { + return votingListTokenId + "_" + votingListNumber + "_errors"; + } + + /** Where to find dynamic data (says choices in this case). */ + protected String tokenId; + + /** Number of person to display. */ + protected int votingListNumber; + + /** Count of personToList for this votingList. */ + protected int nbPersonToLists; + + /** The voting list ot display. */ + protected VotingList votingList; + + public String getPersonToListTokenId() { + return DisplayPersonToList.getPersonToListTokenId(tokenId, votingListNumber); + } + + public int getNbPersonToLists() { + return nbPersonToLists; + } + + public String getTokenId() { + return tokenId; + } + + public void setTokenId(String tokenId) { + this.tokenId = tokenId; + } + + public int getVotingListNumber() { + return votingListNumber; + } + + public void setVotingListNumber(int votingListNumber) { + this.votingListNumber = votingListNumber; + } + + public VotingList getVotingList() { + return votingList; + } + + @Override + public String execute() throws Exception { + if (StringUtils.isNotEmpty(tokenId)) { + + Map<Integer, VotingList> votingLists = + getPollenSession().getDynamicData(tokenId); + + if (votingLists != null) { + + // get choices from datas + votingList = votingLists.get(votingListNumber); + + if (votingList != null) { + + // remove this choice from session + votingLists.remove(votingListNumber); + } + } + + if (MapUtils.isEmpty(votingLists)) { + + // remove it from session + getPollenSession().removeDynamicData(tokenId); + } + } + + if (votingList == null) { + votingList = new VotingListImpl(); + votingList.setWeight(1); + + //TODO tchemit use a default value from configuration + nbPersonToLists = 5; + } else { + nbPersonToLists = votingList.sizePollAccountPersonToList(); + } + nbPersonToLists = Math.max(5, nbPersonToLists); + + // consume votingList errors + String token = getVotingListErrorTokenId(tokenId, votingListNumber); + Map<String, String> errors = getPollenSession().getDynamicData(token); + if (MapUtils.isNotEmpty(errors)) { + // transmit them as field errors + for (Map.Entry<String, String> e : errors.entrySet()) { + String fieldName = e.getKey(); + String errorMessage = e.getValue(); + if (log.isInfoEnabled()) { + log.info("Transmit error on " + fieldName+" ["+errorMessage+"]"); + } + addFieldError(fieldName, errorMessage); + } + } + getPollenSession().removeDynamicData(token); + return SUCCESS; + } +} Property changes on: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayVotingList.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/config/struts-poll.xml =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/config/struts-poll.xml 2012-03-13 14:01:33 UTC (rev 3177) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/config/struts-poll.xml 2012-03-13 14:06:19 UTC (rev 3178) @@ -65,6 +65,18 @@ <result>/WEB-INF/jsp/poll/imageChoice.jsp</result> </action> + <!-- display a votingList --> + <action name="displayVotingList" + class="org.chorem.pollen.ui.actions.poll.DisplayVotingList"> + <result>/WEB-INF/jsp/poll/votingList.jsp</result> + </action> + + <!-- display a personToList --> + <action name="displayPersonToList" + class="org.chorem.pollen.ui.actions.poll.DisplayPersonToList"> + <result>/WEB-INF/jsp/poll/personToList.jsp</result> + </action> + <!-- edit poll --> <action name="modification/*" class="org.chorem.pollen.ui.actions.poll.EditPoll"> Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_en_GB.properties =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_en_GB.properties 2012-03-13 14:01:33 UTC (rev 3177) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_en_GB.properties 2012-03-13 14:06:19 UTC (rev 3178) @@ -1,19 +1,7 @@ -poll.common.aboutPoll=About the poll -poll.common.comments=Comments about this poll -poll.common.myPolls=My polls -poll.common.select.choiceType=Select the type of choice -poll.common.select.userFavoriteList=List -poll.common.vote.results=Results -poll.common.vote.results-help=Display results -poll.common.vote.return=Back to poll -poll.common.vote.return-help=Back to poll -poll.error.poll.detected.duplicate.choice.name=Choices must be unique. -poll.error.poll.required.one.choice=You must provide at least one choice. -poll.error.poll.required.title=You must provide a title for the poll -poll.info.poll.created=Poll created -poll.info.poll.updated=Poll modified pollen.action.addChoice=Add choice pollen.action.addComment=Add a comment +pollen.action.addPersonToList=Add a voter +pollen.action.addVotingList=Add a group pollen.action.backToFavoriteLists=Back to favorite lists pollen.action.create=Create pollen.action.createFavoriteList=Create a new list @@ -41,10 +29,14 @@ pollen.action.pollDelete=Delete the poll pollen.action.pollEdit=Edit poll pollen.action.pollExport=Export poll +pollen.action.pollPersonToListDelete=Delete this voter pollen.action.pollResult=Display poll results pollen.action.pollVote=Vote +pollen.action.pollVotingListDelete=Supprimer le groupe de votants +pollen.action.pollVotingListEdit=Editer ce groupe de votants pollen.action.register=Register pollen.action.validate=Submit +pollen.common.aboutPoll=About the poll pollen.common.addingChoices=Adding choices pollen.common.administrator=Admin pollen.common.beginChoiceDate=Begin choice date @@ -57,6 +49,7 @@ pollen.common.choice=Choice pollen.common.commentName=Name pollen.common.commentText=Comment +pollen.common.comments=Comments about this poll pollen.common.csvImport=CSV import pollen.common.description=Description pollen.common.displayType-group=Results by groups @@ -72,6 +65,7 @@ pollen.common.ldapImport=LDAP import pollen.common.license=Licence pollen.common.login=Login +pollen.common.myPolls=My polls pollen.common.name=Name pollen.common.nbAccounts=Number of members pollen.common.newPassword=New password @@ -80,6 +74,7 @@ pollen.common.or=or pollen.common.password=Password pollen.common.password2=Renter your password +pollen.common.personToList=Voter pollen.common.pollCreator=Creator pollen.common.pollOption.anonymous=Anonymous pollen.common.pollOption.anonymousVoteAllowed=Anonymous vote allowed @@ -95,10 +90,16 @@ pollen.common.pollType=Who can vote ? pollen.common.postDate=Comment date pollen.common.results=Results\: +pollen.common.select.choiceType=Select the type of choice +pollen.common.select.userFavoriteList=List pollen.common.title=Title pollen.common.userSupport=User support pollen.common.victories=Winners\: pollen.common.victory=Winner\: +pollen.common.vote.results=Results +pollen.common.vote.results-help=Display results +pollen.common.vote.return=Back to poll +pollen.common.vote.return-help=Back to poll pollen.common.voteAction=Vote pollen.common.voteCounting-label=Vote Counting\: pollen.common.voteCountingType=Response type @@ -107,7 +108,10 @@ pollen.common.voteCountingTypeHelp.number=Voting by number\: The answer is free, leave blank or enter a integer. pollen.common.voteCountingTypeHelp.percentage=Percentage vote\: allocate choices to get a 100%% total. pollen.common.voteNbVotes=%d existing votes +pollen.common.votePerson=Voter pollen.common.voterName=Votant +pollen.common.votingList=Group +pollen.common.weight=Weight pollen.error.accountNotFound= pollen.error.comment.name.empty=Comment name mandatory pollen.error.comment.text.empty=Comment text mandatory @@ -123,12 +127,25 @@ pollen.error.password.required=Your must provide a password pollen.error.password2.required=You must repeat your password for confirmation pollen.error.passwords.not.equals=Les deux mots de passe saisis non identiques +pollen.error.poll.detected.duplicate.choice.name=Choices must be unique. pollen.error.poll.notfound=No such poll exists. Please make sure that you are using the correct link and copy it completely into your browser's address field. +pollen.error.poll.personToList.email.doublon= +pollen.error.poll.personToList.email.not.valid= +pollen.error.poll.personToList.email.required= +pollen.error.poll.personToList.votingId.doublon= +pollen.error.poll.personToList.weight.not.valid= +pollen.error.poll.required.one.choice=You must provide at least one choice. +pollen.error.poll.required.one.personToList= +pollen.error.poll.required.title=You must provide a title for the poll +pollen.error.poll.required.votingList.name= +pollen.error.poll.votingList.name.doublon= +pollen.error.poll.votingList.weight.not.valid= pollen.error.pollAccount.email.required=Em@il mandatory pollen.error.pollAccount.not.found=Poll account not found pollen.error.pollAccount.votingId.required=Name mandatory pollen.error.pollNotClosed=The poll is not closed. Results may change. pollen.error.pollNotFound=The poll you want to count does not exist. +pollen.error.pollTabErrorFound=Some errors were found on this tab, please fix them to finalize the poll creation. pollen.error.user.alreadyVoted=Someone has already used the name %s to vote. pollen.error.user.bad.login.or.password=Login or password invalid. pollen.error.user.email.already.used=This email is already used @@ -152,6 +169,8 @@ pollen.fieldset.userInformation.toCreate=User informations to create pollen.fieldset.userInformation.toDelete=User informations to delete pollen.fieldset.userInformation.toUpdate=User informations to update +pollen.info.poll.created=Poll created +pollen.info.poll.updated=Poll modified pollen.information.confirmDeleteChoice=Confirm delete of choice %s pollen.information.confirmDeleteVote=Confirm delete of vote for %s pollen.information.favoriteList.created=Favorite list %s created. Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_fr_FR.properties =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_fr_FR.properties 2012-03-13 14:01:33 UTC (rev 3177) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_fr_FR.properties 2012-03-13 14:06:19 UTC (rev 3178) @@ -1,19 +1,7 @@ -poll.common.aboutPoll=A propos du sondage -poll.common.comments=Commentaire à propos du sondage -poll.common.myPolls=Mes sondages -poll.common.select.choiceType=Sélectionner le type de choix -poll.common.select.userFavoriteList=Liste -poll.common.vote.results=Résultats -poll.common.vote.results-help=Voir les résultats -poll.common.vote.return=Retour au sondage -poll.common.vote.return-help=Retour au sondage -poll.error.poll.detected.duplicate.choice.name=Les choix doivent être uniques. -poll.error.poll.required.one.choice=Vous devez saisir au moins un choix. -poll.error.poll.required.title=Vous devez fournir un titre pour le sondage -poll.info.poll.created=Sondage créé -poll.info.poll.updated=Sondage mise à jour pollen.action.addChoice=Ajouter un choix pollen.action.addComment=Ajouter un commentaire +pollen.action.addPersonToList=Ajouter un votant +pollen.action.addVotingList=Ajouter un groupe pollen.action.backToFavoriteLists=Retour à la liste des favoris pollen.action.create=Créer pollen.action.createFavoriteList=Créer une ouvelle liste @@ -41,10 +29,14 @@ pollen.action.pollDelete=Supprimer le sondage pollen.action.pollEdit=Editer le sondage pollen.action.pollExport=Exporter le sondage +pollen.action.pollPersonToListDelete=Supprimer ce votant pollen.action.pollResult=Afficher les résultats du sondage pollen.action.pollVote=Voter +pollen.action.pollVotingListDelete=Supprimer le groupe de votants +pollen.action.pollVotingListEdit=Editer ce groupe de votants pollen.action.register=S'enregistrer pollen.action.validate=Valider +pollen.common.aboutPoll=A propos du sondage pollen.common.addingChoices=Ajout des choix pollen.common.administrator=Admin pollen.common.beginChoiceDate=Date de début des choix @@ -57,6 +49,7 @@ pollen.common.choice=Choix pollen.common.commentName=Nom pollen.common.commentText=Commentaire +pollen.common.comments=Commentaire à propos du sondage pollen.common.csvImport=Import CSV pollen.common.description=Description pollen.common.displayType-group=Résultats par groupes @@ -72,6 +65,7 @@ pollen.common.ldapImport=Import LDAP pollen.common.license=Licence pollen.common.login=Identifiant +pollen.common.myPolls=Mes sondages pollen.common.name=Nom pollen.common.nbAccounts=Nombre de membres pollen.common.nbVotes=%d votes ont été enregistrés @@ -81,6 +75,7 @@ pollen.common.or=ou pollen.common.password=Mot de passe pollen.common.password2=Répétez votre mot de passe +pollen.common.personToList=Votant pollen.common.pollCreator=Créateur pollen.common.pollOption.anonymous=Sondage anonyme pollen.common.pollOption.anonymousVoteAllowed=Autoriser le vote anonyme @@ -96,10 +91,16 @@ pollen.common.pollType=Qui peut voter ? pollen.common.postDate=Date du commentaire pollen.common.results=Résultats \: +pollen.common.select.choiceType=Sélectionner le type de choix +pollen.common.select.userFavoriteList=Liste pollen.common.title=Titre pollen.common.userSupport=Support utilisateur pollen.common.victories=Gagnants \: pollen.common.victory=Gagnant \: +pollen.common.vote.results=Résultats +pollen.common.vote.results-help=Voir les résultats +pollen.common.vote.return=Retour au sondage +pollen.common.vote.return-help=Retour au sondage pollen.common.voteAction=Vote pollen.common.voteCountingType=Type de Réponse pollen.common.voteCountingTypeHelp.condorcet=Vote Condorcet \: classer les choix par ordre de préférence de 1 à N (1\=préféré). Seul l'ordre des choix compte, peu importe les valeurs. Deux choix peuvent avoir la même valeur. @@ -107,7 +108,10 @@ pollen.common.voteCountingTypeHelp.number=Vote par nombre \: La réponse est libre, laissez vide ou entrez un nombre entier pollen.common.voteCountingTypeHelp.percentage=Vote par pourcentage \: répartir les choix de manière à obtenir 100%% au total. pollen.common.voteNbVotes=%d votes existants +pollen.common.votePerson=Votant pollen.common.voterName=Votant +pollen.common.votingList=Groupe +pollen.common.weight=Poids pollen.common.x=Dépouillement pollen.error.accountNotFound= pollen.error.comment.name.empty=Nom du commentaire obligatoire @@ -124,12 +128,25 @@ pollen.error.password.required=Mot de passe obligatoire pollen.error.password2.required=Mot de passe répété obligatoire pollen.error.passwords.not.equals=Les deux mots de passe saisis non identiques +pollen.error.poll.detected.duplicate.choice.name=Les choix doivent être uniques. pollen.error.poll.notfound=Il n'y a pas de sondage à cette adresse. Veuillez verifier que vous utilisez le lien correcte et copiez-le complètement dans le champ d'adresse de votre navigateur. +pollen.error.poll.personToList.email.doublon=Les emails doivent être uniques. +pollen.error.poll.personToList.email.not.valid=Email non valide +pollen.error.poll.personToList.email.required=Email obligatoire +pollen.error.poll.personToList.votingId.doublon=Les noms des votants doivent être uniques. +pollen.error.poll.personToList.weight.not.valid=Poids du votant non valide (doit être une nombre supérieur à 0). +pollen.error.poll.required.one.choice=Vous devez saisir au moins un choix. +pollen.error.poll.required.one.personToList=Aucun votant renseigné +pollen.error.poll.required.title=Vous devez fournir un titre pour le sondage +pollen.error.poll.required.votingList.name=nom du groupe non renseigné +pollen.error.poll.votingList.name.doublon=Les noms de groupes doivent être uniques. +pollen.error.poll.votingList.weight.not.valid=Poids du groupe votant non valide (doit être une nombre supérieur à 0). pollen.error.pollAccount.email.required=Em@il obliqatoire pollen.error.pollAccount.not.found=Membre non trouvé pollen.error.pollAccount.votingId.required=Nom obliqatoire pollen.error.pollNotClosed=Ce sondage n'est pas clos. Les résultats peuvent encore changer. pollen.error.pollNotFound=Le sondage que vous voulez dépouiller n'existe pas. +pollen.error.pollTabErrorFound=Des erreurs ont été detectées dans cet onglet, veuillez les corriger pour valider la création du sondage. pollen.error.user.alreadyVoted=Une personne a déjà voté sous le nom %s. pollen.error.user.bad.login.or.password=Mauvais identifiant ou mot de passe. pollen.error.user.email.already.used=Le courriel saisi est déjà utilisé par un autre utilisateur @@ -153,6 +170,8 @@ pollen.fieldset.userInformation.toCreate=Informations de l'utilisateur à créer pollen.fieldset.userInformation.toDelete=Informations de l'utilisateur à supprimer pollen.fieldset.userInformation.toUpdate=Informations de l'utilisateur à mettre à jour +pollen.info.poll.created=Sondage créé +pollen.info.poll.updated=Sondage mise à jour pollen.information.confirmDeletePollChoice=Confirmer la suppression du chois %s pollen.information.confirmDeletePollVote=Confirmer la suppression du vote de %s pollen.information.favoriteList.created=La liste %s a été créée. Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/create.jsp =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/create.jsp 2012-03-13 14:01:33 UTC (rev 3177) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/create.jsp 2012-03-13 14:06:19 UTC (rev 3178) @@ -28,7 +28,10 @@ href="<s:url value='/css/pollCreation.css'/>"/> <%@include file="/WEB-INF/jsp/choiceHelper.jsp" %> +<%@include file="/WEB-INF/jsp/votingListHelper.jsp" %> +<s:url id='errorImg' value='/img/exclamation.png'/> + <script type="text/javascript"> jQuery(document).ready(function () { @@ -77,10 +80,55 @@ $('[name="poll.choiceType"][value="' + type + '"]').attr('checked', 'checked'); } + function changePollType(type, loading) { + + if (!loading) { + + // remove extra votingLists + var containerId = "votingLists"; + var lastVotingList = getLastVotingList(containerId); + while (lastVotingList > -1) { + deleteVotingList(containerId + "_" + lastVotingList); + lastVotingList -= 1; + } + } + + if (type == 'FREE') { + + // hide everything + $('.restrictedPoll').addClass("hidden"); + $('.groupPoll').addClass("hidden"); + + } else if (type == 'RESTRICTED') { + + if (!loading) { + addNewVotingList(containerId); + } + + // show restricted sutff + $('.restrictedPoll').removeClass("hidden"); + // remove all group stuff + $('.groupPoll').addClass("hidden"); + + } else if (type == 'GROUP') { + + if (!loading) { + addNewVotingList(containerId); + } + + $('.restrictedPoll').removeClass("hidden"); + $('.groupPoll').removeClass("hidden"); + } + } + $('[name="poll.choiceType"]').change(function (event) { changeChoiceType($(this).val()); }); - $('[name="poll.pollType"][value="<s:property value="%{poll.pollType.name()}"/>"]').attr('checked', 'checked'); + + $('[name="poll.pollType"]').change(function (event) { + changePollType($(this).val(), false); + }); + $('[name="poll.voteCountingType"][value="<s:property value="%{poll.voteCountingType.name()}"/>"]').attr('checked', 'checked'); changeChoiceType('<s:property value="%{poll.choiceType.name()}"/>'); @@ -102,6 +150,13 @@ <s:iterator begin="1" end="nbImageChoices" status="status"> addImageChoice(<s:property value='%{#status.index}'/>, <s:property value="nbImageChoices - 1"/>, '<s:property value="imageChoiceTokenId" />'); </s:iterator> + + // votingLists loading + <s:iterator begin="1" end="nbVotingLists" status="status"> + addVotingList(<s:property value='%{#status.index}'/>, <s:property value="nbVotingLists - 1"/>, '<s:property value="votingListTokenId" />'); + </s:iterator> + + changePollType('<s:property value="%{poll.pollType.name()}"/>', true); }); </script> <title><s:text name="pollen.title.createPoll"/></title> @@ -111,7 +166,7 @@ <s:form method="POST" id="registerForm" namespace="/poll" enctype="multipart/form-data"> - <sj:tabbedpanel id="formTabs"> + <sj:tabbedpanel id="formTabs" selectedTab="%{selectedTab}"> <sj:tab id="tabGeneral" target="tgeneral" key="pollen.tab.poll.general"/> <sj:tab id="tabOptions" target="toptions" key="pollen.tab.poll.options"/> @@ -134,24 +189,28 @@ <legend><s:text name="pollen.common.voteCountingType"/></legend> <s:radio key='poll.voteCountingType' list="voteCountingTypes" label='' theme="simple"/> - </fieldset> <br/> <fieldset> <legend><s:text name="pollen.fieldset.poll.choices"/></legend> - <s:radio key='poll.choiceType' list="choiceTypes" - label='' theme="simple"/> + <s:radio key='poll.choiceType' list="choiceTypes" label='' + theme="simple"/> <hr/> <s:fielderror fieldName="poll.choices"/> - <div id="choicesTEXT" class="choices"></div> - <div id="choicesDATE" class="choices"></div> - <div id="choicesIMAGE" class="choices"></div> + <div id="choicesTEXT" class="choices"> + <%--Where to load text choices --%> + </div> + <div id="choicesDATE" class="choices"> + <%--Where to load date choices --%> + </div> + <div id="choicesIMAGE" class="choices"> + <%--Where to load image choices --%> + </div> <hr/> <s:submit key="pollen.action.addChoice" align="center" onclick="return addNewChoice();"/> - </fieldset> </div> @@ -204,30 +263,62 @@ <s:textfield key="reminderHourCountdown" label="%{getText('pollen.common.pollOption.reminderHourCountdown')}"/> </div> - </fieldset> <br/> - <fieldset> <legend><s:text name="pollen.fieldset.poll.general"/></legend> - <sj:datepicker key="poll.beginDate" - label="%{getText('pollen.common.beginDate')}" - displayFormat="dd/mm/yy"/> - <sj:datepicker key="poll.endDate" - label="%{getText('pollen.common.endDate')}" - displayFormat="dd/mm/yy"/> + <sj:datepicker key="poll.beginDate" displayFormat="dd/mm/yy" + label="%{getText('pollen.common.beginDate')}"/> + <sj:datepicker key="poll.endDate" displayFormat="dd/mm/yy" + label="%{getText('pollen.common.endDate')}"/> + </fieldset> + + <br/> + <fieldset> + <legend><s:text name="pollen.common.pollType"/></legend> <s:radio key='poll.pollType' list="pollTypes" label='%{getText("pollen.common.pollType")}'/> - + <hr/> + <div class="restrictedPoll"> + <div id="votingLists"> + <%--Where to load voting lists --%> + </div> + <div class="groupPoll"> + <s:submit key="pollen.action.addVotingList" align="center" + onclick="return addNewVotingList();"/> + </div> + </div> </fieldset> - </div> </sj:tabbedpanel> - <br/> <s:submit action="create" key="pollen.action.createPoll" align="center"/> -</s:form> \ No newline at end of file +</s:form> + +<script type="text/javascript"> + + jQuery(document).ready(function () { + + function addErrorImage(element) { + element.append( + '<image src="${errorImg}">' + ); + element.attr('title', + '<s:text name="pollen.error.pollTabErrorFound"/>'); + } + + if (<s:property value="%{informationsError}"/>) { + var tab = $('#tabGeneral a'); + addErrorImage(tab); + } + if (<s:property value="%{optionsError}"/>) { + tab = $('#tabOptions a'); + addErrorImage(tab); + } + + }); +</script> \ No newline at end of file Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/dateChoice.jsp =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/dateChoice.jsp 2012-03-13 14:01:33 UTC (rev 3177) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/dateChoice.jsp 2012-03-13 14:06:19 UTC (rev 3178) @@ -46,7 +46,7 @@ key="%{#prefix}.description" label='' theme="simple" value="%{choice.description}"/> </div> - <span> + <div class="fright"> <s:a href='#' onclick="return deleteChoice('choicesDATE_%{choiceNumber}')"> <image alt='<s:property value="deleteTitle"/>' title='<s:property value="deleteTitle"/>' @@ -65,6 +65,6 @@ title='<s:property value="upTitle"/>' src="<s:url value='/img/1uparrow.png'/>"></image> </s:a--%> - </span> + </div> <div class="cleanBoth"></div> </div> \ No newline at end of file Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/imageChoice.jsp =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/imageChoice.jsp 2012-03-13 14:01:33 UTC (rev 3177) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/imageChoice.jsp 2012-03-13 14:06:19 UTC (rev 3178) @@ -55,11 +55,10 @@ theme="simple"/> </div> <div class="fleft"> - <s:textarea cols="30" id="%{#prefix}.description" - key="%{#prefix}.description" - label='' theme="simple" value="%{choice.description}"/> + <s:textarea cols="30" id="%{#prefix}.description" label='' theme="simple" + key="%{#prefix}.description" value="%{choice.description}"/> </div> - <span> + <div class="fright"> <s:a href='#' onclick="return deleteChoice('choicesIMAGE_%{choiceNumber}')"> <image alt='<s:property value="deleteTitle"/>' title='<s:property value="deleteTitle"/>' @@ -78,7 +77,7 @@ title='<s:property value="upTitle"/>' src="<s:url value='/img/1uparrow.png'/>"></image> </s:a--%> - </span> + </div> <div class="cleanBoth"></div> </div> \ No newline at end of file Added: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/personToList.jsp =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/personToList.jsp (rev 0) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/personToList.jsp 2012-03-13 14:06:19 UTC (rev 3178) @@ -0,0 +1,61 @@ +<%-- + #%L + Pollen :: UI (strust2) + + $Id$ + $HeadURL$ + %% + Copyright (C) 2009 - 2012 CodeLutin + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --%> +<%@ page language="java" contentType="text/html" pageEncoding="utf-8" %> +<%@ taglib prefix="s" uri="/struts-tags" %> + +<s:set name="prefix">personToList_<s:property + value="votingListNumber"/>_<s:property value="personToListNumber"/> +</s:set> +<s:set id='deleteTitle'> + <s:text name="pollen.action.pollPersonToListDelete"/> +</s:set> +<s:div id='%{#prefix}'> + <s:fielderror/> + <s:hidden key='%{#prefix}.topiaId' value='%{personToList.topiaId}' label=''/> + <div class="fleft choiceName"> + <s:label for="%{#prefix}.votingId" id="%{#prefix}_label" theme="simple" + value=''/> + <s:textfield cssClass="nameField" id='%{#prefix}.votingId' + key="%{#prefix}.votingId" label='' theme="simple" + value="%{personToList.pollAccount.votingId}"/> + - + <s:label for="%{#prefix}.email" key="pollen.common.email" theme="simple"/> + <s:textfield cols="30" id="%{#prefix}.email" key="%{#prefix}.email" + label='' theme="simple" + value="%{personToList.pollAccount.email}"/> + - + <s:label for="%{#prefix}.weight" key="pollen.common.weight" theme="simple"/> + <s:textfield id="%{#prefix}.weight" key="%{#prefix}.weight" size="1" + label='' theme="simple" value="%{personToList.weight}"/> + </div> + <div class="fright"> + <s:a href='#' onclick="return deletePersonToList('%{#prefix}')"> + <image alt='<s:property value="deleteTitle"/>' + title='<s:property value="deleteTitle"/>' + src="<s:url value='/img/delete.png'/>"></image> + </s:a> + </div> + + <div class="cleanBoth"></div> +</s:div> \ No newline at end of file Property changes on: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/personToList.jsp ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/result.jsp =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/result.jsp 2012-03-13 14:01:33 UTC (rev 3177) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/result.jsp 2012-03-13 14:06:19 UTC (rev 3178) @@ -69,12 +69,12 @@ <div id="resultTop"> <s:property value="poll.description"/> <fieldset> - <legend><s:text name="poll.common.aboutPoll"/></legend> + <legend><s:text name="pollen.common.aboutPoll"/></legend> <div style="float: right"> <s:a namespace="/poll" action="votefor/%{uriId}"> <img src="<s:url value='/img/vote.png'/>" - title="<s:text name="poll.common.vote.return-help"/>" - alt="<s:text name="poll.common.vote.return"/>"/> + title="<s:text name="pollen.common.vote.return-help"/>" + alt="<s:text name="pollen.common.vote.return"/>"/> </s:a> </div> <s:label value="%{poll.creator.votingId}" Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/resume.jsp =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/resume.jsp 2012-03-13 14:01:33 UTC (rev 3177) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/resume.jsp 2012-03-13 14:06:19 UTC (rev 3178) @@ -53,6 +53,6 @@ <div style="margin-top: 30px;"> <s:text name="pollen.label.pollRegisterPage"/> <s:a namespace="/user" action="myPolls"> - <s:text name="poll.common.myPolls"/> + <s:text name="pollen.common.myPolls"/> </s:a>. </div> \ No newline at end of file Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/textChoice.jsp =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/textChoice.jsp 2012-03-13 14:01:33 UTC (rev 3177) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/textChoice.jsp 2012-03-13 14:06:19 UTC (rev 3178) @@ -38,13 +38,12 @@ - <s:label for="%{#prefix}.description" key="pollen.common.description" theme="simple"/> + <%--/div> + <div class="fleft"--%> + <s:textarea cols="30" id="%{#prefix}.description" label='' theme="simple" + key="%{#prefix}.description" value="%{choice.description}"/> </div> - <div class="fleft"> - <s:textarea cols="30" id="%{#prefix}.description" - key="%{#prefix}.description" - label='' theme="simple" value="%{choice.description}"/> - </div> - <span> + <div class="fright"> <s:a href='#' onclick="return deleteChoice('choicesTEXT_%{choiceNumber}')"> <image alt='<s:property value="deleteTitle"/>' title='<s:property value="deleteTitle"/>' @@ -63,6 +62,6 @@ title='<s:property value="upTitle"/>' src="<s:url value='/img/1uparrow.png'/>"></image> </s:a--%> - </span> + </div> <div class="cleanBoth"></div> </div> \ No newline at end of file Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/vote.jsp =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/vote.jsp 2012-03-13 14:01:33 UTC (rev 3177) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/vote.jsp 2012-03-13 14:06:19 UTC (rev 3178) @@ -101,14 +101,14 @@ <s:property value="poll.description"/> </div> <fieldset> - <legend><s:text name="poll.common.aboutPoll"/></legend> + <legend><s:text name="pollen.common.aboutPoll"/></legend> <div style="float: right"> <s:if test="poll.publicResults"> <s:a namespace="/poll" action="results/%{uriId}"> <img src="<s:url value='/img/count.png'/>" - title="<s:text name="poll.common.vote.results-help"/>" - alt="<s:text name="poll.common.vote.results"/>"/> + title="<s:text name="pollen.common.vote.results-help"/>" + alt="<s:text name="pollen.common.vote.results"/>"/> </s:a> </s:if> <%--<t:FeedContextLink t:id="feedContext"/>--%> @@ -382,7 +382,7 @@ <tr> <td> <s:a namespace="/poll" action="results/%{poll.pollId}"> - <s:text name="poll.common.vote.results"/> + <s:text name="pollen.common.vote.results"/> </s:a> </td> @@ -416,7 +416,7 @@ </div> <!-- Ajout de commentaires --> -<h3><s:text name="poll.common.comments"/></h3> +<h3><s:text name="pollen.common.comments"/></h3> <div id="commentZone"> <div id="commentsDiv"> Added: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/votingList.jsp =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/votingList.jsp (rev 0) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/votingList.jsp 2012-03-13 14:06:19 UTC (rev 3178) @@ -0,0 +1,87 @@ +<%-- + #%L + Pollen :: UI (strust2) + + $Id$ + $HeadURL$ + %% + Copyright (C) 2009 - 2012 CodeLutin + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --%> +<%@ page language="java" contentType="text/html" pageEncoding="utf-8" %> +<%@ taglib prefix="s" uri="/struts-tags" %> + +<s:set name="prefix">votingList_<s:property value="votingListNumber"/></s:set> +<s:set id='deleteTitle'> + <s:text name="pollen.action.pollVotingListDelete"/> +</s:set> +<s:set id='editTitle'> + <s:text name="pollen.action.pollVotingListEdit"/> +</s:set> + +<script type="text/javascript"> + jQuery(document).ready(function () { + // personToList loading + <s:iterator begin="1" end="nbPersonToLists" status="status"> + addPersonToList(<s:property value="votingListNumber"/>, <s:property value='%{#status.index}'/>, <s:property value="nbPersonToLists - 1"/>, '<s:property value="personToListTokenId" />'); + </s:iterator> + }); +</script> +<s:div id='votingLists_%{votingListNumber}'> + <fieldset class="ui-widget-content ui-corner-all"> + + <s:fielderror/> + <div class="groupPoll"> + <div class="fleft choiceName"> + <s:label for="%{#prefix}.name" theme="simple" + id="votingLists_%{votingListNumber}_label"/> + <s:textfield id='%{#prefix}.name' key="%{#prefix}.name" label='' + theme="simple" value="%{votingList.name}"/> + - + <s:label for="%{#prefix}.weight" key="pollen.common.weight" + theme="simple"/> + <s:textfield id="%{#prefix}.weight" key="%{#prefix}.weight" value="%{votingList.weight}" + size="1" label='' theme="simple"/> + </div> + <div id='<s:property value="%{#prefix}"/>_actions' class="fright"> + <s:a href='#' onclick="return editVotingList('%{prefix}')"> + <image alt='<s:property value="editTitle"/>' + title='<s:property value="editTitle"/>' + src="<s:url value='/img/edit.png'/>"></image> + </s:a> + <s:a href='#' + onclick="return deleteVotingList('votingLists_%{votingListNumber}')"> + <image alt='<s:property value="deleteTitle"/>' + title='<s:property value="deleteTitle"/>' + src="<s:url value='/img/delete.png'/>"></image> + </s:a> + </div> + <hr/> + </div> + <div class="cleanBoth"></div> + <s:hidden key='%{#prefix}.topiaId' value='%{votingList.topiaId}' label=''/> + + <s:div id='personToList_%{votingListNumber}'> + <%--Where to load personToList--%> + </s:div> + <hr/> + <div class="cleanBoth"></div> + <s:submit id='%{#prefix}_addPersonToList' name='%{#prefix}_addPersonToList' + key="pollen.action.addPersonToList" align="center" + onclick='return addNewPersonToList("%{votingListNumber}");'/> + </fieldset> + <br/> +</s:div> Property changes on: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/votingList.jsp ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/votingListHelper.jsp =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/votingListHelper.jsp (rev 0) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/votingListHelper.jsp 2012-03-13 14:06:19 UTC (rev 3178) @@ -0,0 +1,192 @@ +<%-- + #%L + Pollen :: UI (strust2) + + $Id$ + $HeadURL$ + %% + Copyright (C) 2009 - 2012 CodeLutin + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --%> +<%@ page language="java" contentType="text/html" pageEncoding="utf-8" %> +<%@ taglib prefix="s" uri="/struts-tags" %> +<%@ taglib prefix="sj" uri="/struts-jquery-tags" %> + +<script type="text/javascript"> + + var votingListText = '<s:text name="pollen.common.votingList"/>'; + var personToListText = '<s:text name="pollen.common.personToList"/>'; + + function getFirstVotingList(containerId) { + var result = 65535; + getAllVotingLists(containerId).each(function () { + var current = $(this).data('votingListNumber'); + if (current < result) { + result = current; + } + }); + return result; + } + + function getLastVotingList(containerId) { + var result = 0; + getAllVotingLists(containerId).each(function () { + var current = $(this).data('votingListNumber'); + if (current > result) { + result = current; + } + }); + return result; + } + + function getAllVotingLists(containerId) { + return $("div[id^='" + containerId + "_']"); + } + + function updateUpdownVotingListActions(containerId) { + getAllVotingLists(containerId).each(function (index) { + var currentVotingListNumber = $(this).data('votingListNumber'); + var labelWidget = $('#' + containerId + "_" + currentVotingListNumber + "_label"); + labelWidget.html(votingListText + ' ' + (index + 1)); + }); + } + + function loadVotingList(containerId, votingListNumber, nbVotingLists, tokenId) { + if (votingListNumber == -1) { + // to add a new votingList, get the new available votingListNumber + votingListNumber = 1 + getLastVotingList(containerId); + } + $.ajax( + { + url:'<s:url namespace="/poll" action="displayVotingList"/>', + data:{ tokenId:tokenId, votingListNumber:votingListNumber }, + async:false, + dataType:"html", + success:function (data, textStatus) { + var container = $("#" + containerId); + container.append(data); + // store votingListNumber + var votingList = $("#" + containerId + "_" + votingListNumber); + votingList.data('votingListNumber', votingListNumber); + votingList.data('votingListContainerId', containerId); + if (votingListNumber == nbVotingLists || !tokenId) { + updateUpdownVotingListActions(containerId); + } + } + }); + } + + function addVotingList(votingListNumber, nbVotingLists, tokenId) { + loadVotingList('votingLists', votingListNumber, nbVotingLists, tokenId); + } + + function addNewVotingList() { + addVotingList(-1, -1); + return false; + } + + function deleteVotingList(votingListId) { + var votingList = $('#' + votingListId); + var containerId = votingList.data('votingListContainerId'); + votingList.remove(); + updateUpdownVotingListActions(containerId); + return false; + } + + function getFirstPersonToList(containerId) { + var result = 65535; + getAllPersonToLists(containerId).each(function () { + var current = $(this).data('personToListNumber'); + if (current < result) { + result = current; + } + }); + return result; + } + + function getLastPersonToList(containerId) { + var result = 0; + getAllPersonToLists(containerId).each(function () { + var current = $(this).data('personToListNumber'); + if (current > result) { + result = current; + } + }); + return result; + } + + function getAllPersonToLists(containerId) { + return $("div[id^='" + containerId + "_']"); + } + + function updateUpdownPersonToListActions(containerId) { + getAllPersonToLists(containerId).each(function (index) { + var currentPersonToListNumber = $(this).data('personToListNumber'); + var labelWidget = $('#' + containerId + "_" + currentPersonToListNumber + "_label"); + labelWidget.html(personToListText + ' ' + (index + 1)); + }); + } + + function loadPerson(containerId, votingListNumber, personToListNumber, nbPersonToLists, tokenId) { + if (personToListNumber == -1) { + // to add a new personToList, get the new available personToListNumber + personToListNumber = 1 + getLastPersonToList(containerId); + } + $.ajax( + { + url:'<s:url namespace="/poll" action="displayPersonToList"/>', + data:{ + tokenId:tokenId, + votingListNumber:votingListNumber, + personToListNumber:personToListNumber + }, + async:false, + dataType:"html", + success:function (data, textStatus) { + var container = $("#" + containerId); + container.append(data); + // store personToListNumber + var personToList = $("#" + containerId + "_" + personToListNumber); + personToList.data('votingListNumber', votingListNumber); + personToList.data('personToListNumber', personToListNumber); + personToList.data('personToListContainerId', containerId); + if (personToListNumber == nbPersonToLists || !tokenId) { + updateUpdownPersonToListActions(containerId); + } + } + }); + } + + function addPersonToList(votingListNumber, personToListNumber, nbPersonToLists, tokenId) { + loadPerson( + 'personToList_' + votingListNumber, + votingListNumber, personToListNumber, nbPersonToLists, tokenId + ); + } + + function addNewPersonToList(votingListNumber) { + addPersonToList(votingListNumber, -1, -1); + return false; + } + + function deletePersonToList(personToListId) { + var personToList = $('#' + personToListId); + var containerId = personToList.data('personToListContainerId'); + personToList.remove(); + updateUpdownPersonToListActions(containerId); + return false; + } +</script> \ No newline at end of file Property changes on: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/votingListHelper.jsp ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native
participants (1)
-
tchemit@users.chorem.org