0

I have built a simple Bootstrap-based form. The collected user input are displayed at the bottom of the page (thanks to AngularJS):

<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.8/angular.min.js"></script>
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" />

<body ng-app>
<form>
  <fieldset class="border rounded">
  <legend class="alert alert-info">Keywords</legend>
    <div class="form-group row" id="IT-keywords">
      <label for="keywordsIT" class="col-auto col-form-label">Five <span class="badge badge-pill badge-warning">Italian</span> keywords:</label>
      <div class="col">
        <input type="text" class="form-control" name="keywordsIT" id="keywordsIT1" ng-model="keywordsIT1">
      </div>
      <div class="col">
        <input type="text" class="form-control" name="keywordsIT" id="keywordsIT2" ng-model="keywordsIT2">
      </div>
      <div class="col">
        <input type="text" class="form-control" name="keywordsIT" id="keywordsIT3" ng-model="keywordsIT3">
      </div>
      <div class="col">
        <input type="text" class="form-control" name="keywordsIT" id="keywordsIT4" ng-model="keywordsIT4">
      </div>
      <div class="col">
        <input type="text" class="form-control" name="keywordsIT" id="keywordsIT5" ng-model="keywordsIT5">
      </div>
    </div>
    <div class="form-group row" id="EN-keywords">
      <label for="keywordsEN" class="col-auto col-form-label">Five <span class="badge badge-pill badge-warning">English</span> keywords:</label>
      <div class="col">
        <input type="text" class="form-control" name="keywordsEN" id="keywordsEN1" ng-model="keywordsEN1">
      </div>
      <div class="col">
        <input type="text" class="form-control" name="keywordsEN" id="keywordsEN2" ng-model="keywordsEN2">
      </div>
      <div class="col">
        <input type="text" class="form-control" name="keywordsEN" id="keywordsEN3" ng-model="keywordsEN3">
      </div>
      <div class="col">
        <input type="text" class="form-control" name="keywordsEN" id="keywordsEN4" ng-model="keywordsEN4">
      </div>
      <div class="col">
        <input type="text" class="form-control" name="keywordsEN" id="keywordsEN5" ng-model="keywordsEN5">
      </div>
    </div>
  </fieldset>
</form>

<p>My five Italian keywords: {{keywordsIT1}}, {{keywordsIT2}}, {{keywordsIT3}}, {{keywordsIT4}}, {{keywordsIT5}}.</p>
<p>My five English keywords: {{keywordsEN1}}, {{keywordsEN2}}, {{keywordsEN3}}, {{keywordsEN4}}, {{keywordsEN5}}.</p>
</body>

I was wondering whether it would be possible to sort alphabetically the list of keywords after the user has typed them, so that if:

  • {{keywordsEN1}} = b, {{keywordsEN2}} = d, {{keywordsEN3}} = a, {{keywordsEN4}} = e, {{keywordsEN5}} = c

the result is:

  • a, b, c, d, e.

Any help will be greatly appreciated. Thank you all.

1 Answer 1

2

I would suggest you use arrays instead as they are easier to handle. This way all you need to do is sort the array and then join the elements in the array with a ,. I'm using filter to filter out all the null or undefined values before sorting so that they are omitted. Use localeCompare and convert your strings to lowercase during sort so that it will work correctly even if there are capital letters in your input.

Also, since Italian words contain accents/diacritics (Eg. è or ò), you will need to normalize the input before you sort the array.

Here is a working example.

angular.module('app', [])
  .controller('ctrl', ['$scope', ($scope) => {
    $scope.keywordsIT = new Array(5);
    $scope.keywordsEN = new Array(5);

    $scope.sortKeywordsIT = function() {
      return $scope.keywordsIT
        .filter(keyword => !!keyword)
        .map(keyword => keyword.normalize("NFD"))
        .sort((k1, k2) => k1.toLowerCase().localeCompare(k2.toLowerCase()))
        .join(', ');
    }

    $scope.sortKeywordsEN = function() {
      return $scope.keywordsEN
        .filter(keyword => !!keyword)
        .sort((k1, k2) => k1.toLowerCase().localeCompare(k2.toLowerCase()))
        .join(', ');
    }
  }]);
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.8/angular.min.js"></script>
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" />

