Replace() before html() and add "&" between two strings - javascript

Please check out this Fiddle Example. It searches for strings that contain "Glucosamine". How can I strip out "Glucosamine" and add an "&" if it returns two strings, like this:
A Item
Sulfate
B Item
Sulfate & HCl
I got an undefined error using .replace("Glucosamine","") after append.
JSON:
[{"title":"A","Ingredient":"Glucosamine Sulfate,Vitamin C"},{"title":"B","Ingredient":"Vitamin D,Glucosamine Sulfate,Glucosamine HCl,Vitamin A"}]
Code:
$.ajax({
url: "text.json",
success: function (data) {
$(data.query.results.json.json).each(function (index, item) {
var title = item.title;
var ingredients = item.Ingredient;
ingredients = ingredients.split(",");
$.each(ingredients,function(i,ingredient){
if (ingredient.indexOf("Glucosamine") >= 0) {
$('.' + title+'glu').append('<h5>'+ingredient+'</h5>')
}
});
});
},
error: function () {}
});
HTML:
<h3>A Item</h3>
<div class="Aglu"></div>
<h3>B Item</h3>
<div class="Bglu"></div>

Answer
The problem is that you are trying (as far as I can tell) to use replace on the jQuery object like so:
// this will not work
$('.' + title+'glu').append('<h5>'+ingredient+'</h5>').replace("Glucosamine","");
The problem is that replace() is a function of the String object in javascript and there is no replace method in the jQuery object. What you want to do is run replace() against the ingredient variable which is a string.
// this will work
$('.' + title+'glu').append('<h5>'+ingredient.replace("Glucosamine","")+'</h5>');
Not answer
However, based on your latest comment, I don't believe this will actually help you. Although it's unrelated to the actual problem you were having, I'll go ahead and quick put down here how I would approach what you are actually trying to do. I would write your function this way:
$(data.query.results.json.json).each(function (index, item) {
var title = item.title;
var ingredients = item.Ingredient;
// this is good. I like the use of split here
ingredients = ingredients.split(",");
// here I would just filter the array. Don't bother with indexOf.
// You can just as easily use regex. I've chosen to use an
// actual regex pattern but you can also use something like this
// just as easily: ingredient.match("Glucosamine");. I just
// chose to use regex for the sake of using i for case insensi-
// tivity. glucosamineBased is now an array of only the glucose
// ingredients
var glucosamineBased = ingredients.filter(function(ingredient){
return ingredient.match(/glucosamine\s/i);
});
// now that we know which ones are actually glucose based, we
// don't need to itterate through them. Instead we can just jump
// on combining them. I use join which works the opposite as
// split above. After they are joined into one big happy string,
// I strip out the glucosamine words. Easy-peasy. Just keep in
// mind that you need g for global (don't just replace the first
// one, but replace all instances of the pattern) and maybe i for
// case insensitivity.
$('.' + title+'glu').append('<h5>' +glucosamineBased.join(' & ').replace(/glucosamine\s/gi, '')+'</h5>');
});
Hope this helps.
Demo
http://jsfiddle.net/HANvQ/
(oops... forgot the demo)

It's trickier to add the ampersand if the array contains more than one instance of the word "Glucosamine", but the following should do the trick:
$(data.query.results.json.json).each(function (index, item) {
var title = item.title;
var ingredients = item.Ingredient;
ingredients = ingredients.split(",");
var string = '';
$.each(ingredients, function (i, ingredient) {
if (ingredient.indexOf("Glucosamine") >= 0) {
ingredient = ingredient.replace("Glucosamine","");
string += (string.length == 0) ? ingredient : " & "+ingredient;
}
});
$('.' + title + 'glu').append('<h5>' + string + '</h5>')
});
http://jsfiddle.net/wDyZd/2/

Related

Remove selector criteria in variable value

