ScottD ScottD - 4 months ago 8
PHP Question

Javascript to get screen width in PHP variable

I have a responsive site that has a simple drop-down login menu when the site is in a "desktop" view (screen available width > 768) next to other navigational links. When the screen width drops below 768 the navigational links end up in a select option. The problem is that the drop-down login menu doesn't work from within a select option.

I would like to use PHP to change the drop-down login menu to a simple

<a href>
link when the screen width gets smaller than 768.

Right now I have in my page
<head>
:

<?
$screenWidth = '<script type="text/javascript">document.write(screen.availWidth);</script>';
?>


In the
<body>
:

<?
if($screenWidth <= "768") {
echo '<li><a href="login.php">Log in</a></li>';
} else {
?>
<div id="fancy">
<li id="login">
<a id="login-trigger" href="#">Log in <span>&#x25BC;</span></a>
<div id="login-content">
<form>
<fieldset id="inputs">
<input id="username" type="email" name="Email" placeholder="Your email address" required>
<input id="password" type="password" name="Password" placeholder="Password" required>
</fieldset>
<fieldset id="actions">
<input type="submit" id="submit" value="Log in">
<label><input type="checkbox" checked="checked"> Keep me signed in</label>
</fieldset>
</form>
</div>
</li>
<? } ?>


On my desktop, I have echoed the $screenWidth, which gives 1920. Therefore I would expect the "fancy" drop-down login menu to be displayed. (And it does).

On my mobile, the $screenWidth echo gives 320. I would then expect the
<a href>
link to be displayed. (It does not - instead it displays the "fancy" menu).

It seems odd that the variable when echoed in the body will give a different number, but when compared in the if statement it does not change the output.

Is there a better way of changing the output?

Edit: jquery responsive menu code

jquery.responsivemenu.js:

(function($) {
$.fn.responsiveMenu = function(options) {
var defaults = {autoArrows: false}
var options = $.extend(defaults, options);
return this.each(function() {
var $this = $(this);
var $window = $(window);
var setClass = function() {
if ($window.width() > 768) {$this.addClass('dropdown').removeClass('accordion').find('li:has(ul)').removeClass('accorChild');}
else {$this.addClass('accordion').find('li:has(ul)').addClass('accorChild').parent().removeClass('dropdown');}
}
$window.resize(function() {
setClass();
$this.find('ul').css('display', 'none');
});
setClass();
$this
.addClass('responsive-menu')
.find('li.current a')
.live('click', function(e) {
var $a = $(this);
var container = $a.next('ul,div');
if ($this.hasClass('accordion') && container.length > 0) {
container.slideToggle();
return false;
}
})
.stop()
.siblings('ul').parent('li').addClass('hasChild');
if (options.autoArrows) {
$('.hasChild > a', $this)
.find('strong').append('<span class="arrow">&nbsp;</span>');
}
});
}
})(jQuery);

Answer

Your simplest option might be to populate both options in the DOM, then use CSS3 Media queries to hide/show the proper element based on screen size.

So your HTML might look like:

          <li class="login-link"><a href="login.php">Log in</a></li>
          <div id="fancy">
          <li id="login">
            <a id="login-trigger" href="#">Log in <span>&#x25BC;</span></a>
            <div id="login-content">
                <form>
                    <fieldset id="inputs">
                        <input id="username" type="email" name="Email" placeholder="Your email address" required>   
                        <input id="password" type="password" name="Password" placeholder="Password" required>
                    </fieldset>
                    <fieldset id="actions">
                        <input type="submit" id="submit" value="Log in">
                        <label><input type="checkbox" checked="checked"> Keep me signed in</label>
                    </fieldset>
                </form>
            </div>                     
        </li>

And your CSS could look like:

.login-link, #login{
    display: none;
}
@media screen and (max-width: 767px){
    .login-link {
         display: block;
    }
    #login{
         display: none;
    }
}
@media screen and (min-width: 768px) {
    #login{
         display: block;
    }
    .login-link{
         display: none;
    }
}

Edit: Fixed #login reference. Edit 2: Adding JSFiddle Example JSFiddle Example