Skip to content

Commit

Permalink
fix(pb-select): parameter serialization for multi-selection pb-select
Browse files Browse the repository at this point in the history
  • Loading branch information
wolfgangmm committed Sep 1, 2020
1 parent 1791545 commit 3e1af83
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 82 deletions.
34 changes: 23 additions & 11 deletions demo/pb-autocomplete.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,30 @@ <h1>Using pb-autocomplete</h1>
<pb-demo-snippet>
<template>
<pb-page locales="../i18n/{{ns}}/{{lng}}.json" endpoint="http://localhost:8080/exist/apps/tei-publisher">
<h2>Suggestion list passed in a property</h2>
<pb-autocomplete placeholder="type" suggestions='["alpha", "beta", "gamma"]'></pb-autocomplete>
<h2>Suggestion list supplied by remote XQuery</h2>
<pb-autocomplete placeholder="query" source="modules/autocomplete.xql"></pb-autocomplete>
<h2>Combine with other form fields whose value is passed on</h2>
<pb-autocomplete placeholder="query" source="modules/autocomplete.xql">
<select name="field">
<option value="title">Title</option>
<option value="author">Author</option>
</select>
</pb-autocomplete>
<form action="" id="form">
<h2>Suggestion list passed in a property</h2>
<pb-autocomplete name="autocomplete1" placeholder="type" suggestions='["alpha", "beta", "gamma"]'></pb-autocomplete>
<h2>Suggestion list supplied by remote XQuery</h2>
<pb-autocomplete name="autocomplete2" placeholder="query" source="modules/autocomplete.xql"></pb-autocomplete>
<h2>Combine with other form fields whose value is passed on</h2>
<pb-autocomplete name="autocomplete3" placeholder="query" source="modules/autocomplete.xql">
<select name="field">
<option value="title">Title</option>
<option value="author">Author</option>
</select>
</pb-autocomplete>
<button type="submit"><paper-button>Submit</paper-button></button>
</form>
<p>Parameters which would be sent: <code id="output"></code></p>
</pb-page>
<script>
const form = document.getElementById('form');
form.addEventListener('submit', (ev) => {
ev.preventDefault();
const data = new URLSearchParams(new FormData(form)).toString();
document.getElementById('output').innerHTML = data;
});
</script>
</template>
</pb-demo-snippet>
</body>
Expand Down
2 changes: 1 addition & 1 deletion demo/pb-autocomplete2.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ <h1>Using pb-autocomplete with remote suggestions</h1>
<pb-demo-snippet>
<template>
<pb-page locales="../i18n/{{ns}}/{{lng}}.json" endpoint="http://localhost:8080/exist/apps/tei-publisher">
<iron-form id="form" >
<iron-form id="form">
<form action="">
<p>pb-autocomplete used with a pb-repeat:</p>
<pb-repeat>
Expand Down
5 changes: 3 additions & 2 deletions demo/pb-select-i18n.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@
<script src="../node_modules/web-animations-js/web-animations-next-lite.min.js" defer></script>
<script type="module" src="../node_modules/@polymer/paper-button/paper-button.js"></script>
<script type="module" src="../node_modules/@polymer/paper-item/paper-item.js"></script>
<script type="module" src="../node_modules/@polymer/iron-form/iron-form.js"></script>
<script type="module" src="../src/pb-page.js"></script>
<script type="module" src="../src/pb-form.js"></script>
<script type="module" src="../src/pb-select.js"></script>
<script type="module" src="../src/pb-lang.js"></script>
<script type="module" src="../src/pb-i18n.js"></script>
<script type="module" src="../src/docs/pb-demo-snippet.js"></script>
<!--/scripts-->
</head>
<body>
<h1>Use pb-select with i18n</h1>
<h1>Use pb-select with i18n and iron-form</h1>

<p>This demo checks if option and selection labels are properly translated.</p>

Expand All @@ -45,6 +45,7 @@ <h1>Use pb-select with i18n</h1>
<button type="submit"><paper-button>Submit</paper-button></button>
</form>
</iron-form>

