Why can't I remove an attribute of all children? - javascript

I have a cloned div containing input elements, all of which are disabled. I am trying to use the following JQuery code to remove the disabled attribute of each of the div's children.
clonedElement.children().removeAttr('disabled');
I do not have a ton of JQuery experience, so I am probably misunderstanding the way this is supposed to work. How should I be going about removing the "disabled" attribute from all children of the cloned node?
If it helps, clonedElement was created with the JQuery .clone() method.
HTML I AM USING TO TEST---
<div id="original_item" class="hidden">
<div class="row_submit">
<div class="med_field">
<p>Product:</p>
<select name="product[]">
<option></option>
</select>
</div>
<div class="small_field">
<p>Type:</p>
<select name="type[]">
<option></option>
</select>
</div>
<div class="small_field">
<p>Price:</p>
<input type="text" name="price[]" value="test" disabled="disabled" />
</div>
<div class="small_field">
<p>Quantity:</p>
<input type="text" name="quantity[]" />
</div>
<img onclick="removeItem(this);" title="Remove Item" style="margin: 18px 0 0 12px;" src="icons/cancel.gif" />
</div>
<input type="hidden" name="warehouse_data[]" />
</div>

children only looks in immediate children and if the clonedElement is not one of med_field/small-field then it would not work.
You can use find() instead to search for elements beyond immediate children.
i.e.
//for jQuery < 1.6
$("*", clonedElement).removeAttr("disabled");
//or
clonedElement.find("*").removeAttr("disabled");
//for jQuery >= 1.6
$("*", clonedElement).removeProp("disabled");
//or
clonedElement.find("*").removeProp("disabled");

jQuery <1.6 your current code should work.
jQuery 1.6+ do this: clonedElement.children().removeProp('disabled');
See this question .prop() vs .attr() for reasons why

as long as clonedElement is a jquery element you can do:
clonedElement.children().each(function() {
$(this).removeAttr('disabled');
});

Related

Get an element after $(this)

I try to change a text insert in an div box with jquery. Here is the Code:
<div onClick="$(this span).text('My new Text');" class="switch switch-success" style="float: right;">
<label>
<input type="checkbox"><span>Yes</span>
</label>
</div>
I want to change this "Yes" to "No". Thanks for help ;)
Use the .find method
See a working fiddle here
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div onClick="$(this).find('span').text('My new Text');" class="switch switch-success" style="float: right;">
<label>
<input type="checkbox"><span>Yes</span>
</label>
</div>
You have two options.
Pass this a second parameter which is context
$('span', this).text('My new Text');
Get this element and that use find to get span in it.
$(this).find('span').text('My new Text');
Please separate structure, style and function - the CSS, HTML and JS should not be in the same space - its always better to separate the code for better code quality.Also you could do a toggle for the states of the checkbox so that there is different text on the "checked" and "not checked" states.
And you can even do that with CSS
$('.switch').click(function(){
$(this).find('span').text('My new Text')
})
.switch{float: right}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="switch switch-success" >
<label>
<input type="checkbox"><span>Yes</span>
</label>
</div>

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>

jQuery select element and next together

