javascript .data() cuts the string content by whitespace - javascript

So, I have this problem where I have a backwards-button in a webapplication. This is the javascript-code for the button:
function getPrevFunction()
{
localDBSelect("prevViews", function (prevViews)
{
if (prevViews)
{
var prevViewObject = $.parseJSON(prevViews);
var prevViewArray = prevViewObject['funcObjects'];
if (prevViewArray.length > 1)
{
var prevArrayIndex = prevViewArray.length - 2;
var actArrayIndex = prevViewArray.length - 1;
var prevFuncObject = prevViewArray[prevArrayIndex];
var prevFunc = prevFuncObject['function'];
var prevConfig = prevFuncObject['config'];
var inData = prevFuncObject['inData'];
prevViewArray.splice(actArrayIndex, 1);
if (inData !== "")
{
if (prevFunc !== "getGuiSiteList")
{
inData = "<div data-param=" + JSON.stringify(inData) + ">";
}
$('#fieldcontain')[prevFunc](inData, prevConfig);
}
else {
$('#fieldcontain')[prevFunc](prevConfig);
}
if (prevViewArray.length === 1)
{
setVisibilityForBackBtn(false); //If last..
}
prevViewObject['funcObjects'] = prevViewArray;
localDBInsert("prevViews", JSON.stringify(prevViewObject));
}
else {
setVisibilityForBackBtn(false);
}
$('#subcontainer').html("");
if(!$('#fieldcontain').is(":visible"))
{
$('#fieldcontain').show();
}
}
});
}
My problem is that I don't always get the entire content of the json-object. Eg; the json, at the beginning it looks like this:
input = {site: "GAV", location: "EG", set: "INVENTORY", binnum: "B01 T09"}
but after I have tried to fetch the json that is being passed as a data/attribute with an html-element like so:
var input = $(inData).data("param");
the value I recieve looks as follows:
input = "{"site":"GAV","location":"EG","set":"INVENTORY","binnum":"B01"
As you can se it has by some reason cut off all the characters after the whitespace, despite nothing happens between the fact that the last functions is added to the list, and that function is then called again, too be able to go backwards in the application.
I do realize that my explanation is messy and probably hard to understand, but this is the best that I can explain it.
I can provide more code if necessary.
So, I do need the entire json for the getPrevFunction (it is passed as "prevViews")

Use encodeURIComponent() and decodeURIComponent() like below
Setting the data
inData = "<div data-param=" + encodeURIComponent(JSON.stringify(inData)) + ">";
Getting the data
var input = JSON.parse(decodeURIComponent($(testDv).data('param')));
Now there will be no cuttings in the object due to whitespace.

Related

detect for empty field in angularJS

I'm getting json data with a bunch of spaces as strings like this:
{
appNumber: " "
}
but at times i get this back
{
appNumber: "123456"
}
I want to be able to detect when it doesnt have any numerical value in it and display a dash instead
so in my controller i have:
$scope.appNumber = function() {
var appNumber = $scope.appNumber.trim();
if (!appNumber) {
return "-";
}
return $scope.appNumber;
};
in my HTML:
<div ng-bind="appNumber()"></div>
You are calling trim on the current scope function. change the name of your variable you want to trim
To return appNumber if it is a number or '-' try below
$scope.appNumber = function() {
$scope.str = "12312";
var x = + $scope.str;
if (x.toString() === $scope.str) {
return $scope.str;
}
return '-';
};
Working fiddle

Issues looping through a list of arrays with null data

