CakePhp sending response as Json and displaying it - cakephp

i am trying to auto complete department using jquery autocomplete library.
ajax call is as follows
$( "#auto_complete" ).autocomplete({
source: function( request, response ) {
$.ajax({
url: "/employees/getDepartment"
dataType: "jsonp",
//dataType: "text/html",
data: {
featureClass: "P",
style: "full",
maxRows: 12,
name_startsWith: request.term
},
success: function( data ) {
alert("success--");
response( $.map( data.geonames, function( item ) {
return {
label: item.name,
value: item.id
}
}));
}
});
},
minLength: 2,
select: function( event, ui ) {
log( ui.item ?
"Selected: " + ui.item.label :
"Nothing selected, input was " + this.value);
},
open: function() {
$( this ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" );
},
close: function() {
$( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
}
});
my controller has a action called getDepartment is as follows:
public function getDepartment() {
$this->log($this->params->query['name_startsWith'] , 'debug');
$str = $this->params->query['name_startsWith'];
$this->log($str, 'debug');
$name='Departmet';
$this->layout = 'ajax';
$departments = $this->Employee->Department->find('all', array( 'recursive' => -1,
'conditions'=>array('Department.name LIKE'=>$str.'%'),
'fields'=>array('name', 'id')));
$this->set('departments',$departments);
}
here i need to send the $departments as Json .
how to send the response as JSON
why controller is not reaching autocomplete success function (where i have put an alert)
when i run i get response (using fireBug) as
[{"Department":{"name":"Testing","id":"1"}},{"Department":{"name":"Testing","id":"3"}},{"Department":{"name":"Testing2","id":"6"}},{"Department":{"name":"testing","id":"7"}},{"Department":{"name":"test","id":"8"}}]

Your response is valid JSON and so your dataType must be too.
dataType: "json"

Related

asp.net web api call custom method using angularJS

i have a angularJS controller where i put a kendo cascade dropdownlist.For dropdown list value ,on kendo dataSource read i am calling the web api service.
For the first field the api GetDivisions() has been called and it response also but for the 2nd value the GetCascadeDistrict() method not called the GetDivisions() method called again. How can i solve this.Need Help
here's the angular Controller with kendo cascade dropdownlist.
app.controller("filterCtrl", function($scope, $sce,$http) {
var i;
$scope.dashImgSrc = $sce.trustAsResourceUrl('Content/Images/Bangladesh_Govt.gif');
$(document).ready(function () {
var divisions = $("#divisions").kendoComboBox({
filter: "contains",
placeholder: "select a divisions...",
dataTextField: "Name",
dataValueField: "Id",
animation: {
close: {
effects: "zoom:out",
durations:250
}
},
dataSource: {
type: "json",
serverFiltering: true,
transport: {
read: "api/AreaService/GetDivisions()"
}
},
change: function () {
i = divisions.value();
alert("1st hit"+i);
}
}).data("kendoComboBox");
var districts = $("#districts").kendoComboBox({
autoBind: false,
cascadeFrom: "divisions",
filter: "contains",
placeholder: "select a district",
dataTextField: "Name",
dataValueField: "Id",
dataSource: {
type: "json",
serverFiltering: true,
transport: {
read: function () {
alert("2nd hit");
//$http.get("/api/AreaService/GetCascadeDistrict(i)").success(function() {
// alert("Hit the district api");
//}).error(function() {
// alert("Error");
//});
$http({ method: "GET", url: 'api/AreaService/GetCascadeDistrict(i)' }).
success(function() {
alert("Actually it hit the custome get method");
}).
error(function() {
alert("Not hit or other problem");
});
}
}
}
}).data("kendoComboBox");
var upazila = $("#upazila").kendoComboBox({
autoBind: false,
cascadeFrom: "districts",
filter: "contains",
placeholder: "select a upazila...",
dataTextField: "Name",
dataValueField: "Id",
dataSource: {
type: "json",
serverFiltering: true,
transport: {
read: function() {
$http.get("/api/AreaService/GetCascadeDistrict(i)").success(function() {
}).error(function() {
});
}
}
}
}).data("kendoComboBox");
$("#get").click(function () {
var divisionInfo = "\Division: { id: " + divisions.value() + ", name: " + divisions.text() + " }",
districtInfo = "\nDistrict: { id: " + districts.value() + ", name: " + districts.text() + " }",
upazilaInfo = "\nUpazila: { id: " + upazila.value() + ", name: " + upazila.text() + " }";
alert("Road details:\n" + divisionInfo + districtInfo + upazilaInfo);
});
});
});
And the Web api is here
public class AreaServiceController : ApiController
{
private readonly AreaFilterManager _db = new AreaFilterManager();
[System.Web.Http.HttpGet]
public IEnumerable<Division> GetDivisions()
{
return _db.GetDivisions();
}
[System.Web.Http.HttpGet]
public IEnumerable<District> GetCascadeDistrict(int? division)
{
return _db.GetCascadeDistrict(division);
}
[System.Web.Http.HttpGet]
public IEnumerable<Thana> GetCascadeUpzilla(int? district)
{
return _db.GetCascadeThana(district);
}
}
You'll need to separate/distinguish your calls by CRUD operations or by Attribute Routing depends your WebApi version your using in your project.
You cannot use the same CRUD HttpGet twice in the same Class/Controller without putting a different routing attribute.
You need to remember, in WebApi the methods are not being called by their names like in regular programming, therefore the WebApi Class/Controller doesn't know which method you meant to call from your Client (in your case).
That's why you'll need to:
WebApi Ver 1 : separate/distinguish your calls by CRUD operations.
WebApi Ver 2 : separate/distinguish your calls by Attribute Routing.

Facebook Javascript SDK - getLoginStatus callback never called

I'm having all sorts of fun issues with the Facebook API (which is so simple, this has driven me nuts). I'm trying to login to Facebook using their requireJS approach.
When attempting to get the login status while first opening the app, the callback is never fired indicating if a user is logged in or not.
I have to keep clearing cookies to even get the login page to popup - and once I do login to Facebook, the login popup says redirecting at the top and is just white.
define([
'jquery',
'underscore',
'backbone',
'facebook',
'../models/session',
'template!../../../html/appView',
'./searchView'
], function( $, _, Backbone, Facebook, SessionModel, AppViewTemplate, SearchView ) {
'use strict';
return Backbone.View.extend({
id: 'app-view',
searchViews: {},
views: {},
events: {
'click #btn-fb-login' : 'loginWithFacebook'
},
initialize: function() {
this.listenTo( this.model, 'change', this.render, this );
this.searchView = new SearchView();
FB.init({
appId : 'My App ID',
status : true,
version : 'v2.3'
});
this.checkLoginState( true );
},
render: function() {
console.log( 'rendering' );
AppViewTemplate.renderToView( this );
this.$( '#header' ).append( this.searchView.render().$el );
return this;
},
loginWithFacebook: function() {
FB.login(function (response) {
console.log( response );
if ( response.authResponse ) {
console.log('Fetching authResponse information.... ');
} else {
}
}.bind( this ), {
scope: 'email'
});
},
checkLoginState: function( checkOnly ) {
console.log( FB );
FB.getLoginStatus( function( response ) {
console.log('response:', response);
clearInterval( timer );
if (response.status === 'connected') {
// Logged into your app and Facebook.
console.log( 'LOGGED IN!' );
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
} else {
if ( !checkOnly ) {
this.loginWithFacebook();
}
}
}.bind( this ) );
}
});
});
In my main view I was rendering to body - which was removing fb-root (after facebook had already checked if it existed, so it never created it itself).

Payload Empty when Passing in Non-Restful Action in Backbone

How do I pass in data when I need to POST to a non-restful action within the Model?
For Example...
module.exports = Base.extend( {
url: {
'create': '/sites/:site_id/footer',
'update': '/sites/:site_id/footers/:activity',
'copy': '/sites/:site_id/:language/:label/footer/copy',
'delete': '/sites/:site_id/footer/:id'
},
api: 'service',
copy: function () {
var new_label = this.get( 'label' ) + ' Copy';
return this.save( {}, {
type: 'POST',
url: this._getUrl( 'copy' ),
data: JSON.stringify( {
action: 'copy',
label: new_label
} )
} );
}
} );
Problem is that whenever we pass in the data... payload only shows 'action'. Label is completely ignored.
Try this instead:
copy: function () {
var new_label = this.get( 'label' ) + ' Copy';
return this.sync(
'create',
this,
{
url: this._getUrl( 'copy' ),
attrs: {
action: 'copy',
label: new_label
}
}
);
}
This is basically the magic behind the save function without all the auto collection the data to send. Note the if you use the attrs key in the options then you don't need to stringify the data yourself as it will be done for you in the sync method.

Issue with my custom select2 directive for angularjs

I have created custom select2 directive for angular it works perfect for my usecase and works like charm when i use template and it sets and get the values from input/ngModel
but when i use it on view page it do not resolve ngModel via scope.$eval
this is something scope issue please help me on this
please find directive mentioned below:
(function () {
'use strict';
var directiveId = 'snSelect2';
angular.module('app').directive(directiveId, ['datacontext', snSelect2]);
function snSelect2(datacontext) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, controller) {
var urlPrefix =datacontext.urlPrefix;
$(function () {
element.select2({
placeholder: element.attr('placeholder'),
multiple: angular.isDefined(attrs.multiple),
minimumInputLength: 3,
blurOnChange: true,
ajax: { // instead of writing the function to execute the request we use Select2's convenient helper
url: urlPrefix + "/Employees",
dataType: 'json',
data: function (term) {
return {
term: term
};
},
results: function (data) { // parse the results into the format expected by Select2.
// since we are using custom formatting functions we do not need to alter remote JSON data
return { results: data };
}
},
initSelection: function (element, callback) {
var id = scope.$eval(attrs.ngModel);//$(element).val();
if (id != "") {
$.ajax(urlPrefix + "/EmployeeById",
{
data: {
id: id,
format: 'json'
},
datatype: 'json'
}).done(function (data) {
if (angular.isDefined(attrs.multiple)) {
callback(data);
}
else {
callback(data[0]);
}
});
}
//var data = {id: element.val(), text: element.val()};
//callback(data);
},
dropdownCssClass: "bigdrop", // apply css that makes the dropdown taller
escapeMarkup: function (m) { return m; } // we do not want to escape markup since we are displaying html in results
}).select2('val', scope.$eval(attrs.ngModel))
.on("change", function (e) {
scope.$apply(function () {
controller.$setViewValue(attrs.ngModel);
});
});
element.bind("change", function (e) {
scope.$apply(function () {
scope[attrs.ngModel] = e.val;
});
});
});
}
}
}})();
http://snag.gy/lcizI.jpg
<!-- html element -->
<input type="hidden" class="form-control" data-ng-model="show" ui-select2="getShow">
$scope.getShow = {
placeholder: "Enter Show Code",
minimumInputLength: 3,
escapeMarkup: function (m) { return m; },
formatSelection: function(obj, container) {
return "ID: " + obj.showid + " - " + obj.name;
},
formatResult: function(obj, container, query) {
var start = obj.startdate ? moment(obj.startdate).format("DD/MM/YYYY") : "Unknown";
var end = obj.enddate ? moment(obj.enddate).format("DD/MM/YYYY") : "Unknown";
return '<div class="list-group-item small">' +
'<i><span class="label label-default pull-right">ID: ' + obj.showid + '</span></i>' +
'<i><span class="label label-info">(' + obj.code + ')</span></i>' +
'<div style="padding-top: 4px"><strong>' + obj.name + '</strong></div>' +
'<i>' + start + " - " + end + '</i>' +
'</div>';
},
query: function(options) {
if (!options.context)
options.context = {};
// status == processing means http request is in process, so don't do it again
if (options.context.status === "processing")
return;
options.context.status = "processing";
// this is just like ajax $http.get("/search").
model.show.search("search", {code: options.term, limit: 10, sort: 'ts desc'} )
.then(function(result) {
// set status = completed to indicate http request finished.
options.context.status = "completed";
// when you get the result from ajax, callback require you to call with
// an object { results: your result } as result
$scope.list.datalist.show = result;
options.callback({
results: result
});
});
}
}
Data from server looks like
[{
code: "MELCCS"
enddate: "2014-03-10T14:00:00.000Z"
id: "5329c28087b375a4d8a2af43"
name: "Melbourne Caravan and Camping Show"
openinghour: ""
showid: 1810
startdate: "2014-03-05T14:00:00.000Z"
state: "VIC"
status: "Research"
ts: 1395245779280
updatedAt: "2014-03-21T09:16:56.859Z"
warehouse: "52ecd53b673a5fba428e21a7"
}]

