<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Drag and Drop &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/tag/drag-and-drop/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.xojo.com</link>
	<description>Blog about the Xojo programming language and IDE</description>
	<lastBuildDate>Mon, 18 Aug 2025 20:37:37 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Dragging to More Destinations</title>
		<link>https://blog.xojo.com/2025/03/25/dragging-to-more-destinations/</link>
		
		<dc:creator><![CDATA[William Yu]]></dc:creator>
		<pubDate>Tue, 25 Mar 2025 15:33:28 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[2025r1]]></category>
		<category><![CDATA[Drag and Drop]]></category>
		<category><![CDATA[DragItem]]></category>
		<category><![CDATA[FolderItem]]></category>
		<category><![CDATA[RawData]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=14626</guid>

					<description><![CDATA[It’s been a common complaint that on macOS you could not get the Destination of a FolderItem drag. That was then, but this is 2025r1&#8230;]]></description>
										<content:encoded><![CDATA[
<p>It’s been a common complaint that on macOS you could not get the Destination of a FolderItem drag. That was then, but this is 2025r1 and now dragging finally knows where it’s going, and it&#8217;s happy to reveal its Destination!</p>



<h2 class="wp-block-heading">The History</h2>



<p>While we’ve offered an API to get the Destination of a DragItem, it has been returning Nil on macOS for quite some time. In fact, it likely hasn’t worked since our transition from Carbon to Cocoa way back in the day. Amid all the API changes that came with that transition, DragItem.Destination was unfortunately left behind.</p>



<h2 class="wp-block-heading">A New Way to FolderItem Drag</h2>



<p>To avoid breaking existing code, we chose not to overhaul our entire drag-and-drop system just to support this feature. Instead, we’ve made a few simple additions that are necessary to get FolderItem drags to return a valid DragItem.Destination</p>



<p>Here’s how a FolderItem drag would currently be setup (for example in the DesktopWindow.MouseDown event):</p>



<pre class="wp-block-code"><code>Var fileToCopy As FolderItem = SpecialFolder.Temporary.Child("Test")
Var item As New DragItem(Self, 0, 0, 100, 100)
item.FolderItem = fileToCopy
item.Drag</code></pre>



<p>After dropping the item at its Destination, checking item.Destination would always return Nil:</p>



<pre class="wp-block-code"><code>If item.Destination = Nil Then
    MessageBox "Not a happy destination. &#x1f614;"
End If</code></pre>



<p>By making one simple addition and using the RawData API, we can now initiate FolderItem drags in a way that correctly returns a valid FolderItem.Destination.</p>



<pre class="wp-block-code"><code>Var fileToCopy As FolderItem = SpecialFolder.Temporary.Child("Test")
Var item As New DragItem(Self, 0, 0, 100, 100)
item.FolderItem = fileToCopy
item.RawData("public.file-url") = ""
item.Drag</code></pre>



<p>Now, when you check the Destination after the drag is complete, you&#8217;ll receive something much more meaningful:</p>



<pre class="wp-block-code"><code>If item.Destination &lt;&gt; Nil And item.Destination IsA FolderItem Then
    MessageBox(FolderItem(item.Destination).NativePath)
End If</code></pre>



<h2 class="wp-block-heading">An Added Benefit</h2>



<p>While this change is a big improvement, why stop there? In the past, you could only drag FolderItems to the Destination, and the entire contents of that FolderItem would be copied over. With the addition of this new dragging method, you can now assign content to&nbsp;<code>RawData("public.file-url")</code>. Instead of copying the entire FolderItem to the Destination, we’ll copy the content from the RawData&nbsp;instead.</p>



<p>Here&#8217;s how you could set it up:</p>



<pre class="wp-block-code"><code>// The fileToCopy does not need to exist, we'll simply
// pull the file name from it and create the file at
// the destination with the new content that is assigned
// to the RawData.
Var fileToCopy As FolderItem = SpecialFolder.Temporary.Child("DummyFile.txt")
Var item As New DragItem(Self, 0, 0, 100, 100)
item.FolderItem = fileToCopy
item.RawData("public.file-url") = "Content that will be written to the destination file."
item.Drag</code></pre>



<h2 class="wp-block-heading"><strong>Conclusion</strong></h2>



<p>With these enhancements, dragging FolderItems on macOS has become more flexible and powerful than ever. Not only can you now easily retrieve a valid&nbsp;<code>Destination</code>, but you also have the power to control the content being copied, thanks to the integration with the&nbsp;<code>RawData</code>&nbsp;API. </p>



<p>So, go ahead—drag that FolderItem and show us your destination!</p>



<p><em><em><em>William Yu grew up in Canada learning to program BASIC on a Vic-20. He is Xojo’s resident Windows and Linux engineer, among his many other skills. Some may say he has joined the dark side here in the USA, but he will always be a Canadian at heart.</em></em></em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Building a Web Kanban Board GUI with Drag and Drop Support</title>
		<link>https://blog.xojo.com/2025/03/25/building-a-web-kanban-board-gui-with-drag-drop-support/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Tue, 25 Mar 2025 15:32:34 +0000</pubDate>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[2025r1]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Drag and Drop]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=14651</guid>

					<description><![CDATA[Imagine a sleek, interactive Kanban board right in your browser: Columns labeled &#8220;To Do,&#8221; &#8220;In Progress,&#8221; and &#8220;Done,&#8221; each populated with cards representing tasks. With&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Imagine a sleek, interactive Kanban board right in your browser: Columns labeled &#8220;To Do,&#8221; &#8220;In Progress,&#8221; and &#8220;Done,&#8221; each populated with cards representing tasks. With Xojo’s new drag and drop support for web projects, you can grab a card with your mouse, drag it to another column to update its status, or even reorder it within the same column to prioritize it.</p>



<h2 class="wp-block-heading"><strong>The End Result</strong></h2>



<figure class="wp-block-video aligncenter"><video height="1410" style="aspect-ratio: 1854 / 1410;" width="1854" controls src="https://blog.xojo.com/wp-content/uploads/2025/03/kanban-board-demo.mp4"></video><figcaption class="wp-element-caption">Kanban board demo</figcaption></figure>



<p>The latest drag and drop example has a functional GUI that looks professional and feels intuitive. All without writing a single line of JavaScript (we will enhance it a bit with some CSS, though).</p>



<p>Please note this is a sample project created to explore drag and drop, not a full featured Kanban board. I&#8217;ll omit on purpose things like persistence. The complete project can be found in the Examples section of the IDE, under <strong>Platforms > Web</strong>.</p>



<p>Let’s walk through how to make it happen.</p>



<h2 class="wp-block-heading"><strong>Creating the Required Components</strong></h2>



<p>First, we need to define the building blocks of our Kanban board. In Xojo, WebContainers are perfect for modularizing reusable UI elements. Here’s what we’ll create:</p>



<ul class="wp-block-list">
<li><strong>KanbanCard</strong><br>A WebContainer to represent each task card. It’ll have a simple label for the task name (e.g., &#8220;Write blog post&#8221;) and maybe a colored border or handle to indicate it’s draggable. Add a WebLabel for the text and set its properties in the Inspector to make it visually distinct.</li>



<li><strong>KanbanCardContainer</strong><br>Another WebContainer to act as a column. It’ll hold multiple KanbanCard Containers and serve as both a drag source (where cards come from) and a drop target (where cards land). Include a WebLabel at the top for the column title (e.g., &#8220;To Do&#8221;) and a rectangular area below it to house the cards.</li>



<li><strong>Main Page</strong><br>A WebPage to host everything. This is where we’ll arrange our columns side by side.</li>
</ul>



<p>In the Xojo IDE, drag a WebContainer onto your project for the Card, another for the Column, and set up three instances of the Column Container on the main WebPage (&#8220;To Do,&#8221; &#8220;In Progress,&#8221; &#8220;Done&#8221;).</p>



<h2 class="wp-block-heading"><strong>KanbanCard</strong></h2>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img fetchpriority="high" decoding="async" width="1024" height="807" src="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-06-a-las-15.50.08-1024x807.png" alt="" class="wp-image-14653" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-06-a-las-15.50.08-1024x807.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-06-a-las-15.50.08-300x236.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-06-a-las-15.50.08-768x605.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-06-a-las-15.50.08.png 1190w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">The KanbanCard custom control</figcaption></figure>
</div>


<p>This component will be pretty easy to build. It is basically a WebRectangle with a WebLabel that we will use for the Title. To make it easier to update, I&#8217;ve added a Title Computed Property that will update the TitleLabel if needed.</p>



<p>For the background WebRectangle, we will use the following ColorGroup. Please notice Xojo added support for Named colors, that will rely on the current Bootstrap theme, supporting Dark Mode:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img decoding="async" width="1024" height="807" src="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-06-a-las-17.44.17-1024x807.png" alt="" class="wp-image-14654" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-06-a-las-17.44.17-1024x807.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-06-a-las-17.44.17-300x236.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-06-a-las-17.44.17-768x605.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-06-a-las-17.44.17.png 1190w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Adding a ColorGroup using a Bootstrap Named Color</figcaption></figure>
</div>


<p>As you can see, BackgroundRectangle and TitleLabel controls are implementing the Opening event. This is just to set the mouse cursor that will be shown when we hover:</p>



<pre class="wp-block-code xojo"><code>Me.Style.Cursor = WebStyle.Cursors.Move</code></pre>



<p>The container itself is also implementing the Opening event. This is to make this control draggable, using the following line of code:</p>



<pre class="wp-block-code xojo"><code>AllowTextDrag(WebDragItem.DragActionTypes.Move)</code></pre>



<p>Any descendant of the WebUIControl class is draggable. And yes, that includes custom controls created with the Web SDK.</p>



<p>For the WebDragItem.DragActionTypes Enumeration, you can choose one these options:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="324" height="386" src="https://blog.xojo.com/wp-content/uploads/2025/03/1-CopyAndLink.png" alt="" class="wp-image-14655" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/1-CopyAndLink.png 324w, https://blog.xojo.com/wp-content/uploads/2025/03/1-CopyAndLink-252x300.png 252w" sizes="(max-width: 324px) 100vw, 324px" /><figcaption class="wp-element-caption">The WebDragItem.DragActionTypes Enumeration</figcaption></figure>
</div>


<p>In this case we will only be allowed to &#8220;Move&#8221; a card from one place to another.</p>



<p>There are cases where it makes sense to support multiple drag action types. In your operating system&#8217;s file browser, when you drag and drop files and folders, you can change between Move, Link or Copy by using Keyboard shortcut combinations. Depending on the drag action type, the element will be moved, a symbolic link will be created, or it will be copied, respectively.</p>



<p>Normally you will implement just Move or Copy, but keep in mind it&#8217;s possible to have more (at the cost of increasing the learning curve of your application for your users)</p>



<p>Allowing something to be dragged is the first of two steps. You also need a place to drop these items into.</p>



<h2 class="wp-block-heading"><strong>KanbanCardContainer</strong></h2>



<p>This container will be more elaborate, but should be easy to follow. Let&#8217;s see how it works at runtime, with some annotations:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="895" height="1024" src="https://blog.xojo.com/wp-content/uploads/2025/03/WebLabel-895x1024.png" alt="" class="wp-image-14656" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/WebLabel-895x1024.png 895w, https://blog.xojo.com/wp-content/uploads/2025/03/WebLabel-262x300.png 262w, https://blog.xojo.com/wp-content/uploads/2025/03/WebLabel-768x879.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/WebLabel.png 1071w" sizes="auto, (max-width: 895px) 100vw, 895px" /><figcaption class="wp-element-caption">Combined controls to create the KanbanCardContainer</figcaption></figure>
</div>


<p>The WebLabel we used for the Title and the WebButton used for adding new cards are positioned manually in the IDE designer. Same as the invisible WebRectangle holding the KanbanCard items and the KanbanAddCard custom button.</p>



<p>But instead of placing our cards manually, we&#8217;ll take advantage of the browser&#8217;s capacity for doing this job for us. We just want to add them dynamically at runtime and let the browser stack them vertically, automatically. We also want the browser to display a scrollbar if the columns have several cards.</p>



<p>Here is the code we will add to the WebRectangle:</p>



<pre class="wp-block-code"><code>// Let the framework know we want to let the
// browser place the items automatically
Me.LayoutType = LayoutTypes.Flex

// This style will ensure cards won't be
// placed horizontally by the browser
Me.Style.Value("flex-direction") = "wrap"

// If there are more cards than available
// space, this style will allow the user
// to scroll
Me.Style.Value("overflow") = "auto"</code></pre>



<p>Let&#8217;s add some methods to add and remove cards at runtime.</p>



<ul class="wp-block-list">
<li>AddCardWithTitle(title As String)</li>



<li>AddCardWithTitleAt(title As String, index As Integer)</li>



<li>RemoveCardAt</li>
</ul>



<h2 class="wp-block-heading"><strong>Moving Cards Between Columns</strong></h2>



<p>Here’s where Xojo’s drag and drop shines. Each Card Container needs to be draggable and each Column Container needs to accept dropped cards. In Xojo:</p>



<ol class="wp-block-list">
<li><strong>Make Cards Draggable</strong>: Open the KanbanListCard in the IDE and implement the Opening event. Enter this code:<br><code>AllowTextDrag(WebDragItem.DragActionTypes.Move)</code></li>



<li><strong>Accept Card Drops:</strong> Open the KanbanCardContainer and implement the Opening event. This is the code we need in order to accept drops:<br><code>AcceptTextDrop(WebDragItem.DragActionTypes.Move)</code></li>



<li><strong>Remove from Source</strong>: To move (not copy) the card, in the source Column’s DragEnd event, remove the dragged card from its original parent after a successful drop.</li>
</ol>



<p>With this, you can drag a card from &#8220;To Do&#8221; to &#8220;In Progress,&#8221; and it’ll visually jump columns. Xojo handles the heavy lifting. No JavaScript or DOM manipulation needed!</p>



<h2 class="wp-block-heading"><strong>The Hard Part: Reordering Cards</strong></h2>



<p>Reordering cards within a column, or dropping a card into another column in a specific position is trickier. You need to detect where the card lands among its siblings and adjust their positions. Xojo’s drag and drop doesn’t natively sort UI elements, so we’ll simulate it.</p>



<p>There are several ways to achieve this, let&#8217;s explore some options.</p>



<p>One would be to deal with X/Y coordinates. Once you drop a card, you could take a look to see where the card landed, compare the coordinates with the other cards and reorder them accordingly. In desktop and mobile projects this could be a valid solution. In web projects, dealing with specific coordinates might work, but there are more accurate and easier solutions.</p>



<p>The second way could be good enough in most cases. Cards could also accept drops so, if you drop one card on another, we just have to put the card being dropped in the position where it&#8217;s being dropped, and push down the rest of the stack. This way you won&#8217;t need to scratch your head and deal with screen coordinates or control dimensions. The end result will be based on this idea.</p>



<p>But what should we do to generate the gap between Cards? Maybe you can create a transparent Container that also accept Card drops, to simulate the gap between cards.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="1024" src="https://blog.xojo.com/wp-content/uploads/2025/03/KanbanCardContainer-1024x1024.png" alt="" class="wp-image-14657" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/KanbanCardContainer-1024x1024.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/KanbanCardContainer-300x300.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/KanbanCardContainer-150x150.png 150w, https://blog.xojo.com/wp-content/uploads/2025/03/KanbanCardContainer-768x768.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/KanbanCardContainer.png 1158w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">One way of achieving sorting, that we are not using in the sample project</figcaption></figure>
</div>


<p>This would work for you, and I honestly recommend you to give it a try, it&#8217;s super easy to implement and it will just work. If you don&#8217;t want to explore the CSS rabbit hole, that&#8217;s fine, this can be your bus stop.</p>



<p>Two downsides:</p>



<ul class="wp-block-list">
<li>You won&#8217;t have animations</li>



<li>You will double the amount of controls on screen (performance may suffer)</li>
</ul>



<p>I went in another direction though. Using some CSS, you can add and modify margins on the fly, with neat transitions. In my sample project, the margin between cards is managed by the `margin-top` CSS style.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="274" height="444" src="https://blog.xojo.com/wp-content/uploads/2025/03/In-Progress.png" alt="" class="wp-image-14658" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/In-Progress.png 274w, https://blog.xojo.com/wp-content/uploads/2025/03/In-Progress-185x300.png 185w" sizes="auto, (max-width: 274px) 100vw, 274px" /><figcaption class="wp-element-caption">Top margin added to KanbanCardContainer, using CSS styles</figcaption></figure>
</div>


<p>And here is where the Xojo Framework helps. To make styling easier, it adds a CSS class to the element being dragged and also to the element where the mouse is over, when it&#8217;s accepting a drop.</p>



<p><code>dragging</code> &#8211; The HTML element being dragged will have this property<br><code>dragover</code> &#8211; The HTML element under the other element being dragged</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="815" src="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.15.44-1024x815.png" alt="" class="wp-image-14659" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.15.44-1024x815.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.15.44-300x239.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.15.44-768x611.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.15.44-1536x1223.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.15.44-2048x1630.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Some CSS Classes added by the Xojo Web Framework at runtime, to help styling Drag and Drop</figcaption></figure>
</div>


<p>In this case, the &#8220;Bar&#8221; card will receive the dragging CSS class, while &#8220;Test #2&#8221; will receive the dragover CSS class, while the &#8220;Bar&#8221; car is above.</p>



<p>I&#8217;ve added some transparency to elements with the dragging class. As you can see in the screenshot, the &#8220;Bar&#8221; Card opacity is set to 30%.</p>



<p>For dragover class, I&#8217;ve added some margin and transitions. If you drag something into a card, the top margin will grow, simulating it&#8217;s making room for the card you are about to drop.</p>



<p>Here is how the HTML Header section of the sample project looks like. It isn&#8217;t too much code, but it does uses some somewhat advanced CSS tricks:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="807" src="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.29.14-1024x807.png" alt="" class="wp-image-14660" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.29.14-1024x807.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.29.14-300x236.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.29.14-768x605.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.29.14-1536x1211.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.29.14-2048x1614.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Custom CSS added to App &gt; HTML Header</figcaption></figure>
</div>


<p>This approach keeps cards neatly stacked and sortable. It’s the &#8220;hard part&#8221; not because you will have to write a lot of code, but because you&#8217;ll actually have to think a solution that won&#8217;t require roundtrips between the browser and the server. Xojo’s event system makes it manageable without JavaScript, and with some CSS, the result will be great.</p>



<h2 class="wp-block-heading"><strong>Some CSS Enhancements</strong></h2>



<p>In some cases I&#8217;m using shadows and border radius using the Bootstrap&#8217;s CSS classes.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="807" src="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.44.21-1024x807.png" alt="" class="wp-image-14661" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.44.21-1024x807.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.44.21-300x236.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.44.21-768x605.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.44.21-1536x1211.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.44.21-2048x1614.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Bootstrap CSS Classes to make the card be rounded and have a subtle shadow</figcaption></figure>
</div>


<p>As you can see, I&#8217;m using rounded-2 for the border radius, and shadow-sm to easily add a shadow to the cards.</p>



<p>You can read more about this in the following blog post:<br><a href="https://blog.xojo.com/2024/10/01/introducing-named-color-and-css-classes-in-xojo-web/" data-type="post" data-id="13668">Introducing Named Color and CSS Classes in Xojo Web</a></p>



<p>There is a related sample project you might want to check:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="822" src="https://blog.xojo.com/wp-content/uploads/2025/03/Platform-1024x822.png" alt="" class="wp-image-14662" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/Platform-1024x822.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/Platform-300x241.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/Platform-768x616.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/Platform-1536x1233.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/03/Platform.png 1762w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Xojo Web Examples</figcaption></figure>
</div>


<h2 class="wp-block-heading"><strong>Closing Thoughts</strong></h2>



<p>This has been a fun experiment to explore the Xojo Web drag and drop feature. Give the sample project a try and explore each control to see how it&#8217;s been created. I can&#8217;t recommend enough that you try to build it from scratch (and ask in the forum if you get stuck!)</p>



<p>We can&#8217;t wait to hear about how you plan to introduce drag and drop into your projects. Don&#8217;t be shy and create a forum thread to show what you have built, or what you are working on.</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2025/03/kanban-board-demo.mp4" length="710061" type="video/mp4" />

			</item>
	</channel>
</rss>
