Broken Aurelia binding when object is null - javascript

Example based on Aurelia doc.
Page code:
export class MyPage {
products = [
{ id: 0, name: 'Motherboard' },
{ id: 1, name: 'CPU' },
{ id: 2, name: 'Memory' },
];
selectedProduct = null;
}
Page HTML:
<label>
Select product:<br/>
<select value.bind="selectedProduct">
<option model.bind="null">Choose...</option>
<option repeat.for="product of products"
model.bind="product">
${product.id} - ${product.name}
</option>
</select>
</label>
<div if.bind="selectedProduct">
Selected product 1: ${selectedProduct.id} - ${selectedProduct.name}
<div if.bind="selectedProduct.id > 0">
Selected product 2: ${selectedProduct.id} - ${selectedProduct.name}
</div>
</div>
When selecting CPU, then selecting null value, then selecting Memory, Selected product 1 is updated correctly with a value from a select element, but Selected product 2 is stuck with a CPU value.
How to bind selected value correctly inside the inner div?
In my application, I want to be able to display a content of selected item. Depending on an item type, I have a several <div if.bind="item.type === N">...</div> elements in order to display different HTML for each type of an item.
Note: binding doesn't work with newest packages, but works fine when I assign specific versions to the following packages in my package.json:
"aurelia-templating": "1.4.2"
"aurelia-templating-binding": "1.3.0"
"aurelia-templating-resources": "1.4.0"
"aurelia-templating-router": "1.1.0"

Related

searchable dropdown in react

I have below list in react.
<select
id="sponsor"
name="sponsor"
className="form-control"
placeholder="Sponsor"
}
>
<option value="" selected>Please select the sponsor</option>
{
active && result.map((sponsor:Sponsor,index:number)=>
<option value={sponsor.id} >{sponsor.name}</option>
)
}
</select>
it is working perfectly fine. now I need to change it to searchable list. I did below.
import VirtualizedSelect from 'react-virtualized-select'
import "react-virtualized-select/styles.css";
import 'react-virtualized/styles.css'
<VirtualizedSelect
id="sponsor"
name="sponsor"
className="form-control"
placeholder="Sponsor"
options={ active && result.map((sponsor:Sponsor,index:number)=>
{sponsor.name}
)}
>
</VirtualizedSelect>
now nothing is coming in list. basically my requirement is to make list searchable and insert data of API into that list.
Could you please help me with same? Any other option will also be very helpful
Edit1:-
I need list like below. first line "Please choose sponsor"
according to VirtualizedSelect docs here https://www.npmjs.com/package/react-virtualized-select, the component accept array of objects like :
const options = [
{ label: "One", value: 1 },
{ label: "Two", value: 2 },
{ label: "Three", value: 3, disabled: true }
// And so on...
]
not array of strings and I think this is way its not working, I'd suggest to change your code to :
<VirtualizedSelect
id="sponsor"
name="sponsor"
className="form-control"
placeholder="Sponsor"
options={ active && result.map((sponsor:Sponsor,index:number)=>
({label: sponsor.name, value: sponsor.name})
)}
>
</VirtualizedSelect>

Dropdown bound with listbox and item selection of the listbox bound with the button visibility React

