Why is jQuery selector only applied to first item? - javascript

My html form has optional items to display as follows:
<span class="Optional Command1 Command2">
<label for="elem1">Elem 1:</label><input type="text" id="elem1" /><br />
</span>
<span class="Optional Command1 Command3">
<label for="elem2">Elem 2:</label><input type="text" id="elem2" /><br />
</span>
An html select element is used to select Command1, Command2 or Command3 which corresponds to the class for the above html elements.
When the select change event happens, it calls the following function:
function showOptional(commandName) {
$('.Optional').hide(); // clear out optional inputs
$('.Optional').filter('.' + commandName).show(); // show relvant inputs
}
However for Command1, which is included in the class for both elem1 and elem2 above, only the first input element will be displayed, but I thought the jQuery selector would apply both.
In other words, for the above html the showOptional('Command1') Javascript function only displays the first span with Command1, but not the second span with Command1. Why not both?

This works for me:
function showOptional(commandName) {
$('.Optional').hide(); // clear out optional inputsinputs
$('.Optional.' + commandName).show(); // show relvant
}
showOptional('Command1');​
Fiddle: http://jsfiddle.net/sYXuM/1/
However, your original approach works for me as well: http://jsfiddle.net/sYXuM/2/
I just ran a performance test and the following code is faster than your original approach and my suggestion above:
function showOptional(commandName) {
$('.Optional').hide().filter('.' + commandName).show();
}

Related

How to use checked input values used for math as part of cloned div elements

I have written a script that clones a certain div as required by the user. Within the div there are three checkbox input options and each option as a numeric value. I want the script to allow the user to select a checkbox and then the value will be reflected in another input space and each value that are added will be separated by a comma.
The tricky part is that it should be done for each clone, and that each checkbox has the same class name to which the script should be written. I realize that using unique id's would be better, but I would like it that a for loop could do it for any number of checkboxes under the specific class.
Here is the html script:
<style>
.hidden {
display: none;
}
</style>
<body>
<h2>Test</h2>
<button id="add">Add</button>
<div class="test hidden">
<div class="user_input1">
<label>Input1</label>
<input class="input1" type="text" required>
<label>Input2</label>
<input type="text" name="value2" required>
<div class="user_input2">
<table>
<thead>
<tr>
<th>Pick Option</th>
</tr>
</thead>
<tbody>
<tr id="append">
<td><input class="test" type="checkbox" name="test" value="1">Test1</td>
<td><input class="test" type="checkbox" name="test" value="2">Test2</td>
<td><input class="test" type="checkbox" name="test" value="3">Test3</td>
</tr>
</tbody>
</table>
<input type="text" id="insert" name="check">
<button class="hidden" id="testbtn">Calc</button>
</div>
</div>
</div>
<form action="server/server.php" method="POST">
<div class="paste">
</div>
<button type="submit" name="insert_res">Submit</button>
</form>
</body>
And my attempt for the jQuery:
$(document).ready(function() {
var variable = 0
$("#add").click(function() {
var element = $(".test.hidden").clone(true);
element.removeClass("hidden").appendTo(".paste:last");
});
});
$(document).ready(function(event) {
$(".test").keyup(function(){
if ($(".test").is(":checked")) {
var test = $(".test").val();
};
$("#insert").val(test);
});
$("#testbtn").click(function() {
$(".test").keyup();
});
});
I think a for loop should be used for each checkbox element and this to specify each individual clone, but I have no idea where or how to do this. Please help!
I am assuming you already know how to get a reference to the dom element you need in order to append, as well as how to create elements and append them.
You are right in that you can loop over your dataset and produce dom elements with unique id's so you can later refer to them when transferring new values into your input.
...forEach((obj, index) => {
(produce tr dom element here)
(produce three inputs, give all unique-identifier)
oneOfThreeInputs.setAttribute('unique-identifier', index); // can set to whatever you want, really
(proceed to creating your inputs and appending them to the tr dom element)
targetInputDomElementChild.setAttribute('id', `unique-input-${index}`); // same here, doesn't have to be class
});
Observe that I am using template strings to concat the index number value to the rest of the strings. From then on, you can either reference the index to refer to the correct input or tr using jquery in your keyUp event handler:
function keyUpEventHandler($event) {
const index = $(this).attr('unique-identifier');
const targetInput = $(`#unique-input-${index}`)
// do stuff with targetInput
}
I have created a fiddle to show you the route you can take using the above information:
http://jsfiddle.net/zApv4/48/
Notice that when you click an checkbox, in the console you will see the variable number that designates that set of checkboxes. You can use that specific number to get the input you need to add to and concat the values.
Of course, you still need to validate whether it is being checked or unchecked to you can remove from the input.

