add a parameter in url(angularjs) - angularjs

I would like to be able to keep the parameter it in url after the click.
When I'm on the offline page I have this url:
http://localhost:3000/feliway-coupon?src_org=166
And I would like to have the same one once connected. However, the parameters do not remain. And that gives this once connected :
http://localhost:3000/feliway-coupon
And I would just like this parameter (src_org=166) to remain
HTML:
<button ng-click="$ctrl.onConnect()">connect</button>
JS:
onConnect() {
const search = this.$location.search().src_org
if (search === '166') {
this.$location.state().search('src_org', '166')
}
}
I wanted to know if $location could solve this problem? Or by another method but without using ui-router or ng-route.

Related

How to change title using ng-idle title directive

I'm trying to change the page title using ng-idle:
My title:
<title>MySite Local</title>
The code that doesn't seem to be working:
app.run(function (Title) {
Title.idleMessage('You are idle');
});
Taken from https://github.com/HackedByChinese/ng-idle/issues/128
Am I missing anything here? The title doesn't change without the above code either.
I've also got TitleProvider.enabled(true); just in case.
I'm not familiar with that directive, but if all you're trying to do is set the title, a plain old controller will work.
titleController.js
(() => {
"use strict"
angular.module('myApp').controller('titleController', titleController)
function titleController($scope) {
$scope.appTitle = "Hi Dad, I'm in jail!"
}
})()
index.html
{{appTitle}}
Of course, you'd have to add your own logic to detect an idle user.

AngularJS $location replace() replacing last history entry also

On my AngularJS application I need to save only state changes in the browser history. That's why when I'm changing parameters of $location, I'm using replace() method.
For example, When I'm accessing /page1, it is save in the history. 'centre' parameter is added automatically with replace() so it doesn't add a new history entry:
$location.search('centre', hash).replace();
Every time I move a map, 'centre' changes.
When I go to /page2, the new entry in the history is created. When I move map, 'centre' changes.
The thing is that when I press BACK button, I'm going to /page1 but I need to keep 'centre' the same as it was before, but it changes to what was saved together with history entry of /page1.
How would I fix this issue?
I tried to add:
$window.history.replaceState({}, '', $location.absUrl());
After I do replace(), but didn't work.
I found calling the search & replace inside a 0ms timeout ensures it happens in a separate digest cycle from the main state change and prevents the previous state being replaced.
Something like:
$timeout(function() {
$location.search('centre', hash).replace();
}, 0);
This is how I solved this.
First, we need to save search result as previous and current:
$rootScope.$on('$locationChangeStart', function (event, toURL, fromURL) {
if ($rootScope.search.current) {
$rootScope.search.previous = $rootScope.search.current;
}
$rootScope.search.current = $location.search();
});
Then we need to always change the actual location we are in at the moment.
$rootScope.$on('$locationChangeSuccess', function (event, toURL, fromURL) {
$rootScope.actualLocation = $location.path();
});
And if back of forward button was pressed, center must be changed in the URL (using previous search results) without pushing a new history entry.
$rootScope.$watch(function () { return $location.path() }, function (newLocation, oldLocation) {
if ($rootScope.actualLocation === newLocation) {
$location.search('center', $rootScope.search.previous.center).replace();
}
});
I had the same problem and could only get it working by using the native history api, like so:
window.history.replaceState(hash, null, $location.absUrl());

How to reference a form from controller

Background:
I have an AngularJs wizard like app with 3 steps. The wizard steps contain 4 uiRouter states that share a single controller. The first state is an abstract view containing bootstrap pill navigation with a ui-view as a placeholder for the other 3 nested states. The 3 nested states have a separate views that contain uniquely named forms. I would like to control the pill navigation in the the parent state by checking if the current visible form is valid; if the form is invalid then I would hide/disable the ability for the user to click on the next navigation pill.
Note: I'm using the "controller as" syntax declared in the uiRouter states.
Issue:
I don't seem to be able to get a reference to the current viewable form from within the controller.
Here's what I've tried:
1. passing in the reference to the form visible form in an init call --> gets undefined error when I try to write to console
2. renaming the forms and even passing in the scope reference as described in this link:
http://www.technofattie.com/2014/07/01/using-angular-forms-with-controller-as-syntax.html
Demo:
Here's a plnkr link that shows intent:
http://plnkr.co/edit/YUnwoBD2dt4bzbfujJSW
Controller code:
(function () {
'use strict';
angular
.module('recquisitionManagement')
.controller('RecquisitionEditCtrl', [RecquisitionEditCtrl]);
function RecquisitionEditCtrl() {
var vm = this;
// get ref to request form
vm.setRequestForm = function(form) {
vm.requestForm = form;
console.log(form);
// tried to call from form ng-init --> undefined response
}
// console.log($scope.vm.requestForm);
// console.log(vm.requestForm);
vm.recquisition = { id: 0, name: 'some name', date: 'date here' };
vm.requestFormIsInvalid = true; //this.requestForm.$valid;
vm.approvalFormIsInvalid = true;
if (vm.recquisition && vm.recquisition.id > 0) {
vm.title = 'Edit';
} else {
vm.title = 'Create';
}
}
}());
Any suggestions on how to get the needed form reference?
Multiple options are explained here: Can I access a form in the controller?
Also it can be good to rename functions that share the name of the controller and try to use the common angular practice.
yes like so:
<form name="vm.theFormName">
you can then access it via vm
Bit late now I realise but you were passing the ctrl as an array, needed to change this:
.controller('RecquisitionEditCtrl', [RecquisitionEditCtrl]);
to this:
.controller('RecquisitionEditCtrl', RecquisitionEditCtrl);

