Компонент для «таблицы приоритетов» в JSF? - PullRequest
0 голосов
/ 07 апреля 2009

На определенной странице нашего приложения JSF пользователь видит таблицу со списком многих объектов, которые мы будем называть «заданиями». Допустим, у каждой работы есть приоритет, который является ничем иным, как числом, и на этом экране пользователь может редактировать приоритеты работ.

Однако два задания не могут иметь одинаковый номер приоритета. По этой причине мне трудно создать соответствующий пользовательский интерфейс для установки приоритетов.

В начале мы попробовали простое поле редактирования, но вскоре стало ясно, что оно отстой: если пользователь хочет снизить приоритет задания со 100 до 50, ему придется вручную «освободить место для этой работы», добавление 1 к заданиям от 50 до 99.

Теперь я думаю о таблице, в которой пользователь мог бы перетаскивать строки, чтобы визуально настроить приоритет, не прибегая к манипуляциям с номерами приоритетов (фактически никогда не видя их), но не могу найти такой компонент , Кто-нибудь знает о таком компоненте или есть предложения по улучшению пользовательского интерфейса?

Ответы [ 4 ]

1 голос
/ 15 апреля 2009

Не думаю, что вы найдете компонент, который изменит нумерацию приоритетов для вас. Вместо этого вы должны вызвать процедуру переупорядочения, которая обновит номера приоритетов соответственно после изменения приоритета.

Что касается перетаскивания, я предлагаю вам взглянуть на RichFaces или ICEFaces. У RichFaces есть очень удобная функциональность для реализации того, о чем вы говорите. Я рекомендую вам взглянуть на демонстрационную страницу RichFaces и попробовать компоненты поддержки перетаскивания. Набор компонентов RichFaces также получил список упорядочивания (в разделе Rich Selects), но, похоже, он не позволяет изменить порядок упорядочения путем ввода числа, скорее это делается с помощью кнопок вверх и вниз.

1 голос
/ 08 апреля 2009

Как насчет того, чтобы принять вашу текущую идею и позволить компьютеру выполнить работу по освобождению места?

Если пользователь вводит 50, отобразите предупреждение о том, что это задание существует, спросите, хотят ли они, чтобы новое задание было вставлено до или после текущего номера 50, или они хотят полностью отменить операцию. Если они решили вставить запись, вы переупорядочиваете другие элементы в коде.

0 голосов
/ 15 апреля 2009

Я подумал, что мне нужно пойти и посмотреть, сможете ли вы сделать это с готовыми компонентами и script.aculo.us . Это возможно, хотя было бы немного поработать над тем, чтобы он выглядел красиво и предоставлял удобный интерфейс.

Демонстрационный просмотр:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">
    <jsp:directive.page language="java"
        contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" />
    <jsp:text>
        <![CDATA[ <?xml version="1.0" encoding="ISO-8859-1" ?> ]]>
    </jsp:text>
    <jsp:text>
        <![CDATA[ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> ]]>
    </jsp:text>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
    <title>Sortable</title>
    <script src="javascripts/prototype.js" type="text/javascript">/**/</script>
    <script src="javascripts/scriptaculous.js" type="text/javascript">/**/</script>
    </head>
    <body>

    <f:view>
        <h:form>
            <h:dataTable id="table1" binding="#{jobPageBean.table}"
                value="#{jobBean.jobs}" var="row" border="1">
                <h:column>
                    <f:facet name="header">
                        <h:outputText value="jobs" />
                    </f:facet>
                    <h:outputText value="#{row.text}" />
                    <h:inputHidden value="#{row.priority}">
                        <f:convertNumber integerOnly="true" />
                    </h:inputHidden>
                </h:column>
            </h:dataTable>
            <h:commandButton id="ucb1" binding="#{jobPageBean.updateCommandButton}"
                action="#{jobBean.updatePriorities}" value="Save New Priority Order"
                disabled="true" />
        </h:form>

        <h:form>
            <h:inputTextarea value="#{jobBean.newJob}" />
            <h:commandButton action="#{jobBean.addNewJob}" value="Add Job" />
        </h:form>
    </f:view>
    <script type="text/javascript"> /* <![CDATA[ */
    Sortable.create('${jobPageBean.tableClientId}:tbody_element', {tag: 'tr', onChange: sortElements});
    function sortElements() {
        var table = document.getElementById('${jobPageBean.tableClientId}');
        var inputs = table.getElementsByTagName('input');
        for(var i=0; i<inputs.length; i++) {
            inputs[i].value = i;
        }
        var updateCommandButton = document.getElementById('${jobPageBean.updateCommandButtonClientId}');
        updateCommandButton.disabled = false;
    }
    /* ]]> */
    </script>
    </body>
    </html>
