I have a list of events that gets build from a JSON call to my server. The list gets parsed through ng-repeat. I want to implement a like button for the event and if its liked, replace that with unlike.
<a ng-show='event.liked==null' ng-click="like(event.event_id)">Like</a>
<a ng-show='event.liked!=null' ng-click="unLike(event.event_id)">Unlike</a>
Everything works perfectly except I have to refresh the feed to show "Unlike". Is there a way I can update the specific list item at the index that was liked once clicked without the need to refresh.
Please let me know if you need more information. Thanks!
edit: adding like function & unlike function. All it does is send request to my server to like or unlike a specific event with the event_id and user token.
$scope.like = function (event_id) {
var url = www.server.com?type=unlike&event_id=...
$http.post(url).success(function (data) {
console.log('success like');
//I want it to update my index here
}).error(function (data) {
console.log('fail like');
});
};
$scope.unLike = function (event_id) {
var url = www.server.com?type=unlike&event_id=...
$http.post(url).success(function (data) {
console.log('success unlike');
//I want it to update my index here
}).error(function (data) {
console.log('fail unlike');
});
};
Instead of passing in the event_id, pass the object to the like and unLike functions and update the object in success handler.
HTML
<a ng-hide='event.liked' ng-click="like(event)">Like</a>
<a ng-show='event.liked' ng-click="unLike(event)">Unlike</a>
Controller
$scope.like = function(event) {
var url = 'www.server.com?type=unlike&event_id=' + event.event_id;
$http.post(url).success(function (data) {
event.liked = true;
console.log('success like');
}).error(function (data) {
console.log('fail like');
});
};
$scope.unLike = function(event) {
var url = 'www.server.com?type=unlike&event_id=' + event.event_id;
$http.post(url).success(function (data) {
event.liked = null;
console.log('success unlike');
}).error(function (data) {
console.log('fail unlike');
});
};
Related
I have certain fields getting filled in my controller.
public string AjaxLogin()
{
//some code to check admin or not
Session["UserName"] = "Smith";
if(type="Admin")
{
Session["UserRole"] = 1;
}
Session["EmployeeID"] = 101;
}
I have an ajax call to this controller like below and if it is success, I need to access these session variables inside success to check the user role.
$.ajax(
{
url: GLOBAL.GetAppPath() + 'Home/AjaxLogin',
data: data,
type: 'POST',
error: function (xhr, status, error) {
console.log(error);
},
success: function (result, status, xhr) {
if (result == 'OK')
{
var UserVal = '#Session["UserRole"]';
alert(UserVal);
if(UserVal ==1)
{
var baseUrl ="#Url.Action("Admin","AdminPage")";
window.location.href = baseUrl;
}
else
{
var baseUrl ="#Url.Action("Admin","RegularPage")";
window.location.href = baseUrl;
}
}
else {
$('#msgError').html('Error: ' + result);
$('#msgError').css('display', 'block');
}
},
});
But I cannot access this variable in this call. I want to check the user role variable and give url actions accordingly.
If you want to redirect to a controller in your project you can use the Url helper for you
Sample:
return JavaScript( "window.location = '" + Url.Action("Edit","Dispatch") + "'" );
P.S: I couldn't comment since it asks for 50 reputation that's why I'm commenting it over here.
I have the below drop down list in my _Layout.cshtml
#Html.DropDownList("myList",
new SelectList(apps, "AppId", "Name", ViewBag.AppId),
new {#class = "mySelectBox", onchange = "updateAppLayout(this);"})
And the javscript function is in seperate .js file as :
function updateAppLayout(sel) {
var name = sel.options[sel.selectedIndex].text;
var appId = sel.options[sel.selectedIndex].value;
var data = { "appname": name, "appId": appId };
var url = "/Test/TestLayout";
$.post(url, data)
.done(function(msg) {})
.fail(function (xhr, status, error) {
});
}
Whenever i change the drop down value too fast the .fail() method is called. I put a console inside the .fail() method for the sel value and it gives this value - > select#myList.mySelectBox
But if i have the console just before the $.post method I get the dropdownlist.
Not sure whats wrong here.
PS: I do not want to use setTimeout
I would disable the select list while loading, this way you can ensure that it will only get new value on return of the first one
function updateAppLayout(sel) {
var name = sel.options[sel.selectedIndex].text;
var appId = sel.options[sel.selectedIndex].value;
document.getElementById("myList").disabled = true;
var data = { "appname": name, "appId": appId };
var url = "/Test/TestLayout";
$.post(url, data)
.done(function(msg) {
document.getElementById("myList").disabled = false;
//do something
})
.fail(function (xhr, status, error) {
});
}
I know the problem is the order of execution, the scope fires async and loads the data after the rest of the code has been processed. I have a httpGET that gets the information from a web service and it's inside my Facebook share function when the user clicks the Facebook share button. But i tried adding a watch and .then with return promise in the httpget but both i could not get to work.
So the idea is the following: I have an CDImage that the user shares on facebook and i have another directory that holds promotional images for that same CD, not all of them so the httpGET checks if the promotionCDid exists if it exists the variable CDImage should be updated with the CDPromotionalURL instead of the standard url is get from CDImage so the user shares the Promotional image instead of the default CD cover.
So far the problem is that the CDImage does not change directly and console.log(CDImage) displays the CDCover the first time and when you click the button after several seconds the CDImage shows the CDPRomotionURL image.
var CDPromotionalImageUrl = "EMPTY";
$('#facebookshare').click(function () {
$scope.GetCDdata = function () {
$http({
method: 'Get',
url: "/GetCDPromotionImage?id_CD=" + promotionCDId,
})
.success(function (data, status, headers, config) {
$scope.CDdata = data;
CDPromotionalImage = $scope.CDdata[0].filename
$scope.CDPromotionalImageUrl = "https://website.com/" + CDPromotionalImage
})
.error(function (data, status, headers, config) {
$scope.message = 'Unexpected Error';
});
};
if (CDPromotionalImageUrl == "EMPTY") {
CDImage = CDImage;
} else {
CDImage = CDPromotionalImageUrl;
}
console.log(CDImage)
var $this = $(this);
var urlShare = (window.location.href);
var obj = {
method: 'share',
href: (urlShare),
picture: (CDImage),
title: 'The ' + CDName,
caption: "As heard on website.com",
description:(description)
};
function callback(response) {
//alert("Post ID: " + response['post_id']);
}
FB.ui(obj, callback);
});
$scope.GetCDdata();
I'm creating my first web app in angularjs and can't get the page to update with new values once the user submits text/numbers in an input box.
I'm using Java8, MongoDB, angularJS and twitter bootstrap
HTML:
<td>
<input type="text" class="form-control" placeholder="enter bugnumber" data-ng-model="auditdata.newbugnumber">
<h4>Bug Numbers</h4>
{{a}}
</td>
<td>
<button type="submit" data-ng-click="add(auditdata)" class="btn btn-danger" >Save</button>
</td>
In the HTML above i take input from user in ng-model=auditadata.newbugnumber but on server side it sill gets update in the bugnumber filed. The newbugnumber field is acting like a temp variable which is just used to send the new data to the server. The reason for using the temp variable is to avoid two way binding in angularjs.
I tried using $apply(), $watch and digest in the JS below but can't get the value to be updated in the view. The only way the data gets update in view is when i reload the page which is not an option
app.controller('listCtrl', function ($scope, $http,$route) {
$scope.isCollapsed = true;
$http.get('/api/v1/result').success(function (data) {
$scope.audit = data;
}).error(function (data, status) {
console.log('Error ' + data);
})
$scope.add= function(bugInfo) {
$http.post('/api/v1/result/updateBug', bugInfo).success(function (data) {
bugInfo.newbugnumber='';
console.log('audit data updated');
}).error(function (data, status) {
console.log('Error ' + data);
}
};
});
Update function on server side
public void updateAuditData(String body) {
Result updateAudit = new Gson().fromJson(body, Result.class);
audit.update(
new BasicDBObject("_id", new ObjectId(updateAudit.getId())),
new BasicDBObject("$push", new BasicDBObject().append("bugnumber",
updateAudit.getNewbugnumber())));
}
how bugnumber filed in collection looks like
> db.audit.find({"_id" : ObjectId("5696e2cee4b05e970b5a0a68")})
{
"bugnumber" : [
"789000",
"1212"
]
}
Based on your comment, do the following:
Place all your $http handling i a service or factory. This is good practice and makes reuse and testing easier
app.factory('AuditService', function($http) {
var get = function() {
return $http.get("/api/...") // returns a promise
};
var add = function() {
return $http.post("/api/...") // returns a promise
};
return {
get: get,
add: add
}
});
And then in your controller
// note the import of AuditService
app.controller('listCtrl', function ($scope, $http,$route, AuditService) {
// other code here
// If insert is successful, then update $scope by calling the newly updated collection.
// (this is chaining the events using then())
$scope.add = function(bugInfo) {
AuditService.add().then(
function(){ // successcallback
AuditService.get().then(
function(data){ // success
$scope.audit = data;
},
function(){ // error
console.log('error reading data ' + error)
})
},
function(error){ // errorcallback
console.log('error inserting data ' + error)
})
});
The same approach can be applied to all CRUD operations
Scoop...
I have a drop down list that might not display a particular option you're looking for. I added a button with pop up modal to type in a field you want to add to the drop down list. It functions perfectly, but I need to add an ajax postback method to refresh the list after the user hits enter. I don't want to refresh the whole page, just the list. any help?
Controller:
public ActionResult AddLeadSource()
{
return View();
}
[HttpPost]
public ActionResult AddLeadSource(string name)
{
LeadSource ls = new LeadSource();
ls.Name = name;
db.LeadSources.Add(ls);
db.SaveChanges();
return Json(new { success = true });
}
JS
<script>
$("#AddNew").change(function () {
var name = $("#Name").val();
// var order = $("#DisplayOrder").val();
$.ajax({
type: 'POST',
dataType: 'json',
cache: false,
url: '/Admin/LeadSource/AddLeadSource',
data: { name: name },
success: function (response) {
//alert("Success " + response.success);
$('#FollowUpNotes').kendoWindow('destroy');
// Refresh the DropDown <-- Heres where I need some help!
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Error - ' + errorThrown);
}
});
});
In your success function of your Ajax call add this:
$("IdOfDropDownList").data("kendoDropDownList").dataSource.read();
In this way your dropdownlist will call the read function and reload all data. I assumed that your dropdownlist is binding throught read call.
I highly recommend looking at jQuery UI's autocomplete widget. That said,
$('#YourDropDownID option').remove(); //this will remove all option elements inside the <select id="YourDropDownID">
Then you just need to build new ones based on the response data,
for (var o in data) {
if (data[o].Value != undefined) {
$('#YourDropDownID').append('<option value="' + data[o].Value + '">' + ("" + data[o].Display) + '</option>');
}
}
I do this inside the .done() callback of my AJAX:
.done(function (data) {
//above code
}
Depending on the nature of the data you are sending back you may need to loop through it differently. Mine is an array of objects with a Value and Display properties (in my case, account numbers and account names).
//server side controller
var query = #"
Select
SubString([mn_no], 0, 6) As Value,
RTRIM([acct_desc]) As Display
From [some_table]";
return con.Query(query, new { AccountNumber = accounts.Select(x =>
{
return new { Value = x.Value, Display = x.Display };
});