Jquery UI autcomplete with Json data source - json

I am using jquery UI autocomple with json data source but it's not working but when I used same with fixed data it works. Below is my code.
$(document).ready(function () {
var codes = "";
Admin_BasicFeeSchedule.LoadCPTCodes().done(function (response) {
if (response.status != false) {
if (response.CPTCodeCount > 0) {
var CPTCodeLoadJSONData = JSON.parse(response.CPTCodeLoad_JSON);
$.each(CPTCodeLoadJSONData, function (i, item) {
codes = codes + "'" + item.ShortName + "'";
});
//codes = codes + "]";
alert(codes);
}
}
else {
utility.DisplayMessages(response.Message, 3);
}
});
$.widget("ui.autocomplete", $.ui.autocomplete, {
_renderMenu: function (ul, items) {
var that = this;
$.each(items, function (index, item) {
that._renderItemData(ul, item);
});
$(ul).wrap("<div></div>");
},
});
$("input#ddlCPTCode").autocomplete({
source: [codes],//['Tom', 'Alex', 'Patrick'],
});
});

Based on jQueryUI's API, the source option can either be an array or a String that points to an URL or a Function. Furthermore, your code needs to change few things so that the array is handled in appropriate fashion:
$(document).ready(function () {
var codes = []; // array is created
Admin_BasicFeeSchedule.LoadCPTCodes().done(function (response) {
//alert("LoadCPTCodes works") ;
if (response.status != false) {
//alert("response.status true") ;
if (response.CPTCodeCount > 0) {
//alert("CPTCodeCount > 0") ;
var CPTCodeLoadJSONData = JSON.parse(response.CPTCodeLoad_JSON);
$.each(CPTCodeLoadJSONData, function (i, item) {
codes.push(item.ShortName); //add item to an array
});
//codes = codes + "]";
alert(codes);
}
}
else {
utility.DisplayMessages(response.Message, 3);
}
});
$.widget("ui.autocomplete", $.ui.autocomplete, {
_renderMenu: function (ul, items) {
var that = this;
$.each(items, function (index, item) {
that._renderItemData(ul, item);
});
$(ul).wrap("<div></div>");
},
});
$("input#ddlCPTCode").autocomplete({
source: codes // pass an array (without a comma)
});
});
Finally, if those changes related to the array aren't enough to make it work, then I would check the JSON load part. I have added some alert calls that can be uncommented for JSON testing purposes. As I am not familiar with the details of the JSON load functionality that is used in the sample code, then I'm just going to mention that there are alternative ways of loading JSON data such as jQuery's getJSON method.

Related

How to free up memory when saving images inside IndexDB

I have a no of images on page and trying to save it inside IndexDb if it does not exist.
All seems to be working fine and images load up instantly if it exist but looks like browser memory is leaking. It's give some jerk and hang sometime. I m not sure how this can be handle, I have written a directive that looks like this
(function () {
'use strict';
// TODO: replace app with your module name
angular.module('app').directive('imageLocal', imageLocal);
imageLocal.$inject = ['$timeout', '$window', 'config', 'indexDb'];
function imageLocal($timeout, $window, config, indexDb) {
// Usage:
//
// Creates:
//
var directive = {
link: link,
restrict: 'A'
};
return directive;
function link(scope, element, attrs) {
var imageId = attrs.imageLocal;
// Open a transaction to the database
var transaction;
$timeout(function () {
transaction = indexDb.db.transaction(["mystore"], "readwrite");
getImage();
}, 500);
function getImage() {
transaction.objectStore('mystore').get(imageId)
.onsuccess = function (event) {
var imgFile = event.target.result;
if (imgFile == undefined) {
saveToDb(imgFile);
return false;
}
showImage(imgFile);
}
}
function showImage(imgFile) {
console.log('getting');
// Get window.URL object
var url = $window.URL || $window.webkitURL;
// Create and revoke ObjectURL
var imageUrl = url.createObjectURL(imgFile);
element.css({
'background-image': 'url("' + imageUrl + '")',
'background-size': 'cover'
});
}
function saveToDb() {
// Create XHR
var xhr = new XMLHttpRequest(),
blob;
xhr.open("GET", config.remoteServiceName + '/image/' + imageId, true);
// Set the responseType to blob
xhr.responseType = "blob";
xhr.addEventListener("load", function () {
if (xhr.status === 200) {
console.log("Image retrieved");
// Blob as response
blob = xhr.response;
console.log("Blob:" + blob);
// Put the received blob into IndexedDB
putInDb(blob);
}
}, false);
// Send XHR
xhr.send();
function putInDb(blob) {
// Open a transaction to the database
transaction = indexDb.db.transaction(["mystore"], "readwrite");
// Put the blob into the database
var request = transaction.objectStore("mystore").add(blob, imageId);
getImage();
request.onsuccess = function (event) {
console.log('saved');
}
};
}
}
}
})();

