I have DevExtreme dxList:
<div data-bind="dxList: { dataSource: ds, itemTemplate: tpl }">
</div>
var vm = {
ds: [{
"key": "group1",
"items": [{ name: "item1" }, { name: "item2" }]
}],
tpl: function() {
var r = '<div data-options="dxTemplate:{ name:\'tpl\' }">';
r += '<div data-bind="dxCheckBox: { text: name }"></div>';
r += '</div>';
return r;
}
};
};
ko.applyBindings(vm);
How can I change itemTemplate run-time only for a specific item? (e.g. on mouse over)
To change list item template you could use the following sample http://jsfiddle.net/oakvprw9/8/
This is the exemplary item template:
<div data-bind="dxList: { dataSource: dataSource, onItemClick: onItemClick }">
<div data-options="dxTemplate: { name: 'item' }">
<div>
<span data-bind="text: text, visible: !editEnabled()"></span>
<div data-bind="visible: editEnabled">
<div data-bind="dxTextBox: { value: text }"></div>
<div data-bind="dxButton: { text: 'Save', onClick: $root.saveChanges }"></div>
<div data-bind="dxButton: { text: 'Cancel', onClick: $root.cancelChanges }"></div>
</div>
</div>
</div>
Related
I am trying to store some menus and submenus . But when I check a menu/submenu from checkbox, it's showing true/false. I want to get the values of the checked menu/ submenu. Here is a portion of my code(it will not work if you run it)
import { reactive, ref } from "vue";
const menuAside:[
{
to: "/dashboard",
label: "Dahsboard",
},
{
label: "User Manage",
menu: [
{
to: "/register",
label: "New User",
},
{
to: "/alluser",
label: "All User",
},
{
to: "/users/authorities",
label: "Authorities",
},
{
to: "/users/dealers",
label: "Dealers",
},
{
to: "/users/sub-dealers",
label: "Sub Dealers",
},
{
to: "/users/retailers",
label: "Retailer",
},
{
to: "/users/employees",
label: "Employees",
},
],
},
]
const fromInputs = reactive({
name: '',
selectedMenu: [],
});
fromInputs.selectedMenu = menuAside.map(menu => ({
label: menu.label,
selectedSubmenu: menu.menu
? menu.menu.map(submenu => ({ label: submenu.label }))
: [],
}));
<!-- Include the library in the page -->
<script src="https://unpkg.com/vue#2.2.0-beta.1/dist/vue.js"></script>
<!-- App -->
<div id="app">
<div>
<div v-for="menu in menuAside">
<div>
<input type="checkbox" :value="menu.label" v-model="fromInputs.selectedMenu[menuAside.indexOf(menu)].label">{{menu.label}}
</div>
<div v-if="menu.menu">
<div v-for="submenu in menu.menu">
<input type="checkbox" :value="submenu.label" v-model="fromInputs.selectedMenu[menuAside.indexOf(menu)].selectedSubmenu[menu.menu.indexOf(submenu)].label">{{submenu.label}}
</div>
</div>
</div>
</div>
</div>
In the above snippet, I can't get the "value". I want to get "products" menu if check "products". not boolean ture.
i have two tasks:
Displaying the items of the item list 3 per row
Add a input field used to edit the title field in the currently selected element (selection should be made by clicking).
So, I made the first task based on this solving V-if inside v-for - display list of items in two columns and now i have a problem with my second task selecting method. It should be working for every item but on click selects an items from every list and can to edit only from first list. I think that problem can be in onItemClick(index) method but don't know why.
Any ideas about that?
Vue.component('item-list', {
template: '#item-list-template',
data() {
return {
items: [{
title: 'item 1'
},
{
title: 'item 2'
},
{
title: 'item 3'
},
{
title: 'item 4'
},
{
title: 'item 5'
},
{
title: 'item 6'
}
],
activeIndex: -1,
rowArray: []
}
},
mounted(){
this.fakeFetchData();
},
methods: {
// new method from example solving
fakeFetchData(){
var cloned = this.items.slice();
while (cloned.length > 0) {
let chunk = cloned.splice(0,3);
this.rowArray.push(chunk);
}
},
onItemClick(index) {
this.activeIndex = this.activeIndex === index ? -1 : index;
},
setActiveItemValue(event) {
const foundItem = this.items[this.activeIndex];
if (!foundItem) return;
return this.items[this.activeIndex].title = event.currentTarget.value;
}
},
computed: {
activeItemValue() {
return this.items[this.activeIndex]?.title ?? '';
}
}
});
Vue.component('item', {
template: '#item-template',
props: {
isActive: Boolean,
title: String
}
});
new Vue({
el: '#app'
});
li.active {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<item-list></item-list>
</div>
<script type="text/x-template" id="item-list-template">
<div>
<input type="text" placeholder="Edit selected items" :value="activeItemValue" #input="setActiveItemValue" />
<div class="items-col">
<ul class="items-list" v-for="(row, rowIndex) in rowArray" :key="rowIndex">
<item v-for="(item, i) in row" :key="i" :title="item.title" :isActive="activeIndex === i" #click.native="onItemClick(i)" />
</ul>
</div>
</div>
</script>
<script type="text/x-template" id="item-template">
<li class="item" :class="{ active: isActive }">{{ title }}</li>
</script>
<style>
.items-list {
display: flex;
}
</style>
I have modified and moved the fakeFetchData() from mounted to inside computed and modified the inner v-for inside the template. Check it out
Vue.component('item-list', {
template: '#item-list-template',
data() {
return {
items: [{
title: 'item 1'
},
{
title: 'item 2'
},
{
title: 'item 3'
},
{
title: 'item 4'
},
{
title: 'item 5'
},
{
title: 'item 6'
}
],
activeIndex: -1,
rowArray: []
}
},
methods: {
// new method from example solving
onItemClick(index) {
this.activeIndex = this.activeIndex === index ? -1 : index;
},
setActiveItemValue(event) {
const foundItem = this.items[this.activeIndex];
if (!foundItem) return;
return this.items[this.activeIndex].title = event.currentTarget.value;
}
},
computed: {
activeItemValue() {
return this.items[this.activeIndex]?.title ?? '';
},
fakeFetchData(){
// ********* Changes done below ************
var cloned = this.items.map((item, index) => {
return {title: item.title, id: index}
});
this.rowArray = [];
while (cloned.length > 0) {
let chunk = cloned.splice(0,3);
this.rowArray.push(chunk);
}
return this.rowArray;
// ******* End of changes ********
},
}
});
Vue.component('item', {
template: '#item-template',
props: {
isActive: Boolean,
title: String
}
});
new Vue({
el: '#app'
});
li.active {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<item-list></item-list>
</div>
<script type="text/x-template" id="item-list-template">
<div>
<input type="text" placeholder="Edit selected items" :value="activeItemValue" #input="setActiveItemValue" />
<div class="items-col">
<ul class="items-list" v-for="(row, rowIndex) in fakeFetchData" :key="rowIndex">
<!-- Changes done --><item v-for="item in row" :key="item.id" :title="item.title" :isActive="activeIndex === item.id" #click.native="onItemClick(item.id)" />
</ul>
</div>
</div>
</script>
<script type="text/x-template" id="item-template">
<li class="item" :class="{ active: isActive }">{{ title }}</li>
</script>
<style>
.items-list {
display: flex;
}
</style>
I'm stuck with some concept while realizing checkbox system.
I've got an array of objects, it looks like this:
this.columnsGroups = [
{
id: 1,
title: 'General requests',
props: [
{
title: 'Search level',
filterType: 'entry',
visible: undefined
},
{
title: 'ID',
filterType: 'number',
visible: undefined
}
]
},
{
id: 2,
title: 'Technical Requests',
props: [
{
title: 'Search level',
filterType: 'entry',
visible: undefined
},
{
title: 'ID',
filterType: 'number',
visible: undefined
}
]
},
{
id: 3,
title: 'Popular requests',
props: [
{
title: 'Search level',
filterType: 'entry',
visible: undefined
},
{
title: 'ID',
filterType: 'number',
visible: undefined
}
]
},
{
id: 4,
title: 'Misc requests',
props: [
{
title: 'Search level',
filterType: 'entry',
visible: undefined
},
{
title: 'ID',
filterType: 'number',
visible: undefined
}
]
}
]
What I'm trying to do is to parse this array into html template with checkboxes.
The structure of the template consists of: parent checkbox
<div class="ln-select-columns-content" ng-if="currentTab.isAdvancedSearch" ng-repeat="group in ctrl.columnsGroups" ng-style="{'width':'25%'}">
<div class="ln-select-column-row">
<label>
<span class="ln-checkbox">
<input type="checkbox" ng-model="allChecked" ng-checked="allSelected" ng-click="ctrl.toggleSelectAllAttributes()"/>
<span class="ln-bg"></span>
</span>
<div class="ln-select-column-name"><b>{{group.title}}:</b></div>
</label>
<div ng-repeat="column in group.props" class="ln-select-column-row">
<label>
<span class="ln-checkbox">
<input type="checkbox" ng-model="column.visible" />
<span class="ln-bg"></span>
</span>
<span class="ln-select-column-name">{{column.title}}</span>
</label>
</div>
</div>
</div>
Literally, the template view looks like this:
view screenshot
Now, the problem is: when I'm writing a realisation for checkboxing all the child checkboxes with parent checkbox for each column, ng-model=allChecked checks all the child checkboxes from any parent checkbox in the container.
What would be the best way to do parent checkboxing, isolated from the sibling parent checkboxes?
Or maybe the array of objects is not correctly structured?
You have to modify your JSON object a little bit by adding a selected property for tracking ng-model of each checkbox. Then you can write methods in your $scope to trigger on ng-change of each checkbox and toggle checkboxes by modifying JSON object.
For complete solution please see below snippet.
angular.module('app', []).controller('HomeCtrl', function($scope) {
$scope.toggleGroup = function(group) {
if (group.selected) {
group.props.forEach(function (prop) {
prop.selected = true
})
} else {
group.props.forEach(function (prop) {
prop.selected = false
})
}
}
$scope.selectProp = function(group) {
var allSelected = true;
group.props.forEach(function (prop) {
allSelected = allSelected && prop.selected;
})
group.selected = allSelected;
}
$scope.columnsGroups = [
{
id: 1,
title: 'General requests',
selected: false,
props: [
{
title: 'Search level',
filterType: 'entry',
visible: undefined,
selected: false
},
{
title: 'ID',
filterType: 'number',
visible: undefined,
selected: false
}
]
},
{
id: 2,
title: 'Technical Requests',
selected: false,
props: [
{
title: 'Search level',
filterType: 'entry',
visible: undefined,
selected: false
},
{
title: 'ID',
filterType: 'number',
visible: undefined,
selected: false
}
]
},
{
id: 3,
title: 'Popular requests',
selected: false,
props: [
{
title: 'Search level',
filterType: 'entry',
visible: undefined,
selected: false
},
{
title: 'ID',
filterType: 'number',
visible: undefined,
selected: false
}
]
},
{
id: 4,
title: 'Misc requests',
selected: false,
props: [
{
title: 'Search level',
filterType: 'entry',
visible: undefined,
selected: false
},
{
title: 'ID',
filterType: 'number',
visible: undefined,
selected: false
}
]
}
]
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app">
<div ng-controller="HomeCtrl">
<div ng-repeat="group in columnsGroups">
<input type="checkbox" ng-model="group.selected" ng-change="toggleGroup(group)"/> {{group.title}}
<ul>
<li ng-repeat="prop in group.props">
<input ng-change="selectProp(group)" ng-model="prop.selected" type="checkbox"/> {{prop.title}}
</li>
</ul>
</div>
<pre>
{{columnsGroups | json}}
</pre>
</div>
<script src="script.js"></script>
</body>
I've create a new directive to use the jQuery Plug-In Select2 with vue.js as written down on the vue.js example page.
But I don't want to just output the value of the selected option. To store the selections I try to bind my custom method create to the #change event.
Inside the directive, the Select2 will trigger the change event for the select input field while it updates, but nevertheless it still doesn't call my custom method.
Is there some hidden magic? I've tried to read the source code of vue.js but can't find something that puts me in the right direction.
Vue.directive('select', {
twoWay: true,
priority: 1000,
params: ['options'],
bind: function() {
var self = this;
$(this.el)
.select2({
data: this.params.options
})
.on('change', function() {
self.set(this.value);
});
},
update: function(value) {
$(this.el).val(value).trigger('change');
},
unbind: function() {
$(this.el).off().select2('destroy');
}
});
var vm = new Vue({
el: '#items',
data: {
items: [],
new_item: '',
options: [{
id: 1,
text: 'First'
}, {
id: 2,
text: 'Second'
}, {
id: 3,
text: 'Third'
}, {
id: 4,
text: 'Fourth'
}, {
id: 5,
text: 'Fifth'
}]
},
methods: {
create: function() {
var self = this,
label = '';
this.options.map(function(item) {
if (self.new_item == item.id)
label = item.text;
});
var obj = {
id: self.new_item,
name: label
};
this.items.push(obj);
this.new_item = '';
}
}
});
select {
min-width: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/vue/1.0.24/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet" />
<div id="items">
<ul>
<li v-for="item in items">{{ item.id }} – {{ item.name }}</li>
</ul>
<select v-select="new_item" #change="create" :options="options">
<option value="0">--Select--</option>
</select>
</div>
Maybe you can add watcher to your new_item variable like this. So you can do something when new_item value change.
I myself still searching how to trigger #change after select2 change method, but no clue til now.
Vue.directive('select', {
twoWay: true,
priority: 1000,
params: ['options'],
bind: function() {
var self = this;
$(this.el)
.select2({
data: this.params.options
})
.on('change', function() {
self.set(this.value);
});
},
update: function(value) {
$(this.el).val(value).trigger('change');
},
unbind: function() {
$(this.el).off().select2('destroy');
}
});
var vm = new Vue({
el: '#items',
data: {
items: [],
new_item: '',
options: [{
id: 1,
text: 'First'
}, {
id: 2,
text: 'Second'
}, {
id: 3,
text: 'Third'
}, {
id: 4,
text: 'Fourth'
}, {
id: 5,
text: 'Fifth'
}]
},
methods: {
create: function() {
var self = this,
label = '';
this.options.map(function(item) {
if (self.new_item == item.id)
label = item.text;
});
var obj = {
id: self.new_item,
name: label
};
this.items.push(obj);
this.new_item = '';
}
},
watch:{
new_item:function(){
alert(this.new_item);
}
}
});
select {
min-width: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/vue/1.0.24/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet" />
<div id="items">
<ul>
<li v-for="item in items">{{ item.id }} – {{ item.name }}</li>
</ul>
<select v-select="new_item" #change="create" :options="options">
<option value="0">--Select--</option>
</select>
</div>
I am need to take acces to the model fields from the template of the item of a listview. Basically I need to replace the first name with the "valueToAccess" from viewModel. Some Body can help me here.
<div id="app"></div>
<script type="text/x-kendo-template" id="item-template">
#= name #
</script>
<script type="text/x-kendo-template" id="view-template">
<div data-role="listview"
data-bind="source: items"
data-template="item-template">
</div>
</script>
<script>
var viewModel = {
items: new kendo.data.DataSource({
data: [{ name: "item1" }, { name: "item2" }]
}),
valueToAccess: "index",
remove: function(e){
this.items.remove(e.data);
}
};
viewModel.items = new kendo.data.DataSource({
data: [{ name: "item1" }, { name: "item2" }]
});
var view = new kendo.View('view-template', { model: viewModel });
view.render("#app");
</script>
<div id="app"></div>
You can do it by using a dependent property.
<script type="text/x-kendo-template" id="item-template">
<a data-bind="attr: { href: href}, text: name"></a>
</script>
<script>
var viewModel = {
items: new kendo.data.DataSource({
data: [{ name: "item1" }, { name: "item2" }]
}),
valueToAccess: "index",
href: function(item) {
return this.get("valueToAccess") + "/" + item.name;
},
remove: function(e){
this.items.remove(e.data);
}
};
</script>
Here is a live demo: http://jsbin.com/naxiy/1/edit