0

Below is part of a plugin I'm working. Its my first plugin. I can access and send values to functions. But now when i try to get an array from a function, its sending me an Object! Can anyone tell me what is wrong with getValue function? its returning object instead of the array $selected_items

(function($){
    function WMPlugin(item, options) {
        this.options = $.extend({
            selectableList_header: null,
            selectedList_header: null,
        }, options);


        this.$element = $(item);
        this.$container = $('<div/>', { 'class': "wmdl-container" });
        this.$selectable_list = $('<ul/>', { 'class': 'wmdl-selectable-list' });
        this.$selected_list = $('<ul/>', { 'class': 'wmdl-selected-list' });

        this.config = $.extend(true, {
            selectableList_header: null,
            selectedList_header: null,
        }, options || {});

        this.init();
    }
    WMPlugin.prototype = {
        init: function (options) {
            $.extend(this.options, options);
            var $select = this.$element;         
            var $wmdl = this.generateWMDL();
            $select.after($wmdl);
            $select.hide();
            return $wmdl;
        },

        generateWMDL: function (options) {
            var $container = this.$container;
            var $selectable_list = this.selectableList();
            var $selected_list = this.selectedList();
            $container.append($selectable_list).append($selected_list);
            return $container;
        },

        selectableList: function (options) {
            $.extend(this.options, options);
            var $this = this;
            var $selectable_list = this.$selectable_list;
            var $select = this.$element;

            var $optgroups = $select.children('optgroup');
            var $i = 1;
            if( $optgroups.length > 0 ) {
                $optgroups.each(function(i, group){
                    var $group = $(group);
                    var $group_label = $group.attr('label');

                    if ($group_label == "") {
                        $group_label = '<small>No name found</small>';
                    }

                    var $group_parent = $('<li>')
                                        .addClass('wmdl-has-group')
                                        .html('<span>' + $group_label + '</span>');



                    var  $group_ul = $('<ul>')
                                    .addClass('wmdl-group')
                                    .attr('data-wmdl-group', 'wmdl-group-'+i);
                    $group.attr('id', 'wmdl-group-'+i);

                    $group_parent.append($group_ul);

                    $selectable_list.append($group_parent);
                });
            }


            $select.find('option').each(function(i, item) {
                var $item = $(item);
                var $item_value = $(item).attr('value');
                var $item_text = $(item).text();
                var $item_optgroup = $item.parent('optgroup');

                if ($item.is(':selected')) {
                    var $li =  $('<li>')
                                    .css('display', 'none')
                                    .attr('data-wmdl-value', $item_value)
                                    .text($item_text);
                } else {
                    var $li =  $('<li>')
                                    .attr('data-wmdl-value', $item_value)
                                    .text($item_text);
                }

                if ($item_optgroup.length > 0) {
                    var $item_optgroup_id = $item_optgroup.attr('id');
                    $selectable_list.find('[data-wmdl-group="'+ $item_optgroup_id +'"]').append($li);
                } else {
                    $selectable_list.append($li);
                }

                $this.addItem($li);
            });

            return $selectable_list;
        },

        selectedList: function (options) {
            $.extend(this.options, options);
            var $this = this;
            var $select = this.$element;
            var $selected_list = this.$selected_list;

            $select.find('option:selected').each(function(i, item) {
                var $item = $(item);
                var $item_value = $(item).attr('value');
                var $item_text = $(item).text();
                var $item_optgroup = $item.parent('optgroup');
                if ($item_optgroup_label == "") {
                    $item_optgroup_label = '<small>No name found</small>';
                }

                var $li =  $('<li>')
                                .attr('data-wmdl-value', $item_value)
                                .text($item_text);

                if ($item_optgroup.length > 0) {
                    var $item_optgroup_id = $item_optgroup.attr('id');
                    var $item_optgroup_selectedList = $selected_list.find('[data-wmdl-group="'+ $item_optgroup_id +'"]');
                    if ($item_optgroup_selectedList.length > 0) {
                        $item_optgroup_selectedList.append($li);
                    } else {
                        var $item_optgroup_label = $item_optgroup.attr('label');
                        var $group_parent = $('<li>')
                                                .addClass('wmdl-has-group')
                                                .html('<span>' + $item_optgroup_label + '</span>');
                        var  $group_ul = $('<ul>')
                                        .addClass('wmdl-group')
                                        .attr('data-wmdl-group', $item_optgroup_id);

                        $group_parent.append($group_ul);
                        $group_ul.append($li);
                        $selected_list.append($group_parent);
                    }
                } else {
                    $selected_list.append($li);
                }

                $this.removeItem($li);
            });

            return $selected_list;
        },

        getValue: function () {
            var $this = this;
            var $selected_list = this.$selected_list;
            var $selectable_list = this.$selectable_list;
            var $selected_items = [];
            $selected_list.find('li').each(function(){
                var $value = $(this).attr('data-wmdl-value');
                $selected_items.push($value);
            })

            return $selected_items;
        },
    }

    // jQuery plugin interface
    $.fn.WMDuelList = function(opt) {
        var args = Array.prototype.slice.call(arguments, 1);
        return this.each(function() {
            var item = $(this), instance = item.data('WMPlugin');
            if(!instance) {
                // create plugin instance if not created
                item.data('WMPlugin', new WMPlugin(this, opt));
            } else {
                // otherwise check arguments for method call
                if(typeof opt === 'string') {
                    instance[opt].apply(instance, args);
                }
            }
        });
    }

}(jQuery));

