dynamic window.find not working with jQuery - javascript

I can't for the life of me figure out why this isn't working.
I want to search the current page for text using a search box. I googled and found this: http://www.javascripter.net/faq/searchin.htm . I implemented the code into my site, but it doesn't work. the function ( findString() ) works, but only when I hard-code a string (as in i can't use javascript or jquery to get the value of a text input). I made this fiddle: http://jsfiddle.net/alyda/CPJrh/4/ to illustrate the problem.
You can uncomment different lines to see what I've tested.

jQuery has a method :contains() that will make easier what you are looking for.
Take a look here: fiddle
$("button[type='submit']").click(function () {
var string = $('#search').val();
var matched = $('li:contains(' + string + ')');
matched.css('color','red');
console.log(matched);
return false;
});

I found a fix (sort of). It seems that the input needs to be placed well AFTER the content to be searched in the DOM. That means I've done the following:
<section class="content">
<h2>Fire</h2>
<h3>Fire Extinguishers</h3>
<ul>
<li>Model 240</li>
<li>Model C352, C352TS</li>
<li>Model C354, C354TS</li>
</ul>
...
<div id="navbar">
<ul>
...
</ul>
<input id="search" type="text" class="form-control pull-left" placeholder="Search for part number">
<button id="submit" type="submit" class="btn btn-default pull-left" style=" margin-top:6px;">Search</button>
</div>
as you can see, I've moved the input (which is in the navbar div) BELOW all of the text I want to search, and used CSS to programmatically place the navbar at the top of the page. I don't particularly like this setup (as it messes with the flow of content) but since I was looking for the quickest and simplest implementation of a single-page search, it will have to do.
I would still love to know why this happens, when the javascript is at the end of the DOM where it belongs...

In firefox I noticed that the fiddle (v4) as given in the question worked, but not in the way the asker expected it to.
What happens in firefox is that the function does find the value..: you have just entered it in the input-field. Then the browser's find method seems to hang in the 'context' of the input 'control' and doesn't break out of it. Since the browser will continue to search from the last active position, if you select anything after the input-field, the function works as expected. So the trick is not to get 'trapped' in the input-field at the start of your search.
A basic (dirty) example on how to break out of it (not necessarily the proper solution nor pure jquery, but might inspire a useful routine, since you now know the root of the problem in FF):
$( "button[type='submit']" ).click(function(){
var tst=$('#search').val(); //close over value
$('#search').val(''); //clear input
if(tst){ //sanity check
this.nextSibling.onclick=function(){findString( tst );}; //example how to proceed
findString( tst ); //find first value
} else { alert('please enter something to search for'); }
return false;
});
Example fiddle is tested (working) in FF.
PS: given your specific example using <li>, I do feel Sergio's answer would be a more appropriate solution, especially since that would never run line: alert ("Opera browsers not supported, sorry..."), but the proper answer to your window.find question is still an interesting one!
PS2: if you essentially are using (or replicating) the browser's search-function, why not educate the user and instruct them to hit Ctrl+F?
Hope this helps!

I had same problem in an angularjs app and I fix it by changing DOM structure.
my HTML code was something like this:
<body>
<div class="content" >
<input class="searchInput" />
<p>
content ....
</p>
</div>
</body>
and I changed it to something like this:
<body>
<div class="search">
<input class="searchInput" />
</div>
<div class="content">
<p>
content ....
</p>
</div>
</body>
Note: I'm aware that this topic is old.

Related

why doesn't element.attribute doesn't work in Edge?

I'm creating a small quiz type application in javascript. My html structure looks like this.
<div class="btn-group-toggle" data-toggle="buttons">
<label class="btn btn-secondary btn-insight" data-target="#myCarousel" data-responseID="1">
<input type="radio" name="options" id="option1" autocomplete="off">
<h5>1</h5>
<p class="mb-0">label for 1</p>
<div class="line-bottom gradient-purple"></div>
</label>
...
</div>
I'm trying to use the custom data attribute data-responseID to determine what answer was provided by the user.
When the program starts, loop through the labels using querySelectorAll and attaching a click listener to each one.
const responseLables = document.querySelectorAll('div.btn-group-toggle > label');
responseLables.forEach(element => {
element.addEventListener('click', function(e){
const clickedResponse = element.attributes[2].value;
determineWhereToSlide(clickedResponse);
});
});
This works well in Firefox and Chrome, but doesn't in Edge. (I'm not concerned with IE 11)
determineWhereToSlide is just a function that gives an alert for now. Eventually it'll be used to push the carousel forward.
I've made a working example and you can see the issue if you open it up in different browser.
https://codepen.io/anon/pen/dLmQKZ?editors=1010
I don't get why this is happening.
*EDIT 1
I just realized that the order of the attributes are different. If you change the index value to ...attributes[1]... then it works just fine. Is there a better way to do this rather than providing an index?
Don't refer to attributes by index (even if it seems it should work, attributes were unordered at least until DOM3). Use any of:
element.getAttributeNode("data-responseID").value
element.attributes["data-responseID"].value
element.getAttribute("data-responseID")
element.dataset.responseID
You can use the getAttribute() method.
replace this
const clickedResponse = element.attributes[2].value;
to this
const clickedResponse = element.getAttribute('data-responseID')

