Fill materialize javascript autocomplete data with twig object - javascript

I'm working on an application and now I'm messing with the Materialize autocomplete plugin.
Now I would like to parse an array of twig objects (let's say Customers), and to create an array in JS like this one :
var customersAutocomplete = [
{
key: 1,
Title: "John Doe",
label: 'John'},
{
key: 2,
title: "Ulrich",
label: 'John'},
{
key: 3,
label: 'James'}
];
Autocompletion is from a global JS files and looks like this :
$.fn.autocomplete = function (options) {
// Defaults
var defaults = {
data: {customersAutocomplete},
limit: Infinity,
onAutocomplete: null,
minLength: 1
};

Adding to #RaymondA's comment, you can use Twig to do that directly in your template if your customers object has the right structure already :
<!-- views/your.view.html.twig -->
<script>
customersAutocomplete = {{ customers|json_encode() }};
</script>
And then use customersAutocomplete in your js file :
$.fn.autocomplete = function (options) {
// Defaults
var defaults = {
data: customersAutocomplete,
limit: Infinity,
onAutocomplete: null,
minLength: 1
};

Related

Need better JSON Schema to validate sparse matrix data object

I need to validate complex object in JavaScript.
Object is based on dictionary:
var dict = {'1':true,'2':true,'3':true};
Object store matrix of pairs (usually not full):
var obj = {'1':{
'1': 'str1',
'2': 'str2',
'3': 'str3',
},'2':{
'1': 'str1',
'2': 'str2',
}
};
I make validation schema with AJV validator.
Schema requirements:
1st level object contains only properties from dictionary.
2nd level object contains only properties from dictionary.
data is a string
Generating schema:
var dict = {'1':true,'2':true,'3':true};
var subProperties = R.map(function(item){
return {
'type' : 'string',
"minLength": 1,
}
}, dict);
var root = {
"type" : "object",
"additionalProperties" : false
};
root.properties = R.map(function(item){
return {
"type" : "object",
'properties' : subProperties,
"additionalProperties" : false
};
}, dict);
console.log(root)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/4.9.0/ajv.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.22.1/ramda.min.js"></script>
This schema is working well but the problem is performance. When dictionary contains 200 elements it requires 10 seconds to compile this schema (validation is fast, compilation is slow). Moreover it throws out of memory exception time to time. Is it possible to make better validation schema?
Memory exceptions are not surprising here given that you are validating 40000 properties. Your validation function code size should be around 30Mb.
You can use propertyNames keyword that I added to v5/6 proposals and that is available in ajv-keywords package.
var dict = ['1', '2', '3'];
var schema = {
type: 'object',
propertyNames: { enum: dict },
additionalProperties: {
type: 'object',
propertyNames: { enum: dict },
additionalProperties: {
type: 'string',
minLength: 1
}
}
};
var ajv = require('ajv')();
require('ajv-keywords')(ajv, 'propertyNames');
var validate = ajv.compile(schema);
This schema is tiny but does the same.
You can achieve the same using patternProperties keyword that exists in the current standard version (with es6 property syntax):
var names = '^(1|2|3)$';
var schema = {
type: 'object',
additionalProperties: false,
patternProperties: {
[names]: {
type: 'object',
additionalProperties: false,
patternProperties: {
[names]: {
type: 'string',
minLength: 1
}
}
}
}
};
propertyNames looks simpler and should be faster I think.
By mapping over items the result is not 1 but N schema (i.e. if you have 200 items, 200 schema get created for the sole purpose of validating the key).
The alternative is to either use patternProperties with a huge 200 key long RegExp or more simply, just validate the object manually.
var dict = {'1':true,'2':true,'3':true};
var monsterRegex = '^' + Object.keys(dict).join('|') + '$'
var valSchema = {
type: 'string',
minLength: 1
}
var keySchema = {
type: 'object',
additionalProperties: false,
patternProperties: {}
}
keySchema.patternProperties[monsterRegex] = valSchema
var objSchema = {
type: 'object',
additionalProperties: false,
patternProperties: {}
}
objSchema.patternProperties[monsterRegex] = keySchema
console.log(objSchema)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/4.9.0/ajv.min.js"></script>

Create list of object members from object list

Assume I have a list of objects like so:
var list = [
{ date: '22/9/2016', status: 1, id: '11111' },
{ date: '23/9/2016', status: 1, id: '22222' },
{ date: '24/9/2016', status: 1, id: '33333' }
];
I would like to create a list of the ids of all the objects in the above list, so that I end up with:
var idList = ['11111', '22222', '33333'];
Obviously, I could iterate through the list and build the idList manually.
Is there an alternative way of doing this through either native JS, angularJS, or perhaps another library.
Manually iterating through the list isn't a big overhead, I just want to ensure I'm not ignoring functionality of JS / angularJS that would do this for me instead.
You can use Array map
var list = [
{ date: '22/9/2016', status: 1, id: '11111' },
{ date: '23/9/2016', status: 1, id: '22222' },
{ date: '24/9/2016', status: 1, id: '33333' }
];
var idList = list.map(item => item.id );
console.log(idList);
Use
var ids = list.map(function(item) { return item.id});
Should work.

How to add new attribute in data object?

For arrays vue.js good works with default array methods: push, pop, shift, reverse... But how to create new item in object and paste some value?
new Vue({
el: '#demo',
data: {
items: [
{
start: '12:15',
end: '13:15',
name: 'Whatch Vue.js Laracast',
description: 'Watched the Laracast series on Vue.js',
tags: ['learning', 'Vue.js', 'Laracast', 'PHP'],
note: "Vue.js is really awesome. Thanks Evan You!!!"
},
{
start: '13:15',
end: '13:30',
name: "Rubik's Cube",
description: "Play with my Rubik's Cube",
tags: ['Logic', 'Puzzle', "Rubik's Cube"],
note: "Learned a new algorithm."
}
],
},
methods: {
addItemAttribute: function(name, text) {
this.items[0][name] = text;
}
}
});
You can add properties to a Vue object similar to a normal javascript object. Reference: https://vuejs.org/api/#Options-Data
var obj = { a: 1};
obj.a // 1
obj.b // undefined
obj.b = 2;
// Now obj.b is defined
obj.b // 2
You can access data from Vue object like this
var vm = new Vue({
data: {
a: 1,
b: 2
}
});
Now we can access data from $data property
vm.$data.a === 1;
// You can add a new property
vm.$data.c = 3;
// it can be any object
vm.$data.d = {id: 1, name: 'ABC'}
You get and update props of a component using component.options.props
var component = Vue.component('props-demo-advanced', {
props: {
// just type check
size: Number,
// type check plus other validations
name: {
type: String,
required: true,
// warn if not two way bound
twoWay: true
}
}
});
Let's say, we want to make name twoWay binding to false
component.options.props.name.twoWay = faslse
Or even you can change the entire object.
component.options.props = {
size: Number,
type: {
type: Number,
required: false,
twoWay: false
}
}
I don't know the above configurations are correct or not, I am just trying to convey the idea.
You should learn Javascript first, how objects are made, how to change them etc.

Send Python information to a JavaScript file

I am new to Python and JavaScript and (attempting) to use cola.js. My HTML form sends information to Python, which turns it into an array of dictionaries.
Class_Name(ndb.Model):
class_title = ndb.JsonProperty()
def post(self):
classname = self.request.get('classname') #user inputs 1 classname
prereq = self.request.get('prereq') #user inputs 1 prereq
new_dictionary = {}
new_dictionary [classname] = prereq
new_class = Class_Name(class_title = new_dictionary) #stores as a dictionary
new_class.put()
Class_data = Class_Name.query().fetch() #gets all instances of Class_Name
*** code that goes in b/w sends back to input form if want to add more classes, else, goes to below code
output = []
for a in Class_data:
jsonprop = a.class_title
extracted_output = json.dumps(jsonprop)
output.append(extracted_output)
template_vars= {'Class_data': output}
template = jinja2_environment.get_template('template/post.html')
self.response.write(template.render(template_vars))
This is my basic code so far. I want to use cola.js to turn my information into a graph, basically mapping out each class with its prerequisites. However, the cola.js format is a JavaScript file that looks like this:
graph = {
nodes: [
{
id: 'A'
}, {
id: 'B'
}, {
id: 'C'
}
],
links: [
{
id: 1,
source: 'A',
target: 'B'
}, {
id: 2,
source: 'B',
target: 'C'
}, {
id: 3,
source: 'C',
target: 'A'
}
]
};
Is there any way I can tell JavaScript to get my Python array, and enter the info into the JavaScript file like this?
graph = {
nodes: [
{
id: 'Class1' **will put actual class name
}, {
id: 'Class2'
}
],
links: [
{
id: 1,
source: 'Class1',
target: 'prereq'
}, {
id: 2,
source: 'Class2',
target: 'prereq'
}
]
};
This is a rough code for turning my Python information into the JavaScript format.
nodes_array = []
nodes_dict = {}
links_array = []
links_dict = {}
graph_array = []
#loops through every element
for a in Class_data:
jsonprop = a.class_title
extracted_output = json.loads(jsonprop)
for c_class, prereq in extracted_output.iteritems():
# for the links dictionary
counter_link = 1
# creates {'id':'class1'}
nodes_dict['id'] = c_class
#creates [ {'id':'class1'}, {'id':'class2'}]
nodes_array.append(nodes_dictionary)
# creates {'id': 'counter', 'source': 'class1', 'target': 'prereq'}
links_dictionary[id] = counter_link
counter_link++
links_dictionary[source] = c_class
links_dictionary[target] = prereq
# creates [{'id': 'counter', 'source': 'class1', 'target': 'prereq'}]
links_array.append(links_dictionary)
#creating the format --> 'nodes': [ {id: class1}, {id:class2}, {id:class3} ]"
#creating the format --> 'links': [ {id: 1, source :class2, target :class3} ]"
graph[nodes] = nodes_array
graph[links] = links_array
Your Python script can use the json module to write the graph to a file in a format that JavaScript understands.
If you do this in Python:
import json
graph = {
'nodes': [ {'id': 'Class1'}, {'id': 'Class2'} ],
'links': [
{ 'id': 1, 'source': 'Class1', 'target': 'prereq' },
{ 'id': 2, 'source': 'Class2', 'target': 'prereq' }
]
}
with open('graph.js', 'w') as out_file:
out_file.write('var graph = %s;' % json.dumps(graph))
The result is a file named graph.js, containing this:
var graph = {"links": [{"target": "prereq", "source": "Class1", "id": 1}, {"target": "prereq", "source": "Class2", "id": 2}], "nodes": [{"id": "Class1"}, {"id": "Class2"}]};
If you load graph.js before loading your own JavaScript file, you can refer to the variable graph to use your graph.

Converting JSON to DynaTree Object

I have following data Structure which I want to use in data structure given in Dyntree Format:
[
{
title: "my Title",
isFolder: "true",
key: 1
}
]
I am setting above data structure as STRING in a JS variable.
When I set this value as a javascript variable, it gives error of Invalid Type
DynTree format is given below;
var fakeJsonResult = [
{ title: 'Lazy node 1', isLazy: true },
{ title: 'Simple node 2', select: true }
];
This is simple if you want to create a dynatree from the object you mentioned simply do this
var children = [
{
title: "my Title",
isFolder: "true",
key: 1
}
];
$('#tree').dynatree({
children : children
});

Categories

Resources