Select 2 Wrapped component duplicated when loading options - laravel

I've created a wrapped vue component in laravel in order to wrap jQuery select2 element.
Based in this code.
When the values in select.options change, the select element is duplicated. Like the following image.
The selection only works in the second select.
I don't know what is the problem, I add below the code I have made and the content of the options variable.
select2.vue
<template>
<div>
<select>
<slot></slot>
</select>
</div>
</template>
<script>
export default {
name: "select2",
props: ['options', 'value'],
mounted: function () {
let vm = this
$(this.$el)
// init select2
.select2({ data: this.options })
.val(this.value)
.trigger('change')
// emit event on change.
.on('change', function () {
vm.$emit('input', this.value)
})
},
watch: {
value: function (value) {
// update value
$(this.$el)
.val(value)
.trigger('change')
},
options: function (options) {
// update options
$(this.$el).empty().select2({ data: options })
}
},
destroyed: function () {
$(this.$el).off().select2('destroy')
}
}
</script>
<style scoped>
</style>
blade file call
<select2 :options="select.options" v-model="select.value"></select2>
select.options data
[
{
"text": "Group 1",
"children": [
{
"id": 1,
"text": "Element 1"
},
{
"id": 2,
"text": "Element 2"
}
]
},
{
"text": "Group 2",
"children": [
{
"id": 3,
"text": "Element 3"
},
{
"id": 4,
"text": "Element 4"
}
]
}
]

