Card Sort based Setups (#11, #12, #13, #19 & #20)

For all these questions copy paste the below code and update question text, row text and label, column text and label accordingly:

mobile-phone
Bucket Sort Single

  <radio 
   label="ketoolCardsortText"
   builderHint="{"rocochoName":"radiogrid"}"
   fir="off"
   surveyDisplay="desktop">
    <title>Please categorize the following definitions of bank types.</title>
    <comment>You can drag each definition and drop it into the group of your choice.
</comment>
    <col label="c1">Investment</col>
    <col label="c2">Retail</col>
    <col label="c3">Commercial</col>
    <col label="c4">Online</col>
    <row label="r1">A specific division of banking related to the creation of capital for other companies.</row>
    <row label="r2">The bank cannot provide direct ATM access</row>
    <row label="r3">A financial institution that provides services, such as auto loans and mortgage.</row>
    <row label="r4">Typical mass-market banking in which individual customers use local branches of larger commercial banks.</row>
    <row label="r5">Banking services offered to the general public.</row>
    <row label="r6">Financial institution that provides large amounts of long-term fixed capital, primarily for established firms.</row>
    <style name="page.head"><![CDATA[
<style>
        .answers{display:none;}
        #btn_continue {
          visibility: hidden;
        }
      </style>
]]></style>
    <style name="question.after"><![CDATA[
<div class="ketool-stage" id="ketool-stage-${this.label}" style="margin-bottom: 50px; margin-top: -30px;"></div>
<script type="text/javascript" src="${KEDomain}/core/framework.min.js"></script>

        <script>
     if (!ketool.qDefs) {

        ketool.qDefs = {};
                if(!ketool.toolLoader) {
                    ketool.toolLoader = new ketool.Loader({
                        "baseFileURL": "${KEDomain}/core/",
                        "scriptDeps": [
              "fancybox/fancybox.library.js",
              "plugins/jquery-ui.min.js",
              "plugins/jquery.ui.touch-punch.min.js",
              "plugins/jquery_clickfix.ui.touch-punch.min.js",
              "advanced_ui/Carousel_libs.js",
              "advanced_ui/Carousel.js"
            ],
                        "cssDeps": [
              "framework.css",
              "fancybox/fancybox.library.css",
              "ionicons/ionicons.min.css",
              "plugins/jquery-ui.css",
              "advanced_ui/Carousel_libs.css",
              "advanced_ui/Carousel.css"
            ],
                        "coreFile": "application.min.js",
                        "messages": null,
                        "platformInterface": { js: "platform_interface/platform_interface.js", "css": "platform_interface/platform_interface.css" }
                    });
                    console.log("ketool.toolLoader: ", ketool.toolLoader);
                }
            }
             ketool.qDefs["${this.label}"] = ${jsexport()};
             var isTest = "${gv.isUser() and not gv.debug.respview}" === "True";

            var toolSettings = {
                "toolJs": "application.min.js",
                "toolName": "Cardsort",
                "jsToLoad": [],
                "cssToLoad": ["style.css"],
                "baseToolPath": "${KEDomain}/tools/card_sort/",
                "container": "#ketool-stage-${this.label}",
                "toolCssNames": [],
                "imageBaseURL": "https://au.focusvision.com/survey/selfserve/560/221003/",
                "minRequired": ${len(this.rows)},
                "maxAllowed": ${len(this.rows)},
                "timeDataNumDecimals": 2,
                "autoNext": false,
                "autoNextItem": true,
                "numRequiredGroups": 1,
                "maxAllowedInGroups": 0,
                "maxCardDrop": 1,
                "showZoom": false,
                "zoomPosition": "bottom-right",
                "oneByOne": false,
                "isRanking": false,
                "isLadder": false,
                "showCounter": true,
                "countPrefix": "",
                "countDelimiter": "/",
                "countSuffix": "",
                "compOrder": ["itemContainer","bucketContainer"],
                "numCardsCarousel": 1,
                "animationSpeed": 300,
        "cardLayout": "grid", // grid, carousel
        "carouselType": "horizontal", // horizontal, vertical
                "tolerance": "pointer",
                "bucketWidth": 160,
                "bucketHeight": 260,
                "droppedCardWidth": 150,
                "droppedCardHeight": 55,                
                "qid": getFormName(1),
                "formNames":{                    
                    "time_qid": "",
                    "order_qid": "",
                    "exclusive_qid": ""
                },
                "answerItemConfig": {
                    // "width": "100%",
                    // "numItemsPerRow": { "small": 2, "medium": 3, "large": 3 }
                    "width": "240px",
                    "height": "100px",
                    "numItemsPerRow": 4
                },
                "customValidation": function(q){
                    console.log("customValidation()");
                    return true;
                },
                mobileConfig: {}
            };

            ketool.toolLoader.registerSettings(toolSettings, function(info){
                // console.log("Questions loaded");
                // console.log(JSON.stringify(info.bridge._platformInterface._questions));
                // console.log("info: ", info);

                info.bridge.setPageValidation(function(){
                        // console.log("setPageValidation");
                        return true;
                });

                info.instance.on("tool_loaded", function(e){
                  //console.log("tool_loaded", e);
                  if(isTest){
                      ${initKEToggleData()}
                  }
                });
            });
            
            $ (function(){
                ketool.toolLoader.initLoad();

            });
        </script>
]]></style>
  </radio>
  <suspend/>

