get value of each class of span and put string to input - javascript

I have a list of values in a spans called 'tag-label'. I wish to add the value of each of these spans and insert them in a input field separated by commas.
I have set up a JSFiddle to show it. http://jsfiddle.net/stefanselby/7wrg611k/
My HTML:
<label for="TagsHolder">Keywords</label>
<ul>
<li><span class="tag-label">test 1</span></li>
<li><span class="tag-label">test 2</span></li>
<li><span class="tag-label">test 3</span></li>
</ul>
<input type="text" id="TagsHolder" name="TagsHolder" value="" />
<button id="btn">Update</button>
<p></p>
<p>This is what I require</p>
<input type="text" id="TagsHolder2" name="TagsHolder2" value="test 1,test 2,test 3" />
My Javascript (where I am stuck):
$(document).ready(function(){
$("#btn").click(function(){
$.each($('.tag-label'), function (index, value) {
$("#TagsHolder").val(index);
});
});
});

You can use .map to get an array, then join on a ,
var values = $(".tag-label").map(function() {
return $(this).text();
}).get().join(",");
$("#TagsHolder").val(values);
Fiddle: http://jsfiddle.net/7wrg611k/3/

Several problems with your approach.
index is the array index of the current element, not it's text.
Your loop will replace the value each pass, so only the last value will be seen since each previous value set will be replaced
Your best bet is to create an array and join that array:
$("#btn4").click(function () {
var values = $('.tag-label').map(function () {
return $(this).text();
}).get().join();
$("#TagsHolder").val(values);
});
DEMO

Related

need help to add and remove items from list with jQuery

I'm trying to add and remove sub items with price calcuation with following piece of jQuery
$('.sub_item-plus-button').click( function() {
var li_id = $(this).closest('li').attr('id');
var productname = $('#'+li_id+' > .name').text();
var productPrice = $('#'+li_id+' .price').text();//alert(productPrice);
var parent_cat = $('#temp > #main_category').text();
var price = $('#'+li_id+' .price').text();//alert(price);
$("#product-form").append('<input type="text" id="'+li_id+'" name="prdname[]" value="'+productname+'" />');
$("#product-form").append('<input type="text" id="'+li_id+'" name="prdprice[]" value="'+productPrice+'" />');
$("#product-form").append('<input type="text" id="'+li_id+'" name="prdparent[]" value="'+parent_cat+'" />');
//$("#product-form").append('<input type="text" name="sub_category" value="'+price+'" />');
$('li#'+li_id).append('<li id="'+li_id+'" class="extras"><span class="name">1</span><span class="price">1.00</span><span class="right"><span class="icon-minus-sign-empty">Re</span></span></li>');
set_total_price(productPrice);
});
And HTML is
<ul id="sub_item">
<div class="addExtrasTotal"><span>Total</span> £<span class="totalPrice">0.00</span></div>
<li id="ext1" class="popextra" style="clear: both;"><span class="column6 name">Anchovies</span>
<span class="column6 right">£ <span class="price">1.00</span>
<a class="button item-plus" href="JavaScript: void(0);"><span class="sub_item-plus-button">+</span></a>
</span>
</li>
<li id="ext2" class="popextra" style="clear: both;"><span class="column6 name">Artichokes</span>
<span class="column6 right">£ <span class="price">1.00</span>
<a class="button item-plus" href="JavaScript: void(0);"><span class="sub_item-plus-button">+</span></a>
</span>
</li>
</ul>
The Problem with I need help is;
1.When Adding, first time, it adds 1 item, 2nd time, it add 2 items instead of 1 and 3rd time click it adds 3 items.
2.When removing items, it removes all the items on single click in one go but remove price of single item from total and rest of the sub items price still added in total.
Price & item remove function is;
function ri(li_id){
//alert(li_id);
var price = $('#'+li_id+' .price').text(); //alert(price);
var extrass = $('#'+li_id+' .extras').html(); alert(extrass);
$('#'+li_id+' .extras').remove();
set_total_price_minus(price);
}
Really appericate the help to figure out the problem and solution.
Regards
The issue is due to id ambiguity. You are assigning the same id attribute to multiple elements in the $('.sub_item-plus-button').click() function, so jQuery gets confused when trying to select these elements by id. The id attribute is meant to be unique, so only a single element should be assigned a given id.

JQuery Multiple Hidden Values