Using Javascript to display an input (A number) from a user to a div

I have looked at the other questions that are asking similar things to this question however when I attempted to create my own I can't get it to work properly and i dont understand why. It's only very basic before I introduce it into a more complex system I just wanted to try and get the functionality done.
This is my HTML;
<div id="test2">
Please enter a number: <input type="number" id="RValue1">
<button id="test" onclick="R1Value()">Change Value</button>
</div>
<div id="ShowR1"></div>
And this is the JavaScript;
function R1Value() {
var t = document.getElementById("RValue1");
var div = document.getElementById('ShowR1');
div.innerHTML = t.value;
}
I have made this fiddle to save time and so you can have a look at it,
http://jsfiddle.net/2ufnK/52/
I can't see why this doesn't seem to work so if anyone can see why I would really appreciate it. Thanks.
Try it without the button:
Try out this: http://jsfiddle.net/2ufnK/56/
Type in the text, then you can just call the, ".value", method to get its text. Then everything else works the way you've written it.

JQuery: Append/After difficulties

I have a simple input line and want to append whatever has been entered each time somebody pushes the OK button. Sounds simple so far, still I am unable to get it working
HTML:
<p>
<input name="todo" id="todo" type="text" value="Set Me To Value" size="32" maxlength="30" />
<p id="status">Ok</p>
<br>
JQuery:
$(document).ready(function(){
$('#status').on('click', function(){
var input = $('input[name=todo]').val();
$('<br><b id="taskz">'+input+'</b> - <b id="statusz">Ok</b>').after('#status');
});
});
I also tried my luck with append or appendTo, but both times unsuccessfully.
Just in case here is the JSFiddle: http://jsfiddle.net/NRWzE/
.after() works, but you need to set it up correctly, according to documentation it should be:
.after( content [, content ] )
So the right way is:
$("#status").after('<br><b id="taskz">'+input+'</b> - <b id="statusz">Ok</b>');
Try use jquery insertAfter:
$(document).ready(function () {
$('#status').on('click', function () {
var input = $('input[name=todo]').val();
$('<br><b id="taskz">' + input + '</b> - <b id="statusz">Ok</b>').insertAfter('#status');
});
});
It looks like you meant to use:
$('#status').after('<br><b id="taskz">'+input+'</b> - <b id="statusz">Ok</b>');
(see after docs)
or, alternatively insertAfter:
$('<br><b id="taskz">'+input+'</b> - <b id="statusz">Ok</b>').insertAfter('#status');
Try this:
$('#status').click(function(){
var input = $('input[name=todo]').val();
$('#status').append('<br><b id="taskz">'+input+'</b> - <b id="statusz">Ok</b>');
});
There are a few things going on, but the big thing is that you need to research more how after, append and appendTo work. Here's the basic syntax difference in the methods that share a name but one has To on the end:
Newcontent.appendTo(existingElement) returns newElements.
existingElement.append(newContent) returns existingElement.
Additionally, after puts the new element as a sibling of the reference element, whereas append puts the new element as a child. This is an important difference.
So, try this script then:
var taskid = 1;
$('#valueform').on('submit', function(){
var input = $('#todo').val();
$('<br><span id="task' + taskid.toString() + '">' + input
+ '</span> - <span id="status' + taskid.toString()
+ '">Ok</span>').appendTo('#status');
taskid += 1;
$('#todo').focus().select();
return false;
});
$('#todo').focus().select();
See a Live Demo at JSFiddle
Here's the supporting HTML:
<form id="valueform">
<input name="todo" id="todo" type="text" value="Set Me To Value" size="32" maxlength="30" />
<input type="submit" value="OK" id="okbutton">
</form>
<p id="status"></p>
There are some other concerns:
I recommend you study which HTML elements are allowed within which HTML elements.
Instead of putting a <b> tag on each item, use CSS. Additionally, if there is semantic importance for the bolding, then use <strong> instead. <b> also should probably not take an id because it is a presentation tag, not a content tag. When thinking of presentation vs. semantics, one must consider screen readers or browsers that cannot render bold text--in that case, <strong> will allow them to emphasize the text in another way if needed.
Get familiar with the jQuery documentation. Careful reading of what exactly each function does, the object it works on, the parameters expected, and the values returned will enable you to get past barriers in the future without having to ask here.
It looked to me like you wanted to put the new content inside of the #status paragraph, not after it. So I wrote my script that way. If you put it after the way you wrote it, then the most recent status will be on top--but then you have non block-level content (starting with your <br>) outside of any block-level element. So you should be appending <p> elements, or you should put your content inside the existing <p>.
Note: I added a form and made the button type submit instead of button to get easy Enter-key handling. It doesn't have to be this way.

