• Ethan Hotz
  • NEWBIE
  • 10 Points
  • Member since 2016

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 5
    Questions
  • 2
    Replies
I'm trying to implement row hiding/displaying functionality for a page of tables. Code below:
<apex:repeat var="dev" value="{!userList}">
        <apex:pageBlockTable value="{!dev.projectMap}" var="project" id="userTable" rendered="{!tableVisible}" columnsWidth="20%,8%" rowClasses="{!dev.isDisplayed}">
            
            <apex:column id="devHeader" >
                <apex:facet name="header"><apex:commandLink action="{!dev.toggleVisible}">{!dev.userName.name}</apex:commandLink></apex:facet>
                <apex:outputLink id="dataDev" target="_blank" value="/{!project}" rendered="{!IF(project == null, false, true)}" >{!IF(project == caseID, 'Current Case', project)}</apex:outputLink> <!-- Set to caseNumber? -->
                
            </apex:column>
            <apex:repeat value="{!dev.projectMap[project]}" var="date">
            
            <apex:column headerValue="{!dev.totalHourMap[date]}" id="hourHeader"  headerClass="{!dev.colColor[date]}" > 
                 <apex:outputText id="dataOutput" rendered="{!IF(project == null || project == caseID, false, true)}">{!dev.projectMap[project][date]}</apex:outputText>
                 <apex:inputText id="dataInput" rendered="{!IF(project == caseID, true, false)}" value="{!dev.projectMap[project][date]}" style="width:20%"/>
            
            </apex:column>
           
            </apex:repeat>
        </apex:pageBlockTable>
         
        </apex:repeat>

Each "dev" is an instance of a wrapper class with an "isVisible" string that matches up with a respective CSS class containing 'display:none' or no styling. ToggleVisible() switches the value of the string. This system works perfectly on the 'hourheader' column header with colors, but for whatever reason, rowClasses doesn't read the parameter given(defaulted to display:none). If I set rowClasses equal to the CSS class directly, it works fine, and I can see that the toggling function is working in debug logs.

Is this due to some weird property with rowClasses? If so, and I can't get row toggling to work this way, does anyone have any other suggestions as to how I might implement it?
So I've got a page that generates tables dynamically and I'm trying to implement a function to show/hide table rows when a user double clicks on a header cell.
The relevant visualforce code:
 
<apex:pageBlock id="tableBlock">
    
        <apex:pageBlockTable value="{!dummyList}" var="dummyVar" columnsWidth="20%,8%">
          
            <apex:column headerValue="Developer" >
                
            </apex:column>
            <apex:repeat var="week" value="{!formattedWeekList}">
            <apex:column headerValue="{!week}" >
                
            </apex:column>
            </apex:repeat>
        </apex:pageBlockTable>
        
        <apex:variable var="rowNum" value="{!0}"/>
        <apex:repeat var="dev" value="{!userList}">
        <apex:variable var="rowNum" value="{!rowNum + 1}"/>
        <apex:pageBlockTable value="{!dev.projectMap}" var="project" id="userTable" rendered="{!tableVisible}" columnsWidth="20%,8%" ondblclick="toggleRows({!$Component.this});" rowClasses="display:none">
            
            <apex:column headerValue="{!dev.userName.name}" id="devHeader" headerClass="" >
                
                <apex:outputLink id="dataDev" value="/{!project}" rendered="{!IF(project == null, false, true)}" >{!IF(project == caseID, 'Current Case', project)}</apex:outputLink> 
                
            </apex:column>
            <apex:repeat value="{!dev.projectMap[project]}" var="date">
            
            <apex:column headerValue="{!dev.totalHourMap[date]}" id="hourHeader"  headerClass="{!dev.colColor[date]}" > 
               
                 <apex:outputText id="dataOutput" rendered="{!IF(project == null || project == caseID, false, true)}">{!dev.projectMap[project][date]}</apex:outputText>
                 <apex:inputText id="dataInput" rendered="{!IF(project == caseID, true, false)}" value="{!dev.projectMap[project][date]}" style="width:20%"/>
            
            </apex:column>
            
            </apex:repeat>
        </apex:pageBlockTable>
        </apex:repeat>

