I'm trying to convert my vaadin-grid to v2 so I can use the selectionMethods to extract the selected rows as json or csv.
in comments my working v1 vaadin grid, wich imports a json.
imports which are included in the import file:
vaadin-grid.html
vaadin-grid-selection-column.html
vaadin-grid.html
paper-elements/paper-elements.html
List item
my vaadin contains all files from:
https://github.com/vaadin/vaadin-grid
the example file I'm working with:
https://jsfiddle.net/Saulis/sse7d93h/
<!--
#license
Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<link rel="import" href="../../bower_components/polymer/polymer.html">
<dom-module id="my-afmelden-test">
<script>
var grid = document.getElementById('afmelden-grid');
grid.items = window.employees;
var data = window.employees[index];
</script>
<template>
<!-- <iron-ajax
auto
url = "../../signups.json"
handle-as="json"
last-response="{{gridData}}" ></iron-ajax> -->
<!-- <vaadin-grid id="afmelden-grid" items="{{gridData}}" visible-rows="0" selection-mode="multi">
<table>
<colgroup>
<col name="user.name.first" />
<col name="user.name.last" />
<col name="user.email" />
<col name="user.phone" />
</colgroup>
</table>
<button>derpdiederp</button>
<paper-button>derp</paper-button>
</vaadin-grid> -->
<iron-ajax url="https://randomuser.me/api?results=100&inc=name,email,picture" last-response="{{users}}" auto></iron-ajax>
<vaadin-grid id="grid" items="[[users.results]]">
<vaadin-grid-selection-column auto-select="[[autoSelect]]"></vaadin-grid-selection-column>
<vaadin-grid-column width="50px" flex-grow="0">
<template class="header">#</template>
<template>[[index]]</template>
</vaadin-grid-column>
<vaadin-grid-column width="50px" flex-grow="0">
<template class="header"></template>
<template>
<img src="[[item.picture.thumbnail]]"></img>
</template>
</vaadin-grid-column>
<vaadin-grid-column>
<template class="header">First Name</template>
<template>
<div class="capitalized">[[item.name.first]]</div>
</template>
</vaadin-grid-column>
<vaadin-grid-column>
<template class="header">Last Name</template>
<template>
<div class="capitalized">[[item.name.last]]</div>
</template>
</vaadin-grid-column>
<vaadin-grid-column>
<template class="header">Custom Selection</template>
<template>
<div style="display: flex; align-items: center">
<paper-button raised on-tap="_deselect" hidden="[[!selected]]">Deselect</paper-button>
<paper-button raised on-tap="_select" hidden="[[selected]]">Select</paper-button>
<paper-checkbox checked="{{selected}}">Selected</paper-checkbox>
</div>
</template>
</vaadin-grid-column>
</vaadin-grid>
<paper-button on-tap="myAfmelden">Afmelden</paper-button>
</template>
<iron-ajax
id="ajax_my_afmelden"
method="POST"
url="/cgi-bin/gerecht-toevoegen.py"
handle-as="json"
on-response="myAfmelden_ResponseHandler">
</iron-ajax>
</template>
<script>
var grid = document.getElementById('afmelden-grid');
grid.items = window.employees;
// Log selected designers list on select event
grid.addEventListener('selected-items-changed', function() {
console.log('Selected designers:');
gridData.selection.selected(function(index) {
var data = window.employees[index];
console.log('- ' + data[0] + ' ' + data[1]);
});
}.bind(grid));
</script>
<script>
Polymer({
is: 'my-afmelden-test',
properties: {
gridData: {
type: Array, /* array<student-info>: student-info = {id, firstName, lastName, sameGroup}
array is constant groepnr is changable */
},
},
myAfmelden: function() {
// console.log(Selected);
console.log("nu moet die komen...");
this.$.ajax_my_afmelden.contentType="application/json"
this.$.ajax_my_afmelden.body={
users: this.gridData[0]
};
this.$.ajax_my_afmelden.generateRequest();
console.log("Afmelden: " + this.gridData[0]);
// console.log('Selected: ' + this.selection.selected());
// console.log('- ' + data[0] + ' ' + data[1]);
},
myAfmelden_ResponseHandler:function(request_confirm) {
console.log("Response: " + request_confirm);
}
});
</script>
</dom-module>
Just bind to <vaadin-grid>s selected-items property and export the array to JSON, CSV as you see fit. https://jsfiddle.net/gdagvsj6/1/
Related
I'm trying to pass slot into the slot but child component which requires passed down slot doesn't see it.
In the child (TheTable) I have table component from Core UI for Vue (CDataTable) which requires certain slots which I want to pass from a parent:
<CDataTable
class="overflow-auto"
:items="this.items"
:fields="fieldData"
:sorter="{ external: true, resetable: true }"
:sorter-value="this.sorterValue"
:table-filter="{ external: true, lazy: false, placeholder: 'Enter here', label: 'Search:'}"
:responsive="false"
:loading="this.loading"
:hover="true"
:items-per-page-select="true"
:items-per-page="this.perPage"
#pagination-change="paginationChanged"
#update:sorter-value="sorterUpdated"
#update:table-filter-value="filterUpdated"
>
<slot name="requiredTableFields"></slot>
</CDataTable>
In the parent component I have:
<TheTable
v-bind:fields="fields"
v-bind:endpoint-url="endpointUrl"
>
<template slot="requiredTableFields">
<td slot="name" slot-scope="{item}">
<div>{{ item['attributes.email'] }}</div>
<div class="small text-muted">
{{ item['attributes.firstname'] }} {{ item['attributes.lastname'] }}
</div>
</td>
<td slot="registered" slot-scope="{item}">
<template v-if="item['attributes.created_at']">{{ item['attributes.created_at'] }}</template>
<template v-else>Not setup yet</template>
</td>
</template>
</TheTable>
Is there any way to make it work?
Cheers,
Casper
Merging the underlying slots into a single requiredTableFields slot isn't going to work because there's no (easy) way to break the child slots back out once they've been merged.
Instead you can just keep the slots separate:
<TheTable ...>
<template v-slot:name="{ item }">
<td>
...
</td>
</template >
<template v-slot:registered="{ item }">
<td>
...
</td>
</template>
</TheTable>
This is passing two scoped slots, name and registered, into TheTable.
Assuming you don't want to hard-code the slot names into TheTable you'd then need to iterate over the $scopedSlots to include them dynamically.
<CDataTable ...>
<template v-for="(x, slotName) in $scopedSlots" v-slot:[slotName]="context">
<slot :name="slotName" v-bind="context" />
</template>
</CDataTable>
Some notes on this:
x is not used, we just need to loop over the slot names.
The 'data' associated with the scoped slot is referred to as context and is just passed on.
If the slots weren't scoped slots it'd be slightly different. We'd iterate over $slots instead and remove all the parts that refer to context.
There is a : at the start of the :name attribute as we want to pass a dynamic name. It is an unfortunate coincidence that one of the slots in the original question is also called name, potentially leading to some confusion here.
The v-bind="context" part is analogous to the JavaScript spread operator, if that makes it any clearer. Think of it as attributes = { name: slotName, ...context }.
Below is a complete example illustrating this technique outlined above. It doesn't use CDataTable but the core principle for passing on the slots is exactly the same.
const Comp2 = {
template: `
<div>
<h4>Left</h4>
<div><slot name="top" item="Red" /></div>
<h4>Right</h4>
<div><slot name="bottom" item="Green" /></div>
</div>
`
}
const Comp1 = {
template: `
<div>
<comp2>
<template v-for="(x, slotName) in $scopedSlots" v-slot:[slotName]="context">
<slot :name="slotName" v-bind="context" />
</template>
</comp2>
</div>
`,
components: {
Comp2
}
}
new Vue({
el: '#app',
components: {
Comp1
}
})
<script src="https://unpkg.com/vue#2.6.11/dist/vue.js"></script>
<div id="app">
<comp1>
<template v-slot:top="{ item }">
<button>Slot 1 - {{ item }}</button>
</template>
<template v-slot:bottom="{ item }">
<button>Slot 2 - {{ item }}</button>
</template>
</comp1>
</div>
Per the template below, I am trying to keep words from breaking using CSS white-space tags. The problem is Polymer seems to automatically close the open tags I am using as the wrapper. Any help?
<template is="dom-repeat" items="{{getHiddenStrArr(diffObj.value)}}" as="char" >
<template is="dom-if" if="{{!index}}">
<together>[
</template>
<template is="dom-if" if="{{!isASpace(char)}}">
<span class="added-char">{{char}}</span>
</template>
<template is="dom-if" if="{{isASpace(char)}}">
]</together>
<span class="added-char"> </span>
<together>[
</template>
<template is="dom-if" if="{{isEndOfList(diffObj.value, index)}}">
]</together>
</template>
</template>
Resulting HTML:
I know the logic is correct as I used "[" and "]"to represent what the tags are doing visually. Such as:
[ - - - - ] [ - - - ] [ - - ! ]
Polymer: 1.0.3
More routing: 1.0.0
Having some issues with Polymer "more-routing". Those are -
1) Get this log on console -
[dom-bind::_annotatedComputationEffect]: compute method `urlFor` not defined
2) First level routing works (even though I get those error/warning messages). But second level routing (i mean nested routing) does not work. On "users" page pressing the name doesn't take me to "user-info" page. In fact the name does not appear as a link, it appears as a text. Here is my code -
My "routing.html"--
<link rel="import" href="../bower_components/more-routing/more-routing.html">
<more-routing-config driver="hash"></more-routing-config>
<more-route name="home" path="/"></more-route>
<more-route name="users" path="/users">
<more-route name="user-info" path="/:name"></more-route>
</more-route>
<more-route name="contact" path="/contact"></more-route>
My "index.html" ---
<more-route-selector>
<paper-menu class="list" on-iron-select="onMenuSelect">
<a route="home" href="{{urlFor('home')}}">
<iron-icon icon="home"></iron-icon>
<span>Home</span>
</a>
<a route="users" href="{{urlFor('users')}}">
<iron-icon icon="info"></iron-icon>
<span>Users</span>
</a>
<a route="contact" href="{{urlFor('contact')}}">
<iron-icon icon="mail"></iron-icon>
<span>Contact</span>
</a>
</paper-menu>
</more-route-selector>
<more-route-selector selectedParams="{{params}}">
<iron-pages>
<section route="home">
<paper-material elevation="1">
<bortini-home></bortini-home>
</paper-material>
</section>
<section route="users">
<paper-material elevation="1">
<h2 class="paper-font-display2">Users</h2>
<p>This is the users section</p>
Rob
</paper-material>
</section>
<section route="user-info">
<paper-material elevation="1">
<h2 class="paper-font-display2">
User:<span>{{params.name}}</span>
</h2>
<div>This is <span>{{params.name}}</span>'s section</div>
</paper-material>
</section>
<section route="contact">
<paper-material elevation="1">
<h2 class="paper-font-display2">Contact</h2>
<p>This is the contact section</p>
</paper-material>
</section>
</iron-pages>
</more-route-selector>
With 1.0 (perhaps earlier), Polymer stopped supporting expressions inside data-bindings (Migration Guide - Data binding). Thankfully, you can still call a function in a binding (called a "computed binding").
From what I can tell, the urlFor() method must be slightly too complex to work as a computed binding (the params object isn't a dependent property). I was able to make it work by wrapping urlFor() in a simpler function - one that works as a computed binding - something like this:
<more-routing-config driver="path"></more-routing-config>
<more-route name="users" path="/users">
<more-route name="user-info" path="/:name"></more-route>
</more-route>
<template is="dom-bind">
Rob
</template>
<script>
var template = document.querySelector('template');
template.makeUrl = function(route, name) {
return MoreRouting.urlFor(route, {name:name});
};
</script>
You can also pass variables in your computed binding, as long as they're dependent properties, like the item in a repeating template
<template is="dom-bind">
<template is="dom-repeat" items="{{users}}">
{{item.name}}
</template>
</template>
<script>
var template = document.querySelector('template');
template.makeUrl = function(route, user) {
return MoreRouting.urlFor(route, {name:user.name});
};
</script>
I have a problem with passing the category variable inside the <template> tag wrapped by the core-list.
I tried different binding approaches, but no luck. {{category}} corretcly appears outside the 2nd template tag.
<polymer-element name="library-list" attributes="category">
<template>
<style>
...
</style>
<service-library id="library" items="{{items}}"></service-library>
<core-list id="list" data="{{items}}" on-core-select="{{onClick}}">
<template>
<div class="item {{ {selected: selected} | tokenList }}" hidden?="{{category == type}}">
<div class="message">
<span class="title">{{title}}</span>
</div>
</div>
</template>
</core-list>
</template>
Maybe you want to try the injection approach.
<core-list data="{{data}}">
<template>
<div class="item {{ {selected: selected} | tokenList }}">
<span>{{foo}}-<b>{{category}}</b></span>
</div>
</template>
</core-list>
...
data.push({
foo: 999,
category:this.category,
...});
jsbin demo http://jsbin.com/mokok
I couldn't find a good solution, so I filtered the data instead that the core-list displays.
I have a json that is converted from XML and kept "#attributes" :
{"stop":"1021","route":"0057","direction":"1","departures":{"departure":[
{"#attributes":{"accurate":"1","headsign":"Rennes R"},"content":"2013-03-25T12:00:23+01:00"},
{"#attributes":{"accurate":"0","headsign":"Rennes R"},"content":"2013-03-25T12:20:00+01:00"},
{"#attributes":{"accurate":"0","headsign":"Rennes R"},"content":"2013-03-25T12:40:00+01:00"}]}},...
you can here access to the properties in javascript [1] with :
departure[0]["#attributes"].accurate
but if you want to grab it in a template with Meteor, how do you do this?
[1] JSON #attributes
I would suggest accessing the field in a function such as
Templates.your_template.attributes = function()
{
return this["#attributes"];
}
in your template
{{attributes}}
the template in the html side will look like this :
<template name="status">
<div class="line {{status}}_line">
{{stop}}
{{#each departures.departure}}
{{> attributes}}
{{/each}}
</div>
</template>
<template name="attributes">
<div class="attributes">
{{content}}
accurate : {{{access_attributes this}}}
</div>
</template>
and on the js side :
Template.attributes.access_attributes = function(context) {
return context["#attributes"].accurate
}