diff --git a/src/class.settings-api.php b/src/class.settings-api.php
index da58270..848bd25 100755
--- a/src/class.settings-api.php
+++ b/src/class.settings-api.php
@@ -26,6 +26,12 @@ class WeDevs_Settings_API {
*/
protected $settings_fields = array();
+ /**
+ * Tracks whether the repeatable JS has been loaded to prevent multiple calls enqueue_script
+ * @var bool
+ */
+ protected $repeatable_loaded = false;
+
public function __construct() {
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
}
@@ -132,6 +138,7 @@ function admin_init() {
'std' => isset( $option['default'] ) ? $option['default'] : '',
'sanitize_callback' => isset( $option['sanitize_callback'] ) ? $option['sanitize_callback'] : '',
'type' => $type,
+ 'children' => isset( $option['children'] ) ? $option['children'] : null,
);
add_settings_field( $section . '[' . $option['name'] . ']', $option['label'], array( $this, 'callback_' . $type ), $section, $section, $args );
@@ -385,6 +392,77 @@ function callback_color( $args ) {
echo $html;
}
+
+ /**
+ * Displays a repeatable for a settings field. Sanitization, is applied to the final field.
+ *
+ * @param array $args settings field args
+ */
+ function callback_repeatable( $args ) {
+
+ if (!$this->repeatable_loaded) {
+ $url = plugins_url("js/jquery.repeatable.js",__FILE__);
+ wp_enqueue_script("jquery.repeatable", $url, array("jquery"));
+ }
+
+ // Add the repeatable
+ $ex_data = json_decode($this->get_option( $args['id'], $args['section'], $args['std']), true);
+ $ex_keys = array_keys($ex_data);
+
+ $html = '
';
+ $html .= '';
+ echo $html;
+
+ // Add the field group template
+ $template = '';
+
+ echo $template;
+
+ // Push in the JS to make the repeatable go.
+ echo '';
+
+ // On save grab all the values and insert them into the hidden field -- -- this needs to be improved
+ ?>
+
+
+
+ }
+
/**
* Sanitize callback for Settings API
*/
diff --git a/src/js/jquery.repeatable.js b/src/js/jquery.repeatable.js
new file mode 100644
index 0000000..476088e
--- /dev/null
+++ b/src/js/jquery.repeatable.js
@@ -0,0 +1,143 @@
+/*-------------------------------------------
+ * This is basically just a cut and paste of the below
+ * https://github.com/jenwachter/jquery.repeatable
+ *------------------------------------------*/
+
+(function ($) {
+
+ $.fn.repeatable = function (userSettings) {
+
+ /**
+ * Default settings
+ * @type {Object}
+ */
+ var defaults = {
+ addTrigger: ".add",
+ deleteTrigger: ".delete",
+ max: null,
+ startWith: 0,
+ template: null,
+ itemContainer: ".field-group",
+ beforeAdd: function () {},
+ afterAdd: function () {},
+ beforeDelete: function () {},
+ afterDelete: function () {}
+ };
+
+ /**
+ * Iterator used to make each added
+ * repeatable element unique
+ * @type {Number}
+ */
+ var i = 0;
+
+ /**
+ * DOM element into which repeatable
+ * items will be added
+ * @type {jQuery object}
+ */
+ var target = $(this);
+
+ /**
+ * Blend passed user settings with defauly settings
+ * @type {array}
+ */
+ var settings = $.extend({}, defaults, userSettings);
+
+ /**
+ * Total templated items found on the page
+ * at load. These may be created by server-side
+ * scripts.
+ * @return null
+ */
+ var total = function () {
+ return $(target).find(settings.itemContainer).length;
+ }();
+
+
+ /**
+ * Add an element to the target
+ * and call the callback function
+ * @param object e Event
+ * @return null
+ */
+ var addOne = function (e) {
+ e.preventDefault();
+ settings.beforeAdd.call(this);
+ createOne();
+ settings.afterAdd.call(this);
+ };
+
+ /**
+ * Delete the parent element
+ * and call the callback function
+ * @param object e Event
+ * @return null
+ */
+ var deleteOne = function (e) {
+ e.preventDefault();
+ settings.beforeDelete.call(this);
+ $(this).parents(settings.itemContainer).first().remove();
+ total--;
+ maintainAddBtn();
+ settings.afterDelete.call(this);
+ };
+
+ /**
+ * Add an element to the target
+ * @return null
+ */
+ var createOne = function() {
+ getUniqueTemplate().appendTo(target);
+ total++;
+ maintainAddBtn();
+ };
+
+ /**
+ * Alter the given template to make
+ * each form field name unique
+ * @return {jQuery object}
+ */
+ var getUniqueTemplate = function () {
+ var template = $(settings.template).html();
+ template = template.replace(/{\?}/g, "new" + i++); // {?} => iterated placeholder
+ template = template.replace(/\{[^\?\}]*\}/g, ""); // {valuePlaceholder} => ""
+ return $(template);
+ };
+
+ /**
+ * Determines if the add trigger
+ * needs to be disabled
+ * @return null
+ */
+ var maintainAddBtn = function () {
+ if (!settings.max) {
+ return;
+ }
+
+ if (total === settings.max) {
+ $(settings.addTrigger).attr("disabled", "disabled");
+ } else if (total < settings.max) {
+ $(settings.addTrigger).removeAttr("disabled");
+ }
+ };
+
+ /**
+ * Setup the repeater
+ * @return null
+ */
+ (function () {
+ $(settings.addTrigger).on("click", addOne);
+ $("form").on("click", settings.deleteTrigger, deleteOne);
+
+ if (!total) {
+ var toCreate = settings.startWith - total;
+ for (var j = 0; j < toCreate; j++) {
+ createOne();
+ }
+ }
+
+ })();
+ };
+
+})(jQuery);