0

Remove accents and symbols slugify, but leaving dash at the end.

I would also share the same function between controllers , how do?

code:

$scope.slugify = function(slug){
    str = slug.replace("-");
    str = angular.lowercase(str);
    str = str.replace(/[^A-Z0-9]+/ig, "-");        
    $scope.item.slug = str;
}

Example:

source: Neymar the best player!

 return: neymar-the-best-player-

[Resolved]

i found this: https://github.com/paulsmith/angular-slugify

Marco Riesco
  • 401
  • 1
  • 6
  • 17

2 Answers2

2

Main problem:

Remove accents and symbols slugify, but leaving dash at the end.

Before we go to the main problem, there are several parts of you code that needs mending.

  1. The first replace() statement, works for dashes that between any other strings, but would definitely be a problem if dashes are placed in both ends of a string.

e.g. '-Some-Text-' results to 'undefinedSome-Textundefined'

To solve this problem you need to add the second argument for replace() with an empty string.

From:

str = slug.replace("-");

To:

str = slug.replace('-', '');
  1. The second replace() statement has a regular expression flag representing, i, representing for a case-insensitive search. While your regular expression statement suggests an A-Z (uppercase expression), this in fact is redundant, since you've already modified the string into a lower case. So the statement should be changed:

From:

str = str.replace(/[^A-Z0-9]+/ig, "-");

To:

str = str.replace(/[^a-z0-9]+/g, "-");
  1. Now for the main problem, you're simply missing a dash trimming function for both ends of the string.

Add this replace statement after the code in #2

str = str.replace(/^-+|-+$/g, '');

From what I see in your code, this seems to be more of a reusable function rather than something that can be attributed to a controller function. You can create a service for this specific function instead and inject it in your controller.

DEMO

  .controller('SluggerController', function($scope, slugify) {

    $scope.slug = 'Neymar the best player!';
    $scope.item = { slug: '' };

    $scope.slugify = function(slug) {
      $scope.item.slug = slugify(slug);
    };

  })

  .factory('slugify', function() {
    return function(text) {
      return angular.lowercase(text)
        .replace('-', '')
        .replace(/[^a-z0-9]+/g, '-')
        .replace(/^-+|-+$/g, '');
    };
  });

UPDATE:

Since you don't want to include unicode characters as dashed characters then you can incorporate this with #2.

DEMO

Instead of:

str = str.replace(/[^a-z0-9]+/g, "-");

Change it to:

str = str.replace(/[^\u00BF-\u1FFF\u2C00-\uD7FF\w0-9]/g, '-');

As for how I got the regular expression, you can refer to this SO comment

Community
  • 1
  • 1
ryeballar
  • 29,658
  • 10
  • 65
  • 74
  • Thank you for your answer. But tested with some accents and one answer was this: Input: Marco Riescão Output: marco-riesc-o the right would be: marco-riescao – Marco Riesco Jul 25 '15 at 08:59
  • That is the limitation of your second `replace()` statement, even with the solution you have written above does not work with unicode letters. – ryeballar Jul 25 '15 at 10:58
  • The accents are now showing. marco-riescão, Missed taking the accents, I think. – Marco Riesco Jul 25 '15 at 22:18
  • What I had before, I took all signs and accents , that you did , it was great, but the accents are still there .. – Marco Riesco Jul 27 '15 at 20:03
1

To make it public there is a necessary step to return something. Then you can wrap it as a constant and inject in any controller.

app.controller('MainCtrl', function($scope, slugify) {
  $scope.show = function(){
    alert(slugify($scope.someText));
  }
});
app.constant('slugify', function(slug){
    str = slug.replace("-");
    str = angular.lowercase(str);
    str = str.replace(/[^A-Z0-9]+/ig, "-");        
    return  str;
});

Also from the nature of the transformation applied by function it fits the pattern of filter.

app.filter('slugifyFilter', function(){
  return function(slug){
    str = slug.replace("-");
    str = angular.lowercase(str);
    str = str.replace(/[^A-Z0-9]+/ig, "-");        
    return  str;
  }
});

And use like this in template

 {{someText | slugifyFilter}}

See it in action in plunker

Kirill Slatin
  • 6,085
  • 3
  • 18
  • 38