x-editable + maskedinput returning underscores on enter but not on click - x-editable

x-editable + maskedinput returning underscores from maskedinput on enter but it does not when I click. Any ideas on how to fix this?
JSFiddle:
http://jsfiddle.net/xBB5x/10654/
jQuery Library's:
https://github.com/digitalBush/jquery.maskedinput
https://vitalets.github.io/x-editable/index.html
HTML:
1
JS:
$('a').editable({
type: 'text',
name: 'username',
tpl: '<input type="text" id ="zipiddemo" class="mask form-control input-sm dd" style="padding-right: 24px;">'
});
$(document).on("focus", ".mask", function () {
$(this).mask("?999");
});

JSFiddle:
http://jsfiddle.net/xBB5x/10655/
HTML:
1
JS:
$('a').editable({
type: 'text',
name: 'username',
tpl: '<input type="text" id ="zipiddemo" class="mask form-control input-sm dd" style="padding-right: 24px;">',
display: function(value, response) {
return false;
},
success: function(response, newValue) {
$(this).html(newValue.replace(/_/g, ''));
},
});
$(document).on("focus", ".mask", function() {
$(this).mask("?999");
});

Related

vuejs checkbox need to change method

I have a dropdown menu that triggers a method to get data based on what is selected in the dropdown. I would like to add a condition that changes the #change method if a checkbox is selected. The method would switch based on which checkbox is selected. I guess a v-if that runs a check somewhere--Im not sure.
new Vue({
el: "#app",
data: {
selection: 'Select a option',
todos: [{
name: 'apple'
}, {
name: 'oranges'
}, {
name: 'carrots'
}]
},
methods:{
changeP (event) {
this.getSetA();
// alert("this is set a");
},
changeP1 (event) {
this.getSetB();
alert("this is set b");
},
changeP2 (event) {
this.getSetC();
alert("this is set c");
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>Fruit:</h2>
<select v-model="selection" #change="changeP($event)">
<option value="Select a option" disabled>Choose an fruit:</option>
<option v-for="(t, i) in todos" :key="i" :value="t.name">{{ t.name }}</option>
</select>
<br>
<input type="checkbox" id="vehicle1" name="vehicle1" value="apple"> Apples
<input type="checkbox" id="vehicle2" name="vehicle2" value=""> Oranges
<input type="checkbox" id="vehicle3" name="vehicle3" value="">pears
</div>
new Vue({
el: '#app',
data: {
selection: 'Select an option',
selectOptions: [ { name: 'apple' }, { name: 'oranges' }, { name: 'carrots' }],
checkboxOptions: [ 'vehicle1', 'vehicle2', 'vehicle3' ],
checkedItems: [],
message: '',
},
methods: {
onDropdownChange() {
this.message = '';
if (this.checkedItems.length) {
this.message = `You've selected: `;
for(let i = 0; i < this.checkedItems.length; i++) {
this.message += this.checkedItems[i] + ' ';
}
}
switch(this.selection) {
case 'apple':
return this.onAppleSelected();
case 'oranges':
return this.onOrangesSelected();
default:
return this.onCarrotsSelected();
}
},
onAppleSelected() {
if (this.message.length) {
this.message += 'and apple.';
return;
}
this.message = `You've selected apple`;
},
onCarrotsSelected() {
this.message += ' CARROT!'
},
onOrangesSelected() {
this.message += ' No Scurvy';
}
},
template: `
<div id="app">
<h2>Fruit:</h2>
<select v-model="selection" #change="onDropdownChange">
<option value="Select an option">Choose</option>
<option v-for="(o, i) in selectOptions" :key="o.name" :value="o.name">{{o.name}}</option>
</select>
<div style="display:block" v-for="(o, i) in checkboxOptions" :key="o">
<label :for="o">{{o}}</label>
<input type="checkbox" :id="o" :name="o" :value="o" v-model="checkedItems" />
</div>
<p>{{message}}</p>
</div>
`
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
</div>
You should probably have a single method that decides which method to call based on the state of the component.

Vue component is not inserted when called in HTML code

I try to use Vue components, but it is not working.
I also use Pug(Jade) like preprocessor.
But in result HTML code I have raw template without transformation from Vue component to HTML code.
Here is Vue component:
Vue.component('date-input', {
props: ['id', 'format', 'value'],
mounted: function() {
$(this.$el).children().last().datepicker({
autoclose: true,
format: this.format || 'dd.mm.yyyy',
language: 'ru'
});
},
beforeDestroy: function() {
$(this.$el).children().last().datepicker('destroy');
},
methods: {
onInput: function(event) {
this.$emit('input', event.target.value);
},
onIconClick: function() {
$(this.$el).children().last().datepicker('show');
}
},
template: '<div class="date-field">' +
'<span class="icon calendar" #click="onIconClick"></span>' +
'<input id="id" class="form-control" type="text" #input="onInput" :value="value">' +
'</div>'
});
Here is PUG code:
+agreementModal('MYMODAL','MODAL NAME')
.date-range.text-nowrap
date-input.mr-3
date-input
Result HTML code:
<div class="date-range text-nowrap">
<date-input class="mr-3"></date-input>
<date-input></date-input>
</div>
Welcome to SO!
You do not seem to initialize your Vue app (with new Vue()) at some point.
Declaring Vue.component is important so that Vue knows what to do with your custom components, but you still need to tell Vue to start managing a part of your DOM by initializing it.
Vue.component('date-input', {
props: ['id', 'format', 'value'],
mounted: function() {
$(this.$el).children().last().datepicker({
autoclose: true,
format: this.format || 'dd.mm.yyyy',
language: 'ru'
});
},
beforeDestroy: function() {
$(this.$el).children().last().datepicker('destroy');
},
methods: {
onInput: function(event) {
this.$emit('input', event.target.value);
},
onIconClick: function() {
$(this.$el).children().last().datepicker('show');
}
},
template: '<div class="date-field">' +
'<span class="icon calendar" #click="onIconClick"></span>' +
'<input id="id" class="form-control" type="text" #input="onInput" :value="value">' +
'</div>'
});
new Vue({
el: '#app'
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.0/themes/smoothness/jquery-ui.css" />
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>
<script src="https://unpkg.com/vue#2"></script>
<div id="app" class="date-range text-nowrap">
<date-input class="mr-3"></date-input>
<date-input></date-input>
</div>

how to add edit button on vue-good-table in vue

I m new to Vue and stuck in a situation and don't know how to do that if anybody suggests me how I can do this let me show my code first
<div class="table-responsive-sm">
<vue-good-table
title="Shop List Table"
:columns="columns"
:rows="rows"
:paginate="true"
:lineNumbers="true"
:globalSearch="true" >
<template slot="table-row" slot-scope="props" ><a class="btn btn-sm primary" #on-row-click="onRowClick">save</a></template>
</vue-good-table>
and in script
data(){
return{
columns: [
{
label: 'Brand Name',
field: 'brand_name',
},
{
label: 'Brand Desc',
field: 'brand_desc',
},
{
label: 'Action',
field: 'before',
},
],
rows:[],
}
}
getTotals(){
var self = this;
var new1=[];
this.$http.get('/api/brands')
.then(function (response) {
self.rows=response.data
})
},
now my problem is that if I use
<span v-if="props.column.field == 'before'">
before
</span>
as suggested in this https://jsfiddle.net/aks9800/hsf0sqf8/ it throws an error like field not defined I just want to add an extra action button for edit this is vue-good table one more thing none of the action as suggested in this link for eg:- #on-row-click="onRowClick" not working
Try this
<div class="table-responsive-sm">
<vue-good-table
title="Shop List Table"
:columns="columns"
:rows="rows"
:paginate="true"
:lineNumbers="true"
:globalSearch="true" >
<template slot="table-row" slot-scope="props" >
<a class="btn btn-sm primary" #on-row-click="onRowClick">save</a>
</template>
<template slot="table-row" slot-scope="props">
<span v-if="props.column.field == 'actions'">
<a class="btn btn-sm primary" #on-row-click="onRowClick">save</a>
</span>
<span v-else>
{{props.formattedRow[props.column.field]}}
</span>
</template>
</vue-good-table>
</div>
data(){
return{
columns: [
{
label: 'Brand Name',
field: 'brand_name',
},
{
label: 'Brand Desc',
field: 'brand_desc',
},
{
label: 'Actions',
field: 'actions',
sortable: false,
}
],
rows:[],
}
}
getTotals(){
var self = this;
var new1=[];
this.$http.get('/api/brands')
.then(function (response) {
self.rows=response.data
})
},
Here is very good example how to add "edit" button in a row by marekfilip
https://jsfiddle.net/marekfilip/jm4ywzor/
html:
<div id="app">
<vue-good-table
:columns="columns"
:rows="rows" >
<template slot="table-row" slot-scope="props">
<span v-if="props.column.field == 'before'">
<button #click="editRow(props.row.id)">Edit</button>
<button #click="deleteRow(props.row.id)">Delete</button>
</span>
<span v-else>
{{props.formattedRow[props.column.field]}}
</span>
</template>
</vue-good-table>
<span>{{ text }}</span>
</div>
javascript
new Vue({
el: '#app',
data() {
return {
columns: [
{
label: 'Before',
field: 'before'
},
{
label: 'ID',
field: 'id',
sortable: true,
},
{
label: 'Text',
field: 'text',
type: 'number',
sortable: true,
},
],
rows: [
{ text: 'A', id: 1 },
{ text: 'B', id: 2 },
{ text: 'C', id: 3 },
{ text: 'D', id: 5 },
],
text: ''
};
},
methods: {
editRow(id) {
this.showAlert(id, 'EDIT')
},
deleteRow(id) {
this.showAlert(id, 'DELETE')
},
showAlert(id, type) {
this.text = `You clicked ${type} on row ID ${id}`
}
}
});

Performing action when clicking off an element

The below code allows me to have a click-to-edit header tag within my application.
I'm looking for the best way to handle exiting editing mode when any other action is performed on the page... either a click or a drag-n-drop.
<validator name="teamSetValidation">
<input id='teamSetName' v-if="isEditingName" type="text" v-model="teamSet.name" class="semi-bold p-t-10 p-b-10 m-l-15 edit-header" v-on:keyup.enter="saveTeamSetName()" v-on:keyup.esc="doneEditing()" v-validate:name.required.maxlength="teamSetRules" :isEditingName="true"/>
<h3 v-else class="semi-bold p-t-10 p-b-10 m-l-15" v-on:click="editing()" :isEditingName="false">{{ teamSet.name }} <span class="fa fa-edit"></span></h3>
<div class="text-small">
<span class="text-danger" v-if="$teamSetValidation.teamSet.name.required">A name is required.</span>
<span class="text-danger" v-if="$teamSetValidation.teamSet.name.maxlength">The name you provided is too long.</span>
</div>
<div class="b-grey b-b m-t-10"></div>
</validator>
Javascript:
var vm = new Vue({
el: '#page',
data: {
// When true, user can edit the teamSet name
isEditingName: false,
teamSet: teamSet,
teamSetRules: {
required: false,
maxlength: 64
}
},
methods: {
editTeamSetName: function () {
alert('editing');
},
saveTeamSetName: function () {
if(this.$teamSetValidation.valid) {
this.doneEditing();
var teamSet = this.teamSet,
self = this;
$.ajax({
url: '/team/'+teamSet.id,
type: 'PATCH',
data: {
'name': teamSet.name
},
error: function(res) {
Messenger().post({
message: 'Unable to save changes',
type: 'error',
hideAfter: 3
});
self.editing();
}
});
}
},
editing: function () {
this.isEditingName = true;
Vue.nextTick(function () {
$('#teamSetName').focus();
});
},
doneEditing: function () {
this.isEditingName = false;
}
}
});
Attaching a blur event to the input should do the trick:
<input id='teamSetName' v-if="isEditingName"
type="text" v-model="teamSet.name"
class="semi-bold p-t-10 p-b-10 m-l-15 edit-header"
v-on:keyup.enter="saveTeamSetName()"
v-on:keyup.esc="doneEditing()"
v-validate:name.required.maxlength="teamSetRules"
:isEditingName="true" v-on:blur="doneEditing()"
/>

Vuejs + Materializecss select field

I have this code in my template:
<div class="input-field col s6">
<select v-on:change="selectChaned" v-model="item.size">
<option value="" disabled selected>Choose your option</option>
<option v-on:click="optionClicked" v-for="size in case_sizes" v-bind:value="{{ size }}">{{ size }}</option>
</select>
<label for="size">Size</label>
</div>
According to Materializecss docs, I call $('select').material_select(); to transform default select field into something cutie. What it also does - it replaces <select> and <option> tags with <ul> and <li>.
As a result I can't access value of item.size in my ViewModel js file. I even tried to listen for a click on option field and call optionClicked method (which should simply alert a message then), tried to listen for selectChaned. Nothing.
How can I get option value in ViewModel?
p.s. just for information: I only have problem with select field. Input field for example works fine:
<input placeholder="" name="name" type="text" class="validate" v-model="item.name">
In ViewModel I'm able to access item.name
It seems that Materialize doesn't dispatch any events so I couldn't find an elegant solution. But it does seem that the following Vuejs directive + jQuery workaround is working:
Vue.directive("select", {
"twoWay": true,
"bind": function () {
$(this.el).material_select();
var self = this;
$(this.el).on('change', function() {
self.set($(self.el).val());
});
},
update: function (newValue, oldValue) {
$(this.el).val(newValue);
},
"unbind": function () {
$(this.el).material_select('destroy');
}
});
And then in your HTML – bind <select> using v-select instead of v-model.
Vue.js 2.0
Template:
<div v-text="selected"></div>
<material-select v-bind="selected = selected || options[0].value" v-model="selected">
<option v-for="option in options" :value="option.value" v-text="option.name"></option>
</material-select>
Component:
"use strict";
Vue.component("material-select", {
template: '<select><slot></slot></select>',
props: ['value'],
watch: {
value: function (value) {
this.relaod(value);
}
},
methods:{
relaod : function (value) {
var select = $(this.$el);
select.val(value || this.value);
select.material_select('destroy');
select.material_select();
}
},
mounted: function () {
var vm = this;
var select = $(this.$el);
select
.val(this.value)
.on('change', function () {
vm.$emit('input', this.value);
});
select.material_select();
},
updated: function () {
this.relaod();
},
destroyed: function () {
$(this.$el).material_select('destroy');
}
});
Vue.directive('material-select', {
bind:function(el,binding,vnode){
$(function () {
$(el).material_select();
});
var arg = binding.arg;
if(!arg)arg="change";
arg = "on"+arg;
el[arg]=function() {
if (binding.expression) {
if (binding.expression in vnode.context.$data) {
vnode.context.$data[binding.expression] = el.value;
} else if (vnode.context[binding.expression] &&
vnode.context[binding.expression].length <= 1) {
vnode.context[binding.expression](el.value);
} else {
throw new Error('Directive v-' + binding.name + " can not take more than 1 argument");
}
}
else {
throw new Error('Directive v-' + binding.name + " must take value");
}
}
},
unbind:function(el) {
$(el).material_select('destroy');
}
});
new Vue({
el: '#exemple1',
data:function(){
return {
selected: '',
options:[
{value:"v1",text:'description 1'},
{value:"v2",text:'description 2'},
{value:"v3",text:'description 3'},
{value:"v4",text:'description 4'},
{value:"v5",text:'description 5'},
]
}
}
});
new Vue({
el: '#exemple2',
data:function() {
return{
selected: null,
options:[
{value:"v1",text:'description 1'},
{value:"v2",text:'description 2'},
{value:"v3",text:'description 3'},
{value:"v4",text:'description 4'},
{value:"v5",text:'description 5'},
]
}
},
methods:{
change:function(value){
this.selected = value;
alert(value);
}
}
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/css/materialize.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/js/materialize.min.js"></script>
<h4>vue js materialize</h4>
<h5>Exemple1</h5>
<div id="exemple1">
<select v-material-select:change="selected" class="blue-text">
<option value="" disabled selected ><slot>Defaut message</slot></option>
<option v-for="option in options" :value="option.value">{{ option.text}}</option>
</select>
</div>
<h5>Exemple2</h5>
<div id="exemple2">
<select v-material-select:change="change" class="blue-text">
<option disabled selected ><slot>Choisir Votre Abonnement</slot></option>
<option v-for="option in options" :value="option.value">{{ option.text}}</option>
</select>
</div>
The top answer was nice but didn't work for Vue 2.
Here is an update of which works (probably still a little hacky). I moved the jQuery hook into update() as the bind function called too early for materialize.
Vue.directive("select", {
"twoWay": true,
update: function(el, binding, vnode) {
if(!vnode.elm.dataset.vueSelectReady) {
$(el).on('change', function() {
vnode.context.$set(vnode.context, binding.expression, el.value);
});
$(el).material_select();
vnode.elm.dataset.vueSelectReady = true
}
},
unbind: function(el, binding, vnode) {
$(el).material_select('destroy');
}
});
HTML:
<select v-select=selected>
<option value="" disabled selected>Choose your option</option>
<option :value="item" v-for='item in items'>{{ item }}</option>
<label>Materialize Select</label>
</select>
You can make the dynamic select in Vue + Materializecss work with simple hacks
$('#select').val(1).material_select(); // Set value and reinitialize materializecss select
mounted () {
$("#select").change(function(){
this.update_result.category = $("#select").val();
}.bind(this)); // To set the user selected value to the data property
update_result.
}
If you are using meterializecss beta version the function name to initialize the select will differ.
I had a similar problem. The catch here is, you need to issue $('select').material_select(); only after the DOM of your Vue app is ready. So you can add a ready method to your Vue app and include $('select').material_select(); inside your ready method.
var vm = new Vue({
data: function() {
locations: ["Clayton", "Mt Meigs", "Birmingham", "Helena", "Albertville", "Albertville", "Grant"]
},
ready: function() {
$('select').material_select();
}});
Just make sure you include Jquery first, then materialize.js followed by Vue.js in your html file.
I want to include a working fiddle of custom select2 directive which I built for my project. It also supports multiple selects:
fiddle
data: function() {
return {
names: [
{id: 1, value: 'Alice'},
{id: 1, value: 'Bob'},
{id: 1, value: 'Simona'}
],
myStudents: {
names: ['Alice', 'Bob'],
}
}
},
directives: {
'select': {
twoWay: true,
params: ['options'],
bind: function () {
var self = this
$(this.el).select2().on('change', function() {
self.set($(self.el).val())
})
},
update: function (value) {
$(this.el).val(value).trigger('change')
},
},
},
<select multiple v-select="myStudents.names" name="names" v-model="myStudents.names">
<option v-for="name in names" value="{{ name.value }}">{{ name.value }}</option>
</select>
v- VueJs2.4
None of the above answers were for multiple select element. I got it working by traversing the select element options. This is not a correct approach and kind of hack but works.
Plunker
<h4>vue js materialize select</h4>
<div class="row" id="app" style="padding-bottom:2em;">
<div class="input-field col s12 m8">
<select multiple v-material-select:change="selected">
<option value="AngularJs">AngularJs</option>
<option value="Bootstrap3">Bootstrap3</option>
<option value="Bootstrap4">Bootstrap4</option>
<option value="SCSS">SCSS</option>
<option value="Ionic">Ionic</option>
<option value="Angular2">Angular2</option>
<option value="Angular4">Angular4</option>
<option value="React">React</option>
<option value="React Native">React Native</option>
<option value="Html5">Html5</option>
<option value="CSS3">CSS3</option>
<option value="UI/UX">UI/UX</option>
</select>
<label>Technologies Used</label>
</div>
<h2>Your selected options</h2>
<p>{{$data.selected}}</p>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
<script src="https://unpkg.com/vue#2.4.4/dist/vue.js"></script>
<script> Vue.directive("material-select", {
bind: function(el, binding, vnode) {
$(function() {
$(el).material_select();
});
var arg = binding.arg;
if (!arg) arg = "change";
arg = "on" + arg;
el[arg] = function() {
vnode.context.$data.selected = [];
for (let i = 0; i < 12; i++) {
if (el[i].selected === true) {
vnode.context.$data.selected.push(el[i].value);
}
}
};
},
unbind: function(el) {
$(el).material_select("destroy");
}
});
var app = new Vue({el: "#app",data: { selected: []},
ready: function() {
$("select").material_select(); }});</script>
The possible solution that I found is to use an input, and attach it to a dropdown content. It works well with vue even when you are dynamically creating dropdown. And its reactive, that you don't have to emit any other event to bind values.
Codepen: https://codepen.io/aaha/project/editor/DGJNLE
<style>
input{
cursor: pointer;
}
.caret{
float:right;
position: relative;
cursor: pointer;
top:-50px;
}
ul{
width: 100%;
}
</style>
<script>
Vue.component('paper-dropdown', {
template: '<div> \
<div class="input-field">\
<input type="text" class="dropdown-button" v-bind:data-activates="_id"\
v-bind:value="value"> \
<label>{{label}}</label> \
</div> \
<i class="material-icons caret">arrow_drop_down</i>\
<ul v-bind:id="_id" class="dropdown-content"> \
<li v-for="item in options" v-on:click="setselected"><a v-bind:value="item">{{item}}</a></li> \
</ul>\
</div>',
watch: {
value: function(){
Materialize.updateTextFields();
}
},
computed:{
_id: function(){
if(this.id != null) return this.id;
return Math.random().toString(36).substr(2);
}
},
props: {
label:{
type: [String, Number],
default: ''
},
options:{
type: Array,
default: []
},
placeholder:{
type: String,
default: 'Choose your option'
},
value:{
type: String,
default: ''
},
id:{
type: String,
default: 'me'
}
},
methods:{
setselected: function(e){
this.$emit('input', e.target.getAttribute("value"));
}
},
mounted: function(){
$('.dropdown-button').dropdown({
inDuration: 300,
outDuration: 225,
constrainWidth: false, // Does not change width of dropdown to that of the activator
hover: false, // Activate on hover
gutter: 0, // Spacing from edge
belowOrigin: false, // Displays dropdown below the button
alignment: 'left', // Displays dropdown with edge aligned to the left of button
stopPropagation: false // Stops event propagation
}
);
}
});
</script>
I did something much more simple, only on mounted:
....
mounted() {
$(this.$el)
.find(".mdb-select")
.material_select();
const self = this;
$(this.$el).on("change", function(e) {
self.$emit('input', this.inputValue);
});
},
.....