ReOrder List in NativeScript Vue - nativescript-vue

I'm pretty new to nativescript-vue, but I got an app to display a nice list as fetched from an api.
Now I'd like to be able to have the user reorder it.
The documentation seems aged, so I'll just post this example of a list that at least displays, though cannot be reordered:
<template>
<Page class="page">
<ActionBar title="ListView with Avatars/Thumbnails" class="action-bar" />
<ScrollView>
<ListView for="item in items" class="list-group" #itemTap="onItemTap">
<v-template>
<GridLayout class="list-group-item" rows="*" columns="auto, *">
<Image row="0" col="0" :src="item.src" class="thumb img-circle" />
<Label row="0" col="1" :text="item.text" />
</GridLayout>
</v-template>
</ListView>
</ScrollView>
</Page>
<script>
export default {
data() {
return {
items: [
{ text: "Bulbasaur", src: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/1.png" },
{ text: "Charmander", src: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/4.png" },
{ text: "Charizard", src: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/6.png" },
{ text: "Squirtle", src: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/7.png" },
{ text: "Wartortle", src: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/8.png" },
{ text: "Blastoise", src: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/9.png" },
{ text: "Caterpie", src: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/10.png" },
{ text: "Weedle", src: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/13.png" },
]
}
},
methods: {
onItemTap: function(event) {
console.log("You tapped: " + this.$data.items[event.index].text);
}
},
};
</script>
The docs suggest that it should be easy: Item Reorder. But I'm not getting the pieces to fit together. So maybe we can get some concise code here?

Firstly, you need to use the <RadListView> component instead of the <ListView>. Then, all you need is to add the attribute itemReorder="true". Like so:
<RadListView for="item in items" class="list-group" #itemTap="onItemTap"
itemReorder="true">
You can find your example working in this playground.
Also, the Vue docs for the RadListView are located here. These Vue docs are not as complete, but everything should work once you "translate" to Vue.

Related

Scoped and global CSS not applied to Nativescript-Vue

I have created a new Nativescript-Vue project but the CSS is not working, scoped and global. But inline CSS like the code blocks below are working properly.
<ActionBar style="background-color: green" flat title="Nativescript">
and
<ActionBar backgroundColor="green" flat title="Nativescript">
Any tips? TIA
Here is my main.js:
import Vue from 'nativescript-vue'
import Home from './components/Home'
import VueDevtools from 'nativescript-vue-devtools'
import FontIcon from 'nativescript-vue-fonticon'
import store from './store'
if(TNS_ENV !== 'production') {
Vue.use(VueDevtools, {
host: "192.168.42.28" // IP of the machine you are writing your code on, _not_ the Device IP your app runs on
})
}
// Prints Vue logs when --env.production is *NOT* set while building
Vue.config.silent = (TNS_ENV === 'production')
Vue.use(FontIcon, {
debug: true, // <-- Optional. Will output the css mapping to console.
paths: {
'fa': './assets/css/fontawesome.min.css',
'far': './assets/css/regular.min.css',
'fas': './assets/css/solid.min.css',
'fab': './assets/css/brands.min.css'
}
})
new Vue({
store,
render: h => h('frame', [h(Home)])
}).$start()
And here is my Home.vue
<template>
<Page>
<ActionBar style="background-color: green" flat title="Nativescript">
<ActionItem ios.position="right">
<FontIcon name="fa-shopping-bag" type="fas"/>
</ActionItem>
</ActionBar>
<StackLayout>
<Label class="message" :text="msg"/>
</StackLayout>
</Page>
</template>
<script>
export default {
data() {
return {
msg: 'Welcome to Nativescript',
}
}
}
</script>
<style scoped>
ActionBar {
background-color: #53ba82;
color: #ffffff;
}
.message {
vertical-align: center;
text-align: center;
font-size: 20;
color: #333333;
}
</style>
This issue has been fixed in #nativescript/webpack#3.0.3.
Make sure you update the webpack plugin:
ns clean
npm i --save-dev #nativescript/webpack#^3.0.3
ns run <platform>
Details in pinned issue: https://github.com/nativescript-vue/nativescript-vue/issues/715

Create a map of Canada and USA with Datamaps in a single page

I am using Datamaps to create a map of Canada and USA. I saw the tutorial and/or examples in its website and I saw a "USA map only" example. And I did that:
<script>
var addUSA = new Datamap({
scope: 'usa',
element: document.getElementById('usa-map'),
geographyConfig: {
highlightOnHover: false,
borderColor: '#006298',
borderWidth: 0.8,
popupTemplate: function(geography, data) {
return "<div class='hoverinfo'><strong>" + data.info + "</strong></div>";
}
},
dataUrl: 'data.json',
dataType: 'json',
data: {},
fills: {
defaultFill: '#FFFFFF'
}
});
addUSA.labels();
</script>
So I assume that you can also create a "Canada map only". But the problem is, I don't know how to combine two countries.
I aim for labels, the hover-info and json that's why I'm using Datamaps.
So I've found this URL entitled Custom Map Data in Datamaps by Mark DiMarco and I used and tried copying what he had done. On that link, he created a map of Afghanistan which was not included in his main examples on Datamaps website. But instead of one country, we will combine two countries custom map using Datamaps. This is an experiment I've made but I hope this will be the answer to your problem
First, he created a custom topo json for Afghanistan. He published a tutorial on how to create custom map data but I think I don't have an access 'cause I'm getting 404 or he took it down. Going back, the code he used for that custom topo json can also be found in his other works located at "More Versions" link in Datamaps website. You just need to look for the country/ies you need to make a custom topo json. On your end, look for datamaps.afg.js and datamaps.usa.js; and get the json.
I only have 1 reputation and I am limit with two URLs. Just visit this GitHub site where I put those two custom topo json for Canada and USA.
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="style.css">
<title>Canada and USA</title>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script src="http://rawgithub.com/markmarkoh/datamaps/master/dist/datamaps.none.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<!-- CANADA -->
<h1>CANADA</h1>
<div id="canada"></div>
<!-- USA -->
<h1>USA</h1>
<div id="usa"></div>
</body>
</html>
CSS
#canada {
border: 1px solid #000000;
height: 450px;
width: 400px;
}
#usa {
border: 2px solid #EDA552;
height: 400px;
width: 500px;
}
JQUERY
$(function() {
var canadaMap = new Datamap({
element: document.getElementById('canada'),
geographyConfig: {
dataUrl: 'canada.topo.json'
},
scope: 'canada',
fills: {
defaultFill: '#bada55'
},
setProjection: function(element) {
var projection = d3.geo.mercator()
.center([-95, 71])
.scale(200)
.translate([element.offsetWidth / 2, element.offsetHeight / 2]);
var path = d3.geo.path().projection(projection);
return {path: path, projection: projection};
}
});
var USAmap = new Datamap({
element: document.getElementById('usa'),
geographyConfig: {
dataUrl: 'usa.topo.json'
},
scope: 'usa',
fills: {
defaultFill: '#bada55'
},
setProjection: function(element) {
var projection = d3.geo.mercator()
.center([-120, 54])
.scale(250)
.translate([element.offsetWidth / 2, element.offsetHeight / 2]);
var path = d3.geo.path().projection(projection);
return {path: path, projection: projection};
}
});
});
Working code here => JS FIDDLE

How do I create a component that generates Radio-buttons in Ember.js?

Can I and should i pass arrays to components in ember?
For example if I wanted to template something that renders a couple of radiobuttons with labels:
<label for="media">Media</label><input type="radio" name="entry.1602323871" value="media" id="media" />
<label for="guest">Guest</label><input type="radio" name="entry.1602323871" value="guest" id="guest" />
Could I somehow pass an array with this content and loop through it.
Media, media
Guest, guest
Yeah, You can pass anything to components. Just a try to the radio-buttons
//Basic radio Component
App.RadioButton = Ember.Component.extend({
tagName : "input",
type : "radio",
attributeBindings : [ "name", "type", "value", "checked:checked" ],
click : function() {
this.set("selection", this.$().val());
},
checked : function() {
return this.get("value") === this.get("selection");
}.property('selection')
});
Em.Handlebars.helper('radio-button',App.RadioButton);
Updated (component name should be dasherized)
Working Radio Demo
It's now a tiny bit easier to get radio-buttons into your project (if you're using ember-cli) by using the ember-radio-buttons addon
Install:
npm install ember-radio-buttons --save-dev
Usage:
{{radio-button value='one' checked=selectedNumber}}
{{radio-button value='two' checked=selectedNumber}}
Upped #selva-G's answer.
I found that using the ButtonGroup Component from Bootstrap-for-Ember is actually cleaner.
Here's what I've done:
In my view's template:
<script type="text/x-handlebars" data-template-name="myview">
{{bs-btn-group contentBinding="things" selectedBinding="selectedThing"}}
</script>
In that view's controller (which doesn't necessarily need to be an ArrayController, rather can be a generic Ember Controller):
App.MyviewController = Ember.ArrayController.extend({
things: [
Ember.Object.create({value: 'first', title: 'First Thing'}),
Ember.Object.create({value: 'second', title: 'Second Thing'}),
Ember.Object.create({value: 'third', title: 'Third Thing'})
],
selectedThing: 'second'
selection: function() {
console.log(this.get('selectedThing');
}.observes('selectedThing')
});

how to get kendoui grid popup add/edit form created from kendo template, show the correct title for add and edit operations?

I can't seem to find a simple way to set the title on a popup add and edit form launched from the kendoui grid, when it is created using a custom template. When I tried the following example, both Add and Edit operations had "Edit" in the title bar of the popup:
Markup:
<script id="popup-editor" type="text/x-kendo-template">
<p>
<label>Name:<input name="name" /></label>
</p>
<p>
<label>Age: <input data-role="numerictextbox" name="age" /></label>
</p>
</script>
<div id="grid"></div>
JavaScript:
$("#grid").kendoGrid({
columns: [
{ field: "name" },
{ field: "age" },
{ command: "edit" }
],
dataSource: {
data: [
{ id: 1, name: "Jane Doe", age: 30 },
{ id: 2, name: "John Doe", age: 33 }
],
schema: {
model: { id: "id" }
}
},
editable: {
mode: "popup",
template: kendo.template($("#popup-editor").html())
},
toolbar: [{ name: 'create', text: 'Add' }]
});
Fiddle demonstrating the issue: http://jsfiddle.net/codeowl/XN5rM/1/
The issue is that when you press the Add or Edit buttons, the title bar in the popup says: "Edit". I want it to say Add when you press the Add button and Edit when you press the Edit button.
Thank you for your time,
Regards,
Scott
If you want a simple solution, add code to the edit event of the grid to check to see if the model being created when edit is called is a new one or an existing one and set the text accordingly:
...
edit: function (e) {
//add a title
if (e.model.isNew()) {
$(".k-window-title").text("Add");
} else {
$(".k-window-title").text("Edit");
}
}
...
Hope this helps...
If the only thing that you need to do is add a title, you should use:
editable : {
mode : "popup",
window : {
title: "EdiciĆ³n",
}
},
You don't need to define a template unless you need to define something else.
Your modified Fiddle here : http://jsfiddle.net/OnaBai/XN5rM/2/

showing all fields in a Dojo Data Grid with dojo.store.JsonRest

I have a Dojo Data Grid for displaying contact information that is showing values for only two columns: "model" and "pk". The other columns are blank, probably because the JSON response from the server puts the other name/value pairs inside of "fields":
[{"pk": 1, "model": "accounting.contacts", "fields": {"mail_name": "Andy", "city": "Grand Rapids", "zip": "49546", "country": "US", "state": "MI"}}]
What is the best way to get all my fields to show up in the grid?
Here's the relevant view in Django:
def contacts(request):
json_serializer = serializers.get_serializer("json")()
json_contacts = json_serializer.serialize(Contacts.objects.all(), ensure_ascii=False)
return HttpResponse(json_contacts, mimetype="application/json")
And here's my Dojo page:
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojo/dojo.xd.js"
data-dojo-config="isDebug: true,parseOnLoad: true">
</script>
<script type="text/javascript">
dojo.require("dojo.store.JsonRest");
dojo.require("dojox.grid.DataGrid");
dojo.require("dojo.data.ObjectStore");
dojo.ready(function(){
objectStore = new dojo.store.JsonRest({target:"/contacts/"});
//alert(objectStore);
dataStore = new dojo.data.ObjectStore({objectStore: objectStore});
//alert(dataStore);
layoutGridContacts = [{
field: 'mail_name',
name: 'Name',
width: '200px'
},
{
field: 'model',
name: 'DB Table',
width: '100px'
...
}];
gridContacts = new dojox.grid.DataGrid({
query: {
name: '*'
},
store: dataStore,
clientSort: true,
structure: layoutGridContacts
}, dojo.byId("containerGridContacts"));
gridContacts.startup();
});
</script>
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dijit/themes/claro/claro.css" />
<style type="text/css">
#import "http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojox/grid/resources/Grid.css";
#import "http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojox/grid/resources/claroGrid.css";
.dojoxGrid table {margin: 0; } html, body { width: 100%; height: 100%;
margin: 0;}
</style>
</head>
<body class="claro">
<div id="containerGridContacts" style="width: 100%, height: 100%;">
</div>
</body>
Thanks.
This is really a question of, "How do I interact with a javascript object?" Given the JSON in your question, and assuming you assigned it to the variable obj, you could access mail_name with obj[0]['fields']['mail_name'] or using dot notation, obj[0].fields.mail_name. I haven't used Dojo, but I'd wager you just need to set fields.mail_name as the field in layoutGridContacts.
I was able to get the server to produce a JSON response that does not contain nested objects, so the Dojo Store was able to use it. To do this I changed my view to:
def contacts(request):
all_contacts = list(iter(Contacts.objects.values()))
json_contacts = simplejson.dumps(all_contacts)
return HttpResponse(json_contacts, mimetype="application/json")
Use "fields." in front of your field identifier to access the properties inside fields:
layoutGridContacts = [{
field: 'fields.mail_name',
name: 'Name',
width: '200px'
},
...
You can use formatter method to retrieve the data. For your example it will be something like below
{name:"Name",
field: "fields",
width: "20%",
cellStyles:"background-color:#e3690b;",
formatter: function(field){
if(!field){return;}
return field.mail_name;
}
}