argoyle / tapestry-tagselect

Tapestry-tagselect is a select component for Tapestry 5 similar to the version selector in recent JIRA-versions.
Other
12 stars 2 forks source link

Error javascript #8

Closed tnodev closed 12 years ago

tnodev commented 13 years ago

Hello,

I am using Tapestry 5.2.6, Linux Ubuntu, Firefox and I try to use tagselect but, I have a problem.

Here the js error :

Erreur : $("entite").tagSelect is undefined

the tapestry5 tml code :

<html t:type="clientlayout" title="literal:Accueil"
  xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"
  xmlns:p="tapestry:parameter">

<form t:type="form">
  <div t:type="tag/tagselect" t:value="tag" t:id="entite" t:minChars="2" t:vertical="true" style="width: 400px;"></div>
  <t:submit/>
</form>

</html>

and the tapestry5 java code :

@Persist
@Property
private String tag;

SelectModel onProvideCompletionsFromEntite(final String input) {
    return new SelectEntiteModel(input);
}

void onActivate(final EventContext context) {
    if (context.getCount() > 0) {
        final String tag = context.get(String.class, 0);
        this.tag = tag;
    }
}

Is it a bug, or I misunderstood the way to use it ?

Thanks, Thomas

argoyle commented 13 years ago

It sounds like you cloned the repository and built it yourself, right? There might be some small problems left in this version since it's not released yet. I'll try it out and see if I can reproduce your problem.

tnodev commented 13 years ago

That's right, I try to build the 1.4-SNAPSHOT version... So I wait for the 1.4 release.

argoyle commented 13 years ago

Or try to find what I have missed and fix it and then send a pull request? :-)

Did you make sure to clear out caches in the browser and so on just to make sure that you are running with the latest versions of javascript and CSS? I think I have tried it successfully with Firefox on Ubuntu but of course there may be some small bugs left.

tnodev commented 12 years ago

I clear the cache. Nothing change How can I help you to find the pb ?

argoyle commented 12 years ago

You could send me the generated HTML and the tagselect.js that the browser uses. Then I could investigate a bit.

tnodev commented 12 years ago

OK, here's the generated HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><script src="/client/assets/0.3/core/scriptaculous_1_8_2/prototype.js" type="text/javascript"></script><script src="/client/assets/0.3/core/scriptaculous_1_8_2/scriptaculous.js" type="text/javascript"></script><script src="/client/assets/0.3/core/scriptaculous_1_8_2/effects.js" type="text/javascript"></script><script src="/client/assets/0.3/core/tapestry.js" type="text/javascript"></script><script src="/client/assets/0.3/core/tapestry-messages.js" type="text/javascript"></script><script src="/client/assets/0.3/core/tapestry-console.js" type="text/javascript"></script><script src="/client/assets/0.3/atlog/mixins/confirm.js" type="text/javascript"></script><script src="/client/assets/0.3/core/scriptaculous_1_8_2/controls.js" type="text/javascript"></script><script src="/client/assets/0.3/tag/components/TagSelect.js" type="text/javascript"></script><link type="text/css" rel="stylesheet" href="/client/assets/0.3/core/default.css"></link><link type="text/css" rel="stylesheet" href="/client/assets/0.3/ctx/css/client.css"></link><link type="text/css" rel="stylesheet" href="/client/assets/0.3/atlog_appli/components/css/default.css"></link><link type="text/css" rel="stylesheet" href="/client/assets/0.3/core/tapestry-console.css"></link><link type="text/css" rel="stylesheet" href="/client/assets/0.3/tag/components/TagSelect.css"></link><title>Accueil</title><link href="/client/assets/0.3/ctx/favicon.ico" type="image/x-icon" rel="shortcut icon"></link><meta content="text/html; charset=UTF-8" http-equiv="content-type"></meta><meta content="Atlantic Log - Thomas Noirez" name="author"></meta><meta content="AtlanticLog Interface de gestion des clients" name="keywords"></meta><meta content="All text, graphics © 2011 by Atlantic Log" name="copyright"></meta><meta content="all" name="robots"></meta><meta content="Apache Tapestry Framework (version 5.2.4)" name="generator"></meta></head><body><div id="wrapper"><!-- start header --><div id="header"><div id="logo"><p id="logoTitle">
Interface de gestion des clients
</p></div></div><!-- end header --></div><!-- FORM starts here --><div id="menuwrapper"><div id="menu"><a class="linkmenu" href="/client/home"><img title="Home" class="imgTango" src="/client/assets/0.3/tango/32x32/actions/go-home.png"/>
Home
</a><a class="linkmenu" href="/client/recherche"><img title="Recherche" class="imgTango" src="/client/assets/0.3/tango/32x32/actions/system-search.png"/>
Recherche
</a><a class="linkmenu" href="/client/entite/list"><img title="Entité" class="imgTango" src="/client/assets/0.3/tango/32x32/apps/preferences-desktop-theme.png"/>

