[Suiviobsmer-commits] r166 - in trunk: suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/impl suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/mock suiviobsmer-business/src/main/xmi suiviobsmer-ui/src/main/java/fr/ifremer/suiviobsmer/ui/mixins suiviobsmer-ui/src/main/java/fr/ifremer/suiviobsmer/ui/pages suiviobsmer-ui/src/main/webapp suiviobsmer-ui/src/main/webapp/css suiviobsmer-ui/src/main/webapp/js
Author: fdesbois Date: 2010-01-06 13:33:55 +0000 (Wed, 06 Jan 2010) New Revision: 166 Added: trunk/suiviobsmer-ui/src/main/java/fr/ifremer/suiviobsmer/ui/mixins/ZoneUpdater.java trunk/suiviobsmer-ui/src/main/webapp/js/ZoneUpdater.js Modified: trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/impl/ServiceBoatImpl.java trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/impl/ServiceContactImpl.java trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/impl/ServiceSamplingImpl.java trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/mock/ServiceBoatMock.java trunk/suiviobsmer-business/src/main/xmi/suiviobsmer.zargo trunk/suiviobsmer-ui/src/main/java/fr/ifremer/suiviobsmer/ui/pages/Contacts.java trunk/suiviobsmer-ui/src/main/webapp/Contacts.tml trunk/suiviobsmer-ui/src/main/webapp/css/contacts.css Log: - Improve contact filters using ZoneUpdater for facade select - Add autocomplete for boat name field Modified: trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/impl/ServiceBoatImpl.java =================================================================== --- trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/impl/ServiceBoatImpl.java 2010-01-06 08:58:16 UTC (rev 165) +++ trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/impl/ServiceBoatImpl.java 2010-01-06 13:33:55 UTC (rev 166) @@ -542,4 +542,25 @@ // } return result; } + + @Override + public List<String> getBoatNamesStartWith(String input) throws SuiviObsmerException { + TopiaContext transaction = null; + List<String> results = new ArrayList<String>(); + try { + transaction = rootContext.beginTransaction(); + + input = StringUtils.upperCase(input); + + BoatDAO dao = SuiviObsmerModelDAOHelper.getBoatDAO(transaction); + + results = (List<String>)dao.createQuery().addDistinct().setSelect(Boat.NAME).add(Boat.NAME, Op.LIKE, input + "%").execute(); + + transaction.closeContext(); + } catch (Exception eee) { + SuiviObsmerContext.serviceException(transaction, + "Impossible de récupérer les navires avec un nom commencant par '" + input + "'", eee); + } + return results; + } } Modified: trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/impl/ServiceContactImpl.java =================================================================== --- trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/impl/ServiceContactImpl.java 2010-01-06 08:58:16 UTC (rev 165) +++ trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/impl/ServiceContactImpl.java 2010-01-06 13:33:55 UTC (rev 166) @@ -32,7 +32,6 @@ import fr.ifremer.suiviobsmer.SuiviObsmerContext; import fr.ifremer.suiviobsmer.bean.ContactState; import java.io.InputStream; -import org.nuiton.topia.TopiaException; import org.nuiton.topia.framework.TopiaQuery; import fr.ifremer.suiviobsmer.bean.states.ContactStateEnum; import fr.ifremer.suiviobsmer.bean.ContactFilter; @@ -45,7 +44,6 @@ import fr.ifremer.suiviobsmer.entity.ContactImpl; import fr.ifremer.suiviobsmer.entity.ElligibleBoat; import fr.ifremer.suiviobsmer.entity.FishingZone; -import fr.ifremer.suiviobsmer.entity.FishingZoneDAO; import fr.ifremer.suiviobsmer.entity.Profession; import fr.ifremer.suiviobsmer.entity.Program; import fr.ifremer.suiviobsmer.entity.SampleRow; @@ -66,6 +64,7 @@ import java.util.Map; import org.apache.commons.lang.StringUtils; import org.nuiton.topia.TopiaContext; +import org.nuiton.topia.framework.TopiaQuery.Op; import org.nuiton.topia.persistence.TopiaEntity; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -112,6 +111,10 @@ query.add("F.facadeName", filter.getFacadeName()).add("C.sampleRow IN elements(F.sampleRow)"); } + if (!StringUtils.isEmpty(filter.getBoatName())) { + query.add("C.boat.name", Op.LIKE, filter.getBoatName() + "%"); + } + if (!StringUtils.isEmpty(filter.getBoatDistrictCode())) { query.add("C.boat.districtCode", filter.getBoatDistrictCode()); } Modified: trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/impl/ServiceSamplingImpl.java =================================================================== --- trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/impl/ServiceSamplingImpl.java 2010-01-06 08:58:16 UTC (rev 165) +++ trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/impl/ServiceSamplingImpl.java 2010-01-06 13:33:55 UTC (rev 166) @@ -240,6 +240,8 @@ try { transaction = rootContext.beginTransaction(); + // TODO-FD20090106 add filters for facadeName and sectorName (in argument) for Boats and Contacts use + Date current = SuiviObsmerContext.getCurrentDate(); SampleRowDAO dao = SuiviObsmerModelDAOHelper.getSampleRowDAO(transaction); @@ -251,31 +253,6 @@ } results = query.addLoad(SampleRow.PROFESSION, SampleRow.PROGRAM).executeToEntityList(); - -// SampleRowDAO dao = SuiviObsmerModelDAOHelper.getSampleRowDAO(transaction); -// -// if (!user.getAdmin()) { -// if (log.isDebugEnabled()) { -// log.debug("User company : " + user.getCompany().getName()); -// } -// results = dao.findAllByCompany(user.getCompany()); -// } else { -// results = dao.findAll(); -// } -// -// Iterator<SampleRow> it = results.iterator(); -// while (it.hasNext()) { -// SampleRow row = it.next(); -// // Only rows which are not finished will be kept -// if (row.getProgram().isFinished()) { -// it.remove(); -// }/* else { -// // load data -// row.getProgram(); -// row.getCompany(); -// row.getProfession(); -// }*/ -// } transaction.closeContext(); } catch (Exception eee) { Modified: trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/mock/ServiceBoatMock.java =================================================================== --- trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/mock/ServiceBoatMock.java 2010-01-06 08:58:16 UTC (rev 165) +++ trunk/suiviobsmer-business/src/main/java/fr/ifremer/suiviobsmer/mock/ServiceBoatMock.java 2010-01-06 13:33:55 UTC (rev 166) @@ -252,4 +252,9 @@ throw new UnsupportedOperationException("Not supported yet."); } + @Override + public List<String> getBoatNamesStartWith(String input) throws SuiviObsmerException { + throw new UnsupportedOperationException("Not supported yet."); + } + } Modified: trunk/suiviobsmer-business/src/main/xmi/suiviobsmer.zargo =================================================================== (Binary files differ) Added: trunk/suiviobsmer-ui/src/main/java/fr/ifremer/suiviobsmer/ui/mixins/ZoneUpdater.java =================================================================== --- trunk/suiviobsmer-ui/src/main/java/fr/ifremer/suiviobsmer/ui/mixins/ZoneUpdater.java (rev 0) +++ trunk/suiviobsmer-ui/src/main/java/fr/ifremer/suiviobsmer/ui/mixins/ZoneUpdater.java 2010-01-06 13:33:55 UTC (rev 166) @@ -0,0 +1,99 @@ +/** + * *##% Bonzoms Web Interface + * Copyright (C) 2009 CodeLutin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. ##%* + */ +package fr.ifremer.suiviobsmer.ui.mixins; + +import org.apache.commons.lang.ArrayUtils; +import org.apache.tapestry5.BindingConstants; +import org.apache.tapestry5.ClientElement; +import org.apache.tapestry5.ComponentResources; +import org.apache.tapestry5.Link; +import org.apache.tapestry5.RenderSupport; +import org.apache.tapestry5.annotations.Environmental; +import org.apache.tapestry5.annotations.IncludeJavaScriptLibrary; +import org.apache.tapestry5.annotations.InjectContainer; +import org.apache.tapestry5.annotations.Parameter; +import org.apache.tapestry5.ioc.annotations.Inject; + +/** + * ZoneUpdater.java + * + * From http://tinybits.blogspot.com/2009/05/update-zone-on-any-client-side-event.ht... by ingesol + * + * @author ingesol + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author: fdesbois $ + */ + at IncludeJavaScriptLibrary("context:js/ZoneUpdater.js") +public class ZoneUpdater { + + public static final String PLACEHOLDER = "XXX"; + + @Inject + private ComponentResources resources; + + @Environmental + private RenderSupport renderSupport; + + @Parameter(defaultPrefix = BindingConstants.LITERAL) + private String clientEvent; + + @Parameter(defaultPrefix = BindingConstants.LITERAL, required = true) + private String event; + + @InjectContainer + private ClientElement element; + + @Parameter + private Object[] context; + + @Parameter(defaultPrefix = BindingConstants.LITERAL) + // To enable popups to fire events on this document, enter "document" here. + private String listeningElement; + + @Parameter(defaultPrefix = BindingConstants.LITERAL, required = true) + private String zone; + + protected Link createLink(Object[] context) { + + if (context == null) { + context = new Object[]{PLACEHOLDER}; + } else { + context = ArrayUtils.add(context, PLACEHOLDER); // To be replaced by javascript + } + + return resources.createEventLink(event, context); + + } + + void afterRender() { + String link = createLink(context).toAbsoluteURI(); + String elementId = element.getClientId(); + if (clientEvent == null) { + clientEvent = event; + } + + if (listeningElement == null) { + listeningElement = "$('" + elementId + "')"; + } + renderSupport.addScript("new ZoneUpdater('%s', %s, '%s', '%s', '%s', '%s')", elementId, listeningElement, clientEvent, link, zone, PLACEHOLDER); + + } +} Property changes on: trunk/suiviobsmer-ui/src/main/java/fr/ifremer/suiviobsmer/ui/mixins/ZoneUpdater.java ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL" Modified: trunk/suiviobsmer-ui/src/main/java/fr/ifremer/suiviobsmer/ui/pages/Contacts.java =================================================================== --- trunk/suiviobsmer-ui/src/main/java/fr/ifremer/suiviobsmer/ui/pages/Contacts.java 2010-01-06 08:58:16 UTC (rev 165) +++ trunk/suiviobsmer-ui/src/main/java/fr/ifremer/suiviobsmer/ui/pages/Contacts.java 2010-01-06 13:33:55 UTC (rev 166) @@ -64,6 +64,7 @@ import org.apache.tapestry5.annotations.SessionState; import org.apache.tapestry5.beaneditor.BeanModel; import org.apache.tapestry5.corelib.components.Form; +import org.apache.tapestry5.corelib.components.Zone; import org.apache.tapestry5.internal.OptionModelImpl; import org.apache.tapestry5.internal.SelectModelImpl; import org.apache.tapestry5.ioc.annotations.Inject; @@ -126,6 +127,12 @@ @Persist private ContactFilter contactFilter; + @InjectComponent + private Zone filtersZone; + + @InjectComponent + private Zone importExportZone; + @Persist private GenericSelectModel<SampleRow> sampleRowSelectModel; @@ -141,6 +148,10 @@ @Persist private SelectModel sectorSelectModel; + @Property + @Persist("flash") + private boolean filtersVisible; + private boolean reset; public ContactFilter getContactFilter() throws SuiviObsmerException { @@ -193,6 +204,41 @@ return sampleRowSelectModel; } + String[] onProvideCompletionsFromBoatName(String input) throws SuiviObsmerException { + if (log.isInfoEnabled()) { + log.info("BUSINESS REQUEST [getBoatNamesStartWith]"); + } + List<String> results = serviceBoat.getBoatNamesStartWith(input); + return results.toArray(new String[0]); + } + + void onSuccessFromSearchBoat() { + + } + + Object onActionFromShowFilters() { + contactFilter = null; + return filtersZone.getBody(); + } + + Object onActionFromShowImportExport() { + return importExportZone.getBody(); + } + + @Log + public Object onChangeFromFacadeName(String value) throws SuiviObsmerException { + if (!StringUtils.isEmpty(value)) { + // Reset contactFilter to avoid strange behavior (cause of no form submit) + contactFilter = null; + // set facadeName selected in contactFilter + getContactFilter().setFacadeName(value); + // Reset sectors to use facadeName selected + sectorSelectModel = null; + return filtersZone.getBody(); + } + return null; + } + void onSelectedFromReset() { reset = true; } @@ -200,6 +246,8 @@ void onSuccessFromFiltersForm() { if (reset) { contactFilter = null; + } else { + filtersVisible = true; } } Modified: trunk/suiviobsmer-ui/src/main/webapp/Contacts.tml =================================================================== --- trunk/suiviobsmer-ui/src/main/webapp/Contacts.tml 2010-01-06 08:58:16 UTC (rev 165) +++ trunk/suiviobsmer-ui/src/main/webapp/Contacts.tml 2010-01-06 13:33:55 UTC (rev 166) @@ -3,9 +3,22 @@ xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd" xmlns:p="tapestry:parameter"> <!--t:include="creationDate, lastState, boatName, boatImmatriculation, boatDistrictCode, beginTideDate, endTideDate, nbObservants, mammals, editDate, comment, validation"--> -<div t:type="zone" class="so-filters" t:id="filtersZone" t:update="show" id="so-contacts-filters"> +<div id="so-contacts-search"> + <form t:type="form" t:id="searchBoat"> + <input t:type="textfield" t:id="boatName" value="contactFilter.boatName" t:mixins="Autocomplete"/> + <input t:type="submit" class="ico search-32px" t:id="execSearchBoat" value="Search" /> + </form> + <a t:type="actionlink" t:id="showFilters" t:zone="so-contacts-filters"> + recherche avancée + </a> + <a t:type="actionlink" t:id="showImportExport" t:zone="so-contacts-importexport"> + import/export + </a> +</div> + +<div t:type="zone" class="so-filters" t:id="filtersZone" t:update="show" t:visible="prop:filtersVisible" id="so-contacts-filters"> <fieldset> - <legend>Filtres de recherche</legend> + <legend>Recherche avancée</legend> <!--<div class="aright"> <t:if t:test="filtersHidden"> <a t:type="actionlink" t:id="showFilters" t:zone="so-contacts-filters"> @@ -35,15 +48,16 @@ </p:boat> <p:facadeName> <t:label t:for="facadeName" /> - <select t:type="select" t:id="facadeName" t:model="facadeSelectModel" value="contactFilter.facadeName" /> + <input t:type="select" t:id="facadeName" t:model="facadeSelectModel" value="contactFilter.facadeName" + t:mixins="zoneUpdater" t:event="change" t:zone="so-contacts-filters"/> </p:facadeName> <p:sectorName> <t:label t:for="sectorName" /> - <select t:type="select" t:id="sectorName" t:model="sectorSelectModel" value="contactFilter.sectorName" /> + <input t:type="select" t:id="sectorName" t:model="sectorSelectModel" value="contactFilter.sectorName" /> </p:sectorName> <p:sampleRow> <t:label t:for="sampleRow" /> - <select t:type="select" t:id="sampleRow" t:model="sampleRowSelectModel" value="sampleRowId" /> + <input t:type="select" t:id="sampleRow" t:model="sampleRowSelectModel" value="sampleRowId" /> </p:sampleRow> <p:observer> N/A @@ -73,15 +87,17 @@ <!--</div>--> </fieldset> </div> -<form t:type="form" t:id="importContacts"> - <t:errors /> - <t:label for="contactsCsvFile" /> : - <input t:type="upload" t:id="contactsCsvFile" t:validate="required" /> - <input t:type="submit" class="ico import" value="OK" title="Importer une liste de contacts (format CSV)" /> -</form> -<a t:type="actionlink" t:id="exportShowContacts"> - EXPORT -</a> +<div t:type="zone" t:id="importExportZone" t:update="show" t:visible="false" id="so-contacts-importexport"> + <form t:type="form" t:id="importContacts"> + <t:errors /> + <t:label for="contactsCsvFile" /> : + <input t:type="upload" t:id="contactsCsvFile" t:validate="required" /> + <input t:type="submit" class="ico import" value="OK" title="Importer une liste de contacts (format CSV)" /> + </form> + <a t:type="actionlink" t:id="exportShowContacts"> + EXPORT + </a> +</div> <t:zone t:id="gridZone" t:update="show"> <form t:type="form" t:id="contactsForm" t:zone="gridZone"> <t:errors id="so-contact-form-errors" t:banner="message:contactsForm-errors-banner"/> Modified: trunk/suiviobsmer-ui/src/main/webapp/css/contacts.css =================================================================== --- trunk/suiviobsmer-ui/src/main/webapp/css/contacts.css 2010-01-06 08:58:16 UTC (rev 165) +++ trunk/suiviobsmer-ui/src/main/webapp/css/contacts.css 2010-01-06 13:33:55 UTC (rev 166) @@ -14,7 +14,7 @@ font-size: 0.8em; } -/* FORM FOR NEW CONTACT */ +/* FORM FOR NEW CONTACT fieldset#so-contacts-new { padding: 10px; margin-bottom: 10px; @@ -22,6 +22,11 @@ fieldset#so-contacts-new div.content { margin-bottom: 5px; +}*/ + +/* FILTERS */ +div.t-autocomplete-menu ul { + background-color: #19a28d; } /* TABLE OF CONTACTS */ Added: trunk/suiviobsmer-ui/src/main/webapp/js/ZoneUpdater.js =================================================================== --- trunk/suiviobsmer-ui/src/main/webapp/js/ZoneUpdater.js (rev 0) +++ trunk/suiviobsmer-ui/src/main/webapp/js/ZoneUpdater.js 2010-01-06 13:33:55 UTC (rev 166) @@ -0,0 +1,103 @@ +var ZoneUpdater = Class.create(); + +ZoneUpdater.prototype = { + + initialize: function(zoneElementId, listeningElement, event, link, zone, placeholder) { + + this.zoneElement = $(zoneElementId); + + this.event = event; + + this.link = link; + + this.placeholder = placeholder; + + $T(this.zoneElement).zoneId = zone; + + listeningElement.observe(this.event, this.updateZone.bindAsEventListener(this)); + + }, + + updateZone: function(event) { + + var zoneObject = Tapestry.findZoneManager(this.zoneElement); + + if ( !zoneObject ) return; + + var param; + + if (this.zoneElement.value) { + + param = this.zoneElement.value; + + } + + if (!param) param = ' '; + + param = this.encodeForUrl(param); + + var updatedLink = this.link.gsub(this.placeholder, param); + + zoneObject.updateFromURL(updatedLink); + + }, + + encodeForUrl: function(string) { + + /** + + * See equanda.js for updated version of this + + */ + + string = string.replace(/\r\n/g,"\n"); + + var res = ""; + + for (var n = 0; n < string.length; n++) + + { + + var c = string.charCodeAt( n ); + + if ( '$' == string.charAt( n ) ) + + { + + res += '$$'; + + } + + else if ( this.inRange( c, "AZ" ) || this.inRange( c, "az" ) || this.inRange( c, "09" ) || this.inRange( c, ".." ) ) + + { + + res += string.charAt( n ) + + } + + else + + { + + var tmp = c.toString(16); + + while ( tmp.length < 4 ) tmp = "0" + tmp; + + res += '$' + tmp; + + } + + } + + return res; + + }, + + inRange: function(code, range) { + + return code >= range.charCodeAt( 0 ) && code <= range.charCodeAt( 1 ); + + } + +} \ No newline at end of file
participants (1)
-
fdesbois@users.labs.libre-entreprise.org