I'm creating an online shop, with specific links to products e.g. (http://example.com/products/phones/nexus-5).
I'm using the following code,
var get_product_availability_classname = $("[class$='_availability']").attr('class');
which selects (creates a variable with the value of) the element that has a class ending in "_availability".
Every product page has a different piece of text just before the _availability, like GOOGLENEXUS5_availability, SAMSUNG4KTV_availability, whatever_availability...
What I have to do now is to essentially remove the criteria I used to get that whole class name (i.e. class$='_availability'); using the example above it'd be trimmed from SAMSUNG4KTV_availability to SAMSUNG4KTV.
Possible solutions
I haven't figured how to, but we could use JavaScript's substring() or substr().
You will be best off using Regex in this situation. The following will look for the _availability in the classes string and if it finds it it will capture what came before.
var get_product_availability_classname = $("[class$='_availability']").attr('class');
var matches = /([^\s]*)_availability\b/g.exec(get_product_availability_classname)
if(matches.length > 1){
var your_id = matches[1];
}
Use attr() method with a callback and update the class name using String#replace method with word boundary regex.
Although use attribute contains selector since there is a chance to have multiple classes, in that case, the class can be at the start or between two classes.
var get_product_availability_classname = $("[class*='_availability '],[class$='_availability']");
get_product_availability_classname.attr('class',function(i,v){
return v.replace(/_availability\b/g,'');
});
var get_product_availability_classname = $("[class*='_availability '],[class$='_availability']");
get_product_availability_classname.attr('class', function(i, v) {
return v.replace(/_availability\b/, '');
});
console.log(document.body.innerHTML);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="abc_availability"></div>
<div class="abc_availability class"></div>
<div class="class abc_availability"></div>
<div class="class abc_availability class1"></div>
If there will only ever be a single _ in the class name
var get_product_availability_classname = $("[class$='_availability']").attr('class')
.split(' ') // split the class to individual classes
.filter(function(cls) { // filter ones with _availability
return cls.split('_').pop() == 'availability');
})[0]; // use first match
var product = get_product_availability_classname.split('_')[0]
.split('_') creates an array ["PRODUCT", "availability"] and the [0] selects the first item of this array
alternatively you could also
var product = get_product_availability_classname.split('_availability')[0]
this does the same thing, except it splits on the string _availability, and it doesn't matter how many _ in the prefix
If your string is always in the form x_y, where x and y don't contain an underscore, then you can use the split function to split on the underscore.
var str = "SAMSUNG4KTV_availability";
var result = str.split("_")[0];
console.log(result);
The split function returns an array of strings containing the substring in between each underscore, you use [0] to select the first element in the array.

Selecting by text with Protractor

I am mostly familiar with java selenium, and I am new to both JS and Protractor. Lets say I am trying to click an option from a list of options with a common identifier..
var options = $('.options');
How could I get all elements with that common identifier, and then select one by its text? I can not do driver.findElements like I could in java since there is no reference to driver..
This is what I have tried so far but its not working and I think its due to my inexperience with JS
this.selectCompanyCode = function(companyCode) {
dropDownMenus[0].click();
var companyCodeOptions = $('[ng-bind-html="companyCode"]');
companyCodeOptions.filter(function (elem) {
return elem.getText().then(function text() {
return text === companyCode;
});
}).first().click();
};
Select all elements with common identifier: $$('.options'); That selects all elements with a class of .options -- equivalent of element.all(by.css('.options')). This returns an ElementArrayFinder. Also see .get() for how to choose an element by index from the ElementArrayFinder.
Find by text, you could use cssContainingText(css, text). For example,
var loginBtn = element(by.cssContainingText('button.ng-scope', 'Login'));
But if for some reason those are not providing the expected results, you can use .filter() (docs here) on an ElementArrayFinder to go through the array of elements and find an element based on a condition you specify. For example,
var allOptions = $$('.options');
allOptions.filter(function (elem) {
return elem.getText().then(function (text) {
return text === 'What you want';
});
}).first().click();
And, although I've never used regular Java Selenium (so I don't know if this is the same), but there is indeed a browser reference (and therefore findElements function): http://www.protractortest.org/#/api?view=ProtractorBrowser.
Hope it helps!
Edit:
Using your code:
this.selectCompanyCode = function(companyCode) {
// where is dropDownMenus defined? This has function no reference to it.
dropDownMenus.get(0).click(); // should be this
var companyCodeOptions = $$('[ng-bind-html="' + companyCode + '"]');
return companyCodeOptions.filter(function (elem) {
return elem.getText().then(function text() {
return text === companyCode;
});
}).first().click();
};
second edit:
Assuming company code is unique, you probably don't need to use filter. Try this:
this.selectCompanyCode = function(companyCode) {
dropDownMenus.get(0).click();
var companyCodeOptions = $('[ng-bind-html="' + companyCode + '"]');
return companyCodeOptions.click();
};
Use cssContainingText
element(by.cssContainingText(".option", "text")).click();
http://www.protractortest.org/#/api?view=ProtractorBy.prototype.cssContainingText

