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 <li></li> 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 <li></li> 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