I am trying to use tail.select from https://github.com/pytesNET/tail.select.
On the first page load its running well like what I want.
but when I call the row.add method from datatables, each dropdown not working anymore.
Hope somebody can help me to solve this issue.
Best Regards
Thankyou.
In the question's code, I assume that $('#master-row').html() is returning a fragment of HTML - possibly the contents of a <td>.
However, the DataTable row.add() function expects a JavaScript data structure - a JS array or object.
You can provide a variable containing "master row" data using something like this:
var masterRow = [
"",
"<select class=\"select2\"><option>first</option><option>second</option><option>third</option></select>",
"<textarea rows=\"3\" cols=\"20\"></textarea>"
];
It doesn't have to be hard-coded JS like this. It could also be sourced from an ajax call. But for this demo, I will use the above approach.
You can now use this "master row", containing three column values, as follows:
Here is the full HTML page for the demo:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css">
<link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">
<!-- tail.select -->
<link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tail.select#latest/css/tail.select-default.css" />
<script src="https://cdn.jsdelivr.net/npm/tail.select#latest/js/tail.select.min.js"></script>
</head>
<body>
<div style="margin: 20px;">
<button type="button" class="btn-add">New Row!</button>
<br><br>
<table id="example" class="display dataTable cell-border" style="width:100%">
</table>
</div>
<script type="text/javascript">
var masterRow = [
"",
"<select class=\"select2\"><option>first</option><option>second</option><option>third</option></select>",
"<textarea rows=\"3\" cols=\"20\"></textarea>"
];
var dataSet = [];
dataSet.push(masterRow);
$(document).ready(function() {
var table = $('#example').DataTable( {
data: dataSet,
paging: false,
searching: false,
ordering: false,
columnDefs: [
{
targets: 0,
title: "Num",
render: function(data, type, row, meta) {
console.log(data);
return meta.row + 1;
}
},
{
targets: 1,
title: "Select Column"
},
{
targets: 2,
title: "Textarea Column"
}
]
}).on('draw', function() {
tail.select(".select2", {
search: true
});
});
table.draw();
$('.btn-add').click(function() {
table.row.add(masterRow).draw();
});
} );
</script>
</body>
</html>
Notes:
The dataSet variable takes the master row array and adds it into another outer array. This is needed so that we have a full 2-dimensional data structure for DataTables to use when it first loads the table. It is a 2D structure, but with only one (initial) row of data:
When we click on the "new row" button, it uses the masterRow variable as its source for the contents of the new row, resulting in this:
As you can see, the table has a new row, and the drop-downs are working as expected.
You can see the official documentation here for more details about the row.add() API call.
Related
im learnign VUE JS and I dont understand this behavior (strange for me).
I want to get list of people in table via Vue component.
Html tag table is under the list.
Documentation says: Every compoment must have one single root, ok I can wrap each tr with tbody but it doesnt solve this problem.
How to solve it?
<html>
<head>
<link rel="stylesheet" href="index.css">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<table>
<row
v-for="people in peoples"
v-bind:people="people"
v-bind:key="people.id">
</row>
</table>
</div>
<script>
Vue.component('c-tr', {
template: '<tr></tr>'
});
Vue.component('row', {
props: ['people'],
template: '<tr><td>{{ people.name }}</td></tr>'
});
var app = new Vue({
el: '#app',
data: {
peoples: [
{ id: 20, name: 'Roman' },
{ id: 30, name: 'Vasek' },
{ id: 40, name: 'Ondra' }
]
}
})
</script>
</body>
</html>
I am working on a site where the user can select an image via radio selection.
I would like to dynamically update the image URL depending on selection of the user. My approach is to use a computed variable which returns the URL from a list of objects depending on the selection of the user.
<template>
<v-img
:src="require(currBackgroundURL)"
class="my-3"
contain
width="397"
height="560"
></v-img>
</template>
<script>
// data() ...
currBackground: 0,
backgrounds: [
{
name: "Flowers",
url: "../assets/background/bg_1.png"
},
// ...
computed: {
currBackgroundURL: function() {
return this.backgrounds[this.currBackground].url
}
}
</script>
Unfortunately, i get an error which says Critical dependency: the request of a dependency is an expression.
And the browser console says: [Vue warn]: Error in render: "Error: Cannot find module '../assets/background/bg_1.png'"
Question: What is the right way to switch the URL of the image dynamically?
Thanks for your help!
Here is a working example:
var app = new Vue({
el: '#app',
data: () => ({
currBackground: 0,
backgrounds: [
{
name: "black",
url: "https://dummyimage.com/600x400/000/fff"
},
{
name: "blue",
url: "https://dummyimage.com/600x400/00f/fff"
},
{
name: "red",
url: "https://dummyimage.com/600x400/f00/fff"
}
]
}),
computed: {
currBackgroundURL: function() {
return this.backgrounds[this.currBackground].url
}
},
methods: {
nextImage() {
this.currBackground += 1
if (this.currBackground > 2) {
this.currBackground = 0
}
}
}
})
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.min.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.18/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.js"></script>
<div id="app">
<v-btn #click="nextImage()">Change image</v-btn>
<v-img
:src="currBackgroundURL"
class="my-3"
contain
width="397"
height="560"
></v-img>
</div>
</body>
I removed the require.
The src is a link/path so you don't need require. require will try to take a path and load it into a module instead of a link/path.
Hopefully, this helps.
I'm trying to display a simple dgrid as per the first demo on this page:
http://dgrid.io/tutorials/1.0/grids_and_stores/
The only trick is that I'm trying to put it inside an existing structure of containers. So I tried the onFocus event of the container, but when I click on that container, the grid is not showing, and no console.log message appears.
<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"CustomersGrid"'>
<script type='dojo/on' data-dojo-event='onFocus'>
require([
'dstore/RequestMemory',
'dgrid/OnDemandGrid'
], function (RequestMemory, OnDemandGrid) {
// Create an instance of OnDemandGrid referencing the store
var dom = require('dojo/dom');
console.log("onFocus event for CustomersGrid ContentPane");
dom.byId('studentLastname').value = 'test onFocus event';
var grid = new OnDemandGrid({
collection: new RequestMemory({ target: 'hof-batting.json' }),
columns: {
first: 'First Name',
last: 'Last Name',
totalG: 'Games Played'
}
}, 'grid');
grid.startup();
});
</script>
</div>
I could make it work by:
setting the id of the div to 'grid'
adding a "Click me" span (or I had nothing to focus on)
changing the event name from 'onFocus' to 'focus'
Then, the grid appears when you click on the 'Click me' text (to activate focus).
Below the corresponding full source page (for my environment):
<!DOCTYPE HTML><html lang="en">
<head>
<meta charset="utf-8">
<title>Neal Walters stask overflow test</title>
<link rel="stylesheet" href="dojo-release-1.12.2-src/dijit/themes/claro/claro.css" media="screen">
<link rel="stylesheet" href="dojo-release-1.12.2-src/dgrid/css/dgrid.css" media="screen">
</head>
<body class="claro">
<div id='grid' data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"CustomersGrid"'>
<span>click me!</span>
<script type='dojo/on' data-dojo-event='focus'>
require([
'dstore/RequestMemory',
'dgrid/OnDemandGrid'
], function (RequestMemory, OnDemandGrid) {
// Create an instance of OnDemandGrid referencing the store
var dom = require('dojo/dom');
console.log("onFocus event for CustomersGrid ContentPane");
//dom.byId('studentLastname').value = 'test onFocus event';
var grid = new OnDemandGrid({
collection: new RequestMemory({ target: 'hof-batting.json' }),
columns: {
first: 'First Name',
last: 'Last Name',
totalG: 'Games Played'
}
}, 'grid');
grid.startup();
});
</script>
</div>
<script src="dojo-release-1.12.2-src/dojo/dojo.js" data-dojo-config="async:true"></script>
<script type="text/javascript">
require(["dojo/parser", "dojo/domReady!"],
function(parser){
parser.parse();
});
</script>
</body>
The above is using declarative syntax. Alternatively, you may consider going programmatic, as in the source code below where the grid appears on loading the page. Also whereas with the declarative syntax above a breakpoint inside the script is ignored (using firefox), it is activated as expected with the programmatic syntax:
<!DOCTYPE HTML><html lang="en">
<head>
<meta charset="utf-8">
<title>Neal Walters stask overflow test</title>
<link rel="stylesheet" href="dojo-release-1.12.2-src/dijit/themes/claro/claro.css" media="screen">
<link rel="stylesheet" href="dojo-release-1.12.2-src/dgrid/css/dgrid.css" media="screen">
</head>
<body class="claro">
<div id='grid' data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"CustomersGrid"'></div>
<script src="dojo-release-1.12.2-src/dojo/dojo.js" data-dojo-config="async:true"></script>
<script>
require([
'dstore/RequestMemory',
'dgrid/OnDemandGrid'
], function (RequestMemory, OnDemandGrid) {
// Create an instance of OnDemandGrid referencing the store
var dom = require('dojo/dom');
console.log("onFocus event for CustomersGrid ContentPane");
//dom.byId('studentLastname').value = 'test onFocus event';
var grid = new OnDemandGrid({
collection: new RequestMemory({ target: 'hof-batting.json' }),
columns: {
first: 'First Name',
last: 'Last Name',
totalG: 'Games Played'
}
}, 'grid');
grid.startup();
});
</script>
</body>
I have defined dgrid and a button for removing row:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="http://cdn.rawgit.com/SitePen/dgrid/v1.1.0/css/dgrid.css" media="screen" />
</head>
<body class="claro">
<div id="container"></div>
<button id="remove">Remove</button>
<script type="text/javascript">
var dojoConfig = {
async: true,
packages: [
{ name: 'dgrid', location: '//cdn.rawgit.com/SitePen/dgrid/v1.1.0' },
{ name: 'dstore', location: '//cdn.rawgit.com/SitePen/dstore/v1.1.1' }
]
};
</script>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script type="text/javascript">
require([
'dojo/_base/declare',
'dojo/on',
"dojo/dom",
"dstore/Memory",
"dstore/Trackable",
'dstore/SimpleQuery',
'dgrid/Grid',
'dgrid/extensions/Pagination',
'dgrid/extensions/DijitRegistry',
'dojo/domReady!'
],
function(declare, on, dom, Memory, Trackable, SimpleQuery, Grid, Pagination, DijitRegistry) {
var data = [];
for (var i = 1; i <= 500; i++) {
data.push({id:i,name: 'Name '+i, value: i});
}
var Store = declare([Memory, SimpleQuery, Trackable]);
var myStore = new Store({data:data});
var MyGrid = declare([Grid, Pagination]);
var grid = new MyGrid({
collection: myStore,
columns: {
'id' : 'Id',
'name' : 'Name',
'value' : 'Value'
},
className: "dgrid-autoheight",
showLoadingMessage: false,
noDataMessage: 'No data found.'
}, 'container');
grid.startup();
on(dom.byId('remove'),'click',function() {
myStore.remove(10);
});
});
</script>
</body>
</html>
The dgrid shows up, you can sort it, edit name or value.
The problem is, that when you click on the "remove" button, row is deleted, but then, at the end of the gird is 9x written: "No data found" and the dgrid stops to work (you cant delete any other row).
If you set showLoadingMessage: to true, then everything works without a problem.
Edit: I have simplified the example. Problem persists.
The grid may have been encountering error while updating the row data after the row has been removed. As the editor tries to update the row after the button loses focus. Try using the grid.removeRow method to remove the row. It might still encounter some other issues, but worth a try.
Editor might not be the best solution to achieve what your are trying to do.
User renderCell to add button to the grid, to remove the row/record. This might be a better solution.
Update: Just refresh the grid that should solve the problem.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="http://cdn.rawgit.com/SitePen/dgrid/v1.1.0/css/dgrid.css" media="screen" />
</head>
<body class="claro">
<div id="container"></div>
<button id="remove">Remove</button>
<script type="text/javascript">
var dojoConfig = {
async: true,
packages: [
{ name: 'dgrid', location: '//cdn.rawgit.com/SitePen/dgrid/v1.1.0' },
{ name: 'dstore', location: '//cdn.rawgit.com/SitePen/dstore/v1.1.1' }
]
};
</script>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script type="text/javascript">
require([
'dojo/_base/declare',
'dojo/on',
"dojo/dom",
"dstore/Memory",
"dstore/Trackable",
'dstore/SimpleQuery',
'dgrid/Grid',
'dgrid/extensions/Pagination',
'dgrid/extensions/DijitRegistry',
'dojo/domReady!'
],
function(declare, on, dom, Memory, Trackable, SimpleQuery, Grid, Pagination, DijitRegistry) {
var data = [];
for (var i = 1; i <= 500; i++) {
data.push({id:i,name: 'Name '+i, value: i});
}
var Store = declare([Memory, SimpleQuery, Trackable]);
var myStore = new Store({data:data});
var MyGrid = declare([Grid, Pagination]);
var grid = new MyGrid({
collection: myStore,
columns: {
'id' : 'Id',
'name' : 'Name',
'value' : 'Value'
},
className: "dgrid-autoheight",
showLoadingMessage: false,
noDataMessage: 'No data found.'
}, 'container');
grid.startup();
on(dom.byId('remove'),'click',function() {
myStore.remove(10);
grid.refresh();
});
});
</script>
</body>
</html>
Hi I am having some trouble getting a menu to add options dynamically. They idea is the selection of the first menu decides what the second menu contains. I have built this before successfully without polymer. And it semi-works with polymer. dropdown one gets its content from json based on the selection, dropdown two gets its content also from a json. This part works, the issue is when you make a selection from dropdown one and then change it, dropdown two doesn't delete the old selection. I got this working last time with a function that first deletes all dropdown two's children before repopulating the content. Issue with Polymer is once the childNodes are deleted the dropdown breaks and no other children can be added via data binding. tried adding native with plain JS which populates the menu but the children are not selectable(from what I have read this might be a bug). Also I believe data binding on dynamic items also doesnt work anymore. anyway here is what I have:
<link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../../bower_components/paper-material/paper-material.html">
<link rel="import" href="../../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
<link rel="import" href="../../../bower_components/paper-menu/paper-menu.html">
<link rel="import" href="../../../bower_components/paper-item/paper-item.html">
<link rel="import" href="../../../bower_components/iron-ajax/iron-ajax.html">
<link rel="import" href="../../../bower_components/paper-button/paper-button.html">
<link rel="import" href="../../../bower_components/iron-dropdown/demo/x-select.html">
<dom-module id="add-skill">
<template>
<paper-material elevation="1">
<paper-dropdown-menu id="ddMenu" attr-for-selected="value" >
<paper-menu class="dropdown-content" id="vendorSelect" on-iron-select="_itemSelected">
<template is="dom-repeat" items="{{vendorList}}">
<paper-item id="vendorName" value="item">[[item]]</paper-item>
</template>
</paper-menu>
</paper-dropdown-menu>
<paper-dropdown-menu>
<paper-menu class="dropdown-content" id="certificationSelect" on-iron-select="_itemSelected">
</paper-menu>
</paper-dropdown-menu>
<!-- testing ideas -->
<paper-dropdown-menu>
<paper-menu class="dropdown-content" id="test" on-iron-select="_itemSelected">
<option extends="paper-item"> Option </option>
<option extends="paper-item"> Option1 </option>
<option extends="paper-item"> Option2 </option>
</paper-menu>
</paper-dropdown-menu>
<paper-button on-click="_deleteElement">
Delete
</paper-button>
</paper-material>
<iron-ajax
id="vendorSubmit"
method="POST"
url="../../../addskill.php"
handle-as="json"
on-response="handleVendorResponse"
debounce-duration="300">
</iron-ajax>
<iron-ajax
id="certificationSubmit"
method="POST"
url="../../../addskill.php"
handle-as="json"
on-response="handleCertificationResponse"
debounce-duration="300">
</iron-ajax>
</template>
<script>
Polymer({
is: 'add-skill',
ready: function() {
this.sendVendorRequest();
this.vendorList = [];
this.certificationList = [];
},
sendVendorRequest: function() {
var datalist = 'vendor=' + encodeURIComponent('1');
//console.log('datalist: '+datalist);
this.$.vendorSubmit.body = datalist;
this.$.vendorSubmit.generateRequest();
},
handleVendorResponse: function(request) {
var response = request.detail.response;
for (var i = 0; i < response.length; i++) {
this.push('vendorList', response[i].name);
}
},
vendorClick: function() {
var item = this.$;
//var itemx = this.$.vendorSelect.selectedItem.innerHTML;
//console.log(item);
//console.log(itemx);
},
sendCertificationRequest: function(vendor) {
var datalist = 'vendorName=' + encodeURIComponent(vendor);
console.log('datalist: ' + datalist);
this.$.certificationSubmit.body = datalist;
this.$.certificationSubmit.generateRequest();
},
handleCertificationResponse: function(request) {
var response = request.detail.response;
//var vendorSelect = document.getElementById('vendorSelect');
for (var i = 0; i < response.length; i++) {
this.push('certificationList', response[i].name);
}
console.log(this.certificationList);
},
_itemSelected: function(e) {
var selectedItem = e.target.selectedItem;
if (selectedItem) {
this.sendCertificationRequest(selectedItem.innerText);
console.log("selected: " + selectedItem.innerText);
}
},
_removeArray: function(arr) {
this.$.certificationList.remove();
for (var i = 0; i < arr.length; i++) {
console.log(arr[i]);
arr.splice(0, i);
arr.pop();
}
console.log(arr.length);
},
_deleteElement: function() {
var element = document.getElementById('certificationSelect');
while (element.firstChild) {
element.removeChild(element.firstChild);
}
},
_createElement: function() {
var doc = document.querySelector('#test');
var option = document.createElement('option');
option.extends = "paper-item";
option.innerHTML = "Option";
doc.appendChild(option);
}
});
</script>
</dom-module>
Any guidance is always appreciated
Here's a working version of your JSBin, which uses data binding and a <template is="dom-repeat"> to create new, selectable <paper-item> elements dynamically.
I'm not sure what specific issues you ran into when using data binding to stamp out the <paper-item> elements, but the important thing to remember in Polymer 1.0 is that when you modify an Array (or an Object) that is bound to a template, you need to use the new helper methods (like this.push('arrayName', newItem)) to ensure the bindings are updated.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<base href="http://element-party.xyz">
<script src="bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="all-elements.html">
</head>
<body>
<dom-module id="x-module">
<template>
<paper-material elevation="1">
<paper-dropdown-menu>
<paper-menu class="dropdown-content" on-iron-select="_itemSelected">
<template is="dom-repeat" items="[[_menuItems]]">
<paper-item>[[item]]</paper-item>
</template>
</paper-menu>
</paper-dropdown-menu>
<paper-button on-click="_createItem">Add</paper-button>
</paper-material>
</template>
<script>
Polymer({
_createItem: function() {
this.push('_menuItems', 'New Option ' + this._menuItems.length);
},
_itemSelected: function() {
console.log('Selected!');
},
ready: function() {
this._menuItems = ['First Initial Option', 'Second Initial Option'];
}
});
</script>
</dom-module>
<x-module></x-module>
</body>
</html>