How to merge duplicate values in a for loop javascript

I am new to js and I don't understand much of codes and conditions in js.
My question is simple but I need someone to give me a good example if possible as I know what I need but it is getting hard to implement that in code.
This is my code with 2 arrays where the data is coming from.
blind_tmp = '';
for (i=0; i<#All of Blind Relationship Link.length; i++){
blind_tmp = blind_tmp + '<p>[**' + #All of Element Title[i] + '**](' + #All of Blind Relationship Link[i] + ')'
};
What simple needed is that. I want merge records that are duplicates printed.
for example: if Blind Relationship link is AF44 and after 6 elements this AF44 comes again so I want both to be written like 1.AF44,2.AF44
while now it is writing the elements how they come along
example:
AF11,AF22,AF33,AF44,AF55,AF66,AF77,AF44
so in this example you see two AF44
I want them to be written like this
AF11,AF22,AF33,AF44AF44,AF55,AF66,AF77
any help with a code example is appreciated.
The idea is to iterate through each element in the blindRelationshipLink and store those elements in a temporary array which will be used to check the number of occurrence of an array element.
var blindRelationshipLink = ['AF11','AF22','AF33','AF11','AF44','AF44','AF55','AF66','AF77','AF11','AF22','AF11'];
var arrTemp = [];
var p = '';
blindRelationshipLink.forEach(function(arr){
var count = 0;
arrTemp.forEach(function(a){
if(arr === a)
count++;
});
arrTemp.push(arr);
if(count){
count++;
arr= arr + '.' + count;
}
p = p + arr + ',';
});
alert(p);
You test by running the code snippet.
This approach is not best but it may serve your purpose.
Here is a snippet
var elemArray = ['AF11', 'AF22', 'AF33', 'AF44', 'AF55', 'AF66', 'AF77', 'AF44']; // Array of elements
//A new array which which will contain elements which pass our case
var finalArray = [];
elemArray.forEach(function(item) { // loop through main array
// Check if element is present or else push the element
if (finalArray.indexOf(item) == -1) {
finalArray.push(item);
} else {
// if element is there find the index
var getIndex = finalArray.indexOf(item);
// remove the element, else there will be duplicate
finalArray.splice(getIndex, 1);
//concate the matched element
var newElem = item + item;
// push the element in specfic index
finalArray[getIndex] = newElem;
}
})
console.log(finalArray)
Current drawback with this code is what will happen if there are multiple repeated item in the main array. For example presence of AF33 more than twice.
DEMO

Get "id" values from first three tags only and separate them with "," in output

