Use find data attribute to add class - javascript

I am attempting to create a menu with unique data attributes attached to each navigation item. On click I want that navigation item to find the section with the same attribute and add a class to it. This is the code I am using thus-far (it is part of a much larger script).
var $el = $( '#bl-main' ),
$sections = $el.children( 'section' ),
$navItems = $( 'nav > a' );
$navItems.on( 'click', function( event ) {
$el.addClass( 'bl-expand-item' );
$navItems.find("[data-section='" + current + "']");
$sections.find("[data-section='" + $navItems + "']").addClass( 'expand expand-top' );
} );
This is the script it based off of. http://tympanus.net/Development/FullscreenLayoutPageTransitions/
The idea is to add a separate floating navigation to link to the different sections (instead of the direct click to expand that is current implemented). The current script I added only seems to refresh the page on click. I couldn't get it to work in a fiddle at all so the original script im sure will work. The section pasted about I have added in on my local files.

On the first line, when you try to call for a <section> element, you are missing the jQuery shorthand before the parentheses. That should fix your script.
So it should look like:
var $section = $('section');
That should have you all set to continue!

First off you are missing your $ in the first variable assignment. var $section = $('section')
After that it is difficult to tell what you're trying to do without seeing your markup, but I'll take a stab at it.
It appears that you are trying to filter the $section object by the data-section attribute of the nav > a element. This code should do just that:
var $section = $( 'section' ), $navItems = $( 'nav > a' );
$navItems.on( 'click', function( event ) {
var $navSection = $section.filter("[data-section='" + $( this ).data( 'section' ) + "']");
$navSection.addClass( 'expand expand-top' );
return false;
} );
Notice that we are filtering all of the sections by the value of the clicked anchor's data-section attribute.
If that doesn't help, add your markup so we can see your structure.

Related

How do I access filters through external URL and highlight only active filter class in the menu?

My Isotope gallery, which you can see here uses the code below to update the URL hashes in the address bar depending on which class is selected. If you select class Mishmash, you will see https://thedivtagguy.com/#filter=.mishmash in the address bar. This part works well but if you try going to this Mishmash category url I showed you above, it only highlights the filter class and doesn't actually sort the grid.
EDIT: This seems to be working off and on.
Why is this not working, the code seems to be valid?
<script>
(function($) {
function getHashFilter() {
var hash = location.hash;
// get filter=filterName
var matches = location.hash.match( /filter=([^&]+)/i );
var hashFilter = matches && matches[1];
return hashFilter && decodeURIComponent( hashFilter );
}
$( function() {
var $grid = $('.isotope');
// bind filter button click
var $filters = $('#filters').on( 'click', 'li', function() {
var filterAttr = $( this ).attr('data-filter');
// set filter in hash
location.hash = 'filter=' + encodeURIComponent( filterAttr );
});
var isIsotopeInit = false;
function onHashchange() {
var hashFilter = getHashFilter();
if ( !hashFilter && isIsotopeInit ) {
return;
}
isIsotopeInit = true;
console.log(hashFilter);
// filter isotope
$grid.isotope({
// itemSelector: '.selector.col-md-6.col-lg-4',
filter: hashFilter
});
// set selected class on button
if ( hashFilter ) {
$filters.find('.active').removeClass('active');
console.log($filters.find('.active'));
$filters.find('[data-filter="' + hashFilter + '"]').addClass('active');
}
}
$(window).on( 'hashchange', onHashchange );
// trigger event handler to init Isotope
onHashchange();
});
})( jQuery );
Secondly, I've tried adding these links to my main menu (so that the grid is navigable from the top and if the user is on other pages, it would redirect to home and just filter the grid) and I've entered the full URLs for each category as the links, so the main menu has item Mishmash which has the link https://thedivtagguy.com/#filter=.mishmash. As you can see in the image below, for some reason all of the links are active but it's useless navigating using them; only the URL in the address bar changes without actually filtering. Which part of the code is causing this to happen and how do I make the other links inactive?
UPDATE: Video clip of the problem available here
You have two main issues in your code:
You are .isotope for container selection, but you do not have any container with class isotope instead change your code to var $grid = $('.masonry');
You have some class and ids set for your secondary navigation menu, use same classes for your main navigation menu as well, if you want to have active filter link highlighted. Which means adding:
2.1 data-filter attribute to li elements
2.2 change var $filters = $('#filters') to var $filters = $('#filters, #menu-portfolio-1')
for showing active category and sorted items... you have to assign your onHashchange() inside window onload function.
window.onload = function() {
onHashchange()
};
more info MDN

Changing jQuery marquee text and css/style

