I'm trying to redirect back to the previous page using $timeout and $window.history.back(). So when form is submitted a message will show saying (thank you... bla bla) all good from here, but when redirecting back the $timeout doesn't seems to kick in.
<div class="thankyou" data-ng-show="vm.hideEnquiryForm">
<h3><i class="fa fa-envelope fa-x2"></i> Thank you for enquiring, we will get back to you as soon as possible.</h3>
Return
</div>
vm.submitForm = function () {
enquireService.postEnquireForm(vm)
.then(function (response) {
//$location.path(vm.returnUrl);
//console.log($location.path() + ' '+ vm.returnUrl);
if (!vm.hideEnquiryForm) {
vm.hideEnquiryForm = true;
}
$timeout(function () {
$window.history.back;
}, 3000);
})
}
The are many way to do what you want...
The best way, in my opinion, could be using the interface exposed by your router (assuming that you are using a router)...
this is a useful post based on top of UI.Router Angular - ui-router get previous state, so, you need just to go to the previous state using $state.go;
If you cannot do something like that, the only way is using the real history object...
vm.submitForm = function () {
var returnUrl;
enquireService
.postEnquireForm(vm)
.then(function (response) {
var returnUrl = response.returnUrl;
if (!vm.hideEnquiryForm) {
vm.hideEnquiryForm = true;
}
return $timeout(window.history.back.bind(window), 3000);
});
};
Related
Currently I am handling likes like so:
class LikeController extends Controller
{
public function like(Post $post)
{
$attributes = [
['user_id', '=', auth()->user()->id],
['post_id', '=', $post->id]
];
$like = Like::where($attributes);
if($like->exists()) {
$like->delete();
} else {
Like::create(['user_id' => auth()->user()->id, 'post_id' => $post->id]);
}
return redirect()->to(url()->previous());
}
}
and I have a route:
Route::post('like/{post}', [LikeController::class, 'like']);
What I don't like is that each time a like is clicked a new request is sent and the page refreshes to the top, so I added this javascript to scroll back to the previous position when a like is clicked:
$(window).on("scroll", function(e) {
$.cookie("tempScrollTop", $(window).scrollTop());
});
$(".like-form").each(function() {
$(this).submit(function(e) {
$.cookie("action", 'like', {path: '/'});
})
});
$(window).on("load", function (e) {
if ($.cookie("tempScrollTop") && $.cookie('action') === 'like') {
$(window).scrollTop($.cookie("tempScrollTop"));
$.cookie("action", '', {path: '/'});
}
})
This all works great, but I still don't like seeing the page refresh when hitting a like button. Is there a way to make the post request async and/or let it run in the background such that when hitting the like button the page doesn't refresh but the like does get sent to the server? What would be otherwise the correct method to achieve this result?
Thank you any help will be appreciated!
You can do Ajax request via jQuery, or you can use Livewire.
Here is a good blog how to make Livewire Like button: https://rappasoft.com/blog/building-a-like-button-component-in-laravel-livewire
You should'nt use a redirection in your api, but instead implement an ajax request that just return a success message.
public function like(Post $post)
{
// ...
return response()->json("Post successfuly liked"); // Or you could return the Post, or Like object if you want.
}
On the front end side, when calling that route you could then handle the response, for example incrementing the counter :
$(".like-form").each(function() {
$(this).submit(function(event) {
// call the api here, and then handle the response through a callback
// ex:
fetch(`${API_URL}/post/like`).then(response =>
// do something, like querying the dom element for its value and incrementing it.
)
});
});
If AJAX request reloads the page is the issue then simple apply event.preventDefault() will fix this
$(".like-form").each(function() {
$(this).submit(function(event) {
event.preventDefault();
}
}
FYI - Check this reference Laravel 9 Form Submit Using Ajax Example Tutorial
I am trying to figure out how to make this basic test pass consistently.
describe('home page', function () {
beforeEach(function () {
browser.driver.get('https://localhost:0000/xxxx/');
});
it('should have a title', function () {
var userName = browser.driver.findElement(by.id('userid_inputtext')).sendKeys('userNameXX');
var passWord = browser.driver.findElement(By.id("password_inputtext")).sendKeys("passWordXX");
var login = browser.driver.findElement(By.id('sign_in_button'));
login.click();
browser.driver.getCurrentUrl();
browser.driver.getTitle().then(function (title) {
expect(title).toEqual('Webpage Title');
});
});
});
The login in page is not Angular but after login it loads the Angular app. Right now my test is passing some of the time. The problem is that sometimes it picks up the title of the login page and sometimes it picks up the title of the home page(I want it to consistently test the title of the home page after login).
I am have played around with using a promise and browser.wait a little bit but have not really nailed this down. Any advice would be great!
Couple of things I could think of - most of the methods in protractor API are asynchronous and return promises.
In your login page once you login.click(), your homePage takes some time to load and therefore following async methods like - browser.getCurrentUrl & browser.getTitle are called first. This happens inconsistently as you pointed out.
Also you should assign variables to element locators and then perform actions on them! You should use Page Objects to store your locators. Please refer the Official Protractor Style Guide
browser.getCurrentUrl also returns a promise you have to resolve it as well.
To solve this issue you should use browser.wait in the right way:
describe('home page', function () {
beforeEach(function () {
browser.driver.get('https://localhost:0000/xxxx/');
});
it('should have a title', function () {
var userName = browser.driver.findElement(by.id('userid_inputtext'));
userName.clear();
userName.sendKeys('userNameXX');
var passWord = browser.driver.findElement(By.id("password_inputtext"));
passWord.clear();
passWord.sendKeys("passWordXX");
var login = browser.driver.findElement(By.id('sign_in_button'));
browser.driver.wait(login.click(),5000,'homePage should be loaded within 5 secs'); // would throw an error if the page takes more than 5 secs to load
// you could also use `browser.driver.sleep(500)` but not advisable as sleeps slow the tests down!
browser.driver.getCurrentUrl().then(function (url) {
expect(url).toEqual('homePage url');
});
browser.driver.getTitle().then(function (title) {
expect(title).toEqual('Webpage Title');
});
});
});
Also since your login page is non-angular, you could write your test in the right way which is to use browser.ignoreSynchronization and using the protractor api methods in a cleaner way.
describe('home page', function () {
beforeEach(function () {
browser.get('https://localhost:0000/xxxx/');
});
it('should have a title', function () {
browser.ignoreSynchronization = true; // set it to true for non-angular pages(loginPage)
var userName = element(by.id('userid_inputtext'));
userName.clear();
userName.sendKeys('userNameXX');
var passWord = element(By.id("password_inputtext"));
passWord.clear();
passWord.sendKeys("passWordXX");
var login = element(By.id('sign_in_button'));
browser.wait(login.click(),5000,'homePage should be loaded within 5 secs');
browser.ignoreSynchronization = false; // set it to false for angular pages(homePage)
browser.getCurrentUrl().then(function (url) {
expect(url).toEqual('homePage url');
});
browser.getTitle().then(function (title) {
expect(title).toEqual('Webpage Title');
});
});
});
Notice there is no need of accessing the browser.driver object, you can directly use protractor's methods!
I recently built a custom dashboard with the help of Sebastiaan forums in this post:
http://our.umbraco.org/forum/umbraco-7/using-umbraco-7/60887-Custom-dashboard-Umbraco-update-service
However, I have now modified my code in an attempt to make the interface more user friendly by including a datepicker on two fields so that our users can pass two dates into our web services and have a result returned.
The problem is, I am receiving the following Javascript errors in Firebug when I try and access my Dashboard in the back office:
Error: Argument 'AxumUpdateService' is not a function, got undefined
cb#http://localhost:60282/umbraco/lib/angular/1.1.5/angular.min.js:17:79
xa#http://localhost:60282/umbraco/lib/angular/1.1.5/angular.min.js:17:187
Jc/this.$gethttp://localhost:60282/umbraco/lib/angular/1.1.5/angular.min.js:53:310
k/<#http://localhost:60282/umbraco/lib/angular/1.1.5/angular.min.js:44:274
n#http://localhost:60282/umbraco/lib/angular/1.1.5/angular.min.js:7:72
k#http://localhost:60282/umbraco/lib/angular/1.1.5/angular.min.js:44:139
e#http://localhost:60282/umbraco/lib/angular/1.1.5/angular.min.js:40:139
y/<#http://localhost:60282/umbraco/lib/angular/1.1.5/angular.min.js:39:205
Odhttp://localhost:60282/umbraco/lib/angular/1.1.5/angular.min.js:158:14
u/j.success/<#http://localhost:60282/umbraco/lib/angular/1.1.5/angular.min.js:100:347
Uc/e/j.promise.then/i#http://localhost:60282/umbraco/lib/angular/1.1.5/angular.min.js:79:432
Uc/e/j.promise.then/i#http://localhost:60282/umbraco/lib/angular/1.1.5/angular.min.js:79:432
Uc/e/j.promise.then/i#http://localhost:60282/umbraco/lib/angular/1.1.5/angular.min.js:79:432
Uc/e/j.promise.then/i#http://localhost:60282/umbraco/lib/angular/1.1.5/angular.min.js:79:432
Uc/g/<.then/<#http://localhost:60282/umbraco/lib/angular/1.1.5/angular.min.js:80:485
Xc/this.$gethttp://localhost:60282/umbraco/lib/angular/1.1.5/angular.min.js:92:268
Xc/this.$gethttp://localhost:60282/umbraco/lib/angular/1.1.5/angular.min.js:90:140
Xc/this.$gethttp://localhost:60282/umbraco/lib/angular/1.1.5/angular.min.js:92:429
j#http://localhost:60282/umbraco/lib/angular/1.1.5/angular.min.js:101:78
r#http://localhost:60282/umbraco/lib/angular/1.1.5/angular.min.js:104:449
dd/http://localhost:60282/umbraco/lib/angular/1.1.5/angular.min.js:106:90
http://localhost:60282/umbraco/lib/angular/1.1.5/angular.min.js Line
63
At first I thought it was due to some of my Javascript causing a conflict but I have checked it and there are no missing semicolons or errors in the code.
I then checked my package.manifest to ensure that Jquery was called before AngularJS as this is advised on most forums however, this still hasn't helped with this issue.
Does anybody know how to circumvent these issues?
package.manifest
{
javascript:[
"~/app_plugins/Dashboards/jquery-1.11.2.min.js,
"~/app_plugins/Dashboards/css/jquery-ui.min.js",
"~/app_plugins/Dashboards/AxumUpdateServiceJquery.js",
"~/app_plugins/Dashboards/AxumUpdateService.controller.js",
"~/app_plugins/Dashboards/AxumUpdateService.service.js",
],
css:[
"~/app_plugins/Dashboards/css/axumupdateservice.min.css",
"~/app_plugins/Dashboards/css/jquery-ui.min.css"
]
}
AxumUpdateService.service.js
angular.module("umbraco.services").factory("AxumUpdateService", function ($http) {
return {
getAll: function (from, to) {
from = from || "";
to = to || "";
return $http.get("/umbraco/api/Axum/GetAllGroupTours" + "?fromDate=" + from + "&toDate=" + to);
}
}
});
AxumUpdateService.controller.js
angular.module("umbraco")
.controller("AxumUpdateService",
function ($scope, $http, AxumUpdateService) {
$scope.getAll = function () {
$scope.load = true;
$scope.info = "Retreiving updates";
AxumUpdateService.getAll($scope.fromDate, $scope.toDate).success(function (data) {
$scope.result = data;
$scope.info = data;
$scope.load = false;
});
};
});
AxumUpdateServiceJquery.js
$(document).ready(function () {
$(".datepicker").datepicker();
});
Not really sure it's the exact same error I've had but what worked for me was to incrementing the clientDependency version in ClientDependency.config to force it to refresh the cached js files.
Maybe not "proper procedure", but it did the trick for me.
I am trying to dynamically get and set a pageTitle for my sample Meteor app, ideally I'd like to use jQuery, but any other solution would be good too.
I am trying to do it the rough way by setting a session when a certain div class exists on the page, but it's not working for some reason.
Basically, I have this:
Template.layout.helpers({
pageTitle: function() { return Session.get('pageTitle'); }
});
And I want to do something like
if ($('section').hasClass('single')) {
Session.set('pageTitle', 'Post Page');
}
Any idea ho to make this work? thanks!
You need to call it in a controller or the templates rendered section like this:
Template.layout.helpers({
pageTitle: function() {
return Session.get('pageTitle');
}
});
// set when a page template renders
Template.posts.rendered = function() {
setPageTitle("Blog Posts");
};
// or with Iron Router on *every* route using some sort of variable
Router.onBeforeAction(function() {
var someDynamicValue = "FOO";
setPageTitle(someDynamicValue);
});
// or in an IronRouter Controller
PostsController = RouteController.extend({
onBeforeAction: function() {
setPageTitle("Blog Posts");
}
});
// helper function to set page title. puts a prefix in front of page, you
// could opt set a boolean to override that
function setPageTitle(titleName) {
var prefix = "My Site - ";
if ($('section').hasClass('single')) {
Session.set('pageTitle', prefix + titleName);
}
}
As #Kuba Wyrobek pointed out, I needed to use the Template.layout.rendered function.
Here's a snippet that works
Template.postsList.rendered = function(){
Session.set('pageTitle', 'Listing Page')
};
Is it possible to navigate to some page by hash and then do some logic and redirect back without rendering new page/module but REFRESH the one, where I was navigating from?
Actually what I want is to do some logic and refresh the same page without showing splash screen.
For example i have simple HTML link:
<a class="language-link" href="#language/en-US">
In language.js i have simple code which is getting data in "activate" function:
define(['plugins/router', 'jquery'], function (router, $) {
return {
activate: function (culture) {
return $.post("api/language", { '': culture }, function () {
router.navigateBack();
}).then(function () { return false; });
},
viewUrl: 'settings/loading'
}; });
Buty my problem is, that for a short period of time, loading.html from viewUrl property is showing up. Right after that I'm going back to previous page.
I want to prevent loading.html page from rendering. How to do that? I'm travelling through the Durandal documentacion and searching in google, but cannot find anything helpfull.
.then(function () { return false; });
The code above was my try to return false from activate function and prevent page from rendering, but does not work :(
EDIT
I want to prevent settings/loading from rendering and REFRESH previous page where I was navigating from.
Yes you can do that by return false using canActivate lifeCycle function (Read more here)
define(['plugins/router', 'jquery'], function (router, $) {
return {
canActivate: function () {
// some logic..
// router.navigateBack();
return false;
}
}; });