For loop with eval not working - javascript

My first time writing my own javascript/jQuery for-loop and I'm running into trouble.
Basically, I have a series of divs which are empty, but when a button is clicked, the divs turn into input fields for the user. The input fields are there at the outset, but I'm using CSS to hide them and using JS/jQuery to evaluate the css property and make them visible/hide upon a button click.
I can do this fine by putting an id tag on each of the 7 input fields and writing out the jQuery by hand, like this:
$('#tryBTN').click(function(){
if ( $('#password').css('visibility') == 'hidden' )
$('#password').css('visibility','visible');
else
$('#password').css('visibility','hidden');
}
Copy/pasting that code 7 times and just swapping out the div IDs works great, however, being more efficient, I know there's a way to put this in a for-loop.
Writing this code as a test, it worked on the first one just fine:
$('#tryBTN').click(function() {
for(i = 1; i <= 7; i++) {
if($('#input1').css('visibility') == 'hidden')
$('#input1').css('visibility', 'visible');
}
});
But again, this only works for the one id. So I changed all the HTML id tags from unique ones to like id="intput1" - all the way out to seven so that I could iterate over the tags with an eval. I came up with this:
$('#tryBTN').click(function () {
for (i = 1; i <= 7; i++) {
if ($(eval('input' + i)).css('visibility') == 'hidden')
$('input' + i).css('visibility', 'visible');
}
});
When I put in the eval stuff - it doesn't work. Not sure what I'm doing wrong. A sample of the HTML looks like this:
<form>
<div class="form-group">
<label for="page">Description: Specifies page to return if paging is selected. Defaults to no paging.</label>
<input type="text" class="form-control" id="input7" aria-describedby="page">
</div>
</form>

You were forgetting the #:
$('#tryBTN').click(function () {
for (i = 1; i <= 7; i++) {
var el = $('#input' + i); // <-- The needed `#`
if (el.css('visibility') == 'hidden') {
el.css('visibility', 'visible');
}
}
});

#Intervalia's answer explains the simple error in your code (the missing #), and the comments explain why you should never use eval() unless you absolutely know it's the right tool for the job - which is very rare.
I would like to add a suggestion that will simplify your code and make it more reliable.
Instead of manually setting sequential IDs on each of your input elements, I suggest giving them all a common class. Then you can let jQuery loop through them and you won't have to worry about updating the 7 if you ever add or remove an item.
This class can be in addition to any other classes you already have on the elements. I'll call it showme:
<input type="text" class="form-control showme" aria-describedby="page">
Now you can use $('.showme') to get a jQuery object containing all the elments that have this class.
If you have to run some logic on each matching element, you would use .each(), like this:
$('#tryBTN').click( function() {
$('.showme').each( function( i, element ) {
if( $(element).css('visibility') == 'hidden' ) {
$(element).css( 'visibility', 'visible' );
}
});
});
But you don't need to check whether an element has visibility:hidden before changing it to visibility:visible. You can just go ahead and set the new value. So you can simplify the code to:
$('#tryBTN').click( function() {
$('.showme').each( function( i, element ) {
$(element).css( 'visibility', 'visible' );
});
});
And now that the only thing we're doing inside the loop is setting the new visibility, we don't even need .each(), since jQuery will do the loop for us when we call .css(). (Thanks #TemaniAfif for the reminder.)
So the code becomes very simple:
$('#tryBTN').click( function() {
$('.showme').css( 'visibility', 'visible' );
});

Related

I create dynamically some text area in a div. How can i get its names in javascript?

This is my code to create the textarea and it works fine, but I want to know how many textarea the user creates and their names.
function createBoxEquip() {
$codEquip = $('#equipamento').val();
$nomeEquip = $('#equipamento>option:selected').text();
$novadiv = "#div"+$codEquip;
if ( !$( $novadiv ).length ) {
$("#equip_tot").append('<div class="box"name=div'+$codEquip+'id=div'+$codEquip+'></div>')
$("#div"+$codEquip).append('<span class="titulo1" name='+$codEquip+' id='+$codEquip+'> - '+$nomeEquip+'</span><span name=texto'+$codEquip+' id=texto'+$codEquip+'><br> </span>');
$("#div"+$codEquip).append('<input type="button" name=apagar'+$codEquip+' id=apagar'+$codEquip+' value="Remover" onclick="deleteBoxEquip('+$codEquip+')"><span name=texto1'+$codEquip+' id=texto1'+$codEquip+'> <br></span>');
$("#div"+$codEquip).append('<input type="text" style="width: 20px;" name=contalinhas'+$codEquip+' id=contalinhas'+$codEquip+'><span name=texto2'+$codEquip+' id=texto2'+$codEquip+'><br></span>');*/
$("#div"+$codEquip).append('<textarea style="width: 150px;" rows=12 name=numerosserie'+$codEquip+' id=numerosserie'+$codEquip+' value="'+$codEquip+' - '+$nomeEquip+'"/><span name=texto3'+$codEquip+' id=texto3'+$codEquip+'> </span>');
}
}
As long as you can pre-determine what the names of the textarea will be, for example - I've written similar code that generated a bunch of <div> tags with unique ID's, each Id was numeric, so I'd auto-generate a bunch of tags like this:
<div id="div-0">Zero</div>
<div id="div-1">One</div>
<div id="div-2">Two</div>
Because I know in advance that each div id will have the prefix div- followed by a digit which begins at 0 and increments sequentially, I can iterate through each element in a loop, and know when I've reached an undefined element:
function loopElements() {
var divPrefix = "div-";
var divNo = 0;
// Loop through all div- tags:
//
while (true) {
// The .length property will return 0 if the element
// doesn't exist...
//
if ($("#" + divPrefix + divNo.toString()).length == 0)
// This div doesn't exist, bail!
//
break;
// do something with div
divNo++;
}
}
Something like this would work, it depends on the names/id's you're creating, and if you can somehow predetermine what they should be.
hope this helps.
EDIT:
Having read your question again I think the above solution may not be what you're looking for, if not I apologise.
There are some ambiguities with your question...exactly how are these names created? Does the user choose them? Are they generated programmatically?
You should post more code and explain in greater detail.

Dynamical search-function to show/hide divs

this is my first post on StackOverflow. I hope it doesn't go horribly wrong.
<input type="Text" id="filterTextBox" placeholder="Filter by name"/>
<script type="text/javascript" src="/resources/events.js"></script>
<script>
$("#filterTextBox").on("keyup", function () {
var search = this.value;
$(".kurssikurssi").show().filter(function () {
return $(".course", this).text().indexOf(search) < 0;
}).hide();
});
</script>
I have a javascript snippet like this on my school project, which can be found here: http://www.cc.puv.fi/~e1301192/projekti/tulos.html
So the search bar at the bottom is supposed to filter divs and display only those, that contain certain keyword. (t.ex, if you type Digital Electronics, it will display only Divs that contain text "Digital Electronics II" and "Digital Electronics". Right now, if I type random gibberish, it hides everything like it's supposed to, but when I type in the beginning of a course name, it will not hide the courses that dont contain the certain text-string.
Here is an example that I used (which works fine): http://jsfiddle.net/Da4mX/
Hard to explain, but I hope you realize if you try the search-function on my page. Also, I'm pretty new to javascript, and I get the part where you set the searchbox's string as var search, the rest I'm not so sure about.
Please help me break down the script, and possibly point where I'm going wrong, and how to overcome the problem.
in your case I think you show and hide the parent of courses so you can try
$("#filterTextBox").on("keyup", function () {
var search = $(this).val().trim().toLowerCase();
$(".course").show().filter(function () {
return $(this).text().toLowerCase().indexOf(search) < 0;
}).hide();
});
Try this this is working now, paste this code in console and check, by searching.
$("#filterTextBox").on("keyup", function () {
var search = this.value; if( search == '') { return }
$( ".course" ).each(function() {
a = this; if (a.innerText.search(search) > 0 ) {this.hidden = false} else {this.hidden = true}
}); })
Check and the search is now working.
Your problem is there :
return $(".course", this)
From jquery doc: http://api.jquery.com/jQuery/#jQuery-selection
Internally, selector context is implemented with the .find() method,
so $( "span", this ) is equivalent to $( this ).find( "span" )
filter function already check each elements
then, when you try to put $(".course") in context, it will fetch all again...
Valid code :
$("#filterTextBox").on('keyup', function()
{
var search = $(this).val().toLowerCase();
$(".course").show().filter(function()
{
return $(this).text().toLowerCase().indexOf(search) < 0;
}).hide();
});
In fact, you can alternatively use :contains() CSS selector,
but, it is not optimized for a large list and not crossbrowser
http://caniuse.com/#search=contains
You were accessing the wrong elements. This should be working:
$(".kurssikurssi").find('.course').show().filter(function () {
var $this = $(this)
if($this.text().indexOf(search) < 0){
$this.hide()
}
})

Hiding content depending on variable value

I am making a price estimator.
How would correctly write a jQuery function that checks a variable and depending on that amount hides/shows a certain div element accordingly.
So if I had:
a HTML div with the ID 'Answer'
<div id="answer">Hide Me</div>
$("#answer")...
a variable (this variable would change)
var x = 30
Now I know the css to hide the div would be:
#answer{
visibilty:hidden;
}
What would be the correct way to hide the function checking these certain parameters? for example if x > 20 then hide etc
Now I know there will be many ways to do this and they may not require jQuery, please inform me if this is the case. Perhaps it just needs JS. I know there will be many ways to do it not just one so if you have a different way please comment as I am keen to learn.
Any help would be greatly appreciated.
Cheers
F
Note that you can also remove or add a class:
$('#answer').removeClass('hide');
$('#answer').addClass('hide');
But what you want to do is $('#answer').hide(); or $('#answer').show();
Execute this function providing the variable v:
var checkVar = function(v) {
var target = $('#answer');
if (parseInt(v) > 20) {
target.hide();
} else {
target.show();
}
}
For example, if the variable comes form a selection:
$('#selectId').on('change', function() {
checkVar($(this).val());
});
Remove the CSS. You can do it in jQuery
if(x>20){
$('#answer').hide();
}
You can use this one
$("#answer").hide();
#kapantzak's answer looks good. But keep your logic and style separated and if your not going to use the variable for the actual element twice, I wouldn't make it. So go:
var checkVar = function(var) {
var element = $('#answer');
if (parseInt(var) > 20) {
element.addClass('hidden');
}else{
element.removeClass('hidden');
}
}
And in your CSS go:
#answer.hidden{
display: none;
}
Also, depending on your preference, display: none; doesn't display anything of the object whereas visibility: hidden hides the object but the space the object was occupying will remain occupied.
HTML
<input id="changingValue">
...
<div id="answer">Hide Me</div>
CSS (not mandatory if you check values on loading)
#answer{ display:none;}
JS
var limit = 20;
$(function(){
$("#changingValue").change(function(){
if(parseInt($("#changingValue").val())<limit) { $("#answer").show(); }
else { $("#answer").hide(); }
});
});

Auto style checkbox with jQuery ui theme

(jQuery noob here)
Im trying to write a script which when I write <input type='checkbox'/> will automatically convert it to jQuery UI button and look like a checkBox.
Sample code so far ...
var newCheckboxID = 0;
$( "input:checkbox" ).attr('id', "cbx-" + nextCheckboxID++); // how to do that?
$( "input:checkbox" ).after("<label style='width:16px; height:16px; vertical-align:middle;'></label>");
$( "input:checkbox" ).next().attr("for", $(this).attr('id') ); // doesn't work for sure
$( "input:checkbox" ).button();
$( "input:checkbox" ).button( "option", "text", false );
$( "input:checkbox" ).attr("onclick", "$(this).button( 'option', 'icons', {primary:((this.checked)?'ui-icon-check':null),secondary:null} )");
Sorry, if it's too obvious but I've lost more than hour in that ...
EDIT
Finally did it with the old fashioned way (for the doesn't working parts).
Any comments for making it more compact and "more jQuery" would be appriciated ...
Code sample
// ---- set ids
var checkboxID = 0;
//$( "input:checkbox" ).attr('id', "cbx-" + nextCheckboxID++); // how to do that?
var cboxes = document.getElementsByTagName('input'); // <-- do this instead
for(var i=0; i<cboxes.length; i++){
if( cboxes[i].getAttribute('type')!='checkbox' ) continue;
cboxes[i].setAttribute('id', 'cbx-'+checkboxID++);}
// ---- add labels
$( "input:checkbox" ).after("<label style='width:16px; height:16px; vertical-align:middle;'></label>");
//$( "input:checkbox" ).next().attr("for", $(this).attr('id') ); // doesn't work this
for(var i=0; i<cboxes.length; i++){ // <-- do this instead
if( cboxes[i].getAttribute('type')!='checkbox' ) continue;
cboxes[i].nextSibling.setAttribute('for', cboxes[i].getAttribute('id') );}
// ---- create
$( "input:checkbox" ).button();
$( "input:checkbox" ).button( "option", "text", false );
$( "input:checkbox" ).attr("onclick", "$(this).button( 'option', 'icons', {primary:((this.checked)?'ui-icon-check':null),secondary:null} )");
Working examples:
jsFiddle (without comments)
jsFiddle (without comments with UI theme switcher!)
jsFiddle (with comments)
jsFiddle (Just for fun, uses timer and some other jQuery features, just for future reference)
jsFiddle (Just for fun, uses timer and changes UI theme every second!)
In the following, I should note 2 primary changes. I added CSS to do what you were trying to do to labels in "code" (where it really doesn't belong).
Also, I changed the HTML for "ease of jQuery" use. However, I still noted in the comments how you can easily change it back.
the HTML
<center>
<button>Create New CheckBox</button>
</center>
<hr />
<div id="CheckBoxes">
<input class="inp-checkbox" />
<input class="inp-checkbox" />
<input class="inp-checkbox" />
<input class="inp-checkbox" />
</div>​
the CSS
.inp-checkbox+label {
width:16px;
height:16px;
vertical-align:middle;
}​
the JavaScript/jQuery
// keep in mind, and i will explain, some of these "moving-parts" or not needed, but are added to show you the "ease" of jquery and help you see the solution
// This global function is designed simply to allow the creation of new checkboxes as you specified, however, if you won't be making check boxes at end user time, then i suggest simply moving it to within the .each statement found later on.
// Also, this could easily be written as a jQuery plugin so that you could make a "chainable" one-line call to change checkboxes to this but let's get to the nitty gritty first
function createCheckBox(ele, i) {
// First I simply create the new ID here, of course you can do this inline, but this gives us a bottleneck for possible errors
var newID = "cbx-"+i;
// below we use the param "ele" wich will be a jQuery Element object like $("#eleID")
// This gives us the "chainability" we want so we don't need to waste time writing more lines to recall our element
// You will also notice, the first thing i do is asign the "attribute" ID
ele.attr({ "id": newID })
// Here we see "chainability at work, by not closing the last line, we can move right on to the next bit of code to apply to our element
// In this case, I'm changing a "property", keep in mind this is kinda new to jQuery,
// In older versions, you would have used .attr but now jQuery distinguishes between "attributes" and "properties" on elements (note we are using "edge", aka. the latest jQuery version
.prop({ "type": "checkbox" })
// .after allows us to add an element after, but maintain our chainability so that we can continue to work on the input
// here of course, I create a NEW label and then immidiatly add its "for" attribute to relate to our input ID
.after($("<label />").attr({ for: newID }))
// I should note, by changing your CSS and/or changing input to <button>, you can ELIMINATE the previous step all together
// Now that the new label is added, lets set our input to be a button,
.button({ text: false }) // of course, icon only
// finally, let's add that click function and move on!
// again, notice jQuery's chainability allows us no need to recall our element
.click(function(e) {
// FYI, there are about a dozen ways to achieve this, but for now, I'll stick with your example as it's not far from correct
var toConsole = $(this).button("option", {
icons: {
primary: $(this)[0].checked ? "ui-icon-check" : ""
}
});
console.log(toConsole, toConsole[0].checked);
});
// Finally, for sake of consoling this new button creation and showing you how it works, I'll return our ORIGINAL (yet now changed) element
return ele;
}
$(function() {
// This .each call upon the inputs containing the class I asiged them in the html,
// Allows an easy way to edit each input and maintain a counter variable
// Thus the "i" parameter
// You could also use your ORIGINAL HTML, just change $(".inp-checkbox") to $("input:[type='checkbox']") or even $("input:checkbox")
$(".inp-checkbox").each(function(i) {
// as previously noted, we asign this function to a variable in order to get the return and console log it for your future vision!
var newCheckBox = createCheckBox($(this), i);
console.log(newCheckBox);
});
// This next button added is simply to show how you can add new buttons at end-time
// ENJOY!!!
$("button").button().on("click", function(e) {
var checkBoxCount = $("#CheckBoxes .inp-checkbox").length;
var newCheckBox = $("<input />").addClass("inp-checkbox").appendTo($("#CheckBoxes"));
createCheckBox(newCheckBox , checkBoxCount);
console.log(newCheckBox);
});
});​
Update: The original intent here was to purely answer the question, which was to create a jQuery UI styled checkbox and show how jQuery can be used in multiple ways. However, a later comment queried how to include a traditional style label with it. While there are a billion options for this, I'll simply take from the above and extend.
The first option I took is pretty simple. Using jsFiddle (without comments with UI theme switcher!), I made the following changes:
the JavaScript/jQuery
// First I add a new variable.
// It will simply be for a new "wrapper" element, in which to ensure our button is encased.
// Giving this element a new class gives easy access for later CSS or Event Triggering of sub elements (like the checkbox)
var newID = "cbx-"+i,
wrapper = $('<div />', { 'class': 'ui-checkbox-wrapper' }).appendTo('#CheckBoxes');
// Then I added a line to our ele series of methods.
// This line simply append our element (checkbox) to our new wrapper
// Take Note at how I added this method at start rather than at end.
// Had I not done this, then the label would not have been wrapped!
ele.appendTo(wrapper) // <-- new line!
.attr({ "id": newID })
Then I simply added the following CSS:
#CheckBoxes .ui-button .ui-button-text {
background: #A9A9A9;
display: inline;
font-size: 16px;
left: 19px;
padding: 0;
position: relative;
text-indent: 0;
top: -4px;
}
Results!

JQuery, a new Selection using the results

Is there a way to me do this?
<img id="example" src="anything.jpg" title="something" class="abc" />
$('.abc').each(function(){
//test if this result is something
if( $(this)...(???)...('[src^=anything]')) == 'anything.jpg'){
}
//another Jquery selector test for this one
if( $(this)...(???)...('#example').size() > 0){
}
});
This is just an example, what I need is pretty more complex.. But I would like to know if there is a way to make other jQuery selector test in the result of a first selector.. since "find" will find the children of $(this).. and .parent() get alot of brothers..
See what I mean?
Do you have any idea?
So sorry.. let me try again..
$('div').each();
get all "div", right?
But now in that function I need to make another "test" check if div class is "red" or "blue"..
See?
I need to test something else of the result based in Jquery selector..
I know I could do:
class = $(this).attr('class'); and then if(class=="blue"){} .. But I would like to do $('this[class=blue]').size()>0){}
The jQuery is() filter operates on a found set to detect if something is true or not.
The jQuery filter() method will further pare down a found set based on criteria.
var allDivs = $('div');
var greenOnes = allDivs.filter('.green');
var redOnes = allDivs.filter('.red' );
I think you need the is method:
$('.abc').each(function() {
$(this).is('[src^=anything]')
});
This is fairly simple though, but I can't really tell what you are trying to do by the description. Maybe this is enough to get you started though.
You can use the filter and is methods to filter/search within a jQuery object.
if( $(this).is('[src^="anything"]') ) {
}
elseif( $("#example").size() > 0) {
}
You could put $("#example") in a variable outside of the loop and then reference it inside the loop as well.
if(this.src.indexOf("anything") === 0) {
// source starts with 'anything'
}
if($("#example").length) {
// since there can be only one #example
// in a *valid* document
}
Based on your edit:
if($(this).hasClass("blue")) {
...
}
?

Categories