// vim: et:ts=4:sw=4:sts=4:ft=javascript 'use strict'; /*@ Ox.OptionGroup OptionGroup Helper object, used by ButtonGroup, CheckboxGroup, Select and Menu (items, min, max, property) -> OptionGroup items array of items min minimum number of selected items max maximum number of selected items property property to check @*/ Ox.OptionGroup = function(items, min, max, property) { var length = items.length; property = property || 'checked'; max = max == -1 ? length : max; function getLastBefore(pos) { // returns the position of the last checked item before position pos var last = -1; /*Ox.Log('Form', items, items.length, length, Ox.merge( pos > 0 ? Ox.range(pos - 1, -1, -1) : [], pos < items.length - 1 ? Ox.range(items.length - 1, pos, -1) : [] ))*/ // fixme: why is length not == items.length here? Ox.forEach(Ox.merge( pos > 0 ? Ox.range(pos - 1, -1, -1) : [], pos < items.length - 1 ? Ox.range(items.length - 1, pos, -1) : [] ), function(v) { //Ox.Log('Form', pos, v) if (items[v][property]) { last = v; return false; } }); return last; } function getNumber() { // returns the number of checked items var num = 0; items.forEach(function(item) { if (item[property]) { num++; } }); return num; } /*@ [property] returns an array with the positions of all checked item () -> returns checked items @*/ this[property] = function() { // returns an array with the positions of all checked item var checked = []; items.forEach(function(item, i) { if (item[property]) { checked.push(i); } }) return checked; }; /*@ init init group () -> returns items @*/ this.init = function() { var num = getNumber(), count = 0; //if (num < min || num > max) { items.forEach(function(item) { if (Ox.isUndefined(item[property])) { item[property] = false; } if (item[property]) { count++; if (count > max) { item[property] = false; } } else { if (num < min) { item[property] = true; num++; } } }); //} return items; }; /*@ toggle toggle options (pos) -> returns toggled state @*/ this.toggle = function(pos) { var last, num = getNumber(), toggled = []; if (!items[pos][property]) { // check if (num >= max) { last = getLastBefore(pos); items[last][property] = false; toggled.push(last); } if (!items[pos][property]) { items[pos][property] = true; toggled.push(pos); } } else { // uncheck if (num > min) { items[pos][property] = false; toggled.push(pos); } } return toggled; } return this; }