I have a toggle button I've created with a custom directive for "likes". Its using a JSON field with a true/false. The field is is_liked. I've got the toggle portion set up just fine, but I'm having some trouble checking to see wether the field is true or false before adding the toggle.
I need to somehow check to see if the field is already true/false so that button can show wether its already checked or not. Right now the toggle always starts off as unchecked regardless of if the field has been checked or not. Hopefully I'm explaining this well enough. My directive looks like this..
/*jshint unused:false */
/*global _:false */
/*global $:false */
'use strict';
angular.module('hscApp')
.directive('likes' ,['$http',function ($http)
{
return {
restrict: 'A',
scope: { event: '=' },
template: '<div ng-click="togglelike()">'+
'<a ng-hide="isliked"><i class="icon-star"></i>Like</a>'+
'<a ng-show="isliked"><i class="icon-star">Unlike</i></a>'+
'</div>',
link: function($scope){
$scope.isliked = $scope.event.is_liked;
$scope.togglelike = function(){
$scope.eventid = $scope.event.id;
$scope.classes = $scope.event.class;
if ($scope.isliked){
var url = 'http://www.test.com/api/v1/user_favorites/0.json';
var del = $.param({listing_type: $scope.classes, listing_id: $scope.eventid, _method: 'delete'});
$http({
method: 'POST',
url: url,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: del
});
}
else {
var urls = 'http://www.test.com/api/v1/user_favorites.json';
var dels = $.param({listing_type: $scope.classes, listing_id: $scope.eventid});
$http({
method: 'POST',
url: urls,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: dels
});
}
$scope.isliked = !$scope.isliked;
};
}
};
}]);
So on each page load the like button will always start out as Like even if it has already been liked and should be showing Unlike. How do I check to see what state the button is currently in and apply the correct toggle action to it?
You can store a variable on the scope rather than the $scope when your directive loads
.directive('likes' ,['$http',function ($http)
{
return {
restrict: 'A',
scope: { event: '=',
isLikedLocal: "=" // can pass this in as a param, otherwise you can make it one way data bound using # instead of =
},
template: '<div ng-click="togglelike()">'+
'<a ng-hide="isLikedLocal"><i class="icon-star"></i>Like</a>'+
'<a ng-show="isLikedLocal"><i class="icon-star">Unlike</i></a>'+
'</div>',
link: function($scope){ // use function link(scope, element, attrs) instead for consistency
scope.isLikedLocal= $scope.event.is_liked;
$scope.eventid = $scope.event.id;
$scope.classes = $scope.event.class;
scope.togglelike = function(){
if (scope.isLikedLocal){
unlike();
}
else {
like();
}
scope.isLikedLocal= !scope.isLikedLocal;
}
function unLike(){
var url = 'http://www.test.com/api/v1/user_favorites/0.json';
var del = $.param({listing_type: $scope.classes, listing_id: $scope.eventid, _method: 'delete'});
$http({
method: 'POST',
url: url,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: del
});
}
function like(){
var urls = 'http://www.test.com/api/v1/user_favorites.json';
var dels = $.param({listing_type: $scope.classes, listing_id: $scope.eventid});
$http({
method: 'POST',
url: urls,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: dels
});
}
function getLike(){
//some http ajax call to get current status of button
$http.get().then(...)
scope.isLikedLocal = result from get call
}
// initializing the directive should make an ajax call, unless you are passing the data in as a parameter
getLike();
};
}
};
}]);
Related
Using ASP.NET I'm trying to reload only a part of my webpage using jQuery instead of using "location.reload();". It's a single page application. As the user submits a form the user credits change and the new value should be updated without a full page reload. The value for credits is retrieved through an Ajax Get Call and should be updated after an Ajax Post Call. I tried using "$("#userCredits").load(?);" within the Ajax Post but can't get it right. Do I need to make a partial view to achieve this? Thanks for helping.
HTML _Layout.cshtml
<ul class="nav masthead-nav">
<li id="userCredits">
//Paragraph retrived from Ajax Get Call: "#reloadUserCredits".
</li>
<li>
<p class="user">#User.Identity.GetUserName()</p>
</li>
</ul>
JS
//Ajax POST user pack (buy pack)
$("#postform").submit(function (e) {
e.preventDefault();
var data = {
applicationUserId: $("#userId").val().trim(),
packId: $("input.activeImg").val().trim(),
}
$.ajax({
url: '/api/buypack',
type: 'POST',
dataType: 'json',
data: data,
success: function () {
document.getElementById("postform").reset();
location.reload();
},
error: function () {
}
});
});
// Ajax GET user credits (navbar userCredits)
var $credits = $('#userCredits')
$.ajax({
type: 'GET',
url: '/api/user',
success: function (credits) {
$.each(credits, function (i, user) {
$credits.append('<p id="reloadUserCredits" class="credits">Credits: ' + user.credits + '</p>');
});
}
});
As I understand... You already are getting the user credits via Ajax on page load. So you only need to do it again after he bought some more.
Have the Ajax request to /api/user in a named function. Below, I called it get_credits(). Run it on page load AND on success of the Ajax request to /api/buypack.
//Ajax POST user pack (buy pack)
$("#postform").submit(function (e) {
e.preventDefault();
var data = {
applicationUserId: $("#userId").val().trim(),
packId: $("input.activeImg").val().trim(),
}
$.ajax({
url: '/api/buypack',
type: 'POST',
dataType: 'json',
data: data,
success: function () {
document.getElementById("postform").reset();
//location.reload();
// Refresh the credits displayed on the page
get_credits();
},
error: function () {
}
});
});
// Ajax GET user credits (navbar userCredits)
var $credits = $('#userCredits')
function get_credits(){
$.ajax({
type: 'GET',
url: '/api/user',
success: function (credits) {
$.each(credits, function (i, user) {
$credits.html('<p id="reloadUserCredits" class="credits">Credits: ' + user.credits + '</p>');
});
}
});
}
// Run on page load
get_credits();
I'm coding a mobile application with ionic. I have to get a data (daily changing data) from a web page with JSON, but I want to get old data too. For example:
data.json?date=2016-11-10
data.json?data=2016-12-10
How can I send request to JSON?
To send data from PHP, once you get your data from the database, the array will apply json_encode($array); and to return you put return json_encode ($ array);
Try this!
var date = '2016-11-10';
$http({
method: 'GET',
url: data.php,
params: {date: date},
dataType: "json",
contentType: "application/json"
}).then(function(response) {
});
The question is confusing, so I'm not sure how to answer. If you are having trouble formatting a request to a REST service, you will need to find out how the service expects the date to be formatted in your field-value pair i.e:
date=2016/11/10 or date=20161110
If those don't work, this answer may help The "right" JSON date format
However, if you are actually wondering how to serialize a date in JSON, this link may help http://www.newtonsoft.com/json/help/html/datesinjson.htm
I prefer to use services for ajax requests.
Create a Service
//Service
(function() {
'use strict';
angular
.module('appName')
.factory('appAjaxSvc', appAjaxSvc);
appAjaxSvc.$inject = ['$http', '$log', '$q'];
/* #ngInject */
function appAjaxSvc($http, $log, $q) {
return {
getData:function (date){
//Create a promise using promise library
var deferred = $q.defer();
$http({
method: 'GET',
url:'/url?date='+date
}).
success(function(data, status, headers,config){
deferred.resolve(data);
}).
error(function(data, status, headers,config){
deferred.reject(status);
});
return deferred.promise;
},
};
}
})();
Then Use it in Controller
(function() {
angular
.module('appName')
.controller('appCtrl', appCtrl);
appCtrl.$inject = ['$scope', '$stateParams', 'appAjaxSvc'];
/* #ngInject */
function appCtrl($scope, $stateParams, appAjaxSvc) {
var vm = this;
vm.title = 'appCtrl';
activate();
////////////////
function activate() {
appAjaxSvc.getData(date).then(function(response) {
//do something
}, function(error) {
alert(error)
});
}
}
})();
I try to use ng-tags-input with a returned Json list by an api controller .net Mvc 6. My list is created in json but when try to display this list with the autocompletion , nothing works. My autocomplete list isn't displayed and I don't have error in chrome console.
So this is an object of my list :
[{
"ShopID":1,
"CompanyID":1,
"RegionID":1,
"Name":"Les Pieux",
"Town":"Les Pieux",
"Address":null,
"ZipCode":null,
"CreateDate":"2006-01-01T00:00:00",
"ModificationDate":"2006-09-29T00:00:00",
"LastModificationUserID":1,
"PhoneNumber":null,
"Fax":null,
"Email":null,
"CEmployeeShop":null
}]
This is my method in my controller:
$scope.tokenShops = [];
$scope.loadJsonShops = function(query)
{
//$scope.shops contains my list of shops in json format.
return $scope.shops;
}
And the tag in Html:
<div ng-controller="EmployeesCtrl">
<tags-input ng-model="tokenShops"
display-property="Name"
Placeholder="Ajouter un magasin"
add-from-autocomplete-only="true">
<auto-complete resource="loadJsonShops($query)"></auto-complete>
</tags-input>
</div>
This is my code that populates $scope.shops
Api Controller:
public IEnumerable<Shop> Get()
{
using (LSContext db = new LSContext())
{
var listShop = db.Shops.ToList();
return listShop;
}
}
angular shopCtrl:
function ShopsCtrl($scope, $http, $rootScope) {
function getShopsList() {
var reqGetShops = $http({ url: 'api/Shops' });
reqGetShops.success(function (data) {
$scope.shops = data;
$rootScope.$broadcast("getListShops", { list: data });
});
}
//with api controller the list is returned in json format. I tried an another method to fill my list with an convertion that I do and it doesn't work.
angularjs EmployeeCtrl :
$scope.$on("getListShops", function (event, args) {
$scope.shops = args.list;
$scope.selectShop = args.list[0];
})
But I don't think that my problem from my json list.
I hope someone can help me . Have a nice day.
I resolve my problem with a directive:
angular.module('TagsDirective', ['myResources', 'resourcesManagerGet', 'translateI18n'])
.directive('tags', function ($http, $q) {
return {
restrict: 'E',//restraint pour les éléments du dom
template: '<tags-input ng-model="SShops" key-property="ShopID" display-property="Name" placeholder="{{\'AddShop\' | i18n}}" add-from-autocomplete-only="true"><auto-complete source="loadTags($query)"></auto-complete></tags-input>',
scope: false,
link: function (scope, el) {
scope.loadTags = function (query) {
var deferred = $q.defer();
var reqGetShops = $http({ url: 'api/Shops/GetListShopFiltered', params: { 'query': query } });
reqGetShops.success(function (data) {
deferred.resolve(data);
});
return deferred.promise;
}
}
}
});
and in Html:
<tags></tags>
g0loob : thanks for your help, but now you can put an array of objects and use the attribute display-property to choose the text property to display.
example:http://mbenford.github.io/ngTagsInput/demos and look the tags input with custom object.
auto-complete requires array of objects with at least one property named "text" (just like tags-input), if you are not using your template for auto-complete or tags-input. And you also need to filter your result for auto-complete in order to work properly. Also see this link.
angular.module('TagsDirective', ['myResources', 'resourcesManagerGet', 'translateI18n'])
.directive('tags', function ($http, $q) {
return {
restrict: 'E',//restraint pour les éléments du dom
template: '<tags-input ng-model="SShops" key-property="ShopID" display-property="Name" placeholder="{{\'AddShop\' | i18n}}" add-from-autocomplete-only="true"><auto-complete source="loadTags($query)"></auto-complete></tags-input>',
scope: false,
link: function (scope, el) {
scope.loadTags = function (query) {
var deferred = $q.defer();
var reqGetShops = $http({ url: 'api/Shops/GetListShopFiltered', params: { 'query': query } });
reqGetShops.success(function (data) {
deferred.resolve(data);
});
return deferred.promise;
}
}
}
I use a form to submit values. When I click on the submit button, it calls edit().
Values are stored in the database (with php/mysql). Everything works fine so far.
I retrieve the values on the same partial view. On window.location.reload(); the page will refresh but the values are not instantly updated. After several refresh, it's
(When my DevTools is open, the cache is disable... so it's instantly updated)
Without the DevTools open, the cache works even if I put some function to disable the cache.
listingProjectApp.run(function($rootScope, $templateCache) {
$rootScope.$on('$viewContentLoaded', function() {
$templateCache.removeAll();
});
});
listingProjectApp.factory('EditCache', function($cacheFactory) {
return $cacheFactory('editCache', {
capacity: 1
});
});
listingControllers.controller('editProjectCtrl', ['$scope', '$http', '$routeParams', 'EditCache',
function ($scope, $http, $routeParams, EditCache) {
var result = EditCache.get('$http');
if( result ){
$scope.project = result;
console.log("Results from cache");
}
else {
$http({
url: "php/getProjectDetails.php",
method: "GET",
cache: false,
params: { 'id': $scope.projectId }
}).success(function(data) {
$scope.project = data;
EditCache.put('$http', data);
console.log("New results");
});
}
console.log(EditCache.info())
$scope.edit = function(project){
console.log(project);
$http({
url: "php/edit.php",
method: "POST",
data: project
}).success(function(id) {
EditCache.removeAll();
window.location.reload();
});
return false;
}
}]);
Looks like it's not the AngularJS cache's fault, but rather the browser's: for the browser, your XHR requests are simple HTTP GET requests, and all caching policies are applied to them. To avoid caching the partials, you'll have to either tweak your back-end to send appropriate headers to forbid caching, or use the old random suffix trick: add another dummy parameter to your params (like dummy: 'some-random-string'). This way, every GET request will be unique, and you'll not hit the cache.
I am trying to use backbones.js fetch to get json from a twitter search
and my code below can someone tell me where I am going wrong?
(function($){
var Item = Backbone.Model.extend();
var List = Backbone.Collection.extend({
model: Item,
url:"http://search.twitter.com/search.json?q=blue%20angels&rpp=5&include_entities=true&result_type=mixed"
});
var ListView = Backbone.View.extend({
el: $('#test'),
events: {
'click button#add': 'getPost'
},
initialize: function(){
_.bindAll(this, 'render', 'getPost');
this.collection = new List();
this.render();
},
render: function(){
var self = this;
$(this.el).append("<button id='add'>get</button>");
},
getPost: function(){
console.log(this.collection.fetch());
}
});
// **listView instance**: Instantiate main app view.
var listView = new ListView();
})(jQuery);
I am just getting started with backbone and I just want to console.log the json
you can see my example here. jsfiddle.net/YnJ9q/2/
There are two issues above:
Firstly, you need to add a success/fail callback to the fetch method in order for you to have the fetched JSON logged to the console.
getPost: function(){
var that = this;
this.collection.fetch(
{
success: function () {
console.log(that.collection.toJSON());
},
error: function() {
console.log('Failed to fetch!');
}
});
}
Another problem is the issue of "same-origin-policy'. You can find out how to resolve that by taking a look at this link.
Update:
I modified your code and included the updated sync method. It now works! Take a look here!
Basically, update your collection to include the parse and sync methods as below:
var List = Backbone.Collection.extend({
model: Item,
url: "http://search.twitter.com/search.json?q=blue%20angels&rpp=5&include_entities=true&result_type=mixed",
parse: function(response) {
return response.results;
},
sync: function(method, model, options) {
var that = this;
var params = _.extend({
type: 'GET',
dataType: 'jsonp',
url: that.url,
processData: false
}, options);
return $.ajax(params);
}
});