Tuesday, September 06, 2016

AngularJS simple add, delete HTML example

If you are just getting starting with AngularJS, then you may find a humongous amount of tutorial and articles on the internet which can help you get confused and lost pretty quickly.

If you know HTML and JavaScript/Jquery and just quickly want to see how AngularJS would change your regular HTML vs JavaScript interaction, then perhaps this quick article may help you. In this demo, I will not be using any server side stuff. No ASP.NET, no PHP. It will be a plain old HTML page, and a small bit of JavaScript.

As of writing, it is based on AngularJS 1.5.8.

In this demo, I will provide user the ability to provide his first name, last name and gender. This information will get added to a table and will be dynamically updated when new row is added. The user will also be able to select one or more rows, and delete them.

All this will happen on the client side, with no postback happening. Additionally, to keep things simple I am not adding ayn session management or database part so nothing will persist if you re-open the page.



JSFiddle: https://jsfiddle.net/saurabhkum/ftod4zqh/


Raw code below:

HTML

<!DOCTYPE html>
<html lang="en"> 
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>AngularJS Demo</title>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">


    
    
</head>
<body data-ng-app="angulardemo" data-ng-controller="appCtrl" class="container">

<table id="table" class="table table-responsive">
<thead>
<tr>
    <th> </th>
    <th>#</th>
    <th>First:</th>
    <th>Last:</th>
    <th>Gender</th>
</tr>
</thead>
<tbody>
    <tr class="records" data-ng-repeat="record in records | orderBy:'-rating'">
        <td><input type="checkbox" data-ng-model="record.selected"/></td>
        <td>{{$index + 1}}</td>
        <td>{{ record.fname }}</td>
        <td>{{ record.lname }}</td>
        <td>{{ record.gender }} </td>
    </tr>
    <tr>
        <td><input data-ng-hide="!records.length"  type="button" data-ng-click="remove()" class="btn pull-left" value="X"></td>
        <td> </td>
        <td> </td>
        <td> </td>
        <td> </td>
    </tr>
    </tbody>
</table>

<hr/>
<form >
<div class="row"><p>
Enter the details below to add new row:
</p></div>
<div class="row">
      <div class="col-md-3"><strong>First Name  </strong><input type="text"  data-ng-model="record.fname" /></div>
      <div class="col-md-3"><strong>Last Name  </strong><input type="text" data-ng-model="record.lname" /></div>
      <div class="col-md-3 form-group">
            <label><input type="radio" name="gender" value="male" checked data-ng-model="record.gender">Male</label>
            <label><input type="radio" name="gender" value="female" data-ng-model="record.gender">Female</label>
      </div>
      <div class="col-md-3"> <input type="button" data-ng-click="addNew()" class="btn btn-primary addnew pull-right" value="Add New"> </div>
</div>
</form>
<hr/>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<script type="text/javascript" src="myscript.js"></script>                      
</body>
</html>


JavaScript


var app = angular.module('angulardemo', []);
app.controller('appCtrl', ['$scope', function($scope) {
    $scope.record = {}; 
    $scope.records=[];
    $scope.addNew = function(){
        $scope.records.push({ 
            'sr': $scope.records.length, 
            'fname':$scope.record.fname,
            'lname': $scope.record.lname, 
            'gender': $scope.record.gender
        });     
    };
    
     $scope.remove = function(){
                var newDataList=[];
                $scope.selectedAll = false;
                angular.forEach($scope.records, function(selected){
                    if(!selected.selected){
                        newDataList.push(selected);
                    }
                }); 
                $scope.records = newDataList;
            };
}]);

Monday, August 22, 2016

Gulp fails on new Visual Studio project, and does not see tasks

So you decide to give the new yet powerful 'Gulp' tool a try and fire up the Visual Studio 2015 IDE. You follow a basic tutorial or document to create a simple Hello World application. Next, you might create the gulpfile.js and define a couple of tasks to automate. Happy with your quick Gulp example project, you execute your project, and get an error.

Error 1

If the error you get is something like below:

cmd.exe /c gulp --tasks-simple
'gulp' is not recognized as an internal or external command,
operable program or batch file.

then, this is what may help you:



  1. Install the latest Node.js from https://nodejs.org/en/ . I installed v4.5.0 as of writing.
  2. Next, open your Windows Command Prompt
  3. Type node -v and hit enter. If you see the version shown then Node is now installed.
  4. Next type on the command prompt: C:\Users\Saurabh>npm install -g gulp
  5. This should now install Gulp on your machine ready for use in your project