<body ng-app="app" ng-controller="ctrl">
  <form>
    <fieldset class="border rounded">
      <legend class="alert alert-info">Keywords</legend>
      <div class="form-group row" id="IT-keywords">
        <label for="keywordsIT" class="col-auto col-form-label">Five <span class="badge badge-pill badge-warning">Italian</span> keywords:</label>
        <div class="col">
          <input type="text" class="form-control" name="keywordsIT" id="keywordsIT1" ng-model="keywordsIT[0]">
        </div>
        <div class="col">
          <input type="text" class="form-control" name="keywordsIT" id="keywordsIT2" ng-model="keywordsIT[1]">
        </div>
        <div class="col">
          <input type="text" class="form-control" name="keywordsIT" id="keywordsIT3" ng-model="keywordsIT[2]">
        </div>
        <div class="col">
          <input type="text" class="form-control" name="keywordsIT" id="keywordsIT4" ng-model="keywordsIT[3]">
        </div>
        <div class="col">
          <input type="text" class="form-control" name="keywordsIT" id="keywordsIT5" ng-model="keywordsIT[4]">
        </div>
      </div>
      <div class="form-group row" id="EN-keywords">
        <label for="keywordsEN" class="col-auto col-form-label">Five <span class="badge badge-pill badge-warning">English</span> keywords:</label>
        <div class="col">
          <input type="text" class="form-control" name="keywordsEN" id="keywordsEN1" ng-model="keywordsEN[0]">
        </div>
        <div class="col">
          <input type="text" class="form-control" name="keywordsEN" id="keywordsEN2" ng-model="keywordsEN[1]">
        </div>
        <div class="col">
          <input type="text" class="form-control" name="keywordsEN" id="keywordsEN3" ng-model="keywordsEN[2]">
        </div>
        <div class="col">
          <input type="text" class="form-control" name="keywordsEN" id="keywordsEN4" ng-model="keywordsEN[3]">
        </div>
        <div class="col">
          <input type="text" class="form-control" name="keywordsEN" id="keywordsEN5" ng-model="keywordsEN[4]">
        </div>
      </div>
    </fieldset>
  </form>
  <p>My five Italian keywords: {{sortKeywordsIT()}}.</p>
  <p>My five English keywords: {{sortKeywordsEN()}}.</p>
</body>

Sign up to request clarification or add additional context in comments.

6 Comments

Thank you very much, @nash11! Your solution works quite well, but the downside of this approach is that .sort() method is case-sensitive. So if you type: {{keywordsEN1}} = New York, {{keywordsEN2}} = city, {{keywordsEN3}} = town, {{keywordsEN4}} = United States, {{keywordsEN5}} = America the result will be: America, New York, United States, city, town. What about injecting a orderBy filter inside the controller instead? I can't manage to modify your code correctly by my own...
@Gianluca - I have edited my answer so that the sorting works by converting the strings to lowercase before comparing them. This should work for you :)
Now it works like a charm, thank you! :-) Just for the record, I eventually managed to modify your very first code using the orderBy method; I'm not sure it is "clean" from a stylistic point of view, but... it works as well! ;-)
angular.module('app', []) .controller('ctrl', ['$scope', 'orderByFilter', function($scope, orderBy) { $scope.keywordsIT = new Array(5); $scope.keywordsEN = new Array(5); $scope.sortKeywordsIT = function() { return orderBy($scope.keywordsIT).filter(keyword => !!keyword).map(keyword => keyword.normalize("NFD")).join(', '); } $scope.sortKeywordsEN = function() { return orderBy($scope.keywordsEN).filter(keyword => !!keyword).map(keyword => keyword).join(', '); } }]);
@Gianluca - although that might work for English, for Italian, if you use accents (eg. à), it will not sort properly with the code you provided using orderBy :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.