Регистрация  |  Вход

Почему Angular, ngAnimate и reRender для пагинации не хотят жить дружно?

Ну тут, скорее, я делаю что-то не так. Только-только добралась до JS и сразу прощупываю AngularJS. Думаю, что у меня проблемы с неправильно реализованными ng-hide и ng-show. Можете помочь?

Суть проблемы: есть панель с чекбоксом. Если чекбокс == true, под панелью плавно выезжает нижняя панель с детальной информацией. Если false - снова прячем нижнюю панель. И все бы хорошо, но если добавляем пагинацию - на следующей/предыдущей странице просто имеем выпавшую нижнюю панель, а чекбокс становится недееспособным. Если ререндер установить только для верхней панели, получаю просто недееспособный чекбокс без возможности "выкатить" нижнюю панель.

Нужная часть кода на Апексе:

public Integer size{get;set;} 
public Integer noOfRecords{get; set;}

public MyClass(){
size=10;
}

public ApexPages.StandardSetController setController {
get {
if(setController == null) {
setController = new ApexPages.StandardSetController(getSomeList());
setController.setPageSize(size);
noOfRecords = setController.getResultSize();
}
return setController;
}
set;
}
public List<MyObj__c> getListForVF() {
return (List<MyObj__c>) setController.getRecords();
}

Подключение Ангуляра:

<script>
var app = angular.module('myApp', ['ngAnimate'])
</script>

HTML:

<apex:commandButton status="fetchStatus" reRender="pageBlockId" value="<<" 
action="{!setController.first}" disabled="{!!setController.hasPrevious}" title="First Page"/>
<apex:commandButton status="fetchStatus" reRender="pageBlockId" value="<" action="{!setController.previous}" disabled="{!!setController.hasPrevious}" title="Previous Page"/>
&nbsp;
<apex:outputText >
{!(setController.pageNumber * size)+1-size}-{!IF((setController.pageNumber * size)>noOfRecords, noOfRecords,(setController.pageNumber * size))} of {!noOfRecords}
</apex:outputText>
&nbsp;
<apex:commandButton status="fetchStatus" reRender="pageBlockId" value=">" action="{!setController.next}" disabled="{!!setController.hasNext}" title="Next Page"/>
<apex:commandButton status="fetchStatus" reRender="pageBlockId" value=">>" action="{!setController.last}" disabled="{!!setController.hasNext}" title="Last Page"/>

<apex:repeat value="{!ListForVF}" var="list">
<apex:outputPanel id="pageBlockId">
<div class="div-bigpanel-label">
<apex:outputText style="font-weight:800" value="{!list.Name}"/>
<input ng-model="{!list.Id}" type="checkbox" id="{!list.Id}" /><label for="{!list.Id}"></label>
</div>
<div class="div-bigpanel-show-hide" ng-show="{!list.Id}" >
<h2>Detailed INFO</h2>
</div>
</apex:outputPanel>

Стили:

.div-bigpanel-label {
margin-top: 10px;
margin-right: 10px;
margin-left: 10px;
padding: 10px;
border: 2px solid #e0ebeb;
border-radius: 5px;
width: 98%;
height: 80px;
}
.div-bigpanel-show-hide {
margin-right: 10px;
margin-left: 10px;
transition: all linear 0.5s;
overflow: visible;
transition: all linear 0.5s;
background-color: #66c2ff;
border: 1px solid #94b8b8;
border-radius: 0px 0px 5px 5px;
height: 195px;
width: 98%;
}

.div-bigpanel-show-hide.ng-hide {
overflow: hidden;
height: 0;
opacity: 0;
}

Ну тут, скорее, я делаю что-то не так. Только-только добралась до JS и сразу прощупываю AngularJS. Думаю, что у меня проблемы с неправильно реализованными ng-hide и ng-show. Можете помочь?