I have div
<div id="rotatingText" class="marquee">
</div>
and marquee on that div is initialized on window load
jQuery('.marquee').marquee({
duration: 3000,
gap: 50,
delayBeforeStart: 0,
direction: 'left',
duplicated: false
});
Now i need to change text and css of that div on ajax aftersuccess. I get new text and css properties in that ajax response. With that text and css I invoke following:
function setRotatingTextProperties( value, css, objectId )
{
var object = document.getElementById( objectId );
object.innerHTML = value;
jQuery ( object ).attr( 'style', css );
}
After that marquee stops working.
I think that jQuery marquee sets some style in that div and i override it with:
jQuery ( object ).attr( 'style', css );
if I just add my css to existing with
var currentCss = jQuery ( object ).attr( 'style');
jQuery ( object ).attr( 'style', currentCss + css );
with multiple changes I will end up with huge amount of unusable css. And that css will change regularly ( every fiew seconds )...
Any advice and idea will be much appreciated.
Thx in advance.
Actually I think that your problem is not in your css and:
jQuery ( object ).attr( 'style', css );
In my experience problem with jQuery marquee is in changing of text. so your problem is:
object.innerHTML = value;
Best solution ( If you can change html of that page ) is to add span into it:
<div id="rotatingText" class="marquee">
<span id="rotatingTextSpan"></span>
</div>
And change span text, and style of the div. something like:
function setRotatingTextProperties( value, css )
{
// change span text value
$( '#predefineImageRotatingTextSpan' ).text( value );
// change css value on div
$( '#predefineImageRotatingText' ).attr( 'style', css );
}
If you can't change HTML of that page for any reason you can always insert span value into it on window.load or document.ready, but BEFORE you initialize marquee with something like
$( '#predefineImageRotatingTextSpan' ).html( '<span id="predefineImageRotatingTextSpan"></span>' );
and then use above function.
EDIT:
If you have some predefined text in your div at the beginning just copy its value into that div:
var $object = $( '#predefineImageRotatingTextSpan' )
var initialText = $object.text()
$object.html( '<span id="predefineImageRotatingTextSpan"> ' + initialText + '</span>' );

Limiting the jQuery search scope correctly?

