Search code examples
jqueryjquery-uijquery-ui-sortabletoggleclass

Why does the toggling of the class just work partially for a few elements and not always the same?


I have tried to implement a picklist like the one in primeFaces with jQuery and jQuery-ui.

To combine multiselect and sortable I have a function which toggles the class onClick and allows the user to select multiple elements using the ctrl-Button.

Sorting, selecting and moving in between the lists works fine but now I have to implement the same functionality which I have with drag and drop using buttons.

Now my problem is that if I for example move up an item (with the button!) the toggling doesn't work anymore or only partially.

Can anybody help me?

I created a fiddle for this, but the functions for the buttons arent't called and I don't know why.

http://jsfiddle.net/p59vJ/14/ Edit:

fiddle with less code: http://jsfiddle.net/p59vJ/15/

My Code:

Javascript/jQuery:

  var selectedList = new Array();
  var selectedChoice = new Array();
  var selected = new Array();

  jQuery(function() {
      jQuery('#liste, #auswahl').sortable({
          connectWith:".ui-picklist-list",
      });

      jQuery('#liste, #auswahl').children().click( function (eventObject){
          if(!eventObject.ctrlKey) {
              jQuery(".ui-picklist-item").removeClass("ui-state-highlight");
          }
          jQuery(this).toggleClass("ui-state-highlight");
      });

  });

  function initMultiselect(){
      jQuery('#liste, #auswahl').children().click( function (eventObject){
          if(!eventObject.ctrlKey) {
              jQuery(".ui-picklist-item").removeClass("ui-state-highlight");
          }
          jQuery(this).toggleClass("ui-state-highlight");
      });
  }

  function hasClass(element, cls) {
      var r = new RegExp('\\b' + cls + '\\b');
      return r.test(element.className);
  }



  function moveUp(id){
      for(var i=1; i<document.getElementById(id).getElementsByTagName("li").length; i++){
          if(hasClass(document.getElementById(id).getElementsByTagName("li")[i],"ui-state-highlight")){
              var e1 = document.getElementById(id).getElementsByTagName("li")[i];
              var e2 = document.getElementById(id).getElementsByTagName("li")[i-1];

              if(e1 && e2) { //nodes found
                  var parent = e1. parentNode;
                  var clones = [
                   e1. cloneNode(true),
                   e2. cloneNode(true)
                  ];
              //toggle (replace nodes)
              parent. replaceChild(clones[1], e1);
              parent. replaceChild(clones[0], e2);
              }
          }
      }

      jQuery('#'+id).children().click( function (eventObject){
          if(!eventObject.ctrlKey) {
            jQuery(".ui-picklist-item").removeClass("ui-state-highlight");
          }
          jQuery(this).toggleClass("ui-state-highlight");
      });    
  }

HTML-Code:

     <table id="j_idt14:j_idt19" class="ui-picklist ui-widget">
       <tbody>
          <tr>
            <td class="ui-picklist-source-controls">
                <button class="ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only ui-picklist-button-move-up" title="Move Up" type="button" onClick="moveUp('liste');">
                <span class="ui-button-icon-left ui-icon ui-icon ui-icon-arrow-1-n"></span>
                <span class="ui-button-text">moveUp</span>
                </button>
            </td>
            <td>
              <div class="ui-picklist-caption ui-widget-header ui-corner-tl ui-corner-tr">Liste</div>
                <ul class="ui-widget-content ui-picklist-list ui-picklist-source ui-corner-bottom" id="liste">
                  <li class="ui-picklist-item" id="pick1">Messi - 10</li>
                  <li class="ui-picklist-item" id="pick2">Iniesta - 8</li>
                  <li class="ui-picklist-item" id="pick3">Villa - 7</li>
                  <li class="ui-picklist-item" id="pick4">Alves - 2</li>
                  <li class="ui-picklist-item" id="pick5">Xavi - 6</li>
                  <li class="ui-picklist-item" id="pick6">Puyol - 5</li>
                </ul>
     </td>
       <td>
      </td>
       <td>
          <div class="ui-picklist-caption ui-widget-header ui-corner-tl ui-corner-tr">Auswahl</div>
           <ul class="ui-widget-content ui-picklist-list ui-picklist-target ui-corner-bottom " id="auswahl">
           <li class="ui-picklist-item " id="choice1">Element 1</li>
            <li class="ui-picklist-item " id="choice2">Element 2</li>
              <li class="ui-picklist-item " id="choice3">Element 3</li>
             <li class="ui-picklist-item " id="choice4">Element 4</li>
          <li class="ui-picklist-item" id="choice5">Element 5</li>
          <li class="ui-picklist-item " id="choice6">Element 6</li>
          <li class="ui-picklist-item " id="choice7">Element 7</li>
          <li class="ui-picklist-item " id="choice8">Element 8</li>

           </ul>
        </td>
        <td class="ui-picklist-target-controls">
           <button class="ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only ui-picklist-button-move-up" title="Move Up" type="button" onClick="moveUp('auswahl')">
          <span class="ui-button-icon-left ui-icon ui-icon ui-icon-arrow-1-n"></span>
           <span class="ui-button-text">moveUp</span>
          </button>
        </td>
       </tr>
     </tbody>
   </table>

CSS:

.ui-picklist .ui-picklist-list {
height: 200px;
list-style-type: none;
margin: 0;
overflow: auto;
padding: 0;
width: 200px;
}
.ui-picklist .ui-picklist-list li {
margin: 1px;
padding: 2px;
}
.ui-picklist .ui-button {
display: block;
margin-bottom: 0.3em;
margin-left:0.4em;
background: transparent url(../dsv_assets/images/datepicker_button.PNG) no-repeat;
border:none;
}
.ui-picklist .ui-picklist-item {
border: 0 none;
cursor: pointer;
font-weight: inherit;
}
.ui-picklist .ui-picklist-caption {
border-bottom: 1 none;
padding: 4px 10px;
text-align: center;
}
.ui-picklist table {
border-collapse: collapse;
width: 100%;
}
.ui-picklist > tbody {
}

.ui-picklist-item div{
width: 20px;
float: right;
height: 13px;
}

.ui-picklist-caption{
color: black !important;
}

.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header  .ui-state- highlight  {background: highlight; color: white;}

Solution

  • Ok i found the mistake. When I clone the list-elements to move them up or down the list or to the other list the click event gets lost so I initialized it every time after I moved one or more items. Because of that some of the list-items had more than on click function, so when I clicked them and they had an even number of click events it looked like the click event wasn't fired because the class toggled and then toggled in the same moment again.

    The problem why the elements aren't highlighted when i drag and drop them is that the click event is just fired when the mouse button is pressed and let loose not only if it's pressed.

    Solution: After I move one or more list items I call a function which does this:

          jQuery([all my picklist items]).unbind('mousedown');
          jQuery([all my picklist items]).mousedown( function (eventObject){
               if(!eventObject.ctrlKey) {
                  jQuery(".ui-picklist-item").removeClass("ui-state-highlight");
               }
               jQuery(this).toggleClass("ui-state-highlight");
          });