Not able to get the values needed from javascript using substring - javascript

Background
I currently have built a webApi that I used to crawl a SharePoint collection. I am getting images base64 and all the properties needed via csom. I am returning all these value via my controller to a word.js app that I am working on.
Question
The string value I am getting is "width=611px;height=262px;" . As you may be able to tell I am looking to get the width and height from this string and assign them to separate variables.
Current Approach
I have had this conversation before concerning Regex and substring and it is widely known that using substring is more efficient than regex expression. However I wonder if in this case a regex expression will be more effective than using substring?
Current Code
var Widthtest = contentObject.ImageSize[x].replace("width=", '').replace("height=", '').replace("px", '').replace(";", '').trim();
Current Code Problems
The code example supplied gets the values of both height and width combined in one string.
The code example supplied is rudimentary and may cause confusion for other developers
Desired Result
My ultimate goal is to have two variables which hold the value of the width and height separately. From a string that follows the same format as "width=611px;height=262px;"
var height = height.value;
var width = width.value;

The string is a fixed format, all you need to know is the position of the first ; - from that you can extract the values based on their offset within the string. Personally I see no reason to employ a regular expression.
var pos = str.indexOf(";");
var w = str.substr(6, pos - 8);
var h = str.substr(pos + 8, str.length - pos - 11);

One option you have is to use regex to set capturing groups for the two values separately. You can use...
var re = /width=(\d{1,4})px;height=(\d{1,4})px;/;
...as your regex. The pattern assumes that both the height and width will be between 1 and 4 digits long. The first capturing group will be the width value, and the second is the height value.
To use it practically and assign these captured values how you want, you do this:
var height = re.exec('width=611px;height=262px;')[2]; //2 for the second capturing group
var width = re.exec('width=611px;height=262px;')[1]; //1 for the first capturing group
var testStr = 'width=611px;height=262px;';
var re = /width=(\d{1,4})px;height=(\d{1,4})px;/;
console.log('Width: %d', Number(re.exec(testStr)[1]));
console.log('Height: %d', Number(re.exec(testStr)[2]));

It partly depends on the reliability of your input data. A significant advantage of a Regex is that it provides a convenient way to validate the format of the whole input string.
Not that I would necessarily recommend this approach for readability concerns, but you can do it as a one-liner using destructuring assignment in Javascript 1.7+:
[ , width, height ] = (/width=(\d+)px;height=(\d+)px;/.exec(str) || [0,0,0]).map(Number);
Note that [0,0,0] is our default fallback in case of an invalid format of the input string.
Full test code:
var str = "width=611px;height=262px;",
width, height;
[ , width, height ] = (/width=(\d+)px;height=(\d+)px;/.exec(str) || [0,0,0]).map(Number);
console.log('Width = ' + width);
console.log('Height = ' + height);
Output:
Width = 611
Height = 262
Alternate version
This one is more 'academic':
var str = "width=611px;height=262px;",
size, width, height;
if(size = /width=(\d+)px;height=(\d+)px;/.exec(str)) {
[ width, height ] = size.slice(1).map(Number);
}
else {
throw "invalid format";
}
Without Regex
If your input data is reliable enough and you don't need to check its format, something like that should work just as well:
var str = "width=611px;height=262px;",
width, height;
[ width, height ] = str.split('=').slice(1).map(function(s) { return parseInt(s, 10); });

Related

Converting time to hexidecimal then to string using javascrit

I am trying to convert present time to hexidecimal then to a regular string variable.
For some reason I can only seem to produce an output in double quotes such as "result" or an object output. I am using Id tags to identify each div which contains different messages. They are being used like this id="somename-hexnumber". The code if sent from the browser to a node.js server and the ID is split up into two words with first section being the person's name then "-" is the split key then the hexidecimal is just the div number so it is easy to find and delete if needed. The code I got so far is small but I am out of ideas now.
var thisRandom = Date.now();
const encodedString = thisRandom.toString(16);
var encoded = JSON.stringify(encodedString);
var tIDs = json.name+'-'+encoded;
var output = $('<div class="container" id="'+tIDs+'" onclick="DelComment(this.id, urank)"><span class="block"><div class="block-text"><p><strong><'+json.name+'></strong> '+json.data+'</p></div></div>');
When a hexidecimal number is produced I want the output to be something like 16FE67A334 and not "16FE67A334" or an object.
Do you want this ?
Demo: https://codepen.io/gmkhussain/pen/QWEdOBW
Code below will convert the time/number value d to hexadecimal.
var thisRandom = Date.now();
function timeToHexFunc(x) {
if ( x < 0) {
x = 0xFFFFFFFF + x + 1;
}
return x.toString(16).toUpperCase();
}
console.log(timeToHexFunc(thisRandom));