mobile-phone
Bucket Sort Multi
 
  <checkbox 
   label="ketoolMultiCardsortText"
   builderHint="{"rocochoName":"checkboxgrid"}"
   fir="off"
   optional="1"
   surveyDisplay="desktop">
    <title>Drag items to groups</title>
    <validate>
answered = False

for x in ketoolMultiCardsortText.rows:
  if x.any:
    answered = True
    break

exAnswered = [x.val for x in ketoolMultiCardsortText_dk.rows if x.val ]

if (not answered and len(exAnswered)==0) or (answered and len(exAnswered) > 0):
  error("Either drop at least 1 item or select any of the exclusive options to continue.")
    </validate>

    <col label="c1">Group 1</col>
    <col label="c2">Group 2</col>
    <col label="c3">Group 3</col>
    <col label="c4">Group 4</col>
    <col label="c5">Group 5</col>
    <col label="c6">Group 6</col>
    <row label="r1">Item 1</row>
    <row label="r2">Item 2</row>
    <row label="r3">Item 3</row>
    <row label="r4">Item 4</row>
    <row label="r5">Item 5</row>
    <row label="r6">Item 6</row>
    <row label="r7">Item 7</row>
    <row label="r8">Item 8</row>
    <row label="r9">Item 9</row>
    <row label="r10">Item 10</row>
    <row label="r11">Item 11</row>
    <row label="r12">Item 12</row>
    <style name="page.head"><![CDATA[
<style>
  .answers{display:none;}
  #btn_continue {
    visibility: hidden;
  }
</style>
]]></style>
    <style name="question.after"><![CDATA[
<div class="ketool-stage" id="ketool-stage-${this.label}" style="margin-top: -30px;"></div>
<script type="text/javascript" src="${KEDomain}/core/framework.min.js"></script>

        <script>
     if (!ketool.qDefs) {

        ketool.qDefs = {};
                if(!ketool.toolLoader) {
                    ketool.toolLoader = new ketool.Loader({
                        "baseFileURL": "${KEDomain}/core/",
                        "scriptDeps": [
              "fancybox/fancybox.library.js",
              "plugins/jquery-ui.min.js",
              "plugins/jquery.ui.touch-punch.min.js",
              "plugins/jquery_clickfix.ui.touch-punch.min.js",
              "advanced_ui/Carousel_libs.js",
              "advanced_ui/Carousel.js"
            ],
                        "cssDeps": [
              "framework.css",
              "fancybox/fancybox.library.css",
              "ionicons/ionicons.min.css",
              "plugins/jquery-ui.css",
              "advanced_ui/Carousel_libs.css",
              "advanced_ui/Carousel.css"
            ],
                        "coreFile": "application.min.js",
                        "messages": null,
                        "platformInterface": { js: "platform_interface/platform_interface.js", "css": "platform_interface/platform_interface.css" }
                    });
                    console.log("ketool.toolLoader: ", ketool.toolLoader);
                }
            }
             ketool.qDefs["${this.label}"] = ${jsexport()};
             var isTest = "${gv.isUser() and not gv.debug.respview}" === "True";

            var toolSettings = {
                "toolJs": "application.min.js",
                "toolName": "Cardsort",
                "jsToLoad": [],
                "cssToLoad": ["style.css"],
                "baseToolPath": "${KEDomain}/tools/card_sort/",
                "container": "#ketool-stage-${this.label}",
                "toolCssNames": [],
                "imageBaseURL": "https://au.focusvision.com/survey/selfserve/560/221003/",
               "minRequired": 1,
                "maxAllowed": 0,
                "timeDataNumDecimals": 2,
                "autoNext": false,
                "numRequiredGroups": 1,
                "maxAllowedInGroups": 0,
                "maxCardDrop": 3,
                "showZoom": false,
                "zoomPosition": "bottom-right",
                "oneByOne": false,
                "isRanking": false,
                "isLadder": false,
                "showCounter": true,
                "countPrefix": "",
                "countDelimiter": "/",
                "countSuffix": "",
                "compOrder": ["itemContainer","bucketContainer"],
                "numCardsCarousel": 1,
                "animationSpeed": 300,
        "cardLayout": "grid", // grid, carousel
        "carouselType": "horizontal", // horizontal, vertical
                "tolerance": "pointer",
                "bucketWidth": 120,
                "bucketHeight": 260,
                "droppedCardWidth": 110,
                "droppedCardHeight": 40,                
                "qid": getFormName(1),
                "formNames":{                    
                    "time_qid": "",
                    "order_qid": "",
                    "exclusive_qid": "${this.label}_dk"
                },
                "answerItemConfig": {
                    // "width": "100%",
                    // "numItemsPerRow": { "small": 2, "medium": 3, "large": 3 }
                    "width": "120px",
          "height": "40px",
                    "numItemsPerRow": 4
                },
                mobileConfig: {},
                "customValidation": function(q){
                    console.log("customValidation()");
                    return true;
                }
            };

            ketool.toolLoader.registerSettings(toolSettings, function(info){
                // console.log("Questions loaded");
                // console.log(JSON.stringify(info.bridge._platformInterface._questions));
                console.log("info: ", info);

                info.bridge.setPageValidation(function(){
                        console.log("setPageValidation");
                        return true;
                });

                info.instance.on("tool_loaded", function(e){
                  //console.log("tool_loaded", e);
                  if(isTest){
                      ${initKEToggleData()}
                  }
                });
                
                info.instance.on("item_dropped", function(e, payload) {
                    // console.log("item_dropped e.detail.precode: ", e.detail);
                    // info.bridge.platformInterface.setQuestionAnswer();
                });
            });
            
            $ (function(){
                ketool.toolLoader.initLoad();

           });
        </script>
]]></style>
  </checkbox>

  <radio 
   label="ketoolMultiCardsortText_dk"
   fir="off"
   optional="1"
   surveyDisplay="desktop">
    <title>KEtool multiCardsort DK</title>
    <comment>test</comment>
    <row label="r1">Don't know</row>
    <row label="r2">None of these</row>
    <style name="question.after"><![CDATA[
<script type='text/javascript'>
    if (ketool.qDefs)
      ketool.qDefs["${this.label}"] = ${jsexport()};
  </script>
]]></style>
  </radio>

  <suspend/>