Intercept cake2 postLink() form posts with jQuery

Has anyone found a way to intercept the default Form::postLink() forms with Jquery?
I would like the form to work without JS (therefore the postLink).
But with JS enabled I want to intercept the post and call it via AJAX.
<?php echo $this->Form->postLink('Delete', array('action'=>'delete', $prospect['Prospect']['id']), array('class'=>'postLink', 'escape'=>false), __('Sure you want to delete # %s?', $prospect['Prospect']['id'])); ?>
generates:
<form action="/admin/prospects/delete/4f61ce95-2b6c-4009-9b89-07e852b0caef" name="post_4f648f773923b" id="post_4f648f773923b" style="display:none;" method="post">
<input type="hidden" name="_method" value="POST"/>
</form>
<a href="#" class="postLink" onclick="if (confirm('Sure you want to delete # 4f61ce95-2b6c-4009-9b89-07e852b0caef?')) { document.post_4f648f773923b.submit(); } event.returnValue = false; return false;">
Delete
</a>
The main problem is that the js is placed inline here. Therefore always triggers even if I try to intercept the click event (or the post event - tried that too):
<script>
$(document).ready(function() {
$('table.list a.postLink').click(function(e) {
e.preventDefault();
alert('Handler for .submit() called.');
// TODO: do ajax request here and return false
return false;
});
});
</script>
So in the end the form always submits normally and redirects - either ignoring any ajax call (catching the form submit) or posting/redirecting regardless of an ajax call just made (catching the click event).
I would like to delete this record via AJAX and - if successful - just remove that table row from DOM. It would be great if one doesn't have to modify all 300+ "delete buttons" in the application for it, though.
If everything fails I could probably still override the FormHelper (extend it and alias it). But I was hoping on a less invasive solution here.
I know this is old, but for any of those searching:
You need to first remove the 'onclick' attribute added to the delete
link.
Then, you add a .click function to the delete link
You need the url (which can be hardcoded or retrieved from the form, which is always the prev element in cakephp Form->postLink
Here is the code:
$(function(){
$('a:contains("Delete")').removeAttr('onclick');
$('a:contains("Delete")').click(function(e){
e.preventDefault();
var form = $(this).prev();
url = $(form).attr("action");
$.post(url);
return false;
});
});
jymboche - what a genius
why didnt i think of it myself?
Well, here is the modified answer of yours:
$(document).ready(function() {
$('table.list a.postLink').removeAttr('onclick');
$('table.list a.postLink').click(function(e) {
e.preventDefault();
if (!confirm('<?php echo __('Sure?')?>')) {
return false;
}
var form = $(this).prev();
var url = $(form).attr("action");
var tr = $(this).closest('tr');
url = url + '.json';
$.post(url).success(function(res) {
if (res.error) {
alert(res.error);
return false;
}
tr.fadeOut(200);
}).error(function() {
alert("Error");
})
return false;
});
});
This is for future reference only.
I will still accept your answer as you gave me the right idea.
jymboche's solution helped me to get to a working answer, but it didn't work fully for me, due to some security cake plugins that I have installed.
Here's what worked for me:
$(function(){
$('a:contains("Delete")').removeAttr('onclick');
$('a:contains("Delete")').click(function(e){
e.preventDefault();
var form = $(this).prev();
var url = $(form).attr("action");
$.ajax({
type: 'POST',
cache: false,
url: url,
data: $(form).serialize(),
success: function(msg) {
// do any extra calls you need to refresh the page
}
});
return false;
});
});
Just an idea, haven't tested it:
<?php echo $this->Form->postLink('Delete', array('action'=>'delete', $prospect['Prospect']['id']), array('class'=>'postLink', 'onclick' => false, 'escape'=>false), __('Sure you want to delete # %s?', $prospect['Prospect']['id'])); ?>
Couple of issues with the current solutions...
First and foremost, the postLink method requires Javascript to be enabled. From Cake's doco:
"Creates an HTML link, but access the url using method POST. Requires javascript to be enabled in browser."
If javascript is disabled, you just get the exact same output - a hidden form, and a link that tries to submit that form with Javascript (but fails, since JS is turned off).
Second, although it will work, it seems weird to use the postLink method, and then use Javacript to undo precisely all the magic that the postLink method creates.
If you want a non-javascript friendly solution, all you have to do is create a regular form that points to the delete method, and put a link below it like this:
<?php echo $this->Form->create('DefaultAvailability', array('url' array('action' => 'delete', $myRecord['ModelName']['id'])));?>
<?php echo $this->Form->end('Delete (no JS)');?>
<a href='#'>Delete (With JS, use AJAX)</a>
Then, for cases when there's no javascript, hide the link below, and the form will work as normal.
For cases when there is javascript, hide the form, and use javascript to make your delete link trigger a submit on your delete form, and handle that submit with ajax.
I've translated the previous jQuery version to Mootools
//We start with foreach, to select all ajax buttons on the page
$$('.ajaxbutton').each(function(item,index){
//remove onClick
item.removeProperty('onclick');
//attach click event
item.addEvent('click', function(e){
//stop click (in my case the form is inside another link)
e.stop();
var form = item.getPrevious();
url = form.get('action');
new Request({
url: url,//url
method: 'post',//method
onSuccess: function(responseText){
//This is not required, we are dimming the button on success
item.getParents()[0].tween('opacity',0.5)
}
}).send();
return false;
});
})

CakePHP and AJAX to update Database without page refresh

I'm working with CakePHP 1.3.7 and I'm trying to do the following:
On a given page, the user can click a link (or image, or button, doesn't matter) that passes a parameter which is saved into a database. BUT, all this, without refreshing the page.
I've been doing some research and I believe I need to use AJAX as well to acomplish this. However, I can't find the a good example/explanation on how to do it.
I think that the idea is to create the link using AJAX, which calls the controller/action that would receive the variable as a parameter and performs the operation to save it in its corresponding field/table of the DB.
Does anyone have a small example of what I want to do? Or maybe point me to some tutorial that explains it... Thanks so much in advance!
EDIT
Well, thank you guys for your replies. THey're not working directly, but I think I'm getting closer to what I want. Here's what i'm doing now:
I have this code in my view:
<div id="prev"><a>click me</a></div>
<div id="message_board"> </div>
I call this JS file:
$(document).ready(function () {
$("#prev").click(function(event) {
$.ajax({data:{name:"John",id:"100"}, dataType:"html", success:function (data, textStatus) {$("#message_board").html(data);}, type:"post", url:"\/galleries\/add"});
return false;
});
});
And my add action in my galleries controller looks like:
function add() {
$this->autoRender = false;
if($this->RequestHandler->isAjax()) {
echo "<h2>Hello</h2>";
print_r($this->data);
$this->layout = 'ajax';
if(!empty($this->data)) {
$fields = array('phone' => 8, 'modified' => false);
$this->User->id = 6;
$this->User->save($fields, false, array('phone'));
}
}
}
When clicking on the '#prev' element, I get a response from the add action, I know because the text 'Hello' is printed inside #message_board. And it does this without refreshing the page, which is why I need. My problem is that I can't make the $.ajax() function to send any data, when it gets to the controller the $this->data is empty, so it never goes inside the if that saves the info to the database (right now it's saving just an easy thing, but I will want it to save the data that comes from the view).
Can anyone see what am I doing wrong? How can I send the data to the controller?
CakePHP does not matter, most of the code you would need for this would be at clientside. Implementing AJAX by yourself is a pain in the $, so you really want to use a library; currently the most popular is probably jQuery. There's a bunch of examples on their AJAX page: http://api.jquery.com/jQuery.ajax/
So, assuming you have something like this in the document:
<form id="s">
<input id="q"/>
<input type="submit" href="Search!"/>
</form>
<div id="r"/>
you can put this in the JavaScript:
$('#s').submit(function(evt) {
evt.preventDefault();
$.ajax({
url: 'foo.php',
data: {
query: $('#q').val()
},
success: function(data) {
$('#r').html(data);
}
});
return false;
});
Then your foo.php only needs to return the fragment HTML that would go into the div#r.
EDIT: I forgot to stop the submit :( Thanks to #Leo for the correction.
EDIT: I can see what your confusion is about. You will not get a data. I haven't worked with CakePHP, but I assume $this->data is what you'd get from $_REQUEST['data']? You don't get that on the server. data is a hash of what is getting submitted; you will directly get the $_REQUEST['name'] and $_REQUEST['id'] (which, I assume, translate into CakePHP as $this->name and $this->id).
You need to add
$('#s').submit(function(evt) {
evt.preventDefault();
To prevent a page refresh, as in Amadans answer just refer to your controller/ action in the url variable
$('#s').submit(function(evt) {
$.ajax({
url: '/patients/search/',
data: {
query: $('#q').val()
},
success: function(data) {
$('#r').html(data);
}
In the patients/add controller action make sure you return a valid result ( in json is good )

Resources