I am using jQuery v1.8.3 and jQuery UI v1.9.2. I have implemented the Autocomplete widget this way:
$('#input_id').autocomplete({
create: function (event, ui) {
// Initialize data
$(this).data( 'custom', { property1: 'Hello', property2: { num: 1, funct: function() { ... return value } } );
alert($(this).data('custom').property1) // Display 'Hello'
},
select: function(event, ui) {
alert($(this).data('custom').property1) // Display 'Hello'
},
source: function(request, response) {
alert($(this).data('custom').property1) // Display 'undefined'
alert(this.data('custom').property1) // I get 'TypeError: this.data is not a function'
}
});
Why in the source option I get undefined while in create and select events I get Hello? How should I properly access the number property in the search option context so to get Hello?
You're getting undefined there, because apparently this inside source function refers to anonymous function, not to the INPUT you're assigning data to in create function.
Use other means to access input inside source function.
$('#input_id').autocomplete({
create: function (event, ui) {
// when using "this" here, you're refering to #input_id input
},
source: function(request, response) {
// when using "this" here, you're refering to anonymous function
}
});
To access your data within source function use following:
// ...
source: function(request, response) {
// you don't need to wrap this.element in jQuery again since it is already wrapped
this.element.data('custom').property1
}
Demo for future quick reference: http://jsbin.com/ojesig/1/edit
Related
Aim:
I'd like to have two models(sets of data) passed to the custom control with a predefined search field, in which later on I can execute filtering.
I'm a newbie in OpenUi5, so I might be doing something wrong and stupid here. I've started with a simplified task of passing data from the frontend to my custom control and experiencing troubles.
Background of the simplified idea:
Create a custom control with an aggregation foo , the value to it will be provided from the view.
Also create another aggregation element _searchField which will be populated with the data provided from the view.
Fire the onSuggestTerm everytime user types in a _searchField.
Custom control code:
function (Control) {
var DropDownListInput = Control.extend('xx.control.DropDownListInput', {
metadata: {
defaultAggregation: 'foo',
aggregations: {
foo: { type: 'sap.m.SuggestionItem', multiple: true, singularName: 'suggestionItem' },
_searchField: { type: 'sap.m.SearchField', multiple: false, visibility: 'hidden' }
}
}
});
DropDownListInput.prototype.init = function () {
var that = this;
this.onSuggestTerm = function (event) {
var oSource = event.getSource();
var oBinding = that.getAggregation('foo');
oBinding.filter(new sap.ui.model.Filter({
filters: new sap.ui.model.Filter('DISEASE_TERM', sap.ui.model.FilterOperator.Contains, ' Other')
}));
oBinding.attachEventOnce('dataReceived', function () {
oSource.suggest();
});
};
this.setAggregation('_searchField', new sap.m.SearchField({
id: 'UNIQUEID1',
enableSuggestions: true,
suggestionItems: that.getAggregation('foo'),
suggest: that.onSuggestTerm
}));
};
return DropDownListInput;
}, /* bExport= */true);
I'm not providing Renderer function for control here, but it exists and this is the most important excerpt from it:
oRM.write('<div');
oRM.writeControlData(oControl);
oRM.write('>');
oRM.renderControl(oControl.getAggregation('_searchField'));
oRM.write('</div>');
Passing the data to this control from the xml frontend:
<xx:DropDownListInput
id="diseaseTermUNIQUE"
foo='{path: db2>/RC_DISEASE_TERM/}'>
<foo>
<SuggestionItem text="{db2>DISEASE_TERM}"
key="{db2>DISEASE_TERM}" />
</foo>
</xx:DropDownListInput>
The code fails to run with this error Cannot route to target: [object Object] -
and I have no idea what's wrong here..
The problem is that you forgot to provide single quotes in your path:
foo="{path: 'db2>/RC_DISEASE_TERM/'}"
I am using the Polymer framework for my project in which I'm declaring a function callback in properties and trying to call it from another function. But on accessing it I'm getting an error:
Uncaught TypeError: this.callback is not a function
Please have a look into this.
Polymer({
is: "parent-dom",
properties: {
people: {
type: String,
value: "df"
},
item: {
type: String,
value: "asdf",
notify: true
},
callback: {
type: Object,
value: function(index) {
console.log("Inside callback function");
}
},
},
showTargetColorDialog: function(e) {
this.callback("sadf");
}
});
Could you please provide more details about what you would like to achieve, since specify Polymer properties as functions it's not very common case?
So you could declare public methods on your element, like you did with showTargetColorDialog, and they will be accessible to be called like:
document.querySelector('parent-dom').showTargetColorDialog();
But again it's not very "Polymer way" to that.
To answer your original question, if you really need set callback as Polymer property (I'm still not sure why), but you could:
callback: {
type: Object,
value: function() {
return function(index) {
console.log("Inside callback function ", index);
};
}
},
And then you will be able to call this.callback('something');
(function (window, document, $, undefined) {
"use strict";
//we cache a few useful values, like jQuery wrapped window and document
var $window = $(window),
$document = $(document),
ProjectManagement = {
// Cache Properties
cache: {
jsonPromiseCache: {},
},
init: function(){
console.log('ProjectManagement.init() Function ran');
// Call the User module
ProjectManagement.modules.User.populateUserlistJson('test userlistJsonData data');
},
modules: {
User: {},
Milestones: {},
Tasks: {},
},
};
// Run Init on DOM Ready
$(function() {
ProjectManagement.init();
});
}(this, document, jQuery));
Based on this exact code structure above. How could I load an Object with its own similar style functions and properties into this property:
ProjectManagement.modules.User
Something like this would be loaded into the above code where I have ProjectManagement.modules.User ...
(function(){
ProjectManagement.modules.User = {
cache: {
userlistJson: '',
},
init: function(){
console.log('ProjectManagement.modules.User.init() Function ran');
},
populateUserlistJson: function(userlistJsonData){
ProjectManagement.modules.User.cache.userlistJson = userlistJsonData;
console.log('ProjectManagement.modules.User.populateUserlistJson(userlistJsonData) Function ran from ProjectManagement.init()', userlistJsonData);
},
getUsers: function(){
},
};
})();
UPDATE with a JSFiddle Demo
http://jsfiddle.net/jasondavis/cpvsado1/
In the demo I get this error Uncaught TypeError: ProjectManagement.modules.User.populateUserlistJson is not a function - line 44
Line 44 is this: ProjectManagement.modules.User.populateUserlistJson('test userlistJsonData data'); which is inside the ProjectManagement.init() function.
If I try to put the code for ProjectManagement.modules.User above the code for ProjectManagement then I get this error below since my ProjectManagement object hasn't been defined yet:
Uncaught ReferenceError: ProjectManagement is not defined - line 25
Line 25 is the start of the user object code: ProjectManagement.modules.User = {
I am looking for help in modifying the ProjectManagement.modules.User code so that I can access functions and properties from this inside my core ProjectManagement object.
MY real project has about 6,000 lines of code and I do not want to completely change its core structure however the structure for my "modules" can be changed as needed to be able to work in the way I described.
IN my core ProjectManagement object I want to be able to simply load the code into the page for each module and can functions and access property data from these module objects inside my ProjectManagement obnject
Main problem here: ProjectManagement is a local variable, so it can't be access from another function.
You can just add this object to window object, and use as global.
JSFiddle
Also you can just pass this object to function:
(function (window, document, $, undefined) {
"use strict";
//we cache a few useful values, like jQuery wrapped window and document
var $window = $(window),
$document = $(document),
ProjectManagement = {
// Cache Properties
cache: {
jsonPromiseCache: {},
},
init: function(){
console.log('ProjectManagement.init() Function ran');
// Call the User module
ProjectManagement.modules.User.populateUserlistJson('test userlistJsonData data');
},
modules: {
User: {},
Milestones: {},
Tasks: {},
},
};
// Run Init on DOM Ready
$(function() {
ProjectManagement.init();
});
window.ProjectManagement = ProjectManagement;
}(this, document, jQuery));
(function(ProjectManagement){
ProjectManagement.modules.User = {
cache: {
userlistJson: '',
},
init: function(){
console.log('ProjectManagement.modules.User.init() Function ran');
},
populateUserlistJson: function(userlistJsonData){
ProjectManagement.modules.User.cache.userlistJson = userlistJsonData;
console.log('ProjectManagement.modules.User.populateUserlistJson(userlistJsonData) Function ran from ProjectManagement.init()', userlistJsonData);
},
getUsers: function(){
},
};
})(window.ProjectManagement);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
How can I access object properties from functions which will be called as callback function. Please see code below. How can I access config property from processData function which will called when data is received from the server in ajax call.
MyClass: {
config: {
name: "",
id: ""
},
loadData: function() {
MyApi.getData(
this.config,
this.processData, //sucess
this.failureHandler //failure
);
},
processData: function() {
// how to access config object here?
}
}
Probably you can create an anonymous handler function and use call or apply to pass the this scope to actual handler function but is there a better solution than that?
Maybe I am not understanding scoping but in the following:
AisisWriter.Routers.Posts = Backbone.Router.extend({
writer_posts: null,
posts: null,
routes : {
'': 'index'
},
initialize: function() {
this.writer_posts = new AisisWriter.Collections.Posts();
},
index: function() {
var self = this;
this.writer_posts.fetch({
reset: true,
success: function(collection, response, options){
this.posts = collection;
console.log(this.posts);
}
});
console.log(self.posts)
}
});
inside the success: function(){} the this.posts console log has two posts in it. it looks like:
child {length: 1, models: Array[1], _byId: Object, constructor: function, model: function…}
But when I try and use this.posts out side the fetch call, it returns null. Why is that? Is this not scoped properly? or am I doing something wrong?
You are not being able to get access to your this.posts only because it is executed sooner than you get the response. You even don't have to save 'this' in the self variable. To check it just add in the initialize function this line:
this.listenTo(this.writer_posts, 'reset', this.test);
And then create test function:
test: function() { console.log(this.posts); }
As you will see collection is saved properly.
Since your fetch might take time to get into success promise the next line is getting executed sooner before that.
index: function() {
var self = this;
this.writer_posts.fetch({
reset: true,
success: function(collection, response, options){
//write your callback function inside the success
//self.afterSuccess(collection);
}
});
},
You can pass the parameters for the function and fetch it.
afterSuccess: function(collection) {
console.log("the collection has"+JSON.stringify(collection));
}