mobile-phone
Bucket Sort Image

  <radio 
   label="ketoolCardsortCarouselImage"
   fir="off"
   surveyDisplay="desktop">
    <title>Please categorize the following banks, based on your impression of their logo.</title>
    <comment>You can drag each logo and drop it into the group of your choice.<br /><br /></comment>
    <col label="c1">Investment</col>
    <col label="c2">Retail</col>
    <col label="c3">Commercial</col>
    <col label="c4">Online</col>
    <row label="r1">ICICI Bank{@imageURL::bank_1.png||largeImageURL::bank_1_L.png||width::130px||height::170px@}</row>
    <row label="r2">HDFC Bank{@imageURL::bank_2.png||largeImageURL::bank_2_L.png||width::130px||height::170px@}</row>
    <row label="r3">Bank of Baroda{@imageURL::bank_3.png||largeImageURL::bank_3_L.png||width::130px||height::170px@}</row>
    <row label="r4">State Bank of India{@imageURL::bank_4.png||largeImageURL::bank_4_L.png||width::130px||height::170px@}</row>
    <row label="r5">Axis Bank{@imageURL::bank_5.png||largeImageURL::bank_5_L.png||width::130px||height::170px@}</row>
    <style name="page.head"><![CDATA[
<style>
  .answers{display:none;}
  #btn_continue {
    visibility: hidden;
  }
  .ketool-cardsort-container .ketool-collapsible-groupholder.ketool-cardsort-itemholder-inner {
    border: none;
  }
</style>
]]></style>
    <style name="question.after"><![CDATA[
<div class="ketool-stage" id="ketool-stage-${this.label}"></div>
<script type="text/javascript" src="${KEDomain}/framework.min.js"></script><script type="text/javascript" src="${KEDomain}/core/framework.min.js"></script>

        <script>
     if (!ketool.qDefs) {

        ketool.qDefs = {};
                if(!ketool.toolLoader) {
                    ketool.toolLoader = new ketool.Loader({
                        "baseFileURL": "${KEDomain}/core/",
                        "scriptDeps": [
              "fancybox/fancybox.library.js",
              "plugins/jquery-ui.min.js",
              "plugins/jquery.ui.touch-punch.min.js",
              "plugins/jquery_clickfix.ui.touch-punch.min.js",
              "advanced_ui/Carousel_libs.js",
              "advanced_ui/Carousel.js"
            ],
                        "cssDeps": [
              "framework.css",
              "fancybox/fancybox.library.css",
              "ionicons/ionicons.min.css",
              "plugins/jquery-ui.css",
              "advanced_ui/Carousel_libs.css",
              "advanced_ui/Carousel.css"
            ],
                        "coreFile": "application.min.js",
                        "messages": null,
                        "platformInterface": { js: "platform_interface/platform_interface.js", "css": "platform_interface/platform_interface.css" }
                    });
                    console.log("ketool.toolLoader: ", ketool.toolLoader);
                }
            }
             ketool.qDefs["${this.label}"] = ${jsexport()};
             var isTest = "${gv.isUser() and not gv.debug.respview}" === "True";

            var toolSettings = {
                "toolJs": "application.min.js",
                "toolName": "Cardsort",
                "jsToLoad": [],
                "cssToLoad": ["style.css"],
                "baseToolPath": "${KEDomain}/tools/card_sort/",
                "container": "#ketool-stage-${this.label}",
                "toolCssNames": [],
                "imageBaseURL": "https://au.focusvision.com/survey/selfserve/560/221003/",
                "minRequired": ${len(this.rows)},
                "maxAllowed": ${len(this.rows)},
                "timeDataNumDecimals": 2,
                "autoNext": false,
                "autoNextItem": true,
                "numRequiredGroups": 2,
                "maxAllowedInGroups": 3,
                "maxCardDrop": 1,
                "showZoom": false,
                "zoomPosition": "bottom-right",
                "zoomButtonImage" : "${KEDomain}/tools/images/mag.png",
                "oneByOne": false,
                "isRanking": false,
                "isLadder": false,
                "showCounter": true,
                "countPrefix": "",
                "countDelimiter": "/",
                "countSuffix": "",
                "compOrder": ["itemContainer","bucketContainer"],
                "numCardsCarousel": 1,
                "animationSpeed": 300,
        "cardLayout": "carousel", // grid, carousel
        "carouselType": "horizontal", // horizontal, vertical
                "tolerance": "pointer",
                "bucketWidth": 160,
                "bucketHeight": 260,
                "droppedCardWidth": 140,
                "droppedCardHeight": 50,                
                "qid": getFormName(1),
                "formNames":{                    
                    "time_qid": "",
                    "order_qid": "",
                    "exclusive_qid": ""
                },
                "answerItemConfig": {
                    // "width": "100%",
                    // "numItemsPerRow": { "small": 2, "medium": 3, "large": 3 }
                    "width": "300px",
                   "height": "100px",
                    "numItemsPerRow": 4
                },
                mobileConfig: {},
                "customValidation": function(q){
                    console.log("customValidation()");
                    return true;
                }
            };

            ketool.toolLoader.registerSettings(toolSettings, function(info){
                // console.log("Questions loaded");
                // console.log(JSON.stringify(info.bridge._platformInterface._questions));
                console.log("info: ", info);

                info.bridge.setPageValidation(function(){
                        console.log("setPageValidation");
                        return true;
                });

                info.instance.on("tool_loaded", function(e){
                  //console.log("tool_loaded", e);
                  if(isTest){
                      ${initKEToggleData()}
                  }
                });
                
                info.instance.on("item_dropped", function(e, payload) {
                    // console.log("item_dropped e.detail.precode: ", e.detail);
                    // info.bridge.platformInterface.setQuestionAnswer();
                });
            });
            
            $ (function(){
                ketool.toolLoader.initLoad();

           });
        </script>
]]></style>
  </radio>

  <suspend/>


		

