Where each variable is equal to spans content add class - javascript

The Question and Codes
I am struggling with the below code:
$('.rdsubs-mysubscriptions table tbody tr td a').each(function() {
var subItem = $(this).html();
//console.log(subItem);
var subItemStripped = subItem.substring(12);
console.log(subItemStripped);
$('body').find('span:contains("subItemStripped")').addClass('HELLO');
}); // end of each function
When I check the console for subItemStripped then it shows this:
Framework
Content
Slideshow
Which means (in my head at least ;-)) that for each span that is inside the body it should find one of these subItemStripped and where it finds a match it should add the class hello but this is not happening.
Actually, nothing is happening.
When I change this line:
$('body').find('span:contains("subItemStripped")').addClass('HELLO');
to
$('body').find('span:contains("Framework")').addClass('HELLO');
It works nicely. So am I putting the variable subItemStripped wrongly in there or has it something to do with the .each() function.
I tried the below things to make it work
With the above code I tried a couple of variations before I came here:
$('body').find('span:contains(subItemStripped)').addClass('HELLO');
$('body').find("span:contains('subItemStripped')").addClass('HELLO');
I also tried it with completely different sets of code I gathered from other SO posts but none of those worked. Why I don't know.
$("span").filter(function() {
return $(this).text() === subItemStripped;
}).addClass("hello");
$("span").filter(function() {
return $(this).text() === subItemStripped;
}).css("font-size", "6px");
Why do I need this
I know I don't have to explain why I need this but it could be useful in coming up with other great ideas if the above is not feasible.
I have a webpage and on that page is a menu filled with products that a user can download if he/she has access.
Each menu item has a span with the title in it. Those titles are built up like: Framework Content Slideshow
On this same page is also a component that shows all the users subscriptions.
With the above code, I look to all the subscriptions of the user. Which returns
CompanyName Framework CompanyName Content CompanyName Slideshow
Then I Strip .substring(12) all the parts that I know are not present inside the menu. Which leaves me with Framework Content Slideshow
At this point, I know that some menu titles and the stripped item are the same and for every match, I want to add a class upon which I can then add some CSS or whatnot.
Hopefully, the question is clear and thanks to everyone in advance for helping me out.

#gaetanoM You are completely right. Right after I posted the question I came on this site:
jQuery contains() with a variable syntax
And found the answer which is the same as you are saying!
$('body').find("span:contains('" + subItemStripped + "')").addClass('HELLO');
Thanks so much!
#gaetanoM Can you make your comment in an answer? Then I can select it as the accepted answer. I am answering this question now just to make sure it has an answer. As people get punished for asking questions that don't get answers.

Related

How to be able to click on a TR and edit personalia

I'm studying webdevelopment and I'm doing a single page application right now. We are using JavaScript, and I can`t use jquery, bootstrap, etc. I have googled, seen the videos from the lectures, but I am still blank as a canvas.
The problem is I need to make a contactregistre. You should be able to click on the contacts, a different section of the page should be made active where you will be able to edit the contacts and see where they live. The map is OK, but I don`t know how I can make this happen, I find no examples about this which does not suggest using jquery.
We have guessed something like this, but it is probably wrong:
document.querySelector("tr").addEventListener('click' , e => {
document.querySelector('editContact')
function editContact(contact) {
let editContact = document.querySelector("#searchcontact tr");
editContact.innerHTML = "TR";
let form = document.editContact()
}
})
Thanks so much in advance!
There are numerous ways to do this. This is not a complete solution, but should get you started:
Typically you'd have a text input already in your table <input name="username_1" class="hidden" type="text">, which is hidden, along side the content, like <span id="username_1">MAREN</span>
Then you'd have some CSS to hid things:
.hidden {
display:none;
}
So on the click even you'd add the hidden classname to the SPAN and remove it from the INPUT. This visually swaps the static value for the label.
There's more to it after that, but give it a try.

