I'm creating programmatically a table container with numberspinners in dojo.
Is there a way to add a unit (seconds, meters, etc.) to the spinner?
Or if that's not possible, how can I add a second row with just labels in it? So I can define the units there.
Consider creating a custom widget, which will container your "label" value, here an example.
Note:
You can change the HTML template templateString from label to div if your prefer.
Below I am using ContentPage() but you can a layout component as you which.
require(['dijit/form/NumberSpinner', 'dijit/layout/ContentPane', 'dijit/_WidgetBase', 'dijit/_TemplatedMixin', 'dojo/_base/declare', 'dojo/domReady!'], function(NumberSpinner, ContentPane, _WidgetBase, _TemplatedMixin, declare, domReady) {
var data = {
meters: '1'
},
layout = new ContentPane(),
LabelTextbox = declare([_WidgetBase, _TemplatedMixin], {
label: '',
textboxId: '',
name: '',
value: '',
templateString: '<div><label>${label}</label><div data-dojo-attach-point="textboxNode"></div></div>',
postCreate: function() {
this.inherited(arguments);
this.own(new NumberSpinner({
id: this.textboxId,
name: this.meters,
value: this.value
}, this.textboxNode));
}
});
Object.keys(data).forEach(function (prop, index) {
layout.addChild(new LabelTextbox({
textboxId: prop + '-'+ index,
name: prop,
value: data[prop],
label: 'meters: '
}));
}.bind(this));
layout.placeAt('layout');
layout.startup();
});
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<div id="layout"></div>
Related
Thanks for browsing!
I am creating a slider with vue-image-lightbox.
However, now that I have a static src listed in the sample and the image is a slider, I would like to change this src to a dynamic one and display the image accordingly.
So I wrote the code as shown below, but the img src is set to undefind and the image is not displayed.
I thought I stored /uploads/1 here, but it is undefind.
So I'm hoping you can tell me how to store /uploads/1 in src and thumb.
I would like to ask for your wisdom.
<template>
<div>
<figure class="mr-3">
<a class="img-box" #click.prevent.stop="show(0)">
<img
:src="post.main_image_url"
:alt="post.main_image_url"
>
</a>
</figure>
<ImageLightBox :media="media" ref="lightbox" :show-light-box="false" :show-caption="true"></ImageLightBox>
</div>
</template>
<script>
import ImageLightBox from 'vue-image-lightbox';
require("vue-image-lightbox/dist/vue-image-lightbox.min.css");
export default {
name: 'lightbox',
components: {
ImageLightBox,
},
data() {
return {
post: {},
post_main_image_url: '',
media: [
{
// src: "/uploads/1" will work.
thumb: this.post_main_image_url,
src: this.post_main_image_url,
title: '朝日が昇る摩周湖(北海道川上郡弟子屈町)',
},
],
}
},
methods: {
show: function(index){
this.$refs.lightbox.showImage(index)
},
// data acquisition process
getData() {
this.$loading.load(
this.$auth.api.get(
'posts/' + this.post_id, {
params: {}
}
).then(res => {
this.post = res.data.post;
let mainImageUrl = res.data.post.main_image_url;
console.log(mainImageUrl)
// =>/uploads/1
let stringMainImageUrl = String(mainImageUrl)
console.log(stringMainImageUrl)
// =>/uploads/1
this.post_main_image_url = stringMainImageUrl
console.log(String(this.post_main_image_url))
// =>/uploads/1
}).catch(err => {
this.$errorHandlers.initial(err);
})
)
}
}
created() {
this.getData();
},
}
</script>
Hey just looked at your code, here are a couple of things:
// I couldn't find `show` method, is it declared?
<a class="img-box" #click.prevent.stop="show(0)">
<!-- You are initializing 'post' as empty string and I don't see a mounted hook
for initializing this property 'main_image_url' -->
<img :src="post.main_image_url" :alt="post.main_image_url" />
data() {
return {
post: {},
post_main_image_url: '',
media: [
{
/* When the component is mounted both properties will get initialized with an empty string.
You might need to initialize properties within the "mounted" hook. */
thumb: this.post_main_image_url,
src: this.post_main_image_url,
// I don't see this method being called anywhere in the code
getData() {
this.$loading.load(
this.$auth.api
.get('posts/' + this.post_id, {
params: {}
})
I am working on a vuejs repeatable component that will allow a user to due several things---enter a question and select the answer type from the drop down. Issue is based on the type, I need to display a select number of boxes if its multiple choices so it can update an array. I cannot figure out how or where to add this. I also need to make these variable (f1 and f2 dynamic) so that it can be reused at other times. So if its a single line choose f1 if it is multiple choice select f2. Someone please provide some direction
Vue.component('my-input', {
template: '<input v-attr="name: name" v-model="value" type="text">' + '<select>' + '<option value="type1">Multiple Choice</option>' + '<option value="type2">single line</option>' + '<option value="type3">multi-line</option>' + '</select><br>'+'<br>'+'</br>',
data() {
return {
value: '',
brand: 'multiple-choice',
options: ['option a, option b'] };
},
props: ['name'] });
new Vue({
el: '#app',
data: {
message:'',
inputs: [{ type: 'my-input' }]
},
mounted: function () {
this.getAllPages();
},
methods: {
addInput() {
this.inputs.push({ type: 'my-input' });
},
getAllPages: function () {
var vm = this;
$.ajax({
url: vm.config.domainRoot + "/_api/web/lists/getbytitle('" + vm.config.listName + "')/items",
type: 'Get',
headers: {
"Accept": "application/json; odata=verbose"
},
success: function (data) {
vm.pages = data.d.results;
console.log(vm.pages);
}
})
},
createCustomL:function(){
// Get filed collection
var fldCollection = oList.get_fields();
var f1 = clientContext.castTo(
fldCollection.addFieldAsXml('<Field Type="Text" DisplayName="NewField" Name="NewField" Required="True"/>', true, SP.AddFieldOptions.addToDefaultContentType),
SP.FieldText);
f1.set_title("q1");
f1.set_description(mydescription);
f1.update();
//Get filed collection
var fldCollection = oList.get_fields();
var f2 = clientContext.castTo(
oList.get_fields().addFieldAsXml('<Field Type="Choice" DisplayName="state" Name="fldchoice" />', true, SP.AddFieldOptions.addToDefaultContentType),
SP.FieldChoice);
var choices = Array("None", "California", "Colorado", "Connecticut", "Georgia", "Indiana");
f2.set_choices(choices);
f2.update();
}
}
});
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>Vue.js repeater</title>
</head>
<body>
<!-- partial:index.partial.html -->
<div id="app">
<p>Enter your ques</p>
<component v-repeat="inputs" is="{{ type }}" name="inputs[]">
</component>
<button v-on="click: addInput">Add Question</button>
</div>
<br>
<button v-on:click="createCustom">Generate</button>
<!-- partial -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/vue/0.12.8/vue.js'></script>
<script src="./script.js"></script>
</body>
</html>
I don't know if i understand correctly but if you want to pass different data to your component dynamically you can use props.
Take a look here https://v2.vuejs.org/v2/guide/components-props.html
My Vuetify v-select element looks this way:
<v-select
v-bind:items="languages"
v-model="setLocale"
label="Language:"
auto prepend-icon="map"
item-value="fetchedLocale"
hide-details
id="langSelect"
>
In data you can find:
data () {
return {
languages: [
{ shortCode: 'en', text: 'English' },
{ shortCode: 'pl', text: 'Polski' },
{ shortCode: 'es', text: 'Español' },
{ shortCode: 'pt', text: 'Portugues' }
],
fetchedLocale: '',
setLocale: null
}
}, (...)
After some processing, fetchedLocale gets value of some of text properties from the array above, e.g. "Portugues".
Question: how to update the v-select so that it sets fetchedLocale's value, like mentioned before "Portugues", when loading DOM elements, instead of setting default empty value?
As per the documentation, the item-value prop defines the property name to use as the value for each item. The default for this prop is 'value', meaning the value property of each item will be used as each item's value by default. If you set it to text, for example, then the text property of each of your languages will be used as the value of that item. However, this won't actually set the value of the select component.
You've already bound the value of the select component to setLocale via v-model. So if you want to change the select component's value to the fetchedLocale value, just update setLocale with the value of fetchedLocale and the component will update:
this.setLocale = this.fetchedLocale
Here's a working example:
new Vue({
el: '#app',
data() {
return {
languages: [
{ shortCode: 'en', text: 'English' },
{ shortCode: 'pl', text: 'Polski' },
{ shortCode: 'es', text: 'Español' },
{ shortCode: 'pt', text: 'Portugues' }
],
fetchedLocale: '',
setLocale: null
};
},
created() {
setTimeout(() => {
this.fetchedLocale = 'English';
this.setLocale = this.fetchedLocale;
}, 1000);
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script>
<script src="https://unpkg.com/vuetify#0.15.7/dist/vuetify.js"></script>
<link href="https://unpkg.com/vuetify#0.15.7/dist/vuetify.min.css" rel="stylesheet"/>
<link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' rel="stylesheet" type="text/css">
<div id="app">
<v-app>
<v-select
:items="languages"
v-model="setLocale"
label="Language:"
auto prepend-icon="map"
item-value="text"
hide-details
id="langSelect"
></v-select>
</v-app>
</div>
<template>
<div id="app" class="phone-viewport">
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic">
<link rel="stylesheet" href="//fonts.googleapis.com/icon?family=Material+Icons">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<router-view></router-view>
<bottomBar v-bind:visibles='show' ></bottomBar>
</div>
</template>
<script>
export default {
name: '',
show: '',
data () {
return {
visibles: [
{name: 'Football', show: true},
{name: 'Basketball', show: true},
{name: 'Hockey', show: true},
{name: 'VolleyBall', show: false},
{name: 'Baseball', show: false},
]
}
}
}
</script>
I'm looking to hide the bottomBar just on VolleyBall and Beisbol .
But I always have this error "Property or method "show" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.
"
<script>
export default {
name: 'app',
data () {
return {}
},
computed: {
hideBottom: function () {
if (this.$router.path === '/baseball' || this.$router.path === '/volleyball') return false
else { return true }
}
}
}
Baseball
You are calling method show which does not exist, that's why you are getting that error.
As I understand your question, you want to hide that component on particular routes?
If so, You need to create computed variable which will determine if it should be shown or not. e.g.:
computed: {
toShowOrNotToShow: function () {
if(this.$router.path === '/baseball' || this.$router.path === '/volleyball') return false;
else
return true;
}
}
Just use it: <bottomBar v-if='toShowOrNotToShow' ></bottomBar>
I have two dojo select dropdowns. First dropdown is populated on page load and on selecting a value from first drop down, second select box should be populated.
I create the second select box programatically and i destroy it for every on change event of the first dropdown box.( this is to avoid widget already registered error).
But when i select any of the option from second drop down select, it does not fire onchange event.
Pls help on this.
My code is
require(["dojo/parser","dijit/form/RadioButton","dojo/ready","dojo/data/ItemFileReadStore","dijit/registry","dijit/form/Select","dojo/ready","dojo/dom-form", "dojo/dom", "dojo/on", "dojo/request","dojo/domReady"],
function(parser,RadioButton,ready,ItemFileReadStore,registry,Select,ready,Form,dom,on,request){
parser.parse();
var manuData;
var modelData;
var shaftType;
var modelId;
var clubMfr;
var clubType;
var manufacturerList;
dojo.connect(dijit.byId("clubtype"),"onChange",function(event){
clubType=registry.byId("clubtype").get('value');
console.log(clubType);
var id= registry.byId("clubtype");
var option1= registry.byId("manufacturer");
request("/tradeIn/"+clubType).then(function(list){
manuData=list;
var data1 = dojo.fromJson(manuData);
var readstore=new ItemFileReadStore({ data:{
identifier : "manufacturer",
label: "manufacturer",
items : data1,
}});
if(typeof registry.byId("manufacturerId") != "undefined"){
registry.byId("manufacturerId").destroyRecursive();
}
manufacturerList=new Select({
name:"manufacturerId",
id:"manufacturerId",
store:readstore,
onSetStore: function() {
this.options.unshift({selected:'true',label:'Choose One', value:'NULL'});
this._loadChildren();
}
}).placeAt("manuList");
manufacturerList.startup();
});
}
);
dojo.connect(
dijit.byId("manufacturerId"),"onChange",function(event){
var manufacturerId=registry.byId("manufacturerId").get('value');
clubMfr=manufacturerId;
var model= registry.byId("model");
model.removeOption(dijit.byId("model").getOptions());
request("/tradeIn/"+manufacturerId+"/"+clubType).then(function(list){
modelData=list;
var data1 = dojo.fromJson(modelData);
var readstore=new ItemFileReadStore({ data:{
identifier : "model",
label: "model",
items : data1
}});
if(typeof registry.byId("modelId") != "undefined"){
registry.byId("modelId").destroyRecursive();
}
var modelList=new Select({
name:"modelId",
id:"modelId",
store:readstore,
onSetStore: function() {
this.options.unshift({selected:'true',label:'Choose One', value:'NULL'});
this._loadChildren();
}
}).placeAt("modelList");
modelList.startup();
});
}
);
dojo.connect(
dijit.byId("model"),"onChange",function(event){
modelId=registry.byId("model").get('value');
console.log("model "+modelId);
}
);
});
You need to disconnect the onChange event before destroying the select and to reconnect it after creating the select. To achieve the disconnection, you can use own() method.
Here is how it should look like:
if(typeof registry.byId("manufacturerId") != "undefined"){
registry.byId("manufacturerId").destroyRecursive();
}
manufacturerList=new Select({/* ... */});
manufacturerList.own(dojo.connect(
dijit.byId("manufacturerId"),"onChange",function(event){ /* ... */ }
));
Note: This is extremely dirty. The proper approach would be to NOT destroy the second select and instead to update its data.
See the snippets for updating it:
require(['dijit/form/Select', 'dojo/data/ItemFileReadStore', 'dojo/domReady!'], function(Select, ItemFileReadStore) {
var initialStoreData = [
{value: "AL", label: "Alabama"},
{value: "AK", label: "Alaska"},
{value: "AZ", label: "Arizona"}
];
var changedStoreData = [
{value: "CA", label: "California"},
{value: "CO", label: "Colorado"},
{value: "CT", label: "Connecticut"}
];
var prepareData = function(storeData) {
//because the store return sorted data, I have added a space before the word 'Choose'. So it comes first
return [{value: '', label: ' Choose one'}].concat(storeData);
}
var readStore=new ItemFileReadStore({
data:{
identifier: "value",
label: "label",
items: prepareData(initialStoreData)
}
});
var selectWidget = new Select({
store: readStore
});
selectWidget.placeAt(document.getElementById('test'));
selectWidget.startup();
btn.onclick = function() {
var newReadStore=new ItemFileReadStore({
data:{
identifier: "value",
label: "label",
items: prepareData(changedStoreData)
}
});
selectWidget.set('store', newReadStore);
}
});
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/resources/dojo.css">
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/tundra/tundra.css">
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/form/resources/CheckedMultiSelect.css">
<div id="test" class="tundra">
<button id="btn">change data in select</button>
</div>