gtludwig
gtludwig

Reputation: 5611

Thymeleaf + HTML5 - why can't I access my javascripts?

I have an Spring MCV 4 + HTML5 + Thymeleaf based application I can't seem to use javascript on pages.

The webapp structure is:

webapp
    assets
        css
        img
        js
    i18n
        messages.properties
    WEB-INF
        html
            fragments
                common.html
                default.html
                footer.html
                header.html
                login.html // exclusively for ../login.html
                sidebar.html
            home
                welcomeSignedIn.html
            client
                home.html
                create.html

In my login page, since it is a single page, with only a picture in the background, I have a piece of JS that works flawlessly:

<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org">
<head th:include="fragments/login :: loginFragment">
<meta charset="UTF-8" />
<title><th:text="#{app.name}"></label></th:text>
</head>
<body>
<div class="login-container animated fadeInDown">
    <div class="loginbox bg-white">
        <form th:action="@{/login}" method="post">
            <div class="loginbox-title">SIGN IN</div>

            <div class="loginbox-textbox">
                <input type="text" id="ssoId" name="ssoId" class="form-control" placeholder="Username" />
            </div>
            <div class="loginbox-textbox">
                <input type="password" id="password" name="password" class="form-control" placeholder="Password" />
            </div>
            <div class="loginbox-forgot">
                <a href="">Forgot Password?</a>
            </div>
            <div class="loginbox-submit">
                <input type="submit" class="btn btn-primary btn-block" value="Login"/>
            </div>
        </form>
    </div>
</div>

<script type="text/javascript">
    $(function () {
        $('#ssoId').focus();
    });
    </script>
</body>
</html>

Login page has its own fragment, because it's a single, no menus, no sidebar page. All other are.

For may default templating, I have a file called fragments/default.html reponsible for pages organization.

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">

<head th:include="fragments/common :: commonFragment">
<meta charset="UTF-8" />
<title th:text="#{app.name}"> </title>
</head>
<body>
    <div th:id="defaultFragment" th:fragment="defaultFragment">
        <div th:replace="fragments/header :: headerFragment"></div>
            <div class="main-container container-fluid">
                <div class="page-container">
                <div th:replace="fragments/sidebar :: sidebarFragment"></div>
                <div class="page-content">
                    <div class="page-body">
                        <div layout:fragment="content"></div>
                    </div>
                </div>
            </div>
        </div>
        <div th:replace="fragments/footer :: footerFragment"></div>
    </div>
</body>
</html>

So that, for every page, I get included the following links and scripts from fragments/common.html:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head th:id="commonFragment" th:fragment="commonFragment">
    <link rel="icon" th:href="@{/assets/img/favicon.png}" type="image/x-icon" />

    <link rel="stylesheet" th:href="@{/assets/css/bootstrap.min.css}" />
    <link rel="stylesheet" th:href="@{/assets/css/font-awesome.min.css}"/>
    <link rel="stylesheet" th:href="@{/assets/css/beyond.min.css}"/>
    <link rel="stylesheet" th:href="@{/assets/css/demo.min.css}" />
    <link rel="stylesheet" th:href="@{/assets/css/animate.min.css}" />
    <link rel="stylesheet" th:href="@{/assets/css/skins/darkred.min.css}"  />

    <link rel="stylesheet" th:href="@{http://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,400,600,700,300}" />


     <!--Skin Script: Place this script in head to load scripts for skins and rtl support-->
    <script type="text/javascript" src="/assets/js/skins.min.js" th:src="@{/assets/js/skins.min.js}"></script>

    <script type="text/javascript" src="/assets/js/jquery-2.0.3.min.js" th:src="@{/assets/js/jquery-2.0.3.min.js}"></script>
    <script type="text/javascript" src="/assets/js/bootstrap.min.js" th:src="@{/assets/js/bootstrap.min.js}"></script>
    <script type="text/javascript" src="/assets/js/slimscroll/jquery.slimscroll.min.js" th:src="@{/assets/js/slimscroll/jquery.slimscroll.min.js}"></script>
    <script type="text/javascript" src="/assets/js/beyond.js" th:src="@{/assets/js/beyond.js}"></script>
    <script type="text/javascript" src="/assets/js/beyond.min.js" th:src="@{/assets/js/beyond.min.js}"></script>
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
    <div class="container" />
</body>
</html>

My fragments/header.html is defined as:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head th:include="fragments/common :: commonFragment">
</head>
<body>
    <div th:id="headerFragment" th:fragment="headerFragment">
        // content
    </div>
</body>
</html>

fragments/sidebar.html is very similar to `fragments/header.html, just different classes and content.

So, on every page I have on my application, I do something like this:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorator="fragments/default" xmlns:s="http://www.springframework.org/tags">

<head >
<title th:text="#{view.index.title}">Welcome!</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>

<body>
    <div layout:fragment="content">
        // content
    </div>
</body
</html>

I'm sure it's something quite stupid, but I'm failing to see why can't I get javascript working on my pages, even for something quite as simple as:

<script type="javascript" >
    $(function () {
        alert('hello');
    });
</script>

And, what's bothering (a lot!) is that if I on the browser something like:

localhost:8080/appName/assets/js/bootstrap.min.js

It will show the contents of the file.

What am I missing here?

Upvotes: 1

Views: 2713

Answers (2)

gtludwig
gtludwig

Reputation: 5611

Thanks for the input, guys! I got it working. What I did is placing the JavaScript section inside the <div layout:fragment="content">*HERE*</script> area, like on the example bellow.

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorator="fragments/default" xmlns:s="http://www.springframework.org/tags">

<head >
<title th:text="#{view.index.title}">Welcome!</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>

<body>
    <div layout:fragment="content">
        <script type="text/javascript" >
            *JavaScript area*
        </script>
        // content
    </div>
</body
</html>

Hope this will save someone's precious time!

Upvotes: 6

sanluck
sanluck

Reputation: 1554

I think you have problems because there are 2 jquery files included to your fragments/common.html (check it via Firebug or something like that):

<head th:id="commonFragment" th:fragment="commonFragment">
      ...
    <script type="text/javascript" src="/assets/js/jquery-2.0.3.min.js" th:src="@{/assets/js/jquery-2.0.3.min.js}"></script>
      ...
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
</head>

Try to remove one of the definitions.

Upvotes: 1

Related Questions