Can't select and hide any previous element

I'm about lose my mind with this problem. No form of jQuery selector seems to work in dynamically finding any elements above the link. I'm trying to access an element above the link and hide it. Using things like parent(), prev(), before(), closest(), ect. will show a non-null object but it won't respond to the hide() method.
<div class="row">
<div class="col-xs-5">
<div id="test_fields">
<li id="test_input" class="string input optional stringish">
<label class="label" for="test_input">Ingredient name</label>
<input type="text" name="test_input" value="afsfasf" id="test_input">
</li>
</div>
<input type="hidden" id="recipe_recipe_ingredients_attributes_0__destroy" name="recipe[recipe_ingredients_attributes][0][_destroy]">
Remove Ingredient
</div>
</div>
function remove_fields(link)
{
$(link).prev("input[type=hidden]").val('1'); // this doesn't work
var divToHide = $(link).prev('div');
$(divToHide).hide() // this doesn't work
//$('#test_fields').hide(); //this works
}
Try replacing the link as below:
Remove Ingredient
I'm not sure. But maybe this is the problem. Because I remember that I have had problem with 'this'previously and when I replaced that, it performed the job.
you can try .closest() and .find()
function remove_fields(link) {
$(link).closest('div[class^="col-xs"]').find("input[type=hidden]").val('1');
var div_to_hide = $(link).closest('div[class^="col-xs"]').find('#test_fields');
$(div_to_hide).hide();
//$('#test_fields').hide(); //this works
}
You can't change hidden input's "value" attribute by using .val(). You need to use:
$(link).prev("input[type=hidden]").attr('value', '1');
As I'm not really sure what do you want to do with this input, I'll just let it go like this.
.prev() fn goes only one previous element in the structure. As input is a <a>'s previous element, you can't select div like that. You can use .siblings() for instance.
$(link).siblings('div').hide();
If you break the code in pieces, it gets easier.
First I took the 'Link', from it I grabbed the nearest div above it, then I picked up the input.
I did not make many changes to your code.
function remove_fields(link)
{
var $link =$(link);
var $divToHide = $link.closest('div');
$divToHide.find("input[type='hidden']").val('1');
$divToHide.hide()
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="row">
<div class="col-xs-5">
<div id="test_fields">
<li id="test_input" class="string input optional stringish">
<label class="label" for="test_input">Ingredient name</label>
<input type="text" name="test_input" value="afsfasf" id="test_input">
</li>
</div>
<input type="hidden" id="recipe_recipe_ingredients_attributes_0__destroy" name="recipe[recipe_ingredients_attributes][0][_destroy]">
Remove Ingredient
</div>
</div>

I want to use the text of radio inputs. How can i get it using jQuery or JavaScript

I want to use the text 5 and 6 shown below. I cant modify the html as it is auto-generated and there are many other radios with the same structure. How can i achieve this using jQuery or JavaScript and store them as variables.
<label class="radio">
<label style="display: none;">
<input type="radio" name="x_keeper1_price" id="x_keeper1_price_0" value="21"/>
</label>
5
</label>
<label class="radio">
<label style="display: none;">
<label style="display: none;">
<input type="radio" name="x_Defd5_price" id="x_Defd5_price_0" value="28"/>
</label>
</label>
6
</label>
If your text after the radio button is html code, this is a better solution:
var text = $("#x_keeper1_price_0") //the radio button
.closest("label.radio") //the label with class=radio)
.html() //the html code
.replace(/<label[\d\D]+<\/label>/, '');
/* Removing the "second" label and its content.
That will get the text after the radio button. */
alert(text);
jsfiddle: http://jsfiddle.net/72KcV/3/
For this specific markup, you can use the following jQuery code:
$('label.radio').each(function(){
console.log($(this).contents()[2].nodeValue)
});
http://jsfiddle.net/eKG22/
You can do the following
$('.radio').text()
see a working solution here: http://jsfiddle.net/TfP5X/
Because we are using a class to select the text, you might want to loop over the selector and do something with each value like so.
var items = $('.radio');
$.each(items, function(i, item) {
var text = $(item).text();
//do something with text
});

Get Value from Element Javascript/Jquery

Given the following html:
<div class="product">
<span class="name">Product name</span>
<span class="price">Product price</span>
</div>
<input type="button" class="button" value="Purchase" onclick="myfunction()" />
<input type="hidden" name="p-name" value="">
<input type="hidden" name="p-price" value="">
I am trying to build a function in javascript that takes the value from span.name (span.price) and adds it to input p-name (input p-price).
How can you do that?
Apperantly http://api.jquery.com/val/ is not working as expected.
EDIT
Thanks all for answering!
I've corrected the html error you guys pointed out in the comments.
Try this:
$('.product span').each(function () {
var selector = 'input[name=p-' + this.className + ']';
$(selector).val(this.innerHTML);
});
Fiddle
You will need a button or something to fire the copying:
<input type="button" id="copy_values" value="Copy the values" />
and your javascript
$(document).ready(function(){
$("#copy_values").click(function(){
//Change the value of the input with name "p-name" to the text of the span with class .name
$('input[name="p-name"]').val($('.name').text());
$('input[name="p-price"]').val($('.price').text());
});
});
For span we use text() function instead of val()
.val() is used when we use input and .text() is used when we use span in HTML.
Reference link : http://api.jquery.com/text/
That's going to be hard to click to a HIDDEN field.
If you change input type to text, then in onclick you can write: this.value=document.getElementById('name').innerHTML; (to use this, you have to add ID with name to your )
OR, you can create a seperate button, and onclick method can be fired.

Adding "i" to input field, but should be hidden

I want to add "i" to a input field when the red div is clicked, but the "i" that is added to the input field should not be viewable. If the green button is clicked the hidden "i" should be removed.
Here is my HTML live: http://jsfiddle.net/mtYtW/60/
My HTML:
<div class="input string optional">
<label for="company_navn" class="string optional">Name</label>
<input type="text" size="50" name="company[navn]" maxlength="255" id="webhost_navn" class="string optional">
</div>
<div style="width:30px;height:30px;margin-top:10px;display:block;background:green;">
</div>
<div style="width:30px;height:30px;margin-top:10px;display:block;background:red;">
</div>
How to create this functionality?
If you would like to associate data with a specific element, I suggest the .data() method of jQuery. Take a look at the jQuery docs. It's a much cleaner way of accomplishing your goal.
Here's a working Fiddle to get you started.
EDIT
Per the new requirement spelled out in the comments to your question, you can attach to the form submit event like this:
$('#yourForm').submit(function() {
if($('#webhost_navn').data('myData') == 'i')
{
var val = $('#webhost_navn').val();
$('#webhost_navn').val('i' + val);
}
});
NOTE: This code relys on the orginal code in my Fiddle.
It sounds like you want to associate some data with the input field, but not alter the input field's value. For that, you can use the data method:
$(document).ready(function() {
$('#redDiv').click(function() {
$('#webhost_navn').data('myData', 'i');
});
$('#greenDiv').click(function() {
$('#webhost_navn').data('myData', null);
});
});
You'll need to add id's to the red and green divs for the above example to work as is, respectively, redDiv and greenDiv. To retrieve the data you associate with the input, do this:
var myData = $('#webhost_navn').data('myData'); // Will equal 'i' or null
API Ref: http://api.jquery.com/data
EDIT: To append the "i" value to the input's value:
var myData = $('#webhost_navn').data('myData'),
val = $('#webhost_navn').val();
if (myData) {
$('#webhost_navn').val(myData + val);
}
Working example: http://jsfiddle.net/FishBasketGordo/e3yKu/
My update to your code here: http://jsfiddle.net/mtYtW/61/
Basically I gave your red/green button's id's and created a click event to add/remove the content. I also created a css definition for the color of the input box to be white so you don't see the text.
<div class="input string optional"><label for="company_navn" class="string optional"> Name</label><input type="text" size="50" name="company[navn]" maxlength="255" id="webhost_navn" class="string optional"></div>
<div id='green' style="width:30px;height:30px;margin-top:10px;display:block;background:green;"></div>
<div id='red' style="width:30px;height:30px;margin-top:10px;display:block;background:red;"></div>
css:
label {display:block;}
#webhost_navn{color:white};
js:
$("#red").live("click",function()
{
$("#webhost_navn").val("i");
});
$("#green").live("click",function()
{
$("#webhost_navn").val("");
});
Note if the goal is to post an "i" and have nothing else as a value (ie no user input) use <input type='hidden' id=webhost_navn > and use the same jquery code as above without the need for the css.

Categories