views:

41

answers:

2

I am trying to refine my custom jquery plugin. I have asked this before here. The previous problem was resolved. Now I want to make my plugin more flexible. So instead of relying on hardcoded old classes, I am trying to make it rely on the array of values of the select box which dynamically change the classes based on their values. The reason I am doing this, sometimes the class is not there before I click the select option. Sometimes it does for other selector.

To say better what I am trying to achieve:

If the selector has class any of the select box values, remove this class, add new class, based on the latest selected value.

So here is the latest code:

$.fn.classSwitcher = function(options) {
  var baseOptions = {
    classTarget: 'body',
    newClass: ''
    };

  var options = $.extend(baseOptions, options);

  var allVals = [];

  return this.find('option').each(function() {
  //retrieve all select box values
  allVals.push( $(this).val() );

         $(this).click(function() {
           var t = $(this);
           var newClass = (options.newClass) ? options.newClass : t.val();

           // Is it okay to do hasClass to array values?
           if ($(options.classTarget).hasClass(allVals))  {
           $(options.classTarget).removeClass(allVals).addClass(newClass);
           }

           // problem here I guess, can not update the old class with the one
           allVals = newClass;

           $.cookie('cookieNewClass', newClass, { expires: 1 });
           //alert('New Class: ' + $.cookie('cookieNewClass')); // produced expected new class
           //alert(allVals); // produced expected new classes

  });
});
};

The class is added, but like the previous question, I can't update the targeted class to get replaced with the new one. Please also see the comments in the code for other problem.

Feel free to mark it dup if it is and resolved :)

Any hint would be very much appreciated. Thanks

A: 

You can't pass an array to "hasClass()". Well, you can, but it won't work. jQuery doesn't have a "reduce" or "foldl" function so it's not so clean to do an "any" operation, but here's a hack I just thought of:

if ($.map(allVals, function(_, cv) { return $(options.classTarget).hasClass(cv) ? 'x' : ''); }).join('').length) {
  $.each(allVals, function(_. cv) { $(options.classTarget).removeClass(cv); });
  $(options.classTarget).addClass(newClass);
}

[edit] oops that hack won't work hold on a sec ... [edit] fixed now

Pointy
I had no luck to make it work :(
swan
+1  A: 
$.fn.classSwitcher = function(options) {
 var baseOptions = {
  classTarget: 'body'
 };

  var options = $.extend(baseOptions, options);

 var allVals = this.find('option').map(function(){
  return $(this).val();
 });
 var target = $(options.classTarget);

 this.change(function(){ 
  var t = $(this);
  var newClass = t.val();
  target.removeClass(allVals.get().join(' ')).addClass(newClass);
 });
};
$('select.changer').classSwitcher();

html:

<select class="changer">
 <option value="apple-80">apple-80</option>
 <option value="apple-100">apple-100</option>
 <option value="apple-120">apple-120</option>
 <option value="apple-300">apple-300</option>
</select>
PetersenDidIt
This one works great. A great relief ever. Thank you very much for very kind help.
swan