I'm still relatively new to AngularJS so bear with me on this one. I'm trying to create a photo-liking system and when the user clicks the like button, it increases the number of likes. I have this functionality down, but the only thing is that I have to reload the page in order for the "like" to show. This means that everything on the backend is in order. However, I would like to prevent having to do reload the page.
One thing to note is that I have a partial template, and a HTTP post request occurs once the button is clicked with an ng-click directive.
HTML SNIPPET FROM PARTIAL TEMPLATE
<a class="like" ng-click="likeIt(//PHPCODEGOESHERE//)">Like</a>
AngularJS
userApp.controller('photoController',['$scope','$location','$window','$log','$route','$routeParams','$location','$http', function($scope,$location,$window,$log,$route,$routeParams,$location,$http){
$scope.name = 'Photos';
$scope.likeIt = function(parameters){
$http.post('centralcommand.php', {id: parameters}).success(function(data,status,headers,config){
window.location.reload(); // Causes page to reload
}).error(function(data,status,headers,config){
alert('failure');
});
};
}]);
Please also note that I have tried to change the innerHTML in the success callback. This doesn't work because I already am mixing PHP with HTML and I have to use both ' and " in the HTML code so when I get the HTML text and replace it using innerHTML it doesn't work correctly.
I was able to find an answer after perusing a different method and it comes from this answer provided in a separate StackOverflow post. It has to do with reloading the template cache using the $templateCache service:
userApp.controller('photoController',['$scope','$location','$window','$log','$route','$routeParams','$location','$http','$templateCache', function($scope,$location,$window,$log,$route,$routeParams,$location,$http,$templateCache){
$scope.name = 'Photos';
var currentPageTemplate = $route.current.templateUrl; // ADDITION # 1
$scope.routeReloader = function(parameters){
$http.post('centralcommand.php', {id: parameters}).success(function(data,status,headers,config){
$templateCache.remove(currentPageTemplate); // ADDITION # 2
$route.reload(); // ADDITION # 3
}).error(function(data,status,headers,config){
alert('failure');
});
};
}]);
Related
Image a page, that page is called "dashboard". In the dashboard, there is a drop-down menu, with items, which are listed by the PHP script, and their count varies on the number of results from a database.
Now, when a user clicks one of the items from the menu, it should redirect him to the configuration page, with some data (id, type). Sounds simple, but the redirecting method used is made with angular, so it uses URL hashing, without refreshing the site. URL of configuration page then looks like:
https://www.example.com/index.php#/configure
...and I want to get there some data. The site we see there is just a blank site, which, in the file tree, is named "configuration.php", but you don't see it in the URL, because of angular code in "configure.module.js.php", which simply redirects the user, gives them the right site with:
(function () {
'use strict';
angular.module('BlurAdmin.pages.configure', [])
.config(routeConfig);
/** #ngInject */
function routeConfig($stateProvider) {
$stateProvider
.state('configure', {
url: '/configure',
title: 'Configuration',
templateUrl: 'app/pages/configure/configure.php',
controller: 'addCtrl',
});
}
})();
So I assume, that if I want to get the data to my site, I need some kind of a GET request. I figured out, that it will work if I use the GET request like so:
https://www.example.com/index.php?something=works&omg=itWorks#/configure
So my index.php will work with the GET data and write them to a SESSION, which can then be used in configuration.php!
Well, it works, kinda... But the main thing is, that it is all angular, so NO SITE REFRESH AT ALL! That means none of my files will be refreshed, so after I click the button again, the site will not get the GET request again, it will simply redirect me to configuration.php, without dealing with the new data... It will keep the first GET parameters and SESSION.
So there goes my question. how to make it? I really need that one click to send that data to configuration.php, without refreshing the site, but, working and updating.
In html you add ui-sref to like this
ui-sref="configure/({id: valueid})
in file config
url:'/configure/:id'
in your controller add $stateParams like this
function addCtrl($scope,$http,$stateParams)
and use ajax to GET
var params = $.param({'id':$stateParams.id})
$http({
method:'GET',
url:'yoururl?id=' + $stateParams.id,
data:params,
headers : { 'Content-Type': 'application/x-www-form-urlencoded' }
}).then(onSuccess);
I am loading a page but page has a condition. If condition is false I am redirecting url using $window.location.href on another url but before redirecting on another url default page view is showing first then redirecting another url thats not looking good. I am so confused what to do.Please give me any solution.
function get_bookings() {
$http.post($scope.domailurl + 'api/class/booking.php?action=get_booking', { 'id': urlid }).success(function(data, status) {
spinnerService.show('booksSpinner');
if (data.ticket && data.ticket != "") {
$window.location.href = $scope.domailurl + '#/attendeesprint/' + data.ticket;
}
});
}
I am not 100% sure what you are meaning, but I do have a few suggestions that may help.
The first suggestion would be use the $location service angular provides. You can then use the following line instead of having to keep a $scope.domailurl variable. However, I am assuming that this path is still within your application. This may also fix your issues with the default page showing because you are no longer causing a full page refresh.
$location.path('/attendeesprint/' + data.ticket);
My second suggestion would be to move the spinnerService.show('booksSpinner'); line to before you make the $http call. This will make sure your spinner is showing during the asynchronous server operation.
Suppose I have
def bar(request):
template = loader.get_template('activation/bar_chart.html')
context = RequestContext(request,{'name':'bar_chart'})
return HttpResponse(template.render(context))
I want to send a http get request via the javascript in the template
$.get('/bar/')
But it does not render the bar_chart.html, I still stay in the current html page.
If I use the load function in the jquery
$('body').load('/bar/')
then the content of bar_chart.html will replace the body of the current html page. But I want to go to a new page (that is, the url should be /bar)
How can I do that with django and jquery?
Thank you
If you want to go to the /bar/ page you just need to change the location property. JQuery is not needed here:
location.href = "/bar/";
I think i've run into this issue before as well.
If I remember correctly you can do the following
return HttpResponse(template.render(context), mimetype='application/json')
This is my first post of stackoverflow. I've spent the past month trying to solve this on my own, extensively searching Google and this website. Here's my problem:
I have a website where users can search for cases. When they find a case, their results are loaded on a case details page. Users normally search for cases from the homepage by clicking a search option, where they enter a case number like the following:
14-12345
Users submit their search to the homepage's index controller. The controller parses the search and redirects to a "case" action. This action polls the database to get case details, and returns a case view.
This search works - users see the results of their search on a case details page. However, a request was received so users can search for cases from the case details page as well.
I can't make the new request work. I've tried using Web API (which really became a waste of time, because I want to return a whole view, not just search data), and I've failed to create the appropriate controller/view combination to work with my data. I usually wind up trying to use the existing controller (which has the code to search) and the case details view.
Breaking down the pieces...
The model data is stored in a viewmodel file:
public class PortalCaseView
{
public DocketCase CaseInfo { get; set; }
public List<CaseNote> Notes { get; set; }
public string Search { get; set; }
...other various variable declarations, etc
}
The Index.cshtml file is the homepage/main landing page for the site. Users can search for case details by going to a section to search (code from the view here):
<div class="tile">
<span>Search by Case Number</span>
#Html.EditorFor(x => x.Search)
<a class="m-btn green-stripe" href="javascript:submitForm();" style="color: #444;
text-decoration: none;">Submit<i class="icon-hdd"></i></a> <a class="m-btn red-stripe"
href="javascript:toggleSearch();" style="color: #444; text-decoration: none;">Cancel<i
class="icon-remove"></i></a>
</div>
(Submitting the result gives a submit command, which posts the search to the controller.)
The PortalController.cs controller file directs requests for the homepage. Its Index method grabs the Search variable, and redirects to a Case action to process:
Index
if (!string.IsNullOrWhiteSpace(viewmodel.Search))
{
...
return RedirectToAction("Case", new { Year = docketnumber[0], Sequence = docketnumber[1], J = viewmodel.JudgeCode });
}
Case
[HttpGet]
public ActionResult Case(int Year, int Sequence, string J)
{
...various declarations and requests to get db information...
return View(vm); //vm is a viewmodel with info for the case view
}
[HttpPost]
public ActionResult Case(PortalCaseView vm)
{
return View(vm);
}
* When the redirect to the Case action is complete, the Case.cshtml view loads with the necessary details. Now that searches from the case view are required, I've added a section to the case view to take an "on-demand" search query:
<textarea id="searchForCase" style="width: 150px;"></textarea>
<a class="m-btn green-stripe" href="javascript:searchCase();" style="color: #444;
text-decoration: none;">Search<i class="icon-hdd"></i></a>
And here is where problems start. During a typical run, Ajax/JSON code builds a call back to a controller action. Then, the action executes (usually on data stored in a file or folder). A view is returned, and then the page refreshes. (This is when a user is using the site.) It doesn't work the same way for my new custom code.
My custom searchCase() function takes the case number entered by a user to search for it (it goes back to the Index action in the original PortalController.cs file):
var searchCase = function () {
var textArea = document.getElementById("searchForCase");
var txt = String(textArea.value);
jQuery.ajax({
type: "POST",
url: "#Url.Action("Index","Portal")",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify({ fromCaseSearch: txt }),
success: function (data) {
alert(data);
},
failure: function (errMsg) {
alert(errMsg);
}
});
$('form').submit();
}
(Note: I've already tried changing the datatype from json to html; I'm assuming I might need to work with the content type)
I've traced the progress from this point. The website goes back to PortalController.cs and to the Index action (following through like a good POST), and then takes the search query provided by the user. Since it falls out of the Index action when I try to redirect to the Case action like before, I added an if statement to deal with search queries directly from the case details view:
if (!string.IsNullOrEmpty(fromCaseSearch))
{
System.Web.HttpContext.Current.Session.Clear();
//forget why I put that clear request there, but I do
//use session state variables, so I might need to clear
//them when searching from scratch - if they exist
viewmodel = new PortalIndexView();
viewmodel.Search = fromCaseSearch;
...initialization and parsing for search...
...searching for and loading data from database(s)...
ModelState.Clear(); //was hoping this would "refresh" view
//...this didn't work either
return View("Case", vm); //forced website to return
//case view with viewmodel data
//...this actually starts loading
//the case view
}
This actually works... to a point. The data gets processed the same way, and the case view is loaded like normal. However, even after tracing the loading process (and seeing that model variables are sent to the view), the page does not update with the new information).
So, that's where I'm stuck. I've tried tweaking some settings (and even thought the problem might be in the web.config file), but when I run across problems like this, what usually fixes the problem for me is to find out what I did wrong here (or in the general vicinity of the problem - the answers usually happen when I fix simple stuff first).
Some last-minute things:
PortalController.cs (the controller) outputs to Case.cshtml (the case details view). When right-clicking the View controller action, it redirects back to PortalController.cs (the main controller from the landing page).
No other controller shares Case.cshtml.
There is no CaseController.cs file. It looks like my predecessor simply created the search "redirect", figuring users would only search from the homepage (and they did up until now).
Last-second idea? Maybe I'm supposed to account for HTTPGet and HTTPPost actions for my new code as well. Not sure... brain is mush...
Naturally, since this is a work project, I can only provide so many details, but I'll be glad to take suggestions at this point.
UPDATE: is it possible that my problem is because I didn't include a #using (Html.BeginForm(...)) line in my case details view? I noticed there isn't one. Do you need one to be able to have official POST action in the related controller?
One other clarification: I'm using Ajax/JSON for passing data back to the controller from the case view, since I can't get the page to just "submit" (in Javascript/JQuery code, $('form').submit() does not work at all). I'm wondering if it has anything to do with Web API. (There is a Web API file called CaseNoteController.cs that handles notes that get added to cases. When I was trying to work with Web API - and possibly return a view using it - I had a test api call that made the case details view page refresh effortlessly; I just couldn't figure out how to get it to work for my needs.)
Problem solved (my fault). My lack of experience kept me from figuring this out sooner:
I wound up not needing the searchCase function in the Case view. The reason why: I didn't wrap my Case view in a #using(Html.BeginForm()) code block, which meant that my page wasn't posting results (no matter how hard I tried)
I didn't pay attention to my PortalController.cs file, which already had HttpGet and HttpPost variants of my Case action. (The HttpPost action was completely empty, save for returning a view. That explains why the page failed to load and display anything, let alone the results of my next case search.)
Once I corrected those issues (and tweaked a few other buttons so they didn't automatically post or try to run when I submitted the document), the code finally worked! Praise God. No need for convoluted or weird paths back to the controller - things happened real quick after that.
(Now to trim off a whole bunch of scaffolding and otherwise unnecessary code...)
I am having a hard time deciding on an appropriate way to Perform some server side functionality and then redirecting to the same View in my ASP.Net MVC project.
I am trying to call an Action after the selected index changed client side event of my combobox.
One way I can think of is to change the window.location to the url of my Action and pass the data i need via the query string like this
function SelectedIndexChanged(s,e)
{
window.location.href = "/MyController/MyAction?" + s.GetValue();
}
I also see lots of people saying you should use jquery ajax for this
function SelectedIndexChanged(s,e)
{
$.ajax({
url: 'MyController/MyAction',
data: { value: s.GetValue() },
success: function(){
alert('Added');
}
});
}
My Action looks something like this where i set some cookie values using the value and Set View bags values depending on the selected index.
public ActionResult SelectedIndexChanged(string value)
{
//Do some processing
//Set cookie values
SetViewBags(value);
return Redirect(Request.UrlReferrer.ToString());
}
Is there a better approach to accomplish my task, I am leaning more towards changing the location.href as it is simpler, but i'm not sure if this is good practice?
EDIT
To Clarify this Combobox is a Devexpress MVC extension so I will have to handle the "SelectedIndexChanged" client side event.
This Combobox is also on my layout page so it appears on every view in my project. So when it is changed i will need to to call the same Action no matter what page it is on
As you've indicated that your form is in your layout (not a view), I recommend you look at using a view partial. Fortunately, MVC has already provided an example with their view partial (can't remember the name) that has the login and logout buttons. If a user clicks logout, some javascript is fired and the form is submitted. This will redirect the user; however, you could also send the original address (referrer) as a parameter to your server method and then redirect to that page afterward.
You could always use an Html.Action
function SelectedIndexChanged(s,e)
{
#Html.Action("ActionName", "ControllerName", {optional route values})
}