What you do wrong is feed parseFloat() with strings that represent decimal fractions in a human-oriented notation, whereas parseFloat() accepts only the standard format corresponding with the JavaScript number literals, which are region-independent, always use the dot as the decimal separator, and have no thousands separator.
Futhermore, this parseFloat() function, used in all the answers, is too generous in what it accepts as correct input, preventing the detection of what in most cases is incorrect input:
Input      Result
'1Hello'   1
'1 and 2'  1
'1.2+3.4'  1.2
' 25  '    25
In order to get a stricter and therefore better-controlled behavior, I recommend that you implement your own parsing function. Here is mine:
// Parse a decimal fraction with specified thousands
// and group separators:
function /* number */ parse_float
(   /* string */ s      , // string to parse
    /* string */ thousep, // thousands separator, empty string if none
    /* string */ decsep   // decimal separator  , empty string if none
)
{   var /* integer */ whole, frac ; // whole and fractinal parts
    var /* integer */ wnext, fnext; // position of next char after parse
    var /* integer */ fraclen     ; // length of fractional part
    var /* integer */ ofs         ; // offset of the first digit
    var /* boolean */ done        ; // entire string scanned?
    var /* integer */ sign        ; // sign of result
    var /* number  */ res         ; // result
        /* labels  */ end: { whole: {
    // Check parameter types and availability:
    req_param( 's'      , s      , 'string' );
    req_param( 'thousep', thousep, 'string' );
    req_param( 'decsep' , decsep , 'string' );
    
    frac    = 0;
    fraclen = 0;
    res     = NaN;
    // Account for a possible sign:
    switch( s.charAt(0) )
    {   case '-': sign = -1; ofs = 1; break;
        case '+': sign = +1; ofs = 1; break;
        default : sign = +1; ofs = 0; break;
    }
    [done, wnext, whole] = parse_int_ts( s, ofs, thousep );
    if( isNaN( whole )               )           break end;
    if( done                         )           break whole;
    if( s.charAt( wnext ) !== decsep )           break end; 
    
    [done, fnext, frac] = parse_int( s, 0, wnext + 1 );
    if( !done                        )           break end;
    fraclen = fnext - wnext - 1;
    if( fraclen === 0                )           break end;
    } /* whole: */ res = ( whole + frac / Math.pow( 10, fraclen ) ) * sign;
    } /* end:   */ return res;
}
// Require that a value be specified and have the expected type:
function req_param( /* string */ param, /* variant */ val, /* string */ type )
{   var /* string */ errmsg;
    errmsg = ''; if( val === undefined   ) errmsg = 'is undefined';
    else         if( val === null        ) errmsg = 'is null';
    else         if( typeof val !== type ) errmsg = `must of type \`${type}'`;
    if( errmsg !== '' ) // there has been an error
    {   throw new Error(`Parameter \`${param}' ${errmsg}.`);  }
}
// Parse an integer with a specified thousands separator:
function /* object[] */ parse_int_ts
(   /* string    */ s    , // input string
    /* integer   */ start, // start position
    /* character */ sep  , // thousands separator
)
// Returns an array of:
//   0: boolean -- entire string was scanned
//   1: integer -- index of next character to scan
//   2: integer -- resulting inteer 
{   var /* boolean */ full;
    var /* integer */ next;
    var /* integer */ res;
    var /* integer */ len;
    var /* integer */ psep;
    var /* integer */ result;
    
    res     = 0;
    psep    = 0;
    while( true )
    {   result = NaN; // mark an error
        [full, next, res] = parse_int( s, res, start );
        len = next - start;
        if( len === 0  )                 break; // nothing parsed
        if( sep !== '' )
        {   if( psep  >  0 && len !== 3 ) break; // non-first group not 3 digits
            if( psep === 0 && len  >  3 ) break; // first group longer than 3 digits
        }
        result = res; // mark success
        if( s.charAt(next) !== sep )     break;
        if(  full   )                    break;
        start = next;
        psep  = next;
        start = start + 1;
    }
    return [full, next, result];
}
// Parse a compact of digits beginning at position `start' 
// in string `s' as an integer number:
function /* object[]*/ parse_int
(   /* string  */ s   , // input string
    /* integer */ init, // initial value
    /* integer */ start // start position in `s'
)
// Returns an array of:
// 0: boolean -- entire string was scanned
// 1: integer -- index of next character to scan
// 2: integer -- result
{   const /* integer */ ASCII_0 = 48;
    var /* boolean   */ full; // \
    var /* integer   */ next; //  > the return value
    var /* integer   */ res ; // /
    var /* integer   */ n, i; // string length and current position
    var /* integer   */ code; // character code
    n    = s.length;
    full = true;
    next = n;
    res  = init;
    for( i = start; i < n; i += 1 )
    {   code = s.charCodeAt(i);
        if( code < ASCII_0 || code >= ASCII_0 + 10 )
        {   next = i;
            full = false;
            break;
        }
        res = res * 10 + code - ASCII_0;
    }
    if( code === undefined ) res = NaN;
    return [ full, next, res ];
}
And a test program that uses parse_float() to parse numbers of your format:
function test( /* string */ s )
{   var res;
    res = parse_float( s, ' ', ',' );
    console.log(`${('            ' + `[${s}]`).slice(-12)} => ${res}`);
}
test( ''           );
test( '12'         );
test( '12a'        );
test( '12,'        );
test( '12,345'     );
test( '12 345'     );
test( '123 45'     );
test( '1 234 567'  );
test( '12 345 56'  );
test( '12345'      );
test( '12 435,678' );
test( '+1,2'       );
test( '-2 345'     );
It writes:
          [] => NaN
        [12] => 12
       [12a] => NaN
       [12,] => NaN
    [12,345] => 12.345
    [12 345] => 12345
    [123 45] => NaN
 [1 234 567] => 1234567
 [12 345 56] => NaN
     [12345] => NaN
[12 435,678] => 12435.678
      [+1,2] => 1.2
    [-2 345] => -2345