Showing posts with label AJAX. Show all posts
Showing posts with label AJAX. Show all posts

12/25/16

Add Ajax Request Indicator

Some times it is good practice to notify user that due to his actions (like sending the contact us form) some ajax request been sent and it is been processed. If you not reckon with nprogress angular lib yet, this good opportunity to introduce it... This library is angular implementation of nprogress jquery plugin, and its showing very nice loading bar on top of you application:

How to make it shown only if some ajax request made?

If you don't want to track any other requests like js and css files, only data requests to backend, it may be done by watching pendingRequests property of $http angular service:


myApp.run(function ($rootScope, $http, ngProgressFactory) {
        $rootScope.progrs = ngProgressFactory.createInstance();
        var progresstarted, progressbar = $rootScope.progrs;
        $rootScope.$watch(function() {
            var onlyJsonRequests = $http.pendingRequests.filter(function(r){return r.url.match(/json/g);});
            return onlyJsonRequests.length;
        }, function(n) {
             
            if(n>0 && !progresstarted) {
             
                progresstarted = true; 
                progressbar.setColor('blue');
                progressbar.setParent(document.getElementById('mainContainer')); //set a custom container, otherwise will be attached to "body"
               
                progressbar.start();
            } else if(n===0 && progresstarted) { 
                progressbar.complete(); 
                progresstarted = false;  
            }
        }) 
}) 

Notice that progress bar will be shown only if requests with url property that contains /json/ are sent

Provider is Better

Currently we have a lot of logic inside our run section.
One thing that can make the code more accurate is to move the progress logic to provider recipy:


myApp.provider('progress', function($provide, $injector) {
  this.setPattern = function(pattern) {
    this.pattern = new RegExp(pattern,'g');
  };
  this.setContainer = function(container) {
    this.container = container;
  };
  this.setColor = function(color) {
    this.color = color;
  };
  //will fire when used in one of recipies like "controller" or "directive" or "run"
  this.$get = function ($rootScope, $http, ngProgressFactory) {
        var that = this;
        $rootScope.progrs = ngProgressFactory.createInstance();
        var progresstarted, progressbar = $rootScope.progrs;
        $rootScope.$watch(function() {
            var onlyJsonRequests = $http.pendingRequests.filter(function(r){
              return r.url.match(that.pattern);
            });
            return onlyJsonRequests.length;
        }, function(n) {
            if(n>0 && !progresstarted) {
                progresstarted = true; 
                progressbar.setColor(that.color);
               progressbar.setParent(document.getElementById(that.container)); 
                progressbar.start();
            } else if(n===0 && progresstarted) { 
                progressbar.complete(); 
                progresstarted = false;  
            }
        }) 
        return 'watching'
   };
});

Now we can set all the custom settings inside config section:

myApp.config(function(progressProvider) {
  progressProvider.setContainer('mainContainer');
  progressProvider.setPattern('json');
  progressProvider.setColor('blue');

Now inside our run section we can leave only progress injection:

myApp.run(function (progress) {
}) 

If you want to see the full code - look on this plnkr

8/9/16

React - Building Search App (Part 5)

Ajax

In previous parts we have created react functioning application that consists from 3 components, which can communicate and respond to events, but what kind of app is this if it only displaying some static data?
Of course we need to do to some server request for bring some real data.
Unlike angular that has its own http service, react doesn't have helper functions for ajax and this due to its convention - to be lighter as possible.
Fot quickly write a code that makes ajax request we will use good old jquery library. Instead of build some server for serve us data we will take an advantage of awesome github api
For example following api will get you repositories those names contains some characters you specified as search param:


   var url = "https://api.github.com/search/repositories?q="+query+"+language:typescript&sort=stars&order=desc";
   $.get(url, function (result) {
      //result.items will contain repositories corresponding to query
   })

Make a Request

Now the only thing left is to get the request to play with the other code:


    //Search Page
    var SearchPage = React.createClass({
      getInitialState: function() {
        return {results: [{text:'some result'}]};
      }, 
      loadResults: function(query){
        
        var url = "https://api.github.com/search/repositories?q="+query+"+language:typescript&sort=stars&order=desc";
        $.get(url, function (result) {
          if(result.items.length!==0){
            var results = result.items.map(item => { 
              return   {text: item.name};//<--- for our app we need each item to have "text" property
            }).slice(0,5);
            this.setState({results:results});
          }
        }.bind(this));//<-- important to bind this for use "setState"
      },
      handleSearchTextChange: function(txt){

        this.loadResults(txt)//<--- calling the request with search term passed from search input
       
      },
      render: function() {
        return (
          <div>
            <SearchBar onTextChange={this.handleSearchTextChange}/>
            <ResultsList results={this.state.results}  />
          </div>
        );
      }
    });
Note that for pass the results to ResultsList component we need only to modify the state using the setState method.

view the code
Hope you have fun reading

2/3/11

Jquery animations

I'm trying to build simple javascript-based navigation that will display different content each time user clicks one the of links in the navbar.
The content stored in separate HTML files that containing only specific article wrapped in "description" div:

Each link on the navbar has the url to proper content file.


I'm using following jquery code to place content in response of user clicks:


The code working fine, but (to improve user experience) i want to make an fadeIn -fadeOut animation: I want the content fade out and after, the other content fade in.
Its looks like this code will do the work:

Looks like, but not.
The new content appears in the content panel even before the fading out starts.
The 'load' function didnt wait to 'fadeOut' to finish.
Here is some solution to fix this:

Now the 'load' is inside the 'fadeOut' - that means it will happen in the end
of fade out animation
[Download code]

1/24/11

Thoughts about Jquery autocomplete plugin

I'm sure you have experinence of building autocomplete functionality in some way. There many ways to do it -for example with  AJAX Control Toolkit. Since i'm teaching myself a jquery now i want to implement the jquery autocomplete plugin in my ASP.NET site.



Its looks easy as it appears in the exapmle :


After placing this javascript you only need to create input with id -"LOCATION" and the things start working.

So far so good.
The only problem for me with this code is that values coming from the Array(cities). I want values to come from the WebService. So i desided to build some small  site project to experience with plugin.
This is the WebService code:

As you can see there is no logic at all- web method returns the ";" deleimted Cities names in string.
Firstly i tryed to fill the values in separate ajax request-But its

Just Not Worked


Why?
Because the AJAX request that fills data in 'cities' Array is asyncronic. It means that when compiler reaches the '.autocomlete(cities' -the cities is still empty.

One way to work this around is to put the 'autocomplete' inside the 'success'  function of request:

This works fine [Download source]
But I'm not content with this solution because i want the 'suggested' values to be filled in response of user enter characters:
For this ,as i saw in plugin documentation i can put the WebService Url directly inside statement:



Here the things started to be messy. The problem is the break point in the code of webservice became not reacheable.

It taked me a long time to figure out what is the problem. I figured that after inside plugin code (jquery.autocomplete.js) in the 'request' funciton i put the error handler



inside '$.ajax' call. Yes, the ajax call of the plugin cannot reach the server unless you put following code inside web.config under 'system.web' node:



Now, after i can reach the server i started to get another error inside 'parse' function inside the plugin that tryes to split the data to rows with '\n' key.
As solution to this problem i decided to override the 'parse' function:

Now the things started to work. Now we see all cities in the list no matter wath user has
entered.
To repair this i had modifyed the WebService- GetCities method:

So now the method getting user input as parameter.
The only thing left is to modify the 'data' sended with the request inside the 'request' function of the plugin:

Now the thing is realy working:




[Download the source]

Getting started with docker

It is very simple to get started usig docker. All you need to do-is download the docker desktop for your system Once you get docker syste...