<p>Parameters which would be sent: <code id="output"></code></p>
</pb-page>

Expand Down
103 changes: 50 additions & 53 deletions demo/pb-select.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,67 +18,64 @@
<!--/scripts-->
</head>
<body>
<h1>Using pb-select</h1>

<pb-demo-snippet>
<template>
<pb-page locales="../i18n/{{ns}}/{{lng}}.json" endpoint="http://localhost:8080/exist/apps/tei-publisher">
<iron-form id="form">
<form action="">
<p>Single item selection:</p>
<pb-select label="language" name="lang1" value="es">
<paper-item value="bg">Български</paper-item>
<paper-item value="cs">český</paper-item>
<paper-item value="de">Deutsch</paper-item>
<paper-item value="en">English</paper-item>
<paper-item value="es">Español</paper-item>
<paper-item value="el">ελληνικά</paper-item>
<paper-item value="fr">Français</paper-item>
<paper-item value="it">Italiano</paper-item>
<paper-item value="ka">ქართული</paper-item>
<paper-item value="nl">Nederlands</paper-item>
<paper-item value="no">Norsk</paper-item>
<paper-item value="pl">Polski</paper-item>
<paper-item value="pt">Português</paper-item>
<paper-item value="ro">Română</paper-item>
<paper-item value="ru">русский</paper-item>
<paper-item value="sl">Slovenščina</paper-item>
<paper-item value="sv">Svenska</paper-item>
<paper-item value="tr">Türkçe</paper-item>
<paper-item value="uk">Українська</paper-item>
</pb-select>
<p>with option "multi":</p>
<pb-select label="language" name="lang2" values='["fr", "de"]' multi>
<paper-item value="bg">Български</paper-item>
<paper-item value="cs">český</paper-item>
<paper-item value="de">Deutsch</paper-item>
<paper-item value="en">English</paper-item>
<paper-item value="es">Español</paper-item>
<paper-item value="el">ελληνικά</paper-item>
<paper-item value="fr">Français</paper-item>
<paper-item value="it">Italiano</paper-item>
<paper-item value="ka">ქართული</paper-item>
<paper-item value="nl">Nederlands</paper-item>
<paper-item value="no">Norsk</paper-item>
<paper-item value="pl">Polski</paper-item>
<paper-item value="pt">Português</paper-item>
<paper-item value="ro">Română</paper-item>
<paper-item value="ru">русский</paper-item>
<paper-item value="sl">Slovenščina</paper-item>
<paper-item value="sv">Svenska</paper-item>
<paper-item value="tr">Türkçe</paper-item>
<paper-item value="uk">Українська</paper-item>
</pb-select>
<button type="submit"><paper-button>Submit</paper-button></button>
</form>
</iron-form>
<h2>Using pb-select with a standard HTML form</h2>
<form id="form" action="">
<p>Single item selection:</p>
<pb-select label="language" name="lang1" value="es">
<paper-item value="bg">Български</paper-item>
<paper-item value="cs">český</paper-item>
<paper-item value="de">Deutsch</paper-item>
<paper-item value="en">English</paper-item>
<paper-item value="es">Español</paper-item>
<paper-item value="el">ελληνικά</paper-item>
<paper-item value="fr">Français</paper-item>
<paper-item value="it">Italiano</paper-item>
<paper-item value="ka">ქართული</paper-item>
<paper-item value="nl">Nederlands</paper-item>
<paper-item value="no">Norsk</paper-item>
<paper-item value="pl">Polski</paper-item>
<paper-item value="pt">Português</paper-item>
<paper-item value="ro">Română</paper-item>
<paper-item value="ru">русский</paper-item>
<paper-item value="sl">Slovenščina</paper-item>
<paper-item value="sv">Svenska</paper-item>
<paper-item value="tr">Türkçe</paper-item>
<paper-item value="uk">Українська</paper-item>
</pb-select>
<p>with option "multi":</p>
<pb-select label="language" name="lang2" values='["fr", "de"]' multi>
<paper-item value="bg">Български</paper-item>
<paper-item value="cs">český</paper-item>
<paper-item value="de">Deutsch</paper-item>
<paper-item value="en">English</paper-item>
<paper-item value="es">Español</paper-item>
<paper-item value="el">ελληνικά</paper-item>
<paper-item value="fr">Français</paper-item>
<paper-item value="it">Italiano</paper-item>
<paper-item value="ka">ქართული</paper-item>
<paper-item value="nl">Nederlands</paper-item>
<paper-item value="no">Norsk</paper-item>
<paper-item value="pl">Polski</paper-item>
<paper-item value="pt">Português</paper-item>
<paper-item value="ro">Română</paper-item>
<paper-item value="ru">русский</paper-item>
<paper-item value="sl">Slovenščina</paper-item>
<paper-item value="sv">Svenska</paper-item>
<paper-item value="tr">Türkçe</paper-item>
<paper-item value="uk">Українська</paper-item>
</pb-select>
<button type="submit"><paper-button>Submit</paper-button></button>
</form>
<p>Parameters which would be sent: <code id="output"></code></p>
</pb-page>
<script>
const form = document.getElementById('form');
form.addEventListener('iron-form-submit', (ev) => {
form.addEventListener('submit', (ev) => {
ev.preventDefault();
const data = JSON.stringify(form.serializeForm());
const data = new URLSearchParams(new FormData(form)).toString();
document.getElementById('output').innerHTML = data;
});
</script>
Expand Down
18 changes: 18 additions & 0 deletions src/pb-autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,22 @@ export class PbAutocomplete extends pbMixin(LitElement) {
this.placeholder = 'search.placeholder';
this.suggestions = [];
this.lastSelected = null;
this._hiddenInput = null;
}

connectedCallback() {
super.connectedCallback();
}

firstUpdated() {
const inIronForm = this.closest('iron-form,pb-search,pb-custom-form');
if (!inIronForm) {
this._hiddenInput = document.createElement('input');
this._hiddenInput.type = 'hidden';
this._hiddenInput.name = this.name;
this.appendChild(this._hiddenInput);
}

const autocomplete = this.shadowRoot.getElementById('autocomplete');
autocomplete.addEventListener('autocomplete-change', this._autocomplete.bind(this));

Expand All @@ -99,6 +108,12 @@ export class PbAutocomplete extends pbMixin(LitElement) {
});
if (value) {
input.value = value.text || value;
if (this._hiddenInput) {
this._hiddenInput.value = value.value || value;
}
}
if (this._hiddenInput) {
this._hiddenInput.value = this.value;
}
}
}
Expand Down Expand Up @@ -195,6 +210,9 @@ export class PbAutocomplete extends pbMixin(LitElement) {
console.log('autocomplete selected %s', ev.detail.text);
input.value = ev.detail.text;
this.value = input.value;
if (this._hiddenInput) {
this._hiddenInput.value = this.value;
}
}