The first table is blank and just displays date headers. Following tables display user name and hour information in their table headers, with project information in rows. Using rowClasses="display:none" gets the visual I want, but I'm not sure how to toggle that when users click on the user name header cell. Will using javascript to change the CSS class used work here, or should I try a different approach?
I'm trying to render a table using values from a list of a wrapper class, which contains a Map<String, Map<Date, Integer>> for each instance.

The VF:
<apex:pageBlock >
        
        <apex:commandButton action="{!displayData}" Value="Display Data" reRender="tableBlock"/>
    </apex:pageBlock>
    <apex:pageBlock id="tableBlock">
    
        <apex:pageBlockTable value="{!dummyList}" var="dummyVar" >
          
            <apex:column headerValue="Developer">
                
            </apex:column>
            <apex:repeat var="week" value="{!formattedWeekList}">
            <apex:column headerValue="{!week}">
                
            </apex:column>
            </apex:repeat>
        </apex:pageBlockTable>
        <apex:repeat var="dev" value="{!userList}">
        <apex:pageBlockTable value="{!dev.projectMap}" var="project" id="userTable" rendered="{!tableVisible}">
            <apex:column headerValue="{!dev.userName.name}">
                <apex:outputText >{!project}</apex:outputText>
            </apex:column>
            <apex:repeat value="{!dev.projectMap[project]}" var="date"> <!-- This is ID'd as the cause of the null map key -->
            <apex:column headerValue="0" > <!-- Placeholder value   -->
                 {!dev.projectMap[project][date]}
            </apex:column>
            </apex:repeat>
        </apex:pageBlockTable>
        </apex:repeat>
        
    </apex:pageBlock>

And the relevant part of the controller. This method is called for each wrapper class instance whenever I press the Display Data button:
public void checkData() {
            projectMap = new Map<String, Map<Date,Integer>>();
            Set<WeeklyProjectStats__c> querySet = new Set<WeeklyProjectStats__c>();
            Map<ID, Set<WeeklyProjectStats__c>> queryMap = new Map<ID, Set<WeeklyProjectStats__c>>();
            
            for (WeeklyProjectStats__c item : projectList) { //Create new list, if caseid != this.case, add
                querySet.add(item);
                if (querymap.containsKey(item.Case__c)) { 
                    Set<WeeklyProjectStats__c> innerset = queryMap.get(item.Case__c);
                    innerset.add(item);
                    queryMap.put(item.Case__c, innerset);
                } else {
                    Set<WeeklyProjectStats__c> tset = new Set<WeeklyProjectStats__c>();
                    tset.add(item);
                    queryMap.put(item.Case__c, tset);
                }
               
            }
//if (!queryMap.containsKey(TeamAllocationController.caseID)) queryMap.put(TeamAllocationController.caseID, null);
            
            
            if (queryMap.isEmpty()) {
                Map<Date,Integer> tMap = new Map<Date,Integer>();
                for (Date week : TeamAllocationController.weekList) {
                    tmap.put(week, 1);
                }
                projectMap.put('No projects assigned to this user.', tMap);
                return;
            }
            
            for (ID project : queryMap.keySet()) {
                Map<Date,Integer> innerMap = new Map<Date,Integer>();
                for (Date week : TeamAllocationController.weekList) {
                    
                    Integer hours;
                    WeeklyProjectStats__c tempStats = getListItem(querySet, project, week);
                    if (tempStats == null) {
                        hours = 0;
                    } else {
                        Set<WeeklyProjectStats__c> tset = queryMap.get(project);
                        WeeklyProjectStats__c tStat = getListItem(tset, project, week);
                        hours = (Integer)tStat.AssignedHours__c;
                    }
                    
                    innermap.put(week, hours);
                    
                }
                
                projectMap.put(project, innerMap);
            }
            
        }
        
        public WeeklyProjectStats__c getListItem(Set<WeeklyProjectStats__c> statList, ID project, Date week) {
            for (WeeklyProjectStats__c item : statList) {
                if (item.Case__c == project && item.Week__c == week) return item;
            }
            return null;
        }