I have requirement for the component which has a dropdown, which fills from web api, that dropdown is bound with a list box, which displays an unordered list, that unordered list displays items with editable (selectable) checkboxes, and this component has a download button.
Basically how it does is,
1. dropdown shows the directories in a folder, each directory is shown as an item in the dropdown (just as string items though​).
When a directory is selected, the dropdown change event makes a call to the api, which shows all the files within that directory. these files are just shown as names with checkboxes as unordered list within the listbox that's bound with the dropdown
Until user selected at least one checkbox or all checkboxes the download button wouldn't be visible, it should become invisible if all the items in the listbox are unselected automatically.
Once the user makes the selection and clicks on download, it calls the web api which zips all the selected files and names it as the selected text of the dropdown and lets user download the zip file at the client side.
Can anybody please suggest me for something from the below Code, how to achieve this functionality - thanks in advance.
class AccessData extends React.Component {
state = {
files: [],
communities: [],
selectedCommunity: { display: 'Select a Community...', value: '' },
communityValidationError: ""
}
componentDidMount() {
let env = clientConfiguration['Environment'];
let x = `communitiesApi.${env}`;
alert(clientConfiguration[x]);
fetch(clientConfiguration['communitiesApi.local'])
.then((response) => {
return response.json();
})
.then(data => {
let communitiesFromApi = data.map(community => { return { value: community, display: community } })
this.setState({ communities: [{ value: '', display: 'Select a Community...' }].concat(communitiesFromApi) });
})
.catch(error => {
console.log(error);
});
}
handleDDLCommunityChange = (event) => {
alert(event.target.value);
this.setState({
selectedCommunity: event.target.value
});
alert(this.state['selectedCommunity'].display);
}
render() {
return (
<main>
<div className="container">
<div className="aqview-section">
<div id="download_tool">
<form id="download_form" method="post">
<div className="row">
<div className="col-md-12">
<div className="header-box">
<h2>Data Download Tool</h2>
</div>
<select id="communityName" title="Select a Community" name="communityName" onChange={"this.handleDDLCommunityChange.bind(this")} value={"this.state.selectedCommunity"}>
{this.state.communities.map((community) => <option key={"community.value"} value={"community.value"}>{community.display}</option>)}
</select>
<div id="file_list_box">
<p>
Data Files
</p>
<ul id="file_listing">
<li>Please select a community to display available files.</li>
</ul>
</div>
<button id="download" styles="display: none;">Download</button>
</div>
</div>
</form>
</div>
</div>
</div>
</main>
);
}
}
export default connect()(AccessData);
And my dropdown is as below:
<select id="communityName" title="Select a Community" name="communityName" onChange={this.handleDDLCommunityChange.bind(this)} value={this.state.selectedCommunity}>
{this.state.communities.map((community) => <option key={community.value} value={community.value}>{community.display}</option>)}
Any help please
Here is a working sample of the code changes needed to achieve first 3 points of your requirement -
https://codesandbox.io/s/react-example-40wx5
(I have used setTimeout just to mimic api call functionality)
Regarding point 4, you can refer to this question in Stackoverflow on how to download a zip file.

How to add button and input element into drop down list

I've created a simple select menu (dropdown) using bootstrap Vue. My question is how do I insert a button and an input element inside the dropdown list. Below is an example of what I want to achieve, and my current code.
Update I am still trying to solve this issue, any help is greatly appreciated
Picture1: Button inserted at the bottom of the dropdown list
Picture2: When user clicks on the button, there will be an input field for them to enter a value. The value will automatically be inserted to the dropdown list
Current Code
<template>
<b-container class="empty-container">
<b-row align-h="center">
<b-col cols="6">
<b-form-select v-model="selected" :options="options"></b-form-select>
</b-col>
</b-row>
</b-container>
</template>
<script>
export default {
data() {
return {
selected: null,
options: [
{ value: null, text: "Please select an option" },
{ value: "a", text: "This is First option" },
{ value: "b", text: "Selected Option" },
{ value: { C: "3PO" }, text: "This is an option with object value" }
]
};
}
};
</script>
<style>
</style>
I don't know if you'll be able to use the browser's standard dropdown menu. The reason I'm thinking is that you won't be able to reliably select the html of browser specific dropdowns. So I would build my own dropdown and if the last option was clicked convert it to an <input type='text' > and grab the value from that.

Get value from each select