Converting Percent value to pixel in JavaScript or JQuery

I have a string value in percent unit that will be assign to height but before assigning I need to deduct another height which got by top() the output result is NaN, My code is as below:
var valHeight = "50%";
var result = valHeight - $("#item").css("top");
$("#AnotherItem").height(result);
as valHeight is string and percent and height is pixel the result will be NaN. How may I solve that issue? the valHeight is percent but top value is pixel. I need to have my result as percent
Let's clarify more:
I want to use calc function of CSS and I guess the below code is correct:
$('#AnotherItem').css('height', valHeight).css('height', '-='+itemOffsetTop);
the only problem is I want to use subtracted value in animate function.
First
valHeight is a string you need to convert that to number.
var varlHeight = parseInt("50px");
Second
Your $("#item").top() is invalid, use this instead.
$("#item").offset().top
Putting them together
var valHeight=parseInt("50px");
var result= valHeight - $("#item").offset().top;
$("#AnotherItem").height(result);
Update
Since you've updated your post with a '50%' value. How about doing this kind of approach instead.
var valHeight="50%";
var itemOffsetTop = $("#item").offset().top;
$('#AnotherItem').css('height', valHeight).css('height', '-='+itemOffsetTop);
I see two issues with your code:
valHeight is a string, not a number. It needs to be a number before using it in a math operation.
It's also not clear where you're getting .top() from. Perhaps you meant to use .offset().top?
Example:
var valHeight = 50;
var result = valHeight - $("#item").offset().top;
$("#AnotherItem").height(result + "px");
Now, you modified your question to use 50% and it doesn't really make sense. If you want the result to be 50% of $("#item").offset().top, then you could use something like this:
var valHeight = 0.5;
var result = $("#item").offset().top * valHeight;
$("#AnotherItem").height(result + "px");
You need to use .offset() as there is no method as .top() in jQuery
Get the current coordinates of the first element, or set the coordinates of every element, in the set of matched elements, relative to the document.
valHeight should be a number
Code
var valHeight = 50; //Or, parseInt("50px")
var result = valHeight - $("#item").offset().top;
$("#AnotherItem").height(result + "px");

Find two numbers in a string

This is a follow on from my previous question which can be found here
Link For Previous Question
I am posting a new question as the answer I got was correct, however my next question is how to take it a step further
Basically I have a string of data, within this data somewhere there will be the following;
Width = 70
Void = 40
The actual numbers there could be anything between 1-440.
From my previous question I found how to identify those two digits using regular expression and put them into separate fields, however, my issue now is that the string could contain for example
Part Number = 2353
Length = 3.3mm
Width = 70
Void = 35
Discount = 40%
My question is;
How do I identify only the Width + Void and put them into two separate fields, the answer in my previous question would not solve this issue as what would happen is in this example I would have an array of size 4 and I would simply select the 2nd and 3rd space.
This is not suitable for my issue as the length of array could vary from string to string therefore I need a way of identifying specifically
Width = ##
Void = ##
And from there be able to retrieve the digits individually to put into my separate fields
I am using JavaScript in CRM Dynamics
A simpler option is to convert the whole string into an object and get what you need from that object.
str = "Part Number = 2353\n" +
"Length = 3.3mm\n" +
"Width = 70\n" +
"Void = 35\n" +
"Discount = 40%\n";
data = {};
str.replace(/^(.+?)\s*=\s*(.+)$/gm, function(_, $1, $2) {
data[$1] = $2;
});
alert(data['Width']);
Width\s+=\s+(\d+)|Void\s+=\s+(\d+)
You can try this.Grab the capture.See demo.
http://regex101.com/r/oE6jJ1/31
var re = /Width\s+=\s+(\d+)|Void\s+=\s+(\d+)/igm;
var str = 'Part Number = 2353\n\nLength = 3.3mm\n\nWidth = 70\n\nVoid = 35\n\nDiscount = 40%';
var m;
while ((m = re.exec(str)) != null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
// View your result using the m-variable.
// eg m[0] etc.
}
You can use this regex for matching input with Width and Void in any order:
/(\b(Width|Void) += *(\d+)\b)/
RegEx Demo
Your variable names and values are available in captured groups.

How do I convert String to Number according to locale (opposite of .toLocaleString)?