This is my first question here, hoping you can help. Currently I am trying to loop through an API list of 100 arrays all of which contain one string of data. My loop filters through for numerical data and prints it to a div id. However when I hit data with "#N/A" instead of digits, it breaks my loop. I have tried nesting an if statement that would check if data is null or not, but as it treats null data as an object, this does not work. I have included commented out code to show the things I have tried:
var xhr = new XMLHttpRequest();
var URL = "https://spreadsheets.google.com/feeds/list/0AhySzEddwIC1dEtpWF9hQUhCWURZNEViUmpUeVgwdGc/1/public/basic?alt=json";
xhr.open("GET", URL, false);
xhr.send();
var statusResponseStringify = JSON.stringify(xhr.responseText, "", 2);
var statusResponseParse = JSON.parse(xhr.responseText);
var Find = statusResponseParse.feed.entry;
for (var i = 0; i < Find.length; i++) {
var FTSEContent = statusResponseParse.feed.entry[i].content.$t;
document.getElementById("FTSEName").innerHTML+=FTSEContent + "<br><br>";
var text = FTSEContent;
var value = text.match(/(\d[\d\.]*)/g);
//var price = value[0];
//var change = value[1];
console.log(value);
/*if (typeof value === "number") {
document.getElementById("Change").innerHTML+=value + "<br>";
}
else if (typeof value === null) {
document.getElementById("Change").innerHTML+="N/A" + "<br>";
}
else if (typeof value === "object") {
document.getElementById("Change").innerHTML+="Smell" + "<br>";
}
else {
document.getElementById("Change").innerHTML+="poo" + "<br>";
};*/
if (typeof value == "undefined") {
document.getElementById("Print").innerHTML+="N/A" + "<br>";
}
else {
document.getElementById("Print").innerHTML+=value[0] + "<br>";
};
};
This is the console I get back when I run this code
Could anyone help me with some code ideas to circumvent the null responses when looping. I would ideally like to print the numbers and print an N/A whenever there is a null or #N/A within the API data.
Thank you all!
Rewrite your check: instead of if (typeof value == "undefined") it should be...
if (value === null) { ... }
... as .match() returns null on non-matching, and not undefined.
As a sidenote, your code can be simplified a bit. First, you don't have to repeat the whole statusResponseParse.feed.entry... expression in FTSEContent, use Find instead:
var FTSEContent = Find[i].content.$t;
Second, my understanding is that you check for number in that content string. In this case, you can adjust your pattern a bit:
var value = FTSEContent.match(/(\d+(?:\.\d+)?)/);
... so it won't consume such illegal numbers as '3..' and '3.14.15' (in the last case, only 3.14 will be matched), and doesn't have to match globally (you only process the first result anyway).

How to check and return data until there are no matches?