I've stumbled up this code and I'm wondering if its just limiting the scope or selecting both of the elements at the same time.
container = jQuery("#test", parent.document);
jQuery("param[name=scale]", another.object)
Can anyone shed some light on this?
Edit: the full example:
<script type="text/javascript">
jQuery = parent.jQuery;
container = jQuery("#test", parent.document);
another = {
targetw: container.width()
};
function onEnd(){
container.slideUp();
}
function onStart(){
another.object = jQuery("object", document);
another.w = another.object.attr("width");
another.h = another.object.attr("height");
another.targeth = Math.floor(another.targetw * another.h / another.w);
jQuery("div>iframe",container).width(another.targetw);
jQuery("div>iframe",container).height(another.targeth);
another.object.css("width", another.targetw+"px");
another.object.css("height", another.targeth+"px");
another.object.attr("width", another.targetw);
another.object.attr("height", another.targeth);
jQuery("param[name=scale]",another.object).attr("value","exactfit");
another.object.parent().attr('style', function(i,s) { return s + 'background:none; width: '+another.targetw+'px !important; height: '+another.targeth+'px !important;' });
}
document.write('*snipped code*');
</script>
`
That appears to be the context argument from the jQuery selector jQuery(selector[,context]).
From http://api.jquery.com/jquery/
Selector Context
By default, selectors perform their searches within the DOM starting at the document root. However, an alternate context can be given for the search by using the optional second parameter to the $() function. For example, to do a search within an event handler, the search can be restricted like so:
$( "div.foo" ).click(function() {
$( "span", this ).addClass( "bar" );
});
When the search for the span selector is restricted to the context of this, only spans within the clicked element will get the additional class.
Internally, selector context is implemented with the .find() method, so $( "span", this ) is equivalent to $( this ).find( "span" ).
It is a child - parent selector. The search starts within the parent instead of the whole DOM.
$('childNode', parent)
It is same as
$(parent).find('childNode')
Considering container = jQuery("#test", parent.document);
As #test is an ID based selector just jQuery('#test') wont make any difference as IDs are unique across the DOM elements.

Recommended method of adding/storing/constructing HTML controls dynamically

Is there a recommended method of dynamically adding/storying/constructing HTML controls to dynamically added elements on a HTML page?
Basically, I have a widget based system I'm working on, where the user chooses the widgets s/he wants to have displayed. S/He can have as many or as little widgets on the screen as required, and they can also have the same widget many times displayed at once.
The script for that looks something like this:
success: function( widget_shell )
{
if( widget_shell.d[0] ) {
$(".column").empty();
var i = 0;
for ( i = 0; i <= widget_shell.d.length - 1; i++ ) {
var $widget = $("<div class='widget widget_" + widget_shell.d[i].widget_id + "'>").appendTo( $(".column_" + widget_shell.d[i].column_id) );
$("<div class='widget_header widget_header_" + widget_shell.d[i].widget_id + "'>").appendTo( $widget );
$("<div class='widget_sub_header widget_sub_header_" + widget_shell.d[i].widget_id + "'>").appendTo( $widget );
$("<div class='widget_content widget_content_" + widget_shell.d[i].widget_id + "'>").appendTo( $widget );
$("<div class='widget_footer widget_footer_" + widget_shell.d[i].widget_id + "'>").appendTo( $widget );
}
each .widget will need controls such as buttons, textboxes etc in the .widget_sub_header section. What is recommended way of doing that? "That" as in, how to get further HTML controls into the .widget_sub_header. Add the HTML for the controls in the database? Somehow connect to an external file containing the HTML controls and add them in? or some other method?
I guess my 2 main concerns are:
Easy maintenance
Server resource friendly
jquery-ZenCoding is easy way to create some nested html elements :
https://github.com/zodoz/jquery-ZenCoding
exemple :
$.zen("div#widget>ul.instrument>(li{piano}+li{guitare}+li{flute})");
What about something like this? I suggest instead of adding a class with the id, add an actual id on the parent, that's all you need to target children elements.
function createWidget( id ) {
var widget = [
'<div class="widget">',
'<div class="widget_header"></div>',
'<div class="widget_sub_header"></div>',
'<div class="widget_content"></div>',
'<div class="widget_footer"></div>',
'</div>'
].join('');
return $( widget ).attr( 'id', 'widget_'+ id );
}
$.each( widget_shell.d, function( i,v ) {
$('.column_'+ v.column_id)
.append( createWidget( v.widget_id ) );
});
I'd add a small template engine. There is a very simple one made by John Resig that I use frequently at:
John Resig micro-templating
Chances are you'll be doing this sort off thing again so a template engine is pretty handy to have lying around.
If you don't like that one you can have a look at a great resource of micro-templates at:
Microjs templates
I've used to work on a similar widget system.
This is how I've managed it :
Have a hidden div container that holds all the template elements.
<div id='widget-templates'>
<div class='widget1-id' >
<input type='text' class='ytSearch'/>
<button id='btnYtSearch'>Search</button>
</div>
<div class='widget2-id'></div>
...
<!-- etc etc -->
...
</div>
I used an object called widgetFactory which holds all the javascript code needed to create a widget from the template.
var widgetFactory = {
youtubeSearch: function(data){
var $generatedWidget = $('#widget-templates > .widget1-id').clone();
// prepopulate with some data if requested (usually when binding data to an already existing widget)
// ...
// attach events
// ...
return $generatedWidget;
}
}
Then with external javascript logic, I would save just the widget data (as JSON) and widget type into the database.
tbl_widgets(id, name, type)
tbl_user_widget(user_id, widget_id, data)
Note that this is just from my memory and there probably is a much more profound solution, but i hope it could shine any new idea on your user customizing widget system.

Manipulating Tumblr's default iframe controls

Is there any way I can manipulate the tumblr controls? They are quite ugly and gray. I want to know if there is any way to add iframe#tumblr_controls {display:none;} to my CSS and recreate all the controls with the same functionality but with a different look. Tumblr controls (iFrame)
Yes, it's fairly easy to replace all the functionality. As you suggested, you can hide Tumblr's default with:
#tumblr_controls {display:none;}
On index pages, you need Dashboard, Follow, and Email. You can't determine if you need Unfollow, but always showing Follow shouldn't be too bad.
Dashboard URL:
http://www.tumblr.com/dashboard
Follow URL:
http://www.tumblr.com/follow/<blogname>
Email URL:
http://www.tumblr.com/send/<blogname>?redirect_to=http%3A%2F%2F<blogname>.tumblr.com%2F
On permalink pages you also need Reblog and Like. These are a little more difficult but I have a sample here: http://like-button.tumblr.com/
Reblog uses an undocumented variable, {ReblogURL}. You simply make it the the href of a link:
reblog
To add Like functionality, you use the following URL and set it as the src attribute of an invisible <iframe>:
http://www.tumblr.com/<command>/<oauthId>?id=<postId>
<command>: like or unlike
<oauthId>: last eight characters of {ReblogURL}
<postId>: {PostID}
Example:
http://www.tumblr.com/like/fGKvAJgQ?id=16664837215
You need to put both variables, {ReblogURL} and {PostID}, into your {block:Posts} block. Then use script to build the URL and set the src.
$( document ).on( 'click', '.like', function ( event ) {
event.preventDefault();
var command = $( this ).hasClass( 'liked' ) ? 'unlike' : 'like',
post = $( this ).closest( '.post' ),
oauth = post.find( '.reblog' ).attr( 'href' ).slice( -8 ),
id = post.attr( 'id' ),
likeUrl = 'http://www.tumblr.com/' + command + '/' + oauth + '?id=' + id;
$( '#like-it' ).attr( 'src', likeUrl );
$( this ).toggleClass( 'liked' );
} );
{block:Posts}
<article id="{PostID}">
reblog
like
</article>
{/block:Posts}
<iframe id="like-it"></iframe>
#like-it {
display: none;
}
.liked, .like:hover {
color: red !important;
}
It's different now. Just add
#iframe_controls { display:none; }
To the CSS (inside tag of 'Edit HTML').

Categories

Resources