PDA

View Full Version : jQuery - Spiffing up your page where you can't edit the HTML!


Kyttias
01-29-2014, 05:17 AM
Want to modify page elements not directly part of your template? Need to add a class to something so you slap some CSS on it, but you just can't find where the HTML for that widget is being rendered by Mysidia's GUI php scripts? :catfish:

Take a seat!

This is relatively painless.

1. Decide what you're modifying!
Before we get into writing up our custom jQuery script, let's chose what page element we want to modify. For this example, let's say we want to turn the submit button on the login form blue.

Let's get a good look at what this button looks like by default!

Visit your website (and log out so you can clearly see the login button we're wanting to modify). Anywhere on the page, right-click and view the page's source. In Google Chrome, you can even right-click the element you're wanting to modify, and by selecting 'Inspect Element' at the bottom of the list, it'll take you right where the element is in the source code, or very near by. By default, our dull little button looks like this:
<button id="submit" value="submit" name="submit" type="submit">Log In</button>

As we know, CSS makes the web pretty. If we want to fulfill this button's lifelong dream of being blue, we're going to have to add some CSS.

Okay, but...? :displeased: It's got an id attribute already, you say. You could go into your stylesheet right now and say:
#submit { background-color: blue; };

But that wouldn't make this much of a tutorial, would it? No! We don't want to add css to the id, ids can only be used once. We want to add a class that turns any button with that class blue. We could use it on any button anywhere on the site that we've added this class to! Let's add this amazing class to this button pronto! And once we do that, we can add it to any button we want ever, and we will have spectacular buttons! :OHSHITALION:

2. Let's add to your stylesheet!
Find your template's stylesheet (templates/name of your template/style.css) and open it up. We're going to add two classes. Why two? You'll get to see easily how multiple classes are added later on in our actual scripting. For the sake of this tutorial, here's the css:

.btn-primary {
color: #fff;
background-color: #428bca;
border-color: #357ebd;
}
.btn {
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 14px;
font-weight: normal;
line-height: 1.428571429;
text-align: center;
white-space: nowrap;
vertical-align: middle;
cursor: pointer;
background-image: none;
border: 1px solid transparent;
border-radius: 4px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}

As you can guesstimate from the above, the first class is just adding colors, the second is modifying the shape! With this in mind, you could make multiple classes for multiple colors, and if you find yourself wanting a red cancel button and a green confirm button (or whatever floats your boat).

3. Great, but, just how does this work?
Well, first, you will need add jQuery to your template. (What is jQuery (http://jquery.com/)?)

jQuery is hosted as a file by Google's CDN, freely provided, so all we need to do is link to it. (Optionally, you can go to the jQuery website linked above and download the file yourself, place it somewhere in your stuff, then figure out how to link to it. I prefer using Google's CDN as it's highly likely it's already been cached by your users after viewing any website that also links to it from Google's CDN - and this means faster load times! :jay:)

Now let's go open up your template.tpl file (templates/name of your template/template.tpl). Find where the </body> tag ends. Immediately above it, link to jQuery, like this:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="{$home}{$temp}{$theme}/YOUR_JS.js"></script>

The second script being linked to above is where we're going to work our real magic. Linking your custom script with {$home}{$temp}{$theme} directs it to where Mysidia installed/template/the name of your template/ automatically. So now we're going to make the YOUR_JS.js file right there, in that the same folder as template.tpl. (We're done with the template file now, by the way, so we can close it.)

4. Ok, magic time!!
Now we get to why we're really here. YOUR_JS.js (or whatever you actually decide to name it) can be opened with Notepad, or your preferred editor. (Make sure it gets saved as a .js and not anything else, of course.)

Without going into it, this is what we're putting in here:
$("#submit").addClass("btn btn-primary");

Piece of cake! :meow:

Save everything and let's load up our site again. Now our HTML source code should be rendering this change:
<button id="submit" value="submit" name="submit" type="submit" class="btn btn-primary">Log In</button>

5. Comprehension:
Now, let's get a quick lesson in jQuery 101 so you can kind of grasp what's going on here. jQuery is surprisingly beginner friendly, and it took me a very short time to get so comfortable with it. The basic method syntax is as follows:

$("selector").event(function(){
$("selector").effect("parameters");
});

In our case, only using the line in orange, because we don't have any prerequisites and we want this to happen asynchronously when the page loads. We're selecting the page element with the id of submit. The effect we're performing on the thing we're selecting is the rendering of an additional class, and the parameter is the name of the class. There's no need for the CSS designation (a . because it's a class) in the parameter, even though the selector had it's CSS designation (a # because it's an id) -- parameters are just different in this regard. In this case, the class parameters we're adding are just separated by mere spaces.

For a full list of selectors (http://api.jquery.com/category/selectors/) (page elements and how to designate children of them), events (http://api.jquery.com/category/events/) (on resize, on click, on mouse over, etc), and effects (http://api.jquery.com/category/effects/) (adding and removing parameters, fading in and out, hiding and showing, etc) just check out the official jQuery documentation. If you're interested in learning jQuery, I also recommend W3Schools (http://www.w3schools.com/jquery/default.asp) because it has code examples and tutorials.

Because this was such a small line of code, alternatively, it could have been included anywhere in the page itself, rather than linked as a separate file, like this:
<script>$("#submit").addClass("btn btn-primary");</script>

Best practice is to load jQuery and all other javascript libraries at the end of the page, to save load time.

Hall of Famer
01-29-2014, 11:48 AM
Actually its very easy to add a css class to a GUI component. Assume you have the button object, all you need to do is to add one line of script:


$button->setClass("btn btn-primary");


And its done. Of course since in most of the time the button object is instantiated and added directly to the form container object, you may need to modify 2-3 lines rather than just 1 line. Heres an example, you will need to change this:


$form->add(new Button("Click to Submit", "submit", "submit"));


to the three lines script below:

$submitButton = new Button("Click to Submit", "submit", "submit");
$submitButton->setClass("btn btn-primary");
$form->add($submitButton);


Still, its pretty easy in my eyes. Of course for users who lack php or OOP experience it can be a bit tricky. XD

Hall of Famer
01-29-2014, 11:50 AM
Anyway its a nice tutorial, good job Kyttias. I tried to design the GUI components/containers in a way that all of them have ids to manipulate. If you know how to use javascript, just get them by id and edit to whatever you like.

Kyttias
01-29-2014, 06:09 PM
Thanks~

The sole advantage to doing it my way is having it contained all inside your template folder, without modifying the framework. In case you want to change stuff, it's all in one file. (And yeahhhh your code is super intimidating, but thanks for your post, I understand it a little better! <3 I had found the setClass before and was able to set it.)

I'm not sure how I can get Javascript/jQuery to interact directly with PHP variables in any other way than what I'm doing now. So, what I've got may still be the easiest method for template theme builders to understand? A lot of your stuff does come with set ids and classes, or it's pretty easy to add them in like your post explained. But it became worrisome when I wanted to add classes to children in the menu, and they didn't come with a set id to manipulate (and why would it, ids can only be used once per page, and for that matter, there's no way you can predict when someone wants or needs a class on something), so I had to pin point the exact part of the list I wanted to modify, and add a class to it. The button was a bad example, ahaha...

It'll be a lot easier to pop in a new theme template to see if I like it if I don't have to modify the deep source. It could become a real hassle after a while, needing to back up files, needing to remember and note all personal edits that aren't related to the theme...

My largest reason for using jQuery is so I can change, remove or add classes dynamically. I can set and remove classes with your GUI, but what if I need to add one only while doing something crazy, like:

I only want an element to be visible if the page is smaller than 480 pixels? I would make it visible by adding a css class that set it's visibility. That element would be a div or a picture that says 'surprise' and only while being moused over, a div acting as a tooltip pops up with a promo code, because a class was added to this div that made it visible? (Or worse, you don't want it to appear on a page resize, but only a certain time of day.) --I will write up these snippets as I would do them if I were using jQuery later today as soon as I wake up.--

In comparison, my "I want my button to be blue" looks pretty lame, I know. There are lots of ways of doing just that, so it was a pretty tiny example. I'll try and make more complicated snippets in the future so people can use them!

If you can do my new example somewhere in your GUI, that'd probably be better than including it with the template files. (Because that promo code would only appear when that theme was active.......... unless, that's exactly what the website owner wants to happen, and they utilize multiple layouts as a standard feature!) If I wanted this code to be available via jQuery in any layout, I'd probably want to save the file someplace all themes could have access it (not hard, it just has to be separate than the template files).

At some point, I don't know if there's a quick alternative to jQuery's bigger functions without reinventing the wheel. :mii: But if you can automate it so users don't have to go through so much copy-pasting of code someday, that'd be spiffy. For now, I think I'll keep on using jQuery rather than touching your deep code, just in case I mess something up. I'm familiar with jQuery and there's an advantage to writing tutorials and snippets, right?