Blocks are created through a loop, there is a select in each block. Tell me how when clicking on a button, take the selected values from all created selects?
I tried join ref to select, and v-model, but not one of them is working properly
<div v-for="attribute in attributes" class="col">
{{ attribute.name }}
<select ref="selectedVariation" class="form-control">
<option selected>---</option>
<option v-for="variation in attribute.variations"
:key="variation.id"
:value="variation.id">
{{ variation.name }}
</option>
</select>
</div>
<button class="btn btn-success" #click="addItemToCart()">Test</button>
Hi Данил and welcome to stack overflow. There's not enough detail in the question to provide an exact solution, but the following hints might get you started. Also, there are several different approaches that could work; this is just one possibility.
First, include a property in the attributes objects that can be used to track the selected value, perhaps calling it .selected.
data: {
attributes: [
{name: "Name 1", selected: null, variations: [/*...*/]},
{name: "Name 2", selected: null, variations: [/*...*/]},
// ...
]
}
Second, tell Vue about that property using the v-model directive:
<select
class="form-control"
v-model="attribute.selected"
>
Then, when the button is clicked, the code can simply read the appropriate values:
methods: {
addItemToCart() {
// get an array of variation.id values
selectedArray = this.attributes.map(attribute => attribute.selected);
}
}

How to clear v-model used with a select when options change

I have a cascading select (two part select) where the options in the second dropdown are determined by the value of the first dropdown. I do this by having a computed property which is based off of the first select. This then feeds the options into the second select. This mostly works fine.
The problem I'm having is if I have selected an option in the second select (which through v-model sets the value of the bound variable in Vue), and then I change the value of the first select. The options for the second select then update, and in that second select I appear to be selected to the empty option. However, the bound variable still has the previously selected value. I'm assuming this is because updating the option values for the second select doesn't actually trigger an input or change event so v-model doesn't respond to anything. I suppose I could fix this with a watcher, but I was hoping for a more elegant solution.
Coded example is here: https://codepen.io/Slotheroo/pen/ajwNKO/
JS/Vue:
new Vue({
el: '#app',
data: {
selectedFruit: null,
selectedVariety: null,
fruits: {
"apples": [
{
name: "honeycrisp",
madeBy: "applebees",
},
{
name: "macintosh",
madeBy: "the steves",
},
{
name: "gala",
madeBy: "ac/dc",
},
{
name: "pink lady",
madeBy: "Alecia Beth Moore",
},
],
"pears": [
{
name: "d'anjou",
madeBy: "Maya D'Anjoulou",
},
{
name: "bartlett",
madeBy: "Anton Yelchin",
}
],
},
},
computed: {
fruitVarieties: function() {
return this.fruits[this.selectedFruit]
}
},
});
HTML:
<div id="app">
<div>
<select v-model="selectedFruit">
<option value=""></option>
<option v-for="fruitName in Object.keys(fruits)" :value ="fruitName">{{fruitName}}</option>
</select>
</div>
<select v-model="selectedVariety">
<option value=""></option>
<option v-for="fruitVariety in fruitVarieties" :value="fruitVariety">{{ fruitVariety.name }}</option>
</select>
<div>
</div>
<p>Selected variety: {{ selectedVariety }}</p>
</div>
Steps to reproduce:
Select 'apples' in the first select
Select 'honeycrisp' in the second select
Select 'pears' or 'blank' in the first select
Hoped for result
selectedVariety returns to null
Actual result
selectedVariety still equals honeycrisp
I'd add an on-change handler to the first <select> to empty the selectedVariety when the selection changes...
<select v-model="selectedFruit" #change="selectedVariety = null">
https://codepen.io/anon/pen/JByEwy
Another option would be to add a watch on selectedFruit but Vue generally recommends using event handlers.
if you're using version 3.0.0, there is some feature with :reset-on-options-change='true'
e.g
<v-select required :options="filterKaryawan.unit.options" :reset-on-options-change='true' v-model="filterKaryawan.unit.selected" placeholder="placeholder" >
<template #search="{attributes, events}">
<input
class="vs__search"
v-bind="attributes"
v-on="events"
:required="filterKaryawan.unit.selected"
/>
</template>
</v-select>
The computed propertive is actually a watcher. So just put the reset value code in it.
computed: {
fruitVarieties: function() {
this.selectedVariety = null;
return this.fruits[this.selectedFruit]
}
}

Categories