If I do:
var number = 3500;
alert(number.toLocaleString("hi-IN"));
I will get ३,५०० in Hindi.
But how can I convert it back to 3500.
I want something like:
var str='३,५००';
alert(str.toLocaleNumber("en-US"));
So, that it can give 3500.
Is it possible by javascript or jquery?
I think you are looking for something like:
https://github.com/jquery/globalize
Above link will take you to git project page. This is a js library contributed by Microsoft.
You should give it one try and try to use formt method of that plugin. If you want to study this plugin, here is the link for the same:
http://weblogs.asp.net/scottgu/jquery-globalization-plugin-from-microsoft
I hope this is what you are looking for and will resolve your problem soon. If it doesn't work, let me know.
Recently I've been struggling with the same problem of converting stringified number formatted in any locale back to the number.
I've got inspired by the solution implemented in NG Prime InputNumber component. They use Intl.NumberFormat.prototype.format() (which I recommend) to format the value to locale string, and then create set of RegExp expressions based on simple samples so they can cut off particular expressions from formatted string.
This solution can be simplified with using Intl.Numberformat.prototype.formatToParts(). This method returns information about grouping/decimal/currency and all the other separators used to format your value in particular locale, so you can easily clear them out of previously formatted string. It seems to be the easiest solution, that will cover all cases, but you must know in what locale the value has been previously formatted.
Why Ng Prime didn't go this way? I think its because Intl.Numberformat.prototype.formatToParts() does not support IE11, or perhaps there is something else I didn't notice.
A complete code example using this solution can be found here.
Unfortunately you will have to tackle the localisation manually. Inspired by this answer , I created a function that will manually replace the Hindi numbers:
function parseHindi(str) {
return Number(str.replace(/[०१२३४५६७८९]/g, function (d) {
return d.charCodeAt(0) - 2406;
}).replace(/[०१२३४५६७८९]/g, function (d) {
return d.charCodeAt(0) - 2415;
}));
}
alert(parseHindi("३५००"));
Fiddle here: http://jsfiddle.net/yyxgxav4/
You can try this out
function ConvertDigits(input, source, target) {
var systems = {
arabic: 48, english: 48, tamil: 3046, kannada: 3302, telugu: 3174, hindi: 2406,
malayalam: 3430, oriya: 2918, gurmukhi: 2662, nagari: 2534, gujarati: 2790,
},
output = [], offset = 0, zero = 0, nine = 0, char = 0;
source = source.toLowerCase();
target = target.toLowerCase();
if (!(source in systems && target in systems) || input == null || typeof input == "undefined" || typeof input == "object") {
return input;
}
input = input.toString();
offset = systems[target] - systems[source];
zero = systems[source];
nine = systems[source] + 9;
for (var i = 0 ; i < input.length; i++) {
var char = input.charCodeAt(i);
if (char >= zero && char <= nine) {
output.push(String.fromCharCode(char + offset));
} else {
output.push(input[i]);
}
}
return output.join("");
}
var res = ConvertDigits('१२३४५६७८९', 'hindi', 'english');
I got it from here
If you need a jquery thing then please try this link
Use the Globalize library.
Install it
npm install globalize cldr-data --save
then
var cldr = require("cldr-data");
var Globalize = require("globalize");
Globalize.load(cldr("supplemental/likelySubtags"));
Globalize.load(cldr("supplemental/numberingSystems"));
Globalize.load(cldr("supplemental/currencyData"));
//replace 'hi' with appropriate language tag
Globalize.load(cldr("main/hi/numbers"));
Globalize.load(cldr("main/hi/currencies"));
//You may replace the above locale-specific loads with the following line,
// which will load every type of CLDR language data for every available locale
// and may consume several hundred megs of memory!
//Use with caution.
//Globalize.load(cldr.all());
//Set the locale
//We use the extention u-nu-native to indicate that Devanagari and
// not Latin numerals should be used.
// '-u' means extension
// '-nu' means number
// '-native' means use native script
//Without -u-nu-native this example will not work
//See
// https://en.wikipedia.org/wiki/IETF_language_tag#Extension_U_.28Unicode_Locale.29
// for more details on the U language code extension
var hindiGlobalizer = Globalize('hi-IN-u-nu-native');
var parseHindiNumber = hindiGlobalizer.numberParser();
var formatHindiNumber = hindiGlobalizer.numberFormatter();
var formatRupeeCurrency = hindiGlobalizer.currencyFormatter("INR");
console.log(parseHindiNumber('३,५००')); //3500
console.log(formatHindiNumber(3500)); //३,५००
console.log(formatRupeeCurrency(3500)); //₹३,५००.००
https://github.com/codebling/globalize-example
A common scenario for this problem is to display a float number to the user and then want it back as a numerical value.
In that case, javascript has the number in the first place and looses it when formatting it for display. A simple workaround for the parsing is to store the real float value along with the formatted value:
var number = 3500;
div.innerHTML = number.toLocaleString("hi-IN");
div.dataset.value = number;
Then get it back by parsing the data attribute:
var number = parseFloat(div.dataset.value);
This is a Columbus's egg style answer. It works provided the problem is an egg.
var number = 3500;
var toLocaleString = number.toLocaleString("hi-IN")
var formatted = toLocaleString.replace(',','')
var converted = parseInt(formatted)