Issues with jquery id selector

I have this snippet of HTML:
<div class="clearfix" id="menu-file-div">
<label id="menu-file-label" for="id_menu_file">From File</label>
<div class="input">
<div id="file-upload">
<input type="hidden" name="menu_file" id="id_menu_file" />
<script type="text/javascript">var field_id = "id_menu_file";</script>
<script type="text/javascript">var append_to_element_id = "menu-upload";</script>
<script type="text/javascript">var loader_element_id = "newmenu-modal";</script>
<noscript>
<p>Please enable JavaScipt to upload a file.</p>
</noscript>
</div>
</div>
</div>
In my console, when I try to use the jquery id selector, it fails to return the input element:
> $("#id_menu_file")
[]
Any thoughts on why this is so? I feel like I'm missing something simple. Thank you!
EDIT - some other javascript was removing the element, that is why it's not showing up. Thanks all for your help.
To repeat my first answer (which may be applicable to others reading this post later, and which was deleted despite the fact that it "fundamentally answer[ed] the question"):
Is this HTML inside of a frame (iframe or regular)? That could make it difficult for jQuery to find your element, unless you give it the right context.
To add a context to a jQuery selector you just provide that context as an extra argument, for example: $('TD', aFrameElement);
If the element in question is not inside a frame (which is the case for zallarak), the problem is almost certainly a timing issue: the jQuery selection is happening before the element has gotten loaded on the page. You can test this theory by adding the following code (anywhere):
$(function(){
console.log($("#id_menu_file"))
});
If that is the problem, simply wrap your code in $(function(){ to fix matters.
try :
$("#id_menu_file").get(0)
$(selector) return arrays

jquery before() is out of order?

I have a page where you can click a link that says "add a keyword" and an input will appear and you can enter the keyword, and then convert it into a span tag on blur or the "return" key. However, I've been adding onto it to allow for an "autocomplete" feature, so I'm trying to insert a
<ul></ul>
after my input in order to do a .load inside the list.
The relevant code I have is:
var addKeywordId = 0;
$('a.add_keyword').live('click', function(){
$(this).before('<input type="text" class="add_keyword" id="addKeyword'+addKeywordId+'" /><ul><li>hi</li></ul>');
$('.add_keyword').focus();
addKeywordId++;
});
The problem is, that my HTML structure ends up looking like this:
<ul><li>hi</li></ul>
<a class="add_keyword">+ add keyword</a>
<input id="addKeyword0" class="add_keyword" type="text />
INSTEAD OF
<input id="addKeyword0" class="add_keyword" type="text />
<ul><li>hi</li></ul>
<a class="add_keyword">+ add keyword</a>
Anybody know why my HTML is added out of the order I specified??
Thanks
EDIT: This seems to be working fine in Google Chrome, but not in Mozilla Firefox.. :(
This is likely due to the weird rejiggering of code Firefox does to try to display things even when there are errors. I've seen it where I miss a closing div, IE freaks out (as it should) and Firefox looks fine, as it ignores that you missed adding the ending div and guesses.
You could try a 2 stage thing. I would add an id to the ul tag, then add the input before it.
$(this).before('<ul id="ulid"><li>hi</li></ul>');
$('#ulid').before('<input type="text" class="add_keyword" id="addKeyword'+addKeywordId+'" />');
Happy haxin.
_wryteowl

Categories

Resources