View Issue Details

This bug affects 1 person(s).
 12
IDProjectCategoryView StatusLast Update
09382Bug reportsTheme editorpublic2016-05-04 16:13
Reporterdstrohl Assigned Toc_schmitz  
PrioritynormalSeverityminor 
Status closedResolutionduplicate 
Product Version2.05+ 
Summary09382: JQuery.UI bug on drag-drop ranking
Description

It seems like there is a jquery.ui bug that is causing a slightly weird behavior on drag/drop actions.

When you drag an answer to the ranking column, it shows up 1 above where you would expect it to be. (see this bug in jquery: http://bugs.jqueryui.com/ticket/9773). The bug was reported as fixed in the "master" copy, which I assume is v1.10.4+ (see fixed example here: http://codepen.io/tjvantoll/pen/uHDIr) so it looks like this is fixable by simply updating the version of jQuery.

Steps To Reproduce
  1. create a ranking question
  2. add more than three answers to it
    (this comes up in the demo site as well, so you can use that for reproducing)
    3 drag an answer
  3. drag another answer
    5 drag the third answer, this would normally be expected to show up as the third rank, but it defaults to the second.
Additional Information

you can work around this by reordering the answers once dropped, or by moving up and down before dropping, which seems to reset the problem.

As indicated above, I replicated this in the online demo site (https://survey.limesurvey.org/78184?lang=en , General Experience with LimeSurvey page)

TagsNo tags attached.
Attached Files
ranking (1).js (8,561 bytes)   
function doDragDropRank(qID, showpopups, samechoiceheight, samelistheight) {
// TODO : advanced setting in attributes
  if (typeof showpopups === 'undefined'){showpopups=true;}
  if (typeof samechoiceheight === 'undefined'){samechoiceheight=true;}
  if (typeof samelistheight === 'undefined'){ samelistheight=true;}
  // added ONE to the maxanswers var to account for added dummy li in answers  (dstrohl)
  var maxanswers= parseInt($("#ranking-"+qID+"-maxans").text(),10)+1;
  var rankingname= "javatbd"+$("#ranking-"+qID+"-name").text();
  var rankingnamewidth=rankingname.length;
  //Add a class to the question
  $('#question'+qID+'').addClass('dragDropRanking');
  // Hide the default answers list
  // Display for media oral, maybe use !window.matchMedia("(oral)").matches but still hidden if user use default browser with screen reader ?
  $('#question'+qID+' .answers-list').addClass("hide");
  // We are in javascript, then default tip can be replaced
  $('#question'+qID+' .em_default').html(aRankingTranslations.rankhelp);


  // Add connected sortables elements to the question
  // Actually a table : move it to a list is a good idea, but need reviewing template a lot.
  var htmlCode = '<div class="dragDropTable"> \
      <div class="columns2">\
        <strong class="SortableTitle">'+aRankingTranslations.choicetitle+'</strong>\
        <div class="ui-state-default dragDropChoices"> \
          <ul id="sortable-choice-'+qID+'" class="connectedSortable'+qID+' dragDropChoiceList"> \
            <li>'+aRankingTranslations.choicetitle+'</li> \
          </ul> \
        </div> \
      </div>\
      <div class="columns2">\
        <strong class="SortableTitle">'+aRankingTranslations.ranktitle+'</strong>\
        <div class="ui-state-default dragDropRanks"> \
          <ol id="sortable-rank-'+qID+'" class="connectedSortable'+qID+' dragDropRankList selectionSortable"> \
            <li>'+aRankingTranslations.ranktitle+'</li> \
            <li></li> \
          </ol> \
        </div> \
      </div> \
    </div>';
  $(htmlCode).insertAfter('#question'+qID+' .answers-list');
  $('#sortable-choice-'+qID+' li, #sortable-rank-'+qID+' li').remove();
  
  
  // force extra li in selected answers list to overcome weird sorting problem (dstrohl)
  var liLine = '<li class="fixPlaceholderDrop-'+qID+'"></li>';
  var liInsertSelector = '#sortable-rank-'+qID+'.connectedSortable'+qID+'.dragDropRankList.selectionSortable';
  $(liInsertSelector).html(liLine);
  
  // Get the list of choices from the LimeSurvey question and copy them as items into the sortable choices list
  var ranked =[];
  $('#question'+qID+' .answers-list .select-item option:selected').each(function(index, Element) {
    if($(this).val()!=''){
      ranked.push($(this).val());
      htmloption=$("#htmlblock-"+qID+'-'+$(this).val()).html();
      var liCode = '<li class="ui-state-default choice" id="'+rankingname+$(this).val()+'">' + htmloption + '</li>'
      $(liCode).appendTo('#sortable-rank-'+qID+'');
    }
  });
  $('#question'+qID+' .answers-list .select-item:first option').each(function(index, Element) {
    var thisvalue=$(this).val();
    if(thisvalue!='' && jQuery.inArray(thisvalue,ranked)<0){
        htmloption=$("#htmlblock-"+qID+'-'+$(this).val()).html();
        var liCode = '<li class="ui-state-default choice" id="'+rankingname+$(this).val()+'">' + htmloption + '</li>'
        $(liCode).appendTo('#sortable-choice-'+qID+'');
    }
  });
  loadDragDropRank(qID);

  // Set up the connected sortable			
  $('#sortable-choice-'+qID+', #sortable-rank-'+qID+'').sortable({
    connectWith: '.connectedSortable'+qID+'',
    forceHelperSize: true,
    forcePlaceholderSize: true,
    placeholder: 'ui-sortable-placeholder',
    helper: 'clone',
    delay: 200,
    revert: 50,
    receive: function(event, ui) {
    	fixOutOfOrderPlaceholder(qID);
      if($(this).attr("id")=='sortable-rank-'+qID && $(maxanswers>0 && '#sortable-rank-'+qID+' li').length > maxanswers) {
        sortableAlert (qID,showpopups,maxanswers);
        if(showpopups){$(ui.sender).sortable('cancel');}
      }
      },
    stop: function(event, ui) {
      $('#sortable-choice-'+qID+'').sortable('refresh');
      $('#sortable-rank-'+qID+'').sortable('refresh');
      updateDragDropRank(qID);
    },
  }).disableSelection();
  // Adapt choice and list height
  //fixChoiceListHeight(qID,samechoiceheight,samelistheight);
  // Allow users to double click to move to selections from list to list
    $('#sortable-choice-'+qID).delegate('li','dblclick', function() {
      if($(maxanswers>0 && '#sortable-rank-'+qID+' li').length >= maxanswers) {
        sortableAlert (qID,showpopups,maxanswers);
        if(showpopups){return false;}
      }
      else {
        $(this).appendTo('#sortable-rank-'+qID+'');
        $('#sortable-choice-'+qID+'').sortable('refresh');
        $('#sortable-rank-'+qID+'').sortable('refresh');
      }
      updateDragDropRank(qID);
    });
    $('#sortable-rank-'+qID).delegate('li','dblclick', function() {
      $(this).appendTo('#sortable-choice-'+qID+'');
      $('#sortable-choice-'+qID+'').sortable('refresh');
      $('#sortable-rank-'+qID+'').sortable('refresh');
      updateDragDropRank(qID);
    });
  $(function() { // Update height for IE7, maybe for other function too
    fixChoiceListHeight(qID,samechoiceheight,samelistheight);
  }); 
  }

// added to move the dummy placeholder back to the bottom in case of users dropping answer on it (dstrohl)
function fixOutOfOrderPlaceholder(qID){
  $('#sortable-rank-'+qID+' li.choice:nth-last-of-type(3) + .fixPlaceholderDrop-'+qID).each( function() {
  	var liLine = '<li class="fixPlaceholderDrop-'+qID+'"></li>';
  	$('#sortable-rank-'+qID).append(liLine);
  	$(this).remove();
  });
}


function updateDragDropRank(qID){
  var maxanswers= parseInt($("#ranking-"+qID+"-maxans").text(),10);
  var rankingname= "javatbd"+$("#ranking-"+qID+"-name").text();
  var relevancename= "relevance"+$("#ranking-"+qID+"-name").text();
  var rankingnamewidth=rankingname.length;
  $('#question'+qID+' .select-item select').val('');
  $('#sortable-rank-'+qID+' li').each(function(index) {
    // Get value of ranked item
    var liID = $(this).attr("id");
    liValue = liID.substr(rankingnamewidth);
    $('#question'+qID+' .select-item select').eq(index).val(liValue);
  });
  // Update #relevance and lauch checkconditions function
  $("[id^=" + relevancename + "]").val('0');
  $('#question'+qID+' .select-item select:lt('+maxanswers+')').each(function(index){
      number=index+1;
      if($(this).val()!=""){
          $("#"+relevancename+number).val("1");
      }
      checkconditions($(this).val(),$(this).attr("name"),'select-one','onchange');
  });
    $('#sortable-rank-'+qID+' li').removeClass("error");
    $('#sortable-choice-'+qID+' li').removeClass("error");
    $('#sortable-rank-'+qID+' li:gt('+(maxanswers*1-1)+')').addClass("error");
}

function sortableAlert (qID,showpopups)
{
    if(showpopups){
        txtAlert=$("#question"+qID+" .em_num_answers").text()
        alert(txtAlert);
    }
}
function loadDragDropRank(qID){
  var maxanswers= parseInt($("#ranking-"+qID+"-maxans").text(),10);
  var rankingname= "javatbd"+$("#ranking-"+qID+"-name").text();
  var relevancename= "relevance"+$("#ranking-"+qID+"-name").text();
  var rankingnamewidth=rankingname.length;
  // Update #relevance 
  $("[id^=" + relevancename + "]").val('0');
  $('#question'+qID+' .select-item select').each(function(index){
    if($(this).val()!=''){
        number=index+1;
        $("#"+relevancename+number).val("1");
        $('#sortable-choice-'+qID+' li#'+rankingname+$(this).val()).appendTo('#sortable-rank-'+qID);
    }
  });

  $('#sortable-rank-'+qID+' li').removeClass("error");
  $('#sortable-choice-'+qID+' li').removeClass("error");
  $('#sortable-rank-'+qID+' li:gt('+(maxanswers*1-1)+')').addClass("error");
}

// Fix choix and list heigth according to parameter
function fixChoiceListHeight(qID,samechoiceheight,samelistheight){
  if(samechoiceheight)
  {
    var maxHeight=0;
    $('.connectedSortable'+qID+' li').each(function(){
      if ($(this).actual('height')>maxHeight){
        maxHeight=$(this).actual('height');
      }
    });
    $('.connectedSortable'+qID+' li').css('min-height',maxHeight+'px');
  }
  if(samelistheight)
  {
    var totalHeight=0;
    $('.connectedSortable'+qID+' li').each(function(){
      totalHeight=totalHeight+$(this).actual('outerHeight',{includeMargin:true});;
    });
    $('.connectedSortable'+qID).css('min-height',totalHeight+'px');
  }
}
ranking (1).js (8,561 bytes)   
Bug heat12
Complete LimeSurvey version number (& build)141113
I will donate to the project if issue is resolvedNo
BrowserTested on Chrome and Safari
Database type & versionUnk (hosted)
Server OS (if known)Unk *(hosted)
Webserver software & version (if known)Unk (hosted)
PHP VersionUnk (hosted)

Relationships

duplicate of 11078 closedLouisGac Rank click-and-move (swipe) puts selected answer to pre-last item on list 
related to 10507 closedc_schmitz Ranking question does not work in Opera 

Users monitoring this issue

dstrohl, david2013

Activities

DenisChenu

DenisChenu

2014-12-03 10:21

developer   ~31145

Yea, like show in codepen, it's a minor bug, but update jqui is a good idea.

dstrohl

dstrohl

2014-12-03 16:50

reporter   ~31150

Where is the {TEMPLATEJS} defined? and/or how hard is it to change that? I was thinking about testing to see if updating jqui would help.

dstrohl

dstrohl

2014-12-03 16:59

reporter   ~31151

There was also a workaround I found that seemed to work (I tried hacking it in to a rendered page using the chrome dev tools), however it looks like the implementation would be harder than it would be to simply update the jqui lib.

The workaround would be to add another empty

  • at the end of the connected list. The placeholder is then still put one up from the bottom, but that one up from the bottom is then at the actual bottom. However this also seems to add a few new problems to solve:

    1. someone could drop an item on the actual bottom slot, leaving a blank that might (would?) cause validation problems.
    2. cleaning up that last empty line so it didn't cause those same validation problems on saving.
    3. changing the code that alerts for too many answers (that list li seems to count)

    None of these are impossible, in fact, probably none fo them look to be really hard (he said easily as if he actually had looked close enough at the code to know for sure<grin>), but they seem definitely harder than updating the lib... unless of course there is something that the update causes to break.

    (I threw this note in for completeness, and to share my research so others don't have to, not because I think this is the best approach)

    DenisChenu

    DenisChenu

    2014-12-03 19:19

    developer   ~31153

    jquery-ui included by https://github.com/LimeSurvey/LimeSurvey/tree/master/third_party/jqueryui

    You can try with any jquery-ui version, but you have to update the link at https://github.com/LimeSurvey/LimeSurvey/blob/master/application/config/third_party.php#L52

    We don't touch of third_party system (if possible)

    dstrohl

    dstrohl

    2014-12-03 20:20

    reporter   ~31155

    OK, I tried updating the jqui lib with 1.10.4 and had the same behavior, then I tried updating it with 1.11.2 (The latest) and it then puts the placeholder at the top of the list each time. (not sure if that is better or worse).

    I am poking around trying to see what is going on now, it seems like this should now work correctly based on the js code and the docs.

    As a side note; to me this is not really a minor issue (though definitely not a major one either). the problem is that anyone who doesn't pay attention while dragging and dropping, and is expecting the answers to be in the order that they dropped them in, will end up with sending in a set of answers that does match their intent. (and I have lots of respondents who don't pay enough attention to the surveys)

    dstrohl

    dstrohl

    2014-12-03 23:27

    reporter   ~31157

    another update... on a page that I have two ranking questions, the first one works, the second does not. I am going to recreate the survey in a simpler form to see if this is consistent and if there are any patterns... (always the first on a page? random? ??)

    I will upload the simpler survey file to this ticket when I have it.

    DenisChenu

    DenisChenu

    2014-12-04 08:49

    developer   ~31159

    Great , thanks.

    dstrohl

    dstrohl

    2014-12-04 17:36

    reporter   ~31165

    Last edited: 2014-12-04 17:37

    OK, I uploaded a lss file for this, there are three groups of questions, and the problem seems to happen on the later questions on a page. so, when I have three questions on a page, it happens on questions 2 & 3, or sometimes just 3. when I have 2 questions, sometimes it does not happen, and sometimes it just happens on Q2. I tried longer sets of answers (so, Q1 with 15 answers, Q2 with 2, and it did not happen at all, I tried more shorter sets, and it did happen.

    The problem does seem to be consistent to the point that when it picks which questions to work weirdly, they always work weirdly, so it's not totally random.

    I tried this with IE (v11), Chrome, and Safari and all did the same. (this was tested on my server running v 1.11.2 of jqui btw.)

    DenisChenu

    DenisChenu

    2014-12-04 17:47

    developer   ~31166

    It's allways the same bug, the third (or last) answer don't go to last place ?

    The most important is : did EM show him at last place or not (did the select/option are same than the drag-drop div).

    dstrohl

    dstrohl

    2014-12-04 19:01

    reporter   ~31167

    Its always the same bug:
    With jqui v10.4; the last item dropped will be the -second-to-last- item in the list
    With jqui v11.2; the last item dropped will be the -first- item in the list.

    (this assumes that you do not intersect the drop list before dropping, in which case it works correctly).

    I am not sure about the answer to your other question, what is EM?

    dstrohl

    dstrohl

    2014-12-04 20:53

    reporter   ~31169

    OK, after some frustration, I went back to v1.10.4 and tried the approach I threw out earlier as not the best option. I uploaded my ranking.js here for your thoughts.

    All of the chances were commented with a "(dstrohl)" so you can find them.

    This approach still seems to be a brute force "hack" approach, and there are still several cases that I need to take into account in the code (so it's not finished), but I wanted to get your thoughts before going too far.

    Basically, I:

    • added an extra
    • on the selected list, this does not appear at this point though skinning could make it appear.
    • changed the maxanswer count to be maxanswer+1 (to account for the extra item in that list
      -added a function that is called on each drop event that checks to make sure that the item is not dropped after the dummy item, if so, it moves the dummy placeholder back below the new item.

    the things that still need to be addressed:

    • I need to make sure that it doesnt make things choke on saving the question (not sure if I should just remove it before it hits the save function, or change the save function to ignore it)
    • I need to try either setting display=none, or otherwise making it not selectable, right now a user could drag it back to the other table.

    unknowns:
    how do the various options interact with this such as answer filters, relevance, equations, etc... and is this likely to screw up a bunch of other things?

    so....

    Any thoughts? is this a dumb approach likely to cause lots of potential problems, or is it a valid hack at least?

    DenisChenu

    DenisChenu

    2014-12-06 12:02

    developer   ~31186

    HI,

    I think we can update jquery-ui and jquery at the same time. We update jquery somle week ago, maybe it's a child.

    I have to take time ..... but actually less time than i want ;)

    DenisChenu

    DenisChenu

    2014-12-14 12:58

    developer   ~31249

    Last edited: 2014-12-14 13:00

    According to first ticket it's a duplicate of http://bugs.jqueryui.com/ticket/9314 , and this one is fixed in 1.10.3. We use actually 1.10.3 .....
    Oh no, fixed in master only ....

    1.10.4 not fixed issue ...

    dstrohl

    dstrohl

    2014-12-15 16:28

    reporter   ~31255

    yup, I found that 1.10.4 didn't fix it as well, nor does 1.11.2... (hence my thoughts above on trying a different approach).

    dstrohl

    dstrohl

    2014-12-16 17:16

    reporter   ~31271

    I created a ticket for jQuery to report this bug (tested it on a jfiddle and it happens with a very vanillia design as well.) http://bugs.jqueryui.com/ticket/10727

    I fixed jQuery in my own repo (here: https://github.com/dstrohl/jquery-ui/blob/master/ui/sortable.js) and updated a version of jQuery which I will upload to this bug.

    I didn't close the jQuery bug hoping that someone else will take a look at the code and make sure I didn't break anything else, so I don't suggest necessarily including my custom jQuery in your code yet, and it should definitely go through some more rigorous testing as well.

    DenisChenu

    DenisChenu

    2014-12-16 17:22

    developer   ~31272

    Great adding placeholder show better it : http://jsfiddle.net/17n55z5u/8/

    DenisChenu

    DenisChenu

    2016-01-21 09:07

    developer   ~34303

    Mazi : seems you fix the bug in LS reloaded .

    Maybe you can fix core ?
    http://limesurvey-templates.com/ls2demo/index.php/survey/index/sid/855647/newtest/Y/lang/en

    Mazi

    Mazi

    2016-01-21 09:27

    updater   ~34306

    Louis, can you test if this is an issue at all with the LS 2.5 templates?
    Because if not, I'd recommend to just skip this issue for now since the next release comes with completely different shipped templates.

    If I should provide anyone the adjusted template from http://www.limesurvey-templates.com/limesurvey-template-default-reloaded-p-29.html for further testing just drop me a note!

    DenisChenu

    DenisChenu

    2016-01-21 09:34

    developer   ~34307

    Oh yes .... not fixed in default-reloaded too :

    Your show at top of page ....
    sortables far enough down to require scrolling.

    DenisChenu

    DenisChenu

    2016-01-21 09:38

    developer   ~34309

    jqueyui master are the bug fixed. I think i just upadet this part in our jqueryu-ui for 2.06 and 2.5 need a better fix

    DenisChenu

    DenisChenu

    2016-01-21 11:02

    developer   ~34314

    2.50 have the same issue (jqueryui aren't updated) . But hard to reproduce because : sometrimes it work, sometimes not ....

    c_schmitz

    c_schmitz

    2016-05-04 16:11

    administrator   ~38207

    I cannot find a matching bug in the tracker for jQuery UI.
    Some are similar but they are suppoed to be reolved.
    So I'd guess we should submit one.

    Tony, can you maybe create a JSFiddle that is reproducing the issue?

    Issue History

    Date Modified Username Field Change
    2014-12-03 00:03 dstrohl New Issue
    2014-12-03 00:04 dstrohl Issue Monitored: dstrohl
    2014-12-03 10:21 DenisChenu Note Added: 31145
    2014-12-03 10:21 DenisChenu Assigned To => DenisChenu
    2014-12-03 10:21 DenisChenu Status new => confirmed
    2014-12-03 16:50 dstrohl Note Added: 31150
    2014-12-03 16:59 dstrohl Note Added: 31151
    2014-12-03 19:19 DenisChenu Note Added: 31153
    2014-12-03 20:20 dstrohl Note Added: 31155
    2014-12-03 23:27 dstrohl Note Added: 31157
    2014-12-04 08:49 DenisChenu Note Added: 31159
    2014-12-04 17:32 dstrohl File Added: limesurvey_survey_677718.lss
    2014-12-04 17:36 dstrohl Note Added: 31165
    2014-12-04 17:37 dstrohl Note Edited: 31165
    2014-12-04 17:47 DenisChenu Note Added: 31166
    2014-12-04 19:01 dstrohl Note Added: 31167
    2014-12-04 20:43 dstrohl File Added: ranking (1).js
    2014-12-04 20:53 dstrohl Note Added: 31169
    2014-12-06 12:02 DenisChenu Note Added: 31186
    2014-12-14 12:58 DenisChenu Note Added: 31249
    2014-12-14 13:00 DenisChenu Note Edited: 31249
    2014-12-15 16:28 dstrohl Note Added: 31255
    2014-12-16 17:16 dstrohl Note Added: 31271
    2014-12-16 17:18 dstrohl File Added: jquery-ui-1.11.2.testfix.js
    2014-12-16 17:22 DenisChenu Note Added: 31272
    2015-12-11 14:40 c_schmitz Category Templates => Theme editor
    2016-01-21 09:06 DenisChenu Assigned To DenisChenu => Mazi
    2016-01-21 09:06 DenisChenu Status confirmed => assigned
    2016-01-21 09:07 DenisChenu Note Added: 34303
    2016-01-21 09:25 Mazi Assigned To Mazi => LouisGac
    2016-01-21 09:27 Mazi Note Added: 34306
    2016-01-21 09:34 DenisChenu Note Added: 34307
    2016-01-21 09:36 DenisChenu Assigned To LouisGac => DenisChenu
    2016-01-21 09:38 DenisChenu Note Added: 34309
    2016-01-21 11:02 DenisChenu Note Added: 34314
    2016-01-25 05:13 david2013 Issue Monitored: david2013
    2016-03-07 11:09 DenisChenu Assigned To DenisChenu =>
    2016-03-07 11:10 DenisChenu Status assigned => new
    2016-03-07 11:11 DenisChenu Relationship added related to 10507
    2016-05-03 14:38 DenisChenu Relationship added related to 11078
    2016-05-04 16:11 c_schmitz Note Added: 38207
    2016-05-04 16:13 c_schmitz Relationship replaced duplicate of 11078
    2016-05-04 16:13 c_schmitz Status new => closed
    2016-05-04 16:13 c_schmitz Assigned To => c_schmitz
    2016-05-04 16:13 c_schmitz Resolution open => duplicate