Drag handles provide a dedicated area for grabbing and moving cards. When enabled, only the handle icon on each item is draggable, preventing accidental drags when clicking on card content. This is especially useful when items contain interactive elements or when precise click vs. drag distinction is needed.
Source
<h:outputScript>
function kanbanDragHandleDefault() {}
function kanbanDragHandleGrip() {
this.cfg.itemHandleOptions = {
customCssHandler: 'drag_handler_grip',
customCssIconHandler: 'drag_handler_grip_icon'
};
}
</h:outputScript>
<div style="margin-bottom:8px">
<p:outputLabel for="dragHandle" value="Drag Handle" styleClass="font-bold" style="margin-right:8px" />
<p:selectOneMenu id="dragHandle" value="#{kanbanDragHandleController.dragHandle}" style="width:120px">
<f:selectItem itemLabel="Enabled" itemValue="true" />
<f:selectItem itemLabel="Disabled" itemValue="false" />
<p:ajax update="kanban" process="@this" />
</p:selectOneMenu>
<p:outputLabel for="handleStyle" value="Handle Style" styleClass="font-bold" style="margin:0 8px 0 16px" />
<p:selectOneMenu id="handleStyle" value="#{kanbanDragHandleController.handleStyle}" style="width:140px">
<f:selectItem itemLabel="Default" itemValue="default" />
<f:selectItem itemLabel="Grip" itemValue="grip" />
<p:ajax update="kanban" process="@this" />
</p:selectOneMenu>
</div>
<pe:kanban id="kanban"
widgetVar="kanbanDragHandleWidget"
value="#{kanbanDragHandleController.columns}"
draggable="true"
dragHandle="#{kanbanDragHandleController.dragHandle}"
extender="#{kanbanDragHandleController.extender}"
style="height:400px">
<p:ajax event="drop" listener="#{kanbanDragHandleController.onDrop}" update="growl" />
</pe:kanban>
@Named
@ViewScoped
public class KanbanDragHandleController implements Serializable {
private static final long serialVersionUID = 1L;
private List<KanbanColumn> columns;
private boolean dragHandle = true;
private String handleStyle = "default";
@PostConstruct
public void init() {
columns = new ArrayList<>();
KanbanColumn todoColumn = new KanbanColumn("todo", "To Do");
todoColumn.setCssClass("kanban-todo");
todoColumn.addItem(new KanbanItem("item1", "Add support for Kanban",
"Create a new Kanban component for PrimeFaces Extensions"));
todoColumn.addItem(new KanbanItem("item2", "Write documentation",
"Document the new component"));
KanbanColumn inProgressColumn = new KanbanColumn("inprogress", "In Progress");
inProgressColumn.setCssClass("kanban-inprogress");
inProgressColumn.addItem(new KanbanItem("item3", "Design component",
"Design the Kanban board component"));
KanbanColumn doneColumn = new KanbanColumn("done", "Done");
doneColumn.setCssClass("kanban-done");
doneColumn.addItem(new KanbanItem("item4", "Research libraries",
"Research available Kanban libraries"));
columns.add(todoColumn);
columns.add(inProgressColumn);
columns.add(doneColumn);
}
public void onDrop(KanbanDragEvent event) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Item Moved",
"Item " + event.getItemId() + " moved from " + event.getSourceColumnId()
+ " to " + event.getTargetColumnId() + " at position " + event.getNewPosition());
FacesContext.getCurrentInstance().addMessage(null, message);
}
public List<KanbanColumn> getColumns() {
return columns;
}
public boolean isDragHandle() {
return dragHandle;
}
public void setDragHandle(boolean dragHandle) {
this.dragHandle = dragHandle;
}
public String getHandleStyle() {
return handleStyle;
}
public void setHandleStyle(String handleStyle) {
this.handleStyle = handleStyle;
}
public String getExtender() {
if (!dragHandle) {
return null;
}
if ("grip".equals(handleStyle)) {
return "kanbanDragHandleGrip";
}
return "kanbanDragHandleDefault";
}
}