alex1er
22 Feb 2007, 7:05 AM
Ok
So there is my code.
To produce the bug, click on an element list then press CTRL down and click one the same item.
You'll see that the item has a style that i never set.
Then if you click on the div of the list, this style will be removed.
So i don't know why.
Thanks
list.js
/**
* @constructor
* Creation d'une nouvelle Liste.
* @param {Object} config configuration options
*/
List =
function ( config )
{
this.init ( config );
};
/**
* _div
* x
* y
* width
* height
*
*/
List.prototype =
{
/**
* Identifiant du div container.
* @type String
*/
_id : null,
/**
* Objet Element de la yui-ext
* @type YAHOO.ext.Element
*/
_element : null,
/**
* Collection des Elements (html) de la liste.
* @type YAHOO.ext.util.MixedCollection
*
*/
_mapElement : null,
/**
* Collection des elements ajoutes a la liste.
* @type YAHOO.ext.util.MixedCollection
*/
_mapObject : null,
/**
* Collection des elements ajoutes a la liste.
* @type YAHOO.ext.util.MixedCollection
*/
_mapEvent : null,
/**
* Collection des elements selectionne dans la liste.
* @type YAHOO.ext.util.MixedCollection
*/
_mapSelected : null,
/**
* Index courant séléctionné.
* @type int
*/
_selectedIndex : null,
/**
* Les items sont-ils séléctionnables.
* @type boolean
*/
_selectable : false,
_multiselectable : false,
/**
* Fonction appellée lors du click sur un item de la liste.
* @type handler
*/
_onclick : null,
/**
* Doit on mettre en surbrillance l'item lors de son survol par le pointeur de la souris
* @type boolean
*/
_highlightOnmouseover : false,
/**
* Tableau de fonctions associées aux tools de chaque item de la liste.
* On peut lui passer des paramères grace à la propriété _onclickArg de l'objet {ObjListe} que l'on ajoute.
* @see #_onclickArg
* @type handler []
*/
_handlers : null,
/**
* Fonction appellée par le constructeur
* @private
* @param {Object} config
* @return {void}
*/
init : function ( config )
{
ApplyConfig ( config, this );
this._element = YAHOO.ext.Element.get ( this._id );
if ( this._element == null )
{
this._element = YAHOO.ext.DomHelper.append ( document.body, {tag:'div', id:this._id}, true );
}
this._element.setAbsolutePositioned();
if ( this._css == null )
{
this._element.setBounds ( this.x, this.y, this.width, this.height );
}
else
{
this._element.addClass ( this._css );
}
this._element.addClass ( this._class );
this._mapObject = new YAHOO.ext.util.MixedCollection ( true );
this._mapObject.getKey = function ( el )
{
return el._libelle;
}
this._mapElement = new YAHOO.ext.util.MixedCollection ( true );
this._mapElement.getKey = function ( el )
{
return el.dom.getAttribute ( "id" );
//return el.dom.getAttribute ( "indice" );
}
this._mapSelected = new YAHOO.ext.util.MixedCollection ( true );
this._mapSelected.getKey = function ( el )
{
return el.dom.getAttribute ( "id" );
//return el.dom.getAttribute ( "indice" );
}
this._mapEvent = new YAHOO.ext.util.MixedCollection ( true );
this._selectedIndex = -1;
//console.log ("start :" + this._element.dom.childNodes.length);
},
/**
* Ajout d'un item à la liste.
*
* @param {ObjListe} object L'objet à ajouter à la liste.
* Soit une chaine de caractère soit un objet de type {ObjListe}.
* @return {void}
*/
Add : function ( object )
{
if ( typeof object != "object" )
{
object = new ObjListe ({_libelle:object});
}
this._mapObject.add ( object );
this.PaintOneObject ( object );
},
/**
* Suppression de l'item dont le texte est passé en paramètre.
* @return {void} *
* @param {String} item Le libellede l'item à supprimer.
*/
Remove : function ( item )
{
this._mapObject.removeKey ( item );
this.Repaint ();
},
/**
* Suppression de tous les éléments de la liste.
* @return {void}
*/
Clear : function ()
{
this._element.update ("");
this._mapElement.clear ();
this._mapObject.clear ();
},
/**
* Redessine tous les items de la liste à la suite d'une suppression d'élément.
* @private
* @return {void}
*/
Repaint : function ()
{
this._element.update ("");
this._mapElement.clear ();
for ( var i=0; i<this._mapObject.getCount(); i++ )
{
var obj = this._mapObject.items [i];
this.PaintOneObject ( obj );
}
},
/**
* Dessin d'un item de la liste. Cette fonction est appellée lors de l'ajout d'un item.
* @see #Add
* @private
* @param {Object} obj
*/
PaintOneObject : function ( obj )
{
console.warn ( "List::PaintOneObject" );
var val = "";
if ( typeof obj == "object" )
{
val = obj._libelle;
}
else
{
val = obj;
}
var html = "";
var classe = "";
var style = "";
//Couleurs alternées.
if ( this._mapElement.getCount() % 2 == 0 )
{
classe = "paire";
}
else
{
classe = "impaire";
}
//Class du dernier item
for ( var ind=0; ind<this._mapElement.getCount(); ind++ )
{
if ( ind != this._mapObject.getCount () -1 )
{
style = "border-bottom : 0px solid black;";
this._mapElement.get ( ind ).setStyle ( "border-bottom", "0px" );
}
}
//Dessin du trait bas du dernier élément.
if ( this._mapElement.getCount() == this._mapObject.getCount () -1 )
{
style = "border-bottom : 1px solid black;";
}
var dh = YAHOO.ext.DomHelper;
var divItem = dh.append ( this._element.dom, {tag:'div', style:style}, true );
divItem.addClass ( "cell" );
divItem.addClass ( classe );//OK
style = "width:100%;";
var divTable = dh.append ( divItem.dom, { tag:'table', style:style}, true );
divTable.dom.setAttribute ( "cellpadding", "0" );
divTable.dom.setAttribute ( "cellspacing", "0" );//OK
var divTBody = dh.append ( divTable.dom, {tag:'tbody'}, true );
var divTr = dh.append ( divTBody.dom, { tag:'tr' }, true );//OK
style = "text-align:left;";//z-index:-10;
var divTd = dh.append ( divTr.dom, { tag:'td', style:style, indice:this._mapElement.getCount(), html:val }, true );//OK
if ( obj._configTool != null )
{
style = "width:" + (obj._configTool.length * 22) + "px;text-align:right;";
var tdTools = dh.append ( divTr.dom, { tag:'td', style:style }, true );
style = "text-align:right;font-size:2px;";
var tableTool = dh.append ( tdTools.dom, { tag:'table', style:style}, true );
tableTool.dom.setAttribute ( "cellpadding", "0" );
tableTool.dom.setAttribute ( "cellspacing", "0" );
var tbodyTool = dh.append ( tableTool.dom, {tag:'tbody'}, true );
var trTool = dh.append ( tbodyTool.dom, {tag:'tr'}, true );
for ( var ind=0; ind<obj._configTool.length; ind++ )
{
var tdTool = dh.append ( trTool.dom, {tag:'td'}, true );
tdTool.dom.setAttribute ( "indice", this._mapElement.getCount() );
//console.log ("_configTool : %o", obj._configTool [ind]);
if ( obj._configTool [ind]._alt != null )
{
//console.log (obj._configTool [ind]._alt);
//tdTool.dom.setAttribute ( "alt", obj._configTool [ind]._alt );
new YAHOO.widget.Tooltip("tt"+this._mapElement.getCount()+"_"+ind,
{ context:tdTool.dom,
text:obj._configTool [ind]._alt });
}
tdTool.addClass ( obj._configTool [ind].css );
if ( obj._configTool [ind]._arguments != null )
{
for ( var arg=0; arg<obj._configTool [ind]._arguments.length; arg++ )
{
tdTool.dom.setAttribute ( "arg_"+arg, obj._configTool [ind]._arguments [arg] );
}
}
//tdTool.dom.setAttribute ("handler", obj._configTool [ind].handler);
var _scope = divItem;
if ( obj._configTool [ind].scope != null )
{
_scope = obj._configTool [ind].scope;
//console.log ("scope : %o", _scope);
}
//
tdTool.on ( "click", this._handlers [ ind ].createDelegate( _scope, obj._configTool [ind]._arguments ), _scope );
//tdTool.on ( "click", this._handlers [ ind ].createCallback( _scope, obj._configTool [ind]._arguments ), _scope );
//myElement.on("click", myObject.clickHandler.createCallback("foo", {bar:"bletch"}), myObject)
}
}
divItem.dom.setAttribute ( "indice", this._mapElement.getCount() );
if ( this._highlightOnmouseover == true )
{
divItem.addClassOnOver ( "mouseover" );
}
divItem.on ("click", this.ClickHandler, this );
for ( var j=0; j<this._mapEvent.getCount(); j++ )
{
//console.log ("evt");
var evt = this._mapEvent.get ( j );
divItem.on ( evt._name,
function()
{
evt._handler.apply ( evt._scope || this, [this] || []);
},
divItem );
}
divItem.dom.setAttribute ( "_value", this._mapObject.get ( this._mapElement.getCount() )._libelle );
//Implementation du OnClick sur l'item.
if ( this._onclick != null && obj._onclickArg != null )
{
divItem.on ( "click", this._onclick.createDelegate( window, obj._onclickArg ), window );
}
this._mapElement.add ( divItem );
},
//Fonction interne qui met a jour sur le click la variable selectedIndex.
//On peut lui coder d'autre chose
/**
* @private
* @param {Object} evt
*/
ClickHandler : function ( evt )
{
console.log ( evt );
var indice = evt.target.getAttribute ( "indice" );
var element = this._mapElement.get ( indice );
console.log ( element );
//On est en mode sélection.
if ( this._selectable == true || this._multiselectable == true )
{
//On supprime toutes les classes selected
this._mapElement.each ( this.RemoveClassSelected, this );
//Mode selection simple
if ( this._selectable == true && this._multiselectable == false )
{
this._mapSelected.clear ();
this._mapSelected.add ( element );
element.addClass ( "selected" );
this._selectedIndex = indice;
}
//Mode selection multiple
if ( this._multiselectable == true )
{
//Touche CTRL non enfoncée
if ( evt.ctrlKey == false )
{
this._mapSelected.clear ();
this._mapSelected.add ( element );
element.addClass ( "selected" );
this._selectedIndex = indice;
}
//Touche CTRL enfoncée
else
{
if ( this._mapSelected.contains ( element ) )
{
console.log ( "avant : %d", this._mapSelected.getCount() );
this._mapSelected.remove ( element );
console.log ( "apres : %d", this._mapSelected.getCount() );
}
else
{
this._mapSelected.add ( element );
}
this._mapSelected.each ( this.AddClassSelected, this );
}
}
}
},
/**
* Ajout de l'item de la liste de son état selected.
* @private
* @param {YAHOO.ext.Element} el L'element de la liste pour lequel on veut ajouter le style selectionne
*/
AddClassSelected : function ( el )
{
el.addClass ( "selected" );
},
/**
* Suppression de l'item de la liste de son état selected.
* @private
* @param {YAHOO.ext.Element} el L'element de la liste pour lequel on veut supprimer le style selectionne
*/
RemoveClassSelected : function ( el )
{
el.removeClass ( "selected" );
},
/**
* Retourne l'index de l'élément sélectionné seulement si la liste est selectable.
* @return {int} L'index sélectionné.
*/
GetSelectedIndex : function ()
{
if ( this._selectable == true && this._mapSelected.getCount () == 1 )
{
return parseInt ( this._selectedIndex );
}
return -1;
},
/**
* Retourne les indexes des éléments sélectionnés seulement si la liste est mulitselectable.
* @return {int[]} Le tableau des indices selectionnes
*/
GetSelectedIndexes : function ()
{
var arrInd = [];
if ( this._multiselectable == true )
{
for ( var i=0; i<this._mapSelected.getCount (); i++ )
{
var obj = this._mapSelected.items [i];
var indice = obj.dom.getAttribute ( "indice" );
arrInd.push ( parseInt( indice ) );
}
arrInd.sort ();
return arrInd;
}
return arrInd;
},
/**
* Sélectionne l'index passé en paramètre.
* @param {Object} index L'index à sélectionner.
*/
SetSelectedIndex : function( index )
{
console.error ( "List::SetSelectedIndex -> Tester selectable et multiselectable et ajouter à mapSelect" );
this._selectedIndex = index;
},
/**
* Permet d'ajouter à chacun des items de la liste un évenement qui sera appellé sans paramètres.
* Pour passer des paramètres à un handler sur un item de la liste, utiliser la propriété _onclick.
* @see #_onclick
* @param {Object} eventName Le type de l'evenement.
* @param {Object} handler La fonction a appellée lors de l'évenement.
* @param {Object} scope Le scope à partir duquel le handler est appellé.
*/
on : function ( eventName, handler, scope )
{
var evt = new ObjEvent ( {_name:eventName,_handler:handler, _scope:scope} );
this._mapEvent.add ( eventName, evt );
/*for ( var i=0; i<this._mapElement.getCount(); i++ )
{
var elem = this._mapElement.get ( i );
elem.on ( eventName,
function()
{
handler.apply ( scope || this, [this] || []);
},
elem );
}*/
this.Paint ();
}
};
ObjEvent = function ( config )
{
this.init ( config );
};
ObjEvent.prototype=
{
_name : null,
_scope : null,
_handler : null,
_params : null,
init : function ( config )
{
ApplyConfig ( config, this );
}
}
//configTool = [{ handler : null, css : null, argument : null }];
/**
*
* @constructor
* Création d'un nouvel item de Liste.
* L'utilité de cet objet est d'associer à chaque item un outil (tool) représenté par un icon qui permet d'exécuter une fonction et de lui passer des arguments.
*
* @param {Object} config configuration options
*/
ObjListe = function ( config )
{
this.init ( config );
}
ObjListe.prototype =
{
/**
* Le libellé de l'item qui apparaitra dans la liste.
* C'est le seul membre obligatoire de cet Objet.
* Toutefois, si vous n'avez qu'une chaine à ajouter à la liste, ce n'est pas la peine d'utiliser cet objet.
* @see #List.Add
* @type String
*/
_libelle : null,
/**
* Tableau contenant chacun des tools associés à l'item courant.
Il contient son apparence, un handler, des arguments.
* @type Object []
*/
_configTool : null,
/**
* Tableau des arguments qui seront passés à la fonction _onclick de l'objet List.
* @see #List
* @type String []
*/
_onclickArg : null,
init : function ( config )
{
ApplyConfig ( config, this );
}
}
index.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>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"/>
<title>LISTES</title>
<link href="./js-lib/yui-ext/resources/css/basic-dialog.css" type="text/css" rel="stylesheet">
<link href="./js-lib/yui-ext/resources/css/button.css" type="text/css" rel="stylesheet">
<link href="./js-lib/yui-ext/resources/css/resizable.css" rel="stylesheet" type="text/css" />
<link href="./css/list.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="./js-lib/yui/build/yahoo/yahoo-min.js"></script>
<script type="text/javascript" src="./js-lib/yui/build/event/event-min.js"></script>
<script type="text/javascript" src="./js-lib/yui/build/dom/dom-min.js"></script>
<script type="text/javascript" src="./js-lib/yui/build/dragdrop/dragdrop-min.js"></script>
<script type="text/javascript" src="./js-lib/yui/build/connection/connection-min.js"></script>
<script type="text/javascript" src="./js-lib/yui-ext/yui-ext.js"></script>
<script type="text/javascript" src="./js-lib/BGeocoder/geonamesData.js"></script>
<script type="text/javascript" src="./js-lib/BGeocoder/jsr_class.js"></script>
<script type="text/javascript" src="./js-lib/BGeocoder/BGeocoder.js"></script>
<script type="text/javascript" src="./js-lib/BGeocoder/lib_navig.js"></script>
<script type="text/javascript" src="./js-lib/BGeocoder/lib_xhr.js"></script>
<script type="text/javascript" src="./js-lib/BGeocoder/json.js"></script>
<script type="text/javascript" src="./components/component.js"></script>
<script type="text/javascript" src="./components/container.js"></script>
<script type="text/javascript" src="./components/label.js"></script>
<script type="text/javascript" src="./components/button.js"></script>
<script type="text/javascript" src="./components/textfield.js"></script>
<script type="text/javascript" src="./components/panel.js"></script>
<script type="text/javascript" src="./visual/drawer.js"></script>
<script type="text/javascript" src="./visual/visualX.js"></script>
<script type="text/javascript" src="./function.js"></script>
<script type="text/javascript" src="./list.js"></script>
<style>
body
{
font-family : Sans-serif;
}
</style>
<style>
.drawer .selection
{
position:absolute;
border:1px solid #ff0000;
font-size:1px;
display:none;
}
</style>
</head>
<body >
<div id="list" style="border:1px solid red;"></div>
</div>
<script type="text/javascript">
//var visualX = new VisualX ();
function OnItemClick ( evt )
{
console.log ( "OnItemClick %o", evt.target );
console.log ( "this %o", this );
}
var liste = new List ( {_id:'list', x:50,y:100,width:250,height:220,
_class : 'liste',
_selectable : true,
_multiselectable : true,
_onclick : OnListClick,
_highlightOnmouseover: true,
_handlers : [OnItemClick, OnItemClick]});
//liste.on ( "click", OnListClick, this );
liste.Add ( new ObjListe ({_libelle:'le libelle', _configTool:[{css:'delete'},{css:'delete'}]}) );
liste.Add ( "Encore" );
liste.Add ( "Un autre" );
liste.Add ( new ObjListe ({ _libelle : 'OnClick',
_onclickArg : ['salut0', 'salut1'],
_configTool : null}) );
function OnListClick ( arg0, arg1 )
{
console.log ( "OnListeClick %o %o", arg0, arg1 );
}
/*liste.Add ( "das it work" );
liste.Add ( "Encore" );
liste.Add ( "Un de plus" );*/
/*
var container = new XPanel ( 'main0' );
var label = new XLabel ( 'idLab', 'un cool label' );
var bouton = new XButton ( 'idBut', 'un bouton' );
var textfield = new XTextField ( 'idText', 'une zone de saisie' );
container.SetBounds (450, 150, 600, 300 );
container._element.setAbsolutePositioned ();
container.Add ( label );
container.Add ( textfield );
container.Add ( bouton );
label.SetBorderWidth ( "1px dashed blue" );
label.SetBounds ( 30, 10, 100, 25 );
textfield.SetBorderWidth ( "1px solid #000000" );
textfield.SetBounds ( 300, 50, 150, 25 );
bouton.SetBorderWidth ( "1px solid #000000" );
bouton.SetBounds ( 450, 50, 100, 25 );
bouton.AddActionListener ( "click", OnClick );
function OnClick ( evt )
{
alert ( textfield.GetText () );
}
var elem = new YAHOO.ext.Element ( "input" , true );
elem.setStyle ( "border", "1px solid black" );
console.log ("elem : %o", elem);*/
</script>
</body>
</html>
css/list.css
.liste
{
padding:0px;
overflow:auto;
border : 1px solid black;
font-size : 14px;
}
.liste .paire
{
background-color:#d6d7ff;
}
.liste .impaire
{
background-color:#ffffff;
}
.liste .cell
{
border-top : 1px solid black;
border-left : 1px solid black;
border-right : 1px solid black;
padding : 2px;
}
.liste .mouseover
{
background-color:#a5a6ff;
}
.liste .selected
{
background-color:#a5a6ff;
}
.liste .delete
{
background-image:url(./delete.png);
background-repeat : no-repeat;
width:15px;
height:14px;
}
Powered by vBulletin® Version 4.1.5 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.