Repeat group elements order changes after save

Status
Not open for further replies.
Hi,
I am developing an app on Joomla 3.3.0 / Fabrik 3.1 and I noticed then, after saving a form, the repeat group elements are seen in a different way from JavaScript.

IfI make a simple:
Object.each(block.elements, function (element, key) {
console.log(key);
});

if I am in a new form, it gives me this result;

family_name_0
first_name_0
address_0
family_name_1
first_name_1
address_1
family_name_2
first_name_2
address_2
...

if, instead, I'm in a saved form, this is the result:

family_name_0
family_name_1
family_name_2
first_name_0
first_name_1
first_name_2
address_0
address_1
address_2

so I had to write 2 different codes to read the form.

What I'm asking is: is it a bug, is it working as designed or am I doing something wrong? Will ths change if I update to latest joomla/fabrink?
 
In general, the ordering of the objects shouldn't matter, and your JS shouldn't make assumptions about what the order will be. What is your code trying to do?

If you give us an overview of what you are trying to do, and paste your code here, we can probably help.

-- hugh
 
Something like:
var lineIndex = 0;
Object.each(block.elements, function (element, key) {
if (key.contains('orders_7_repeat___line_room_type')) {
lineIndex = offerLines.length;
offerLines[lineIndex] = new offerLine();
console.log(lineIndex);
offerLines[lineIndex].line_room_type = element.get('value').toFloat();
} else if (key.contains('orders_7_repeat___room_name')) {
offerLines[lineIndex].room_name = element.get('value');
} else if (key.contains('orders_7_repeat___rooms')) {
offerLines[lineIndex].rooms = element.get('value').toFloat();
}
....
} else if (key.contains('orders_7_repeat___referring')) {
offerLines[lineIndex].referring = element.get('value').toFloat();
}
});

And be sure order matters :), this because every time you are on the first field of the repeat group, you know you are on a new line. If you check a saved form with this code, you will make n new lines by reading the first elements, while only the last line will containg last repeat element data, because this code will continuously rewrite the last line.

To read it, I had to make something like (not so elegant, I know, but I was in a hurry):
Object.each(block.elements, function (element, key) {
if (key.contains('orders_7_repeat___line_room_type')) {
offerLines[lineIndex] = new offerLine();
offerLines[lineIndex].line_room_type = element.get('value').toFloat();
lineIndex++;
elementLines++;
} else if (key.contains('orders_7_repeat___room_name')) {
if (lineIndex > elementLines - 1) {
lineIndex = 0;
}
offerLines[lineIndex].room_name = element.get('value');
lineIndex++;
}
...

} else if (key.contains('orders_7_eta')) {
if (lineIndex > elementLines - 1) {
lineIndex = 0;
}
offerLines[lineIndex].eta = element.get('value').toFloat();
lineIndex++;
} else if (key.contains('orders_7_referring')) {
if (lineIndex > elementLines - 1) {
lineIndex = 0;
}
offerLines[lineIndex].referring = element.get('value').toFloat();
lineIndex++;
}

});
 
However, code works but I want to be sure it will not crash at next update...

By the way, to kow if I'm in a new form or if I'm editing an existing record, I check the form ID with something like:
if(!offerId) {
Do you think there's a more solid and elegant way to check it?
 
I guess I phrased my response incorrectly. Obviously ordering "matters", but typically you can never guarrantee or make assumptions that ordering of someone else's data structures will remain the same. So it's always better to write code which doesn't depend on ordering.

In this case, you'd probably be better off working from the formElements[] array. First grab the block you need. So if this is form ID 2 ...

Code:
var block = Fabrik.getBlock('form_2');

Then you can get the number of repeats for your group from the repeatGroupMarkers array. So if this is (say) group ID 11 ...

Code:
var numRepeats = block.repeatGroupMarkers[11];

Note that repeat num suffixes are always going to be sequential, even if you add and remove groups. We re-shuffle id's so you don't have gaps.

Now you know how many repeats there are, so you can iterate, and pick up the values you need ...

Code:
for (var rnum = 0; rnum < numRepeats; rnum ++) {
  var room_name = block.formElements.get('orders_7_repeat___room_name_' + rnum).getValue();
  // do whatever you need to do with room_name here ... etc etc
}

Also, note that by doing it this way, using the Fabrik element objects and getValue(), you are running the actual Fabrik element object's getValue() method, which will return a value more consistently than using the DOM element get('value'). For instance, a date element has separate input DOM elements which contain the date and time parts. But calling the Fabrik object getValue() will return those, re-assembled, and normalized into a MySQL format, GMT value.

Hopefully that should get you headed in the right direction.

-- hugh
 
Hi,
just for curiosity... If I had more than one repeating group, how could I find how many times each of them reiterates?

Thanks
 
Status
Not open for further replies.
We are in need of some funding.
More details.

Thank you.

Members online

No members online now.
Back
Top