Dropdown menu choice hides fields through class - javascript

I have a dropdown menu, that when a value is chosen it hides/ shows fields, because of the php code behind it I need to use class to choose it.
I was also wondering if theres a way to add back the padding when hiding and showing the fields.
I tried using "document.getElementsByClassName("className");" But couldn't get it working.
HTML:
<select id="form" onchange="ChangeDropdowns(this.value);">
<option value="hide">hide</option>
<option value="show">show</option>
</select>
<input type="text" id="testField" class="testField" />
Javascript:
function ChangeDropdowns(value) {
if (value == "show") {
document.getElementById('testField').style.display = 'none';
} else if (value == "hide") {
document.getElementById('testField').style.display = 'block';
}
}

You are using the querySelectorAll function wrong, it returns an array of elements, if you want a single element use querySelector which in this case it looks like thats what you want.
HTML
<input type="text" id="testField" class="testField2"/>
JS
//Uses class, a period needs to be before the class name, when selecting by class
document.querySelector(".testField2").style.display='none';
//Uses id, a # needs to be before the id name, when selecting by id
document.querySelector("#testField").style.display='none';
When using querySelectorAll it will return an array, so you have to access it as such
var elements = document.querySelectorAll(".testField");
elements[0].style.display='none';
Your fiddle had a couple errors:
Function name in onchange didnt match the actual function name
you had onLoad selected for the wrap, which was making it so the function wasnt being declared in the global scope.
You werent using the proper css selector, classes have . prefixed to the name, ids have # prefixed, when no period or # before the name, the name is looked up as an element tagname

Related

How to focusout an html array? [duplicate]