JQuery Toggle Divs Based On Index not retoggle when clicked twice

and thank you for reading this question. Let me preface this by saying that I am not a programmer and only have tried to learn javascript to make my own websites look and function the way I want.
I have a page with several hidden divs. I'm using elements with the same class and different targets to trigger this Jquery
jQuery(function () {
jQuery('.nav').click(function () {
var index = $(this).index(),
newTarget = jQuery('.targetDiv').eq(index);
jQuery('.targetDiv').not(newTarget).slideUp('fast')
newTarget.delay('fast').slideToggle('fast')
return false;
})
});
So my ".targetDiv"s look like this:
<div class=".targetDiv" style="display:none">div1</div>
<div class=".targetDiv" style="display:none">div2</div>
<div class=".targetDiv" style="display:none">div3</div>
And the "navigation" would look something like this
link1
link2
link3
This is not my code, and I got it from here: http://forum.jquery.com/topic/slidetoggle-multiple-divs-31-5-2013
It works exactly as it is supposed to and I have no complaints about that. When you click on a link, the corresponding div toggles, but when you click the same div again right afterwards, it toggles again and slides up (which is how the code is written). I want to stop that from happening, and since I am new to Javascript and Jquery I can't figure out how to do it. My non programmer mind assumes that there should be some kind of if else clause, where you would say:
if .targetDiv is :visible, then do not toggle newTarget. However when I tried to do that, it did not work.
if($(".targetDiv").is(":hidden")) { jQuery(function () {
jQuery('.nav').click(function () {
var index = $(this).index(),
newTarget = jQuery('.targetDiv').eq(index);
jQuery('.targetDiv').not(newTarget).slideUp('fast')
newTarget.delay('fast').slideToggle('fast')
return false;
})
});}
else {alert("already open")}
I don't know how else I should handle this, but it must be possible and I am probably just thinking of how to achieve what I want in entirely the wrong way. I understand very little about javascript, but I am not asking for someone to write this for me, I'd rather have someone tell me what it is that I am doing that is incorrect, then explain what it is I should be trying to do. Then I can use google to search for the way to achieve that.
Again, thank you for taking the time to read this and hopefully I've been detailed enough for some answers.
You just need to wrap the two 'slide' lines in the if statement, like so:
if (!newTarget.is(':visible'))
{
jQuery('.targetDiv').not(newTarget).slideUp('fast');
newTarget.delay('fast').slideToggle('fast');
}
You may also want to fix a few issues with the html, e.g. take the periods out of your class names. When querying for DOM elements, the "." means, "Find the things that have a class called _[whatever follows the dot]". Don't put dots in the classes themselves.
You may also want to take out the href attributes of the <a> tags. They aren't necessary.
Here's a working JSFiddle. Cheers!

Pass a PHP variable from a loop via an onclick

This may have been answered elsewhere but I couldn't find a question which fit my circumstances.
I have a site page which out puts in DIVs records from a database, this the same DIV looped. In this DIV I have a button which brings up a modal box. This modal DIV however is not coded within the looped DIV.
I need the modal box to be able to get the ID of the record for the data which the looped DIV is showing.
The button is:
<a href = "javascript:void(0)"onclick = "document.getElementById('light2').style.display='block';document.getElementById('fade').style.display='block'">
<div class= "obutton feature2">Reserve Book</div>
</a>
I assume I'll need to use java script somehow, but I don't know how to use it in this manner.
Ideally using some sort of form $_POST would be easiest with the form button having the set value of the $row->ID, but I can't make a form button also a can I?
Sorry for the possibly silly question, as I've said I've found similar things asked, but always find it hard to understand the full workings on other peoples scenarios as opposed to my own.
All help appreciated -Tom
I think the key to your answer is understanding how JS (and jQuery) uses this. When a function is called, the caller is almost always passed as the this variable. For example:
<button data-id="1234" onclick="runThisFunction()" value="run" />
<script>
function runThisFunction() {
//Do Stuff
var data_id = this.data('id');
};
</script>
In the above code, this contains the button that was clicked on. You can get lots of information from the this variable. In jQuery, you can even get to siblings, parents, or children in the DOM.
Here is an example solution to your question:
http://jsfiddle.net/yr6ds/1/
Here is a more elegant solution:
http://jsfiddle.net/yr6ds/2/