mobile-phone
Bucket Sort Custom1 (Free Bucket with few predefined)

  <define label="ketoolCardsort1Row">
    <row label="r1">Guacamole</row>
    <row label="r2">Hummus</row>
    <row label="r3">Salsa</row>
    <row label="r4">Applesauce</row>
    <row label="r5">Breakfast meat (e.g., bacon, sausage)</row>
    <row label="r6">Bruschetta</row>
    <row label="r7">Butter/margarine</row>
    <row label="r8">Candy bar/ Chocolate candy</row>
    <row label="r9">Canned soups</row>
    <row label="r10">Cheese dips</row></define>
  <define label="ketoolCardsort1Col">
    <row label="c1">Dip</row>
    <row label="c2">2</row>
    <row label="c3">3</row>
    <row label="c4">4</row>
    <row label="c5">5</row></define>
  <radio 
   label="ketoolCardsort1"
   builderHint="{"rocochoName":"radiogrid"}"
   fir="off"
   ss:questionClassNames="ketool-main-question-container"
   surveyDisplay="desktop">
    <title>Group the following ingredients</title>
    <comment>You can drag each ingredients and drop it into the group of your choice.</comment>
    <insert source="ketoolCardsort1Row"/>
    <insert as="cols" source="ketoolCardsort1Col"/>
    <style name="page.head"><![CDATA[
<style>
.answers{display:none;}
#btn_continue {visibility: hidden;}
.question:not(.ketool-main-question-container) {padding-top: 0;margin-top: 0;padding-bottom: 0;margin-bottom: 0;width: 100%;max-width:calc(924px - 15px);}
</style>
]]></style>
    <style name="question.after"><![CDATA[
<div class="ketool-stage" id="ketool-stage-${this.label}" style="margin-bottom: 50px; margin-top: -30px;"></div>
<script type="text/javascript" src="${KEDomain}/core/framework.min.js"></script>

<script>
if (!ketool.qDefs) {

	ketool.qDefs = {};
	if (!ketool.toolLoader) {
		ketool.toolLoader = new ketool.Loader({
			"baseFileURL": "${KEDomain}/core/",
			"scriptDeps": [
              "fancybox/fancybox.library.js",
              "plugins/jquery-ui.min.js",
              "plugins/jquery.ui.touch-punch.min.js",
              "plugins/jquery_clickfix.ui.touch-punch.min.js",
              "advanced_ui/Carousel_libs.js",
              "advanced_ui/Carousel.js"




			],
			"cssDeps": [
              "framework.css",
              "fancybox/fancybox.library.css",
              "ionicons/ionicons.min.css",
              "plugins/jquery-ui.css",
              "advanced_ui/Carousel_libs.css",
              "advanced_ui/Carousel.css"

            ],
                        "coreFile": "application.min.js",
                        "messages": null,
                        "platformInterface": { js: "platform_interface/platform_interface.js", "css": "platform_interface/platform_interface.css" }
                    });
                    console.log("ketool.toolLoader: ", ketool.toolLoader);
                }
            }

ketool.qDefs["${this.label}"] = ${jsexport()};
var isTest = "${gv.isUser() and not gv.debug.respview}" === "True";

var toolSettings = {
	"toolJs": "application.min.js",
	"toolName": "Cardsort",
	"jsToLoad": ["custom_bucket/customBucket.js"],
	"cssToLoad": ["style.css", "custom_bucket/customBucket.css"],
	"baseToolPath": "${KEDomain}/tools/card_sort/",
	"container": "#ketool-stage-${this.label}",
	"toolCssNames": [],
	"imageBaseURL": "",
	"minRequired": ${len(this.rows)},
	"maxAllowed": ${len(this.rows)},
	"timeDataNumDecimals": 2,
	"autoNext": false,
	"autoNextItem": true,
	"numRequiredGroups": 1,
	"maxAllowedInGroups": 0,
	"maxCardDrop": 3,
	"showZoom": false,
	"zoomPosition": "bottom-right",
	"oneByOne": false,
	"isRanking": false,
	"isLadder": false,
	"showCounter": true,
	"countPrefix": "",
	"countDelimiter": "/",
	"countSuffix": "",
	//"compOrder": ["bucketContainer", "itemContainer"],
	"compOrder": ["itemContainer", "bucketContainer"],
	"numCardsCarousel": 1,
	"animationSpeed": 300,
	"cardLayout": "grid", // grid, carousel
	"carouselType": "horizontal", // horizontal, vertical
	"tolerance": "pointer",
	"bucketWidth": 160,
	"bucketHeight": 260,
	"droppedCardWidth": 150,
	"droppedCardHeight": 55,
	"qid": getFormName(1),	
	"formNames": {
		"time_qid": "",
		"order_qid": "",
		"exclusive_qid": ""
	},
	"answerItemConfig": {
		"width": "240px",
		"height": "50px",
		"numItemsPerRow": 4
	},
	"customBucketSettings" : {
		bucket_qid : getFormName(1)+"Header",
    	showBucketBy: "button", // "free" - show buckets when card is dragged || "button" - add +/- button to show or hide buckets
		initBucketShown: 1,
		
		//for manual adding of new group
    	btnPosition : "top", //top or bottom of the buckets
    	addOnEmpty : false,
	},
	"customValidation": function(q) {
		console.log("customValidation()");
		return true;
	},	
	mobileConfig: {}

};


ketool.toolLoader.registerSettings(toolSettings, function(info) {
	// console.log("Questions loaded");
	// console.log(JSON.stringify(info.bridge._platformInterface._questions));
	// console.log("info: ", info);

	info.bridge.setPageValidation(function() {
		// console.log("setPageValidation");
		return true;
	});
	
	info.instance.on("item_dropped", function(e) {
		ketool.customPlugin.func.onItemDropped(info, toolSettings, e)
	});
	info.instance.on("tool_loaded", function(e) {
		//console.log("tool_loaded", e);
		ketool.customPlugin.func.initGroupings(info, toolSettings)
		
		if (isTest) {
			${initKEToggleData()}
		}
	});
});

$ (function() {
	ketool.toolLoader.initLoad();
	
});
</script>
]]></style>
  </radio>

  <text 
   label="ketoolCardsort1Header"
   translateable="0">
    <title>Bucket Name</title>
    <row label="c2">2</row>
    <row label="c3">3</row>
    <row label="c4">4</row>
    <row label="c5">5</row>
    <style name="question.after"><![CDATA[
<script type='text/javascript'>if (ketool.qDefs) ketool.qDefs["${this.label}"] = ${jsexport()};</script>
]]></style>
  </text>
  <suspend/>

