I would like to modify an existing JavaScript function that formats a user name properly by setting the first name first letter to upper case, as well as the first name of the last name.
There are some last names that are hyphenated and when those happen, they look like Hugo Bearsotti-potz, when in fact it should be Hugo Bearsotti-Potz
I would like to ask for help to modify this function so it allows proper case to hyphenated last names, if possible.
Here is the existing code (pertinent snippet only):
if (input) {
var out = '';
input.split(delimiter || ' ').forEach(function (sector) {
var x = sector.toLowerCase();
out += x.charAt(0).toUpperCase() + x.substr(1) + ' ';
});
if (out.length > 0) {
out = out.substring(0, out.length - 1);
}
return out;
}
Many thanks.
this should satisfy your test conditions set: http://plnkr.co/edit/9welW6?p=preview
html:
<input type="text" ng-model="foo">
<br>
{{foo | nameCaps}}
js:
app.filter('nameCaps',function(){
return function(input) {
if (!input) return;
return input.toString().replace(/\b([a-z])/g, function(ch) {
return ch.toUpperCase();
});
};
});
although I'm wary about making assumptions about people's names http://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/
You could also create a function for capitalizing the first character after any given delimiter. Not quite as succinct as the regex solution though.
function capitalizeAfter(input, delimiter) {
var output = '',
pieces = input.split(delimiter);
pieces.forEach(function(section, index) {
// capitalize the first character and add the remaining section back
output += section[0].toUpperCase() + section.substr(1);
// add the delimiter back if it isn't the last section
if (index !== pieces.length - 1) {
output += delimiter;
}
}
return output;
}
Then it would be used like so:
if (input) {
return capitalizeAfter(capitalizeAfter(input.toLowerCase(), ' '), '-');
}
Related
I receive a set of functions in text for another software program which I need to modify and then save and am trying to find the best way to do this.
I could receive a text like this:
Sum(Revenue) + Sum({<CostCentre={'$(=Sum(FIELD))'}>}COGS)
I would like to be able to add text directly after Sum( where it is NOT immediately followed by {< Ideally my end result would like this:
Sum(TEXT_I_WANT_TO_ADD Revenue) + Sum({<CostCentre={'$(=Sum(TEXT_I_WANT_TO_ADD FIELD))'}>}COGS)
Any ideas how to achieve this in a simple way? So far my only idea was to use split and then look at the next object of the array to determine if it contains {<, however I am wondering if there is an easier way to do this.
My try (which works and but is hard to follow and not sure if it will always work):
let text = `Sum(Revenue) + Sum({<CostCentre={'$(=Sum(FIELD))'}>}COGS)`;
let input_text = 'TEXT_I_WANT_TO_ADD ';
let split_text = 'Sum('
let split = text.split(split_text);
console.log(split);
let final_text = '';
for (let i in split) {
let split_modified;
// Not last item
if (i < split.length - 1) {
let next = (parseInt(i) + parseInt(1));
// Does not include {<
console.log(next, split[next]);
if (!split[next].includes('{<')) {
final_text += split_text + input_text;
}
// Does include {<
else {
final_text += split_text + split[next]
}
}
// Last item
else {
final_text += split[i]
}
}
console.log(final_text);
Any ideas how to do this is a better, easier way?
You can capture the word inside the parenthesis of Sum() and replace it :
const input_text = "TEXT_I_WANT_TO_ADD ";
const text = `Sum(Revenue) + Sum({<CostCentre={'$(=Sum(FIELD))'}>}COGS)`;
const result = text.replace(/Sum\(\w+\)/g, match => `Sum(${input_text})`);
console.log(result);
I'm working on my final project of the Winter 2017 quarter to demonstrate how to use Regular Expressions in both C# and JavaScript code behind pages. I've got the C# version of my demonstration program done, but the JavaScript version is making me pull what little hair I have left on my head out (no small achievement since I got a fresh buzz cut this morning!). The problem involves not getting any output after applying a Regular Expression in a While loop to get each instance of the expression and printing it out.
On my HTML page I have an input textarea, seven radio buttons, an output textarea, and two buttons underneath (one button is to move the output text to the input area to perform multiple iterations of applying expressions, and the other button to clear all textareas for starting from scratch). Each radio button links to a function that applies a regular expression to the text in the input area. Five of my seven functions work; the sixth is the one I can't figure out, and the seventh is essentially the same but with a slightly different RegEx pattern, so if I fix the sixth function, the seventh function will be a snap.
(I tried to insert/upload a JPG of the front end, but the photo upload doesn't seem to be working. Hopefully you get the drift of what I've set up.)
Here are my problem children from my JS code behind:
// RegEx_Demo_JS.js - code behind for RegEx_Demo_JS
var inputString; // Global variable for the input from the input text box.
var pattern; // Global variable for the regular expression.
var result; // Global variable for the result of applying the regular expression to the user input.
// Initializes a new instance of the StringBuilder class
// and appends the given value if supplied
function StringBuilder()
{
var strings = [];
this.append = function (string)
{
string = verify(string);
if (string.length > 0) strings[strings.length] = string;
}
this.appendLine = function (string)
{
string = verify(string);
if (this.isEmpty())
{
if (string.length > 0) strings[strings.length] = string;
else return;
}
else strings[strings.length] = string.length > 0 ? "\r\n" + string : "\r\n";
}
this.clear = function () { strings = []; };
this.isEmpty = function () { return strings.length == 0; };
this.toString = function () { return strings.join(""); };
var verify = function (string)
{
if (!defined(string)) return "";
if (getType(string) != getType(new String())) return String(string);
return string;
}
var defined = function (el)
{
// Changed per Ryan O'Hara's comment:
return el != null && typeof(el) != "undefined";
}
var getType = function (instance)
{
if (!defined(instance.constructor)) throw Error("Unexpected object type");
var type = String(instance.constructor).match(/function\s+(\w+)/);
return defined(type) ? type[1] : "undefined";
}
}
Within the code of the second radio button (which will be the seventh and last function to complete), I tested the ScriptBuilder with data in a local variable, and it ran successfully and produced output into the output textarea. But I get no output from this next function that invokes a While loop:
function RegEx_Match_TheOnly_AllInstances()
{
inputString = document.getElementById("txtUserInput").value;
pattern = /(\s+the\s+)/ig; // Using an Flag (/i) to select either lowercase or uppercase version. Finds first occurrence either as a standalone word or inside a word.
//result = pattern.exec(inputString); // Finds the first index location
var arrResult; // Array for the results of the search.
var sb = getStringBuilder(); // Variable to hold iterations of the result and the text
while ((arrResult = pattern.exec(inputString)) !==null)
{
sb.appendLine = "Match: " + arrResult[0] ;
}
document.getElementById("txtRegExOutput").value = sb.toString();
/* Original code from C# version:
// string pattern = #"\s+(?i)the\s+"; // Same as above, but using Option construct for case insensitive search.
string pattern = #"(^|\s+)(?i)the(\W|\s+)";
MatchCollection matches = Regex.Matches(userTextInput, pattern);
StringBuilder outputString = new StringBuilder();
foreach (Match match in matches)
{
string outputRegExs = "Match: " + "\"" + match.Value + "\"" + " at index [" + match.Index + ","
+ (match.Index + match.Length) + "]" + "\n";
outputString.Append(outputRegExs);
}
txtRegExOutput.Text = outputString.ToString();
*/
} // End RegEx_Match_The_AllInstances
I left the commented code in to show what I had used in the C# code behind version to illustrate what I'm trying to accomplish.
The test input/string I used for this function is:
Don’t go there. If you want to be the Man, you have to beat The Man.
That should return two hits. Ideally, I want it to show the word that it found and the index where it found the word, but at this point I'd be happy to just get some output showing every instance it found, and then build on that with the index and possibly the lastIndex.
So, is my problem in my While loop, the way I'm applying the StringBuilder, or a combination of the two? I know the StringBuilder code works, at least when not being used in a loop and using some test data from the site I found that code. And the code for simply finding the first instance of "the" as a standalone or inside another word does work and returns output, but that doesn't use a loop.
I've looked through Stack Overflow and several other JavaScript websites for inspiration, but nothing I've tried so far has worked. I appreciate any help anyone can provide! (If you need me to post any other code, please advise and I'll be happy to oblige.)
I'm programming my own autocomplete textbox control using C# and javascript on clientside. On client side i want to replace the characters in string which matching the characters the user was searching for to highlight it. For example if the user was searching for the characters 'bue' i want to replace this letters in the word 'marbuel' like so:
mar<span style="color:#81BEF7;font-weight:bold">bue</span>l
in order to give the matching part another color. This works pretty fine if i have 100-200 items in my autocomplete, but when it comes to 500 or more, it takes too mutch time.
The following code shows my method which does the logic for this:
HighlightTextPart: function (text, part) {
var currentPartIndex = 0;
var partLength = part.length;
var finalString = '';
var highlightPart = '';
var bFoundPart = false;
var bFoundPartHandled = false;
var charToAdd;
for (var i = 0; i < text.length; i++) {
var myChar = text[i];
charToAdd = null;
if (!bFoundPart) {
var myCharLower = myChar.toLowerCase();
var charToCompare = part[currentPartIndex].toLowerCase();
if (charToCompare == myCharLower) {
highlightPart += myChar;
if (currentPartIndex == partLength - 1)
bFoundPart = true;
currentPartIndex++;
}
else {
currentPartIndex = 0;
highlightPart = '';
charToAdd = myChar;
}
}
else
charToAdd = myChar;
if (bFoundPart && !bFoundPartHandled) {
finalString += '<span style="color:#81BEF7;font-weight:bold">' + highlightPart + '</span>';
bFoundPartHandled = true;
}
if (charToAdd != null)
finalString += charToAdd;
}
return finalString;
},
This method only highlight the first occurence of the matching part.
I use it as follows. Once the request is coming back from server i build an html UL list with the matching items by looping over each item and in each loop i call this method in order to highlight the matching part.
As i told for up to 100 items it woks pretty nice but it is too mutch for 500 or more.
Is there any way to make it faster? Maybe by using regex or some other technique?
I also thought about using "setTimeOut" to do it in a extra function or maybe do it only for the items, which currently are visible, because only a couple of items are visible while for the others you have to scroll.
Try limiting visible list size, so you are only showing 100 items at maximum for example. From a usability standpoint, perhaps even go down to only 20 items, so it would be even faster than that. Also consider using classes - see if it improves performance. So instead of
mar<span style="color:#81BEF7;font-weight:bold">bue</span>l
You will have this:
mar<span class="highlight">bue</span>l
String replacement in JavaScript is pretty easy with String.replace():
function linkify(s, part)
{
return s.replace(part, function(m) {
return '<span style="color:#81BEF7;font-weight:bold">' + htmlspecialchars(m) + '</span>';
});
}
function htmlspecialchars(txt)
{
return txt.replace('<', '<')
.replace('>', '>')
.replace('"', '"')
.replace('&', '&');
}
console.log(linkify('marbuel', 'bue'));
I fixed this problem by using regex instead of my method posted previous. I replace the string now with the following code:
return text.replace(new RegExp('(' + part + ')', 'gi'), "<span>$1</span>");
This is pretty fast. Much faster as the code above. 500 items in the autocomplete seems to be no problem. But can anybody explain, why this is so mutch faster as my method or doing it with string.replace without regex? I have no idea.
Thx!
How do I turn this text:
• Ban Ki-moon calls for immediate ceasefire• Residents targeted in
al-Qusayr, witnesses tell HRWIsrael ignoring expanding violence by
settlers, EU reports9.18am: Footage from activists suggests that
opposition forces continue to resist government troops.This footage...
into this text:
Ban Ki-moon calls for immediate ceasefire. Residents targeted in
al-Qusayr, witnesses tell HRW. Israel ignoring expanding violence by
settlers, EU reports. 9.18am: Footage from activists suggests that
opposition forces continue to resist government troops. This
footage...
This needs to be fixed with javascript (multiple .replace commands are possible)
"• " has to be removed and replaced by a ". ", however the first "• " should just be removed
If there is no space after a dot ".", a space must be added (.This footage)
If there is no space before a time (9.18am), a space must be added
If there is no space before a capital letter (HRWIsrael) that is
followed by non-capital letters, then a dot and space ". " must be added in front
of that non-capital letter.
Breaking down into several replace statements (as listed below) is the way I would go about it (working fiddle).
The fixBullets function will turn all bullets into HTML Entities and the fixBulletEntities fixes those. I did this to normalize bullets as I'm not sure if they are just bullet characters or HTML entities in your source string.
The fixTimes function changes "9.18am:" into " 9:18am. " (otherwise, the fixPeriods function makes it look like " 9. 18am" which I am sure you do not want.
One major caveat regarding the fixCapitalsEndSentence function... This will also convert strings like "WOrDS" into "WO. rDS" which may not be what you want.
At the least, this should get you started...
function fixBullets(text) {
var bullets = /•/g;
return text.replace(bullets, '•');
}
function fixBulletEntities(text) {
var bulletEntities = /•/ig;
text = text.replace(bulletEntities, '. ');
if (text.indexOf('. ') === 0) {
text = text.substring(2);
}
return text;
}
function fixTimes(text) {
var times = /(\d+)[\.:](\d+[ap]m):?/ig;
return text.replace(times, ' $1:$2. ');
}
function fixPeriods(text) {
var periods = /[.](\w+)/g;
return text.replace(periods, '. $1');
}
function fixCapitalsEndSentence(text) {
var capitalsEndSentence = /([A-Z]{2,})([a-z]+)/g;
text = text.replace(capitalsEndSentence, function(match1, match2, match3) {
var len = match2.length - 1;
var newText = match2.substring(0, len) + '. ' + match2.substring(len, len + 1) + match2.substring(len + 1) + match3;
return newText;
});
return text;
}
function fixMultipleSpaces(text) {
var multipleSpaces = /\s+/g;
return text.replace(multipleSpaces, ' ');
}
function fixAll(text) {
text = fixBullets(text);
text = fixBulletEntities(text);
text = fixTimes(text);
text = fixPeriods(text);
text = fixCapitalsEndSentence(text);
text = fixMultipleSpaces(text);
return text;
}
I'm working on a form and I'd like to mask the input of the phone numbers. The plugins what I found aren't okay for me since the area code could be 1 or 2 character long.
What I'd like to do is the following:
when the user types his number after the first two character the script inserts a space on keyup, then after the next three and later after every fourth character.
So when someone types 44444444444 then in the textbox appears 44 44 444 4444.
I must check the second group as well, and when someone types there for example 1, the the number must look like: 44 1 444 4444
Is any solution to do that?
You could do something like this:
http://jsfiddle.net/ffwAA/4/
Which applies this function to the string to get the desired formatting:
function formatCode(str){
var result = str;
str = str.replace(/\D+/g, "");
var m = str.match(/^(\d\d)(?:([2-90]\d|1)(?:(\d\d\d)(\d+)?)?)?$/);
if(m){
result = m[1] + " ";
if(m[2]) result += m[2] + " ";
if(m[3]) result += m[3] + " ";
if(m[4]){
result += m[4].split(/(\d{4})/).join(" ");
result = result.replace(/\s+/g, " ");
}
}
return result;
}
And using this jQuery to set it up:
function update(obj){
var val = obj.value;
var got = formatCode(val);
if(got != val)
obj.value = got;
}
var timer;
var prev_val = "";
$('#code').keyup(function(){
clearTimeout(timer);
// when adding numbers at the end of input, update at once
// don't want to update when editing in the middle of the string or removing parts of it
// because it would move the carret location to the end of input, and make it unusable
if(this.value.indexOf(prev_val) == 0){
update(this);
prev_val = this.value;
return;
}
prev_val = this.value;
// in other cases update 1 second after the changes are done
timer = setTimeout(update, 1000, this);
});
Have you tried the maskedInput plugin?
http://digitalbush.com/projects/masked-input-plugin/
I think it can solve your problem.
Hope this helps. Cheers