Суть проблемы: есть панель с чекбоксом. Если чекбокс == true, под панелью плавно выезжает нижняя панель с детальной информацией. Если false - снова прячем нижнюю панель. И все бы хорошо, но если добавляем пагинацию - на следующей/предыдущей странице просто имеем выпавшую нижнюю панель, а чекбокс становится недееспособным. Если ререндер установить только для верхней панели, получаю просто недееспособный чекбокс без возможности "выкатить" нижнюю панель.

Нужная часть кода на Апексе:
[code]public Integer size{get;set;} 
public Integer noOfRecords{get; set;}

public MyClass(){
    size=10;
}

public ApexPages.StandardSetController setController {
    get {
        if(setController == null) {                
            setController = new ApexPages.StandardSetController(getSomeList());
            setController.setPageSize(size);  
            noOfRecords = setController.getResultSize();
        }
        return setController;
    }
    set;
}
public List<MyObj__c> getListForVF() {
    return (List<MyObj__c>) setController.getRecords();
}[/code]

Подключение Ангуляра:
[code]<script>
    var app = angular.module('myApp', ['ngAnimate'])
</script>[/code]

HTML:
[code]<apex:commandButton status="fetchStatus" reRender="pageBlockId" value="<<" 
action="{!setController.first}" disabled="{!!setController.hasPrevious}" title="First Page"/> 
<apex:commandButton status="fetchStatus" reRender="pageBlockId" value="<" action="{!setController.previous}" disabled="{!!setController.hasPrevious}" title="Previous Page"/> 
&nbsp;
<apex:outputText >
{!(setController.pageNumber * size)+1-size}-{!IF((setController.pageNumber * size)>noOfRecords, noOfRecords,(setController.pageNumber * size))} of {!noOfRecords}
</apex:outputText> 
&nbsp;
<apex:commandButton status="fetchStatus" reRender="pageBlockId" value=">" action="{!setController.next}" disabled="{!!setController.hasNext}" title="Next Page"/> 
<apex:commandButton status="fetchStatus" reRender="pageBlockId" value=">>" action="{!setController.last}" disabled="{!!setController.hasNext}" title="Last Page"/>

<apex:repeat value="{!ListForVF}" var="list">
<apex:outputPanel id="pageBlockId">
    <div class="div-bigpanel-label">
        <apex:outputText style="font-weight:800" value="{!list.Name}"/>
        <input ng-model="{!list.Id}" type="checkbox" id="{!list.Id}" /><label for="{!list.Id}"></label>
    </div>
    <div class="div-bigpanel-show-hide" ng-show="{!list.Id}" >
        <h2>Detailed INFO</h2>
    </div>
</apex:outputPanel>[/code]

Стили:
[code].div-bigpanel-label {
    margin-top: 10px;
    margin-right: 10px;
    margin-left: 10px;
    padding: 10px;
    border: 2px solid #e0ebeb;
    border-radius: 5px;
    width: 98%;
    height: 80px;
}
.div-bigpanel-show-hide {
    margin-right: 10px;
    margin-left: 10px;
    transition: all linear 0.5s;
    overflow: visible;
    transition: all linear 0.5s;
    background-color: #66c2ff;
    border: 1px solid #94b8b8;
    border-radius: 0px 0px 5px 5px;
    height: 195px;
    width: 98%;
}

.div-bigpanel-show-hide.ng-hide {
    overflow: hidden;
    height: 0;
    opacity: 0;
}[/code]

Сначала я подумал: боже, что тут происходит?!
Потом было: зачем ангуляр для такой простой страницы?

Ну, а после: просто при ререндере у тебя получается абсолютно новый кусок DOM, о котором ангуляр ничего не знает.

Вариантов несколько: переделать всю страницу на ангуляр, убрать ангуляр и пользовать только jquery.

Я бы голосовал за второй вариант: все что нужно это всего лишь написать аттрибут onclick="togglePanel();"