I have a situation, hope experts here will help me to sort it out. I need to get "id" values for first three tags and than on console.log print the values with comma separated.
I have managed to get the values from tag and print it on output. However, I am not able to comma separate them, and the issue is I am getting id of all the number of articles rather than only 3.
This is the jquery code that I come up with
jQuery(document).ready(function($) {
$("article").each(function() {
var info1 = $(this).attr("id");
var info2 = info1.replace( /[^\d]/g, '');
console.log(info2);
});
});
And this is the test
http://jsfiddle.net/0mvjbkhs/1/
Please note that I am not able to do any changes to html, all I can do is to get things done using jquery.
Please help to fix my code, So my output will looks like
[155569, 155570, 155571]
Thank you,
Use the jQuery .map() method which returns an array; if you need a single comma-delimited string, use the JavaScript .join() method. Don't forget :lt(3) which say you want the first three:
var arr1st3 = $('article:lt(3)').map(function() {
return this.id.replace(/[^\d]/g, '');
}).get();
console.log( arr1st3 );//OUTPUT: ["155569", "155570", "155571"]
//If you want [155569, 155570, 155571] as output
//use return +this.id.replace(/[^\d]/g, ''); instead
DEMO
jQuery(document).ready(function($) {
// search by the attribute
var ids = $('article')
// Take only the first three items
.slice(0, 3)
// Loop them to return an array
.each(function() {
// Get just the id and put that in the array
return this.attr('id');
});
// Format your output
console.log('[' + ids.join(', ') + ']');
});
http://jsfiddle.net/0mvjbkhs/4/
jQuery(document).ready(function($) {
var articles = [];
$("article").each(function() {
var info1 = $(this).attr("id").replace( /[^\d]/g, '');
articles.push(info1);
if (articles.length == 3) {
// break;
return false;
}
});
console.log('[' + articles.join(', ') + ']');
});

jQuery .each help, I want to trim() all the strings in an array

I'm splitting a string into an array, then I want to remove the white space around each element. I'm using jQuery. I'm able to do this successfully with 2 arrays but I know it's not correct. How do I loop thru an array and trim each element so the elements keep that change. Thanks for any tips. Here is my working code using two array. Please show me the correct way to do this.
var arVeh = vehicleText.split("|");
var cleanArry = new Array();
$.each(arVeh, function (idx, val) {
cleanArry.push($.trim(this));
});
Cheers,
~ck in San Diego
You don't even really need the idx or val parameters. This appears to work on jsFiddle:
var cleanVehicles = [];
$.each(vehicleText.split("|"), function(){
cleanVehicles.push($.trim(this));
});
EDIT: Now that I've seen what you're really after, try using map:
var cleanVehicles = $.map(vehicleText.split("|"), $.trim);
I'm going to suggest not using the overhead of jQuery for a simple for-loop...
var arVeh = vehicleText.split("|");
for (var i = 0, l = arVeh.length; i < l; ++i) {
arVeh[i] = $.trim(arVeh[i]);
});
Alternatively, get rid of the whitespace from the beginning, and avoid the need for another loop at all.
var arVeh = $.trim(vehicleText).split(/\s*\|\s*/);
Without 'creating' an array in the javascript code (an array will nevertheless be created in memory)
vehicles = $.map(vehicleText.split("|"), function(e,i) { return $.trim(e) });
var my_arr = [' cats', 'dogs ', ' what '];
$.each(my_arr, function (id, val) {
my_arr[id] = $.trim(val);
});
console.log(my_arr);
This will trim the value and set it to the indexed item.
You don't have to use JQuery. Here is your vanilla solution:
testArray.map(Function.prototype.call, String.prototype.trim);
Function.prototype.call calls trim() on each of the elements of the testArray. As simple as that!
Could you not just do this?
var arVeh = vehicleText.split("|");
$.each(arVeh, function (idx, val) {
arVeh[idx] = $.trim(this);
});
//a simple function
function trimArray(dirtyArray){
$.map(dirtyArray.split("|"), function(idx, val){
return $.trim(this);
});
}
trimArray(vehicleArray);
should do the trick
Or you could use some of the awesome power of javascript and use array.prototype. I'm still a little new at using the .prototype of any object... so this isnt guaranteed to work (but it certainly can be done).
Array.prototype.trim = function (){
$.map(dirtyArray.split("|"), function(idx, val){
return $.trim(this);
});
}
someArray.trim()
You need these two jQuery functions:
1.) iterate through array element with ability to edit items:
http://api.jquery.com/jquery.map/
2.) remove blank spaces from beginning and end of a string:
http://api.jquery.com/jQuery.trim/
Use them this way:
array = $.map(array, function(value) { return value.trim();});
Check this JSFiddle:
https://jsfiddle.net/L00eyL4x/49/

Categories