Search code examples
javascriptjqueryvue.jsswitchery

Wrapping Switchery in a Directive VueJS


I am trying to wrap the Switchery iOS 7 in a Vue Directive but I had no success until now! Somebody to help me?

There is my code fiddle.

JS

Vue.directive('plSwitchery', {
  twoWay: true,

  deep: true,

  params: [],

  bind: function() {

    var self = this,
      value = self.value,
      el = self.el;

    el.checked = true;

    new Switchery(el);

    $(el).on('change', function(a) {
      value = !value;
      self.set(value);
      alert(self.value);
    });

  },
  update: function(value) {
    window.console.log('directive update');
  },
  unbind: function() {
    this.el.destroy();
  }
});

var vm = new Vue({
  el: '#app',
  data: {
    selected: 1,
  },
  methods: {
    onChange: function() {
      alert('Do HTTP request');
    }
  }
});

HTML

<div id="app">

  <input type="checkbox" v-pl-switchery="selected" />

</div>

So I could wrap it and it's partially working... Now I need to know how to update my SELECTED data and how to call the method onChange when the user trigger the change event to call the server and update some information on the database!

I don't really get how to deal with it!

Thanks in advance!


Solution

  • Actually I gave up Switchery plugin and I've made my own component!

    There is my solution!

    JS

    Vue.component('plSwitch', {
      template: '#ck',
      props: {
        model: {
          default () {
            return false
          }
        },
        text: {
          default () {
            return;
          }
        },
        disabled: {
          default () {
            return false
          }
        }
      },
      methods: {
        onChange() {
          console.log('oi')
          vm.$dispatch('onChange')
        }
      }
    })
    
    var vm = new Vue({
      el: '#add',
      data: {
        state: true
      },
      events: {
        onChange: function() {
          alert('Do HTTP request');
        }
      }
    })
    

    CSS

    .label_switch {
      display: inline-block;
      margin: 0;
      cursor: pointer;
      font-weight: normal;
      position: relative;
    }
    .label_switch input[type="checkbox"] {
      position: absolute;
      -webkit-appearance: none;
      appearance: none;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      margin: 0;
      opacity: 0;
      cursor: pointer;
    }
    .label_switch input[type="checkbox"] + span {
      display: inline-block;
      width: 38px;
      height: 18px;
      position: relative;
    }
    .label_switch input[type="checkbox"] + span:before {
      content: "";
      display: block;
      width: 38px;
      height: 22px;
      border-radius: 20px;
      border: 1px solid #dfdfdf;
      -webkit-transition: all 0.1s ease-out;
      transition: all 0.1s ease-out;
    }
    .label_switch:hover input[type="checkbox"] + span:before {
      box-shadow: inset 0 0 15px #eee;
    }
    .label_switch input[type="checkbox"] + span:after {
      content: "";
      position: absolute;
      top: 0px;
      left: 0;
      display: block;
      width: 22px;
      height: 22px;
      -webkit-transition: all 0.3s ease-out;
      transition: all 0.3s ease-out;
      background: #fff;
      border-radius: 20px;
      border: solid 1px #dfdfdf;
      box-shadow: 2px 1px 1px -2px rgba(0, 0, 0, 0.4)
    }
    .label_switch input[type="checkbox"]:checked + span:after {
      left: 18px;
      border: solid 1px #5FBEAA;
      box-shadow: none;
    }
    .label_switch input[type="checkbox"]:checked + span:before,
    .label_switch input[type="checkbox"]:disabled:checked + span:before {
      border: 1px solid #5FBEAA;
      background-color: #5FBEAA;
    }
    .label_switch:hover input[type="checkbox"]:checked + span:before {
      box-shadow: none;
    }
    .label_switch input[type="checkbox"]:disabled + span {
      opacity: 0.6;
    }
    .label_switch input[type="checkbox"]:disabled + span:before {
      background-color: #f7f7f7;
    }
    .label_switch input[type="checkbox"]:disabled + span:after {
      background-color: #f3f3f3;
    }
    .label_switch input[type="checkbox"]:disabled + span:after {
      background-color: #fff;
    }
    .label_switch input[type="checkbox"]:disabled + span:before,
    .label_switch input[type="checkbox"]:disabled + span:after {
      cursor: no-drop;
    }
    .label_switch input[type="checkbox"]:disabled:checked + span:before {} .m-r-5 {
      margin-right: 5px !important;
    }
    .m-l-5 {
      margin-left: 5px !important;
    }
    .disabled {
      cursor: no-drop!important;
    }
    

    HTML

    <template id="ck">
      <label class="label_switch" :class="{ 'disabled' : disabled }">
        <input type="checkbox" v-model="model" :false-value="false" :true-value="true" :disabled="disabled" @click="onChange()">
        <span :class="{ 'm-r-5': text != '' }"></span> {{ text }}
      </label>
    </template>
    
    <div id="add">
      <pre>{{ $data | json }}</pre>
      <pl-switch :model.sync="state" text="Example"></pl-switch>
    </div>
    

    Let me know you do you guys think!