Remove selector criteria in variable value - javascript

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.

Related

HTML DOM check if the text of an element includes specific text?

How to check if an element's innerHTML includes "as me to" (the whole phrase and not just if it includes one of the words)?
I know that it is pretty short, but the question is already stated in the title.
you can use indexOf()
var str = $('some selector id').innerHTML();
var result = str.indexOf("as");
if result is -1 then there is no instance of "as" in the given string.
You can check it using RegExp. If the element has given string, the test() function will return true or false if it's not.
function check(elem, str) {
var element = document.getElementById(elem).innerHTML,
rg = new RegExp(str, 'g'),
res = rg.test(element);
console.log(`Does the ${elem} element contains ${str} - ${res}`);
return res;
}
check('p', 'as');
check('p', 'something');
<p id='p'>ashamed</p>
Try this!
HTML
<div id="source">this word as </div>
JAVASCRIPT
var sourceEl = document.getElementById('source');
if (sourceEl.textContent.includes('as'))
{
alert("Exist");
}
https://jsfiddle.net/n3zkzy1g/5/

Why can I not insert a substring into an array using splice()?

Excuse the petty question, but this is really nagging me. I'm following the mozilla example: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
Can someone explain why this doesn't work:
<body>
<p id="test">
</p>
</body>
var url = "teststring";
document.getElementById("test").innerHTML = (url.split('').splice(2,0,"teststring").join(''));
jsFiddle: https://jsfiddle.net/uyk2p437/1/
The Array#splice method returns an array containing removed elements, in your case, it would be empty and you are applying Array#join method which generates an empty string.
Use String#slice ( or String#substring) method instead :
url.slice(0, 2) + "teststring" + url.slice(2)
var url = "teststring";
document.getElementById("test").innerHTML = url.slice(0, 2) + "1" + url.slice(2);
<body>
<p id="test">
</p>
</body>
Because the return value from splice is the removed items. Not the modified array. It modifies in place
As per MDN
Return value
An array containing the deleted elements. If only one element is removed, an array of one element is returned. If no elements are removed, an empty array is returned.
var url = "teststring";
var split = url.split('');
split.splice(2,0,"teststring"); // this returns an empty array because you aren't removing anything
// but the value in split is now:
// ['t','e','t','e','s','t','s','t','r','i','n','g','s','t','s','t','r','i','n','g']
console.log(split.join('')); // gives you the expected result
Or you can use slice as in Pranav's answer, or substr or substring.

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

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/

jQuery selector: match array attribute's n-th value

I have an attribute for a set of HTML5 objects that is an array. Something like
<button attr=[1,0,0,0,1,1]>test</button>
<button attr=[1,1,0,0,1,1]>test</button>
...
How do I formulate a jQuery selector to match only elements whose n-th value of attr is 1? Something like $("attr[1]=1") that would only select the second button from this example (this syntax does not work, but I wrote it just to give an idea of what I need).
In my case I am not dealing with buttons but with other types of objects, I just wanted so simplify the context of the question.
You can use a custom filter to select only the matched elements.
<button data-attr="[1,0,0,0,1,1]">button 1</button>
<button data-attr="[1,1,0,0,1,1]">button 2</button>
Note that attr is not a valid html attribute for button. I'd suggest you use the data-attr instead. You can use .data('attr') to get the data back.
var selected = $('button').filter(function (idx) {
var attr = $(this).data('attr');
return attr && attr[1] == 1;
});
alert(selected.html());
jsFiddle Demo
You can write your own selector like this (i called it "array", you can use a better name here):
jQuery.expr[':'].array = function (elem, index, match) {
var params = match[3].replace(/^\s+|\s+$/g, '').split(/\s*,\s*/),
attribute = params[0],
arrayindex = parseInt(params[1]),
matchvalue = params[2],
value = JSON.parse($(elem)[attribute](attribute));
return value[arrayindex] == matchvalue;
};
Then, use it like any other selector where the first parameter is the name of the attribute, the second parameter is the index in your array and the third parameter is the expected value:
$('button:array(attr,1,1)');
Fiddle: http://jsfiddle.net/pascalockert/uDnK8/2/

Form value addition with js

I'm trying to write a order form that shows the value of the selected items automatically. The backend is already complete, and on the front end each field, all radio / checkbox, look like this:
<input type="radio" name="shirt-size" value="shirt_size_m[18]" />
'18' being the price, everything else being irrelevant to the front end price calculation. I cannot change the naming convention, so I need to get the value between the brackets on all the <input>s on the page (or below the parent ID), add them together (on update), and append the value to another ID. Jquery is already in use on the site if that makes thongs easier.
I just need to be pointed in the right direction as my JS experience is limited to examples and minor customizations :)
Try using a simple regular expression with Javascript's replace, to replace all non-numeric characters with the empty string:
var str = "shirt_size_m[18]";
var theNumber = parseInt(str.replace(/[^0-9]/g, ''));
alert(theNumber);
Demo: http://jsfiddle.net/XvTaY/1/
You could try something like this:
function calculate_sum(form_id) {
var $form = $(form_id);
var sum = 0;
$checkbox_and_radios = $form.find('input[type=checkbox], input[type=radio]').each(function(){
sum += parseInt($(this).val().match(/^[^\[]+\[(\d+)\]$/)[1]);
});
return sum;
}
$(function(){
$("#id_of_the_form").find('input[type=checkbox], input[type=radio]').change(function(){
var sum = calculate_sum("#form_id");
// I don't know the type of your element containing
// the sum, so I put multiple solutions here:
// some input element
$('#another_id').val(sum);
// or another element
$('#another_id').html(sum);
// I'm assuming you don't really mean append
// If you're sure you want to append: (but then the old value won't be deleted)
$('#another_id').append(sum);
});
});
u can use:
var v;
v = $('#input-identifier').val();
v = v.split("[");
v = v[1];
v = v.split("]");
v = v[0];
// now v has the number

Categories