Error 2

If the error you get is something like below, where your Task Runner Explorer is not able to see any Gulp tasks and gives "No tasks found" error:



For this error to go away,
  1. Open Command Prompt
  2. Go to the folder of your project, and enter command npm install gulp
  3. Press enter to execute
  4. Now, if you refresh your Task Runner, it should load the tasks




Monday, April 04, 2016

SSL certificate problem on Azure running PHP

So recently I was trying out a piece of code in PHP, and wanted to hit the Google reCaptcha server, but my curl requests all failed for some reason.

I then added an 'echo curl_error($curl);' to my code and was greeted with a "SSL certificate problem: unable to get local issuer certificate" error. Now this was much more meaningful, than a blindly failing curl request.

So here is how I fixed this issue:

Physical file configuration:

  1. Open your Azure file structure, perhaps using your favorite FTP client. I swear by FileZilla!
  2. In your site folder structure, create a folder say, "ini" under the "site" folder.
  3. Create another folder under the 'site' folder named 'ca'
  4. Go to https://curl.haxx.se/docs/caextract.html and download the 'cacert.pem' file. Place this file inside the 'ca' folder
  5. Inside 'ini' folder create a text file 'extensions.ini'
  6. Add the following line to the 'extensions.ini' file - "curl.cainfo=d:\home\site\ca\cacert.pem"
Azure Portal configuration:
  1. Head to your portal.azure.com account
  2. Refer to the documentation on how to configure custom PHP settings.
  3. Open the 'Application Settings' page for your offending Web App.
  4. On this page, under 'App Settings', set 'PHP_INI_SCAN_DIR' to 'd:\home\site\ini'
  5. Remember to hit 'Save' on top of this page, and then restart this Web App.

Wait for a few seconds, and try opening your web page again. My error vanished at this pointed and I was back in business!

Hope this helps someone out there reading this page.

Tuesday, January 26, 2016

Fitbit Sync Battery Drain - Tasker Profile

Recently I got myself a Fitbit Charge HR, which added to my new year resolve to do something proactive to improve my health. Let's see how this resolve stands beyond the first few weeks, but that is out of scope for this blog entry.

I have an Android Nexus 5 phone where I installed my Fitbit app, and via Bluetooth the app syncs with my Fitbit. The device should ideally last around 5 days with a fresh charge, but I noticed mine was lasting hardly for two days! Together with the proprietary charge cable, this, I saw as an added pain.

Quick fixes included:



  • Make very sure that the FitBit is updated to any latest firmware version
  • Turning off the 'Quick View' feature of my Charge HR
  • Turning off  'Add Day Sync'. This was hitting my fitbit almost every 15 minutes or so!
  • Turning off  'Always Connected'. This was bad too for both my phone and the device battery life
I feel this did help a lot in saving battery life of my Fitbit, but now I had to manually remember to sync. I also do not like keeping my bluetooth always open. So I needed someway to automate my fitbit getting synced once or twice a day.

Check on my settings on the shown screenshot of my FitBit.

Tasker to the rescue!

I happen to have Tasker on my phone, which I paid for for it's ease of automating almost anything on my phone. I made a quick profile using it, to solve my requirements.

I can confirm that post my tasker profile, and the above FitBit config changes, instead of max 2 days, I am easily getting 5+ days now!

Profile Features:

Version 1.1 (Feb 19, 2016)
Have tweaked the profile to make it more reliable.
One major change in this version is that during sync, I turn off wifi, and rely on the mobile data for internet connectivity. At least for my testing, I have found this to be much more reliable for some reason in making the FitBit to sync.

I also check if internet is connected, before opening the App. Additionally a few strategic delays were added to allow the system to stabilize post a setting change.

Till now, I am getting sync perfectly as planned, twice a day (7:30 AM and 9:00 PM, but ofcource you can change these times if you need to).

Original version (Jan 26, 2016)
  1. Sync my Fitbit twice a day, at 7 AM and then at 8 PM. This way my curious self gets to see in the morning how was my sleep yesterday, and in the evening to see how my day went.
  2. The profile would turn on bluetooth at the defined time for 5 minutes and will wake up the phone
  3. during this time the profile would also launch the Fitbit app so that a manual sync begins
  4. After 5 minutes, the bluetooth would be turned back off
  5. I think tasker uses the efficient Android API to try to wake up the phone at "approximately" the times defined to try club other wake requests
Download the latest profile XML from here

Do let a comment if this helped you, or if you may improve this further.