Current File : //home/tradevaly/www/public/assets/backend/js/repeater.js |
$.fn.repeaterVal = function () {
var parse = function (raw) {
var parsed = [];
foreach(raw, function (val, key) {
var parsedKey = [];
if(key !== "undefined") {
parsedKey.push(key.match(/^[^\[]*/)[0]);
parsedKey = parsedKey.concat(map(
key.match(/\[[^\]]*\]/g),
function (bracketed) {
return bracketed.replace(/[\[\]]/g, '');
}
));
parsed.push({
val: val,
key: parsedKey
});
}
});
return parsed;
};
var build = function (parsed) {
if(
parsed.length === 1 &&
(parsed[0].key.length === 0 || parsed[0].key.length === 1 && !parsed[0].key[0])
) {
return parsed[0].val;
}
foreach(parsed, function (p) {
p.head = p.key.shift();
});
var grouped = (function () {
var grouped = {};
foreach(parsed, function (p) {
if(!grouped[p.head]) {
grouped[p.head] = [];
}
grouped[p.head].push(p);
});
return grouped;
}());
var built;
if(/^[0-9]+$/.test(parsed[0].head)) {
built = [];
foreach(grouped, function (group) {
built.push(build(group));
});
}
else {
built = {};
foreach(grouped, function (group, key) {
built[key] = build(group);
});
}
return built;
};
return build(parse($(this).inputVal()));
};
$.fn.repeater = function (fig) {
fig = fig || {};
var setList;
$(this).each(function () {
var $self = $(this);
var show = fig.show || function () {
$(this).show();
};
var hide = fig.hide || function (removeElement) {
removeElement();
};
var $list = $self.find('[data-repeater-list]').first();
var $filterNested = function ($items, repeaters) {
return $items.filter(function () {
return repeaters ?
$(this).closest(
pluck(repeaters, 'selector').join(',')
).length === 0 : true;
});
};
var $items = function () {
return $filterNested($list.find('[data-repeater-item]'), fig.repeaters);
};
var $itemTemplate = $list.find('[data-repeater-item]')
.first().clone().hide();
var $firstDeleteButton = $filterNested(
$filterNested($(this).find('[data-repeater-item]'), fig.repeaters)
.first().find('[data-repeater-delete]'),
fig.repeaters
);
if(fig.isFirstItemUndeletable && $firstDeleteButton) {
$firstDeleteButton.remove();
}
var getGroupName = function () {
var groupName = $list.data('repeater-list');
return fig.$parent ?
fig.$parent.data('item-name') + '[' + groupName + ']' :
groupName;
};
var initNested = function ($listItems) {
if(fig.repeaters) {
$listItems.each(function () {
var $item = $(this);
foreach(fig.repeaters, function (nestedFig) {
$item.find(nestedFig.selector).repeater(extend(
nestedFig, { $parent: $item }
));
});
});
}
};
var $foreachRepeaterInItem = function (repeaters, $item, cb) {
if(repeaters) {
foreach(repeaters, function (nestedFig) {
cb.call($item.find(nestedFig.selector)[0], nestedFig);
});
}
};
var setIndexes = function ($items, groupName, repeaters) {
$items.each(function (index) {
var $item = $(this);
$item.data('item-name', groupName + '[' + index + ']');
$filterNested($item.find('[name]'), repeaters)
.each(function () {
var $input = $(this);
// match non empty brackets (ex: "[foo]")
var matches = $input.attr('name').match(/\[[^\]]+\]/g);
var name = matches ?
// strip "[" and "]" characters
last(matches).replace(/\[|\]/g, '') :
$input.attr('name');
var newName = groupName + '[' + index + '][' + name + ']' +
($input.is(':checkbox') || $input.attr('multiple') ? '[]' : '');
$input.attr('name', newName);
$foreachRepeaterInItem(repeaters, $item, function (nestedFig) {
var $repeater = $(this);
setIndexes(
$filterNested($repeater.find('[data-repeater-item]'), nestedFig.repeaters || []),
groupName + '[' + index + ']' +
'[' + $repeater.find('[data-repeater-list]').first().data('repeater-list') + ']',
nestedFig.repeaters
);
});
});
});
$list.find('input[name][checked]')
.removeAttr('checked')
.prop('checked', true);
};
setIndexes($items(), getGroupName(), fig.repeaters);
initNested($items());
if(fig.initEmpty) {
$items().remove();
}
if(fig.ready) {
fig.ready(function () {
setIndexes($items(), getGroupName(), fig.repeaters);
});
}
var appendItem = (function () {
var setItemsValues = function ($item, data, repeaters) {
if(data || fig.defaultValues) {
var inputNames = {};
$filterNested($item.find('[name]'), repeaters).each(function () {
var key = $(this).attr('name').match(/\[([^\]]*)(\]|\]\[\])$/)[1];
inputNames[key] = $(this).attr('name');
});
$item.inputVal(map(
filter(data || fig.defaultValues, function (val, name) {
return inputNames[name];
}),
identity,
function (name) {
return inputNames[name];
}
));
}
$foreachRepeaterInItem(repeaters, $item, function (nestedFig) {
var $repeater = $(this);
$filterNested(
$repeater.find('[data-repeater-item]'),
nestedFig.repeaters
)
.each(function () {
var fieldName = $repeater.find('[data-repeater-list]').data('repeater-list');
if(data && data[fieldName]) {
var $template = $(this).clone();
$repeater.find('[data-repeater-item]').remove();
foreach(data[fieldName], function (data) {
var $item = $template.clone();
setItemsValues(
$item,
data,
nestedFig.repeaters || []
);
$repeater.find('[data-repeater-list]').append($item);
});
}
else {
setItemsValues(
$(this),
nestedFig.defaultValues,
nestedFig.repeaters || []
);
}
});
});
};
return function ($item, data) {
$list.append($item);
setIndexes($items(), getGroupName(), fig.repeaters);
$item.find('[name]').each(function () {
$(this).inputClear();
});
setItemsValues($item, data || fig.defaultValues, fig.repeaters);
};
}());
var addItem = function (data) {
var $item = $itemTemplate.clone();
appendItem($item, data);
if(fig.repeaters) {
initNested($item);
}
show.call($item.get(0));
};
setList = function (rows) {
$items().remove();
foreach(rows, addItem);
};
$filterNested($self.find('[data-repeater-create]'), fig.repeaters).click(function () {
addItem();
});
$list.on('click', '[data-repeater-delete]', function () {
var self = $(this).closest('[data-repeater-item]').get(0);
hide.call(self, function () {
$(self).remove();
setIndexes($items(), getGroupName(), fig.repeaters);
});
});
});
this.setList = setList;
return this;
};