mobile-phone
Bucket Sort Custom2 (Free Bucket)

  <define label="ketoolCardsort2Row">
    <row label="r1">Guacamole</row>
    <row label="r2">Hummus</row>
    <row label="r3">Salsa</row>
    <row label="r4">Applesauce</row>
    <row label="r5">Breakfast meat (e.g., bacon, sausage)</row>
    <row label="r6">Bruschetta</row>
    <row label="r7">Butter/margarine</row>
    <row label="r8">Candy bar/ Chocolate candy</row>
    <row label="r9">Canned soups</row>
    <row label="r10">Cheese dips</row></define>
  <define label="ketoolCardsort2Col">
    <row label="c1">1</row>
    <row label="c2">2</row>
    <row label="c3">3</row>
    <row label="c4">4</row>
    <row label="c5">5</row></define>
  <radio 
   label="ketoolCardsort2"
   builderHint="{"rocochoName":"radiogrid"}"
   fir="off"
   ss:questionClassNames="ketool-main-question-container"
   surveyDisplay="desktop">
    <title>Group the following ingredients</title>
    <comment>You can drag each ingredients and drop it into the group of your choice.</comment>
    <insert source="ketoolCardsort2Row"/>
    <insert as="cols" source="ketoolCardsort2Col"/>
    <style name="page.head"><![CDATA[
<style>
.answers{display:none;}
#btn_continue {visibility: hidden;}
.question:not(.ketool-main-question-container) {padding-top: 0;margin-top: 0;padding-bottom: 0;margin-bottom: 0;width: 100%;max-width:calc(924px - 15px);}
</style>
]]></style>
    <style name="question.after"><![CDATA[
<div class="ketool-stage" id="ketool-stage-${this.label}" style="margin-bottom: 50px; margin-top: -30px;"></div>
<script type="text/javascript" src="${KEDomain}/core/framework.min.js"></script>

<script>

if (!ketool.qDefs) {

	ketool.qDefs = {};
	if (!ketool.toolLoader) {
		ketool.toolLoader = new ketool.Loader({
			"baseFileURL": "${KEDomain}/core/",
			"scriptDeps": [
              "fancybox/fancybox.library.js",
              "plugins/jquery-ui.min.js",
              "plugins/jquery.ui.touch-punch.min.js",
              "plugins/jquery_clickfix.ui.touch-punch.min.js",
              "advanced_ui/Carousel_libs.js",
              "advanced_ui/Carousel.js"




			],
			"cssDeps": [
              "framework.css",
              "fancybox/fancybox.library.css",
              "ionicons/ionicons.min.css",
              "plugins/jquery-ui.css",
              "advanced_ui/Carousel_libs.css",
              "advanced_ui/Carousel.css"

            ],
                        "coreFile": "application.min.js",
                        "messages": null,
                        "platformInterface": { js: "platform_interface/platform_interface.js", "css": "platform_interface/platform_interface.css" }
                    });
                    console.log("ketool.toolLoader: ", ketool.toolLoader);
                }
            }
ketool.qDefs["${this.label}"] = ${jsexport()};
var isTest = "${gv.isUser() and not gv.debug.respview}" === "True";

var toolSettings = {
	"toolJs": "application.min.js",
	"toolName": "Cardsort",
	"jsToLoad": ["custom_bucket/customBucket.js"],
	"cssToLoad": ["style.css", "custom_bucket/customBucket.css"],
	"baseToolPath": "${KEDomain}/tools/card_sort/",
	"container": "#ketool-stage-${this.label}",
	"toolCssNames": [],
	"imageBaseURL": "",
	"minRequired": ${len(this.rows)},
	"maxAllowed": ${len(this.rows)},
	"timeDataNumDecimals": 2,
	"autoNext": false,
	"autoNextItem": true,
	"numRequiredGroups": 1,
	"maxAllowedInGroups": 0,
	"maxCardDrop": 1,
	"showZoom": false,
	"zoomPosition": "bottom-right",
	"oneByOne": false,
	"isRanking": false,
	"isLadder": false,
	"showCounter": true,
	"countPrefix": "",
	"countDelimiter": "/",
	"countSuffix": "",
	//"compOrder": ["bucketContainer", "itemContainer"],
	"compOrder": ["itemContainer", "bucketContainer"],
	"numCardsCarousel": 1,
	"animationSpeed": 300,
	"cardLayout": "grid", // grid, carousel
	"carouselType": "horizontal", // horizontal, vertical
	"tolerance": "pointer",
	"bucketWidth": 160,
	"bucketHeight": 260,
	"droppedCardWidth": 150,
	"droppedCardHeight": 55,
	"qid": getFormName(1),	
	"formNames": {
		"time_qid": "",
		"order_qid": "",
		"exclusive_qid": ""
	},
	"answerItemConfig": {
		"width": "240px",
		"height": "50px",
		"numItemsPerRow": 4
	},
	"customBucketSettings" : {
		bucket_qid : getFormName(1)+"Header",
    	showBucketBy: "free", // "free" - show buckets when card is dragged || "button" - add +/- button to show or hide buckets
		initBucketShown: 1,
		
		//for manual adding of new group
    	btnPosition : "top", //top or bottom of the buckets
    	addOnEmpty : false,
	},
	"customValidation": function(q) {
		console.log("customValidation()");
		return true;
	},	
	mobileConfig: {}

};


ketool.toolLoader.registerSettings(toolSettings, function(info) {
	// console.log("Questions loaded");
	// console.log(JSON.stringify(info.bridge._platformInterface._questions));
	// console.log("info: ", info);

	info.bridge.setPageValidation(function() {
		// console.log("setPageValidation");
		return true;
	});
	
	info.instance.on("item_dropped", function(e) {
		ketool.customPlugin.func.onItemDropped(info, toolSettings, e)
	});
	info.instance.on("tool_loaded", function(e) {
		//console.log("tool_loaded", e);
		ketool.customPlugin.func.initGroupings(info, toolSettings)
		
		if (isTest) {
			${initKEToggleData()}
		}
	});
});

$ (function() {
	ketool.toolLoader.initLoad();
	
});
</script>
]]></style>
  </radio>

  <text 
   label="ketoolCardsort2Header"
   translateable="0">
    <title>Bucket Name</title>
    <insert source="ketoolCardsort2Col"/>
    <style name="question.after"><![CDATA[
<script type='text/javascript'>if (ketool.qDefs) ketool.qDefs["${this.label}"] = ${jsexport()};</script>
]]></style>
  </text>
  <suspend/>
		
