LStarky LStarky - 1 month ago 13
jQuery Question

Using jQuery MiniColors with Aurelia binding

For some reason the jQuery MiniColors color picker (http://labs.abeautifulsite.net/jquery-minicolors/) seems to not work correctly with Aurelia data binding.

calendar.html (template):

<!-- src/settings/school/calendars -->
<template>
<require from="jquery-minicolors/jquery.minicolors.css"></require>
<form>
<div class="form-group">
<label class="control-label" for="cal_name_orig"><span t="Calendar_name"></span></label>
<input type="text" class="form-control" ref="cal_name_orig" value.bind="calendar.cal_name_orig & validate" />
</div>
<div class="form-group">
<label class="control-label" for="cal_color"><span t="Color"></span></label>
<input type="text" id="cal_color" class="form-control" value.bind="calendar.cal_color">
</div>
</form>
</template>


And my calendar.js (view-model)

//src/settings/school/calendars.js
import 'jquery-minicolors';

export class SettingsSchoolCalendars {

error = null;
selectedId = null;
calendar = {};

attached() {
var self = this;
// set focus when modal is shown
$("#cal_color").minicolors({
control: "wheel",
theme: "bootstrap",
});
}
}


The control works in the form, but there are two problems with the binding:


  1. The value of calendar.cal_color appears in the input but does NOT set the color of the color picker.

  2. When I change the color picker color, the new value appears in the input but does NOT update the binded value calendar.cal_color.



Is jQuery MiniColors messing with the value.bind property of the input control? Is there another explanation?

I can successfully get the model to update by adding this to the MiniColors instantiation:

change: function(hex, opacity) {
self.calendar.cal_color = hex;
}


But, I can't seem to do the opposite (update the MiniColors control when the model changes). And it still doesn't load the initial color correctly.

Help!

Answer

I don't seem to be having issues with this control. I just played with it.

In my HTML, I have this:

<input type="text" ref="minicolors" value.bind="color" class="form-control" id="color">
<div>Color: ${color}</div>

Then I set a default color:

color = '#ff6161';

Finally, in my attached callback, I use the ref'd element:

attached() {
  $(this.minicolors).minicolors({
    change: (value, opacity) => {
      this.color = value;
    }
  });
}

It's all working for me as expected.

Edit: I finally got around to creating a gist to show this all off: https://gist.run/?id=6e4a6ea77751ae9c69b178eb51105137

app.html

<template>
    Control value: ${controlValue}
  <form>
        <div class="form-group">
            <test></test>
            <label for="color">Color</label>
            <input type="text" value.bind="colorInfo.color" class="form-control" id="color">
      <div>Color: ${colorInfo.color}</div>
        </div>
        <div class="form-group">
            <test></test>
            <label for="color">Color</label>
            <input type="text" ref="minicolors" value.bind="colorInfo.color" class="form-control" id="color">
      <div>Color: ${colorInfo.color}</div>
        </div>
    </form>
</template>

app.js

import {inject, BindingEngine} from 'aurelia-framework';

@inject(BindingEngine)
export class App {
  colorInfo = {
    color: '#ff6161'
  }

  constructor(bindingEngine) {
    this.subscription = bindingEngine.propertyObserver(this.colorInfo, 'color')
      .subscribe( () => {
        this.widget.minicolors('value', this.colorInfo.color);
      });
  }

  attached() {
    this.widget = $(this.minicolors);
    this.widget.minicolors({
      change: (color, opacity) => {
        this.colorInfo.color = color; 
        this.colorInfo.opacity = opacity;
      } 
    });
  }

  get controlValue() {
    if(this.widget) {
      return this.widget.minicolors('value');
    }
    return '';
  }

  detached() {
    subscription.dispose();
  }
}
Comments