As is, the page returns a map key null not found error. The weird thing is, whenever I enable the 
if (!queryMap.containsKey(TeamAllocationController.caseID)){ queryMap.put(TeamAllocationController.caseID, null); }

line, the table renders fine, except with null keys instead of the current page's case ID. I've probed most of my code with debug logs showing that the map seems to be populated as it should, so I have no idea what could be causing the page to fail.
 
I'm trying to construct a table that tracks how many hours per week a developer works on each project they're assigned to. The collapsed view for each row should show the total amount of assigned hours per developer per week, but when expanded, the per-project breakdown should be shown. Here's a rough sketch of what I'm trying to do:
Developer1/1/20161/8/20161/15/20161/22/2016
User-added imageBob
30/4040/4020/400/40
User-added imageJohn
40/4040/4030/405/40
Project12030250
Project2201055

It seems like I might need a nested table for each row, with each nested table's column headers being the collapsed data? I'm not sure if that's at all possible with visualforce or not.

Oh, also, the weekly column headers need to be dynamically generated, and update week to week. I've started with that here:
<apex:pageBlock >
        <apex:pageBlockTable value="{!projectList}" var="project" >
          
            <apex:column headerValue="Developer">
                <apex:outputText>{!project.User__c}</apex:outputText>
            </apex:column>
            <apex:repeat var="week" value="{!formattedWeekList}">
            <apex:column headerValue="{!week}">
                
            </apex:column>
            </apex:repeat>
        </apex:pageBlockTable>
    </apex:pageBlock>
But I'm afraid I'm lost as to where to go from here. Any help in the right direction would be hugely appreciated.
 
So I've been stuck on this for way too long; I've scoured the forums and made every change I could think of, but I have no idea why I'm not getting the save to function. I've tried using the standard controller's save, and the current setup using the custom save method. The way I've got it set now, the developer console shows that there are DML calls being made, but the changes aren't sticking. 

If someone could tell me where I'm going wrong, I'd really appreciate it.

The VF page:
<apex:page standardController="WeeklyDevStats__c" recordSetVar="weeklyDevList" extensions="MaxHoursController2">
    
 <apex:pageBlock >
 <apex:pageMessages />
  <apex:pageBlockSection >
   <apex:form >
    <apex:selectList label="Week" value="{!selectedWeek}" size="1" multiselect="false" >
     <apex:actionSupport event="onchange" action="{!changeWeek}" />
      <apex:selectOptions value="{!weeks}" />
    </apex:selectList>
    
   </apex:form>
  </apex:pageBlockSection>
  <apex:pageBlockSection >
   <apex:dataTable value="{!weeklyDevList}" var="dev" columnsWidth="150">
      <apex:column headerValue="Developer">
         <apex:outputField value="{!dev.Dev_name__c}"/>
      </apex:column>
      <apex:column headerValue="Max Hours">
         <apex:form ><apex:inputField value="{!dev.MaxHours__c}">
           
         </apex:inputField></apex:form>
      </apex:column>
   </apex:dataTable>
  </apex:pageBlockSection>
 </apex:pageBlock>
 <apex:form ><apex:commandButton value="Save" action="{!saveHours}"/></apex:form>
 
</apex:page>
The controller:
public class MaxHoursController2 {


    public String selectedWeek { get; set; }
    public List<SelectOption> weeks { get; set; }
    public List<WeeklyDevStats__c> weeklyDevList {get; set;}
    
    public Apexpages.standardsetcontroller sc;
    
    public MaxHoursController2(ApexPages.StandardSetController controller) {
        sc = controller;
        selectedWeek = CalendarClass.getInstance().getMonday().format();
        weeks = new List<SelectOption>();
        
        setWeekList();
        setWeeklyDevList(Date.parse(selectedWeek));
    }
    

