I have two hidden <div> elements which are hidden at the bottom of my page like so:
<div class="hidden-unit" style="display:none;">
<h1>ad unit one</h1>
</div>
<div class="hidden-unit" style="display:none;">
<h1>ad unit two</h1>
</div>
Further up my page I have another two div elements, like so...
<div class="visible-unit"></div>
<div class="visible-unit"></div>
I would like to loop through each of the hidden units, place the content from the first .hidden-unit into the first .visible-unit and then likewise for the second.
The content that sits within each .hidden-unit will actually be an inline script used for displaying ads, this is passed through from an array into a view that I have created in PHP so there is a strong possibility that more content could be added to the array or removed, so this loop needs to accommodate for such situations.
I have tried a number of solutions using jQuery's .each() but I can't seem to get it right. I've also created a JSFiddle should anyone want to demonstrate a solution:
https://jsfiddle.net/p89sq2df/3/
I've tried loads of different combinations and the latest attempt only seems to be populating the .visible-unit elements with the 'ad unit two' text.
$('.hidden-unit').each(function() {
$('.visible-unit').html($(this).html());
});
Anyone had to do anything like this before? I appreciate it's an odd one.
You can try using the index:
$('.hidden-unit').each(function(index) {
$('.visible-unit').eq(index).html($(this).html());
});
var visibleUnits = $('.visible-unit').toArray();
var x = 0;
$('.hidden-unit').each(function() {
visibleUnits[x].html($(this).html());
x++;
});
The gotcha is that there could be more .hidden-unit elements than .visible-unit elements, which would cause an exception. But this you put you on the right track.
You need to use the index the elements so you update matching instances. This can be done using each or html(function)
$('.visible-unit').html(function(index){
return $('.hidden-unit').eq(index).html();
});
Since you mention that the content is loaded by script originally, you may need to allow time for any asynchronous loading (if any) in the scripts
DEMO
Rather than trying to match indices and having to maintain two lists of divs, you can clone the hidden divs and add them to a container, or insert them before or after another element if you really don't want a container element.
$(".hidden-unit").clone()
.removeClass("hidden-unit")
.removeAttr("style")
.addClass("available-unit")
.appendTo(".container");
Working fiddle here: https://jsfiddle.net/ygn34zL8/
Related
I have two divs on the same page using CKEditor. I can get a toolbar to load for the first div, but not the second. I realize this is the case because I'm using an id for ckToolbar instead of a class. However, if I use a class, the toolbar doesn't show up.
Div 1
<div id="ckEditor">
<div id="ckToolbar"></div>
<div class="editor" data-bind="wysiwyg: txtBody, value:txtBody, valueUpdate:'keydown'"></div>
</div>
Div 2
<div id="ckEditor">
<div id="ckToolbar"></div>
<div class="editor" data-bind="wysiwyg: txtHelpText, value:txtHelpText, valueUpdate:'keydown'"></div>
</div>
Config.js
config.extraPlugins = 'sharedspace';
config.sharedSpaces = { top: 'ckToolbar' };
I am also using Knockout JS. I created a custom binding and a div instead of a textarea because I couldn't use the CKEDITOR replace function with my binding.
You can't have two elements on the same page with same id's. How is JavaScript supposed to recognize which one you have in mind? You should either use classes or different id's and adjust you knockout code to handle that.
Sorry for the general answer but there is simply no way around it. You can't have two elements with same id on a single page.
NOTE: CKEditor auto replaces elements with ckeditor class however if you are using knockout, I don't think this will me much of a use for you.
I have a PHP script that outputs data. It is all conveniently wrapped inside a p class.
It outputs the same data and same class multiple times, so there are like 6 blocks of text, each block being wrapped inside p class.
I need to reduce each block to 3 lines using any method possible. I already tried using PHP in various ways to no avail.
I came across Clamp.js which looked great. The only issue is, it will only work using ID. I can change the p class tags to p id, however, they'd all have to share the same ID, which, obviously, won't work.
Here's the current code I've tried:
var module = document.getElementsByClassName("clampjs");
$clamp(module, {clamp: 1});
And the HTML (times 6):
<div class="headtab">
Forum title<p class="bold">Posted By:</p> username <p class="bold">In:</p> category</div>
<div class="maintext">
<p class="clampjs">TEXT I WANT TO BE CLAMPED</p>
</div>
Like I say, it works fine when I use an ID, but obviously, only for the first block of text as the ID HAS to stay the same, that's why I'm using p class.
Sadly, what I've tried above doesn't work at all. Does anybody know a little fix for this script, or perhaps a different script that will clamp objects using a class element? Jquery is acceptable too.
Jsfiddle
Working code thanks to the accepted answer:
$(document).ready( function() {
$('.clampjs').css({ //changes the css of the clicked content.
'max-height':'75px', //give what ever height you want.
'overflow':'hidden'
});
});
this could be easily done with just editing your css
$('.clampjs').click( function() {
$(this).css({ //changes the css of the clicked content.
'height':'100px', //give what ever height you want.
'overflow':'hidden'
});
});
just now tested in my page it works...
Layout of the code:
An .html file & I link to an external .js and .css in head. Various table cells onclick make a "popup" div change its position and become visible. To do this, I made the JS functions reference a global variable which I set by adding
<script>var popup = document.getElementById('popdiv');</script>
just above the end of /body.
popdiv has 3 child elements:
<div id='popdiv'>
<div class='header'>Time Slot</div>
<div class='xout' onclick='hide(event)'>X</div>
<div class='showtag'>tag1, tag2, tag3, tag4, tag5, tag6, tag7, tag8, tag9, tag10, tag11</div>
</div>
Anything I do with popup works fine, except when I try to call popup.firstChild, which screws everything up. popup.firstChild.type returns undefined, and popup.childNodes.length returns 7. I gave the nested div an id so I could grab it; [getheader].parentNode.type is also undefined.
And I replaced the .header selector in my .css file with a first-child of popdiv selector (#popdiv >:first-child) and its style was still correctly applied; all 3 children will also inherit style attributes like color:red--if I set them in the CSS file. Not so if I set them with JavaScript.
In this case there are other ways I can access the divs, but I want to know for the sake of understanding JavaScript what the heck happened--or if I misunderstand something fundamental about parent-child HTML elements. Did I do something awful that could break other things? (Having the extra script at the end of the file feels wrong, but I don't know the actual reason it doesn't work out fine.)
Thank you in advance
Try document.getElementById('popdiv').children[0] as described here - for getting first child. Also you can use popup.firstElementChild that give you the same result.
And you can use document.getElementById('popdiv').childrento get all children.
I have a div that will appear on the page at a separate point. It doesn't always appear on the page and can be added via a CMS if needed. There's a line of text that will appear within the body. If the user has decided to have this div added, it would need to be moved into position via jquery. So, I have this text:
<p><strong>Key Facts:</strong></p>
I want to find it using jquery, then move the other div in front of it. I tried a couple of different ways to select this text then move the div in front of it and haven't had any luck. The best way I found to find the text was to do this:
var foundin = $('*:contains("<p><strong>Key Facts:</strong></p>")');
From that point, to move the div into position, I thought I could something like this:
$('#DivIWantToMove').insertBefore($foundin);
That didn't work, though. I also looked at this:
$( $foundin ).before( $('#DivIWantToMove') );
AS you might imagine, since you're reading this, that didn't work either. So, I'm asking you, is it possible to do what I want? I'm fairly constrained by the CMS that we are using. The DIV I need to move will always be someplace on the page and I have to move it. The client doesn't want to have to add a class to <p><strong>Key Facts:</strong></p> so I'm let with this. If I could have a class on <p> then it would be super easy. I've already done it. The client doesn't like having an extra step. Any ideas?
I think contains selector only looks for text, not html tags. so you have to modify your contains selector. if your html is like this -
<div>
<p><strong>Key Facts:</strong>
</p>
</div>
<div id="move">something something</div>
and you want to move your <div id='move'> in front of p, then try this -
var foundin = $('p:contains("Key Facts")');
var divtomove = $('div#move');
foundin.before(divtomove);
Demo
Update also look into this QA: jQuery :contains with html. Instead of using contains you can use one of the methods from there.
I am creating a UI, in which user can add / delete items (of similar layout).
It starts with one item and you can click 'add' to add more. The UI consists of several different types of items.
What I am doing currently is populating a single item item 1 ( of each type ) and on add event, I clone the item 1, replace the changes done by user in item 1 and append the clone to the container.
In simple words, instead of dynamically creating html with jQuery, I am cloning html of a div. But in this approach , I had to change a lot of things to keep to give the new item to initial state.
So, I want to avoid the replacing the edits done by user, so I was thinking something like below,
<script type="text/template" id="item_type1">
<div>
<div>Box</div>
</div>
</script>
<script type="text/template" id="item_type2">
<div>
<div>Box2</div>
</div>
</script>
And on add event, I want to do something like $('#item_type1').html() and $('#item_type2') to create new items.
I know there are sophisticated libraries like handlebar and mustache and underscore has its own way of implementing templates.
But I am not using any of these already and thus do not want to included them just to copy content. I dont want anything special. I am not passing variables. I am just cloning some markup to use again and again.
Is this way to insert html in script tags , going to work in all browsers ? and is it a good way ?
EDIT:
Its for the wp plugin and I assume js is turned on , else the plugin wont work anyways.
What about:
Your HTML should be, for example:
<script type="text/template" id="item_type1">
<div>
<h1>Box1</h1>
<p>
</p>
</div>
</script>
And your code would be:
var templateHtml = $('#item_type1').html();
var $item = $(templateHtml);
$('body').append($item);
$item.on('click', function() {});
This is an easy way that will work on all browsers.
Step 1: Create an HTML file with your template inside of it
Step 2: Using jQuery's load() method, call your HTML template into a div element in the main HTML file:
$("#main-div").load("yourtemplate.html")
Step 3: Be amazed
Is this a good idea? It depends:
If it's a self contained application on a known environment with a determined supported browser and with equally determined settings (like if JavaScript is on or not) then yea, sure. Why not?
If it's open to the public in every single browser possible with many different configurations, then no, it's a horrible idea. If your user doesn't have JavaScript enabled, then your content doesn't show up. Also, if one of your scripts break in production, then you are again left with no content. You can learn this lesson from when Gawker made this same mistake