I am trying to implement a rudimentary site search for a page of images. The search function should go through each element in a specific class looking for a word match in the image's alt text.
I think my issue is with binding the function to a form submit but I can't seem to figure out where I went wrong.
I have tried this with jQuery (fiddle:http://jsfiddle.net/u2oewez4/)
$(document).ready(function(){
$("#search-form").click(function() {
var searchQuery = "Text";
$.each('.single-image', function(){
$(this).children("img").attr("alt"):contains(searchQuery).hide("slow");
});
});
});
As well as with JavaScript (fiddle:http://jsfiddle.net/m3LkxL1c/)
function submitSearch(){
// create regex with query
var searchQuery = new RegExp(document.getElementById('search-input').value);
// create array of content to look for query in
var content = document.getElementsByClassName("single-image");
// create an array to put the results to hide in
var hideResults = [];
var imagesToHide = document.getElementsByClassName("single-image-hide");
// get the current display value
var displaySetting = imagesToHide.style.display;
for (i=0; i<content.length; i++) {
if (! searchQuery.test(content[i].firstChild.firstChild.nodeValue)) {
// if the query not found for this result in query
hideResults.push(content[i]);
// push to the hideResults array
content[i].className = "single-image-hide";
// change class name so CSS can take care of hiding element
document.getElementById("form-success").style.display = 'inline-block';
alert(searchQuery); // for debugging
return false; // results will not stick without this?
}
}
// set display to hidden
if(displaySetting == 'inline-block'){
imagesToHide.style.display = 'none'; // map is visible, so hide it
}
else{
imagesToHide.style.display = 'inline-block'; // map is hidden so show it
}
}
FYI I have built the JQuery off a few StackOverflow threads, so I've definitely tried my best to find a similar example. (Similar functions: here, and here)
Okay, various bug fixes, most of which I noted in the comments already because I wanted to make sure not to miss any. You need to read the details for in the jQuery documentation much more closely. That'll fix a lot of the problems you're having, like using the wrong each function. Other things will come with time. Keep studying, and READ THE DOCUMENTATION.
$("#search-form").click(function() {
//this gets the val for the search box, then puts the Imgs in a variable so we don't have to use the selector multiple times. Selectors are expensive time-wise, stored variables are not.
var searchQuery = $("#search-text").val(),
singleImgs = $('.single-image');
//you have to show the images for each new iteration, or they'll remain hidden
singleImgs.show();
singleImgs.each(function(){
//get alt attribute
var thisAlt = $(this).find("img").attr("alt");
//if thisAlt does not contains searchQuery (use > instead of === for does)
if(thisAlt.indexOf(searchQuery) === -1){
$(this).hide();
}
});
});
working fiddle
Related
I am currently attempting to make a page that would allow for users to search multiple knowledge bases from a single field.
Currently, I have been able to build this tool out so that clicking the corresponding button will search the designated tool, but I am trying to get a single button to search all 4.
Where I am stuck is the function tied to the All button. When I click it, it only appears to be running the last function in the group rather than opening 4 browser tabs with all 4 results.
I have attached a JSFiddle, in case my explanation is poor.
Note: The page is not pretty as I am trying to get it working before I add any CSS. I really just need JS advice. I am still somewhat of a novice with JS, so if anyone can provide a fairly simple solution, that would be most ideal.
Super Search Fiddle:
This is just to give an idea on how it might work depending on you needs. Ill assume that all the searches return a boolean value. So the code would go something like this:
function doAll() {
var msg = ["google","payroll","inquira","sdfc"]
var retvalue = [googleSearch(),payrollSearch(),inquiraSearch(),sfdcSearch()];
for (var i = 0; i < retvalue.length; i++){
if(retvalue[i] == false){
console.log(msg[i]+" search returned false");
}
}
}
It will do all the searches first and after it finishes, it will give out which searches failed, but you can change that functionality according to your needs.
Hope it helps
Update/Alternative(Almost same code):
function doAll() {
var msg = ["google","payroll","inquira","sdfc"]
var retvalue1 = googleSearch();
var retvalue2 = payrollSearch();
var retvalue3 = inquiraSearch();
var retvalue4 = sfdcSearch();
var retvalue = [retvalue1,retvalue2,retvalue3,retvalue4];
//var retvalue = [googleSearch(),payrollSearch(),inquiraSearch(),sfdcSearch()];
for (var i = 0; i < retvalue.length; i++){
if(retvalue[i] == false){
console.log(msg[i]+" search returned false");
}
}
}
I've created a very basic script that allows the user to replace a specific font in all the document (even LayerSets) by another one.
A practice example: I want to substitute all Arial-Bold by Arial-Italic, but some of the TextLayers have Arial-Bold and Arial-Regular inside the same Layer, how can make that the script only changes the Arial-Bold part of the TextLayer and not the whole layer?
Code I'm currently using:
var inFont = prompt("write inFont","Write inFont");
var outFont = prompt("write outFont","Write outFont");
app.preferences.typeUnits = TypeUnits.PIXELS;
var doc = app.activeDocument;
function changeFonts(target){
var layers = target.layers;
for(var i=0;i<layers.length;i++){
if(layers[i].typename == "LayerSet"){
changeFonts(layers[i]);
} else {
if((layers[i].kind == LayerKind.TEXT) && (layers[i].textItem.font == inFont)) {
layers[i].textItem.font = outFont;
};
};
};
};
changeFonts(doc);
I would assume you would have to crawl through the text and look at each individual character. Here is an article that that talks about formatting specific character ranges. Formatting text ranges.
You could use something like this to loop through the text one character at a time, check the formatting and change it if needed. I can't think of any other way to approach this.
I'm trying to remove (or disable) certain list items on a NetSuite form based on the selected option of a different list. I have been able to alter the form in other ways, using custom code, but the list items appear to be created on the page dynamically. The field is actually an input field, that is altered by JavaScript, when you "open" it (apparently).
Any assistance with this would be greatly appreciated. My only other option appears to be to add all of the options to each list programatically (via SuiteScripts), but I'd rather not do that, since there are a lot of lists that need to be altered, depending on other options selected by the client.
EDITED
Well, I found a way, using some of the code from the SuiteScript functions... It's not ideal, but it could work... Unless anyone has a better way of doing it...
//Add Option
var textCustom = "test inserted option";
var valueCustom = '100';
var selectedCustom = 'T';
var fldnamCustom = 'custevent_fieldNameGoesHere';
var formCustom = document.forms['main_form'];
var fldCustom = getFormElement(formCustom,fldnamCustom.toLowerCase());
if (fldCustom != null){
addSelectOption(document,fldCustom,textCustom,valueCustom,selectedCustom);
}
//Remove Option
valueCustom2="1";
var formCustom2 = document.forms['main_form'];
var fldCustom2 = getFormElement(formCustom2,fldnamCustom.toLowerCase());
if (fldCustom2 != null){
eval( valueCustom2 != null ? 'deleteOneSelectOption(fldCustom2, valueCustom2)' : 'deleteAllSelectOptions( fldCustom2, window )' )
}
I need to create a function where the user can access input question , and they can see different results. It's a magic eight ball simulation. I need to use an array, but i'm not sure how to do this with images.
Here's what I have now.
function eightBall() {
var answer = document.getElementById('questBox').value;
answer = answer.toLowerCase();
if (answer.search(/[?]/) > -1) {
var no = '../images/eightBallNo.png';
$('#answerImages').html(no);
}
}
I'm not sure how to do this, so any help would be appreciated. In addition, I need to make it so that when the user enters the same question, it always returns the same result. My instructions were to do this through an if statement. Again, any help would be greatly appreciated.
Create a map using an object and store each question and the resulting random mage in it. When somebody asks a question, check to see if you've already mapped that question to something. If so, use the cached result. If not, get a random image from your array, and then add it to the cache:
// empty cache to use
var answerMap = {}
// array of your images
var images = ['image_1.png', 'image_2.png', ... 'image_n.png'];
function eightBall() {
var imageToUse = false;
var answer = document.getElementById('questBox').value;
answer = answer.toLowerCase();
// this syntax could be wrong, I forget the check as my JS is rusty
// check the cache to see if we got asked this before
if (answerMap[answer] != undefined) {
// if so, use the cached image value
imageToUse = answerMap[answer];
} else {
// otherwise, get a random image, and add it to the cache
var randomIndex = Math.floor(Math.random()*images.length);
imageToUse = images[randomIndex];
answerMap[answer] = imageToUse;
}
// do whatever you need to do with the image
}
Use that URL in an IMG tag, like this:
var no = '../images/eightBallNo.png';
$('#answerImages').html('<img src='+no+'/>');
But, this doesn't use an array. Where were you needing to use an Array? An Array of image urls?
I am trying to create a function that given a divid, and a list of classes, will then do some text replacing inside them.
Having learned of how Firefox Dom is handling text nodes differently, I read that I had to use javascript to loop through the elements, sibling to nextSibling.
The last obstacle I had in my script, of which you see a small portion of, is getting the classname. I need the class name so that I can filter down what content get's text replaced.
Having looked all the answers, and with the help of a co-worker named Ryan at work, we have redone this in jquery.
$(divid).find(".status_bar").each( function() {
var value = $.trim($(this).text());
// if value is not defined thru browser bugs do not replace
if (typeof(value) != 'undefined') {
// it is a text node. do magic.
for (var x = en_count; x > 0; x--) {
// get current english phrase
var from = en_lang[x];
// get current other language phrase
var to = other_lang[x];
if (value == from) {
console.log('Current Value ['+value+'] English ['+from+'] Translation ['+to+']');
value = to;
$(this).attr('value', to);
}
}
}
});
This currently works in all areas, except in the replacing of text.
The reason I had originally with doing this in jQuery, had to be not sure I could loop thru elements, and avoid the problem with firefox and text nodes.
I am doing a loop of all elements inside a div, and I now need to get the classname of the element that I am looping by.
Then i can check if the current element's class is one, I need to do something with...
// var children = parent.childNodes, child;
var parentNode = divid;
// start loop thru child nodes
for(var node=parentNode.firstChild;node!=null;node=node.nextSibling){
var myclass = (node.className ? node.className.baseVal : node.getAttribute('class'));
}
But this code for getting the classname only get's null values.
Any suggestions?
For those of you who are trying to figure out what the whole point is, read this JavaScript NextSibling Firefox Bug Fix I have code that does my language translation that works in Google Chrome and IE. But when I use it in Firefox, and try to translate div content after ajax has loaded it, it fails because of the whitespace issue.
I really don't have a preference of jQuery or Pure Javascript, I just want a working solution.
Thank you all for being patient. I personally thought I was extremely clear in my description, I apologize if it wasn't. I wasn't trying to be obscure or make it difficult to get help. But please don't insult me, by implying I am trying to make it unclear.
Thanks.
Hm... You have jQuery but don't use it?
$(divid).children(".yourSpecialClassName").each( function() {
doSomethingWith(this);
});
To get the CSS class attribute value, this will do:
$(divid).children().each( function() {
alert(this.className);
});
Based on the function you posted now, you want this:
$(divid).find(".status_bar").each( function() {
$(this).text( function(i, text) {
var x = $.inArray(en_lang, $.trim(text));
if (x > -1) {
console.log('Current Value ['+text+'] English ['+en_lang[x]+'] Translation ['+other_lang[x]+']');
return other_lang[x];
}
return text;
});
});
And please, don't ever use "do magic" as a comment again. This is incredibly lame.
EDIT. This can be made much more efficient (superfluous console.log() removed):
$(divid).find(".status_bar").each( function() {
// prepare dictionary en_lang => other_lang
var dict = {};
$.each(en_lang, function(x, word) { dict[word] = other_lang[x]; });
$(this).text( function(i, text) {
var t = $.trim(text);
return (t in dict) ? dict[t] : text;
});
});
if you are using jquery you can do this:
$("#myDiv").find("*").each(
function(){
var myclass = $(this).attr("class");
}
);
Your sample code doesn't make sense.
$(this).attr('value', to);
'value' is an attribute of the tag, not the text content.
Did you really mean to do this instead?
$(this).text(to);
Also, you've re-edited your question, but you're still trying to loop through the child nodes using non-jQuery methods. You said "The last obstacle I had in my script, of which you see a small portion of, is getting the classname. I need the class name so that I can filter down what content get's text replaced."
If you are using jQuery it is completely unnecessary to loop through anything to get a class name. You simply have to use a proper selector in the first place.
$(divid).find(".status_bar.replaceme").each( function() {
// .replaceme is whatever class you're using for the stuff you want to change
// .status_bar.replaceme matches all elements with BOTH status_bar and replaceme classes
var value = $.trim($(this).text());
// if value is not defined thru browser bugs do not replace
if (typeof(value) != 'undefined') {
// it is a text node. do magic.
// NOTE: The following is inefficient but I won't fix it.
// You're better off using an associative array
for (var x = en_count; x > 0; x--) {
// get current english phrase
var from = en_lang[x];
// get current other language phrase
var to = other_lang[x];
if (value == from) {
console.log('Current Value ['+value+'] English ['+from+'] Translation ['+to+']');
// value = to; <-- useless, get rid of it.
$(this).text(to);
// or $(this).html(to);
}
}
}
});