    public PageReference changeWeek() {
        setWeeklyDevList(Date.valueOf(selectedWeek));
        
        return null;
    }
    
    public PageReference saveHours() {
        
        try {
            update weeklyDevList;
        } catch(DMLException e) {
            Apexpages.addmessages(e);
        }
        return null;
    }
    
    public void setWeekList() {
        for (Date day : CalendarClass.getInstance().getNextMondays(8)) {
            weeks.add(new SelectOption(String.valueOf(day), String.valueOf(day)));
        }
   }

    public void setWeeklyDevList(Date week) {
    
        weeklyDevList = [SELECT Dev_name__c, MaxHours__c FROM WeeklyDevStats__c WHERE Week_dev__c = :week];
    }
    
    public List<WeeklyDevStats__c> getWeeklyDevList() {
        return weeklyDevList;
    }
    
}


 
I'm trying to render a table using values from a list of a wrapper class, which contains a Map<String, Map<Date, Integer>> for each instance.

The VF:
<apex:pageBlock >
        
        <apex:commandButton action="{!displayData}" Value="Display Data" reRender="tableBlock"/>
    </apex:pageBlock>
    <apex:pageBlock id="tableBlock">
    
        <apex:pageBlockTable value="{!dummyList}" var="dummyVar" >
          
            <apex:column headerValue="Developer">
                
            </apex:column>
            <apex:repeat var="week" value="{!formattedWeekList}">
            <apex:column headerValue="{!week}">
                
            </apex:column>
            </apex:repeat>
        </apex:pageBlockTable>
        <apex:repeat var="dev" value="{!userList}">
        <apex:pageBlockTable value="{!dev.projectMap}" var="project" id="userTable" rendered="{!tableVisible}">
            <apex:column headerValue="{!dev.userName.name}">
                <apex:outputText >{!project}</apex:outputText>
            </apex:column>
            <apex:repeat value="{!dev.projectMap[project]}" var="date"> <!-- This is ID'd as the cause of the null map key -->
            <apex:column headerValue="0" > <!-- Placeholder value   -->
                 {!dev.projectMap[project][date]}
            </apex:column>
            </apex:repeat>
        </apex:pageBlockTable>
        </apex:repeat>
        
    </apex:pageBlock>

And the relevant part of the controller. This method is called for each wrapper class instance whenever I press the Display Data button:
public void checkData() {
            projectMap = new Map<String, Map<Date,Integer>>();
            Set<WeeklyProjectStats__c> querySet = new Set<WeeklyProjectStats__c>();
            Map<ID, Set<WeeklyProjectStats__c>> queryMap = new Map<ID, Set<WeeklyProjectStats__c>>();
            
            for (WeeklyProjectStats__c item : projectList) { //Create new list, if caseid != this.case, add
                querySet.add(item);
                if (querymap.containsKey(item.Case__c)) { 
                    Set<WeeklyProjectStats__c> innerset = queryMap.get(item.Case__c);
                    innerset.add(item);
                    queryMap.put(item.Case__c, innerset);
                } else {
                    Set<WeeklyProjectStats__c> tset = new Set<WeeklyProjectStats__c>();
                    tset.add(item);
                    queryMap.put(item.Case__c, tset);
                }
               
            }
//if (!queryMap.containsKey(TeamAllocationController.caseID)) queryMap.put(TeamAllocationController.caseID, null);
            
            
            if (queryMap.isEmpty()) {
                Map<Date,Integer> tMap = new Map<Date,Integer>();
                for (Date week : TeamAllocationController.weekList) {
                    tmap.put(week, 1);
                }
                projectMap.put('No projects assigned to this user.', tMap);
                return;
            }
            
            for (ID project : queryMap.keySet()) {
                Map<Date,Integer> innerMap = new Map<Date,Integer>();
                for (Date week : TeamAllocationController.weekList) {
                    
                    Integer hours;
                    WeeklyProjectStats__c tempStats = getListItem(querySet, project, week);
                    if (tempStats == null) {
                        hours = 0;
                    } else {
                        Set<WeeklyProjectStats__c> tset = queryMap.get(project);
                        WeeklyProjectStats__c tStat = getListItem(tset, project, week);
                        hours = (Integer)tStat.AssignedHours__c;
                    }
                    
                    innermap.put(week, hours);
                    
                }
                
                projectMap.put(project, innerMap);
            }
            
        }
        
        public WeeklyProjectStats__c getListItem(Set<WeeklyProjectStats__c> statList, ID project, Date week) {
            for (WeeklyProjectStats__c item : statList) {
                if (item.Case__c == project && item.Week__c == week) return item;
            }
            return null;
        }