What is a robust & nifty way to cycle thru a string and shave off a part of it till

I have a string and in some instances it can be over 150 chars in length(including space and special chars). I was just gonna take the curr length, minus 150 (if greater than 150) and with the remember, shave off a part of the string. I am curious if there is a robust way to do it? The issue is, I don't necessarily want to shave the end. I want to shave the part that resides in a "span" with a certain ID. I want to have that string section and append with "...". So, I have this.
For example. I have.
<div id="divid">
Funny thing is, I went to the store <span id="spanid">on a Tuesday afternoon while the sun was in the sky</span> and rode home with excitement and glee. Did I say it was Tuesday?
</div>
var txtcount = jQuery('#divid').text().length;
var spanidcount = jQuery('#spanid').text().length;
if(txtcount > 140){
var tocut = txtcount - 140;
// here I would reduce the contents of spanid so that the total string count is 140 or less. and have spanid end with "..." - with the ... counting toward the total of 140.
}
A cleaner way would be to use CSS text-overflow:ellipsis on your div. Sample fiddle.
The advantage of this way that you don't trust font size and variant letter width to not screw you up. You always cut the text exactly where you need it. And if div is resized, the ellipsis is automagically adjusted to the right length.
The best thing to do is implement a truncate function. You don't have to extend the String prototype, but I did in this case. :P
http://jsfiddle.net/j89em/1/
String.prototype.truncate = function (len, trail) {
len = len || 10; // default to 10
trail = trail || '...';
return len < this.length ? this.substring(0, len - trail.length) + trail : this;
};
var $div = $('div'),
$span = $div.find('span');
$span.text($span.text().truncate(25));
So you could actually test the total test length and apply the truncate method if needed.
if ($div.text().length > 140) {
$span.text($span.text().truncate(25));
}
You can do it like this:
html:
<p>Funny thing is, I went to the store <span>on a Tuesday afternoon while the sun was in the sky</span> and rode home with excitement and glee. Did I say it was Tuesday?</p>
<button>Reduce</button>
jQ:
var reduceStr = function(str, maxLen) {
return str.substr(0, maxLen-1) + (str.length > maxLen ? '...' : '');
};
$('button').click(function(){
$('span').text(reduceStr($('span').text(), 30));
});
Include this (plug-in) in a script tag or linked from an external .js file sometime after jQuery has been loaded:
(function($) {
$.fn.trimFluff = function(options) {
var settings = $.extend({
'childSelector': '#spanid',
'maxLength': 140
}, options);
return this.each(function() {
var container = $(this);
var child = $(settings.childSelector);
var containerLen = container.text().length;
var childLen = child.text().length;
var fluffToTrim = containerLen - settings.maxLength;
if (containerLen > settings.maxLength) {
if (fluffToTrim > childLen) { //'fluffToTrim' is larger than the child contents...
$(this).find(settings.childSelector).remove(); //remove child
containerLen = container.text().length; //recalc new length
fluffToTrim = containerLen - settings.maxLength; //recalc 'fluffToTrim'
if (containerLen > settings.maxLength) {
//remove "offending length" characters + 3 for the ellipsis and replace with the ellipsis
container.text(container.text().substring(0, containerLen - fluffToTrim + 3) + '...');
//string is now under (or equal to) 140 characters
}
} else {
//remove "offending length" characters + 3 for the ellipsis, from the child, and replace with the ellipsis
child.text(child.text().substring(0, childLen - fluffToTrim + 3) + '...');
}
}
});
};
}(jQuery));
Then call it like so:
$('#divid').trimFluff();
or pass in an options object. There are two options, childSelector which accepts any valid jQuery selector (or element, or jQuery object) and maxLength (which I hope is self-explanatory :) ).
Examples:
$('#divid').trimFluff({childSelector: 'span', maxLength: 150});
$('#divid').trimFluff({childSelector: $('#spanid'), maxLength: 140});
$('#divid').trimFluff({childSelector: 'span#spanid.customClass', maxLength: 160});
var s = document.getElementById('spanid');
$('divid').trimFluff({childSelector: s);
This will trim from the child first, keeping the left side, and if the text to to cut is larger than the child itself, it will remove the child entirely and trim the remaining contents of the div (or other container) until the text is less than the maxLength.
This does not do virtually any error checking, but it will work with any jQuery object where the text() function does something.
Have fun with it.

Categories