General Instructions for all ketool setups

For all ketool setup, please implement the below block at the start of the survey XML

<exec when="init">
KEDomain = "https://au.focusvision.com/survey/selfserve/560/221003"
project_id = gv.survey.path

def initKEToggleData():
  returntext = "\n var dataToggler = jQuery('<div>For testing only - click here to expand data capturing nodes to verify the data capture during test mode.</div>');\n"
  returntext += "dataToggler.addClass('dataToggle');\n"
  returntext += "dataToggler.css({'text-decoration': 'underline','font-size': 'small','color': 'blue','cursor': 'pointer','margin-top': '20px'});\n"
  returntext += "jQuery('.ketool-stage').last().after(dataToggler);\n"
  returntext += "dataToggler.click(info.bridge.toggleDataNodes());\n"
  return returntext

def initkelegacyDataToggle():
  if gv.isUser() and not gv.debug.respview:
    output = "<script>\n"
    output += "var dataToggler = jQuery('<div>Please click here to see the data nodes for this tool.</div>');\n"
    output += "dataToggler.addClass('dataToggle');\n"
    output += "dataToggler.css({'text-decoration': 'underline','font-size': 'small','color': 'blue','cursor': 'pointer','margin-top': '20px'});\n"
    output += "dataToggler.click(kelegacyDataToggle);\n"
    output += "function kelegacyDataToggle(){ if(jQuery('.survey-page').hasClass('showkelegacyData')) jQuery('.survey-page').removeClass('showkelegacyData'); else jQuery('.survey-page').addClass('showkelegacyData');  }\n"
    output += "jQuery(function(){jQuery ('.survey-buttons').before(dataToggler); })\n"
    output += "</script>\n"
    output += "<style>.showkelegacyData .answers,.showkelegacyData .question{display: block !important;visibility: visible !important;}</style>\n"
    return output
  else:
    return ""