I have an auto-generated HTML and I want to group together elements.
Input Html:
<div class="editor-label"><label for="StringField">StringField</label></div>
<div class="editor-field"><input id="StringField" type="text" value="" /></div>
<div class="editor-label"><label for="IntField">IntField</label></div>
<div class="editor-field"><input id="IntField" name="IntField" type="number" value="0" /></div>
<!-- more like above -->
Desired output:
<div class="form-group">
<div class="editor-label"><label for="StringField">StringField</label></div>
<div class="editor-field"><input id="StringField" type="text" value="" /></div>
</div>
<div class="form-group">
<div class="editor-label"><label for="IntField">IntField</label></div>
<div class="editor-field"><input id="IntField" name="IntField" type="number" value="0" /></div>
</div>
I'm trying to use jQuery's next selector to get those groups, and then wrap them, but I'm having trouble getting the items to select as one to use with wrap(). I'm not sure if I can write a single selector to get this, or if I will need to do it iteratively. Here are some of the selectors I've tried.
//selects just the labels
$('.editor-label')
//returns only the .editor-fields
$('.editor-label + .editor-field')
//returns all 4 elements separately
$('.editor-label, .editor-label + .editor-field')
What selector can I use to select the element (.editor-label) and it's next (.editor-field) as one "element"?
You are going to need to do the selection in a for each and not with a selector by itself.
$(".editor-label").each(function() {
var lab = $(this);
var inp = $(lab).next();
lab.add(inp).wrapAll('<div class="wrapper"/>');
});
.wrapper { border: 2px solid black; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="editor-label"><label for="StringField">StringField</label></div>
<div class="editor-field"><input id="StringField" type="text" value="" /></div>
<div class="editor-label"><label for="IntField">IntField</label></div>
<div class="editor-field"><input id="IntField" name="IntField" type="number" value="0" /></div>
Try this
$('.editor-label').each(function(){
var group = $(this).next().addBack().wrapAll('<div class="form-group"></div>');
});
Use .each(), .addBack() and .wrapAll()
jsBin demo
$('.editor-label').each(function(){
$(this).next(".editor-field").addBack().wrapAll("<div class='form-group'/>");
});
.each() will target all the desired elements, inside the callback, find the .next(".editor-field"), addBack the starting selector (the current .editor-label) and wrapAll() inside the desired element
You can use the jQuery siblings method:
$(".editor-label").siblings(".editor-label")
See if this will work.
var fields = $('.editor-field');
$.each(fields, function(index, obj){
var field = $(obj);
var label = field.prev('.editor-label');
field.wrap('<div class='form-group'></div>').before(label);
});

how can I add a wildcard with jquery binding

how can I add a wild card into this jquery bind event so that form fields with 'PauNumber' are ignored? This field is repeated for each entity. Unfortunately I can't easily assign a css class to it because the text box is created server side.
many thanks
<div class="PassengerWrapper">
<input type="text" value="" name="PauNumber0" id="PauNumber0">
</div>
<div class="PassengerWrapper">
<input type="text" value="" name="PauNumber1" id="PauNumber1">
</div>
<div class="PassengerWrapper">
<input type="text" value="" name="PauNumber2" id="PauNumber2">
</div>
$('.PassengerWrapper input[type=text], .PassengerWrapper select').not(':hidden').each(function () {
You can do it inside the .not('selector') to filter the elements you don't want
$('.PassengerWrapper input[type=text], .PassengerWrapper select').not(':hidden,input[name*=PauNumber]').each(function () {
You can use [name*=PauNumber] or [id*=PauNumber]
Here's an example fiddle for you http://jsfiddle.net/XQWmf/
Also link to the different selectors

traversing this with jquery gives me undefined

When I click .getdata, I want to go from .getdata to name=top and read the value of whichever option is selected (in this case it's 0), but I'm having a hard time getting to it. I keep getting undefined.
This is my html. The div class="main" repeats so I can't simply select input[name=top]. It would have to be through traversing the tree to the closest input[name=top]. Can someone get this right? I'm starting to think it's a browser error because I tried different options and all give me undefined.
<div class="main">
<div class="branch">
<div class="element">
<label>top color:</label>
<input type="radio" value="1" name="top">black
<input type="radio" value="0" name="top" checked="checked">white
<input type="radio" value="null" name="top">transparent
</div>
</div>
<div class="controls">
<a class="getdata">get data</a>
</div>
</div>
<div class="main">
....
</div>
$('a.getdata').click(function() {
var val = $(this).closest('.main').find('input[name="top"]:checked').val();
});
Place a click()(docs) event on the <a> element
On a click, use the closest()(docs) method to traverse up to the .main element
Then use the find()(docs) method along with the the attribute-equals-selector(docs) and the checked-selector(docs) to get the checked name="top" radio.
Finally use the val()(docs) method to get its value.
$(".getdata").click(function(){
selectedValue=$(this).parent().prev().children().children("input[name=top]:checked").val();
console.log(selectedValue);
});

Categories