Add class to LI element depending on data-size attributes - javascript

I am using Gridster for Wordpress to control the arrangement of a masonry style grid layout. Gidster basically allows site admins to reorder / resize posts in realtime (see screenshot)
Now as a rule I would only like to use a number of grid sizes (1x1, 1x2, 2x2). The markup for the grid is output as the following:
1x1: <li data-sizex="1" data-sizey="1" class="gs_w">
1x2: <li data-sizex="1" data-sizey="2" class="gs_w">
2x2: <li data-sizex="2" data-sizey="2" class="gs_w">
You can see the grid size is determined by the HTML 5 data attributes 'data-sizex' and 'data-sizey'. I would like to use Jquery check for these attributes on page load and add classes respectively..
For example an element with a grid size of 1x1 (data-sizex="1" data-sizey="1") would have a class of '1x1'
I believe I need to use attribute selector but am a little unsure as how to proceed.
$("li[data-sizex='1']")

You can use each to parse and get data elements to make the class
$('li').each(function(){
$(this).addClass($(this).data('sizex') + "x" + $(this).data('sizey'));
});
Edit to limit the add class for specific li e.g descendant of a particular element as mentioned by OP in comment we can extend the selector.
$('.gridster li').each(function(){...

$('li').each(function(){
$(this).addClass($(this).attr('data-sizex') + "x" + $(this).attr('data-sizey'));
});

Related

Obtaining Upper level li text

So I currently have a list like so on my page
<li class="head">
<b>Introduction</b>
<ul>
<li class="sub">somethingsomething</li>
</ul>
</li>
This list is being used with sortable, so the user can decide on the order, and I am passing this information to a grails controller for use in application logic. So, I am trying to read it in, and place the text contained in the "head" and "sub" classes in 2 different arrays. However, when I use a jquery selector to obtain the head elements, and obtain the text attribute of the element, it contains the inside list as well.
$('#divname').find("ul > li.head").each(function()
{
var current = $(this);
console.log(current.text());
});
results in Introductionsomethingsomething
Is there any way to only obtain the 'Introduction' text from the list, and ignore the text in the nested <ul> and <li.sub>? Due to it being nested, I am unable to figure out how to use jQuery's :not() selector
You can find the b tag using jquery tagname selector.Like this:
var current = $(this).find('b');
console.log(current.text());
Working Demo
May be this is solution:
<script>
$('#divname').find("ul > li.head").each(function()
{
var current = $(this).find("b");
console.log(current.text());
});
</script>

Remove inline css of an HTML elements

I'm using wordpress 3.5 and create menu with submenus. It's structured like this:
<ul class="menu">
<li id="menu1">Menu 1</li>
<li id="menu2">Menu 2</li>
<li id="menu3" style="z-index:100;">
Menu 3
<ul class="submenu">
<li id="submenu1">submenu1</li>
<li id="submenu2">submenu2</li>
<li id="submenu3">submenu3</li>
</ul>
</li>
</ul>
The problem is the menu with submenus, it's automatically attached a z-index with value 100. I don't want it to be like that because it gives me trouble on adding lavalamp effect to those menus.
I tried to edit the z-index by using jquery just after the menu is created using wp_nav_menus simply like this:
jQuery(document).ready(function(){
jQuery("#menu3").css("z-index", "0");
});
But unfortunately, it doesn't work. How can I remove that inline css style?
Use the removeAttribute method, if you want to delete all the inline style you added manually with javascript.
element.removeAttribute("style")
Reset z-index to initial value
You could simply reset the z-index to it's initial value causing it to behave just like the li would without the style declaration:
$(function(){
$('#menu3').css('z-index', 'auto');
});
You can go vanilla and use plain javascript (code should run after your menu html has loaded):
// If you're going for just one item
document.querySelector('#menu3').style.zIndex = 'auto';
Remove style attr
You could use jQuery to remove the style attributes from all your list:
Note: Keep in mind this will remove all styles that have been set to your element using the style attribute.
$(function(){
$('#menu3').removeAttr('style');
});
Or vanilla:
// Vanilla
document.querySelector('#menu3').style = '';
If you want remove all inline styles, Pranay's answer is correct:
$("#elementid").removeAttr("style")
If you want to remove just one style property, say z-index, then you set it to an empty value:
$("#elementid").css("zIndex","")
From the jQuery documentation (http://api.jquery.com/css/):
Setting the value of a style property to an empty string — e.g. $('#mydiv').css('color', '') — removes that property from an element if it has already been directly applied, whether in the HTML style attribute, through jQuery's .css() method, or through direct DOM manipulation of the style property.
This is what I consider a better approach because it only removes the z-index style instead of the whole style attribute. Here is a working Fiddle.
//As commented by #DA this is enough
$("#elementid").css("zIndex","")
//this could be useful in another situation so I will leave it :)
$(document).ready(function () {
$('#menu3').attr('style', function(i, style){
return style.replace(/\z-index\b[^;]+;?/g, '');
});
});
Hope it helps.

Table made from list (<ul>,<li>), how to select a row? (:nth-child())?

I made a table out of a simple list structure:
<html>
<body>
<ul id="Column:0">
<li id="Row:0></li>
<li id="Row:1></li>
<li id="Row:2></li>
<li id="Row:3></li>
<li id="Row:4></li>
</ul>
<ul id="Column:1">
<li id="Row:0></li>
<li id="Row:1></li>
<li id="Row:2></li>
<li id="Row:3></li>
<li id="Row:4></li>
</ul>
<ul id="Column:2">
<li id="Row:0></li>
<li id="Row:1></li>
<li id="Row:2></li>
<li id="Row:3></li>
<li id="Row:4></li>
</ul>
</body>
</html>
Now I want to add a simple .mouseover() to every row, for e.g. changing the color of a row, when hovered. And this is what I figured out, so far:
for (var i = 2; i <= _totalRows; i++) {
var row = $('#TimeTable ul li:nth-child(' + i + ')')
row.each(function() {
$(this).click(function(evt) {
var $target = $(evt.target);
console.log($target.nodeName)
if (evt.target.nodeName == 'DIV') {
console.log(evt.parent('li'));
}
}); //end $(this).click(fn)
}); // end each(fn)
}
I get a set of all <li> objects matching to :nth-child(i) where i is the rows number.
var row = $('#TimeTable ul li:nth-child(' + i + ')')
Now I just iter this set through to add a .click(fn) to every <li>.
This works fine. Every cell has it's .click(fn) attached to it.
But the following, what to do on a click, is where I'm stuck for several hours now:
var $target = $(evt.target);
console.log($target.nodeName)
if (evt.target.nodeName == 'DIV') {
console.log(evt.parent('li'));
}
I simply don't get it to run.
You can actually ignore this gibberish, as it's just the last of several things I already tried here.
What I'm trying to do is simply select every <li> with an id='Row:X' and manipulate its CSS. The best I yet had was, that I can click a cell, but no matter in what row this cell is, the last one gets colored. I remember having used i as the row-index, when that happened, so I might miss some understanding of event-handling here, too.
Use a class name for duplicate groups of elements not an ID. If you give row one a class of "Row1" the selector is simply:
$('.Row1')
Then:
$('#TimeTable li').removeClass('highlight');
$('.Row1').addClass('highlight');
If you just wish to change the color on mouseover:
$('#TimeTable ul li').mouseover(function(){
$(this).css('background','red');
});
$('#TimeTable ul li').mouseout(function(){
$(this).css('background','green');
});
Make your ID's like so: C1R1 (Column1Row1) and so on
JQuery read/google up "jquery each"
JQuery read/google up "jquery bind click"
JQuery read/google up "jquery attr" and "JQuery val()"
This will give you the knowledge to write your own and most importantly understand it better. You will want to achieve the following (your close but no for loop required):
A list which JQuery attaches a click event handler to each LI, and then when the click happens the ID can be retrieved.
PS. There's a time and place for tables, they 9/10 times nearly always better for displaying data than CSS is. If you have a complex multi column row and want fiexed hights and no JS to fix things or do anything smart you can have a table and css :Hover on TR for stying mouse over and out etc. Heights are also constant.
PS. PS. If your data is dynamic and coming from a database and the whole row is an ID from the database I tend to avoid using the html ID attribute for this and make my own. You can retrieve this via attr("myattribute");
NOTE ON CSS and IDS:
Standard practice for ID's are to be used once on a page.
Class for repeatable content
Good luck.

Parallel sorting two different lists using jquery sortable

I am having very specific case where I needed to split the data into two different lists in html. Like this:
<ul id="first_list">
<li ref="1">The quick brown</li>
<li ref="2">My father works</li>
</ul>
And the second list is like:
<ul id="second_list">
<li ref="1">jumps over the lazy dog</li>
<li ref="2">at the Ministry of Defense</li>
</ul>
So as you can see I from the "ref" attribute I know which <li> element from the second list is a continuation of which <li> element from the fist list.
Now I need to enable the jQuery UI sortable() to those lists but when I reorder the first I need the second reordered too. I tried using handle but it doesn't works because it looks like the handle element needs to be inside the element which is moved but these two are at a different places in the page.
I do believe that you should have shared some of your code (what you've tried), and I'm assuming you are familiar with Sortable plugin that you are using. You should run the below code on success event of Sortable so as soon as you sort any LI, the other list will be sorted too. Anyways,
Try this:
//This line stored the LIs in a temp variable and remove it
var $cachedList = $('<div />').html($('#second_list').html());
$('#second_list > li').remove();
//This line loads up the first UL's LIs and replaces the content for each LI
//using $cachedList.
$('#second_list').html($('#first_list').html()).find('li').each(function () {
$(this).html($cachedList.find('li[ref="'+$(this).attr('ref')+'"]').html());
});
Demo: http://jsfiddle.net/AR8px/

Selecting element to copy using jQuery Clone

I have a guide where each chapter is located in a separate LI of a UL. I am trying to use the jQuery Clone function to search through the parent UL that contains all of these 'chapter' LIs, and return those chapters that contain specific text.
Right now, I'm getting odd results, likely because it's copying elements at their smallest child, rather than just the entire div.
Also, each of these chapter LIs should only be returned once.
makeIntoSldieshowUL - UL that contains all 'chapters'
slideShowSlide - class name for each 'chapter'
searchResultsArea - Div in which to append 'chapters' that contain text
So far I have:
$("#makeIntoSlideshowUL").find(".slideShowSlide:contains('" + $(this).val() + "')").clone().appendTo("#searchResultsArea");
To give you an idea of the content I'm looking to clone, here is a brief sample
<ul id="makeIntoSlideshowUL">
<li class="slideShowSlide" id="0">
<div class="topicTitle">Cardholder responsibilities</div>
<p>Cardholders are responsible for ensuring proper use of the card. If your division or department has approved you for a Pro-Card, you must use the card responsibly in accordance with the following requirements:</p>
<ul>
<li>Purchase items for UCSC business use only</li>
<li>Never lend or share your Pro-Card</li>
<li>Purchase only allowable goods and services</li>
</ul>
</li>
<li class="slideShowSlide" id="1">
<div class="topicTitle"><strong>Restricted and Unallowable Pro-Card Purchases</strong></div>
<p>Some types of purchases are restricted are not allowed with the Pro-Card. Disputes with suppliers are initially handled by the Cardholder if, for example, they don't recognize a transaction on their statement, or the amount doesn't match their receipt. The Cardholder is responsible for contacting the supplier immediately to try to resolve the matter.</p>
</li>
Use jQuery's .children() method instead of .find() since it sounds like the .slideShowSlide elements are immediate children.
$("#makeIntoSlideshowUL").children(".slideShowSlide:contains('" + $(this).val() + "')").clone().appendTo("#searchResultsArea");
Or you could use the > child selector instead.
$("#makeIntoSlideshowUL > .slideShowSlide:contains('" + $(this).val() + "')").clone().appendTo("#searchResultsArea");
EDIT: At one point, you seem to refer to the chapters as divs. If they're a child of the <li> elements, you'll likely need something like:
$("#makeIntoSlideshowUL > li > .slideShowSlide:contains('"...
try using the has or contains selector
has will not change the current element on the jquery stack.
$("#makeIntoSlideshowUL")
.has(".slideShowSlide:contains('" + $(this).val() + "')")
.clone()
.appendTo("#searchResultsArea");

Categories