и сделать <script>
function togglePanel() {
jQuery(this).parent().next().toggleClass('class_name');
}
</script>

Сначала я подумал: боже, что тут происходит?!
Потом было: зачем ангуляр для такой простой страницы?

Ну, а после: просто при ререндере у тебя получается абсолютно новый кусок DOM, о котором ангуляр ничего не знает.

Вариантов несколько: переделать всю страницу на ангуляр, убрать ангуляр и пользовать только jquery.

Я бы голосовал за второй вариант: все что нужно это всего лишь написать аттрибут onclick="togglePanel();"

и сделать <script>
function togglePanel() {
jQuery(this).parent().next().toggleClass('class_name');
}
</script>

+

+

Мне кажется что тут и jQuery не нужен

public Boolean isChecked{get; set;}


<apex:outputPanel id="div-bigpanel-show-hide" rendered="{!isChecked'}">

Мне кажется что тут и jQuery не нужен

public Boolean isChecked{get; set;}


<apex:outputPanel id="div-bigpanel-show-hide" rendered="{!isChecked'}">

akr0bat
Мне кажется что тут и jQuery не нужен

public Boolean isChecked{get; set;}


<apex:outputPanel id="div-bigpanel-show-hide" rendered="{!isChecked'}">

Так человек хотел учить что-то из жаваскрипта :)

[quote="akr0bat"]Мне кажется что тут и jQuery не нужен

public Boolean isChecked{get; set;}


<apex:outputPanel id="div-bigpanel-show-hide" rendered="{!isChecked'}">[/quote]

Так человек хотел учить что-то из жаваскрипта :)

С jQuery совсем запуталась.

Вариант 1:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
function togglePanel() {
jQuery(this).parent().next().toggleClass('div-bigpanel-label');
}
</script>

Кнопки:
<apex:commandButton status="fetchStatus" reRender="pageBlockId" value="<<" 
action="{!setController.first}" disabled="{!!setController.hasPrevious}" title="First Page"/>
<apex:commandButton status="fetchStatus" reRender="pageBlockId" value="<" action="{!setController.previous}" disabled="{!!setController.hasPrevious}" title="Previous Page"/>
&nbsp;
<apex:outputText >
{!(setController.pageNumber * size)+1-size}-{!IF((setController.pageNumber * size)>noOfRecords, noOfRecords,(setController.pageNumber * size))} of {!noOfRecords}
</apex:outputText>
&nbsp;
<apex:commandButton status="fetchStatus" reRender="pageBlockId" value=">" action="{!setController.next}" disabled="{!!setController.hasNext}" title="Next Page"/>
<apex:commandButton status="fetchStatus" reRender="pageBlockId" value=">>" action="{!setController.last}" disabled="{!!setController.hasNext}" title="Last Page"/>

Остальное:
<apex:repeat value="{!ListForVF}" var="list">
<apex:outputPanel id="pageBlockId">
<div class="div-bigpanel-label">
<apex:outputText style="font-weight:800" value="{!list.Name}"/>
<!-- Онклик передаю в чекбокс, который овтечает за открытие/закрытие -->
<input onclick="togglePanel();" type="checkbox" id="{!list.Id}" /><label for="{!list.Id}"></label>
</div>
<div class="div-bigpanel-show-hide">
<h2>Detailed INFO</h2>
</div>
</apex:outputPanel>
</apex:repeat>

Ничего не происходит: на клики не реаугирует.

Вариант 2:

<script>
$(document).ready(function(){

$("div[id|=div-bigpanel-label]").click(function(){
$("div[id|=div-bigpanel-show-hide]").slideToggle("slow");
});
});
</script>

В этом случае с пагинацией точно та же беда, что и в ангуляре (в них ли дело?):
<apex:repeat value="{!ListForVF}" var="list">
<apex:outputPanel id="pageBlockId">
<div id="div-bigpanel-label">
<apex:outputText style="font-weight:800" value="{!list.Name}"/>
<input type="checkbox" id="{!list.Id}" /><label for="{!list.Id}"></label>
</div>
<div id="div-bigpanel-show-hide">
<h2>Detailed INFO</h2>
</div>
</apex:outputPanel>
</apex:repeat>