I have the following HTML;
<ul class="list-group">
<li class="list-group-item">
www.andrewspiers.co.uk
<input type="hidden" name="url" value="www.andrewspiers.co.uk">
</li>
<li class="list-group-item">
wikipedia.org
<input type="hidden" name="url" value="wikipedia.org">
</li>
</ul>
The plan is to add a button to each row and then get the value from the hidden field when the button is clicked.
I have this;
alert( $('input[name="url"]').val() );
But that returns the value of the first row no matter which button is clicked.
This should work:
$('button').click(function(){
console.log($(this).closest('li').find('input[name="url"]').val())
})
You need to use $(this) within the click function to refer to that specific element and then traverse the DOM accordingly (multiple ways to skin a cat on this one) to get the hidden input.
jsFiddle example
Assuming your buttons are placed inside the same li, you need a more specific selector:
alert( $(this).siblings('input[name="url"]').val() );
You can add buttons like this :
$('.list-group-item').each(function(){
$(this).append('<input class="clicked" type="button" value="Click me"/>')
})
YOu can then get value of each hidden according to the button like this:
$('.clicked').on('click',function(){
var hiddenval =$(this).parent().find('input[name="url"]').val();
console.log(hiddenval);
})

Get Checkbox to toggle div based on only the string inside a checkbox's label - jQuery

I'm trying to create a script to hide divs based on just the label of a "checked" checkbox. And do it without having to use a specific value, id or attribute. I was previously shown how to do it using spans/divs, but checkboxes have got me stumped.
My example in jsfiddle:
http://jsfiddle.net/6qLX7/2/
HTML:
<fieldset class="filter-row">
<div class="row-section">
<div class="row-heading">art</div>
<ul>
<li>
<div class="checkbox">
<input type="checkbox" name="studio art" value=".studio_art" id="studio_art" />
<label for="studio_art">studio art</label>
</div>
</li>
<li>
<div class="checkbox">
<input type="checkbox" name="ceramics" value=".ceramics" id="ceramics" />
<label for="ceramics">ceramics</label>
</div>
</li>
</ul>
</div>
</fieldset>
<fieldset class="filter-row">
<div class="row-section">
<div class="row-heading">studio art</div>
<ul>
<li>
<div class="checkbox">
<input type="button" value=".option1" name="option1" id="option1" />
</div>
</li>
<li>
<div class="checkbox">
<input type="button" value=".option2" name="option2" id="option2" />
</div>
</li>
</ul>
</div>
<div class="row-section ">
<div class="row-heading">ceramics</div>
<ul>
<li>
<div class="checkbox">
<input type="button" value=".option1" name="option1" id="option1" />
</div>
</li>
<li>
<div class="checkbox">
<input type="button" value=".option2" name="option2" id="option2" />
</div>
</li>
</ul>
</div>
</fieldset>
JS:
$(document).ready(function () {
$("input:checked").click(function () {
var clickedText = $(this).text();
$(".row-section").filter(function () {
return $(this).find("div").text() === clickedText;
}).toggle();
});
});
Forked fiddle: http://jsfiddle.net/ru8YL/1/
I've created a new selector to get the label text that accords with the checkbox: $(this).siblings('label').text().
Select all checkboxes instead of the buttons you previously used: $("input:checkbox").
Use the change event rather than click.
Use .is(':checked') to see if the checkbox is checked or not.
Send toggle a parameter to tell it to hide or show. This second parameter is specified in the documentation: http://api.jquery.com/toggle/
$("input:checkbox").change(function () {
var clickedText = $(this).siblings('label').text();
console.log(clickedText);
$(".row-section").filter(function () {
return $(this).find("div.row-heading").text() === clickedText;
}).toggle(this.checked);
});
$(document).ready(function () {
$("input").change(function () {
var isChecked = $(this).is(":checked");
});
});
use change event instead of click event
Here's my contribution. It just shows there's a large number of ways you can express the same thing using jQuery.
$(document).ready(function () {
$("input:checkbox").click(function () {
var clickedText = $(this).next('label').text();
$("fieldset:nth-child(2) .row-section").filter(function () {
return $('.row-heading', this).text() === clickedText;
}).toggle($(this).is(':checked'));
});
});
http://jsfiddle.net/LhuT9/1/
Compared this with Joe Frambach's answer, it differs by:
This example uses next instead of siblings
The filter function extracts the text using $('.row-heading', this).text() instead of $(this).find("div.row-heading").text()
Yet another alternative, though it's much the same with only minor differences:
// selects all input elements whose type is 'checkbox':
$('input[type="checkbox"]')
// binds an anonymous function to the 'change' event:
.on('change', function(){
// caching the this variable for later use:
var input = this,
// finding whether node.textContent or node.innerText is supported in the browser:
textProp = 'textContent' in document.body ? 'textContent' : 'innerText';
// selecting the '.row-section' elements,
$('.row-section')
// filtering that collection:
.filter(function(){
// using '$.trim()' to remove leading/trailing white-space
return $.trim($(this)
// finding the 'div.row-heading' elements within the current '.row-section':
.find('div.row-heading')
// retrieving its text:
.text())
// comparing for strict equality:
===
// finding the text of the label attached to the element
// the benefit of this approach is that it's independent
// of the DOM structure:
$.trim(input.labels[0][textProp]);
// showing if the input is checked, hiding if not:
}).toggle(input.checked);
// triggering the change event, so the anonymous function is called on page-load:
}).change();
JS Fiddle demo.
References:
JavaScript:
HTMLInputElement, to see a brief introduction to the labels property
jQuery:
$.trim().
change().
find().
filter().
on().
text().
toggle().

