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);
Related
I think this is a weird issue... And maybe another bug!
I insert html via innerHTML to a div like this:
const verbs = ['leave', 'left', 'left'];
const insertion = `${getSpans()}`;
const elem = document.getElementById("container");
elem.innerHTML = insertion;
function getSpans() {
let result = '';
for(let i = 0; i < verbs.length; i++) {
const verb = verbs[i];
if(i === 0){
result += `<tspan id="span1">${verb.trim()}</tspan>`;
result += '<tspan fill="#fcba03"> - </tspan>';
} else if(i === 1) {
result += `<tspan id="span2">${verb.trim()}</tspan>`;
result += '<tspan fill="#fcba03"> - </tspan>';
} else {
result += `<tspan id="span3">${verb.trim()}</tspan>`
}
}
return result;
}
<div id="container"></div>
Here everything works fine and as you see the hyphens between verbs seem to be separated with a single space between each word.
I did the exact same thing in my code (I can not reproduce it here because its consists of multiple files and etc) but the first hyphen seem to be attached to the leave verb!!! I mean there is no space after leave verb...
Here is a proof of what I say:
And what makes it weird is although I'm 100 percent sure that the insertion string into innerHTML is correct (you can see the spans in above image in console) the issue happens.
Also if I make an update in the page like zooming in or out everything get fixed!
What am I missing and how to fix this? Any comments would be appreciated...
I have a sentence stored in a variable.That sentence I need to extract into 4 parts depends on sentence which I have put into variables in my code,I can able to extract here and get into console but I am not getting the whole text of inside the bracket,only I am getting first words.Here is the code below.Can anyone please help me.
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="messages">
SCRIPT
$(document).ready(function() {
regex = /.+\(|\d. \w+/g;
maintext = "Welcome to project, are you a here(1. new user , 2. test user , 3. minor Accident or 4. Major Accident)";
matches = maintext.match(regex);
text_split0 = matches[0].slice(0, -1);
text_split1 = matches[1];
text_split2 = matches[2];
text_split3 = matches[3];
text_split4 = matches[4];
console.log(text_split0);
console.log(text_split1);
console.log(text_split2);
console.log(text_split3);
console.log(text_split4);
$(".messages").append('<li>'+text_split0+'</li><li>'+text_split1+'</li><li>'+text_split2+'</li><li>'+text_split3+'</li><li>'+text_split4+'</li>');
// $("li:contains('undefined')").remove()
});
function buildMessages(text) {
let messages = text.split(/\d\.\s/);
messages.shift();
messages.forEach((v)=>{
let msg = v.replace(/\,/,'').replace(/\sor\s/,'').trim();
$('.messages').append(`<li>${msg}</li>`);
// console.log(`<li>${msg}</li>`);
});
}
let sentenceToParse = "Welcome to project, are you a here(1. new user , 2. test user , 3. minor Accident or 4. Major Accident)";
buildMessages(sentenceToParse);
Use the split function on the String, keying on the digits (e.g. 1.), you will get the preface and each of the steps into an array.
Use the shift function on the Array removes the unneeded preface.
Use forEach to iterate over the values in the array, clean up the text.
Using replace to first remove commas, then remove or with spaces on either side.
Use trim to remove leading and training whitespace.
At this point, your array will have sanitized copy for use in your <li> elements.
If you're only concerned with working through a regex and not re-factoring, the easiest way may be to use an online regex tool where you provide a few different string samples. Look at https://www.regextester.com/
Ok, Try another approach, cause regex for this isn't the best way. Try this:
$(document).ready(function() {
// First part of sentence.
var mainText = "Welcome to project, are you a here(";
// Users array.
var USERS = ['new user', 'test user', 'minor Accident', 'Major Accident'];
var uSize = USERS.length;
// Construct string & user list dynamically.
for(var i = 0; i < uSize; i++) {
var li = $('<li/>').text(USERS[i]);
if(i === uSize - 1)
mainText += (i+1) + ". " + USERS[i] + ")";
else if(i === uSize - 2)
mainText += (i+1) + ". " + USERS[i] + " or ";
else
mainText += (i+1) + ". " + USERS[i] + " , ";
$(".messages").append(li);
}
console.log(mainText); // You will have you complete sentence.
}
Why that way is better? Simple, you can add or remove users inside the user array. String together with your user list will be updated automatically. I hope that help you.
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!
I'm not sure exactly how much this question has something to do with ExtJS and how much with pure JavaScript. Anyways I have a string with comma separated value. I need to use for the GUI so I try to make it as user-friendly as I can. I made most of the things I wanted but one thing I can't accomplish yet. I want to replace all commas in the string with a proper image, which I think will fit very well on what I'm doing but for now - I try with no success.
For those familiar with ExtJS - I'm doing this for each cell in a certain column of a grid with a render function. But I think that maybe the problem must be solved with a pure JavaScript function. Here is what I have by now:
_cusomizeString: function(dates) {
if (dates != null)
{
var date = dates.replace(/,/g,"|");
var www = date.split('|');
var xxx = www.length;
for (var i = 2; i < xxx; i+=3)
{
www[i] = www[i] + '<br />';
}
var ggg = www.toString();
var hhh = ggg.replace(/,/g,'<img src =" ' + D:\dir1\dir2\dir3\dir4\dir5\img.png + ' "/>');
return hhh;
}
return dates;
}
I tried a few variations, now I don't get error but don't see an image either.
Thanks
Leron
P.S
With this change in the function:
var finalString = tempString.replace(/,/g,'<img src ="http://www.finishingtouch.co.uk/assets/images/common/calendar_icon.png"/>');
I am able to visualize this:
The main problem now is how to add the image before the first element, because now it's missing (Noticeable especially when there's only one date) and how I can make it work with local files for now? I've tried using this in my replace function:
'<img src ="file:///D:\\symapac\\src\\public\\img\\icons\\draft.png"/>'
But the console log returns this and I dont see no image:
07-06-2012<img src ="file:///D:\dir1\dir2\dir3\dir4\dir5\img.png"/>16-06-2012
Ok, I have almost final solution. Here is how it looks like:
Here is my final function:
_checkDates: function(dates) {
if (dates != null)
{
var date = dates.replace(/,/g,"|");
var arrayOfDates = date.split('|');
var stringLength = arrayOfDates.length;
for (var i = 2; i < stringLength; i+=3)
{
arrayOfDates[i] = arrayOfDates[i] + '<br />';
}
var tempString = arrayOfDates.toString();
var finalString = tempString.replace(/,/g," ,");
finalString = finalString.replace(/,/g,"<img src="+ "'" + pathToImage + "'" +"/>");
var imgSrc = "<img src="+ "'" + pathToImage + "'" +"/>";
var otuputString = imgSrc.concat(finalString);
return otuputString;
}
return dates;
}
There is that little problem that no matter now many tabs I put in var finalString = tempString.replace(/,/g," ,"); the space between the icons is always the same, no idea why. But that's the closest I get to what I've wanted.
Cheers
Leron
'<img src ="file:///D:/dir1/dir2/dir3/dir4/dir5/img.png"/>'
You have a space before your filename, also your filename isn't in quotes.
I am trying to add and remove things in a string with using arrays. However this following script I created is not working as it doesn't remove numbers that have been submitted:
function updateCCList(id)
{
var MemberClicked = '[' + id + ']';
var ListClickedMembers = document.frmSendMail.hidSenderList.value;
if(ListClickedMembers.indexOf(MemberClicked) == -1)
{
ListClickedMembers += MemberClicked;
}
else
{
ListClickedMembers = ListClickedMembers.replace(/' + MemberClicked + '/g,'');
}
alert(ListClickedMembers);
document.frmSendMail.hidSenderList.value += ListClickedMembers;
}
Any idea what is wrong?
Many thanks,
Paul
The main problem:
ListClickedMembers = ListClickedMembers.replace(/' + MemberClicked + '/g,'');
The first RegExp there looks bad. I think you mean new RegExp('\\['+id+'\\]')
In case you care about avoiding duplicate entries:
document.frmSendMail.hidSenderList.value += ListClickedMembers;
You don't need += there, = will suffice.