Entité
</a><a class="linkmenu" href="/client/contact/list"><img title="Contact" class="imgTango" src="/client/assets/0.3/tango/32x32/apps/system-users.png"/>
Contact
</a><a class="linkmenu" href="/client/export/list"><img title="Export" class="imgTango" src="/client/assets/0.3/tango/32x32/mimetypes/x-office-document-template.png"/>
Export
</a><a class="linkmenu" href="/client/param/list"><img title="Paramétre" class="imgTango" src="/client/assets/0.3/tango/32x32/categories/preferences-system.png"/>
Paramétre
</a></div><div id="logout"><a id="logout" href="/client/home.clientlayout.loginform.logout"><img title="Se déconnecter" class="imgTango" src="/client/assets/0.3/tango/32x32/actions/process-stop.png"/> Déconnexion </a></div></div><div id="page"><form onsubmit="javascript:return Tapestry.waitForPage(event);" action="/client/home.quicksearch" method="post" id="quickSearch"><div class="t-invisible"><input value="H4sIAAAAAAAAAFvzloG1nJeB2yM/N9UqNa8ksyS1uIjBNL8oXS+xIDE5I1WvJLEgtbikqNJULzm/KDUnM0kvKbE4Vc8xCSiYmFzilpmak6ISnFpSWqAaepj7oejxP0wMjD4M3Mn5eSVF+Tl+ibmpJQxCPlmJZYn6OYl56frBJUWZeenWFQUlDGwQGzEd4EiqAwKK8pNTi4uDS5NyM4uLM/PzDq9LMUn7Nu8cEwNDRQHcgmKQfAnQAge8FiTn5xbk5wFdU6wHNrEE0/yZwZ8kt25pcWZiYPJh4EjOyQSq9kwpZKgDez41JzUXKADyPFgI7FmI5SUMHBBGvAEA7GTpzn0BAAA=" name="t:formdata" type="hidden"></input></div><div style="width: 400px;" class="uiTokenizer"><div class="uiTokenizerCt uiTypeahead uiTokenizerSingle" id="entite-uiTokenizer-container"><input value="" name="entite-values" id="entite-values" type="hidden"></input><div class="wrap " id="entite-tags"><a onclick="$('entite').tagSelect.removeToken('u-tag-19763624958829', '')"></a><div onclick="new function() { $('entite').tagSelect.triggerCompletion(); }" class="uiTokenDropdown" style="display:block" id="entite-trigger"><div></div></div><input class="inputtext" id="entite" autocomplete="off" u:type="single" value="" type="text"></input></div><div class="uiTypeaheadView" id="entite:menu"></div></div></div><img id="entite_icon" class="t-error-icon t-invisible" alt="" src="/client/assets/0.3/core/spacer.gif"/><input id="submit" name="submit_0" type="submit"></input></form></div><div id="footer"><p id="legal"><a shape="rect" target="_blank" href="http://www.atlanticlog.org/">Atlantic Log</a>
- Interface de gestion des clients - version 0.3
</p></div><script type="text/javascript">Tapestry.DEBUG_ENABLED = true;
Tapestry.onDOMLoaded(function() {
Tapestry.init({
  "formEventManager" : [
    {
      "formId" : "quickSearch",
      "validate" : {
        "submit" : true,
        "blur" : true
      }
    }
  ]
});
new Confirm('logout', 'Confirmer la d\u00E9connexion !');
$('entite').tagSelect = new TagSelect('entite', '', new Ajax.Autocompleter('entite', 'entite:menu', 'http://localhost:8081/client/home.entite:autocomplete', {
  "minChars" : "2",
  "callback" : function(field, query) { return query + '&values=' + $('entite-values').value; },
  "updateElement" : function (span) { $('entite').tagSelect.addToken(span); },
  "frequency" : "0.0",
  "paramName" : "u:input"
}));
});
</script></body></html>

and the js