As is, the page returns a map key null not found error. The weird thing is, whenever I enable the 
if (!queryMap.containsKey(TeamAllocationController.caseID)){ queryMap.put(TeamAllocationController.caseID, null); }

line, the table renders fine, except with null keys instead of the current page's case ID. I've probed most of my code with debug logs showing that the map seems to be populated as it should, so I have no idea what could be causing the page to fail.
 
So I've been stuck on this for way too long; I've scoured the forums and made every change I could think of, but I have no idea why I'm not getting the save to function. I've tried using the standard controller's save, and the current setup using the custom save method. The way I've got it set now, the developer console shows that there are DML calls being made, but the changes aren't sticking. 

If someone could tell me where I'm going wrong, I'd really appreciate it.

The VF page:
<apex:page standardController="WeeklyDevStats__c" recordSetVar="weeklyDevList" extensions="MaxHoursController2">
    
 <apex:pageBlock >
 <apex:pageMessages />
  <apex:pageBlockSection >
   <apex:form >
    <apex:selectList label="Week" value="{!selectedWeek}" size="1" multiselect="false" >
     <apex:actionSupport event="onchange" action="{!changeWeek}" />
      <apex:selectOptions value="{!weeks}" />
    </apex:selectList>
    
   </apex:form>
  </apex:pageBlockSection>
  <apex:pageBlockSection >
   <apex:dataTable value="{!weeklyDevList}" var="dev" columnsWidth="150">
      <apex:column headerValue="Developer">
         <apex:outputField value="{!dev.Dev_name__c}"/>
      </apex:column>
      <apex:column headerValue="Max Hours">
         <apex:form ><apex:inputField value="{!dev.MaxHours__c}">
           
         </apex:inputField></apex:form>
      </apex:column>
   </apex:dataTable>
  </apex:pageBlockSection>
 </apex:pageBlock>
 <apex:form ><apex:commandButton value="Save" action="{!saveHours}"/></apex:form>
 
</apex:page>
The controller:
public class MaxHoursController2 {


    public String selectedWeek { get; set; }
    public List<SelectOption> weeks { get; set; }
    public List<WeeklyDevStats__c> weeklyDevList {get; set;}
    
    public Apexpages.standardsetcontroller sc;
    
    public MaxHoursController2(ApexPages.StandardSetController controller) {
        sc = controller;
        selectedWeek = CalendarClass.getInstance().getMonday().format();
        weeks = new List<SelectOption>();
        
        setWeekList();
        setWeeklyDevList(Date.parse(selectedWeek));
    }
    

    public PageReference changeWeek() {
        setWeeklyDevList(Date.valueOf(selectedWeek));
        
        return null;
    }
    
    public PageReference saveHours() {
        
        try {
            update weeklyDevList;
        } catch(DMLException e) {
            Apexpages.addmessages(e);
        }
        return null;
    }
    
    public void setWeekList() {
        for (Date day : CalendarClass.getInstance().getNextMondays(8)) {
            weeks.add(new SelectOption(String.valueOf(day), String.valueOf(day)));
        }
   }

    public void setWeeklyDevList(Date week) {
    
        weeklyDevList = [SELECT Dev_name__c, MaxHours__c FROM WeeklyDevStats__c WHERE Week_dev__c = :week];
    }
    
    public List<WeeklyDevStats__c> getWeeklyDevList() {
        return weeklyDevList;
    }
    
}