1
votes

I want to perform a row switch onclick, like in example below. The only way primefaces allow swapping rows is make them draggable, which is not an option to me. Poked it for about a day, no luck. I would appreciate any assistance, thanks! PF version 6.1.

function moveUp(id){
    let element = $("tr").find(`[data-ri='${id}']`);
    element.prev().before(element);
}
function moveDown(id){
        let element = $("tr").find(`[data-ri='${id}']`);
        element.next().after(element);
}
<p:dataTable id="prices-table" var="price" value="#{Bean.prices}">
    <p:ajax event="rowReorder" listener="#{Bean.onPriceReorder}"
            update="prices-table" />
    <p:column style="width:16px">
        <p:commandButton update="prices-table" onclick="moveUp()">up</p:commandButton>
        <p:commandButton update="prices-table" onclick="moveDown()">down</p:commandButton>
    </p:column>
    <p:column headerText="Title">
        <h:outputText value="#{price.title}" />
    </p:column>
</p:dataTable>
1
How would you re-order with a single click? Or do you want to have 'move-one-row-up/down' functionality? And where is the javascript code of the attempt? And tried a newer version of PF? And yes, making them technically draggable is required for this to function at all. You might be able to have them technically be draggable but functionally not by overriding some javascript.Kukeltje
Yes, i want up/down functionality. Unfortunately newer version of PF is also not an option. Tried different approaches with js, but i feel like i am not going into right direction. Updated code with one of suppose jquerry solution (not working).Алексей
You need row ordering to be configured on the datatable. Otherwise this issue is not primefaces related at all but a plain html/javascript thing (like you do now in the javascript. Look at the datatabke js source how drag/drop is done and fake that. Use its low-level javascript code)Kukeltje
To expand on Kukeltje's answer, I do row ordering by storing a line number for each item. Let's say you want to move line C above line B. That's the equivalent of subtracting one from C's line number, and adding one to B's line number. Then you sort and refresh the display. If you want to move line C down below line D, you add one to C's line number and subtract one from D's. Your "move up" and "move down" buttons can call the bean method to perform those actions.Tom T

1 Answers

1
votes

Thanks, i managed to do it without any JS at all, posting code for anyone who may stumble upon this issue. JSF:

<p:dataTable id="prices-table" var="price" value="#{Bean.prices}">
  <p:column style="width:16px">
    <p:commandButton update="@form" actionListener="#{Bean.movePrice(price, 'up')}">up</p:commandButton>
    <p:commandButton update="@form" actionListener="#{Bean.movePrice(price, 'down')}">down</p:commandButton>
  </p:column>
  <p:column headerText="Title">
    <h:outputText value="#{price.title}" />
  </p:column>
  <p:column headerText="Amount">
    <h:outputText value="#{price.amount}">
      <f:convertNumber minFractionDigits="2" type="currency" currencySymbol="$" />
    </h:outputText>
  </p:column>

Bean:

public void movePrice(Price price, String direction) {
    int orderPosition = price.getOrderPosition();
    boolean isPricesSwapped = false;
    if (direction.equals("up") && orderPosition != 0) {
        Collections.swap(prices, orderPosition - 1, orderPosition);
        isPricesSwapped = true;
    }
    if (direction.equals("down") && orderPosition != prices.size()) {
        Collections.swap(prices, orderPosition, orderPosition + 1);
        isPricesSwapped = true;
    }
    if (isPricesSwapped) {
        for (int i = 0; i < prices.size(); i++) {
            price = prices.get(i);
            price.setOrderPosition(i);
        }
    }
}