0

現在、ポップアップ ウィンドウを介して一度に 1 つずつ取得される文字列のリストを表すリスト ボックス (検索条件の一部) があります。ただし、ポップアップ ウィンドウを閉じると、選択した文字列がリスト ボックスに追加されることはありません。(隠し変数が更新されていることを確認しました。検索の実行後にページから移動して戻った場合、リスト ボックスには、以前にポップアップから選択した文字列が正しく表示されます)。どんな助けでも大歓迎です!

    <script type="text/javascript">
        function selectBook(bookId, extendedBookName) {
            var idInput = jQuery("#myForm\\:bookNames");
            if (idInput.val() == "") {
                idInput.val(extendedBookName);
            } else {
                idInput.val(idInput.val() + '@@@' + extendedBookName);
            }  
        }
    </script>
...
 <h:form id="myForm">
    ...
      <ui:define name="form-fields">
         <h:selectOneListbox id="booksListBox" size="3" style="width:470px">  
            <s:selectItems var="_var" value="#{bean.searchCriteria.bookNames}" label="#{_var}" noSelectionLabel="" />
         </h:selectOneListbox>
         <h:outputLink onclick="return openNewWindow('#{bean.booksLookupUrl}?#{bean.bookLookupParameters}', 'book');" 
                       target="_blank">
                     <h:inputHidden id="bookNames" value="#{bean.searchCriteria.bookNames}" converter="StringListConverter"/>
                     <h:outputText value="Add"/>
         </h:outputLink>

      </ui:define>
    ...
 </h:form>

これは、ルックアップ ウィンドウに属する JavaScript です。これはselectBook関数を呼び出します

function selectBook(bookId, extendedBookName) {
        var extendedName = unescape(extendedBookName);
        window.opener.selectBook(bookId, extendedName);
        window.close();
    }

そして私のJavaコードのために...

public class BookSearchCriteria implements Serializable {
...
private List<String> bookNames = new ArrayList<String>();

    public List<String> getBookNames() {
    return bookNames;
}
public void setBookNames(List<String> bookNames) {
    this.bookNames = bookNames;
}

StringListConverter コード...

@FacesConverter("myStringListConverter")
public class StringListConverter implements Converter {

    // this is used as a regex, so choose other separator carefully
    private static final String MY_SEPARATOR = "@@@";

    @Override
    public Object getAsObject(FacesContext context, UIComponent component,
            String value) {
        if (value == null) {
            return new ArrayList<String>();
        }
        return new ArrayList<String>(Arrays.asList(value.split(MY_SEPARATOR)));
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component,
            Object value) {
        if (value == null) {
            return "";
        }
        return join((List<String>) value, MY_SEPARATOR);
    }

    /**
     * Joins a String list, src: http://stackoverflow.com/q/1751844/149872
     * 
     * @param list
     * @param conjunction
     * @return
     */
    public static String join(List<String> list, String conjunction) {
        StringBuilder sb = new StringBuilder();
        boolean first = true;
        for (String item : list) {
            if (first) {
                first = false;
            } else {
                sb.append(conjunction);
            }
            sb.append(item);
        }
        return sb.toString();
    }

}
4

2 に答える 2

1

ポップアップ ウィンドウのページは、ドロップダウン メニューの新しいオプションを作成するサーバー側のJava コードを実行しています。これは、親ページが再ロードされてサーバーによって再生成されるまで、親ページにまったく影響を与えません。ページのリロードを回避するには、クライアント側のJavaScript/jQuery コードを使用して新しいオプションを作成して選択する必要があります。

結果のオプションの HTML コードが次のようになると仮定すると、次のよう<option value="bookId">extendedBookName</option>に使用できます。

<script>
function addBook(bookId, extendedBookName) {
    var newOption = jQuery('<option>').val(bookId).text(extendedBookName);
    var idInput = jQuery('#myForm\\:bookNames');
    idInput.append(newOption).val(bookId);
}
</script>

デモ: http://jsfiddle.net/5Cwjk/

または、ポップアップ ウィンドウからの選択が新しいものであることが保証されていない場合は、重複を避けるために、作成する前にオプションの作成が必要かどうかを動的に判断する必要があります。

<script>
function addBook(bookId, extendedBookName) {
    var idInput = jQuery('#myForm\\:bookNames');
    if (idInput.val(bookId).val() != bookId) {
        var newOption = jQuery('<option>').val(bookId).text(extendedBookName);        
        idInput.append(newOption).val(bookId);
    }
}
</script>

デモ: http://jsfiddle.net/nTtY9/1/

于 2013-10-01T01:38:35.890 に答える
1

ポップアップを使用してlistBoxにデータを入力する理由がよくわかりません。

ただし、基礎となる Bean 値を変更する場合は、<h:selectOneListbox/>これらの変更を反映するために を再レンダリングする必要があります。richfaces フレームワークを使用している (または使用できる) 場合は、ajax 呼び出しを介して非常に簡単に実行できます。

呼び出されたajax4jsfコンポーネント<a4j:jsFunction/>は、その仕事を行うことができます。たとえば、親ページに次を追加します。

<a4j:jsFunction name="refreshListbox" reRender="booksListBox" limitToList="true"/>

ポップアップで、新しい簿価が選択されたときにこのjs関数を呼び出すだけです:

<script type="text/javascript">
    window.opener.refreshListbox();
</script>

ポップアップの代わりに aを使用<rich:modalPanel>して、同じページにとどまり、jsf コンポーネントとより簡単に対話することもできます。

于 2013-10-01T15:27:34.487 に答える