r3372 - in trunk: pollen-persistence/src/main/java/org/chorem/pollen/entities/migration pollen-persistence/src/main/xmi pollen-services/src/main/java/org/chorem/pollen/bean pollen-services/src/main/java/org/chorem/pollen/services/impl pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/interceptors pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll pollen-ui-struts
Author: tchemit Date: 2012-05-18 08:52:21 +0200 (Fri, 18 May 2012) New Revision: 3372 Url: http://chorem.org/repositories/revision/pollen/3372 Log: fixes #154: [Poll] Impossible de choisir l'ordre des choix fixes #561: Can not create a image poll Un petit coup de menage, car y'a des choses qui fonctionnent pas et sont tr?\195?\168s compliqu?\195?\169es pour rien au final... Added: trunk/pollen-persistence/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallbackV1_4.java Modified: trunk/pollen-persistence/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallback.java trunk/pollen-persistence/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallbackV1_3.java trunk/pollen-persistence/src/main/xmi/pollen.properties trunk/pollen-persistence/src/main/xmi/pollen.zargo trunk/pollen-services/src/main/java/org/chorem/pollen/bean/PollDateChoice.java trunk/pollen-services/src/main/java/org/chorem/pollen/bean/PollImageChoice.java trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollFeedService.java trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollService.java trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/FileUploadAware.java trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AddChoice.java trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/SavePoll.java trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/interceptors/PollenFileUploadInterceptor.java trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/createPoll_choices.jsp trunk/pollen-ui-struts2/src/main/webapp/js/createPoll.js Modified: trunk/pollen-persistence/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallback.java =================================================================== --- trunk/pollen-persistence/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallback.java 2012-05-18 00:56:32 UTC (rev 3371) +++ trunk/pollen-persistence/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallback.java 2012-05-18 06:52:21 UTC (rev 3372) @@ -44,9 +44,11 @@ public static final Version V_1_3 = VersionUtil.valueOf("1.3"); + public static final Version V_1_4 = VersionUtil.valueOf("1.4"); + /** Les versions de mise à jour disponibles. */ public static final Version[] AVAILABLE_VERSIONS = new Version[]{ - V_1_1, V_1_2, V_1_3 + V_1_1, V_1_2, V_1_3, V_1_4 }; public PollenMigrationCallback() { Modified: trunk/pollen-persistence/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallbackV1_3.java =================================================================== --- trunk/pollen-persistence/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallbackV1_3.java 2012-05-18 00:56:32 UTC (rev 3371) +++ trunk/pollen-persistence/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallbackV1_3.java 2012-05-18 06:52:21 UTC (rev 3372) @@ -43,7 +43,7 @@ import java.util.Map; /** - * Migration for version {@code 1.2.6}. + * Migration for version {@code 1.3}. * * @author tchemit <chemit@codelutin.com> * @since 1.3 Added: trunk/pollen-persistence/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallbackV1_4.java =================================================================== --- trunk/pollen-persistence/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallbackV1_4.java (rev 0) +++ trunk/pollen-persistence/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallbackV1_4.java 2012-05-18 06:52:21 UTC (rev 3372) @@ -0,0 +1,101 @@ +package org.chorem.pollen.entities.migration; + +import org.nuiton.topia.TopiaException; +import org.nuiton.topia.framework.TopiaContextImplementor; +import org.nuiton.topia.framework.TopiaSQLQuery; +import org.nuiton.topia.migration.TopiaMigrationCallbackByClass; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +/** + * Migration for version {@code 1.4}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4 + */ +public class PollenMigrationCallbackV1_4 extends TopiaMigrationCallbackByClass.MigrationCallBackForVersion { + + public PollenMigrationCallbackV1_4(TopiaMigrationCallbackByClass callBack) { + super(PollenMigrationCallback.V_1_4, callBack); + } + + @Override + protected void prepareMigrationScript(TopiaContextImplementor tx, + List<String> queries, + boolean showSql, + boolean showProgression) throws TopiaException { + + // add indexed choices (says there is an order kept in db) : http://chorem.org/issues/154 + addIndexedChoices(tx, queries); + + } + + private void addIndexedChoices(TopiaContextImplementor tx, + List<String> queries) throws TopiaException { + + queries.add("ALTER TABLE choice ADD COLUMN poll_idx INTEGER;"); + + // get all polls + + + TopiaSQLQuery<String> getAllPollsQuery = new TopiaSQLQuery<String>() { + + @Override + protected PreparedStatement prepareQuery(Connection connection) throws SQLException { + PreparedStatement ps = connection.prepareStatement("select distinct(poll) from choice;"); + return ps; + } + + @Override + protected String prepareResult(ResultSet set) throws SQLException { + return set.getString(1); + } + }; + List<String> pollIds = getAllPollsQuery.findMultipleResult(tx); + + String choiceUpdate = "UPDATE choice SET poll_idx = %s WHERE topiaid = '%s';"; + + for (final String pollId : pollIds) { + + // get all choice ids for this poll + List<String> choiceIds = + new GetChoiceIdsSQLQuery(pollId).findMultipleResult(tx); + + int index = 0; + for (String choiceId : choiceIds) { + queries.add(String.format(choiceUpdate, index++, choiceId)); + } + + } + + // now can add not null constraints + // can not use this strong not null constraint, hibernate will at create time let a null value here :( +// queries.add("ALTER TABLE choice ALTER COLUMN poll_idx SET NOT NULL;"); + } + + private static class GetChoiceIdsSQLQuery extends TopiaSQLQuery<String> { + + private final String pollId; + + public GetChoiceIdsSQLQuery(String pollId) { + this.pollId = pollId; + } + + @Override + protected PreparedStatement prepareQuery(Connection connection) throws SQLException { + PreparedStatement ps = connection.prepareStatement( + "SELECT topiaid FROM choice WHERE poll = ? ORDER BY topiacreatedate;"); + ps.setString(1, pollId); + return ps; + } + + @Override + protected String prepareResult(ResultSet set) throws SQLException { + return set.getString(1); + } + } +} Modified: trunk/pollen-persistence/src/main/xmi/pollen.properties =================================================================== --- trunk/pollen-persistence/src/main/xmi/pollen.properties 2012-05-18 00:56:32 UTC (rev 3371) +++ trunk/pollen-persistence/src/main/xmi/pollen.properties 2012-05-18 06:52:21 UTC (rev 3372) @@ -25,12 +25,11 @@ #model.tagvalue.dbSchema=Pollen model.tagvalue.constantPrefix=PROPERTY_ model.tagvalue.java.lang.String=text -model.tagvalue.version=1.3 +model.tagvalue.version=1.4 model.tagvalue.doNotGenerateBooleanGetMethods=true model.tagvalue.indexForeignKeys=true -org.chorem.pollen.business.persistence.Poll.attribute.choice.stereotype=ordered -org.chorem.pollen.business.persistence.Poll.attribute.choice.tagvalue.orderBy=topiaCreateDate +org.chorem.pollen.business.persistence.Poll.attribute.choice.stereotype=indexed org.chorem.pollen.business.persistence.Poll.attribute.vote.stereotype=ordered org.chorem.pollen.business.persistence.Poll.attribute.vote.tagvalue.orderBy=topiaCreateDate Modified: trunk/pollen-persistence/src/main/xmi/pollen.zargo =================================================================== (Binary files differ) Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/bean/PollDateChoice.java =================================================================== --- trunk/pollen-services/src/main/java/org/chorem/pollen/bean/PollDateChoice.java 2012-05-18 00:56:32 UTC (rev 3371) +++ trunk/pollen-services/src/main/java/org/chorem/pollen/bean/PollDateChoice.java 2012-05-18 06:52:21 UTC (rev 3372) @@ -56,7 +56,6 @@ setDescription(choice.getDescription()); setTopiaId(choice.getTopiaId()); setValidate(choice.isValidate()); - setPoll(choice.getPoll()); setDate(new Date(Long.valueOf(choice.getName()))); } Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/bean/PollImageChoice.java =================================================================== --- trunk/pollen-services/src/main/java/org/chorem/pollen/bean/PollImageChoice.java 2012-05-18 00:56:32 UTC (rev 3371) +++ trunk/pollen-services/src/main/java/org/chorem/pollen/bean/PollImageChoice.java 2012-05-18 06:52:21 UTC (rev 3372) @@ -54,7 +54,6 @@ setDescription(choice.getDescription()); setTopiaId(choice.getTopiaId()); setValidate(choice.isValidate()); - setPoll(choice.getPoll()); } public void toChoice(Choice choice) { Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollFeedService.java =================================================================== --- trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollFeedService.java 2012-05-18 00:56:32 UTC (rev 3371) +++ trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollFeedService.java 2012-05-18 06:52:21 UTC (rev 3372) @@ -146,14 +146,14 @@ addFeedEntry(vote.getPoll(), title, content, pollVoteUrl); } - public void onAddChoice(Choice choice, PollUrl pollVoteUrl) { + public void onAddChoice(Poll poll, Choice choice, PollUrl pollVoteUrl) { String title = _("pollen.feed.addChoiceTitle", choice.getName()); String content = _("pollen.feed.addChoiceContent", choice.getDescription()); - addFeedEntry(choice.getPoll(), title, content, pollVoteUrl); + addFeedEntry(poll, title, content, pollVoteUrl); } /** Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollService.java =================================================================== --- trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollService.java 2012-05-18 00:56:32 UTC (rev 3371) +++ trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollService.java 2012-05-18 06:52:21 UTC (rev 3372) @@ -26,11 +26,8 @@ import com.google.common.base.Function; import com.google.common.base.Objects; import com.google.common.base.Preconditions; -import com.google.common.base.Predicates; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; @@ -79,7 +76,6 @@ import java.util.Date; import java.util.List; import java.util.Map; -import java.util.Set; public class PollService extends PollenServiceSupport { @@ -132,12 +128,12 @@ * matches an existing {@link UserAccount}, the resulting poll creator will * be attached to it. * - * @param pollUid Uid of the poll to edit, if not defined, a new poll is instanciated + * @param pollUid Uid of the poll to edit, if not defined, a new poll is instanciated * @param userAccount User account to attach to the creator - * @param clone Flag to copy or not ids in case of poll cloning - * @return the Poll ready for edition (no longer linked to the topia context) + * @param clone Flag to copy or not ids in case of poll cloning + * @return the Poll ready for edition (no longer linked to the topia context) * @see #getNewPoll(UserAccount) - * @see #getNewPollCopy(Poll, UserAccount, boolean) + * @see #getNewPollCopy(Poll, UserAccount, boolean) */ public Poll getPollEditable(String pollUid, UserAccount userAccount, boolean clone) { @@ -151,18 +147,18 @@ if (poll == null) { result = getNewPoll(userAccount); - + } else { - result = getNewPollCopy(poll, userAccount, clone); + result = getNewPollCopy(poll, userAccount, clone); } } return result; } - + protected Poll getNewPollCopy(Poll source, UserAccount userAccount, boolean clone) { - + Preconditions.checkNotNull(source); - + PollDAO pollDAO = getDAO(Poll.class); Poll result = newInstance(pollDAO); @@ -245,7 +241,7 @@ // Load votes to have the correct size used to check if vote is started result.setVote(source.getVote()); - + return result; } @@ -354,27 +350,19 @@ // -- Choices -- // if (!voteStarted) { - - // Retrieve previous existing choices - Map<String, Choice> choicesExist = Maps.uniqueIndex( - pollToUpdate.getChoice(), - PollenServiceFunctions.newTopiaIdExtractor() - ); - + // Save all choices from source poll - Set<String> choicesAdded = Sets.newHashSet(); + List<Choice> choicesAdded = Lists.newLinkedList(); for (Choice choice : poll.getChoice()) { - String choiceId = saveChoice(pollToUpdate, choice); - choicesAdded.add(choiceId); + Choice choiceLoaded = saveChoice(pollToUpdate, choice); + choicesAdded.add(choiceLoaded); } - - // Delete all previous choices not keeped in source poll - Map<String, Choice> choicesToDelete = - Maps.filterKeys(choicesExist, - Predicates.not(Predicates.in(choicesAdded))); - for (Choice choice : choicesToDelete.values()) { - pollToUpdate.removeChoice(choice); - } + + // removed choice will be deleted from db by composition relation + pollToUpdate.clearChoice(); + + // re-add choices in incoming order. + pollToUpdate.addAllChoice(choicesAdded); } // -- PreventRules -- // @@ -403,12 +391,12 @@ URL applicationUrl = serviceContext.getApplicationURL(); String baseUrl = applicationUrl + "/poll/votefor/"; PollUri pollUri = PollUri.newPollUri(poll.getPollId()); - + if (moderate) { String creatorId = poll.getCreator().getAccountId(); pollUri.setAccountId(creatorId); } - + PollUrl result = PollUrl.newPollUrl(baseUrl, pollUri); return result; } @@ -484,24 +472,6 @@ } catch (TopiaException e) { throw new PollenTechnicalException("Could not obtain invited polls", e); } - -// try { -// PollDAO dao = PollenDAOHelper.getPollDAO(getTransaction()); -// TopiaQuery countQuery = dao.createQuery("e"); -// countQuery.addWhere("e." + Poll.PROPERTY_CREATOR + "." + PollAccount.PROPERTY_USER_ACCOUNT, TopiaQuery.Op.EQ, user); -// long records = dao.countByQuery(countQuery); -// pager.setRecords((int) records); -// -// PagerUtil.computeRecordIndexesAndPagesNumber(pager); -// TopiaQuery query = dao.createQuery("e"); -// TopiaFilterPagerUtil.addPagerToQuery(pager, query); -// query.addWhere("e." + Poll.PROPERTY_CREATOR + "." + PollAccount.PROPERTY_USER_ACCOUNT, TopiaQuery.Op.EQ, user); -// -// List<Poll> result = dao.findAllByQuery(query); -// return result; -// } catch (TopiaException e) { -// throw new PollenTechnicalException(e); -// } } public Map<Poll, PollAccount> getParticipatedPolls( @@ -558,12 +528,12 @@ * create or update is done here. The {@code poll} is used to retrieve a potential * existing vote with pollAccount linked to {@code userAccount}. * - * @param accountId Id of the existing account (optional) + * @param accountId Id of the existing account (optional) * @param userAccount UserAccount where account will be attached (optional) - * @param poll Poll where pollAccount will be added + * @param poll Poll where pollAccount will be added * @return the existing PollAccount or a new instance * @throws PollAccountNotFound if accountId is defined and doesn't match any - * existing PollAccount + * existing PollAccount */ public PollAccount getPollAccountEditable(String accountId, UserAccount userAccount, Poll poll) throws PollAccountNotFound { PollAccount result = null; @@ -741,7 +711,7 @@ return result; } - public void createChoice(String pollId, Choice choice) throws PollNotFoundException { + public void addChoice(String pollId, Choice choice) throws PollNotFoundException { Preconditions.checkNotNull(pollId); Preconditions.checkNotNull(choice); @@ -752,12 +722,15 @@ throw new PollNotFoundException(); } - saveChoice(poll, choice); + Choice choiceAdded = saveChoice(poll, choice); - commitTransaction("Can't create new choice [" + poll.getChoiceType() + "] for poll '" + pollId + "'"); + poll.addChoice(choiceAdded); + + commitTransaction("Can't create new choice [" + + poll.getChoiceType() + "] for poll '" + pollId + "'"); } - protected String saveChoice(Poll poll, Choice choice) { + protected Choice saveChoice(Poll poll, Choice choice) { ChoiceType choiceType = poll.getChoiceType(); ChoiceDAO dao = getDAO(Choice.class); @@ -772,15 +745,18 @@ if (choiceType == ChoiceType.IMAGE) { - // copy image where it belong and generate the thumb PollImageChoice imageChoice = (PollImageChoice) choice; imageChoice.toChoice(choiceLoaded); - try { - saveImages(poll, imageChoice); - } catch (IOException e) { - throw new PollenTechnicalException( - "Could not create image choice", e); + if (choice.getTopiaId() == null) { + // copy image where it belong and generate the thumb + // only if choice is to create + try { + saveImages(poll, imageChoice); + } catch (IOException e) { + throw new PollenTechnicalException( + "Could not create image choice", e); + } } } else if (choiceType == ChoiceType.DATE) { @@ -797,8 +773,8 @@ choiceLoaded.setValidate(choice.isValidate()); choiceLoaded.setName(choice.getName()); } - - return choiceLoaded.getTopiaId(); + + return choiceLoaded; } public void deleteChoice(String pollId, String choiceId) @@ -961,7 +937,7 @@ Vote voteToAdd = getEntityById(Vote.class, voteId); pollToUpdate.addVote(voteToAdd); - + // Update hasVoted flag for RESTRICTED/GROUP poll if (PollType.FREE != poll.getPollType()) { @@ -1015,7 +991,7 @@ result.setName(votingList.getName()); result.setWeight(votingList.getWeight()); - + PollUrl voteURL = getPollVoteUrl(poll, false); // Merge PersonToList @@ -1023,7 +999,7 @@ for (PersonToList personToList : votingList.getPollAccountPersonToList()) { PollAccount pollAccount = personToList.getPollAccount(); - + PersonToList personToListLoaded; PollAccount pollAccountLoaded; if (personToList.getTopiaId() == null) { @@ -1040,11 +1016,11 @@ } pollAccountLoaded = pollAccountDAO.findByAccountId(accountId); - if (pollAccountLoaded == null) { + if (pollAccountLoaded == null) { pollAccountLoaded = create(pollAccountDAO); pollAccountLoaded.setAccountId(accountId); } - + } else { personToListLoaded = getEntityById(PersonToList.class, personToList.getTopiaId()); pollAccountLoaded = personToListLoaded.getPollAccount(); @@ -1071,7 +1047,7 @@ } result.setPollAccountPersonToList(personToListsUpdated); } - + protected void savePreventRule(Poll poll, PreventRule preventRule) { PreventRuleDAO preventRuleDAO = getDAO(PreventRule.class); Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/FileUploadAware.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/FileUploadAware.java 2012-05-18 00:56:32 UTC (rev 3371) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/FileUploadAware.java 2012-05-18 06:52:21 UTC (rev 3372) @@ -23,19 +23,28 @@ */ package org.chorem.pollen.ui.actions; +import org.chorem.pollen.ui.interceptors.PollenFileUploadInterceptor; + import java.io.File; -import java.util.List; /** + * Contract to place on actions which needs some upload. + * <p/> + * This is linked with the {@link PollenFileUploadInterceptor} interceptor + * which logic is not the same than the bacis struts2 upload interceptor. + * <p/> * Created: 30/03/12 * * @author fdesbois <desbois@codelutin.com> + * @author tchemit <chemit@codelutin.com> + * @since 1.3 */ public interface FileUploadAware { - void setFiles(String paramName, List<File> files); + void addFile(int index, File file); - void setFileContentTypes(String paramName, List<String> contentTypes); + void addFileContentType(int index, String contentType); - void setFileNames(String paramName, List<String> fileNames); + void addFileName(int index, String fileName); + } Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AddChoice.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AddChoice.java 2012-05-18 00:56:32 UTC (rev 3371) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AddChoice.java 2012-05-18 06:52:21 UTC (rev 3372) @@ -24,7 +24,6 @@ package org.chorem.pollen.ui.actions.poll; import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; import com.opensymphony.xwork2.Preparable; import com.opensymphony.xwork2.interceptor.annotations.InputConfig; import org.apache.commons.lang3.StringUtils; @@ -36,7 +35,6 @@ import org.chorem.pollen.ui.actions.FileUploadAware; import java.io.File; -import java.util.List; /** * To add a poll comment. @@ -50,52 +48,31 @@ protected Choice choice; - private List<File> imageChoices; + private File imageChoice; - private List<String> imageChoiceContentTypes; + private String imageChoiceContentType; - private List<String> imageChoiceFileNames; + private String imageChoiceFileName; public Choice getChoice() { return choice; } @Override - public void setFiles(String paramName, List<File> files) { - this.imageChoices = Lists.newArrayList(files); + public void addFile(int index, File file) { + imageChoice = file; } @Override - public void setFileContentTypes(String paramName, List<String> contentTypes) { - this.imageChoiceContentTypes = Lists.newArrayList(contentTypes); + public void addFileContentType(int index, String contentType) { + imageChoiceContentType = contentType; } @Override - public void setFileNames(String paramName, List<String> fileNames) { - this.imageChoiceFileNames = Lists.newArrayList(fileNames); + public void addFileName(int index, String fileName) { + imageChoiceFileName = fileName; } - public List<File> getImageChoices() { - if (imageChoices == null) { - imageChoices = Lists.newArrayList(); - } - return imageChoices; - } - - public List<String> getImageChoiceContentTypes() { - if (imageChoiceContentTypes == null) { - imageChoiceContentTypes = Lists.newArrayList(); - } - return imageChoiceContentTypes; - } - - public List<String> getImageChoiceFileNames() { - if (imageChoiceFileNames == null) { - imageChoiceFileNames = Lists.newArrayList(); - } - return imageChoiceFileNames; - } - @Override public void prepare() throws PollNotFoundException { @@ -105,12 +82,12 @@ choice = getPollService().getNewChoice(choiceType); // Push image choice data from uploaded file - if (ChoiceType.IMAGE == choiceType && getImageChoices().size() == 1) { + if (ChoiceType.IMAGE == choiceType && imageChoice != null) { - String fileName = getImageChoiceFileNames().get(0); - String location = getImageChoices().get(0).getAbsolutePath(); + String fileName = imageChoiceFileName; + String location = imageChoice.getAbsolutePath(); choice.setName(fileName); - ((PollImageChoice)choice).setLocation(location); + ((PollImageChoice) choice).setLocation(location); } } @@ -120,7 +97,7 @@ ChoiceType choiceType = getPoll().getChoiceType(); String propName = ChoiceHelper.getValuePropertyName(choiceType); - + Object value = ChoiceHelper.toValue(choice, choiceType); // -- Validate value notEmpty @@ -145,7 +122,7 @@ @Override public String execute() throws Exception { - getPollService().createChoice(getPollId(), choice); + getPollService().addChoice(getPollId(), choice); return SUCCESS; } Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/SavePoll.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/SavePoll.java 2012-05-18 00:56:32 UTC (rev 3371) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/SavePoll.java 2012-05-18 06:52:21 UTC (rev 3372) @@ -87,15 +87,6 @@ private static final Pattern IMAGE_CHOICE_NAME_PATTERN = Pattern.compile("imageChoice_(\\d+)\\.name"); - /** Uploaded images (for choice type poll). */ - private List<File> imageChoice; - - /** Uploaded images content type (for choice type poll). */ - private List<String> imageChoiceContentType; - - /** Uploaded images name (from use desktop) (for choice type poll). */ - private List<String> imageChoiceFileName; - /** Flag when there is some errors on the information panel. */ protected boolean informationsError; @@ -106,7 +97,7 @@ * All the parameters send by request used to build back choices of the * poll. */ - protected Map<String, String[]> parameters; + protected final Map<String, String[]> parameters = Maps.newTreeMap(); /** * Indexed choices retreive from parameters for the choiceType selected in @@ -137,22 +128,22 @@ userAccount = getPollService().getEntityById(UserAccount.class, userId); } } - + poll = getPollService().getPollEditable(pollUid, userAccount, false); // If vote is started, prepare choices and votingLists is useless // because they can't be updated. if (!isVoteStarted()) { - + // Retrieve choiceType from parameters, the poll object will be updated after prepare String choiceTypeParam = getNonEmptyParameterValue("poll.choiceType"); ChoiceType pollChoiceType = ChoiceType.valueOf(choiceTypeParam); poll.setChoiceType(pollChoiceType); - + // build poll choices - + switch (pollChoiceType) { - + case TEXT: choices = buildTextChoices(); break; @@ -163,30 +154,30 @@ choices = buildImageChoices(); break; } - + PollType pollType; String pollTypeParam = getNonEmptyParameterValue("poll.pollType"); if (pollTypeParam == null) { pollType = poll.getPollType(); - + } else { pollType = PollType.valueOf(pollTypeParam); } - + switch (pollType) { - + case FREE: - + // empty voting list votingLists = Maps.newTreeMap(); break; case RESTRICTED: - + // restricted voting list votingLists = buildVotingLists(pollType); break; case GROUP: - + // group voting lists votingLists = buildVotingLists(pollType); break; @@ -197,9 +188,9 @@ @Override public String input() { - Collection<Choice> pollChoices = + Collection<Choice> pollChoices = isVoteStarted() ? poll.getChoice() : choices.values(); - Collection<VotingList> pollVotingLists = + Collection<VotingList> pollVotingLists = isVoteStarted() ? poll.getVotingList() : votingLists.values(); loadChoicesAndvotingLists(poll, @@ -249,7 +240,7 @@ if (!isLimitChoice()) { poll.setMaxChoiceNb(0); } - + poll.clearPreventRule(); PreventRuleService preventRuleService = @@ -289,51 +280,39 @@ } @Override - public void setFiles(String paramName, List<File> files) { - this.imageChoice = Lists.newArrayList(files); + public void addFile(int index, File file) { + parameters.put( + "imageChoice_" + index + ".location", + new String[]{file.getAbsolutePath()}); } @Override - public void setFileContentTypes(String paramName, List<String> contentTypes) { - this.imageChoiceContentType = Lists.newArrayList(contentTypes); + public void addFileContentType(int index, String contentType) { + // not used here } @Override - public void setFileNames(String paramName, List<String> fileNames) { - this.imageChoiceFileName = Lists.newArrayList(fileNames); + public void addFileName(int index, String fileName) { + parameters.put("imageChoice_" + index + ".name", + new String[]{fileName}); } @Override public void setParameters(Map<String, String[]> parameters) { - this.parameters = parameters; + this.parameters.putAll(parameters); } - public List<File> getImageChoice() { - return imageChoice; - } - - public List<String> getImageChoiceContentType() { - if (imageChoiceContentType == null) { - imageChoiceContentType = Lists.newArrayList(); - } - return imageChoiceContentType; - } - - public List<String> getImageChoiceFileName() { - if (imageChoiceFileName == null) { - imageChoiceFileName = Lists.newArrayList(); - } - return imageChoiceFileName; - } - + @Override public boolean isInformationsError() { return informationsError; } + @Override public boolean isOptionsError() { return optionsError; } + @Override public int getSelectedTab() { int result; if (isInformationsError()) { @@ -415,30 +394,31 @@ } } } - + String creatorEmail = poll.getCreator().getEmail(); if (StringUtils.isNotBlank(creatorEmail) && !StringUtil.isEmail(creatorEmail)) { addOptionsError("poll.creator.email", _("pollen.error.email.invalid")); } - + if (validateEndDate(poll.getBeginChoiceDate(), poll.getEndChoiceDate())) { - - addOptionsError("poll.endChoiceDate", - _("pollen.error.poll.endChoiceDate.before.beginChoiceDate")); + + addOptionsError( + "poll.endChoiceDate", + _("pollen.error.poll.endChoiceDate.before.beginChoiceDate")); } if (validateEndDate(poll.getBeginDate(), poll.getEndDate())) { addOptionsError("poll.endDate", - _("pollen.error.poll.endDate.before.beginDate")); + _("pollen.error.poll.endDate.before.beginDate")); } if (validateEndDate(poll.getEndChoiceDate(), poll.getEndDate())) { addOptionsError("poll.endChoiceDate", - _("pollen.error.poll.endChoiceDate.after.endDate")); + _("pollen.error.poll.endChoiceDate.after.endDate")); } } @@ -447,9 +427,10 @@ Set<String> groups, Set<String> voters, Set<String> emails) { - + PollType votingListType = poll.getPollType(); - String fieldNamePrefix = "votingList" + votingListType + "_" + votingListNumber; + String fieldNamePrefix = "votingList" + votingListType + "_" + + votingListNumber; if (isGroupPoll()) { @@ -498,8 +479,9 @@ // check there is at least one voter - List<PersonToList> personToLists = votingList.getPollAccountPersonToList(); - + List<PersonToList> personToLists = + votingList.getPollAccountPersonToList(); + if (CollectionUtils.isEmpty(personToLists)) { // no personToList found for unique votingList 0 @@ -528,7 +510,7 @@ Set<String> emails) { String fieldNamePrefix = votingListFieldNamePrefix + - "PersonToList_" + personToListNumber; + "PersonToList_" + personToListNumber; PollAccount pollAccount = personToList.getPollAccount(); @@ -686,20 +668,6 @@ protected Map<Integer, Choice> buildImageChoices() { Map<Integer, Choice> result = Maps.newTreeMap(); - // push back in parameters stuff from uploaded files - int index = 0; - - 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()}); - } - index++; - } - int maxNumber = 0; for (String paramName : parameters.keySet()) { @@ -788,14 +756,6 @@ 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); } } Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/interceptors/PollenFileUploadInterceptor.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/interceptors/PollenFileUploadInterceptor.java 2012-05-18 00:56:32 UTC (rev 3371) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/interceptors/PollenFileUploadInterceptor.java 2012-05-18 06:52:21 UTC (rev 3372) @@ -35,22 +35,19 @@ import javax.servlet.http.HttpServletRequest; import java.io.File; -import java.util.ArrayList; import java.util.Enumeration; -import java.util.List; import java.util.Locale; -import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Overrides the default file upload interceptor to be able to match uploaded * files in specific fields. - * + * <p/> * We want to put upload files in a list (field is file for example) and then * fileName in another list but the default interceptor does not accept this * since it suffix the filename field with FileName... - * + * <p/> * TODO tchemit 2012-03-05 submit a patch to struts guys to avoid this fork. * * @author tchemit <chemit@codelutin.com> @@ -80,6 +77,12 @@ Object action = invocation.getAction(); + if (!(action instanceof FileUploadAware)) { + + // only used for our purpose + return invocation.invoke(); + } + if (action instanceof ValidationAware) { validation = (ValidationAware) action; } @@ -104,6 +107,14 @@ // get the value of this input tag String inputName = (String) fileParameterNames.nextElement(); + Matcher matcher1 = FILENAME_PATTERN.matcher(inputName); + + if (!matcher1.matches()) { + throw new IllegalStateException( + "Uploaded param name must match " + FILENAME_PATTERN); + } + Integer suffix = Integer.valueOf(matcher1.group(2)); + // get the content type String[] contentType = multiWrapper.getContentTypes(inputName); @@ -114,50 +125,33 @@ if (isNonEmpty(fileName)) { // get a File object for the uploaded File File[] files = multiWrapper.getFiles(inputName); + if (files != null && files.length > 0) { - List<File> acceptedFiles = new ArrayList<File>(files.length); - List<String> acceptedContentTypes = new ArrayList<String>(files.length); - List<String> acceptedFileNames = new ArrayList<String>(files.length); - Matcher matcher1 = FILENAME_PATTERN.matcher(inputName); - - String contentTypeName; - String fileNameName; - if (matcher1.matches()) { - String prefix = matcher1.group(1); - String suffix = matcher1.group(2); - contentTypeName = prefix + "ContentType[" + suffix + "]"; - fileNameName = prefix + "FileName[" + suffix + "]"; - } else { - contentTypeName = inputName + "ContentType"; - fileNameName = inputName + "FileName"; + if (files.length > 1) { + throw new IllegalStateException("Only accept one file to upload for name " + inputName); } + File acceptedFile = null; + String acceptedContentType = null; + String acceptedFileName = null; - for (int index = 0; index < files.length; index++) { - if (acceptFile(action, files[index], fileName[index], contentType[index], inputName, validation, ac.getLocale())) { - acceptedFiles.add(files[index]); - acceptedContentTypes.add(contentType[index]); - acceptedFileNames.add(fileName[index]); - } - } - if (!acceptedFiles.isEmpty()) { + if (acceptFile(action, files[0], fileName[0], contentType[0], inputName, validation, ac.getLocale())) { - if (action instanceof FileUploadAware) { - FileUploadAware fileUpload = (FileUploadAware) action; + acceptedFile = files[0]; + acceptedContentType = contentType[0]; + acceptedFileName = fileName[0]; + } - fileUpload.setFiles(inputName, acceptedFiles); - fileUpload.setFileContentTypes(contentTypeName, acceptedContentTypes); - fileUpload.setFileNames(fileNameName, acceptedFileNames); + if (acceptedFile != null) { - } else { - Map<String, Object> params = ac.getParameters(); + FileUploadAware fileUpload = (FileUploadAware) action; - params.put(inputName, acceptedFiles.toArray(new File[acceptedFiles.size()])); - params.put(contentTypeName, acceptedContentTypes.toArray(new String[acceptedContentTypes.size()])); - params.put(fileNameName, acceptedFileNames.toArray(new String[acceptedFileNames.size()])); - } + fileUpload.addFile(suffix, acceptedFile); + fileUpload.addFileContentType(suffix, acceptedContentType); + fileUpload.addFileName(suffix, acceptedFileName); + } } } else { @@ -178,13 +172,6 @@ private static final String DEFAULT_MESSAGE = "no.message.found"; -// private PatternMatcher matcher; -// -// @Inject -// public void setMatcher(PatternMatcher matcher) { -// this.matcher = matcher; -// } - private boolean isNonEmpty(Object[] objArray) { boolean result = false; for (int index = 0; index < objArray.length && !result; index++) { Modified: trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/createPoll_choices.jsp =================================================================== --- trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/createPoll_choices.jsp 2012-05-18 00:56:32 UTC (rev 3371) +++ trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/createPoll_choices.jsp 2012-05-18 06:52:21 UTC (rev 3372) @@ -32,21 +32,24 @@ <hr/> <s:fielderror fieldName="poll.choices"/> - <s:set id='deleteTitle'><s:text name="pollen.action.pollChoiceDelete"/></s:set> + <s:set id='deleteTitle'><s:text + name="pollen.action.pollChoiceDelete"/></s:set> <s:set id='upTitle'><s:text name="pollen.action.pollChoiceUp"/></s:set> <s:set id='downTitle'><s:text name="pollen.action.pollChoiceDown"/></s:set> <div id="choicesTEXT" class="choices"> <s:iterator value="textChoices" status="status" var="choice"> <s:set name="choiceNumber"><s:property value="%{#status.index}"/></s:set> - <s:set name="prefix">textChoice_<s:property value="%{#choiceNumber}"/></s:set> + <s:set name="prefix">textChoice_<s:property + value="%{#choiceNumber}"/></s:set> <div id='choicesTEXT_<s:property value="choiceNumber"/>'> <s:hidden key='%{#prefix}.topiaId' value='%{#choice.topiaId}' label=''/> <sp:fielderror fieldName="%{#prefix}"/> <div class="fleft choiceName"> <s:label for="%{#prefix}.name" id="choicesTEXT_label_%{#choiceNumber}" theme="simple" value=''/> - <s:textfield cssClass="nameField" id='%{#prefix}.name' key="%{#prefix}.name" + <s:textfield cssClass="nameField" id='%{#prefix}.name' + key="%{#prefix}.name" label='' theme="simple" value="%{#choice.name}" disabled="%{voteStarted}"/> - @@ -54,30 +57,33 @@ theme="simple"/> <%--/div> <div class="fleft"--%> - <s:textarea cols="30" id="%{#prefix}.description" label='' theme="simple" - key="%{#prefix}.description" value="%{#choice.description}" + <s:textarea cols="30" id="%{#prefix}.description" label='' + theme="simple" + key="%{#prefix}.description" + value="%{#choice.description}" disabled="%{voteStarted}"/> </div> <s:if test="!voteStarted"> <div class="fright"> - <s:a href='#' onclick="return deleteChoice('choicesTEXT_%{#choiceNumber}')"> + <s:a id='choicesTEXT_down_%{choiceNumber}' + cssClass="hidden" href='#' + onclick="return downChoice('choicesTEXT_%{choiceNumber}')"> + <image alt='<s:property value="downTitle"/>' + title='<s:property value="downTitle"/>' + src="<s:url value='/img/1downarrow.png'/>"></image> + </s:a> + <s:a id='choicesTEXT_up_%{choiceNumber}' href='#' cssClass="hidden" + onclick="return upChoice('choicesTEXT_%{choiceNumber}')"> + <image alt='<s:property value="upTitle"/>' + title='<s:property value="upTitle"/>' + src="<s:url value='/img/1uparrow.png'/>"></image> + </s:a> + <s:a href='#' + onclick="return deleteChoice('choicesTEXT_%{choiceNumber}')"> <image alt='<s:property value="deleteTitle"/>' title='<s:property value="deleteTitle"/>' src="<s:url value='/img/delete.png'/>"></image> </s:a> - <%--s:a id='choicesTEXT_down_%{choiceNumber}' - cssClass="hidden" href='#' - onclick="return downChoice('choicesTEXT_%{choiceNumber}')"> - <image alt='<s:property value="downTitle"/>' - title='<s:property value="downTitle"/>' - src="<s:url value='/img/1downarrow.png'/>"></image> - </s:a> - <s:a id='choicesTEXT_up_%{choiceNumber}' href='#' cssClass="hidden" - onclick="return upChoice('choicesTEXT_%{choiceNumber}')"> - <image alt='<s:property value="upTitle"/>' - title='<s:property value="upTitle"/>' - src="<s:url value='/img/1uparrow.png'/>"></image> - </s:a--%> </div> </s:if> <div class="cleanBoth"></div> @@ -87,16 +93,19 @@ <div id="choicesDATE" class="choices"> <s:iterator value="dateChoices" status="status" var="choice"> <s:set name="choiceNumber"><s:property value="%{#status.index}"/></s:set> - <s:set name="prefix">dateChoice_<s:property value="%{#choiceNumber}"/></s:set> + <s:set name="prefix">dateChoice_<s:property + value="%{#choiceNumber}"/></s:set> <div id='choicesDATE_<s:property value="choiceNumber"/>'> <s:hidden key='%{#prefix}.topiaId' id='%{#prefix}.topiaId' - value='%{#choice.topiaId}' label='' theme="simple" /> + value='%{#choice.topiaId}' label='' theme="simple"/> <sp:fielderror fieldName="%{#prefix}"/> <div class="fleft choiceName"> <s:label for="%{#prefix}.name" id="choicesDATE_label_%{choiceNumber}" theme="simple" value=''/> - <sj:datepicker id='%{#prefix}.name' key="%{#prefix}.name" changeMonth="true" - changeYear="true" labelSeparator="" theme="simple" label="" + <sj:datepicker id='%{#prefix}.name' key="%{#prefix}.name" + changeMonth="true" + changeYear="true" labelSeparator="" theme="simple" + label="" timepicker="true" value="%{#choice.date}" displayFormat="%{getText('pollen.common.datePickerPattern')}" disabled="%{voteStarted}"/> @@ -112,24 +121,25 @@ </div> <s:if test="!voteStarted"> <div class="fright"> - <s:a href='#' onclick="return deleteChoice('choicesDATE_%{choiceNumber}')"> + <s:a id='choicesDATE_down_%{choiceNumber}' + cssClass="hidden" href='#' + onclick="return downChoice('choicesDATE_%{choiceNumber}')"> + <image alt='<s:property value="downTitle"/>' + title='<s:property value="downTitle"/>' + src="<s:url value='/img/1downarrow.png'/>"></image> + </s:a> + <s:a id='choicesDATE_up_%{choiceNumber}' href='#' cssClass="hidden" + onclick="return upChoice('choicesDATE_%{choiceNumber}')"> + <image alt='<s:property value="upTitle"/>' + title='<s:property value="upTitle"/>' + src="<s:url value='/img/1uparrow.png'/>"></image> + </s:a> + <s:a href='#' + onclick="return deleteChoice('choicesDATE_%{choiceNumber}')"> <image alt='<s:property value="deleteTitle"/>' title='<s:property value="deleteTitle"/>' src="<s:url value='/img/delete.png'/>"></image> </s:a> - <%--s:a id='choicesDATE_down_%{choiceNumber}' - cssClass="hidden" href='#' - onclick="return downChoice('choicesDATE_%{choiceNumber}')"> - <image alt='<s:property value="downTitle"/>' - title='<s:property value="downTitle"/>' - src="<s:url value='/img/1downarrow.png'/>"></image> - </s:a> - <s:a id='choicesDATE_up_%{choiceNumber}' href='#' cssClass="hidden" - onclick="return upChoice('choicesDATE_%{choiceNumber}')"> - <image alt='<s:property value="upTitle"/>' - title='<s:property value="upTitle"/>' - src="<s:url value='/img/1uparrow.png'/>"></image> - </s:a--%> </div> </s:if> <div class="cleanBoth"></div> @@ -139,14 +149,15 @@ <div id="choicesIMAGE" class="choices"> <s:iterator value="imageChoices" status="status" var="choice"> <s:set name="choiceNumber"><s:property value="%{#status.index}"/></s:set> - <s:set name="prefix">imageChoice_<s:property value="%{#choiceNumber}"/></s:set> + <s:set name="prefix">imageChoice_<s:property + value="%{#choiceNumber}"/></s:set> <div id='choicesIMAGE_<s:property value="choiceNumber"/>'> <s:hidden key='%{#prefix}.topiaId' value='%{#choice.topiaId}' label=''/> <sp:fielderror fieldName="%{#prefix}"/> <div class="fleft choiceName"> <s:label for="%{#prefix}.name" id="choicesIMAGE_label_%{choiceNumber}" theme="simple" value=''/> - <s:if test="choice.name != ''"> + <s:if test="#choice.name != null"> <%--Uploaded image--%> <s:hidden id="%{#prefix}.name" name="%{#prefix}.name" @@ -160,7 +171,8 @@ </s:if> <s:else> <%--New image--%> - <s:file key='%{#prefix2}' label='' theme="simple" cssClass="nameField" + <s:file key='imageChoice[%{#choiceNumber}]' label='' theme="simple" + cssClass="nameField" disabled="%{voteStarted}"/> </s:else> - @@ -168,30 +180,33 @@ theme="simple"/> </div> <div class="fleft"> - <s:textarea cols="30" id="%{#prefix}.description" label='' theme="simple" - key="%{#prefix}.description" value="%{#choice.description}" + <s:textarea cols="30" id="%{#prefix}.description" label='' + theme="simple" + key="%{#prefix}.description" + value="%{#choice.description}" disabled="%{voteStarted}"/> </div> <s:if test="!voteStarted"> <div class="fright"> - <s:a href='#' onclick="return deleteChoice('choicesIMAGE_%{choiceNumber}')"> + <s:a id='choicesIMAGE_down_%{choiceNumber}' + cssClass="hidden" href='#' + onclick="return downChoice('choicesIMAGE_%{choiceNumber}')"> + <image alt='<s:property value="downTitle"/>' + title='<s:property value="downTitle"/>' + src="<s:url value='/img/1downarrow.png'/>"></image> + </s:a> + <s:a id='choicesIMAGE_up_%{choiceNumber}' href='#' cssClass="hidden" + onclick="return upChoice('choicesIMAGE_%{choiceNumber}')"> + <image alt='<s:property value="upTitle"/>' + title='<s:property value="upTitle"/>' + src="<s:url value='/img/1uparrow.png'/>"></image> + </s:a> + <s:a href='#' + onclick="return deleteChoice('choicesIMAGE_%{choiceNumber}')"> <image alt='<s:property value="deleteTitle"/>' title='<s:property value="deleteTitle"/>' src="<s:url value='/img/delete.png'/>"></image> </s:a> - <%--s:a id='choicesIMAGE_down_%{choiceNumber}' - cssClass="hidden" href='#' - onclick="return downChoice('choicesIMAGE_%{choiceNumber}')"> - <image alt='<s:property value="downTitle"/>' - title='<s:property value="downTitle"/>' - src="<s:url value='/img/1downarrow.png'/>"></image> - </s:a> - <s:a id='choicesIMAGE_up_%{choiceNumber}' href='#' cssClass="hidden" - onclick="return upChoice('choicesIMAGE_%{choiceNumber}')"> - <image alt='<s:property value="upTitle"/>' - title='<s:property value="upTitle"/>' - src="<s:url value='/img/1uparrow.png'/>"></image> - </s:a--%> </div> </s:if> Modified: trunk/pollen-ui-struts2/src/main/webapp/js/createPoll.js =================================================================== --- trunk/pollen-ui-struts2/src/main/webapp/js/createPoll.js 2012-05-18 00:56:32 UTC (rev 3371) +++ trunk/pollen-ui-struts2/src/main/webapp/js/createPoll.js 2012-05-18 06:52:21 UTC (rev 3372) @@ -303,17 +303,17 @@ //-- Choice methods //---------------------------------------------------------------------------- -/*function getFirstChoice(containerId) { - var result = 65535; +function getFirstChoice(containerId) { + var result = 65535; - getAllChoices(containerId).each(function () { - var currentChoiceNumber = $(this).data('choiceNumber'); - if (currentChoiceNumber < result) { - result = currentChoiceNumber; - } - }); - return result; - }*/ + getAllChoices(containerId).each(function () { + var currentChoiceNumber = $(this).data('choiceNumber'); + if (currentChoiceNumber < result) { + result = currentChoiceNumber; + } + }); + return result; +} function getLastChoice(containerId) { var result = 0; @@ -330,13 +330,14 @@ return $("div[id^='" + containerId + "_']"); } -function prepareChoices(containerId) { +function prepareChoices(containerId, choicePrefix) { getAllChoices(containerId).each(function (index) { var choice = $("#" + containerId + "_" + index); choice.data('choiceType', containerId); choice.data('choiceNumber', index); + choice.data('choicePrefix', choicePrefix); }); if (containerId == 'choicesDATE') { @@ -355,8 +356,8 @@ function updateUpdownActions(containerId) { -// var firstChoice = getFirstChoice(containerId); -// var lastChoice = getLastChoice(containerId); + var firstChoice = getFirstChoice(containerId); + var lastChoice = getLastChoice(containerId); getAllChoices(containerId).each(function (index) { @@ -365,28 +366,28 @@ var labelWidget = $('#' + containerId + "_label_" + currentChoiceNumber); labelWidget.html(datas['choiceText'] + ' ' + (index + 1)); - /*var upWidget = $('#' + containerId + "_up_" + currentChoiceNumber); - if (firstChoice == currentChoiceNumber) { - // hide up - upWidget.addClass('hidden'); - } else { - //show up - upWidget.removeClass('hidden'); - } + var upWidget = $('#' + containerId + "_up_" + currentChoiceNumber); + if (firstChoice == currentChoiceNumber) { + // hide up + upWidget.addClass('hidden'); + } else { + //show up + upWidget.removeClass('hidden'); + } - var downWidget = $('#' + containerId + "_down_" + currentChoiceNumber); - if (lastChoice == currentChoiceNumber) { - // hide down - downWidget.addClass('hidden'); - } else { - //show down - downWidget.removeClass('hidden'); - }*/ + var downWidget = $('#' + containerId + "_down_" + currentChoiceNumber); + if (lastChoice == currentChoiceNumber) { + // hide down + downWidget.addClass('hidden'); + } else { + //show down + downWidget.removeClass('hidden'); + } }); } -function loadChoice(containerId, url, choiceNumber, nbChoices, tokenId) { +function loadChoice(containerId, choicePrefix, url, choiceNumber, nbChoices, tokenId) { if (choiceNumber == -1) { // to add a new choice @@ -407,6 +408,7 @@ var choice = $("#" + containerId + "_" + choiceNumber); choice.data('choiceType', containerId); choice.data('choiceNumber', choiceNumber); + choice.data('choicePrefix', choicePrefix); if (choiceNumber == nbChoices) { updateUpdownActions(containerId); @@ -426,7 +428,7 @@ function addTextChoice(choiceNumber, nbChoices, tokenId) { loadChoice( - 'choicesTEXT', + 'choicesTEXT', 'textChoice_', datas['displayTextChoiceUrl'], choiceNumber, nbChoices, tokenId ); @@ -434,14 +436,14 @@ function addDateChoice(choiceNumber, nbChoices, tokenId) { loadChoice( - 'choicesDATE', + 'choicesDATE', 'dateChoice_', datas['displayDateChoiceUrl'], choiceNumber, nbChoices, tokenId ); } function addImageChoice(choiceNumber, nbChoices, tokenId) { - loadChoice('choicesIMAGE', + loadChoice('choicesIMAGE', 'imageChoice_', datas['displayImageChoiceUrl'], choiceNumber, nbChoices, tokenId ); @@ -467,32 +469,65 @@ return false; } -/*function upChoice(choiceId) { - var choice = $('#' + choiceId); - var containerId = choice.data('choiceType'); - var choiceNumber = choice.data('choiceNumber'); - console.info("will up [" + containerId + "-" + choiceNumber + "]"); - updateUpdownActions(containerId); - return false; - } +function upChoice(choiceId) { + var choice = $('#' + choiceId); + var containerId = choice.data('choiceType'); + var choicePrefix = choice.data('choicePrefix'); + var choiceNumber = choice.data('choiceNumber'); + var newChoiceNumber = (choiceNumber - 1); - function downChoice(choiceId) { - var choice = $('#' + choiceId); - var containerId = choice.data('choiceType'); - var choiceNumber = choice.data('choiceNumber'); - console.info("will down [" + containerId + "-" + choiceNumber + "]"); - updateUpdownActions(containerId); - return false; - }*/ + return switchChoices(containerId, choicePrefix, choiceNumber, newChoiceNumber); +} +function downChoice(choiceId) { + var choice = $('#' + choiceId); + var containerId = choice.data('choiceType'); + var choicePrefix = choice.data('choicePrefix'); + var choiceNumber = choice.data('choiceNumber'); + var newChoiceNumber = (choiceNumber + 1); + + return switchChoices(containerId, choicePrefix, choiceNumber, newChoiceNumber); +} + +function switchChoices(containerId, choicePrefix, choiceNumber, newChoiceNumber) { + + console.info("will switch (" + choicePrefix + ") [" + choiceNumber + + "] to [" + newChoiceNumber + "]"); + + // change topiaId + switchValue(choicePrefix, choiceNumber, newChoiceNumber, '.topiaId'); + // change description + switchValue(choicePrefix, choiceNumber, newChoiceNumber, '.description'); + + // change name + switchValue(choicePrefix, choiceNumber, newChoiceNumber, '.name'); + + if ('imageChoice_' == choicePrefix) { + + // change location + switchValue(choicePrefix, choiceNumber, newChoiceNumber, '.location'); + } + return false; +} + +function switchValue(choicePrefix, choiceNumber, newChoiceNumber, suffix) { + var choiceTI = $('[name="' + choicePrefix + choiceNumber + suffix + '"]'); + var choiceTIVal = choiceTI.val(); + var newChoiceTI = $('[name="' + choicePrefix + newChoiceNumber + suffix + '"]'); + var newChoiceTIVal = newChoiceTI.val(); + console.info("switch " + choiceTIVal + " to " + newChoiceTIVal); + choiceTI.val(newChoiceTIVal); + newChoiceTI.val(choiceTIVal); +} + function confirmClose() { - $('.ui-dialog-title').html(datas['confirmCloseTitle']) - var dialog = $("#confirmDialog"); - var url = datas['confirmCloseUrl'] + '?' - + $.param({redirectUrl:datas['confirmCloseRedirectUrl']}); - dialog.load(url); - dialog.dialog('open'); - return false; + $('.ui-dialog-title').html(datas['confirmCloseTitle']) + var dialog = $("#confirmDialog"); + var url = datas['confirmCloseUrl'] + '?' + + $.param({redirectUrl:datas['confirmCloseRedirectUrl']}); + dialog.load(url); + dialog.dialog('open'); + return false; } jQuery(document).ready(function () { @@ -575,9 +610,9 @@ // before loading all choices let's hide everything, it will be shown later $('.choices').addClass('hidden'); - prepareChoices('choicesTEXT'); - prepareChoices('choicesDATE'); - prepareChoices('choicesIMAGE'); + prepareChoices('choicesTEXT', 'textChoice_'); + prepareChoices('choicesDATE', 'dateChoice_'); + prepareChoices('choicesIMAGE', 'imageChoice_'); prepareVotingLists('votingListRESTRICTED'); prepareVotingLists('votingListGROUP'); @@ -589,7 +624,5 @@ changePollType(datas['pollType']); - $('.tooltip').tipTip({ - defaultPosition : 'top' - }); + $('.tooltip').tipTip({ defaultPosition:'top' }); }); \ No newline at end of file
participants (1)
-
tchemit@users.chorem.org