Jquery Mobile Autocomplete JS Function as Source - javascript

I am trying to implement jquery mobile autocomplete plugin. The sample usage as mentioned below.
I want to set a Javascript function for the source parameter, and want to make some database queries in that and return information to the page.
How can I do that? Or is there any other way that I can achieve what I want?
$("#searchField").autocomplete({
target: $('#suggestions'),
//Source is either
source: 'data.cfc?method=search&returnformat=json&data=simple'
//or a js object
//autocompleteData = $.parseJSON('[{"value":"1.0","label":"Alabama"},{"value":"2.0","label":"Alaska"}]');
source: autocompleteData
});

You can just pass a function to the source. Though it appears to not be documented, digging through the source code (around line 100) you can see that they can take a function for the source option.
They have a quick example in the comments of the source:
source:function(text,callback) { mydata = [1,2]; callback(mydata); }
It appears to work almost exactly the same as the regular jQuery autocomplete, where the first parameter is the text in the box and you call the second parameter and pass it your filtered data.

Related

What's the correct way to send Javascript code along with rendered HTTP to a client?

Mid development I decided to switch to server-side rendering for a better control amongst other benefits. My web application is completely AJAX based, no url redirecting, so the idea here is a website that builds itself up
I just couldn't figure out the proper way to send javascript events/functions along with the html string, or should all the necessary javascript always be preloaded in the static files?
Let's say client clicks a pre-rendered button 'open table'
The server will make a query, build the html table and send it back, but this table also needs javascript triggers and functions to work properly, how are these sent, received and executed?
There are a couple of articles that mention to not use eval() in Javascript, is there any way around this? I don't want to have to preload unnecessary events for elements that don't yet exist
The server is Python and the Client is Javascript/JQuery
Theoretical example :
Client Base Javascript :
$("body").on("click", "#open_table", function() {
$.getJSON('/get_table', function(response){
$("#table_div").append(response.html);
eval(response.javascript()); //??
}
});
Python Server(views.py) :
def get_table(request):
data = {}
#String containing rendered html
data['html'] = get_render_table()
#String containing Javascript code?
data['javascript'] = TABLE_EVENTS_JAVASCRIPT
return HttpResponse(json.dumps(data),content_type='json')
Worth noting my question comes from an experimental/learning perspective
Update:
You can use jQuery.getScript() to lazy load JS. I think this solution is as close as you can get to run JS without using eval().
See this example:
jQuery.getScript("/path/to/script.js", function(data, textStatus, jqxhr) {
/* Code has been loaded and executed. */
console.log( data ); // Data returned
console.log( textStatus ); // Success
console.log( jqxhr.status ); // 200
console.log( "Load was performed." );
});
and "/path/to/script.js" could be a string returned from $.getJOSN response.
Also, the documentation for getScrippt() has examples on how to handle errors and cache files.
Old Answer:
Using .on() attaches events to current and future DOM elements.
You can either attache events prior to DOM insertion or attache event after DOM insertion.
So in your example you can do something like:
$("body").on("click", "#open_table", function() {
$.getJSON('/get_table', function(response){
var code = $(response.html);
code.find(".elementToFind").on("click", function (){
// Code to be executed on click event
});
$("#table_div").append(code);
}
});
I did not test the code but I think it should work.
Assuming you can't just set up an event-binding function and then call it from the main script (the JavaScript you need can't be guessed ahead of time, for example) then one really easy way is just to append the JavaScript to the bottom of the returned HTML content within script tags. When it's appended along with the HTML, the script should simply execute, with no eval() required.
I can't swear that this would work in old browsers, but it's a trick I've used a couple of times, and I've had no problems with it in Firefox, Chrome, or any of the later IE versions.
I think I see what you're asking here, from my understanding you want to send the new "page" asynchorously, and render the new javascript and html. It looks like you already got your request/response down, so i'm not gonna go and talk about sending JSON objects, and the whole "how-to" of sending html and javascript because it looks like you got that part. To do what you want and to dynamically add your javascript in, this stackoverflow question looks like it has what you need
Is there a way to create a function from a string with javascript?
So pertaining to your example, here is how it would look when you recieve the JSON string from your python script:
$("body").on("click", "#open_table", function() {
$.getJSON('/get_table', function(response){
$("#table_div").append(response.html);
/* Create function from string */
var newFunction = Function(response.javascript['param_1'], response.javascript['param_2'], response.javascript['function']);
/* Execute our new function to test it */
newFunction();
}
});
*Your actual function contents would be the string: response.javascript['function']
*Your parameter names if any would be in separate strings ex: response.javascript['param_1']
That is almost a direct copy of the "String to function" code that you can see in the linked question, just replaced it with your relevant code. This code is also assuming that your object is sent with the response.javascript object containing an array with your actual function content and parameter names. I'm sure you could change the actual name of the var too, or maybe put it in an associative array or something that you can keep track of and rename. All just suggestions, but hopefully this works for you, and helps you with your problem.
I am also doing similar work in my project where I had to load partial html using ajax calls and then this partial HTML has elements which requires events to be attached. So my solution is to create a common method to make ajax calls and keep a js method name to be executed post ajax call in html response itself. For example my server returns below html
<input type="hidden" data-act="onPartialLoad" value="createTableEvents" />
<div>.........rest of html response.....<div>
Now in common method, look for input[type='hidden'][data-act='onPartialLoad'] and for each run the method name provided in value attribute (value="createTableEvents")
Dont Use Eval() method as it is not recommended due to security
issues. Check here.
you can run js method using window["method name"]...so here is a part of code that I use.
$.ajax(options).done(function (data) {
var $target = $("#table_div");
$target.fadeOut(function () {
$target.html(data);
$target.fadeIn(function () {
try {
$('input[data-act="onPartialLoad"]', $target).each(function () {
try {
//you can pass parameters in json format from server to be passed into your js method
var params = $(this).attr('params');
if (params == undefined) {
window[$(this).val()]();
}
else {
window[$(this).val()]($.parseJSON(htmlutil.htmlDecode(params)));
}
} catch (e) {
if (console && console.log) {
console.log(e.stack);
console.log($(this).val());
}
}
});
}
catch (e) {
console.log(e.stack);
}
});
});
});
use jQuery.getScript() (as suggested by Kalimah Apps) to load the required js files first.

Calling a jQuery autocomplete widget function based on variable name

So to initialize autocomplete for a textbox, you do this $('#textbox').autocomplete({...});
I have a custom widget declared:
$.widget( "custom.catcomplete", jQuery.ui.autocomplete, {
......
});
In this case the widget's name is catcomplete, so to initialize a custom autocomplete, you can do this: $('#textbox').catcomplete({...});
Now comes the tricky part. I'm trying to call $('#textbox').catcomplete({...}); using a variable name, in this way:
var w = 'catcomplete';
//this is where i try to call the widget
$('#textbox').{w}({...}); // <-- this is obviously wrong
While the example is obviously wrong, but I hope it gives a generally good idea of what I'm trying to do. By the way the widget cannot be modified (legacy issues).
Thanks in advanced!
This simple code works to call jQuery.find method (get the first div inside the body):
$('body')['find']('div:first')
So, the solution for you should be something like this:
$('body')[yourVariable]({...})

Dojo Gridx programattic refresh shows no data

I am trying to create a programmatic filter. I have a dijit.tree and a dojo gridx using the same source on a jsp. When user clicks the tree node, I want to use the node as a filter and show all rows matching it in the gridx
This is my code I have now for the onClick event of the dijit tree node.
var global=this;
treeWidget.onClick = function(item){
global.grid.filter.setFilter(global.grid.filter.grid.filter.moduleClass.or("test"));
Earlier I asked for a sample expression. I went and tried the code above and seems to
refresh the grid but comes back as No items to display. I do have data that match test and if I do a manual filter I see data returning. What am I missing here.
At https://github.com/oria/gridx/wiki/How-to-filter-Gridx-with-any-condition%3F ( see Filter Expressions)
I was able to accomplish the task using the following code in the diji.tree onClick event.
global.grid.filterBar.applyFilter({
conditions: [{
condition: 'contain',
value: 'test'
}]
});
This is a comment rather than an answer, but I can't post comments yet.
Can you post a working snippet of code? That's not complete, as I don't see your store that you're specifying, etc.
I usually do a myinstancename.grid.body.refresh(); to accomplish a proper refresh.

How to add an EventSource details page for Fullcalendar

I'd like to add a EventSource detail page to Adam Shaw's Fullcalendar. A use case for this page is that the user wants to change the URL of the source or change the color of the events belonging to this source. For now I am blocked by the fact that I don't know exactly how to retrieve the source object. Part of the problem is that as far as I know, sources do not have an ID.
Which is the proper function in which I should inject the EventSourceID into the source object?
Should this function be something similar to the addEventSource from $ROOT/src/common/Views.js?
UPDATE: I changed the text in question the source to EventSource, to make it clear. Also now I have one solution in my mind, let me know if it's intrusive:
make sure each source object has an ID property set. This could be done by adding a source normalizer function to fc.sourceNormalizers array.
create retrieveEventSource which takes an EventSourceID as an argument and returns the source. The implementation this would be similar to _addEventSource.
UPDATE: Already found a problem, function retrieveEventSource is private and I don't know how to expose it to the world outside FullCalendar. Also, I have no idea yet on how to implement the update function that should redraw /AND/OR/ refetch the events, after the source details have changed.
Well since you're the one that populates the calendar event data in the first place just use that data on the new page.
events: function (start, end, callback) {
$.ajax({
url: url,
data: "json-events.php",
success: function (data) {
callback([event0,event1,event2,.....])
},
dataType: /* xml, json, script, or html */
});
...
Just get the data on the other page outside the calendars api

How to parse JSON created by WCF DataContract object

I have an object decorated with [DataContract] attribute and my WCF service is returning this as JSON like this:
{"GetCommentsByPostResult":[{"CommentCreated":"\/Date(1305736030505+0100)\/","CommentText":"Comment 1"},{"CommentCreated":"\/Date(1305736030505+0100)\/","CommentText":"Comment 2"},{"CommentCreated":"\/Date(1305736030505+0100)\/","CommentText":"Comment 2"}]});
Ive attempted to iterate through the CommentCreated with this jQuery code:
$(data).each(function ()
{
alert(this.CommentCreated);
});
But all I get is an alert box with 'undefined in' so I changed it to:
$(data).each(function () {
$(this.GetCommentsByPostResult).each(function () {
alert(this.GetCommentsByPostResult);
});
});
but that still doesnt work. What I want to do is iterate the CommentCreated and throw them to an alert box....
I'm not sure, but I don't think this would be the current element when calling each. Also, why are you wrapping the data variable with the jQuery function? jQuery collections are for DOM elements.
$.each(data.GetCommentsByPostResult, function (e) {
alert(e.CommentCreated);
});
Depending on how you are acquiring the data (a library? custom code?) you will most likely have to convert the JSON string first into an actual JavaScript object. Many browsers have built in methods for doing this, though you may need to take advantage of a 3rd party library to take advantage of those that do not have out-of-box support. I would recommend JSON-js as it follows the same syntax as those found built into some browsers.
var obj = JSON.parse(data);
Once you have this object, you can now access the data with standard JavaScript dot or bracket notation:
var comments = obj.GetCommentsByPostResult; // or...
var comments = obj['GetCommentsByPostResult'];
Those two lines are equivalent. To iterate the comments, as you are trying to do, you could try:
$.each(obj.GetCommentsByPostResult, function (e) {
alert(e.CommentCreated);
});
Also, I would recommend using console.log() instead of alert(), and a browser that supports inspection of the logged objects. This would be FireFox with the Firebug extension, or Chrome with their developer tools (Ctrl-Shift-J to activate). Not sure about the status of this type of tool in IE9, though I would not be surprised if there was an equivalent tool there as well.

Categories