Change Service Portal URL without reloading the page.

amanda_l_webb
Kilo Contributor

Has anyone figured out how to change the URL without reloading the page?

I would like to alter the URL so that my users can send it out and it will pre-populate widget information. Problem is that it reloads. I have tried to figure out how to use ngRoute, ui.route, and history.pushState. All seem to reload the page. Any other thoughts?

Thanks!

1 ACCEPTED SOLUTION

You are right, it seems like that the reason for this is that the $locationChangeStart events gets triggered more than once so you have to build a condition within the event listener.
What has worked for me is the following:



The event listener:


var originalUrl, initUrl;


$rootScope.$on("$locationChangeStart", function(e, newUrl){


        if(newUrl != originalUrl && newUrl != initUrl){


                  $window.history.replaceState(newUrl, $document.title, newUrl);


        }


        originalUrl = newUrl;


        e.preventDefault();


});



The URL change:


$scope.changeURL = function(){


        initUrl = $location.absUrl();



        //Set your desired URL parameters here, you could also extend the current ones with:        


        /*


        var params = $location.search()


        angular.extend(params, {


                  someParam:'test'


        });


          */      


        var params = {


                  someParam:'test',


                  anotherParam:'anotherTest'


        };



        //triggers the $locationChangeStart event


        $location.search($httpParamSerializer(params));


}



Dont forget to inject $document, $httpParamSerializer, $location, $scope and $rootScope in your controller.


Let me know if this worked out for you.


View solution in original post

30 REPLIES 30

It really seems like this should be the magic bit:



$scope.$on('$locationChangeSuccess', function(e) {


if ($scope.ignoreLocationChange){


$scope.ignoreLocationChange = false;


return;


}



but I have that in my code and I still get a refresh. I may step through the table next to see if I can figure out what the difference is..


Rama Chandra D
Kilo Guru

Can you provide the widget code, that I may look into it?



Darshak


OK - so I wrote a small widget to demonstrate the issue:



HTML:


<div>


  <h1>Wassup</h1>


  <input type="text" ng-model="c.userInput" placeholder="type something..."/>


  <button type="button" ng-click="c.submit()" value="submit">Submit</button>


  <div>


      <p>You entered: {{c.submittedInput}}</p>


  </div>


</div>



Client Script:


function($location,$scope) {


  /* widget controller */


  var c = this;


  c.submittedInput = '';



c.submit = function() {


c.submittedInput = c.userInput;


var search = $location.search();


angular.extend(search, {submittedInput: c.submittedInput});


$location.search(search);


};



$scope.$on('$locationChangeSuccess', function(evt){


return;


});



}



Server Script:


(function() {


  /* populate the 'data' object */


  /* e.g., data.table = $sp.getValue('table'); */




})();




Once the user hits the submit button, the location is updated and the screen/controller refreshed. I stole the $locationChangeSuccess bit from the Data Table widget, but it does not seem to have the desired effect.


Hey,



I've tried this and it do not reload the page, until I manually reload it. I removed the location change part though. But it wouldn't work when you send someone the link, because the submittedInput is on the client side and not on the server. So another user would have his instance of widget loaded and not yours. That is what I understand.




Reposting code:



HTML


<div>


  <h1>Wassup</h1>


  <input type="text" ng-model="c.userInput" placeholder="type something..."/>


  <button type="button" ng-click="c.submit()" value="submit">Submit</button>


  <div>


      <p>You entered: {{::data.submittedInput}}</p>


  </div>


</div>



Client :



function($location,$scope) {


  /* widget controller */


  var c = this;


  var submittedInput = c.data.submittedInput || c.userInput;



c.submit = function() {


submittedInput = c.userInput;


var search = $location.search();


angular.extend(search, {submittedInput: submittedInput});


$location.search(search);


};






}


Server:





(function() {


  /* populate the 'data' object */


  /* e.g., data.table = $sp.getValue('table'); */




  data.submittedInput = $sp.getParameter('submittedInput');


  gs.addInfoMessage(data.submittedInput);




  })();




Darshak



Edit: The bold code might not work but you need to get the parameter and then pass it to the client side, if you want to share the link and make it work.You can look at Service Portal: Communicating between the Client Script and the Server Script of a widget - YouTube


I believe input will never be populated in that code, because server.get() or update() are not called. You can get the search parameters, but I kind of stopped writing the snippet and didn't use the parameter because I could already tell it was refreshing. For instance, if I use the code posted below, with a break point in the Client Script, I will hit it when the page loads and when I call search().



This reloads the controller, and I think I have two for a moment as you can see in the screen shot below:


find_real_file.png



This is the behavior that is confusing me... I do not want the client script to be refreshed when I call search().



I added in getting the value from the URL, but the page is refreshing, so this is still not desired behavior.



Curr code:


HTML:


<div>


  <h1>Wassup</h1>


  <input type="text" ng-model="c.userInput" placeholder="type something..."/>


  <button type="button" ng-click="c.submit()" value="submit">Submit</button>


  <div>


      <p>You entered: {{c.submittedInput}}</p>


  </div>


</div>



Server Script:


(function() {


  /* populate the 'data' object */


  /* e.g., data.table = $sp.getValue('table'); */



var test = $sp.getParameter('submittedInput');


$sp.log('test: ' + test);


if(test)


data.submittedInput = test;


})();




Client Script:


function($location,$scope) {


  /* widget controller */


  var c = this;


if(c.data.submittedInput)


c.submittedInput = c.data.submittedInput;



c.submit = function() {


c.submittedInput = c.userInput;


var search = $location.search();


angular.extend(search, {submittedInput: c.submittedInput});


$location.search(search);


};



$scope.$on('$locationChangeSuccess', function(evt){


return;


});



}



Thank you for your help!!