</jsp:root>

Фасоль:

public class JobPageBean {

  // Declaration:
  // <managed-bean>
  // <managed-bean-name>jobPageBean</managed-bean-name>
  // <managed-bean-class>job.JobPageBean</managed-bean-class>
  // <managed-bean-scope>request</managed-bean-scope>
  // </managed-bean>

  private UIComponent dataTable;
  private UIComponent updateCommandButton;

  public void setTable(UIComponent dataTable) {
    this.dataTable = dataTable;
  }

  public UIComponent getTable() {
    return dataTable;
  }

  public String getTableClientId() {
    FacesContext context = FacesContext
        .getCurrentInstance();
    return dataTable.getClientId(context);
  }

  public void setUpdateCommandButton(
      UIComponent updateCommandButton) {
    this.updateCommandButton = updateCommandButton;
  }

  public UIComponent getUpdateCommandButton() {
    return updateCommandButton;
  }

  public String getUpdateCommandButtonClientId() {
    FacesContext context = FacesContext
        .getCurrentInstance();
    return updateCommandButton.getClientId(context);
  }

}

public class JobBean {

  // Declaration:
  // <managed-bean>
  // <managed-bean-name>jobBean</managed-bean-name>
  // <managed-bean-class>job.JobBean</managed-bean-class>
  // <managed-bean-scope>session</managed-bean-scope>
  // </managed-bean>

  private List<Job> jobs;
  private DataModel model;

  private String newJob;

  public DataModel getJobs() {
    if (jobs == null) {
      jobs = new ArrayList<Job>();
      model = new ListDataModel(jobs);
    }
    return model;
  }

  public String updatePriorities() {
    if (jobs != null) {
      Collections.sort(jobs);
    }

    return null;
  }

  public String getNewJob() {
    return newJob;
  }

  public void setNewJob(String newJob) {
    this.newJob = newJob;
  }

  public String addNewJob() {
    if (newJob == null || newJob.trim().length() == 0) {
      return null;
    }

    Job job = new Job();
    job.setText(newJob);
    job.setPriority(jobs.size());
    jobs.add(job);

    newJob = null;

    return null;
  }

}

public class Job implements Comparable<Job> {

  private String text;

  private int priority;

  public String getText() {
    return text;
  }

  public void setText(String text) {
    this.text = text;
  }

  public int getPriority() {
    return priority;
  }

  public void setPriority(int priority) {
    this.priority = priority;
  }

  public int compareTo(Job other) {
    if (other.priority == priority) {
      return 0;
    }
    return other.priority < priority ? 1 : -1;
  }

}
  • Вы можете изменить порядок строк, перетаскивая их, но вам нужно отправить форму для сохранения изменений - вы не получите хорошую поддержку AJAX без сторонней среды, которая добавляет ее (по крайней мере, до JSF 2.0)
  • Я использовал MyFaces 1.2.3, dataTable которого отображает свой элемент tbody с атрибутом id, заканчивающимся на : tbody_element - Я не знаю, все ли реализации делают это
  • Я не слишком беспокоился о способах проверки ввода, не обращал внимания на использование клавиатуры для поддержки специальных возможностей или всех других вещей, необходимых для профессионального пользовательского интерфейса ...
0 голосов
/ 15 апреля 2009

Проверьте плагин jQuery table drag'n'drop . Затем просто привяжите полученные вызовы javascript к своему внутреннему интерфейсу с помощью Ajax (например, a4j: jsFunction from Richfaces). Получите внутренний компонент для обработки перетасовки последующих заданий.

Это определенно будет выглядеть и вести себя лучше, чем любой готовый компонент, который вы сейчас найдете в библиотеке JSF.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...