This question already has answers here:
jQuery selector for inputs with square brackets in the name attribute
(5 answers)
Closed 1 year ago.
I want to add a focusout function to this html array.
Array:
echo '<td><input name="codemf[]" type="text" id ="codemf'.$indexofid.'" class="form-control form-control-sm" required></td>';
Focusout function:
$('#codemf[]').focusout(function ()
{
if ($('#codemf[]').val() !== '')
{
$.get("req.php?mf=", function (data)
{
var is=0;
var info = data.split('|');
for(let i=0;i<info.length;++i)
{
if($('#codemf[]').val()==info[i])
{
is=1;
}
}
if(is==0)
{
$('#codemf[]').addClass("is-invalid");
$('#command').attr('disabled', true);
} else {
$('#codemf[]').removeClass("is-invalid");
$('#command').attr('disabled', false);
}
});
}
else
{
$('#codemf[]').removeClass("is-invalid");
$('#command').attr('disabled', false);
}
});
I tried a lot of things but nothing works...
If anyone has an idea, it would save me.
What you are using is an id selector $('#codemf[]').
You can attach a class to all input tags that you want to have the focusout event and just use the $(this) selector to select the current element.
<input name="codemf[]" type="text" class="some-class form-control form-control-sm" required>
$(".some-class").focusout(function(){
// do something here
// like $(this).addClass("another-class");
});
Note that you'd have to delegate the event for it to work on dynamically added elements, so you'd have to use on().
$(".some-class").on("focusout", function(){
// do something here
// like $(this).addClass("another-class");
});
I might be bad on few things so take care of what I'm saying.
!-----
this is probably your problem:
the $('#..') of Jquery take care of the ID, not the name of the element
(selector of jquery work like CSS one # for ID, for class, nothing for tag)
or as the last guy said, you can select by attribute ---
$('input[name="..."]')
!----
if the id needs to be dynamic for any reason, you can add a listener on a class and get the id of the focus out element with this.id
depending on what you want you can use focus out or blur (not a mistake, just in case of a problem)
name case: I am not sure about '[]' in name propriety, most of the time I use only camel case letters and no special chars

Check if exact substring is in a string

I know that somewhere someone asked this question before but I've tried to find an answer without any luck.
I'm trying to find if an exact substring is found in a string.
For example
<input class="form-control alphanumeric-chars" />
I want to match 'alphanumeric-characters' but if the class name was alphanumeric it won't be a match
I've tried many options like:
$('input').filter(function() {
return $(this).className.includes('alphanumeric-chars');
})
Or
return $(this).className === 'alphanumeric-chars';
Any idea what am I missing?
There is no need of filter. Just use the class selector as follow
$('input.alphanumeric-chars')
why don't you go for hasClass() if you want to do something based on condition!
if($(this).hasClass('className')){
//do some code.
}
else{
//do else part
}
You have multiple options if you use jquery :
$(this).hasClass('alphanumeric-chars')
or if you don't use jquery :
this.className.indexOf('alphanumeric-chars') // return -1 if not found, >= 0 if found
If you want all input without 'alphanumeric-chars' class you can do this :
$('input:not(.alphanumeric-chars)')
There multiple ways to find the class
$('input.alphanumeric-chars') // select only those input who has class name "alphanumeric-chars"
$('.alphanumeric-chars') // select all element has class name "alphanumeric-chars"
$('[class="alphanumeric-chars"]') // select all element has class name "alphanumeric-chars"
$('input[class="alphanumeric-chars"]') // select only those input who has class name "alphanumeric-chars"
$('input').hasClass('alphanumeric-chars') // select only those input who has class name "alphanumeric-chars"

How to clone elements and generate dynamic ids

I am cloning some form elements and want to generate for them dynamic ids so I can acces their content later on, but I don't really know how to do that, I'm a noob with Jquery/Javascript, by the way.
My html:
<tr>
<td>
<label for="ability">Ability</label><br>
<div id="rank_ability" name="rank_ability">
<select name="ability" id="ability">
<option value=""></option>
<option value="hexa">Test</option>
</select><br>
<label for="range_ability_min">Range:</label>
<input type="textbox" name="range_ability_min" id="range_ability_min" class="small_text" value="0" /> -
<input type="textbox" mame="range_ability_max" id="range_ability_max" class="small_text" value="0" /><br>
</div>
Add Ability<br><br>
</td>
</tr>
My JS:
$(document).ready(function () {
var element, ele_nr, new_id;
$('.rank_clone').click( function() {
element = $(this).prev();
ele_nr = $('div[name="'+element.attr('name')+'"]').length;
new_id = element.attr('name') + ele_nr;
element.clone().attr('id', new_id).attr('name', new_id).insertAfter(element);
});
});
I setup a jsfiddle with what I got here: http://jsfiddle.net/xjoo4q96/
Now, I am using .prev() to select the element to clone which leads to those repeated 1 in the id/name attributes, how could I select it in another way (to mention: I really need to use 'this' because I need this little script in like 3 places, so I don't want to write it for an element with a specific id/class).
Also, I am counting only the element with the base name attribute so .lenght yelds 1 all the time, how would I go around counting all of them ? I guess I have to place them in another div or something but I don't know how would I go around couting them even then.
And, at last, how would I go around changing all the name/id attributes of the elements I have in the div ?
I'd appreciate any help. Thanks.
you can put the template in a hidden div like #tmpl, then clone and set the id attr, e.g.
$('#tmpl').children().first().clone().appendTo('#target').attr('id', 'the_generated_id');
Update
Demo of the template way: http://jsfiddle.net/xjoo4q96/1/, though it would be quite easy to adjust the code to clone the first component that already existed.
BTW, principally, id should be unique, thus the sub-element in the cloned component should use other attribute, like class or certain data- attribute, like those used in the updated fiddle.
Also you might want to call event.preventDefault() as you're clicking an <a>
You are searching already with the wrong name, since it still has the number attached. So delete it first, search for element which have a name attribute starting with this name and then use this base name to create a new one.
$(document).ready(function () {
var element, ele_nr, new_id, base_name;
$('.rank_clone').click( function() {
element = $(this).prev();
base_name = element.attr('name').replace(/[0-9]/g, '');
ele_nr = $('div[name^="'+base_name+'"]').length;
new_id = base_name + ele_nr;
element.clone().attr('id', new_id).attr('name', new_id).insertAfter(element);
});
});
And to answer your last question: you can not go around changing all ids of inner elements, it would be invalid HTML. In principal you can do the same with every id, like adding a number. If you have to do the same with all the name attributes depends on what you want to do exactly. If you have to distinguish between the first and second input, which I suggest, you have to change them too.
try to use cloneJs, it's clone ids, names input, and parametre inside functions ids of input must be like id_foo_1, id_foo_2 ,,,, and name be like inputName[0][foo], inputName[1][foo] https://github.com/yagami271/clonejs

calling one javascript function affecting two html drop download list

My question is can you call just one javascript function and affect two html drop down list the idea is to use the codes below
javascript code:
document.getElementsByClassName("cmbRecom")
html code:
<Select name="drop1" class="cmbRecom" >
<option>Check Fields</option>
</Select>
<Select name="drop2" class="cmbRecom" >
<option>Check Fields</option>
</Select>
what is in my head, is the css behavior where you can name html elements with the same class names and all will follow that style that is declared for that class.
Yes, you can. One possible way is as follows:
document.documentElement.cmbRecomb;
When selecting elements using the function getElementsByClassName the code should work with the returned elements as an array, which will require iteration through the selected elements.
var selects = document.getElementsByClassName("cmbRecom"); //was cmbField
for(var i = 0; i < selects.length; i++){
selects[i].style.width = "200px";
}
Note: The class name and selector were different.
JS Fiddle: http://jsfiddle.net/LWxcX/

jQuery single event for several DOM objects

I'm trying to make a change event trigger for several objects in the DOM. Let me show you; I have this code
$(document).ready(function() {
$(".select_something").change(function() {
if (!($(".select_something option[value='0']").attr("selected"))) {
$(".write_something").css('display','');
}
else
{
$(".write_something").css('display','none');
}
});
});
And with this I have several selectors/dropdowns all of which is called .select_something. When the option is not the default value (which is 0), it should show a <textarea></textarea> appear, again all of which is called .write_something.
All in all it's a quite simplistic function.
The problem I'm experiencing is that this only affects the very first .select_something, .write_something pair, and the rest is unaffected.
I've tried mixing around with .find(), .parent() and .children() to see if it could stick, but it don't.
How can I make it so all of my .select_something, .write_somethingpairs get changed when triggered?
Edit: The IDs was supposed to be classes, of course.
#select_something
Is an id. IDs must be unique over your entire page. If you have multiple elements with this same id, that's fundamentally wrong (and will cause you massive problems).
Having said that, the fix is easy: change those ids to css classes.
<select id="select_something">
becomes
<select class="select_something">
Then you could select against the css class, but of course you'll have to select the : write_something element relative to the current select. Something like this might work depending on your structure:
$(".select_something").change(function() {
if (!($("option[value='0']", this).attr("selected"))) {
$(this).siblings(".write_something").css('display','');
}
else
{
$(this).siblings(".write_something").css('display','none');
}
});
You should be using a common class for the multiple objects, not a common ID.
The ID attribute is used to IDentify a single item. The CLASS attribute is used to define that an item is part of a group of items, all which have the same class name.
Use the class name selectObject on all of them, and then..
$(document).ready(function() {
$(".selectObject").change(function() {
//inside of an event, $(this) refers to the object that triggers the event,
//in this case, the item that was clicked.
if (!($(this).val()==0)) {
...
}
else
{
...
}
});
});
Here is something for illustration.
http://jsfiddle.net/FxLSR/1/
As mentioned in other answers and comments, only use an ID for unique elements, use a class for multiple elements.
This is how I would setup my code:
HTML:
<div>
<select class="select_something"> ... </select>
<textarea class="write_something"> ...</textarea>
</div>
<div>
<select class="select_something"> ... </select>
<textarea class="write_something"> ...</textarea>
</div>
etc...
Javascript:
$(document).ready(function() {
$(".select_something").change(function() {
if (!($(this).val() == "0") {
$(this).next().show();
}
else
{
$(this).next().hide();
}
});
});
If the elements can't be placed next to each other as in the example HTML code I have given, then just make sure to select the textarea using some sort of relative selector such that you're not selecting all of the text areas. For example, if the two are siblings but they're not next to each other use: $(this).siblings(".write_something")

Categories

Resources