2009-11-25 4 views
3

У меня есть приложение JSF 1.2 (Sun RI, Facelets, Richfaces), которое использовалось только в браузерах IE6. Теперь мы также должны поддерживать Firefox (да!).JSF CommandLink не работает в Firefox после целой формы reRender

На одной из моих страниц у меня есть форма, содержащая кнопку, которая будет повторно отображать всю форму. После повторной рендеринга в этой форме добавляются некоторые ссылки (<h:commandLink/>).

для JSF код выглядит следующим образом:

<h:form id="foobar"> 
    ... 
    <a4j:commandButton ... reRender="foobar"/> 
    ... 
    <h:commandLink .../> 
</h:form> 

Моя проблема связана с HTML-кодом, генерируемым компонентом команды линии связи, которая выглядит следующим образом:

<a href="#" onclick="if(typeof jsfcljs == 'function'){jsfcljs(document.forms['foobar'],'...','');}return false">bla bla</a> 

(для информации, jsfcljs является функцией Javascript, генерируемой компонентом <h:commandLink/>)

Проблема в том, что document.forms["foobar"] работает ну, когда страница изначально отображается, но как только форма повторно отображается после вызова Ajax, этот код больше не работает в Firefox (но работает на IE6).

Это результат ошибки Javascript, когда я нажимаю на одну ссылку в форме после вызова Ajax.

Обратите внимание, что, если я позвоню document.getElementById("foobar"); после вызова Ajax, Firefox основывает свою форму ...

Если рассмотрим следующую функцию JavaScript:

function test() { 
    var e = document.forms; 
    var tmp = ""; 
    for (i = 0; i < e.length; i++) { 
     tmp = tmp + e[i].id + " ; "; 
    } 
    alert(tmp); 
} 

, когда я запускаю его до и после Ajax вызов, я получаю следующие результаты:

someForm ; anotherForm ; foobar ; // Before Ajax call on FF 
someForm ; anotherForm ; // After Ajax call on FF. PROBLEM HERE! 

someForm ; anotherForm ; foobar ; // Before Ajax call on IE6 
someForm ; anotherForm ; foobar ; // After Ajax call on IE6 

Вот мои мысли о причине проблемы:

Когда ответ Ajax получен на стороне клиента, a4j удаляет элементы-объекты reRender (в частности, мою форму foobar) из объектов дерева DOM, что приводит к удалению из массива document.forms. Затем он снова добавляет форму foobar с ее новым контентом. Но Firefox делает не обновляет массив document.forms, в то время как IE6 делает. Именно поэтому document.forms["foobar"] возвращает undefined после вызова Ajax.

Мое решение для решения этой проблемы - изменить атрибут reRender, чтобы повторно отобразить только отдельные части формы, а не форму. Таким образом, мои ссылки работают.

Однако, я хотел знать, есть ли другой способ решить эту проблему, не изменяя атрибут reRender. Любая идея?


Редактировать

Javascript код, когда ссылка команды нажата следующий:

function dpf(f) { 
    var adp = f.adp; 
    if (adp != null) { 
     for (var i = 0; i < adp.length; i++) { 
      f.removeChild(adp[i]); 
     } 
    } 
}; 

function apf(f, pvp) { 
    var adp = new Array(); 
    f.adp = adp; 
    var ps = pvp.split(','); 
    for (var i = 0, ii = 0; i < ps.length; i++, ii++) { 
     var p = document.createElement("input"); 
     p.type = "hidden"; 
     p.name = ps[i]; 
     p.value = ps[i + 1]; 
     f.appendChild(p); 
     adp[ii] = p; 
     i += 1; 
    } 
}; 

function jsfcljs(f, pvp, t) { 
    apf(f, pvp); 
    var ft = f.target; 
    if (t) { 
     f.target = t; 
    } 
    f.submit(); 
    f.target = ft; 
    dpf(f); 
}; 

В OnClick атрибута <h:commandLink>, мы называем jsfcljs(document.forms['foobar'], 'someId', ''), который вычисляется в jsfcljs(undefined, 'someId', ''). Затем, когда вызывается f, я получаю ошибку Javacript, которая говорит, что f is undefined.

+0

MyFaces или RI? – Bozho

+0

ВС реализации. – romaintaz

ответ

2

Проблема на самом деле является одним из HTML из того, что я вижу.

форма должна быть определена с именем, а не просто атрибут ID:

Различные браузеры лечить имя и код эквивалентности по-разному. Если это не решит ваш комментарий проблемы, и я создам тестовый пример, который не требует серверной стороны, чтобы продемонстрировать любой эффект, который вы видите.

Другой способ создания кода проблемы - переписать вызовы onclick online на стороне клиента, чтобы ссылаться на форму по идентификатору с помощью вызова document.getElementById («foobar») вместо document.forms ["foobar "]

+0

Спасибо за идею использования 'name' в дополнение к атрибуту' id'. Я проверю это скоро! Что касается вашего предложения об изменении встроенной функции onclick, это невозможно, поскольку этот JS-код * сгенерирован * ядром JSF. Однако, как указано в ** BalusC **, этот код, возможно, развился со времени последней версии JSF 1.2 ... – romaintaz

+0

Функции могут быть изменены другим кодом javascript, встроенным в страницу. Если окажется, что это необходимо, я могу, вероятно, предоставить код, который выполняет эту задачу. –

+1

У меня есть аналогичная проблема с Chrome, делающим Rerender, но Firefox отказывается переигрывать. Добавление имени в форму не помогло. – kongo09

0

Я помню это как одну из ошибок Sun Mojarra 1.2 (которая уже существует уже 4 года). Модернизация библиотек должна решить эту проблему. В настоящее время Sun Mojarra 1.2 является 1.2_14, который был выпущен всего три недели назад. Просто замените две библиотеки JSF в /WEB-INF/lib ими.

Смежные вопросы