</exec>

We also have few general options in all ketool setups with function “initKEToggleData” is being called, which should not be changed, these are:


These options are optional and should only be implemented if needed:
For any follow-up question (including “_time”, “_order” questions) should include the below code:
<exec when="init">
<style name="question.after"><![CDATA[
<script type='text/javascript'>if (ketool.qDefs) ketool.qDefs["${this.label}"] = ${jsexport()};</script>
]]></style>
We can also use below row/column/group options (wherever applicable) in each row in format “{@rowOption1::rowOption1Value|| rowOption2::rowOption2Value @}” wherever required, all the possible options in a question are mentioned below.

Card Sort based Setups (#11, #12, #13, #19 & #20)
We have multiple setups i.e. Bucket Sort Single, Bucket Sort Multi Bucket Sort (with images), Bucket Sort Custom #1 (with few predefined scales) and Bucket Sort Custom #1 (with no predefined scales) based on base card sort type questions, so for these we will have below settings and its uses:
Tool Settings Use Value Type / Syntax Default Value / Possible Values
minRequired Minimum number of cards that the user must drop before the next button is shown. A value of 0 = no cards required to be dropped. Number > 0 2
maxAllowed Maximum number of cards that the user can drop. Setting this to 0 means any number of cards can be dropped. Number > 0 0
maxCardDrop The maximum number of times a card can be dropped. Number > 0 1
showZoom Zoom-in buttons appear if true. boolean false
bucketHeight Bucket option height (px). String (for width in px) 260
bucketWidth Bucket option width (px). String (for width in px) 160
droppedCardWidth Width of card when inside bucket. String (for width in px, %, em, rem) 140
droppedCardHeight Height of card when inside bucket. String (for width in px, %, em, rem) 55
answerItemConfig width Answer option width String (for width in px, %, em, rem) 300px
height Answer option height (px). String (for width in px) 100px
numItemsPerRow number of items per row to be displayed in a grid system custom format {"small": 1, "medium": 1, "large": 1}
Here we can specify number in the above (i.e. replace 1 by specific value)
formNames time_qid Question for holding the timers. Make sure you have the same option code list/order as in the grid. string
order_qid Question for holding the order data. Make sure you have the same option code list/order as in the grid. string
exclusive_qid Single response question for holding the overall exclusive data. The question itself can have multiple rows - for multiple overall exclusive options string
cardLayout Layout of how cards are shown. When isMobile is set to true, the cardLayout will always be 'carousel'. Fixed string Default value: grid
Possible values: ["grid","carousel"]
isRanking If true, only 1 item can dropped on every option. Boolean false
timeDataNumDecimals Number of decimal places that the time data should be stored. number > 0 2
autoNext Auto next when validation is met. Boolean false
autoNextItem Whether to automatically move to the next item after answering. Boolean True
numRequiredGroups The minimum number of dropzones that must have cards dropped in it before the user can proceed forward. Minimum 1. number > 0 0
maxAllowedInGroups The maximum number of cards that can be added to groups. Setting this to 0 means any number of cards can be dropped. 'min' property in answer scale options overrides this. number > 0 0
zoomButtonImage Image URL to use for the 'zoom' button that appears on answer cards. Boolean Path already specified; no change needed here
zoomPosition Position of the zoom button. Fixed string Default value: bottom-right
Possible values: ["bottom-right","top-right","bottom-left","top-left"]
oneByOne If true, all draggable items are stacked and one is shown at a time. False and all items are shown in a carousel. This overrides 'numCardsCarousel' if set to true (effectively sets this to 1). Boolean false
isLadder If true, vertical ranking is shown. Only works if 'isRanking' set to true. boolean false
showCounter (For 'cardLayout' : 'carousel') Set to true to show progress indicator. boolean true
countPrefix Text that appears at the start of the counter text. string
countDelimiter Text that appears between the numbers in the counter text. string /
countSuffix Text that appears at the end of the counter text. String
numCardsCarousel (For 'cardLayout' : 'carousel')
Number of cards shown at once in the carousel.
If 'oneByOne', 'isMobile', 'autoNextItem' is set to true, it effectively ignores any value here and sets a value of 1 for this param.
If this param is not specified then the tool will attempt to show as many cards as possible based off the card size.
number > 0 1
animationSpeed (For 'cardLayout' : 'carousel') Transition speed between cards in carousel. number > 0 300
tolerance Which mode to use for testing whether a draggable is hovering over a droppable. Possible values: pointer, fit, intersect. Fixed string Default value: pointer
Possible values: ["pointer","fit","intersect"]
compOrder The position of any of the core parts of the tool from top to bottom.(e.g. \"itemContainer\",\"bucketContainer\")" array Default value: ["itemContainer","bucketContainer"]
Possible values: ["itemContainer","bucketContainer"]
carouselType Determines the layout of carousel Fixed string Default value: horizontal
Possible values: ["horizontal","vertical"]
isMobile Determines whether card sort should be displayed in mobile mode. Boolean false
mobileConfig showCarouselNav Whether to show the carousel navigation buttons. boolean true
showErrorMessage Whether to display the error messages. boolean true
errorMessages isInBucketError Message to display if item is already in the bucket. String Item already in bucket.
maxAllowedError Message to display if maximum # of items that can be dropped is reached. String You've reached the max number of items that can be dropped.
maxAllowedInGroupsError Message to display if maximum # of items in bucket is reached. String You've reached the max number of items allowed in this bucket.
otherMinChar Minimum character required for the other specify box. number > 0 0
Row Options Use Value Type / Syntax Possible Values
imageURL URL for image to be displayed in the answer option cards. string Image file URL
largeImageURL Alternative URL for image to be displayed in the zoom window if different from the image in the card. string Image file URL
width Custom width to apply to this answer option. string Width in px, rem, em or %
height Custom height to apply to this answer option. string Width in px, rem, em or %
other Whether this card is an 'other, please specify' boolean
Scale/column Options Use Value Type / Syntax Possible Values
width Custom width to apply to this scale option. string Width in px, rem, em or %
height Custom height to apply to this scale option. string Width in px, rem, em or %
min The minimum number of items this group must have dropped in it before the user can proceed past this question number > 0
max The maximum number of items this group can contain number > 0