Backbone view pass value to another view

MenuView.js
events: {
"click ul li": "MenuClick"
},
MenuClick: function (e) {
var elm = e.currentTarget;
return elm.firstChild.innerText;
},
ModuleView.js
ModuleView = Backbone.View.extend({
initialize: function () {
var moduleDt = new ModuleCol();
moduleDt.fetch({
data: JSON.stringify({ Code: "Pass to here" }),
dataType: "json",
type: 'POST',
contentType: "application/json; charset=UTF-8"
});
},
The code should work like, when clicking the ul li, I will get the value from the li and pass to the moduleView.js to proceed with backbone fetch, but I dont have any idea on how actually to make it, I had search through quite some link, but still can't figure out the correct, are it is correct to make it?
Update1:
View/MenuView.js
define(['underscore', 'backbone', '../Collection/MenuCol'], function (_, Backbone, MenuCol) {
var MenuView = Backbone.View.extend({
initialize: function () {
//var vent = _.extend({}, Backbone.Events);
var mnCol = new MenuCol();
mnCol.fetch({
type: 'POST',
contentType: "application/json; charset=UTF-8",
success: _.bind(this.AppendMenu, this),
});
},
AppendMenu: function (msg) {
var feed = JSON.parse(JSON.stringify(msg));
//var title = _.pluck(_.flatten(feed[0]), "Title");
_.each(_.flatten(feed[0]), function (data) {
this.$('ul').append('<li class="inactive"><p class="none">' + data.Code + '</p><a>' + data.Title + ' </a></li>');
});
},
events: {
"click ul li": "MenuClick"
},
MenuClick: function (e) {
var elm = e.currentTarget
console.log(elm.firstChild.innerText);
this.trigger('itemChoose', elm.firstChild.innerText);
},
});
return MenuView;
});
View/ModuleView.js
define(['underscore', 'backbone', 'datatables', '../Collection/ModuleCol', '../View/MenuView'], function (_, Backbone, dataTable, ModuleCol, MenuView) {
var ModuleView = Backbone.View.extend({
initialize: function () {
//MenuView.vent.on('itmChoose');
MenuView.on('itemChoose', function (item_value) { });
var mdCol = new ModuleCol();
mdCol.fetch({
data: JSON.stringify({ Code: "" }),
type: 'POST',
contentType: "application/json; charset=UTF-8",
success: _.bind(this.AppendModule, this),
});
},
AppendModule: function (msg) {
var feed = JSON.parse(JSON.stringify(msg));
$('table[id$=gvMenu]').dataTable({
"bAutoWidth": false,
"aoColumns": [
{ "sWidth": "10%" },
{ "sWidth": "90%" },
],
"bFilter": false,
"bInfo": false,
"bLengthChange": false,
"bSort": false,
"bPaginate": false,
"aLengthMenu": [
[25, 50, 100, 200, -1],
[25, 50, 100, 200, "All"]
],
"iDisplayLength": -1,
"aoColumns": [
{
"sTitle": "Code", "mDataProp": "Title",
},
{
"sTitle": "Description", "mDataProp": "Description",
}],
sAjaxSource: "",
sAjaxDataProp: "",
fnServerData: function (sSource, aoData, fnCallback) {
//console.log(feed.d);
//fnCallback(feed.d);
},
});
}
});
//MenuView.on('itmChoose', function (item_value) { });
return ModuleView;
});
master.js
require(['jquery', '../JScripts/View/MenuView', '../JScripts/View/ModuleView'], function ($, menu, module) {
$(document).ready(function () {
new menu({ el: $('#sidebar') });
new module({});
});
});
This is my code, but still, it is correct to code like this? I had spent a night to work it out, but it still say is undefined.
When li click, I get the value of the li, and pass to module.js to ajax data so that I can create datatable.
I continue to puzzle it out and see if I can make it today while waiting for your guide :) thanks
According your updates, you must supply instance of MenuView to ModuleView instance:
master.js:
require(['jquery', '../JScripts/View/MenuView', '../JScripts/View/ModuleView'], function ($, menu, module) {
$(document).ready(function () {
var menuInstance = new menu({ el: $('#sidebar') });
new module({menu: menuInstance});
});
});
ModuleView.js:
var ModuleView = Backbone.View.extend({
initialize: function (options) {
//MenuView.vent.on('itmChoose');
options.menu.on('itemChoose', function (item_value) { });
var mdCol = new ModuleCol();
mdCol.fetch({
data: JSON.stringify({ Code: "" }),
type: 'POST',
contentType: "application/json; charset=UTF-8",
success: _.bind(this.AppendModule, this),
});
},
If your ModuleView and MenuView are equal components of system - pick out in your code some central component (e.g. descendant Backbone.Router) and make communication through it.
If your views aren`t equal components (e.g. ModuleView aggregates MenuView), you can subscribe on some event from MenuView in ModuleView and pass value:
//in ModuleView
menuView.on('itemChoosen', function(item_value) { .... });
//in MenuView
MenuClick: function (e) {
var elm = e.currentTarget;
this.trigger('itemChoosen', elm.firstChild.innerText);
},

Resources