Jquery toggle mobile menu (remove href javascript)

I'm trying to make a jQuery toggle menu for a mobile website for one of my clients. I'll have to tell you i'm not experienced in javascript and i justed started looking at it.
The current website is a Wordpress website so the menu structure is generated by WP.
Because this is generated by WP i need to use javascript to manipulate the data for adding the + - and > signs for toggleing and if no childeren to go directly to the page.
I use this javascript for adding the spans with the desired icon. I've managed so far.
http://jsfiddle.net/9Dvrr/9/
But there are still 2 problems i can't seem to figure out.
Remove the href from the "a" when the "li" has a "ul" child.
This should remove the links of the items so they will only toggle (not link) to navigate straight throug to the deepest level.
Currently the javascript is adding mutiple spans with the icons. I can't seem to figure out why
I'm stuggeling with this for a while now and was wondering if someone could help me with this.
In the jsfiddle you provided, you loop on the elements to add spans with a "+" or "-" sign inside, depending on the case. The thing is, the HTML you're starting with already has those spans in it, wich is why you're seeing some duplicates.
As you said you can't add those spans in the HTML because of your WP strucutre, I guess they come from a bad copy/paste you did while creating the jsfiddle. I removed them in the HTML and added a return false to prevent linking to another page when there is a ul inside the a tag.
http://jsfiddle.net/wzzGG/
Your first problem can be solved with the following:
$.each($('#menu-mobiel li'), function(i, value) {
var $this = $(this);
if ($this.has('ul').length > 0) {
$this.children('a').attr('href','javascript:');
}
Your second problem is a bit harder for me to understand. Do you only want one + for items with submenus, and one > for items with a link?

Trying to fix table header, getting css issue

Initially I asked this Question and written my own plugin to achieve the same,But i am facing very strange issue regarding to css of table.
After applying the plugin table cells borders are getting dis-sorted.
jsFiddle of the problem: Problem demo
In fiddle you can see that after first cell of the first tr, the header border line and table border line don't line up. I want the border line of thead cells and td cells to line up.
Can anyone tell me how to achieve that?
Lets start by doing a bit of a clean up of the code you posted so I can actually read your code and maintain a firm grasp on reality while we go down this rabbit hole.
If you write clean code, your problems will be exceptionally easier to see.
So lets clean it up and watch as all the problems here reveal themselves.
Step one: Your jsFiddle sets it to run "onDomReady," which basically means you've got $(document).ready(...) calling all the code in the box, which is fine, except you're got another got $(document).ready(...) inside there. Lets change that.
Step two: Lets add some white space and proper indentation in there, and stop using these one letter variable names.
{} are scope brackets, they should indent, not cover everything, they let us know what part of scope something is in.
Don't write .each() loops on one line, this adds no value and makes your code confusing to read.
$t should be called something meaningful, lets try element, because it holds the $(this) element, which is the active element you're working with.
w should be called something meaningful, but since you only use it twice I'm just going with element.width().
o needs to be less ambiguious, lets go with obj.
Step three: Selection structures
if(typeof(i)=='number')o.height=i;
else if(typeof(i)=='object')o=i;
else if(typeof(i)=='undefined')o={height:300}
Break that up, make it readable. Saving lines doesn't make you a better program, writing clean and easily understandable code will.
Why not use the switch-case statement?
switch (typeof(i)){
case "number":
o.height=i;
break;
case "object":
o=i;
break;
case "undefined":
o={height:300};
break;
}
Step four: Don't in-line styles. Just don't. There's no reason to do it, and it makes everyone's life harder.
Instead, lets just place the styles gently into the style sheet where it belongs, and make the parent=$('...') line look like parent=$('<div><div></div></div>').appendTo('body');.
Step five: Closure doesn't pass any value to arguments
After a bit of clean up, we see this block of code:
self.width(self.width() -
function(width){
var parent,child;
if(width===undefined){
parent=$('<div><div></div></div>').appendTo('body');
child=parent.children();
width= (child.innerWidth()) - (child.height(99).innerWidth());
parent.remove();
}
return width;
}()
);
Okay, that's a problem. Lets cut out a few lines to point out the problem here:
self.width(
self.width() -
function(width){
/*...*/
if(width===undefined){
/*...*/
}
return width;
}()
);
So, a quick refresher on this pattern you have here:
(function(arg1){
/*code*/
})(data);
Data gets passed to arg1. Arg1 declaires a variable in the scope local to that function, it doesn't get anything from outside. Outside data is passed in through the set of () that call the function, which your code had left abandoned. Think of it this way:
var msg = function(text) {
alert(text);
};
Then you call it as...
msg("hello world");
What your closure is doing is almost the same thing, except where you define your function, you also call it. Thus...
(function(text) {
alert(text);
})("hello world");
So, you need to pass a value of some sort into there, other wise this whole thing is always undefined. Lets do that. What are we passing? I have no way to be sure. This is why programmers need to add comments to their code.
Step six: Comment your code so people other than yourself will look at this code and have not a damn clue what you truthfuly wanted to do, and can only guess. It's like you posted a 200 point bounty and didn't bother helping people who want to help you. Why are you doing this to yourself, dude? Why couldn't you just go //This is what this does to give me a hint? What did I ever do to you?
Step Seven: Lets see if we can make the JS changes work with the JS Fiddle
Great odin... that HTML's 2000 lines long?
Okay, I'm working with pastebin here for the sake of saving space in the post here.
Alright, you started off with this: http://pastebin.com/xjmm4cev
You're using a lot of no-wrap, and putting classes onto individual elements. You shouldn't have to do this on each HTML element, CSS takes care of that very effectively, so lets go ahead and just rip out all the nowrap=nowrap and class="header" stuff (we'll put it back in a moment, but only ONE per group, not each element).
Then lets get rid of the useless blank lines.
Lets run this through HTML tidy and get it nice and indented correctly.
http://pastebin.com/uHtSZ4h5
Much easier to read over. Okay, so what do we see here? Well, it looks like you keep going in circles, cutting and pasting the same thing again and again. You also in-line javascript such as using onchange and onclick attributes. This is generally an awful thing to do to your code, and makes it hard to maintain (as I'm sure you've seen with this 2000+ line beast of cut+paste 27 times in a row).
So, lets take a look here:
elements, not inside a form
Elements in a table that are outside of rows, but not head/body/footer sections of a table
Code that's a huge pain to maintain because it keep going in circles, if you need to change this, you're basically screwed.
Lets fix all that.
We're going to use events in the tags, rather than in-line things. So, all of those in-line onchange and click attributes get the boot.
All of these inputs that are just floating around need to get put into a form, and taken out of this place in tables that only rows or table sections belong in.
Figure out how we can not have excessive input elements, if we can help it.
What the heck is the )="" that you have on every input button? Deleted.
So, here's all of your hidden boxes: http://pastebin.com/LXZSkvyf which I've removed, because we don't have a anywhere.
And here's what the code looks like without all of these weird things in it: http://pastebin.com/MiaJTGpb
Much more readable, but still not quite there.
Step 8: What can you do to make the HTML of the table work better?
You're using Thead and Tbody, and that's good.
You're using attributes for things like cellpadding, that's bad.
You've given each body row an ID. I don't feel you needed to do this, but it's not always bad. However, I'll show you how you could work without it.
You give some selects a select-box class, but it's nowhere in the css. I've removed it.
You give a title attribute to the selects that says "option_value". The title attribute is generally used to make a tool-tip popup when you leave the mouse over something. I'm not sure what you're going to do here, but that's bound to confuse your user. I'd highly suggest giving something better than option_value in that place.
You keep using the ID Submit_FMS_AddDelivery. HTML ID tags are meant to be unique, and used only once on one element. You've got it 27 times, that's bad. I don't think you need an ID on it, so I've removed it.
You've also got input-btn going on, I'm removing it, because you haven't shown it's used anywhere.
You probably don't need any of these ID tags on select and TR to be honest, so I'm pulling them.
What's that look like? Basically, you've got what's almost just the data, in it's nice pure form. That's good. http://pastebin.com/UNS6CAtb
Step 9: What were you trying to do?
Lets step back and take a look here.
All you really wanted to do was keep a fixed header, but you've ended up doing a lot of JavaScript hacks and manipulating the DOM in a lot of places. We need to stop doing this. Is there a simpler way to do what you want?
I'll have to expand on how to make this function with the rest of your stuff, but I get up for work in a few hours. I'll update again with more... But we'll get there.
Right now, because I haven't fixed what I took out, it doesn't look right. But I'm tired.
So, here's where we are so far: http://jsfiddle.net/5C6z7/
Plus those inputs we took out (and will be going back in later, in a different way)
Looks like all you have to do is to take the padding into account: each cell has 3 px padding both left and righ so you have to add 6 px to the width:
$t.find('tr:first th').each(function(){cols.push($(this).width()+6);});
Otherwise the cells with only one word inside will "push" the actual width a bit wider so that the word will fit and other cells with space to move will compensate by becoming a bit narrower. The header and the body both do this independently with different contents which creates the difference in actual cell widths.
EDIT: For Firefox you also need to widen the table so that the cells fit. After calculating the column widths add
var actualWidth = $t.width()+cols.length*6;
$t.width( actualWidth );
And later change the wrapper to:
$wrap.css({width:actualWidth,height:o.height,overflow:'auto'});
EDIT 2: To have both the header and the body scroll simultaneously you need to wrap them both to an outer div that handles the scrolling.
var $outerWrap = $( '<div>' ).css( {width:"300px", overflow:'auto' } );
var $wrap=$('<div>').css(
{ width:actualWidth,height:o.height,"overflow-y":'auto', "overflow-x":'hidden' }
);
$firstRow.wrap( $outerWrap );
$firstRow.after( $wrap );
$wrap.append( $t );
Demo: http://jsfiddle.net/YcRTz/2/
What about replacing '<th>' tags with '<td>' tags?
No extra js code required.
http://jsfiddle.net/spQAh/7/
Okay so instead of troubleshooting or using anything complex, I came up with simple CSS + JS solution to your problem. Take a look at http://jsfiddle.net/TdLQT/
Obviously, the process of making header static, can be made dynamic, meaning trigger it after user scrolls a bit or have it there by default or count other object's position from top window and trigger static behavior when it reaches or exceeds certain pixels. I can provide that if you give me details on exact design of your HTML page.
Anyways, I as you can see, have used fixed pixel heights which you can choose not to or make them elastic or dynamic. What is important to know is that, though solution relies on JS a bit, output position is purely from CSS. I am using classes to manipulate the position.
the simple solution is that when you calculate the width of the column you do not include padding. So you need to change the line
$t.find('tr:first th').each( function() {
cols.push($(this).width());
});
to
$t.find('tr:first th').each( function() {
cols.push($(this).outerWidth());
});
if your cells have margins use .outerWidth(true)
This works in quirks mode with IE7&8 and Chrome IE8 has a problem in strict mode. However I believe that that problem is caused by the added scrollbar. If you want to use IE8 in strict mode you have to allow for the width of the vertical scrollbar..

Categories