Когда составной компонент, содержащий код JS, отображается несколько раз, JS работает только с последним компонентом
У меня есть составной компонент, который использует PrimeFaces <p:selectOneMenu>
определяется как:
<p:selectOneMenu id="inOut" onchange="inOutChanged()">
..
</p:selectOneMenu>
Затем у меня есть файл JavaScript, который включен как часть компонента, который определяет inOutChanged()
функционировать как
function inOutChanged() {
var inOut = $({cc.clientId}:inOut);
if(inOut.val() == "INC") {
slider.addClass("includedInRange");
}
}
Этот составной компонент отлично работает, когда на странице есть только один. Проблема в том, что мне нужно иметь 4 из них на странице. Поэтому, когда я изменяю выбор одного составного компонента, он меняет класс слайдера последнего компонента. Я считаю, что это потому, что в действительности 4 inOutChanged()
функции, которые все определены на странице.
Есть ли способ либо расширить область действия функции, либо назвать ее уникальным образом, чтобы они не давили друг на друга?
2 ответа
Ваша конкретная проблема вызвана тем, что вы повторно объявили и переназначили одну и ту же переменную JavaScript slider
в глобальном масштабе. Вам необходимо переместить декларацию slider
внутрь функции.
Переопределение точно такой же функции не вредит, но неэффективно и не СУХО. Вы должны переместить функцию в свою .js
файл и использование <h:outputScript>
включить это. JSF в конечном итоге включит его только один раз. Затем измените функцию соответственно, чтобы принимать переменные в качестве аргументов.
Что-то вроде этого
<h:outputScript library="composite" name="some.js" target="head" />
...
<h:panelGroup id="...">
<p:selectOneMenu ... onchange="inOutChanged(this)">
...
</p:selectOneMenu>
...
<p:slider ... />
</h:panelGroup>
с этим внутри /resources/composite/some.js
(при условии, что /resoruces/composite
содержит XHTML-файл вашего составного компонента)
function inOutChanged(menuElement) {
var $menu = $(menuElement);
if ($menu.val() == "INC") {
$menu.parent().find(".ui-slider").addClass("includedInRange");
}
}
Вы должны использовать $(this)
селектор в вашем слушателе событий изменения:
$(".inOut").change(function(){
var sel = $(this).find('option:selected').text();
if(sel == 'INC') {
//find slider and add class
}
});
Обратите внимание, что я ограничил прослушиватели событий onchange за пределами области действия компонента и нашел компоненты на основе присоединенного класса CSS. Это может быть сделано в течение $(document).ready()
,
Конечно, вы можете использовать идентификаторы клиента в функции JS или связать эту функцию с атрибутом компонента.