Firefox html5 drag and drop not working

I know there are a lot of similar questions on here, but, when putting them to action, I still resolve in the same problem.
I have 2 angular directives (drag and drop) and one angular factory (dndAPI). This is all based off of fisshy's Angular Drag and Drop on github.
I finally got firefox to accept and drag movement by adding data to the event, however I can't seem to keep it from doing it's default behavior (and loading that data as a url). I also apologize I couldn't get it to work at all on jsfiddle...at all. I'll try again if someone can't see if I'm doing something outrageously wrong.
angular.module('dragAndDrop', [])
.directive('drag',function (dndApi) {
var drags = [],
dragging = new RegExp('(\\s|^)dragging(\\s|$)');
return {
restrict: 'A',
scope: {
item: '=drag',
whenStart: '&',
whenEnd: '&',
dropzones: '='
},
link: function (scope, elem, attr, ctrl) {
elem.bind('dragstart', function (e) {
angular.element('query-tool-tip').removeClass('active');
//if ( drags.length === 0 ) {
drags = document.querySelectorAll('.drop');
//}
angular.forEach(drags, function (value, key) {
if (scope.dropzones.indexOf(value.getAttribute('drop')) >= 0) {
value.className = value.className + ' dragging';
}
});
elem.addClass('dragging');
dndApi.setData(scope.item, scope.dropzones);
e.originalEvent.dataTransfer.effectAllowed = 'move';
//KEEPS FIREFOX FROM CRAPPING OUT:
e.originalEvent.dataTransfer.setData( 'text/plain', 'stop' );
scope.$apply(function () {
scope.whenStart({ data: dndApi.getData() });
});
});
elem.bind('dragleave', function(e){});
elem.bind('dragend', function (e) {
elem.removeClass('dragging');
angular.forEach(drags, function (value, key) {
value.className = value.className.replace(dragging, '');
});
scope.$apply(function () {
scope.whenEnd({ data: dndApi.getData() });
});
dndApi.removeData();
e.preventDefault();
});
elem[0].draggable = true;
elem[0].className = elem[0].className + ' drag';
}
};
}).directive('drop',function (dndApi) {
var drags = [],
dragging = new RegExp('(\\s|^)dragging(\\s|$)');
return {
scope: {
drop: '=drop',
whenDrop: '&',
whenEnter: '&',
whenLeave: '&',
queryIndex: "=queryIndex",
hideElem: '='
},
link: function (scope, elem, attr, ctrl) {
var left = elem[0].offsetLeft,
right = left + elem[0].offsetWidth,
top = elem[0].offsetTop,
bottom = top + elem[0].offsetHeight;
elem.bind('drop', function (e) {
// e.originalEvent.preventDefault();
//if (e.stopPropagation()) {
// e.stopPropagation();
//e.originalEvent.stopPropagation();
//e.preventDefault();
//e.originalEvent.preventDefault();
//}
e.originalEvent.dataTransfer.clearData();
if (dndApi.getDropZones().indexOf(scope.drop) >= 0) {
scope.$apply(function () {
scope.whenDrop({ data: dndApi.getData(), queryI: scope.queryIndex });
});
}
if (drags.length === 0) {
drags = document.querySelectorAll('.drop');
}
angular.forEach(drags, function (value, key) {
value.className = value.className.replace(dragging, '');
});
dndApi.removeData();
e.stopPropagation();
e.originalEvent.stopPropagation();
e.preventDefault();
e.originalEvent.preventDefault();
});
elem.bind('dragenter', function (e) {
e.preventDefault();
e.originalEvent.preventDefault();
if (elem[0] == e.target) {
scope.$apply(function () {
scope.whenEnter({ data: dndApi.getData() });
});
}
return false;
});
elem.bind('dragleave', function (e) {
e.preventDefault();
e.originalEvent.preventDefault();
if ((e.x < left || e.x > right) ||
(e.y < top || e.y > bottom)) {
scope.$apply(function () {
scope.whenLeave({ data: dndApi.getData() });
});
}
return false;
});
elem.bind('dragover', function (e) {
//if (e.preventDefault) {
e.preventDefault();
e.originalEvent.preventDefault();
//}
return false;
});
elem[0].className = elem[0].className + ' drop';
scope.$watch('hideElem', function () {
if (scope.hideElem === true) {
elem.hide();
} else {
elem.show();
}
});
}
};
}).factory('dndApi', function () {
var dnd = {
dragObject: {},
dropzones: []
};
return {
setData: function (data, areas) {
dnd.dragObject = data;
dnd.dropzones = areas;
},
removeData: function () {
dnd.dragObject = null;
dnd.dropZones = [];
},
getData: function () {
return dnd.dragObject;
},
getDropZones: function () {
return dnd.dropzones;
}
};
});
I've done a lot of what's recommended on other questions. I've added event.preventDefault() to the dragenter and dragleave spots. And then when that didn't work I added them everywhere. I have a feeling it has to do with my drop method. If i put event.prevendDefault() at the beginning of the binding, the rest of my code isn't executed.
Any advice, even if it's something small that I might've overlooked, will be helpful.
Thanks!
You are calling e.originalEvent.dataTransfer.clearData(); in the drop event handler which will cause an exception to be thrown (you won't have permission to alter the original dataTransfer object). This is preventing e.originalEvent.preventDefault(); from being called.

knockout js polling not working

I am having difficulty with knockout refreshing.
Here's my viewModel;
$(document).ready(function () {
ko.applyBindings(new Task(), document.getElementById('taskSummary'));
setInterval(Task, 2000);
});
function task(name, description, project) {
var self = this;
self.name= ko.observable(name);
self.description = ko.observable(description);
self.project = ko.observable(project);
}
function Task() {
var self = this;
self.tasks = ko.observableArray([]);
self.tasks.removeAll;
$.getJSON("/api/tasks/5", function (data) {
$.each(data, function (key, val) {
self.tasks.push(new task(val.Name, val.Description, val.Project));
});
});
}
It returns data to the view but does not update when I change the data in the back end database.
any help appreciated. Im sure its something small that I'm missing.
For knockout, it might be better if you apply your model to a new Task instance, save that instance, then set up a setInterval loop that can modify the Task's "tasks" observableArray values.
$(document).ready(function () {
var oTask = new Task();
ko.applyBindings(oTask, document.getElementById('taskSummary'));
function onLoop() {
var self = oTask;
$.getJSON("/api/tasks/5", function (data) {
self.tasks.removeAll(); // not sure if you need this...
$.each(data, function (key, val) {
self.tasks.push(new task(val.Name, val.Description, val.Project));
});
});
}
setInterval(onLoop, 2000);
});

Backbone using external js

Hi all I have a site developed in cakephp and I would to integrate backbone on it.
For my scope I would to use external js for backbone to reuse the code.
I have write some lines but I can't append results on my element.
I have tried to print the "el" in this modes:
console.log($(this.el));
console.log(this.el);
console.log(this.$el);
But nothing I can't enter into el to make a simple append!
The container #search-results already exist
This is my main view:
<script type="text/javascript">
var search = {};
search.product = {};
search.product.template = "#results-product-template";
search.product.container = "#search-results";
search.product.defaults = {
id:0,
type:"product",
};
$(function(){
var ProductList = new Search.Collections.Products();
var ProductView = new Search.Views.Product({
// new Search.Collections.Products();
collection:ProductList
,el:$("#search-results")
});
function parseResults () {
var json = {
//my data
}
for (var i = json.products.length - 1; i >= 0; i--) {
ProductList.add([new Search.Models.Product(json.products[i])]);
};
updateResults();
}
function updateResults () {
console.log('updateResults: Ritorno il risultato quando hunter riceve una risposta dal server');
if ($('#search-results').length == 0) {
$('div.main > section:first-child').before('<section id="search-results"> <ul id="product-results"> <li>Contenuto</li> </ul> </section>');
}
ProductView.render();
}
// search
$('#search-results .close').on('click', function () {
$('#search-results').animate({height:0}, 500, function () {
$(this).remove();
})
});
});
</script>
And this is my external js with backbone
var Search = {
Models: {},
Collections: {},
Views: {},
Templates:{}
}
Search.Models.Product = Backbone.Model.extend({
defaults: search.product.defaults || {},
toUrl:function (url) {
return url.replace(" ", "-").toLowerCase();
},
initialize:function () {
console.log("initialize Search.Models.Product");
this.on("change", function (){
console.log("chiamato evento change del Model Search.Models.Product");
});
this.on("change:text", function () {
console.log("chiamato evento change:text del Model Search.Models.Product");
});
}
});
Search.Collections.Products = Backbone.Collection.extend({
model: Search.Models.Product,
initialize:function () {
console.log("initialize Search.Collections.Products");
console.log(this);
console.log(this.length);
console.log(this.models);
}
});
Search.Views.Product = Backbone.View.extend({
initialize:function () {
console.log("initialize Search.Views.Product");
console.log($(search.product.template).html());
},
template:function (data) {
if (data == null) {
data = this.collection.toJSON();
}
var template = Handlebars.compile($(search.product.template).html());
template(data);
},
render:function () {
console.log($(this.el));
$(this.el.append("TEST"));
//HERE IS THE PROBLEM
// I have tried this.$el.append("TEST");
return this;
}
});
Does this change anything?
var ProductView = new Search.Views.Product({
// new Search.Collections.Products();
collection:ProductList,
el:$("#search-results")[0]
});
I think backbone can accept both jQuery wrapped or not wrapped object and be fine, but I don't know what Backbone version you are using, see if this works
EDIT: From backbone 1.0 sources, it seems backbone can indeed take either a jQuery wrapped object or a regular dom element, it should still work
this.$el = element instanceof Backbone.$ ? element : Backbone.$(element);
Do you have something online (JSFiddle?) I will be happy to take a look, but this.$el should work and be equal to $("#search-results") from your code in a quick glance.
Have you tried using ProductView.setElement($("#search-results")) instead? it should be the same, but worth a try as well.

HTML FileReader

function fileSelected() {
// get selected file element
var files = document.getElementById('files[]').files;
for (var i = 0; i < files.length; i++) //for multiple files
{
(function (file) {
var fileObj = {
Size: bytesToSize(file.size),
Type: file.type,
Name: file.name,
Data: null
};
var reader = new window.FileReader();
reader.onload = function (e) {
fileObj.Data = e.target.result;
};
// read selected file as DataURL
reader.readAsDataURL(file);
//Create Item
CreateFileUploadItem(fileObj);
})(files[i]);
}
}
function CreateFileUploadItem (item) {
console.log(item);
$('<li>', {
"class": item.Type,
"data-file": item.Data,
"html": item.Name + ' ' + item.Size
}).appendTo($('#filesForUpload'));
}
So when console.log(item) gets run in the CreateFileUploadItem function it shows the item.Data. YET it won't add it to the data-file of the LI. Why is that?
The call to readAsDataURL is asynchronous. Thus, the function call is likely returning prior to the onload function being called. So, the value of fileObj.Data is still null when you are attempting to use it in CreateFileUploadItem.
To fix it, you should move the call to CreateFileUploadItem into your onload function. As for the console logging the proper value, you can't rely on that being synchronous either. I think using a breakpoint during debugging at that line instead will likely show the true null value.