I have a selectize where I set optgroups, give them an $order, and then try to set lockOptgroupOrder, which ends up throwing an exception: "Uncaught TypeError: Cannot read property '$order' of undefined".
This all works perfectly before I try to use lockOptgroupOrder (except that it sorts wrong). I cannot figure out why it can't find $order, when I'm clearly passing $order in as part of optgroups. (I've also tried setting optgroupOrder: ['first', 'recents', 'favorites', 'all'] with no luck.)
var stuff = $('#stuff').selectize({
optgroups: [
{value: 'first', label: '', $order: 1},
{value: 'recents', label: 'Recents', $order: 2},
{value: 'favorites', label: 'Favorites', $order: 3},
{value: 'all', label: 'All', $order: 4}
],
optgroupField: 'type',
lockOptgroupOrder: true,
//more things like load() and onChange()...
});
The error:
It's breaking in this loop:
I have exhausted all other forms of researching this error. Has anyone come across this before?
So after many, many hours of googling, chrome debugging, and general crying, I figured out the issue and now I'm posting my solution in case anyone else comes across this error.
Thanks to this discussion board:
lockOptgroupOrder breaks onChange
I was able to piece together that one of my data elements was missing a 'type' field (optgroupField). I stepped through all 1350 options before realizing that it was actually the default option I added to the select before turning it into a selectize. In this instance, I need this option to stay, so I can't just get rid of that line of html. But I also can't add a "type" attribute to the option, or even a data-type attribute, it doesn't pass it along.
Finally I figured out from this discussion board:
Add data-attribute to selectize.js options
that I can assign a data-data attribute and pass it the name and value, and then it would pass that attribute along when it turns into a selectize. So my final solution was to add what I needed via the option before it turns into a selectize:
<option selected disabled value="default" data-data='{"type":"first"}'>The Stuff</option>
May this help some other poor soul from having to go through this in the future.
Related
I have a multiatlas with different types of images inside:
this.load.multiatlas('images', 'images.json', 'images.png');
I want to make an animation from a particular set of images inside the atlas, say, 'face1'...'face9'. How can I target them when creating the animation? I mean, there is a method
this.anims.create({
key: 'faceAnim',
frames: [ {key: '...'}, {key: '...'} ]
})
But I don't know what would be placed inside the 'key' values to make it work. key: 'face1' obviously doesn't work, because Phaser needs to know which atlas to use.
Assuming all of the frames you want to use are named starting with face in your images.json file, you can do this:
this.anims.create({
key: 'images',
frames: this.anims.generateFrameNames('images', { prefix: 'face', start:1, end: 9},
[any other animation config settings you want, repeat, etc.]
});
I'm guessing on the start and end values because I can't see your images.json to know how you named everything, but this should get you started down the right path. This question might also help.
In this jsfiddle I have a line that is created from a subclass (it's basically a line with two additional attributes). I'm trying to serialize/deserialize the line to/from JSON. I can serialize with no problems (including the two additional attributes) but when I try to deserialize with loadFromJSON I get the Cannot read property 'async' of undefined exception.
Uncomment the last line in the jsfiddle to get the error.
I implemented the fromObject() method, but I'm not sure it's correct. What's wrong with this code?
Javascript:
var canvas = new fabric.Canvas('c');
fabric.PolySegment = fabric.util.createClass(fabric.Line, {
type: 'seg',
initialize: function(points,options) {
options || (options = { });
this.callSuper('initialize', points,options);
this.set('poly', options.poly);
this.set('id', options.id);
},
toObject: function() {
return fabric.util.object.extend(this.callSuper('toObject'), {
poly: this.get('poly'),
id: this.get('id')
});
},
_render: function(ctx) {
this.callSuper('_render', ctx);
}
});
fabric.PolySegment.fromObject = function (object, callback) {
return new fabric.PolySegment(object);
};
fabric.PolySegment.async = true;
var coords1 = [ 10, 10, 100, 100 ];
var seg1 = new fabric.PolySegment(coords1, {
stroke: 'black',
strokeWidth: 6,
originX: 'left',
originY: 'top',
poly: 111111,
id: 222222
});
canvas.add(seg1);
var json = JSON.stringify(canvas);
document.getElementById('t').innerHTML = json;
// uncomment the line below, you'll get an exception
//canvas.loadFromJSON(json);
In looking at your Fiddle, it seems like the issue is the type value you have given your new class. If I change:
type: 'seg',
to
type: 'polySegment',
and uncomment the last line, I don't get the error. However, I also don't get the line to load on the canvas. But I guess I'm not 100% sure what is happening in your script there - you're loading the polySegment, then converting it to JSON and reloading it? I'm assuming this is merely for illustration purposes.
While what I suggest here gets rid of your error, I'm personally not 100% sure why it works. In reading the FabricJS documentation on Subclassing, it doesn't specify that the subclass type needs to match that of the subclass definition, but it seems to work...
I hope that helps in some way.
One last comment about this, I've always used the toJSON method to transfer a canvas element to JSON. Though this retrieves a JSON object, not a string like you are doing. Also, the toJSON method requires that you specify what properties you want to capture, so maybe this isn't the best method for your case. It's discussed on this page. But my point for bringing this up, is I know for certain that the toJSON method works well with the loadFromJSON method. So I mention that in case you find the JSON.stringify method to be the issue, there is a alternate method to approach the same concept.
Having trouble in setting up the default value for the drop down when AngularJS/ng-repeat/custom directive + Select2 JS is used.
1. I avoided using ng-options as the directive priority is 0.
2. I tried setting the priority for the custom directive 'select2Directive' to a number less than 1000, but still no luck.
Plunker # http://plnkr.co/edit/Csy5FqDSQbErTm2fNPac. Appreciate any help. Thanks.
I noticed that you are calling the select2 using a small directive, but I found this library named angular-select2 which is easy to implement as well.
you can set the default values with your ng-model/$scope, take a lookt to this plunker to get the idea
http://plnkr.co/edit/pFkY5f?p=preview
EDIT:
I'd rather try to pass the data in other way seems like the select2 data and your the ng-repeat are not in sync
you could try a different approach something like creating a directive and insert the data from there.
directive('select2Dynamic', function ($timeout) {
return {
restrict: 'A',
priority: 1,
scope: {
ngModel: "="
},
require: 'ngModel',
link: function (scope, element, attr) {
var select2Inst = element.select2();
select2Inst.select2({data:scope.$parent.$eval(attr.ngModel)});
select2Inst.select2('val',attr['select2Dynamic']);
}
}
});
<select select2-dynamic='2' ng-model='addresses' id="address" name="address" style="width:200px;" >
</select>
if you want to stick to your approach you'll consider to set up the value and the end of the "model binding event"
look at this plunker
anyway I still stand my point that you should try angular-select2 library
hope that helps
This is very odd... I'm using populate() with a ref to fill in an array within my schema, but then the properties are inaccessible. In other words, the schema is like this:
new Model('User',{
'name': String,
'installations': [ {type: String, ref: 'Installations'} ],
'count': Number,
}
Of course, Insallations is another model.
Then I find & populate a set of users...
model.find({count: 0}).populate('installations').exec( function(e, d){
for(var k in d)
{
var user = d[k];
for(var i in user.installations)
{
console.log(user.installations[i]);
}
}
} );
So far so good! I see nice data printed out, like this:
{ runs: 49,
hardware: 'macbookpro10,1/x86_64',
mode: 'debug',
version: '0.1' }
However, if I try to actually ACCESS any of those properties, they're all undefined! For example, if I add another console log:
console.log(user.installations[i].mode);
Then I see "undefined" printed for this log.
If I try to operate on the object, like this:
Object.keys(user.installations[i]).forEach(function(key) { } );
Then I get a typical "[TypeError: Object.keys called on non-object]" error, indicating that user.installations[i] is not an object (even though it is outputted to the console as if it were). So, I even tried something ugly like...
var install = JSON.parse(JSON.stringify(user.installations[i]));
console.log(install, install.mode);
And, again, the first output (install) is a nice object containing the property 'mode'... but the 2nd output is undefined.
What gives?
Finally, I solved this...
I tried doing a console.log(typeof user.installations[i]); and got "string" as the output. This seemed odd, given that printing the object directly created console output (above) that looked like a normal object, not a string. So, I tried doing a JSON.parse(); on the object, but received the error "SyntaxError: Unexpected token r"
Finally, I realized what was going on. The "pretty console output" I described above was the result of a string formatted with \n (newlines). I had not expected that, for whatever reason. The JSON.parse() error is due to the fact that there is a known necessity with the node.js parser when attempting to parse object keys without quotations; see the SO question here:
Why does JSON.parse('{"key" : "value"}') do just fine but JSON.parse('{key : "value"}') doesn't? .
Specifically, note that the JSON parser in my case is failing on the character 'r', the fist character of "runs," which is the first key in my JSON string (above). At first I was afraid I needed to get a custom JSON parser, but then the problem hit me.
Look back to my original schema. I used a String-type to define the installation ref, because the array field was storing the installations's _id property as a String. I assume the .populate() field is converting the object to a String on output.
Finally, I looked at the Mongoose docs a little closer and realized I'm supposed to be referencing the objects based upon Schema.ObjectID. This explains everything, but certainly gives me some fixing to do in my schemas and code elsewhere...
I'm currently trying to create an application with Griffon 0.9.5 and the FlamingoBuilder.
I've the changed the value of frameClass in Application.groovy to 'org.jvnet.flamingo.ribbon.JRibbonFrame' and tried a few things in order to add a ribbon to the application window.
My first attempt was creating a ribbonTask node with nested ribbonBand nodes. The application starts but the buttons are not shown.
application(title: 'test01',
preferredSize: [320, 240],
pack: true,
locationByPlatform: true,
iconImage: imageIcon('/griffon-icon-48x48.png').image,
{
ribbonTask(title: 'Start') {
ribbonBand(id: 'fooBarBand', title: 'FooBar', image: imageIcon('/griffon-icon-48x48.png').image) {
commandButton(id: 'fooButton', text: 'Foo', image: imageIcon('/griffon-icon-48x48.png').image)
commandButton(id: 'barButton', text: 'Bar', image: imageIcon('/griffon-icon-48x48.png').image)
}
}
// add content here
label('Content Goes Here') // delete me
}
)
In my second attempt I explicitly create a RibbonTask and call addTask. The buttons are shown. However, I'm not sure if this is really the Griffon-way of doing things.
Question: Is there a better way to create a ribbon?
application(title: 'test01',
preferredSize: [320, 240],
pack: true,
locationByPlatform: true,
iconImage: imageIcon('/griffon-icon-48x48.png').image,
{
ribbonBand(id: 'fooBarBand', title: 'FooBar', image: imageIcon('/griffon-icon-48x48.png').image) {
commandButton(id: 'fooButton', text: 'Foo', image: imageIcon('/griffon-icon-48x48.png').image)
commandButton(id: 'barButton', text: 'Bar', image: imageIcon('/griffon-icon-48x48.png').image)
}
current.ribbon.addTask new RibbonTask('Start', fooBarBand)
// add content here
label('Content Goes Here') // delete me
}
)
I then tried adding a ribbonApplicationMenu with the following code snippet:
ribbonApplicationMenu(id: 'appMenu') {
ribbonApplicationMenuEntryPrimary(id: 'quitMenuEntry', text: 'Quit',
entryKind: JCommandButton.CommandButtonKind.ACTION_ONLY,
image: imageIcon('/griffon-icon-48x48.png').image)
}
However, it doesn't work. I get the following runtime exception:
java.lang.RuntimeException: Failed to create component for
'ribbonApplicationMenuEntryPrimary' reason:
groovy.lang.MissingPropertyException: No such property: text for
class:
griffon.builder.flamingo.factory.RibbonApplicationMenuEntryPrimaryFactory
The documentation of FlamingoBuilder states that there is a text property and when I remove the text property I get an exception because the text property must be set. I'm a little bit at loss. What's wrong with this code snippet?
I'm afraid the first issue is related to the application() node factory vs ribbonFrame() factory. You see, Griffon assumes the frame subclass to behave like any other regular JFrame however JRibbonFrame handles its children in a different way. This is not know to ApplicationFactory so it "fails" to add ribbon tasks unless you add them manually as you show in the second snippet.
This problem can be fixed by moving the parent/child relationship code from ribbonFrame() to ribbonBand/ribbonTask factories. This requires a new release of FlamingoBuilder.
Now on the second problem, that appears to be a bug on our side. Considering that FlamingoBuilder should be updated in any case we'll fix this problem too.