Skip to Content
Technical Articles
Author's profile photo Sumanth Nandeti

SAP UI5 Drag and Drop Functionality for Tokenizer(Custom)

  1. SAP-UI5 DRAG AND DROP FUNCTIONALITY

 

In this we are going to learn about how to implement Drag and Drop for SAP-UI5 controls.

My requirement is to Drag and Drop tokens of Tokenizer from one container to another container (here I have used a VBox as my container)

In order to achieve this, we need to Extend the Tokenizer control as Draggable and Droppable

 

Scenario:

We will be having 4 sets of data containers with Tokens in it. Here we need to drag and drop the tokens from one set to another set

Now I will be selecting one token from Set A and I will drop it Set D which is empty now.

Click and Drag a token from Set A

Drop it in Set D

You can see, now it is dropped in Set D

 

 

Coding:

Here we are Dragging the tokens and dropping in VBox’s. We need to add “Drag Info” feature to the Tokenizer. It is disabled by default. We should enable it by extending the Tokenizer control as shown below

// Code for Extending Tokenizer //

sap.ui.define([
	"sap/m/Tokenizer"
], function (Tokenizer) {
	"use strict";
	return Tokenizer.extend("com.test.Tokenizer.util.DragTokenizer", {
		metadata: {
			aggregations : {
		      tokens : { type: 'sap.ui.core.Control', multiple : true, dnd : {draggable: true, droppable: true, layout: "Horizontal" } },
		      header : {type : "sap.ui.core.Control", multiple : false, dnd : true }
		    }
		},
		renderer: {}
	});
});

 

And now we want to drag “tokens”, so we need to specify this as which aggregation we are going to drag, in “Drag Info” for the custom tokenizer we built. Keep the Source aggregation as “tokens” as we want to drag the tokens

// Code of Xml //

   <DT:DragTokenizer class="SelectedFracMapToken" tokens="{fracMappingData>/FracThreeTokens}" width="100%">
				<DT:dragDropConfig>
					<dnd:DragInfo sourceAggregation="tokens"/>
				</DT:dragDropConfig>		<Token class="selectedTokenText" key="{fracMappingData>WellName}"  tooltip="{fracMappingData>WellName}" text="{fracMappingData>WellName}"/>
	</DT:DragTokenizer>

Now we need to specify where to drop the token, so we need to provide “Drop info” to the VBox as shown below

// Code for Drop Info //

<mvc:View controllerName="com.test.Tokenizer.controller.View1" xmlns:dnd="sap.ui.core.dnd" xmlns:mvc="sap.ui.core.mvc" displayBlock="true"
	xmlns:DT="com.test.Tokenizer.util" xmlns="sap.m">
	<Shell id="shell">
		<App id="app">
			<pages>
				<Page id="page" title="Drag And Drop Functionality">
					<content>
						<HBox class="hboxHeader">
							<Label text="Set A" width="12rem"></Label>
							<Label text="Set B" width="12rem"></Label>
							<Label text="Set C" width="12rem"></Label>
							<Label text="Set D" width="12rem"></Label>
						</HBox>
						<HBox>
							<VBox width="12rem">
								<dragDropConfig>
									<dnd:DropInfo drop="onTokenDrop"/>
								</dragDropConfig>
								<DT:DragTokenizer class="SelectedFracMapToken" tokens="{fracMappingData>/FracOneTokens}" width="100%">
									<DT:dragDropConfig>
										<dnd:DragInfo sourceAggregation="tokens"/>
									</DT:dragDropConfig>
									<Token class="selectedTokenText" key="{fracMappingData>WellName}" tooltip="{fracMappingData>WellName}" text="{fracMappingData>WellName}"></Token>
								</DT:DragTokenizer>
							</VBox>
							<VBox width="12rem">
								<dragDropConfig>
									<dnd:DropInfo drop="onTokenDrop"/>
								</dragDropConfig>
								<DT:DragTokenizer class="SelectedFracMapToken" tokens="{fracMappingData>/FracTwoTokens}" width="100%">
									<DT:dragDropConfig>
										<dnd:DragInfo sourceAggregation="tokens"/>
									</DT:dragDropConfig>
									<Token class="selectedTokenText" key="{fracMappingData>WellName}"  tooltip="{fracMappingData>WellName}" text="{fracMappingData>WellName}"/>
								</DT:DragTokenizer>
							</VBox>
							<VBox width="12rem">
								<dragDropConfig>
									<dnd:DropInfo drop="onTokenDrop"/>
								</dragDropConfig>
								<DT:DragTokenizer class="SelectedFracMapToken" tokens="{fracMappingData>/FracThreeTokens}" width="100%">
									<DT:dragDropConfig>
										<dnd:DragInfo sourceAggregation="tokens"/>
									</DT:dragDropConfig>
									<Token class="selectedTokenText" key="{fracMappingData>WellName}"  tooltip="{fracMappingData>WellName}" text="{fracMappingData>WellName}"/>
								</DT:DragTokenizer>
							</VBox>
							<VBox width="12rem">
								<dragDropConfig>
									<dnd:DropInfo drop="onTokenDrop"/>
								</dragDropConfig>
								<DT:DragTokenizer class="SelectedFracMapToken" tokens="{fracMappingData>/FracFourTokens}" width="100%">
									<DT:dragDropConfig>
										<dnd:DragInfo sourceAggregation="tokens"/>
									</DT:dragDropConfig>
									<Token class="selectedTokenText" key="{fracMappingData>WellName}"  tooltip="{fracMappingData>WellName}" text="{fracMappingData>WellName}"/>
								</DT:DragTokenizer>
							</VBox>
						</HBox>
					</content>
				</Page>
			</pages>
		</App>
	</Shell>
