I'm in the midst of creating my first 'real' website and try to add some responsiveness to my layout and navigation: www.dknytkom.dk/forside/
I use alot of addClass and removeClass to menu items as well as toggling corresponding to the width of the browser window. So far so good.
Problem is that my search field disappears upon focus when view on my iPhone. I have a vague suspicion it is to do when my jquery commands that make it go away when the document width is changed. But really I'm at a loss.
Also the toggling of the menu items tends to go awire when clicking on the menu elements even though I conditioned them to wait for the document to load. Any suggestions?
I've tried to create a jsfiddle from where the full code can be inspected:
$(document).ready(function() {
var $introbrowserwidth= $(window).width();
$soeg = $('a.soege-knap');
$mobnav = $('a.mob-nav');
$soegelist = $('div#search-table') ;
$searchtable = $('#search-table') ;
$soegefelt = $('ul.menu-item-holder > #searchfield');
$menuknap = $('li a.menu-knap');
$menu = $('div.menu')
$menulist = $('.menu li')
$emneoversigt = $('#emneoversigt')
$emneoversigtlistitem = $('#emneoversigt li')
$('.mob-nav').css('cursor','pointer');
$temamenu = $('#tema-menu');
if ($introbrowserwidth <=480) {
$soegelist.addClass('displaynone');
$soegefelt.addClass('displaynone');
$('#menudiv').removeClass('displayblock').addClass('displaynone');
$('#menudiv > ul').addClass('background-colour7 zebra');
$('#menudiv a').addClass('displayblock');
}
else{
$menulist.removeClass('listitem').addClass('inlineblock');
$menu.removeClass('displaynone').addClass('displayblock');
$soegefelt.removeClass('displaynone').addClass('inlineblock');
};
$soeg.on("click",function(e) {
e.preventDefault();
$soegelist.toggleClass('displayblock');
$soegefelt.toggleClass('displayblock');
$emneoversigt.removeClass().addClass('displaynone');
$soeg.toggleClass('soege-knap-aktiv');
$('#menudiv').removeClass('displayblock').addClass('displaynone');
$('#menudiv > ul').removeClass('background-colour7 zebra');
$menuknap.removeClass('menu-knap-aktiv');
$('ul.menu-item-holder').toggleClass('expandheight');
});
$menuknap.on("click",function(e) {
e.preventDefault();
var $menutilstand = $(window).width();
$menulist.addClass('padding5');
$menuknap.toggleClass('menu-knap-aktiv');
$soeg.removeClass('soege-knap-aktiv');
$soegelist.removeClass().addClass('displaynone');
$('ul.menu-item-holder').removeClass('height expandheight')
$('#menudiv > ul').addClass('background-colour7 zebra');
if($soeg.hasClass('soege-knap-aktiv')) {
$soeg.removeClass('soege-knap-aktiv');
$('ul.menu-item-holder').removeClass('height expandheight');
};
if ( ($menutilstand <=480) && ($('#menudiv').hasClass('displaynone')) ) {
$('#menudiv').removeClass('displaynone').addClass('displayblock');
$($menulist).removeClass('displayblock').addClass('padding5 listitem');
$soegefelt.removeClass('displayblock');
} else { $('#menudiv').removeClass('displayblock').addClass('displaynone');}
if ($('ul#menu-item-holder').hasClass('expandheight')){
$('ul#menu-item-holder').removeClass('expandheight').addClass('height')
}
});
$('#indexbtn').on("click",function(e) {
$('#emneoversigt').toggleClass('displayblock');
e.preventDefault(); })
$( window ).resize(function()
{
var browserwidth= $(window).width();
$emneoversigt.removeClass('listitem').addClass('displaynone');
$('.menu').removeClass('padding5');
$emneoversigt.removeClass('displayblock').addClass('displaynone');
$menuknap.removeClass('menu-knap-aktiv');
$('*').removeClass('height expandheight')
$('#menudiv > ul').removeClass('background-colour7 zebra');
$soeg.removeClass('soege-knap-aktiv');
if(browserwidth <= 480 ) {
$soegefelt.addClass('displaynone');
$temamenu.addClass('displaynone');
$soegelist.removeClass('inlineblock displayblock').addClass('displaynone');
$menu.addClass('displaynone');
$menulist.removeClass('inlineblock').addClass('listitem');
$('ul.menu-item-holder').removeClass('height');
$menulist.removeClass('listitem displayblock').addClass('displaynone');
$('#menudiv').removeClass('displayblock');
$('ul#menu-item-holder').addClass('height');
}
else { $('li#searchfield').removeClass().addClass('inlineblock');
$soegelist.removeClass('displaynone').addClass('inlineblock');
$menu.addClass('displayblock'); $temamenu.removeClass('displaynone'); $menulist.removeClass('listitem stroke displayblock ').addClass('padding5 inlineblock');
$('ul.menu-item-holder').addClass('height');
}
})
});
This is the div with your search:
<div id="search-table">
<span>
<form id="soege_form" action="<?=$grundsti;?>sider/soegning.php" method="post">
<input name="portal_id" type="hidden" value="<?=$valgt_portal_id;?>" />
<input placeholder="Søg i alle artikler" name="soegeterm" border="none" id="soegeterm" type="text" size="30" maxlength="100" class="loginfelter venstrefloat boxshadow" />
<button id="submit" style="cursor: pointer;" class="sendknap venstrefloat button_bg">Søg</button>
</form>
</span>
</div>
This is where you assign the div to the variable:
$soegelist = $('div#search-table') ;
This line makes it dissapear:
if ($introbrowserwidth <=480) {
$soegelist.addClass('displaynone');
...
Found out that when typing in the input it affected the width of the document and thus activating my js-resize functions.
Strange thing that it only did so on iOS though.
The solution was to add an !$('input:focus').length to the conditions, meaning as long as someone is using any form input the conditions for toggling are not met.
Problem now though is: how to distinguish between wanted and unwanted doc resizing?
Related
I am using this github source code here https://github.com/customd/jquery-visible
I am trying to check if the div labeled "test" is visible to the viewport and add a class to an element.
I've tried this here.
$(window).scroll(function() {
var detectPartial = $('#test').val() == 'partial';
// Is this element visible onscreen?
var visible = $(this).visible( detectPartial );
// Set the visible status into the span.
if(visible) {
$('#test').addClass('active');
}
});
Script Code:
<script type="text/javascript">
$(window).scroll(function() {
if($('#test').visible()){
$('.contact').addClass('active');
$('.home').removeClass('active');
} else {
$('.home').addClass('active');
$('.contact').removeClass('active');
}
});
</script>
HTML Code:
<div class="test" id="test" style="height: 700px"></div>
<li class="main-li">Contact Us</li>
I am trying to check if test is visible to the viewport.
If it is visible then add active class to contact.
This is one way to achieve that result.
$(window).scroll(function() {
if ($('#test').visible()) {
$('#test').addClass('active');
}
});
I'm not sure what you are trying to do with the .val() method, and your $(this) won't have any relation to the #test div the way things are. Can you explain in more detail?
I have a form which uses dynamic styling. Consider this html
<div class="field-name field-form-item">
<label class="placeholder" for="name">Name</label>
<input class="form-input" id="name" type="text" name="name" maxlength="50" size="30">
</div>
The label is ABOVE the input, with CSS. When you click the label :
$('.placeholder').on('click focus', function() {
$(this).addClass('ph-activated');
$(this).siblings('input').focus();
})
Then the label is animated and let the user type in the input.
If the user dont wan't to write anything, the animation goes back, and hide input field :
$('input').on(' blur', function(){
if ($(this).val().length === 0) {
$(this).siblings('label').removeClass('ph-activated');
}
});
That's alright.
But when a user fill the input, THEN refresh the page and its browser didn't reset input fields(ie firefox) : the label is above the input, even if the latter is not empty.
I tried this :
$(document).ready(function() {
if ($('input').val().length) {
$(this).siblings('label').addClass('ph-activated');
}
})
But it doesn't seem to trigger, I tried several ways to write this function. Up to now I never managed to give the class ph-activated to a label with a filled input on page refresh.
Sorry I can't fiddle this. I just have far too much html/css/js/php to copy paste
Well you are targeting wrong element in $(document).ready because you are referring label with this thinking that $(this) is input whereas it is document. So try applying below code and I hope there will be multiple input elements in page, so I've used $.each and looping through all the inputs
$(document).ready(function() {
$('input').each(function(){ //loop through each inputs
if ($(this).val().length) {
$(this).siblings('label').addClass('ph-activated');
}
});
})
DEMO - Inspect the label and you will find ph-activated class added to label
Try this one:
$(document).ready(function() {
var length = $('input').filter(function( index ) {
return ($(this).val() !== '');
}).length;
if (length > 0) {
$(this).siblings('label').addClass('ph-activated');
}
})
I have 5 buttons 'Free call' on my site. On hover on them pops up contact form. I have a number of problems with it:
How to make the form be the only one on the page? I mean, from different buttons must be shown the same form. (For ex. I filled in the form in one place and when I hover other button, I see message 'You're done' or smth like that)
How to make the showing function work only once for every button? (The code below)
I tried to solve this problems but my methods didn't work
HTML
I have 5 such buttons on the page in different places
function showForm() {
var currentButton = $(this);
if ( currentButton.find('.popover-form') !== undefined ) {
var freeCallForm = "<form class=\"popover-form free-call-form\"><label for=\"\">Name</label><input type=\"text\"> <label for=\"\">Phonenum</label><input type=\"text\" value=\"+375\"><button>Call me!</button> </form>";
currentButton.append(freeCallForm);
}
}
$('.main-btn').on('mouseover', showForm);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="main-btn free-call">
<p>Use free call
<br/>
<i class="glyphicon glyphicon-chevron-down"></i>
</div>
This function above unfortunately doesn't work. With if I tried to make function work only when .main-btn hasn't .popover-form.
And other problem is that on hover on different buttons anyway appends NEW form for every button. I can't find correct solution for this problem.
var isOpen = false;
function showForm() {
var currentButton = $(this);
if ( currentButton.find('.popover-form') !== undefined && !isOpen) {
var freeCallForm = "<form class=\"popover-form free-call-form\"><label for=\"\">Name</label><input type=\"text\"> <label for=\"\">Phonenum</label><input type=\"text\" value=\"+375\"><button>Call me!</button> </form>";
isOpen = true;
currentButton.append(freeCallForm);
}
}
$('.main-btn').on('mouseover', showForm);
//on modal close set isOpen back to false
The solution is the append() method. It moves DOM elements, not copies them (I thought so).
So I inserted my <form id="free-call-form"> to the end of the document, before </body>.
JS
function showForm() {
var currentButton = $(this);
if ( ( currentButton.find('.popover-form') !== undefined && !currentButton.existsFreeCall ) ) {
var freeCallForm = $('#free-call-form');
currentButton.append(freeCallForm);
currentButton.existsFreeCall = true;
}
}
$('.main-btn').on('mouseover', showForm);
In this code the same form moves from one to another button without copying and multiple appending.
I have table cell with a javascript/css content box that pops up upon mouseover.
There are 20 cells on the page. Everything is working correctly, in that when you mouseover the product link, you see the content box. However, I want to put a LINK inside the content box that the user can click on if they choose. So, the popup box has to stay up long enough for the user to mouseover to click the link.
Really, I want the OnMouseOver to stay open until either a second or two has gone by and/or the user OnMouseOver's another cell.
The problem I'm having is that the pop up box doesn't stay open (due to OnMouseOut) to click the link. If I turn OnMouseOut off (which I tried), then all the pop up boxes just stay open, so this doesn't do the job either.
My CSS looks like this:
<style type="text/css" title="">
.NameHighlights {position:relative; }
.NameHighlights div {display: none;}
.NameHighlightsHover {position:relative;}
.NameHighlightsHover div {display:block;position:absolute;width: 15em;top:1.3em;*top:20px;left:70px;z-index:1000;}
</style>
And the html:
<td>
<span class="NameHighlights" onMouseOver="javascript:this.className='NameHighlightsHover'" onMouseOut="javascript:this.className='NameHighlights'">
Product 1
<div>
# of Votes: 123<br>
% Liked<br>
<a href="product review link>See User reviews</a>
</div>
</span>
</td>
So, how can I make the pop up box stay open long enough to click on the link, but also make it disappear if another content box is activated?
Thanks in advance.
You have to improve your HTML markup for this task, need to get rid of inline event handlers:
<span class="NameHighlights">
Product 1
<div>
# of Votes: 123<br>
% Liked<br>
See User reviews
</div>
</span>
Then you have to bind your events to all .NameHighlights spans:
var span = document.querySelectorAll('.NameHighlights');
for (var i = span.length; i--;) {
(function () {
var t;
span[i].onmouseover = function () {
hideAll();
clearTimeout(t);
this.className = 'NameHighlightsHover';
};
span[i].onmouseout = function () {
var self = this;
t = setTimeout(function () {
self.className = 'NameHighlights';
}, 300);
};
})();
}
http://jsfiddle.net/3wyHJ/
So the idea is to use setTimeout method.
Notes: I used querySelectorAll which is not supported by IE7, if you need to support it then you can use any of implementations of the getElementsByClassName method.
In case anyone is looking for a jQuery version of the accepted answer:
var t;
$(function(){
$('span.NameHighlights').mouseover(
function(e){
hideAll();
clearTimeout(t);
$(this).attr('class', 'NameHighlightsHover');
}
).mouseout(
function(e){
t = setTimeout(function() {
//$(this).attr('class', 'NameHighlights');
hideAll();
}, 300);
}
);
});
function hideAll() {
$('span.NameHighlightsHover').each(function(index) {
console.log('insde hideAll');
$(this).attr('class', 'NameHighlights');
})
};
jsFiddle
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
input type=file show only button
The has this kind of design:
Can I modify it so it won't show the text field?
a very good guide is found in quirksmode - Styling an input type="file"
quote with some modifications to match question:
Take a normal <input type="file"> and put it in an element with position: relative. or absolute
To this same parent element, add an image or a button, which have the correct styles. Position this element absolutely, so
that they occupy the same place as the <input type="file">.
Set the z-index of the <input type="file"> to 2 so that it lies on top of the styled image or button.
Finally, set the opacity of the <input type="file"> to 0. The <input type="file"> now becomes effectively invisible, and the styled
image or button shines through, but you can still click on the "Browse"
button. (Note that you can't use visibility: hidden, because a truly
invisible element is unclickable, too, and we need the <input
type="file"> to remain clickable)
Suggestion: You can use the uploadify plugin.
Don't see a jQuery tag in your question but hey, it's helpful, and possibly quite easy to rewrite in vanilla JS. This is a little jQuery plugin I extracted from Ideal Forms, a plugin I maintain at github. It covers all the basics to do what you want, with fallback for IE and multiple for HTML5 browsers. Plus handling events and markup replacement. CSS is on your own, but nothing too complicated to style as you can see. You can hide the text field too if you want. The idea here is that this allows for ANY customization possible with CSS.
$.fn.toCustomFile = function () {
return this.each(function () {
var
$file = $(this), // The file input
// Necessary markup
$wrap = $('<div class="wrap">'),
$input = $('<input type="text" class="filename" />'),
$button = $('<button type="button" class="upload">Open</button>')
// Hide by shifting to the left, that way can
// still use events that are otherwise problematic
// if the field is hidden as in "display: none"
$file.css({
position: 'absolute',
left: '-9999px'
})
// Events
$button
.attr('tabIndex', -1) // disable focus on button for better usability
.click(function () {
$file.trigger('click') // Yes, `click`, not `change`. Crossbrowser compat.
})
$file
.attr('tabIndex', -1)
.on({
change: function () {
// Detect if browser supports HTML5 "file multiple"
var multipleSupport = typeof $('input')[0].multiple !== 'undefined',
files = [],
fileArr,
filename
if (multipleSupport) {
fileArr = $file[0].files
for (var i = 0, len = fileArr.length; i < len; i++)
files.push(fileArr[i].name)
filename = files.join(', ')
} else {
filename = $file.val().split('\\').pop() // Remove fakepath
}
$input.val(filename)
// Set filename as title tooltip on
// input field for better usability
$input.attr('title', filename)
},
focus: function () {
$input.trigger('focus')
}
})
$input
.on({
keyup: function () { $file.trigger('change') },
focus: function () { $file.trigger('change') },
blur: function () { $file.trigger('blur') },
// Open files when pressing [ENTER]
// on the input field
keydown: function (e) { if (e.which === 13) $file.trigger('click') }
})
// Append to DOM
$wrap.append($button, $input).insertAfter($file)
})
}
Here's a gist for ease of use: https://gist.github.com/3051209