aurelia - dropdown not selecting value from db on load - aurelia

I am using aurelia and have a dropdown. It passes the GroupId correctly back into my save function however it isnt selecting anything when editing a item.
return this.dataContext.getBaseContent(this.id)
.then(baseContent => this.baseContent = baseContent);
<dropdown disabled.bind="readonly" options.bind="core.GetVariableGroups()" selected.bind="baseContent.GroupId" />
HTML of dropdown
<div class="chosen-container chosen-container-single" style="width: 877px;" title="">
<a class="chosen-single chosen-default" tabindex="-1">
<span>Choose an option...</span>
<div><b></b></div>
</a>
<div class="chosen-drop">
<div class="chosen-search"><input type="text" autocomplete="off"></div>
<ul class="chosen-results">
<li class="active-result au-target" data-option-array-index="1">Option 1</li>
<li class="active-result au-target" data-option-array-index="2">Option 2</li>
<li class="active-result au-target" data-option-array-index="3">Option 3</li>
</ul>
</div>
</div>
<template>
<select disabled.bind="disabled" class="form-control" data-placeholder.bind="placeholder" value.bind="selected">
<option repeat.for="option of options" value.bind="option.Id" text.bind="option.Name"></option>
</select>
</template>
{"$type":"Admin.Contracts.Pocos.Development.ApplicationVariables.BaseContentModel, Admin.Contracts","Id":441,"GroupId":1,"GroupName":"Option 1"
Ive found the issue, unsure how to solve it. Its already bond the values before it goes off and grab the data from the db. I need it to rebind on 'complete' unsure how to do this though.

This is required: add just below the constructtor, you need to trigger a chosen:update.
selectedChanged(){
// if chosen item isnt = selected then set it
var currentSelected = $('select', this.element).find(':selected').val();
if(currentSelected != this.selected) {
if(this.options.some(o => o.Id == this.selected)){
$('select', this.element).val(this.selected);
$('select', this.element).trigger("chosen:updated");
}
else{
// new selected isnt in list of options..
// set back to prev value
this.selected = currentSelected;
}
}
}

Related

How to unshift/push image to list in vue

I have list of comments and I could append username of user, content and date to the list put when I tried to append the user image it shows null and I tried to append image from internet and also it shows null
<ul v-for="comment in comments" :key="comment">
<li class="comment-object">
<div class="image-container">
<img class="profile-pic" :src="'http://192.168.63.200:8000' + comment.author_image" v-on:change="currentUserImage" alt="profile picture"/>
</div>
<div class="comment-text">
<h2 class="username" style="color: #C2C3C4">{{comment.author}} <span class="muted">ยท {{comment.publish}}</span></h2>
<p class="comment">{{comment.content}} </p>
</div>
</li>
</ul>
await axios.post('/video/api/video/comments/create/', commentData)
.then(response => {
this.comments.unshift({ content: this.commentContent, author: this.$store.state.user.username, author_image: 'https://image.shutterstock.com/image-photo/surreal-image-african-elephant-wearing-260nw-1365289022.jpg', likes:0, publish:'now'})
})
The problem was in <img class="profile-pic" :src="'http://192.168.63.200:8000' + comment.author_image" v-on:change="currentUserImage" alt="profile picture"/>
I just removed the url http://192.168.63.200:8000 and it worked

VUE's focus() method return a console error? How to use it correctly?

I'm trying to focus on several elements of my form but the first one, despite being applied, returns an error by console.
This is my template:
<div class="container">
<div class="col-xs-12">
<div class="row">
<h1 class="animal-title">Your selection is : </h1>
</div>
<div class="wrapper">
<form class="first-form" #submit.prevent="onSubmit">
<div class="image-wrapper">
<div class="sel-image">
<div v-on:click="imageSelected = true" v-for="item in items" v-bind:key="item.id">
<label>
<input
type="radio"
name="selectedItem"
ref="item"
:value="item.id"
v-model="itemFormInfo.selectedItem"
#change="onChangeItem($event)"
/>
<img v-if="item.id === 1" src="../../assets/1.png" />
<img v-if="item.id === 2" src="../../assets/2.png" />
<img v-if="item.id === 3" src="../../assets/3.png" />
</label>
<p class="cie-animal-subtitle">{{item.name}}</p>
</div>
</div>
</div>
<div class="form-select">
<div v-show="filteredStock && (imageSelected || itemFormInfo.selectedItem) > 0">
<h1 v-if="this.itemName === 'Phone' || this.itemName === 'Tablet'" for="selectedItem" ref="itemVisible">
Select the brand of your <span>{{this.itemName}}</span> :
</h1>
<h1 v-if="this.itemName === 'PC'" for="selectedBreed" ref="itemVisible">
Select the type of your <span>{{this.itemName}}</span> :
</h1>
<select
ref="brand"
class="form-control"
id="selectedBrand"
v-model="itemFormInfo.selectedBrand"
#change="onChangeBrand($event)">
<option v-for="brand in filteredBrand" v-bind:key="brand.name">{{ brand.name }}</option>
</select>
<div v-show="this.isBrandSelected">
<h1>What are you going to use your
<span>{{itemName}}</span> for ?
</h1>
<input
type="text"
id="componentName"
ref="componentName"
class="form-control fields"
style="text-transform: capitalize"
v-model="itemFormInfo.component"
#keypress="formChange($event)"
/>
<div class="loader-spinner" v-if="loading">
<app-loader/>
</div>
</div>
</div>
</div>
<div class="service-options" v-show="isComponentCompleted">
<div class="from-group">
<h1>
Here are the options for your <span>{{this.itemFormInfo.component}}</span> :
</h1>
<div class="services">
<div class="column-service" v-for="option in options" v-bind:key="option.name">
<div class="service-name">{{option.name}}</div>
<div class="service-price">{{option.price.toString().replace(".", ",")}} </div>
</div>
</div>
and here my first method
onChangeItem(event) {
let item = event.target._value;
this.itemName = this.getItemName(item);
if (this.isItemSelected = true) {
this.isItemSelected = false;
this.isComponentCompleted = false;
this.isLoaderFinished = false;
this.itemFormInfo.name = ""
}
this.$refs.item.focus();
},
in this function that I control my first input, the focus is working but it returns me by console the following error:
"this.$refs.item.focus is not a function at VueComponent.onChangeItem"
I have seen some references to similar cases where they involved the reference in a setTimeout or used the this.$nextTick(() => method but it didn't work in my case.
What am I doing wrong?
How can I focus on the next select with ref brand, once I have chosen the value of the first input?
Thank you all for your time and help in advance
How can I focus on the next select with ref brand, once I have chosen the value of the first input?
You want to put focus on brand but your onChangeItem handler is calling this.$refs.item.focus() (trying to focus item). Seems strange to me...
Reason for the error is you are using ref inside v-for.
Docs: When used on elements/components with v-for, the registered reference will be an Array containing DOM nodes or component instances
So the correct way for accessing item ref will be this.$refs.item[index].focus().
Just be aware that right now v-for refs do not guarantee the same order as your source Array - you can find some workarounds in the issue discussion...

Vue.js - Use v-for with dynamic range value

Maybe I'm going about this the wrong way ... but I'm trying to use a v-for loop to duplicate/remove a custom component x times. x is decided by a <select> field above. What I have works on the initial page load, but then when you select a different option, only one custom component is displayed (although x is updated). Does anyone have any idea what I am doing wrong?
// here is the select field that defines the number of enrolling students
<select name="number_students_enrolling" v-model="formFields.numberStudentsEnrolling">
<option value="" default selected></option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
// here is the custom component I'm trying to duplicate/remove dynamically
<div class="students-container">
<student v-for="n in formFields.numberStudentsEnrolling" :key="n" v-bind:index="n" >
</student>
</div>
// here is the custom component
Vue.component('student', {
props: ["index"],
template: `
<div class="input--student">
<div class="input--half">
<label>
<span class="d-block">
Student {{ index }} Name <span class="field--required">*</span>
</span>
<input type="text">
</label>
</div>
<div class="input-wrap input--half">
<label>
<span class="d-block">
Student {{ index }} DOB <span class="field--required">*</span>
</span>
<input type="text">
</label>
</div>
</div>
`
})
// Here is the Vue.js instance
var test = new Vue({
el: '#test',
data: {
formFields: {
numberStudentsEnrolling: 3
}
}
});
v-for needs a Number, but you're giving it a string (the selected value). Convert it to a Number so v-for will treat it as a range from 1 to N:
<div class="students-container">
<student
v-for="n in Number(formFields.numberStudentsEnrolling)"
:key="n"
v-bind:index="n">
</student>
</div>
For completeness, another approach (per #HusamIbrahim) is to annotate the v-model reference with .number, which will automatically do the conversion.
<select
name="number_students_enrolling"
v-model.number="formFields.numberStudentsEnrolling"
>
Here's a codesandbox: https://codesandbox.io/s/xzy6or9qo

Vue.js how to use radio buttons inside v-for loop

I'm trying to use radio buttons, so that users can choose one of the photos as their profile photo:
<ul v-for="p in myPhotos">
<li>
<div>
<div>
<div>
photo id: {{p.imgId}}
</div>
<input type="radio" v-model="profileImg" value="p.imgId"> Choose as profile image
</div>
<div><img v-bind:src="BASE_URL +'/uploads/' + userId + '/'+ p.imgId" /> </div>
</div>
</li>
</ul>
The values are otained like this:
created () {
axios.get(this.BASE_URL + '/profile/g/myphotos/', this.jwt)
.then( res => {
this.myPhotos = res.data.photos;
this.showUploadedPhoto = true;
this.profileImg = res.data.profileImg
})
.catch( error => {
console.log(error);
})
},
When an photo is chosen, the profileImg variable should be set to that photo's imgId.
The problem is how to let users to choose only one photo as profile image inside this v-for loop?
Update: a photo my myPhotos object that I'm iterate over:
By providing name you can treat it as one element
var app = new Vue({
el:"#app",
data:{
images:[{imgId:1},{imgId:2},{imgId:3}],
profileImg:2
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div>
<div v-for="image in images">
<input type="radio" v-model="profileImg" name="profileImg" :value="image.imgId"> Choose as profile image
</div>
You have selected : {{profileImg}}
</div>
</div>
How about setting name attribute for the input field
<ul v-for="p in myPhotos">
<li>
<div>
<div>
<div>
photo id: {{p.imgId}}
</div>
<input type="radio" name="user_profile_photo" v-model="profileImg" :value="p.imgId"> Choose as profile image
</div>
<div><img v-bind:src="BASE_URL +'/uploads/' + userId + '/'+ p.imgId" /> </div>
</div>
</li>
</ul>

How to add Validation for multiple checkboxes in Aurelia?

So I've just got a form set up with a list checkboxes of states so that you can select multiple states, however I'm not quite sure how to put the validation on the collection of checkboxes rather than each individual one.
Right now, I have:
my-view.html
<div repeat.for="territory of availableTerritories" class="form-row">
<input type="checkbox" value.bind="territory" checked.bind="region.territories & validate">
<label>${territory}</label>
</div>
<ul if.bind="validationController.errors">
<li repeat.for="error of validationController.errors">
${error.message}
</li>
</ul>
<button class="button cancel" click.trigger="cancel()">Cancel</button>
<button class="button ok" click.trigger="saveRegion()">Save Territories</button>
my-viewmodel.js
availableTerritories = [
'US-AL',
'US-AK',
...
]
region = {
territories: []
}
constructor(validationController) {
ValidationRules
.ensure(region=>region.territories)
.required()
.minItems(1)
.on(this.region);
}
However, when I test this out with an empty input, I get a ValidationError for every checkbox rather than just the collection of them.
My ValidationError message
Territories must contain at least 1 item.
Territories must contain at least 1 item.
Territories must contain at least 1 item.
...
So I ended up adding a hidden input to the form and doing the validation on that, instead of the checkboxes themselves:
my-view.html
<div repeat.for="territory of availableTerritories" class="form-row">
<input type="checkbox" value.bind="territory" checked.bind="region.territories"> // No validation here
<label>${territory}</label>
</div>
<input type="hidden" value.bind="region.territories & validate"> //Added validation here instead
<ul if.bind="validationController.errors">
<li repeat.for="error of validationController.errors">
${error.message}
</li>
</ul>
<button class="button cancel" click.trigger="cancel()">Cancel</button>
<button class="button ok" click.trigger="saveRegion()">Save Territories</button>