На чистом JS тоже пробовала: та же беда.

Начинаю подозревать, что что-то не так в самой пагинации. Или в симбиозе HTML с апекс-формой. Это же допустимое оформление VF?

<html>
<apex:form>
<apex:pageBlock id="pageBlockId">
<body>

С jQuery совсем запуталась.

Вариант 1:
[code]
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script> 
function togglePanel() { 
	jQuery(this).parent().next().toggleClass('div-bigpanel-label'); 
} 
</script>[/code]
Кнопки:
[code]<apex:commandButton status="fetchStatus" reRender="pageBlockId" value="<<" 
action="{!setController.first}" disabled="{!!setController.hasPrevious}" title="First Page"/> 
<apex:commandButton status="fetchStatus" reRender="pageBlockId" value="<" action="{!setController.previous}" disabled="{!!setController.hasPrevious}" title="Previous Page"/> 
&nbsp;
<apex:outputText >
{!(setController.pageNumber * size)+1-size}-{!IF((setController.pageNumber * size)>noOfRecords, noOfRecords,(setController.pageNumber * size))} of {!noOfRecords}
</apex:outputText> 
&nbsp;
<apex:commandButton status="fetchStatus" reRender="pageBlockId" value=">" action="{!setController.next}" disabled="{!!setController.hasNext}" title="Next Page"/> 
<apex:commandButton status="fetchStatus" reRender="pageBlockId" value=">>" action="{!setController.last}" disabled="{!!setController.hasNext}" title="Last Page"/>[/code]
Остальное:
[code]<apex:repeat value="{!ListForVF}" var="list">
<apex:outputPanel id="pageBlockId">
    <div class="div-bigpanel-label">
        <apex:outputText style="font-weight:800" value="{!list.Name}"/>
        <!-- Онклик передаю в чекбокс, который овтечает за открытие/закрытие -->
        <input onclick="togglePanel();" type="checkbox" id="{!list.Id}" /><label for="{!list.Id}"></label>
    </div>
    <div class="div-bigpanel-show-hide">
        <h2>Detailed INFO</h2>
    </div>
</apex:outputPanel>
</apex:repeat>[/code]
Ничего не происходит: на клики не реаугирует.

Вариант 2:
[code]<script>
$(document).ready(function(){
            
    $("div[id|=div-bigpanel-label]").click(function(){
        $("div[id|=div-bigpanel-show-hide]").slideToggle("slow");
    });
});
</script>[/code]
В этом случае с пагинацией точно та же беда, что и в ангуляре (в них ли дело?):
[code]<apex:repeat value="{!ListForVF}" var="list">
<apex:outputPanel id="pageBlockId">
    <div id="div-bigpanel-label">
        <apex:outputText style="font-weight:800" value="{!list.Name}"/>
        <input type="checkbox" id="{!list.Id}" /><label for="{!list.Id}"></label>
    </div>
    <div id="div-bigpanel-show-hide">
        <h2>Detailed INFO</h2>
    </div>
</apex:outputPanel>
</apex:repeat>[/code]
На чистом JS тоже пробовала: та же беда.

Начинаю подозревать, что что-то не так в самой пагинации. Или в симбиозе HTML с апекс-формой. Это же допустимое оформление VF?
[code]<html>
    <apex:form>
        <apex:pageBlock id="pageBlockId">
		<body>[/code]

function togglePanel(el) { 
jQuery(el).parent().next().toggleClass('div-bigpanel-label');
}

onclick=togglePanel(this);

[code]function togglePanel(el) { 
	jQuery(el).parent().next().toggleClass('div-bigpanel-label'); 
} 

onclick=togglePanel(this);
[/code]