model.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. var utils = require('../utils'),
  2. isIE9 = navigator.userAgent.indexOf('MSIE 9.0') > 0
  3. module.exports = {
  4. bind: function () {
  5. var self = this,
  6. el = self.el,
  7. type = el.type
  8. self.lock = false
  9. // determine what event to listen to
  10. self.event =
  11. (self.compiler.options.lazy ||
  12. el.tagName === 'SELECT' ||
  13. type === 'checkbox' ||
  14. type === 'radio')
  15. ? 'change'
  16. : 'input'
  17. // determin the attribute to change when updating
  18. var attr = type === 'checkbox'
  19. ? 'checked'
  20. : 'value'
  21. // attach listener
  22. self.set = self.filters
  23. ? function () {
  24. // if this directive has filters
  25. // we need to let the vm.$set trigger
  26. // update() so filters are applied.
  27. // therefore we have to record cursor position
  28. // so that after vm.$set changes the input
  29. // value we can put the cursor back at where it is
  30. var cursorPos
  31. try {
  32. cursorPos = el.selectionStart
  33. } catch (e) {}
  34. // `input` event has weird updating issue with
  35. // International (e.g. Chinese) input methods,
  36. // have to use a Timeout to hack around it...
  37. setTimeout(function () {
  38. self.vm.$set(self.key, el[attr])
  39. if (cursorPos !== undefined) {
  40. el.setSelectionRange(cursorPos, cursorPos)
  41. }
  42. }, 0)
  43. }
  44. : function () {
  45. // no filters, don't let it trigger update()
  46. self.lock = true
  47. self.vm.$set(self.key, el[attr])
  48. self.lock = false
  49. }
  50. el.addEventListener(self.event, self.set)
  51. // fix shit for IE9
  52. // since it doesn't fire input on backspace / del / cut
  53. if (isIE9) {
  54. self.onCut = function () {
  55. // cut event fires before the value actually changes
  56. setTimeout(function () {
  57. self.set()
  58. }, 0)
  59. }
  60. self.onDel = function (e) {
  61. if (e.keyCode === 46 || e.keyCode === 8) {
  62. self.set()
  63. }
  64. }
  65. el.addEventListener('cut', self.onCut)
  66. el.addEventListener('keyup', self.onDel)
  67. }
  68. },
  69. update: function (value) {
  70. if (this.lock) return
  71. /* jshint eqeqeq: false */
  72. var self = this,
  73. el = self.el
  74. if (el.tagName === 'SELECT') { // select dropdown
  75. // setting <select>'s value in IE9 doesn't work
  76. var o = el.options,
  77. i = o.length,
  78. index = -1
  79. while (i--) {
  80. if (o[i].value == value) {
  81. index = i
  82. break
  83. }
  84. }
  85. o.selectedIndex = index
  86. } else if (el.type === 'radio') { // radio button
  87. el.checked = value == el.value
  88. } else if (el.type === 'checkbox') { // checkbox
  89. el.checked = !!value
  90. } else {
  91. el.value = utils.toText(value)
  92. }
  93. },
  94. unbind: function () {
  95. this.el.removeEventListener(this.event, this.set)
  96. if (isIE9) {
  97. this.el.removeEventListener('cut', this.onCut)
  98. this.el.removeEventListener('keyup', this.onDel)
  99. }
  100. }
  101. }