I'm using the jQuery data() function to store data on a series of divs in a format similar to:
{
options: {
example: {
option_1: {
value: "example 1"
},
option_2: {
value: "example 2"
}
}
}
}
I can add new keys and update the data, e.g.
$("#mydiv").data('options',{'example':{} }); // the object is already created in the live version
$("#mydiv").data('options')['example']['option_3'] = { value: "example 3" };
But when I come to use removeData(), FireBug tells me that the key is undefined, e.g.
$("#mydiv").removeData('options')['example']['option_2'];
Any help appreciated!
.removeData(name) removes the previously stored data with the given name, and returns a jQuery object. In your scenario, you don't want the remove the entire options object, just a specific property of it, so you should be using delete instead:
delete $("#mydiv").data('options')['example']['option_2'];
Related
I am in Angular environment using Kendo. All I want to do is following:
Take Json
Produce Kendo tree using it
I have tried it with simple data and it seems to work fine. But this time I have somewhat complex data and it seems like it does not work well with complex Json. I have been trying to have it render Json but it seems like it keeps on thinking and never comes back. I have created a sample Dojo for reference:
http://dojo.telerik.com/EdOqE
I am not sure what am I doing wrong but it just does not seem to work. Can anyone help me with this please?
I presume you have controll over the resultant json, because you'll have to change it a little to fit the TreeView's expected format. Check this out:
{
"items": [{ // Projects
"Id": 0,
"Name": "Your Example Project",
"CreatedOn": "",
"hasChildren": true,
"items": [{ // Analyses
"Id": 0,
"Name": "1.0 - Your Example Run",
"CreatedOn": "",
"hasChildren": true,
"items": [{ // Samples
"Id": 0,
"Name": "Sample 1",
"hasChildren": false,
"Description": "ample frample sample"
}, {
"Id": 0,
"Name": "Sample 2",
"hasChildren": false,
"Description": null
}]
}]
}]
};
The above json is what I did to work in the widget. First of all, the collection properties were renamed to items. All of them, in all levels. With that, kendo will know how property it should deal with. A hasChildren property was added to let it know when it has to show the expand icon. Otherwise it will show the expand option even if the item doesn't haves any children. So user clicks it and get an empty result.
This is the widget initialization options:
{
dataSource: new kendo.data.HierarchicalDataSource({
data: things,
schema: {
data: "items"
}
}),
dataTextField: "Name"
};
With schema.data I tell which property kendo will deal as the collection item. The dataSource expects an array, but if you give him an object, you have to set this property. If it was an array, then kendo would look for item property of each child for default. dataTextField is the name of the property it will use as the label.
Demo
Here is another demo with the data as an array. No need to set schema.data.
Update:
I was afraid you would say that. Yes, there is a way to deal with the data if you can't change it in the server-side. You have to intercept the data at the schema.parse() method and change the resultant data object property to items, so then the widget will understand:
schema: {
data: "items",
parse: function(data) {
if (data.hasOwnProperty("Projects")) {
return { items: data.Projects };
}
else if (data.hasOwnProperty("Analyses")) {
return { items: data.Analyses };
}
else if (data.hasOwnProperty("Samples")) {
return { items: data.Samples };
}
}
}
Demo
Every node when opened will call parse with items collection as data parameter. You have to return a new object with the property name as items instead of Projects, Analysis or Samples.
I forgot you can't touch the data, so can't add hasChildren property as well. Then you have to add a tiny logic into parse to set those properties in each level, otherwise the expand icon would not appear:
schema: {
data: "items",
parse: function(data) {
if (data.hasOwnProperty("Projects")) {
data.Projects.forEach(p => {
p.hasChildren = false;
if (p.hasOwnProperty("Analyses")) {
p.hasChildren = true;
}
});
return { items: data.Projects };
}
else if (data.hasOwnProperty("Analyses")) {
data.Analyses.forEach(a => {
a.hasChildren = false;
if (a.hasOwnProperty("Samples")) {
a.hasChildren = true;
}
});
return { items: data.Analyses };
}
else if (data.hasOwnProperty("Samples")) {
return { items: data.Samples };
}
}
}
Demo
It is ugly, I know. But get used to Kendo, it is the it goes with it.
I am using firebase, and angularfire.
there are so many ways to do CRUD with the Firebase Api
actually, I still don't get what is specific difference for using
$add with $firebaseArray
.push() method
.set() method
I think they are technically same, I prefer to use .set method() without knowing the exact reason, why I'd using that. is there any specific reason to not use it? what is exactly $firebaseArray did? if we could just declare basic reference variable.
in this case:
var usersRef = Ref.child('users');
$scope.createUser = function() {
$scope.userRef.child($id).set({
name: name
});
};
or
$scope.data = $firebaseArray(Ref.child('users'));
$scope.createUser = function() {
$scope.data.child($id).$add({
name: name
});
};
thank you.
If I have the following data tree in Firebase:
{
users:
{
key: { name:"bob" }
}
}
When I do an $add, I will create a new item in the tree
$scope.data.child('users').$add({
name: name
});
Since $add uses the Push method in Firebase, new random Key will be used when pushing data to the child.
{
users:
{[
key: { name:"bob" },
key2: { name:"name" }
]}
}
If I do a set on the same Users object, I will overwrite the data that is already there. So, in your example, without specifying a key, you will overwrite the entire user object.
$scope.userRef.child('users').set({
name: name
});
};
This will result with this data
{
users:
{
name: "name"
}
}
This happens because any null values you pass to the Set method will delete any data that was originally there.
Passing null to set() will remove the data at the specified location.
https://www.firebase.com/docs/web/api/firebase/set.html
I have the below JS code in my Ember app that gets called;
myPanels.accordionPanels = [];
myPanels.accordionPanels.push({
panel: {
name: "my-grid",
type: 'comp',
props: [{
key: 'elementId',
value: "myCustomId"
}]
}
});
So as you can see, I start by setting myPanels.accordionPanels = [] every time and then push the object.
However, I got the following error
Assertion Failed: Attempted to register a view with an id already in
use: myCustomId
So I am assuming that the object inside is not getting reset & it is able to find the earlier created "myCustomId".
Am I resetting the array (or rather the object inside it) correctly ?
Since I am able to push values using:
accordionPanels = [];
accordionPanels.push({
panel: {
name: "my-grid",
type: 'comp',
props: [{
key: 'elementId',
value: "myCustomId"
}]
}
});
make sure myPanels.accordionPanels doesn't have any prototype associated with it.
Try to inspect its value as:
myPanels.accordionPanels = [];
console.log(myPanels.accordionPanels); // see if it has values.
You can delete value using :
delete myPanels.accordionPanels PROTOTYPE
When building up a list of options in a select list using Javascript I'd like to attach a Javascript object to that option that I could easily retrieve in the change event.
So, while writing this question I wanted to provide some sample code and found a way to make this work; so I have a slight addition to the question. Is it bad to attach javascript object to DOM elements? Back in the day I remember there being issues with memory leaks in certain circumstances.
Here's a working example:
http://jsbin.com/afolo3/edit
var objs = [
{ id: 1, value: "One", type: "number" },
{ id: 2, value: "Two", type: "number" },
{ id: 3, value: "Three", type: "number" },
{ id: "A", value: "A", type: "char" },
{ id: "B", value: "B", type: "char" },
{ id: "C", value: "C", type: "char" },
];
var options = $.map(objs, function(item, idx) {
var opt = $("<option/>").val(item.id).text(item.value);
opt[0]["obj"] = item;
return opt;
});
$.fn.append.apply($("#select"), options)
.change(function() {
$("#select option:selected")
.each(function(){
alert(this.obj.type);
});
});
Use jQuery's .data() function instead.
Updated example: http://jsbin.com/afolo3/2
You can certainly attach objects to element instances the way you have; in fact, that's how jQuery does its data magic behind-the-scenes in the current version.
That said, since you're using jQuery already, I'd probably use the jQuery API for this (data) instead, just in case it turns out that at some stage, a browser comes on the scene where a workaround is required — you'll get the benefit of the jQuery maintainers doing the workaround for you, rather than having to do it yourself.
Here's what it would look like using data. Basically to set the data:
opt.data("obj", item);
...and to retrieve and show its type property:
alert(opt.data("obj").type);
...where in each case, opt is a jQuery object for the option element in question.
One slight "gotcha" with jQuery's data function: If you retrieve a data object you've never set, you'll get null back (rather than undefined, which would be the usual JavaScript convention).
I'm currently looking into the Twitter-API - specifically the daily trends-API (http://search.twitter.com/trends/current.json).
Example return from Twitter
{
trends: {
2009-11-19 14:29:16: [
{
name: "#nottosayonfirstdate",
query: "#nottosayonfirstdate"
},
{
name: "New Moon",
query: ""New Moon""
},
{
name: "#justbecause",
query: "#justbecause"
}
]
}
}
I wonder how I can return the values within there without knowing the exact date at the time of the call, since it won't be possible to synchronise the client-time with the server-time.
Normally, I'd go for trends.something[1].name to get the name, but since the timestamp will change all the time, how can I get it when trends is no array?
you can use this:
for (var i in trends) {
alert (i); // "2009-11-19 14:29:16"
alert (trends[i][0].name); // "#nottosayonfirstdate"
}