Expand Down
49 changes: 37 additions & 12 deletions src/pb-select.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,20 +71,31 @@ export class PbSelect extends pbMixin(LitElement) {
constructor() {
super();
this.value = null;
this.values = [];
this.values = null;
this._items = [];
this._selected = [];
this._inIronForm = false;
}

connectedCallback() {
super.connectedCallback();

this.subscribeTo('pb-i18n-update', this._refresh.bind(this));
// in multi-select mode, copy any value set via 'value' to 'values'
if (this.multi) {
if (!this.values && this.value) {
this.values = [this.value];
}
// delete this.value so it is not picked up by iron-form
this.value = undefined;
}
}

firstUpdated() {
super.firstUpdated();

this._inIronForm = this.closest('iron-form, pb-search,pb-custom-form');

const slot = this.shadowRoot.querySelector('[name="subform"]');
if (slot) {
slot.assignedNodes().forEach((node) => {
Expand Down Expand Up @@ -170,11 +181,21 @@ export class PbSelect extends pbMixin(LitElement) {
return html`
<slot name="subform"></slot>
<iron-label for="list" part="label">${translate(this.label)}</iron-label>
<paper-listbox id="list" slot="dropdown-content" class="dropdown-content" .selectedValues="${this.values}" ?multi="${this.multi}"
${
this.multi ?
html`<paper-listbox id="list" slot="dropdown-content" class="dropdown-content"
.selectedValues="${this.values}" multi
attr-for-selected="value" @iron-select="${this._changed}" @iron-deselect="${this._changed}">
<slot></slot>
${this._items.map((item) => html`<paper-item value="${item.value}">${item.label}</paper-item>`)}
</paper-listbox>
</paper-listbox>` :
html`<paper-listbox id="list" slot="dropdown-content" class="dropdown-content"
.selected="${this.value}"
attr-for-selected="value" @iron-select="${this._changed}" @iron-deselect="${this._changed}">
<slot></slot>
${this._items.map((item) => html`<paper-item value="${item.value}">${item.label}</paper-item>`)}
</paper-listbox>`
}
<slot name="output"></slot>
`;
}
Expand All @@ -197,18 +218,9 @@ export class PbSelect extends pbMixin(LitElement) {
if (this.multi) {
this._selected = list.selectedValues;
this.values = this._selected;

// set value anyway for the purpose of testing serialization
var svalue = '';
this._selected.forEach((val) => {
if (svalue) {svalue +=', ';}
svalue += val;
});
this.value = '[' + svalue + ']';
} else {
this._selected = [list.selected];
this.value = list.selected;
this.values = [];
}

// check if selected items really changed
Expand All @@ -217,6 +229,19 @@ export class PbSelect extends pbMixin(LitElement) {
return;
}

if (!this._inIronForm || this.multi) {
this._clear('[name="output"]');

const vals = this.multi ? this.values : [this.value];
vals.forEach((val) => {
const hidden = document.createElement('input');
hidden.type = 'hidden';
hidden.name = this.name;
hidden.value = val;
hidden.slot = 'output';
this.appendChild(hidden);
});
}
this.dispatchEvent(new CustomEvent('change'));
}

Expand Down
32 changes: 29 additions & 3 deletions test/pb-select.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { fixture, expect, waitUntil } from '@open-wc/testing';
import { fixture, expect, waitUntil, oneEvent } from '@open-wc/testing';
import '../src/pb-select.js';
import '../src/pb-page.js';
import '@polymer/paper-item';
Expand Down Expand Up @@ -68,14 +68,40 @@ describe('simple select', () => {

const form = el.querySelector('iron-form');
const select = el.querySelector('pb-select');
expect(form.serializeForm()).to.deep.equal({'key': '[1]'});
expect(form.serializeForm()).to.deep.equal({'key': "1"});
expect(select.values).to.deep.equal(['1']);

select.values = ["2", "3"];
await select.updateComplete;
expect(select.values).to.deep.equal(['2', '3']);

expect(form.serializeForm()).to.deep.equal({'key': '[2, 3]'});
expect(form.serializeForm()).to.deep.equal({'key': ["2", "3"]});
});
it('works in standard HTML form', async () => {
let initDone;
document.addEventListener('pb-page-ready', () => {
initDone = true;
});
const el = (
await fixture(`
<pb-page endpoint=".">
<form action="" id="form">
<pb-select label="Items" name="key" values='["1", "2"]' multi>
<paper-item></paper-item>
<paper-item value="0">Item 0</paper-item>
<paper-item value="1">Item 1</paper-item>
<paper-item value="2">Item 2</paper-item>
<paper-item value="3">Item 3</paper-item>
</pb-select>
</form>
</pb-page>
`)
);
await waitUntil(() => initDone);

const form = el.querySelector('form');
const data = new URLSearchParams(new FormData(form)).toString();
expect(data).to.equal('key=1&key=2');
});
});

Expand Down

0 comments on commit 3e1af83

Please sign in to comment.