Hi guys, for any of you who have used the ajaxformloop over the years and
have struggled not to have to use @Persist and handle the save on form
submission know that it has been a challenge. I managed to come up with the
following solution this morning that thus far seems to work very well. I'd
like to share it so that it can be picked apart, but also provide another
working example demonstrating how this can be done.


TimeSheet is a parent entity containing a one to may relationship with
EffortAllocation.


<div t:type="AjaxFormLoop" t:source="timeSheet.effortAllocations"
t:value="effortAllocation" t:encoder="encoder">
    <t:textfield t:id="activityCode" value="effortAllocation.activityCode"
t:validate="required/>
    <t:removerowlink>remove</t:removerowlink>
</div>

public ValueEncoder<EffortAllocation> getEncoder() {
        return new ValueEncoder<TimeSheet>() {
            @Override
            public String toClient(EffortAllocationv) {
                //getTempId is a a transient temp id in the
effortallocation entity
                //example Long tempId = 0 - System.nanoTime();
                //This is used to create a unique client id.
                String id = v.getId() != null ? v.getId().toString() :
v.getTempId().toString();
                return id;
            }

            @Override
            public EffortAllocationtoValue(String toValue) {
                Long id = Long.parseLong(toValue);

                if (id > 0) {
                    //timeSheet object is populated in onActivate /
setupRender from the database
                    for (EffortAllocation effortAllocation :
timeSheet.getEffortAllocations()) {
                        if (effortAllocation.getId().equals(id)) {
                            return effortAllocation;
                        }
                    }
                }
                return new EffortAllocation(timeSheet);
            }
        };
    }

void onPrepareForSubmit() {
        this.isSubmitAction = true;
    }

public EffortAllocation getEffortAllocation() {
        return effortAllocation;
    }

    public void setEffortAllocation(EffortAllocation effortAllocation) {
        this.effortAllocation = effortAllocation;

        if (isSubmitAction) {
            //transient field within the effort allocation entity
            //this is used to determine whether or not the object should be
removed
            //See removeEffortAllocations code
            effortAllocation.setHoldObj(true);

            if (effortAllocation.getId() == null && form.isValid()) {
                timeSheet.getEffortAllocations().add(effortAllocation);
            }
        }
    }

//Call this method after form example, example onValidate. This will remove
deleted rows where
//isHoldObj hasn't been set to true in the set method.
public void removeEffortAllocations() {
        List<EffortAllocation> effortAllocations = new ArrayList<>();

        for (EffortAllocation _effortAllocation :
timeSheet.getEffortAllocations()) {
            if (!_effortAllocation.isHoldObj()) {
                effortAllocations.add(_effortAllocation);
            }
        }

        if (!effortAllocations.isEmpty()) {
            timeSheet.getEffortAllocations().removeAll(effortAllocations);
        }
    }

void onRemoveRow(EffortAllocation effortAllocation) {
    }
-- 
George Christman
www.CarDaddy.com
P.O. Box 735
Johnstown, New York

Reply via email to