</mvc:View>

Now you can drag and drop the tokens. On each drag and drop we need to delete an item from Previous set and we should add it in the new set. This functionality will be done on dropping of the token

On drop of the tokens, we need to call an event to perform necessary actions. For that we have “drop” event we will use that as shown below

// Code for functionality //

onTokenDrop:function(oEvent){
		var DragBindingContext=oEvent.getParameters().draggedControl.getBindingContext("fracMappingData").sPath.split("/");
				var DragBindingBucket=DragBindingContext[1];
				var Dragpath=DragBindingContext[2];
				var dragged=this.getView().getModel("fracMappingData").getProperty("/"+DragBindingBucket);
				
				var DropBindingContext=oEvent.getParameters().droppedControl.mAggregations.items[0].mBindingInfos.tokens.path.split("/");
				var DropBindingBucket=DropBindingContext[1];
				var dropped=this.getView().getModel("fracMappingData").getProperty("/"+DropBindingBucket);
				dropped.push(dragged[Dragpath]);
				this.getView().getModel("fracMappingData").setProperty("/"+DropBindingBucket,dropped);
				 dragged.splice(Dragpath,1);
				 this.getView().getModel("fracMappingData").setProperty("/"+DragBindingBucket,dragged);
		}

 

Conclusion:

With this tutorial, I intended to convey how easy it is to make any control as draggable and droppable. This property and event is given by default by SAP, just that we need to extend and enable it and rest will fall in place.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Assigned Tags

      5 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo George Abraham
      George Abraham

      This is really a good article! Well done and keep up.

      Author's profile photo Sumanth Nandeti
      Sumanth Nandeti
      Blog Post Author

      Thank you so much George 🙂

      Author's profile photo Tritty Tang
      Tritty Tang

      Hi Sumanth,

      I use Tokenizer inside a TreeTable with drag and drop functionality (the table row is draggable and dropable). Now the dnd seems to work fine but when dragging row with Tokenizer, the drag ghost does not show up. This issue won't happen when dragging a row with no Tokenizer. I tried your solution but it still doesn't work. Do you know what's happening here? Do you have any clue to solve this problem? Thank you sooooo much.

      Author's profile photo Jingjing Guo
      Jingjing Guo

      Great idea!

      I used your solution directly, but tokens inside tokenizer are not arranged vertially. So it looks like VBox is not taking effect.

      So i adjust the solution a little bit. Instead of extending m.Tokenizer, i extended m.FlexBox, and it works perfectly.

      sap.ui.define([
      "sap/m/FlexBox"
      ], function (FlexBox) {
      "use strict";
      returnFlexBox.extend("sap.my.control.FlexBox", {
      metadata: {
      aggregations : {
      items : {
      type:'sap.ui.core.Control',
      multiple :true,
      singleName:"item",
      dnd : {draggable:true, droppable:false, layout:"Horizontal" }
      }
      }
      },
      renderer: {}
      });
      });

       

      xml:

      <my:FlexBox id="ticketDimensionBox" class="sapUiTinyMargin"
      direction="Column"alignItems="Start"
      items="{path:'mymodel>/dimension'}">
      <my:dragDropConfig>
      <dnd:DragInfosourceAggregation="items"/>
      </my:dragDropConfig>
      <Tokentext="{mymodel>text}"editable="false"/>
      </my:FlexBox>
      Author's profile photo Sumanth Nandeti
      Sumanth Nandeti
      Blog Post Author

      Good Work Jingjing Guo,

      I have used CSS Properties to get tokens vertically aligned in the VBox.

      .SelectedFracMapToken .selectedTokenText {

      display: inline-flex !important;
      justify-content: space-between !important;

      }

      Extending FlexBox instead of Tokenizer will also work in the same. its really nice approach.

      Thanks for dragging your knowledge and dropping here 🙂