Working JSFiddle - https://jsfiddle.net/uh7w0dwb/

7
  • looks like it's to do with the way this is being called? have you tried diong a console.log($selected_items[1]); before the return to check if there's a second array item? or console.log($selected_items.length); Commented Mar 5, 2017 at 21:42
  • Provide a minimal reproducible example that reproduces problem Commented Mar 5, 2017 at 21:46
  • @Sam0, I if print it in console inside the function, i get the array. But when i want to call it by $(element).MWDuelList('getValue);, i'm getting an object Commented Mar 5, 2017 at 21:47
  • @charlietfl, I had another question created on this plugin. But no one responded there. It has complete codes (though, i updated the pattern in this above codes). You can check it. Commented Mar 5, 2017 at 21:50
  • Questions should be self contained. Commented Mar 5, 2017 at 21:52

2 Answers 2

1

you could try changing the return context of your plugin interface. This works on the basis that there is only one instance of list items being returned. i.e. providing the getValue is called on an ID and not a class with multiple occurrences.

UPDATED: pushing results into an array for multiple instances:

    // jQuery plugin interface
    $.fn.WMDuelList = function(opt) {
        var args = Array.prototype.slice.call(arguments, 1), inst=[];
        this.each(function() {
            var item = $(this), instance = item.data('WMPlugin');
            if(!instance) {
                // create plugin instance if not created
                item.data('WMPlugin', new WMPlugin(this, opt));
            } else {
                // otherwise check arguments for method call
                if(typeof opt === 'string') {
                    inst.push(instance[opt].apply(instance, args));
                }
            }
        });
        return inst;
    } 

you'll need to remember to use console.log(value[0]); where there's one instance. There may however be scenario's in which this pattern isn't ideal.

(function($) {
  function WMPlugin(item, options) {
    this.options = $.extend({
      selectableList_header: null,
      selectedList_header: null,
    }, options);


    this.$element = $(item);
    this.$container = $('<div/>', {
      'class': "wmdl-container"
    });
    this.$selectable_list = $('<ul/>', {
      'class': 'wmdl-selectable-list'
    });
    this.$selected_list = $('<ul/>', {
      'class': 'wmdl-selected-list'
    });

    this.config = $.extend(true, {
      selectableList_header: null,
      selectedList_header: null,
    }, options || {});

    this.init();
  }
  WMPlugin.prototype = {
    init: function(options) {
      $.extend(this.options, options);
      var $select = this.$element;
      var $wmdl = this.generateWMDL();
      $select.after($wmdl);
      $select.hide();
      return $wmdl;
    },

    generateWMDL: function(options) {
      var $container = this.$container;
      var $selectable_list = this.selectableList();
      var $selected_list = this.selectedList();
      $container.append($selectable_list).append($selected_list);
      return $container;
    },

    selectableList: function(options) {
      $.extend(this.options, options);
      var $this = this;
      var $selectable_list = this.$selectable_list;
      var $select = this.$element;

      var $optgroups = $select.children('optgroup');
      var $i = 1;
      if ($optgroups.length > 0) {
        $optgroups.each(function(i, group) {
          var $group = $(group);
          var $group_label = $group.attr('label');

          if ($group_label == "") {
            $group_label = '<small>No name found</small>';
          }

          var $group_parent = $('<li>')
            .addClass('wmdl-has-group')
            .html('<span>' + $group_label + '</span>');



          var $group_ul = $('<ul>')
            .addClass('wmdl-group')
            .attr('data-wmdl-group', 'wmdl-group-' + i);
          $group.attr('id', 'wmdl-group-' + i);

          $group_parent.append($group_ul);

          $selectable_list.append($group_parent);
        });
      }


      $select.find('option').each(function(i, item) {
        var $item = $(item);
        var $item_value = $(item).attr('value');
        var $item_text = $(item).text();
        var $item_optgroup = $item.parent('optgroup');

        if ($item.is(':selected')) {
          var $li = $('<li>')
            .css('display', 'none')
            .attr('data-wmdl-value', $item_value)
            .text($item_text);
        } else {
          var $li = $('<li>')
            .attr('data-wmdl-value', $item_value)
            .text($item_text);
        }

        if ($item_optgroup.length > 0) {
          var $item_optgroup_id = $item_optgroup.attr('id');
          $selectable_list.find('[data-wmdl-group="' + $item_optgroup_id + '"]').append($li);
        } else {
          $selectable_list.append($li);
        }

      });

      return $selectable_list;
    },

    selectedList: function(options) {
      $.extend(this.options, options);
      var $this = this;
      var $select = this.$element;
      var $selected_list = this.$selected_list;

      $select.find('option:selected').each(function(i, item) {
        var $item = $(item);
        var $item_value = $(item).attr('value');
        var $item_text = $(item).text();
        var $item_optgroup = $item.parent('optgroup');
        if ($item_optgroup_label == "") {
          $item_optgroup_label = '<small>No name found</small>';
        }

        var $li = $('<li>')
          .attr('data-wmdl-value', $item_value)
          .text($item_text);

        if ($item_optgroup.length > 0) {
          var $item_optgroup_id = $item_optgroup.attr('id');
          var $item_optgroup_selectedList = $selected_list.find('[data-wmdl-group="' + $item_optgroup_id + '"]');
          if ($item_optgroup_selectedList.length > 0) {
            $item_optgroup_selectedList.append($li);
          } else {
            var $item_optgroup_label = $item_optgroup.attr('label');
            var $group_parent = $('<li>')
              .addClass('wmdl-has-group')
              .html('<span>' + $item_optgroup_label + '</span>');
            var $group_ul = $('<ul>')
              .addClass('wmdl-group')
              .attr('data-wmdl-group', $item_optgroup_id);

            $group_parent.append($group_ul);
            $group_ul.append($li);
            $selected_list.append($group_parent);
          }
        } else {
          $selected_list.append($li);
        }

      });

      return $selected_list;
    },

    getValue: function() {
      var $this = this;
      var $selected_list = this.$selected_list;
      var $selectable_list = this.$selectable_list;
      var $selected_items = [];
      $selected_list.find('li').each(function() {
        var $value = $(this).attr('data-wmdl-value');
        $selected_items.push($value);
      });

      return $selected_items;
    }
  }

  // jQuery plugin interface
  $.fn.WMDuelList = function(opt) {
    var args = Array.prototype.slice.call(arguments, 1),
      inst = [];
    this.each(function() {
      var item = $(this),
        instance = item.data('WMPlugin');
      if (!instance) {
        // create plugin instance if not created
        item.data('WMPlugin', new WMPlugin(this, opt));
      } else {
        // otherwise check arguments for method call
        if (typeof opt === 'string') {
          inst.push( instance[opt].apply(instance, args));
        }
      }
    });
    return inst;
  }

}(jQuery));

$(document).ready(function() {
  $('#wm-duel-list').WMDuelList({

  });

  $('#get-value').click(function() {
    var value = $('#wm-duel-list').WMDuelList('getValue');
    console.log(value[0]);
  });
});
body {
  font-family: Arial;
}

.wmdl-container {
  position: relative;
  box-sizing: border-box;
  padding: 0;
  margin: 0 0 15px 0;
}

.wmdl-container * {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.wmdl-container:after,
.wmdl-header:after {
  clear: both;
  content: " ";
  height: 0;
  display: block;
}

.wmdl-container:before {
  content: "\21C4";
  display: block;
  position: absolute;
  font-size: 200%;
  font-weight: 900;
  color: #000;
  top: 50%;
  left: 50%;
  -moz-transform: translatex(-50%) translatey(-50%);
  -ms-transform: translatex(-50%) translatey(-50%);
  -o-transform: translatex(-50%) translatey(-50%);
  -webkit-transform: translatex(-50%) translatey(-50%);
  transform: translatex(-50%) translatey(-50%);
}

.wmdl-header {
  position: relative;
}

.wmdl-header>div {
  border-top-left-radius: 5px;
  border-top-right-radius: 5px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: "...";
  padding: 10px 15px;
  background-color: #0275D8;
  color: #fff;
  font-size: 110%;
  font-weight: bold;
  text-align: center;
}

.wmdl-header>div,
.wmdl-selectable-list,
.wmdl-selected-list {
  position: relative;
  float: left;
  width: calc(50% - 20px);
}

.wmdl-selectable-list,
.wmdl-selected-list {
  list-style: none;
  border: 1px solid #ccc;
  border-radius: 5px;
  height: 211px;
  overflow-y: auto;
  overflow-x: hidden;
}

.wmdl-header>div:first-child,
.wmdl-selectable-list {
  margin-right: 40px;
}

.has-header .wmdl-selectable-list,
.has-header .wmdl-selected-list {
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}

.wmdl-selectable-list>li,
.wmdl-selected-list>li {
  list-style-type: none;
  padding: 7px 15px;
  border-bottom: 1px solid #ccc;
  cursor: pointer;
}

.wmdl-selectable-list>li.wmdl-has-group,
.wmdl-selected-list>li.wmdl-has-group {
  padding: 0;
}

.wmdl-selectable-list>li:not(.wmdl-has-group):hover,
.wmdl-selected-list>li:not(.wmdl-has-group):hover {
  background-color: #0275D8;
  color: #fff;
}

.wmdl-selectable-list>li.wmdl-has-group>span,
.wmdl-selected-list>li.wmdl-has-group>span {
  display: block;
  padding: 4px 15px;
  background-color: #ccc;
}

.wmdl-group {
  list-style: none;
  padding: 0;
  margin: 0;
}

.wmdl-group>li {
  padding: 7px 25px;
  list-style-type: none;
  border-bottom: 1px solid #ccc;
}

.wmdl-group>li:hover {
  background-color: #0275D8;
  color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="wm-duel-list" multiple="multiple">
		<option value="1">Item 1</option>
		<option value="2">Item 2</option>
		<option value="3" selected>Item 3</option>
		<option value="4" selected>Item 4</option>
		<option value="5" selected>Item 5</option>
		<option value="6" selected>Item 6</option>
		<option value="7" selected>Item 7</option>
		<option value="8">Item 8</option>
		<option value="9">Item 9</option>
		<option value="10">Item 10</option>
	</select>

<div class="div">
  <button id="get-value">Get</button>
</div>

Sign up to request clarification or add additional context in comments.

6 Comments

It works!! But, what if i'll have multiple functions which will return some string or array like the getValue?
alternate option is to then push those into an array and return that, this means you'll be making a 2d array and you'll need to remember to request the first item. Would you like the answer amended to reflect?
Yes, if you can amend it would be great for me and also for others who faces the same situation. I'm going to mark it as answer anyway. But will be waiting for the amend. Also, please try include a sample of creating Private function. Or i can create another question and u can answer about the private function.
Amended. Didn't quite understand your question about the private function? Your jquery plugin pattern uses strategies I'm unfamiliar with and is very different to the one I'm use to so I may not be able to help. Can have a look but no promises.
What i mean is, I learned using '' makes a function private, means not callable like getValue. But in this plugin if i use '' i can still call the function. For example _getValue. It would be nice if you can show the pattern you use on ur plugins.
|
1

Can change the main plugin function to check for string first before entering the each loop.

If it is string and that method exists return the method call and if method doesn't exist throw error or do something else

Something like:

  // jQuery plugin interface
  $.fn.WMDuelList = function(opt) {
    var args = Array.prototype.slice.call(arguments, 1);

    if (typeof opt === 'string') {
      var instance = this.data('WMPlugin');
      if (instance && instance[opt]) {
        return instance[opt]();
      } else {
        console.error('Either method does not exist or plugin hasn\'t been initialized')
      }

    } else {
      return this.each(function() {
        var item = $(this),
          instance = item.data('WMPlugin');
        if (!instance) {
          // create plugin instance if not created
          item.data('WMPlugin', new WMPlugin(this, opt));
        }

      });
    }

  }

DEMO

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.