I tried for a while to reproduce the problem you were having, without any success.
I noticed a couple of things that might help you:
this.$el refers to the div in your example, where as the examples I've seen use select.
Try and avoid using the same names for properties and variables, as this makes it confusing options: function (options) {
I've included a snippet below in case it helps.
Vue.config.productionTip = false;
Vue.config.devtools = false;
Vue.component("select2", {
template: "<select style='width: 100%'></select>",
props: ['options', 'value'],
mounted: function() {
let vm = this
$(this.$el)
.select2({
data: this.options
})
.val(this.value)
.trigger('change')
.on('change', function() {
vm.$emit('input', this.value)
})
},
watch: {
value: function(value) {
$(this.$el)
.val(value)
.trigger('change')
},
options: function(val) {
$(this.$el).empty().select2({
data: val
})
}
},
destroyed: function() {
$(this.$el).off().select2('destroy')
}
});
new Vue({
el: "#app",
data: () => {
return {
selected: null,
options: [{
"text": "Group 1",
"children": [{
"id": 1,
"text": "Element 1"
},
{
"id": 2,
"text": "Element 2"
}
]
},
{
"text": "Group 2",
"children": [{
"id": 3,
"text": "Element 3"
},
{
"id": 4,
"text": "Element 4"
}
]
}
]
}
},
methods: {
modifyOptions() {
this.options = [{
"text": "Group 1",
"children": [{
"id": 4,
"text": "Element 1"
},
{
"id": 6,
"text": "Element 2"
}
]
}];
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2#4.0.13/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2#4.0.13/dist/js/select2.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div>
<select2 :options="options" v-model="selected"></select2>
<div>
Selected: {{selected}}
</div>
<button type="button" #click="modifyOptions">Modify Options</button>
</div>
</div>

Related

Display Nested data in vuetify

Hi guys new coder here... just need some help.
I want to display a nested data in vue having vuetify
here is my data:
{
"data": [
{
"id": 1,
"customer": {
"id": 88,
"name": "David Zulauf III",
"mobile": "240-545-5366 x7059"
},
"item": "rau",
"qty": "4",
"fit": {
"name": "fourth"
},
"shop": "Metz, Cole and McKenzie"
},
],
}
I am using Laravel as a back end. not sure about the proper term but I used the Laravel resource functionality to somewhat relate my table together that's why I got this nested data.
this is my vue file and I used vuetify data tables to display the above data
<script>
export default {
data () {
return {
search: '',
dialog: false,
edit:false,
items:[],
headers: [
{text: 'customer',align: 'start',sortable: false,value: 'customer',},
{ text: 'item', value: 'item' },
{ text: 'qty', value: 'qty' },
{ text: 'fit', value: 'fit' },
{ text: 'shop', value: 'shop' },
],
}
},
created(){
this.fetchItems();
},
methods: {
fetchItems(){
axios.get('api/item')
.then(res=>{
this.items = res.data.data;
});
}
}
}
</script>
<template>
<v-card>
<v-card-title>
Items
<v-spacer></v-spacer>
<v-btn depressed color="primary" #click="addNew"> ADD</v-btn>
<v-spacer></v-spacer>
<v-text-field
v-model="search"
append-icon="mdi-magnify"
label="Search"
single-line
hide-details
></v-text-field>
</v-card-title>
<v-data-table :headers="headers" :items="items" :search="search"></v-data-table>
</v-card>
</template>
thank you for the help guys.
You could provide a path to that nested properties like :
headers: [
{text: 'name',align: 'start',sortable: false,value: 'customer.name',},
{text: 'mobile',align: 'start',sortable: false,value: 'customer.mobile',},
{ text: 'item', value: 'item' },
{ text: 'qty', value: 'qty' },
{ text: 'fit name', value: 'fit.name' },
{ text: 'shop', value: 'shop' },
],
Also you can completely customise your Datatable using "item" slot and others, you can look through Vuetify documentation for getting more details.
It can be more complicated but helps when you need to get both values in same column or get different nested levels in one column.

How to implement Quill Emojis in vue2editor?

I tried to add Quill Emojis to editor but I am getting console error as
Uncaught ReferenceError: Quill is not defined
I am using Laravel 5.6 and vue js and definately new to vue and its components so I may sound silly to you but for the past 3 days I am searching on the google for the solution and even contacted author of vue2editor on github here is the link
This is what I have tried so far:
vue2editor.vue
<template>
<div id="app">
<vue-editor v-model="content"></vue-editor>
</div>
</template>
<script>
import { VueEditor, Quill } from 'vue2-editor';
import Emoji from 'quill-emoji/dist/quill-emoji';
Quill.register('modules/quill-emoji', Emoji);
export default {
name: 'vue2editor',
components: { VueEditor },
data() {
return {
content: "<h1>Some initial content</h1>",
editorSettings: {
modules: {
toolbar: {
container: [
[{'size': ['small', false, 'large']}],
['bold', 'italic', 'underline', 'strike'],
['blockquote', 'code-block'],
[{ 'header': 1 }, { 'header': 2 }],
[{ 'list': 'ordered' }, { 'list': 'bullet' }],
[{ 'script': 'sub' }, { 'script': 'super' }],
[{ 'indent': '-1' }, { 'indent': '+1' }],
[{ 'direction': 'rtl' }],
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
[{ 'color': [] }, { 'background': [] }],
[{ 'font': [] }],
[{ 'align': [] }],
['clean'],
['link', 'image', 'video'],
['emoji'],
],
handlers: {
'emoji': function () {}
},
},
toolbar_emoji: true,
short_name_emoji: true,
textarea_emoji:true,
},
},
text: null,
};
},
};
</script>
I even tried the method mentioned by one of the user on github for Quill-Emoji, here is the link.
I came here with lots of hopes; if anyone here is to help me out, at least tell me what I am missing will be more than a help for me.
Quill.register({
'formats/emoji': Emoji.EmojiBlot,
'modules/short_name_emoji': Emoji.ShortNameEmoji,
'modules/toolbar_emoji': Emoji.ToolbarEmoji,
'modules/textarea_emoji': Emoji.TextAreaEmoji}, true);
you need register the model, add the up code to you code.
Edit:
//1) Add plugin to laravel mix
const mix = require('laravel-mix')
mix.webpackConfig(webpack => {
return {
plugins: [
new webpack.ProvidePlugin({
"window.Quill": "quill/dist/quill.js",
Quill: "quill/dist/quill.js"
})
]
};
});
//2 example vue file
<template>
<div class="mt-1">
<vue-editor
ref="editor"
v-model="content"
:editor-toolbar="customToolbar"
:editorOptions="editorSettings"
/>
</div>
</template>
<script>
import { VueEditor, Quill } from "vue2-editor";
import Emoji from "quill-emoji/dist/quill-emoji";
Quill.register("modules/emoji", Emoji);
export default {
components: {
VueEditor,
},
props: {
bubble: Object,
contentCol: {
type: String,
},
},
data() {
return {
edit: false,
content: "<b>Content is here</b>",
customToolbar: [["bold", "italic", "underline"], ["link"], ["emoji"]],
editorSettings: {
modules: {
"emoji-toolbar": true,
"emoji-textarea": true,
"emoji-shortname": true,
},
},
};
},
beforeDestroy() {},
};
</script>
<style src="quill-emoji/dist/quill-emoji.css"/>

Amchart doesn't show up when listed with html <select> tag

My previous issue was to get json data attached to amcharts, after struggling for a while, I got it running the way I want. But when I move it from test page to page where it would be listed with other charts it doesn't seem to work. When I click on blank chart this error appears in the console
Uncaught TypeError: Cannot read property 'length' of undefined
at Object.xToIndex (serial.js:14)
at b.handleCursorMove (serial.js:8)
at Object.a.inherits.b.fire (amcharts.js:1)
at Object.dispatchMovedEvent (amcharts.js:27)
at Object.handleMouseDown (amcharts.js:26)
at b.handleMouseDown (serial.js:1)
at HTMLDivElement.<anonymous> (amcharts.js:18)
Below is the code which is working when I have it on separate page
var chart = AmCharts.makeChart("chart1", {
"type": "serial",
"dataLoader": {
"url": "#myURL"
},
"valueAxes": [{
"title": "Load Average",
"gridColor": "#FFFFFF",
"gridAlpha": 0.2,
"dashLength": 0
}],
"gridAboveGraphs": true,
"startDuration": 1,
"graphs": [{
"balloonText": "[[title]] of [[category]]:[[value]]",
"id": "AmGraph-1",
"lineThickness": 3,
"valueField": "LoadAverage"
}],
"chartCursor": {
"categoryBalloonEnabled": false,
"cursorAlpha": 0,
"zoomable": false
},
"categoryField": "EndTimeLoop",
"categoryAxis": {
"title": "End Time Loop",
"gridPosition": "start",
"gridAlpha": 0,
"tickPosition": "start",
"tickLength": 20,
"labelRotation": 90
}
});
function setDataSet(dataset_url) {
AmCharts.loadFile(dataset_url, {}, function(data) {
chart.dataProvider = AmCharts.parseJSON(data);
chart.validateData();
});
};
this is the part where select happens in html side
<div class="chartWrapper" id="chartSingleTest1">
<select onchange="showChart(this.options[this.selectedIndex].value);">
<option value="chart1">Chart #1</option>
<option value="chart2">Chart #2</option>
<option value="chart3">Chart #3</option>
</select>
<div id="chart1" class="chartBoxSingle" style="display: none;"></div>
<div id="chart2" class="chartBoxSingle" style="display: none;"></div>
<div id="chart3" class="chartBoxSingle" style="display: none;"></div>
</div>
and here is js part where selects the first option on page load
var currentChart;
function showChart( divid ) {
if (currentChart !== undefined)
currentChart.style.display = "none";
if ( divid ) {
currentChart = document.getElementById(divid);
currentChart.style.display = "block";
}
else {
currentChart = undefined;
}
}
$(document).ready(function() { showChart('chart1'); });
You have to call the chart object's validateSize method when toggling the display of a chart from none to block as shown in this example that uses tabs. Here's another example using your structure:
var charts = {};
charts["chart1"] = AmCharts.makeChart("chart1", {
type: "serial",
dataProvider: [{
"value": 1,
"category": "Category 1"
}, {
"value": 2,
"category": "Category 2"
}, {
"value": 3,
"category": "Category 3"
}],
categoryField: "category",
graphs: [{
valueField: "value",
type: "column",
fillAlphas: .8
}]
});
charts["chart2"] = AmCharts.makeChart("chart2", {
type: "pie",
dataProvider: [{
"value": 2,
"title": "Slice 1"
}, {
"value": 2,
"title": "Slice 2"
}, {
"value": 2,
"category": "Slice 3"
}],
titleField: "title",
valueField: "value"
});
var currentChart;
function showChart(divid) {
if (currentChart !== undefined)
currentChart.style.display = "none";
if (divid) {
currentChart = document.getElementById(divid);
currentChart.style.display = "block";
charts[divid].validateSize();
} else {
currentChart = undefined;
}
}
$(document).ready(function() {
showChart('chart1');
});
.chartBoxSingle {
width: 100%;
height: 400px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="//www.amcharts.com/lib/3/amcharts.js"></script>
<script type="text/javascript" src="//www.amcharts.com/lib/3/serial.js"></script>
<script type="text/javascript" src="//www.amcharts.com/lib/3/pie.js"></script>
<div class="chartWrapper" id="chartSingleTest1">
<select onchange="showChart(this.options[this.selectedIndex].value);">
<option value="chart1">Chart #1</option>
<option value="chart2">Chart #2</option>
</select>
<div id="chart1" class="chartBoxSingle" style="display: none;"></div>
<div id="chart2" class="chartBoxSingle" style="display: none;"></div>
</div>

Kendo Treeview checked Get parent node on checking child nodes

enter image description hereIĀ“m trying to use a treeview with checkboxes for definition User Rights. (2 actions - enabled/disabled right)
How can I to get value (id) from parent node ?
Kendo tree view
This example will return the parent id for the selected node.
treeView.select().parentNode().id;
If you need to find the parent for a specific node, you must specify a selector in the select() function: treeView.select($("search criteria"))
If you want to loop in the parent, you can do this
var parentNode = treeView.select().parentNode();
while (parentNode) {
//Add your parent logic here
//...
parentNode = parent.parentNode();
}
Please try with the below code snippet.
<!DOCTYPE html>
<html>
<head>
<title>Jayesh Goyani</title>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.1111/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.1111/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.1111/styles/kendo.default.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.1111/styles/kendo.mobile.all.min.css">
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2015.3.1111/js/angular.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2015.3.1111/js/jszip.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2015.3.1111/js/kendo.all.min.js"></script>
</head>
<body>
<div id="treeview"></div>
<p id="result">No nodes checked.</p>
<script>
$(document).ready(function () {
$("#treeview").kendoTreeView({
checkboxes: {
checkChildren: true
},
check: onCheck,
dataSource: [{
id: 1, text: "1", expanded: true, items: [
{
id: 2, text: "2", expanded: true, items: [
{ id: 3, text: "3" },
{ id: 4, text: "4" },
{ id: 5, text: "5" }
]
},
{
id: 6, text: "6", expanded: true, items: [
{ id: 7, text: "7" },
{ id: 8, text: "8" },
]
},
{
id: 9, text: "9", expanded: true, items: [
{ id: 10, text: "10" },
{ id: 11, text: "11" },
{ id: 12, text: "12", expanded: true, items: [{ id: 13, text: "13", expanded: true, items: [{ id: 14, text: "14" }, { id: 15, text: "15" }] }] }
]
}
]
}]
});
});
// function that gathers IDs of checked nodes
function checkedNodeIds(nodes, checkedNodes) {
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].checked) {
getParentIds(nodes[i], checkedNodes);
checkedNodes.push(nodes[i].id);
}
if (nodes[i].hasChildren) {
checkedNodeIds(nodes[i].children.view(), checkedNodes);
}
}
}
function getParentIds(node, checkedNodes) {
if (node.parent() && node.parent().parent() && checkedNodes.indexOf(node.parent().parent().id) == -1) {
getParentIds(node.parent().parent(), checkedNodes);
checkedNodes.push(node.parent().parent().id);
}
}
// show checked node IDs on datasource change
function onCheck() {
var checkedNodes = [],
treeView = $("#treeview").data("kendoTreeView"),
message;
checkedNodeIds(treeView.dataSource.view(), checkedNodes);
if (checkedNodes.length > 0) {
message = "IDs of checked nodes: " + checkedNodes.join(",");
} else {
message = "No nodes checked.";
}
$("#result").html(message);
}
</script>
</body>
</html>
Let me know if any concern.

How do I pass parameters to javascript in a kendo grid column template?

I have a kendo grid with a column template. I try to pass a value from the current row as a parameter for my javascript function. My code:
{
field: "CrmTaskId",
title: "Crm ",
template: '<a href="javascript:hrefTest(#=CrmTaskId#);" ># if( CrmTaskId==null) {#<span><span># } else {#<span>#: CrmTaskId#<span>#} #</a>'
}
hrefTest is javascript function with one param. But it's not working. Any ideas?
It can be done like this
.ClientTemplate("<a href='javascript: void(0);'
onclick=\"return YourJSFunction('#= OpportunityUrl #');\">#= OpportunityName #</a>")
This is part of the column definition, so what it is saying is...Make the OpportunityName
clickable and pass in the OpportunityUrl. #= Field # is the syntax for pulling values off of the Model.
I have tried with your code but not able to reproduce this issue. Please create new HTML/CSHTML page and check it.
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<link href="http://cdn.kendostatic.com/2014.1.318/styles/kendo.common.min.css" rel="stylesheet" />
<link href="http://cdn.kendostatic.com/2014.1.318/styles/kendo.default.min.css" rel="stylesheet" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://cdn.kendostatic.com/2014.1.318/js/kendo.all.min.js"></script>
</head>
<body>
<div id="grid"></div>
<script>
var movies = [
{ "CrmTaskId": 1, "rating": 9.2, "year": 1994, "title": "The Shawshank Redemption"},
{ "CrmTaskId": 2, "rating": 9.2, "year": 1972, "title": "The Godfather"},
{ "CrmTaskId": null, "rating": 9, "year": 1974, "title": "The Godfather: Part II" },
{ "CrmTaskId": '', "rating": 9.9, "year": 1874, "title": "The Godmother: Part III" }
];
function hrefTest(CrmTaskId)
{
alert("CrmTaskId is: " + CrmTaskId);
}
$(document).ready(function () {
$("#grid").kendoGrid({
dataSource: {
data: movies,
pageSize: 10
},
groupable: true,
sortable: true,
pageable: {
refresh: true,
pageSizes: true
},
columns: [{
field: "CrmTaskId",
title: "Crm"
}, {
field: "title",
title: "title"
},
{
template: '<a href="javascript:hrefTest(#=CrmTaskId#);" ># if( CrmTaskId==null) {#<span><span># } else {#<span>#: CrmTaskId#<span>#} #</a>'
}
]
});
});
</script>
</body>
</html>
Please try with the below code snippet.
Use this :
{
field: "Field",
editable: true,
title: "Title",
template: showRelatedLink,
allownull: true,
width: 100
}
and then in your function :
function showRelatedLink(container, options)
{
var yourVariable = container.YourField;
}
You can pass a field to a function like this too:
Grid:
columns: [
{ field: "ProductTypeID", title: "Type", template: "#=product_type_to_name(ProductTypeID)#" },
]
Function:
function product_type_to_name(product_type_id) {
console.log(product_type_id);
var name = "";
// convert ID to name
return name;
}
I have tried this
{
field: "DisplayChangedFrom",
title: "From",
template:"#=generateTemplate(DisplayChangedFrom)#
},
Then the function
function generateTemplate(items) {
var html = "<ul>";
if (items !== null && items.length > 0) {
for (var x = 0; x < items.length; x++) {
html += "<li>";
html += items[x];
html += "</li>";
}
}
html += "</ul>";
return html;
};

Resources