jQuery product filter using checkboxes and :contains() show/hide

I'm attempting to put together a simple jQuery product filter for a store that lists all products of a category on one page. This can't be achieved through AJAX because of the way the store is set up.
Simply put, all products of the category are on one page. They have varying brands product names and team names. The markup looks something like this (the form at the end is how I'm planning on doing the filter).
<div id="CategoryContent">
<ul>
<li class="product">Brand1 PRODUCT1 TeamA</li>
<li class="product">Brand1 PRODUCT2 TeamB</li>
<li class="product">Brand2 PRODUCT3 TeamB</li>
<li class="product">Brand2 PRODUCT4 TeamC</li>
<li class="product">Brand3 PRODUCT5 TeamA</li>
<li class="product">Brand3 PRODUCT6 TeamD</li>
<li class="product">Brand4 PRODUCT7 TeamD</li>
<li class="product">Brand1 PRODUCT8 TeamA</li>
<li class="product">Brand1 PRODUCT9 TeamA</li>
<li class="product">Brand1 PRODUCT10 TeamB</li>
<li class="product">Brand4 PRODUCT11 TeamD</li>
<li class="product">Brand2 PRODUCT12 TeamA</li>
</ul>
<div style="clear:both;"></div>
<div class="filter">
<form id= "brandfilter" action="">
<h2>Brands:</h2>
<input type="checkbox" name="brand" value="Brand1"/>Brand1 </br>
<input type="checkbox" name="brand" value="Brand2"/>Brand2 </br>
<input type="checkbox" name="brand" value="Brand3"/>Brand3 </br>
<input type="checkbox" name="brand" value="Brand1"/>Brand4 </br>
</form>
<form id="teamfilter" action="">
<input type="checkbox" name="team" value="TeamA"/>TeamA </br>
<input type="checkbox" name="team" value="TeamB"/>TeamB </br>
<input type="checkbox" name="team" value="TeamC"/>TeamC </br>
<input type="checkbox" name="team" value="TeamD"/>TeamD </br>
</form>
I have found this filter works as I want. In console replacing hide with show and Brand1 with Brand2, TeamA, etc works just fine.
$("#CategoryContent li").not(
$("#CategoryContent li:contains(Brand1)")
).hide();
The next step is getting a double filter which works as well:
$("#CategoryContent li").not(
$("#CategoryContent li:contains(Brand1):contains(TeamA)")
).hide();
My problem with getting this working is two fold. 1 is replacing the Brand1 / Team A with variables (hence the formids).
The second is trying to run the script when a checkbox is clicked. It should work if either one is clicked and if both are clicked (meaning that with the script above it would need to reset by showing all and then hiding).
Currently to initiate it I'm running this script but I'm running into problems so I've gone back to just 1 filter.
$("input:checkbox[name='brand']").click(function() {
var brandfilter = $(this).val();
alert (brandfilter);
$("#CategoryContent li:contains(' + brandfilter + ')").parent().hide();
});
The alert that pops up is what I want (i.e. Brand1) but the hide function afterwards doesn't work and when I alert (brandfilter) again in console again I get [object HTMLFormElement]. So I think the variable isn't storing correctly or something?
Here is the simple working basic script http://jsfiddle.net/7gYJc/
Assuming you want to show items which match any currently ticked box, you can use this:
$('input:checkbox').change(showHideProducts);
function showHideProducts()
{
var checked = $('input:checked');
var products = $('.product');
// If all the boxes are unchecked, show all the products.
if (checked.length == 0)
{
products.show();
}
else
{
products.hide();
checked.each
(
function()
{
$('.product:contains("' + $(this).val() + '")').show();
}
);
}
}​
EDIT: Since you want all the boxes to display when nothing is checked, just add an if (length = 0) check and show everything in there (see above).
I can't tell where the problem is but you can try using filter() instead of the :contains selector. With filter() you can create your own custom filtering rules as it takes a function as parameter.
var myProducts = function (brand, team) {
brand = brand || '';
team = team || '';
return $('.product').filter(function () {
var re = new RegExp(brand + '.+' + team, 'i');
return re.test($(this).text());
});
};
myProducts('Brand1', 'TeamA').hide();
myProducts('Brand2').hide();
Example: http://jsfiddle.net/elclanrs/hYZcW/
I came up with the following approach:
Start with all the checkboxes checked, because you want to show all the products. If the user unticks a checkbox, then it should hide products matching that brand/team.
Here is the code I had:
var $filters = $("input:checkbox[name='brand'],input:checkbox[name=team]").prop('checked', true); // start all checked
var $categoryContent = $('#CategoryContent li'); // cache this selector
$filters.click(function() {
// if any of the checkboxes for brand or team are checked, you want to show LIs containing their value, and you want to hide all the rest.
$categoryContent.hide();
$filters.filter(':checked').each(function(i, el) {
$categoryContent.filter(':contains(' + el.value + ')').show();
});
});​
jsFiddle link.
I had the same kind of problem this week with multiple selects. The selectors worked fine, but hide did not work. I was able to solve it using
.css('visibility', 'hidden'); // instead of .hide() and
.css('visibility', ''); // instead of .show()
I do not understand it, but it worked.

How to loop over nested input forms with jquery

I have the following html form, which is generated dynamically:
<ul class="precursorList">
<li>
Precursor Name: <input name="precursorName" type="text">
<ul class="portList">
<li>Portname of precursor: <input name="precursorPort" type="text">
Portname of this: <input name="thisPort" type="text">
</li>
</ul>
</li>
<li>
<li>
Precursor Name: <input name="precursorName" type="text">
<ul class="portList">
<li>Portname of precursor: <input name="precursorPort" type="text">
Portname of this: <input name="thisPort" type="text">
</li>
</ul>
</li>
<li>
</ul>
I want to get the values using jquery, therefore I have defined this loop:
ports = [];
$(".precursorList :input").each(function() {
if(this.name == "precursorName") {
var precursorName_ = this.value
$(".portList :input ").each(function() {
if(this.name == "precursorPort") {
precursorPort_ = this.value;
} else if(this.name == "thisPort") {
ports.push({
filterName : precursorName_,
portNameOfFilter : precursorPort_,
portNameOfThis : this.value
});
}
});
}
});
Unfortunately this function does not work like I want it to work. The following loop $(".portList :input ").each( will always only loop over all elements in portList in the html document. How can I achieve that this loop will only loop over the corresponding portList, for each precursor?
UPDATE: The structure of the html element will stay the same only, the number of inputs will change. But there will only be a portList if a PrecursorElement exist.
id must be a unique field, instead use class to select multiple elements. Also use .live() for dynamically added elements.
EDIT:
If you are using Jquery > 1.7 use .on() instead of .live().
I tried following and it seems that its working
$(".precursorPort").each(function() {
temp = this.name;
$(this).parents(".portList").each(function() {
$(this).parents(".precursorList").each(function() {
alert(temp);
// use temp var and save it in ports
});
});
});
Check this fiddle : http://jsfiddle.net/Ajinkya_Parakh/DR233/
It may not be the best/most efficient but it is one of the working alternative.
An id must be unique in a document. If you want to create a group of similar things, then use a class instead.
I'd do something like this:
<ul id="precursorList">
<li>
Precursor Name1: <input class="precursor" name="precursorName1" id="precursorName1" type="text">
<ul id="portList1">
<li>Portname of precursor1: <input class="precursorPort" name="precursorPort1" id="precursorPort1" type="text">
Portname of this1: <input class="thisPort" name="thisPort1" id="thisPort1" type="text">
</li>
</ul>
</li>
<li>
Precursor Name2: <input class="precursor" name="precursorName2" id="precursorName2" type="text">
<ul id="portList2">
<li>Portname of precursor2 <input class="precursorPort" name="precursorPort2" id="precursorPort2" type="text">
Portname of this2: <input class="thisPort" name="thisPort2" id="thisPort2" type="text">
</li>
</ul>
</li>
</ul>
and then:
ports = [];
$("#precursorList > li").each(function()
{
precursor = $(this).find(".precursor")[0];
precursorPort = $(this).find(".precursorPort")[0];
thisPort = $(this).find(".thisPort")[0];
ports.push({filterName: precursor.value, portNameOfFilter: precursorPort.value, portNameOfThis: thisPort.value});
});
Step back a minute, I think you're overthinking this a bit.
Wrap your dynamic form in <form> tags. Then do a $('form').serialize() No need for crazy loops. Serialize is essentially a built-in, one line version of what you're already trying to do. Of course, serialize works on names so you'll have to have distinct ones (even if it's just name1, name2,etc) ID's must be unique too, so either fix that or drop them.
Simplicity always trumps crazy technical genius.
Fiddle for proof

Categories