var TagSelect = Class.create({
    initialize: function(clientId, reset, autocompleter) {
        this.clientId = clientId;
        this.autocompleter = autocompleter;
        var uType = $(clientId).readAttribute('u:type'); 
        var focus = uType != 'single' ? '-uiTokenizer-container' : '-tags';

        var instance = this;
        Event.on($(clientId), 'keydown', this.onKeyDownT); 
        Event.on($(clientId), 'keyup', this.onKeyUpT);
        Event.on($(clientId + focus), 'click', function(){instance.onFocusT()});

        this.defaultInputSize();
        this.resetValue(reset); 
        this.showLabelT(uType);
    },

    onKeyUpT: function(event, field) {
        var instance = $(field.id).tagSelect;
        instance.onTabT(event, field);
        instance.updateInputSize(null);
    },

    onKeyDownT: function(event, field) {
        var type = $(field.id).readAttribute('u:type');

        var instance = $(field.id).tagSelect;
        if(type == 'multi') {
            instance.backSpace(event, field)
        }

        if(type == 'single') {
            instance.clearSingle(event, field.id); 
        }
    },

    onFocusT: function() {
        //Iterates page for all existing uiTypeaheadFocused classes.
        $$('.uiTypeaheadFocused').each(function(x) {
            //Removes all existing uiTypeaheadFocused classes.
            x.removeClassName('uiTypeaheadFocused'); 
        });   

        //Sets focus and adds uiTypeaheadFocused on selected component container.
        $(this.clientId + '-uiTokenizer-container').addClassName('uiTypeaheadFocused'); 
        $(this.clientId).activate();  
    },

    //Handles auto focus when using the tab key.
    onTabT: function(event, field) {
        if(event.keyCode == 9) {
            this.onFocusT(field.id);  
        }        
    },     

    showLabelT: function(uType) {
        // Set focus and blur handlers to hide and show 
        // labels with 'placeholder-label' class names.
        if($(this.clientId + '-uiTokenLabel')) {            

            // Hide any placeholder labels where value field has an initial value.
            if($(this.clientId + "-values").value != '' && uType != null) {
                this.toggleLabelT(true);
            }   

            var instance = this;

            // Set handlers to show and hide labels.
            $(this.clientId).onfocus = function () {
                //Hides label
                instance.toggleLabelT(true);
            };

            $(this.clientId).onblur = function () { 
                //checks hidden value field for values.
                //checks to ensure the vertical configuration is excluded.
                //checks to be sure no text is present in client value field.                
                if (($(instance.clientId + "-values").value == '' || uType == null) && this.value == '') {
                    //Show labels
                    instance.toggleLabelT(false);
                }
            };        
        }
    },

    toggleLabelT: function(hide) {
        //toggles label place holder
        $(this.clientId + '-uiTokenLabel').style.textIndent = (hide) ? '-10000px' : '0px';
    },

    addToken: function(span) {
        var single = ($(this.clientId).readAttribute('u:type') == 'single');

        if(single) {
            this.resetValue("");
        }

        if (this.addToValueField(span)) {
            if (single) {                
                this.addTagSingle(span);
                this.updateInputSize(false);
                $(this.clientId).focus();
            } else {
                this.addTag(span);  
                this.updateInputSize(true);
                this.clearField();
            }            
        }        
    },

    removeToken: function(tagId, value) {
        this.removeFromValueField(value);
        this.removeTag(tagId);
        this.updateInputSize(null);
        this.defaultInputSize();
    },    

    //handles backspace key
    backSpace: function(event, field) { 
        if (!field.value && event.keyCode == 8) {            
            event.stop();

            var tags = $(field.id + '-tags').childElements();
            if (tags.length > 0) {
                var tag = tags[tags.length - 1];
                var values = $A($(field.id + '-values').value.split(';'));
                var value = values[values.length - 1];
                this.removeToken(tag.id, value);
            } else {
                this.defaultInputSize();
            }

            return false;
        }
        return true;
    },     

    //Sets the default width of the input field to size 48 when no values are present.
    defaultInputSize: function() {
        var tags = $(this.clientId + '-tags').childElements();

        if (tags.length == 0) {
            $(this.clientId).writeAttribute('size', 48); 
        }

        this.updateDropdownHeight();   
    },

    //On keyup, updates input box sizes
    updateInputSize: function(reset) {  
        if(this.clientId != undefined) {
            //resets value to null after new tag has been added.
            if(reset) {
                this.clearField();
            }

            var length = $(this.clientId).value.length;

            $(this.clientId).writeAttribute('size', 1); 
            //this sets the width of the input field to the length of the field value.
            if(length >= 1) {
                $(this.clientId).writeAttribute('size', length); 
            }              

            this.updateDropdownHeight();   

        }
    },

    //Updates dropdown menu height
    updateDropdownHeight: function() {
        //checks to see if dropdown exist
        if($(this.clientId + '-trigger')) {
            var cssClass = $(this.clientId).readAttribute('u:type') != null ? '-uiTokenizer-container' : '-uiTypeahead';
            var dropheight = $(this.clientId + cssClass).getLayout().get('height') - 2;

            $(this.clientId + '-trigger').setStyle('height:' + dropheight + 'px');
        }
    },

    triggerCompletion: function(field) {
        setTimeout(this.autocompleter.activate.bind(this.autocompleter), 200);
    },

    addToValueField: function(span) {
        var valueField = $(this.clientId + '-values');
        var origin = valueField.value;
        if (origin.length == 0) {
            var values = new Array();
        } else {
            var values = $A(valueField.value.split(';'));
        }
        values.push(span.readAttribute('id'));
        var result = values.uniq().join(';');
        valueField.value = result;
        return origin != result;
    },

    removeFromValueField: function(value) {
        var valueField = $(this.clientId + '-values');
        var values = $A(valueField.value.split(';'));
        valueField.value = values.without(value).join(';');
    },

    addTag: function(span) { 
        //Gets label from nested span tag within autocomplete results
        var label = $(span.readAttribute('id') + '-label').innerHTML
        var tagsField = $(this.clientId + '-tags');
        tagsField.insert("<span title='"+ label + "' id='u-tag-" + TagSelect.tagId + "'>" + label + "<a onclick='$(\"" + this.clientId + "\").tagSelect.removeToken(\"u-tag-" + TagSelect.tagId++ + "\", \"" + span.readAttribute('id') + "\")'></a></span>");
    },

    addTagSingle: function(span) {
        $(this.clientId + '-tags').addClassName('selected');
        $(this.clientId).setValue(this.entityDecoder(span.firstChild.innerHTML));   
        $(this.clientId + '-tags').down(1).setAttribute('onClick', '$(\"' + this.clientId + '\").tagSelect.removeToken(\'u-tag-' + TagSelect.tagId++ +'\', \'' + span.readAttribute('id') + '\')');

        //Sets dropdown status to display none;
        this.dropdownStatus(this.clientId, false); 
    },

    //Decodes special characters in value labels.
    entityDecoder: function(str) {
        var ta = document.createElement("textarea");
        ta.innerHTML=str;
        return ta.value; 
    }, 

    removeTag: function(tagId) {
        if($(this.clientId).readAttribute('u:type') == 'single') {
            this.clearField();
            this.resetValue("");
            this.dropdownStatus(true);
            $(this.clientId + '-tags').removeClassName('selected'); 
        } else {
            var tag = $(tagId);
            tag.remove();
        }
    },

    //Clears input field values.
    clearField: function() {
        $(this.clientId).setValue("");        
    },   

    //Clears hidden field values.
    resetValue: function(reset) {
        $(this.clientId + '-values').setValue(reset);
    },    

    //clears single value when auto focus is present. Ignors custom ignor keys. 
    clearSingle: function(event) {
        if(!this.ignoreKeys(event) && $(this.clientId + '-tags').hasClassName('selected')) {
            $(this.clientId + '-tags').removeClassName('selected');
            //Sets hidden value to null.
            this.resetValue(""); 
            //Resets dropdown menu status to display block
            this.dropdownStatus(true);              
        }     
    },

    dropdownStatus: function(status) {
        var displayStatus = status ? "block" : "none";

        //Checks for existing drop down menu
        if($(this.clientId+ '-trigger')) {
            //If dropdown menu exist, sets menu container to display block.
            $(this.clientId+ '-trigger').setStyle({'display': displayStatus});
        }         
    },

    //handles keys that need to be ignored with clear single
    ignoreKeys: function(event) {
        var keyCodes = new Array(9, 16, 17, 18, 20, 33, 34, 35, 36, 45, 91, 92, 93, 144);        
        return keyCodes.indexOf(event.keyCode) != -1;
    }  
});

TagSelect.tagId = 0;
tnodev commented 12 years ago

You can try today on http://tno2.atlanticlog.org/client/home argoyle/argoyle

argoyle commented 12 years ago

Aaah...Great that I could try your site. I think I have found the problem. Your site gets an older version of the prototype javascript lib than I get with my test-app. The version you have does not contain the function Event.on and therefor the initialization breaks almost immediately.

Are you sure that you are really getting version 5.2.6 of the Tapestry-libraries?

Could it be that some mixin or something is based on an older version of Tapestry and you get the wrong version of the libraries?

tnodev commented 12 years ago

Cool, it works with Tapestry 5.2.6 !!! Thanks you very much

argoyle commented 12 years ago

No problem. Closing this issue then. :-)