I have created a function, that will search for different tags, tags like [image] and [gallery] inside a JSON file. If there is a match, it will return and replace it with a new output. Like an image object or a slideshow.
A JSON object can contain multiple tags of the same type, or contain different ones at the same time. So an object can contain two [image] tags for e.g.
JSON
http://snippi.com/s/bzrx3xi
The problem was, if there are multiple [image] tags found, it was replaced with the same content. I was looking for a script that is searching for the tags, until there will no matches anymore. Many thanks to #debatanu for the solution.
Unfortunately, I have some extra wishes for the script, because now the tags like image, will be replaced for the last image object of the media array inside the JSON and it will only grab and replace the first tag.
I was wondering if it is possible to check each tag and replace each tag with the new output.
Search for tags
filterText: function(data) {
// Loop through JSON data
// Check if [tag] in data.text exists
var dataText = data.text;
var tags = {
"gallery": /\[gallery\]/ig,
"image": /\[image\]/ig
};
if (dataText != undefined) {
var raw_data = dataText;
for (var key in tags) {
if (tags.hasOwnProperty(key)) {
var tag = tags[key];
var tagArr = [];
// Check if [tag] in data.text exists
while ( (tagArr = tag.exec(dataText)) !== null ) {
// Call functions
if (key == "gallery") {
console.error('GALLERY');
parsedHTML = raw_data.replace(tagArr[0], shortcodeController.gallery(data));
raw_data = parsedHTML;
return parsedHTML;
}
if (key == "image") {
console.error('IMAGE');
parsedHTML = raw_data.replace(tagArr[0], shortcodeController.image(data));
raw_data = parsedHTML;
return parsedHTML;
// model.find('p').html(parsedHTML);
}
}
}
}
};
Call the filterText function
getDataPopup: function(data) {
if (data.text != undefined) {
$('.js-popup .article').html(data.text);
var parsed = dataController.filterText(data);
console.log('parsed: ', parsed);
$('.js-popup .article').html(parsed);
} else {
$('.js-popup .article').html(data.intro);
}
},
Above function will search for tags inside a while loop.
This script is called, when the user clicked on an item, that will open a popup screen.
The script that is called by the getDataPopup function when the user clicked on an item, will search for a match, when there is a match found, it will call the function shortcodeController.image(data) that return the new output to the variable: parsedHTML.
The function that generates a new output will look like this:
image: function(data) {
// Development
console.log('shortcodeController.image');
var raw_data = data.text;
var outputHTML;
if (data.media != undefined) {
for (var i = 0; i < data.media.length; i++) {
if (data.media[i].image != undefined) {
outputHTML = '<div class="image">';
// Extract filename
var url = data.media[i].image.src;
var filename = url.substring( url.lastIndexOf('/') + 1, url.lastIndexOf('.') );
// console.log(filename);
outputHTML += '<img src="' + url + '" alt="' + filename + '" />';
//data.media[i].image = undefined;
outputHTML +='</div>';
}
};
return outputHTML;
} else {
// If media doesn't exists return empty string
return '';
}
},
Debatanu has mentioned that I should use data.media[i].image = undefined; directly after the outputHTML that contains the actual image object, but this will result in an undefined error. The first [image] tag is replaced by undefined. When I comment this line out, it will be replaced by the last image object inside the media array, as mentioned before.
Maybe it does not work like properly, because the while loop, however, only looks for the gallery and image tags and if there is a match, running it once, because he already saw the tag. Then it will be called again and replaces the first image tag again with the second image object within the media array. Should there might be a while loop added in the if statements on whether it is a gallery or image, so for each tag within the text object is the function called?
Also I noticed, when I console logged tagArr it will give me an value of null when I past it after the while loop and a empty array [] when I paste it directly after the array is created. Beside that, when I console log tag directly after the while loop is started, it only console log tag once, while there are two image tags set inside the JSON.
You can use exec and loop through it using
var dataText = data.text;
var tags = {
"gallery": /\[gallery\]/ig,
"image": /\[image\]/ig,
};
if (dataText != undefined) {
var raw_data = dataText;
for (var key in tags) {
if (tags.hasOwnProperty(key)) {
var tag = tags[key];
var arr=[];
while ((arr= tag.exec(dataText)) !== null) {
//arr[0] will contain the first match
//var newTag=newTags[key];
//you need to replace the matched output
//so no need for newTag
if (key == "gallery") {
console.error('GALLERY');
//replace the matched output arr[0]
//instead tag or newTag
//Since u have [] to replace we need to ommit the regex literal format /<<exp>>/
parsedHTML = raw_data.replace(arr[0], Triptube.shortcodeController.gallery(data));
//Need to add this line for reflecting the changed data
raw_data=parsedHTML;
model.find('p').html(parsedHTML);
}
if (key == "image") {
console.error('IMAGE');
//replace the matched output arr[0]
//instead tag or newTag
//Since u have [] to replace we need to ommit the regex literal format /<<exp>>/
parsedHTML = raw_data.replace(arr[0], Triptube.shortcodeController.image(data));
console.log(parsedHTML);
//Need to add this line for reflecting the changed data
raw_data=parsedHTML;
model.find('p').html(parsedHTML);
}
}
}
}
}
You can find more about it in MDN
With each loop the exec will give you the next match untill no match is left.
EDIT
I have added the entire filter code from the beginning. You see the raw_data variable should be assigned before the loop. Once that is done, the code below with the image function should give you the proper result.
EDIT 2
First the filterText function will return the parsed html post completion of parsing the html
filterText: function(data) {
// Loop through JSON data
// Check if [tag] in data.text exists
var dataText = data.text;
var tags = {
"gallery": /\[gallery\]/ig,
"image": /\[image\]/ig
};
if (dataText != undefined) {
var raw_data = dataText,
newData=JSON.parse(JSON.stringify(data));//Copy of the data object
for (var key in tags) {
if (tags.hasOwnProperty(key)) {
var tag = tags[key];
var tagArr = [];
// Check if [tag] in data.text exists
while ( (tagArr = tag.exec(dataText)) !== null ) {
// Call functions
if (key == "gallery") {
console.error('GALLERY');
parsedHTML = raw_data.replace(tagArr[0], shortcodeController.gallery(newData));
raw_data = parsedHTML;
//return parsedHTML;
}
if (key == "image") {
console.error('IMAGE');
parsedHTML = raw_data.replace(tagArr[0], shortcodeController.image(newData));
raw_data = parsedHTML;
//return parsedHTML; we will return the parsed HTML only when all the tags have been replaced
// model.find('p').html(parsedHTML);
}
}
}
}
return parsedHTML; //return the parsed HTML here
};
Next is the image function which will parse through the images,
image: function(data) {
// Development
console.log('shortcodeController.image');
var raw_data = data.text;
var outputHTML;
if (data.media != undefined) {
for (var i = 0; i < data.media.length; i++) {
if (data.media[i].image != undefined) {
outputHTML = '<div class="image">';
// Extract filename
var url = data.media[i].image.src;
var filename = url.substring( url.lastIndexOf('/') + 1, url.lastIndexOf('.') );
// console.log(filename);
outputHTML += '<img src="' + url + '" alt="' + filename + '" />';
outputHTML +='</div>';
data.media[i].image = undefined;
//Uncommented the above code, because now the operation will be done on the copy of the original data object
}
};
return outputHTML;
} else {
// If media doesn't exists return empty string
return '';
}
}

Parse config string into javascript/JSON [duplicate]

This question already has answers here:
javascript parser for a string which contains .ini data
(4 answers)
Closed 10 years ago.
I have a textarea where the user edits configurations. It is formatted like this:
foo = 'value'
bar = 2.1
john = false
Values can be false, true, floats or strings (no functions). I need to regexp this string to create something like:
{
foo: 'value',
bar: 2.1,
john: false
}
Is there a library or something for this?
I took this answer which should be a good beginning for your request, and added some further rules to handle the different data types, maybe this helps:
var data ="foo = 'value'";
data +="\n" + "bar = 2.1";
data += "\n" + "john = false";
function JSONFY(data){
var regex = {
section: /^\s*\[\s*([^\]]*)\s*\]\s*$/,
param: /^\s*([\w\.\-\_]+)\s*=\s*(.*?)\s*$/,
comment: /^\s*;.*$/
};
var value = {};
var lines = data.split(/\r\n|\r|\n/);
var section = null;
function handleSection(sec) {
var isFloat = /^(?:[1-9]\d*|0)?(?:\.\d+)?$/;
if(sec.match(isFloat)) {
return parseFloat(sec);
} else if(sec=='true') {
return true;
} else if(sec=='false') {
return false;
}
return sec.replace(/^['"]/,'').replace(/['"]$/,'');
}
lines.forEach(function(line){
if(regex.comment.test(line)){
return;
}else if(regex.param.test(line)){
var match = line.match(regex.param);
if(section){
value[section][match[1]] = match[2];
}else{
value[match[1]] = handleSection(match[2]);
}
}else if(regex.section.test(line)){
var match = line.match(regex.section);
value[match[1]] = {};
section = match[1];
}else if(line.length == 0 && section){
section = null;
};
});
return value;
}
console.log(JSONFY(data));
Here is the fiddle to test.
Depending on how much you can trust the input data, you can always write a simple function utilising code like the following (uses jQuery for simplicity's sake):
var lines = $('textarea').val().split('\n');
var output = '{';
$(lines).each(function(l){
output += '\n\t' + lines[l].replace(/(\w+)\s=\s(.*)/, '$1: $2,');
});
output = output.substring(0, output.length - 1);
output += '\n}';
$('textarea').val(output);
The main point here is that you will want to tweak the regex depending on how strict you want to be (i.e. allow whitespace to be optional with a ? after the \s or make sure the values are a specific format.

Difficulty writing a function to extract URL from array

I'm trying to extract a URL from an array using JS but my code doesn't seem to be returning anything.
Would appreciate any help!
var pages = [
"www.facebook.com|Facebook",
"www.twitter.com|Twitter",
"www.google.co.uk|Google"
];
function url1_m1(pages, pattern) {
var URL = '' // variable ready to accept URL
for (var i = 0; i < pages[i].length; i++) {
// for each character in the chosen page
if (pages[i].substr(i, 4) == "www.") {
// check to see if a URL is there
while (pages[i].substr(i, 1) != "|") {
// if so then lets assemble the URL up to the colon
URL = URL + pages[i].substr(i, 1);
i++;
}
}
}
return (URL);
// let the user know the result
}
alert(url1_m1(pages, "twitter")); // should return www.twitter.com
In your case you can use this:
var page = "www.facebook.com|Facebook";
alert(page.match(/^[^|]+/)[0]);
You can see this here
It's just example of usage RegExp above. Full your code is:
var pages = [
"www.facebook.com|Facebook",
"www.twitter.com|Twitter",
"www.google.co.uk|Google"
];
var parseUrl = function(url){
return url.match(/^(www\.[^|]+)+/)[0];
};
var getUrl = function(param){
param = param.toLowerCase();
var page = _(pages).detect(function(page){
return page.toLowerCase().search(param)+1 !== 0;
});
return parseUrl(page);
};
alert(getUrl('twitter'));
You can test it here
In my code I have used Underscore library. You can replace it by standard for or while loops for find some array item.
And of course improve my code by some validations - for example, for undefined value, or if values in array are incorrect or something else.
Good luck!
Im not sure exactly what you are trying to do, but you could use split() function
var pair = pages[i].split("|");
var url = pair[0], title=pair[1];

Categories