FREELessons: 13Length: 1.7 hours

• Overview
• Transcript

# 3.4 Creating Working Image Upload Fields

When dealing with image upload fields, we have two options. The first one is to use an input with the type file and write all the upload-related PHP ourselves.

Alternatively, we could use the new fancy image uploader from WordPress that allows us not only to upload an image, but also to select one from the media library.

Let’s go with the second option!

## 3.Creating a More Complex Page5 lessons, 58:33

### 3.4Creating Working Image Upload Fields21:02

When dealing with image uploads, we have two options basically. One is to write all the upload code ourselves. We use an input type file, and then we code the whole upload process ourselves. Or option number two is to use the new fancy image uploader from WordPress. That not only allows us to upload an image, but also choose an existing one from the image gallery. That's pretty cool, right? Let's go with option number two because there's less codes to write. We're using existing components and all the behind the scenes processes are handled by WordPress for us. So, to get started, we're gonna write our code in the upload case here. Now this field will be somewhat different from the others because, one, we're gonna have an image control or an image element to show the image that we're uploading. We're gonna have an input type hidden that's gonna hold the path to the image. We're gonna have an input type button and that's gonna allow us to upload a button. We're gonna have another input type button that's gonna allow us to remove the button. And finally, we'll have a paragraph with the class of description. Let's go ahead and write that. So I'm gonna start with an echo, and we're gonna do img src=. I'm gonna say $field_value, this is the variable that we're setting here. So we're either or getting the value from the database or its default value. Now we're gonna set an alt='Logo'. We're gonna give it a class of ap and inside that echo here. So I'm gonna use single quotes. So 'ap-custom-thumbnail'. We're gonna use some custom CSS to style this. And on top of this, I also need to set a$visibility_class. The $visibility_class will basically hide or show the image if there is any content in it. I'm just gonna say$visibility_class and we're gonna define this in just a little bit. And finally, let's add an id and the id will be equal to, we're gonna get the id of the field -thumbnail. And we're gonna close the image tag. Now, what about this $visibility_class? Well, let's go ahead and define it right here.$visibility_class is gonna be equal to. Well, what we're gonna do is we're gonna check the $field_value. If the$field_value is blank then we're gonna set the $visibility_class to nothing, otherwise we're gonna set it to hide. And this allows us to hide an image when that image doesn't have a source or when the field associated with that image doesn't have a source. So, in here we're gonna say this is different than$field_value. Yeah, then, we're gonna assign blank. Otherwise, we're gonna assign, hide. So if $field_value is not empty, this is what it means.$visibility_class will be equal to nothing which means it will be shown, otherwise it's gonna be set to hide. Let’s also write the input that's gonna hold the $field_value and this is a hidden input. We don't want to show it, it makes really no sense to display the path to that image because we are using the media uploader. So we don't have to. So input type='hidden' name='ap_options', again to be able to save it in the database. We're giving it the id of the field -upload-field. We'll use this in just a little bit, and the value is gonna set to the$field_value. Now we're gonna need two buttons, one for uploading the image and one for removing the image. So, for those, we're gonna write the following code. Input type button both. Then both have the class of button. This is a WordPress class, by the way, so WordPress will style it nicely. And then, two additional classes. These are custom, btn-upload-img and remove-img. On the first one, we're giving it a value of upload logo and we're also setting a data-field-id with the id of my current field. We're gonna use this and just a little bit, it's an HTML5 attribute. We're gonna use it in JavaScript to gain access to this button. The second one, the remove button also has the $visibility_class, because if there is no image, there should be no remove button. value='Remove logo', again with the data-field-id, and we're setting the id to the id of the field /, -remove-button. Finally, we're gonna echo a paragraph with a class='description' and inside we're gonna say$ap_fields $id and we're gonna grab the description. So now, if we do a refresh, you're gonna see that we have these two images where it says Logo here and then two buttons, Upload logo, Remove logo. But we're also seeing this old text here, which means an image is missing. But we shouldn't be seeing that because we did set the class of hide. Well, the problem is we haven't defined the class of hide anywhere in our code. To do that and also to be able to work with JavaScript to write our own custom functions, we need to create an enqueue and a few custom scripts. So let's go ahead and do that right now. We're gonna start in the HOOKS right here where I'm gonna say add_action and we're gonna tap into admin_enqueue_scripts. And we're gonna pass in the function ap, we'll call it options_custom_scripts. Now, we're gonna define that function. Let's see where we should define it, HOOKS, RENDER FUNCTIONS, CUSTOM SCRIPTS. Yeah, this is the place. I have function ap_options_custom_scripts(). And in here, we're gonna register a custom script, a custom style. And we're gonna load these scripts, only if we are on the theme options page. Otherwise, there's no point in doing it. So, first thing we'll do is, we're gonna get information about the current page. We're gonna create a variable$screen = get_current_screen, this is a WordPress function. Next, we're going to register a custom script that depends on jQuery which is available from the WordPress core. To do that, we use the wp_register_script function. We give our script an ID. We're setting the path where we can find the script. In our case, it's going to be inside AP theme options. And we're gonna create a folder here, called js. And inside, a new file called ap-custom-admin-styles.js. You can name these whatever you want basically. But this is the name that I chose. And here is a list of dependencies. In our case, our script only depends on jQuery. Then we're gonna register some custom styles. And for that, we're going to use the wp_register_style function. Again, giving this an ID. And then setting the path to the file. In our case it's gonna be inside a new folder called CSS. And the file is called ap-custom-admin-styles.css. Okay, so now that these scripts are registered, we need to load them. But we're only gonna load them, if we're on the theme options page. For that, we're gonna say, if our page has the ID of appearance_page_ap-theme-options. Yeah, if that's gonna be equal to screen id, then we're gonna say wp_enqueue_media. And this is a function that will enqueue all scripts, styles, settings and templates, necessary to use the media JavaScript APIs. In other words, this will allow us to use that fancy new image uploader. Then we're gonna load the custom scripts. For that, we're gonna use the function wp_enqueue script. And we're gonna pass in the ID of our script, which in my case is this. I'm just gonna copy it from here. And we're gonna load the custom styles, with wp_enqueue_style. And we're gonna pass in the ID of our styles from here, all right. Now let's do our refresh to see if everything is okay, no errors. Let's begin by writing our custom CSS. And this is pretty straightforward. We need a style for hide, to hide Our image or remove button. Here we're just gonna say display none. And we'll do important, just to make sure that we're cutting through any pre-existing styles. And then a style for ap-custom-thumbnail. Now remember, these styles that we're loading right now, only affect the backend or the admin part of WordPress, not the frontend. So ap-custom-thumbnail, let's say we're gonna give it a width, well max-width, actually, of 25%. Height of auto. Remember these styles are applied to images. Maybe a margin bottom. About 18 pixels. We'll give it a border. Also to display block, this sometimes get rid of some unwanted margins. And we'll set a padding of 15 pixels. So now if we do a refresh, you'll see that things are a little bit changed. That image is now gone. Now if we click on the upload logo button, nothing happens. Because we need to write some JavaScript that's gonna trigger the image uploader. That's gonna open, we'll be able to select our files, and then come back and put them in our fields. So we're gonna start in our JavaScript files, where I'm gonna say jQuery. Document ready function. Maybe you are not necessarily used to seeing JavaScript written like this. That's because this is kind of a special way of writing JavaScript, when you're inside WordPress. It's called no-conflict mode. It allows you to use the dollar sign to reference stuff, without generating any errors from WordPress. So we're gonna start by declaring a few variables. One is for the current field ID. So we need to know what button we're clicking. And then one for image_uploader. We're gonna use this to trigger the WordPress media uploader. So now let's see what happens when we click the upload button. We're gonna reference the class of btn-upload-image. And we're gonna say, on click function. And we're gonna pass in an event. The first thing we'll do is say, event.preventDefault to get rid of any default behavior that button might have. And then we'll get the ID of the corresponding field. So if the buttons for the main logo, we need to the the ID of that field. We're gonna say current_field_id is gonna be equal to this. And this refers to the button we just clicked. Data and we'll grab field-id. And it's gonna go to the button. And it's gonna get the value from this data-field-id. Next, we're gonna do a check. If the uploader object already exists, reopen it. We're gonna say if( image_uploader ). Then image_uploader.open and we'll hit return. Now if the image uploader isn't open, we have to create one by extending the WP media object. And the code for that looks something like this. Essentially, we're creating an uploader object. We're assigning it to image uploader. And we're passing in a few parameters like title, the button text and whether or not we can select multiple images. This is set to false because we only want to select a single image, for a logo, right? Now once we create this object, we'll simply open the uploader. We're gonna say image uploader, open. All right, so let's see if this works. We're gonna do a refresh here. We don't have any errors, warnings, anything like that, we hit upload logo and we're greeted with this dialogue here. So I've already prepared a few images here. I can click on either one and click choose image. Or I can upload a new one if I want, either by selecting files or dropping them directly from my computer. But I'm gonna choose this one, hit Choose image. And when I do that, nothing happens. And that's because we have to write some code, that's gonna handle the selection process. So let's go back here. And we're gonna say, after the file is selected, we're gonna get the URL for the file and set it as the hidden fields value. And we're gonna say image_uploader. On select, we have a function. In here we're gonna say attachment equals image uploader.state.getselection.first.twoJSON. So now the attachment will hold information about the image that we just chose. Now from that information we need the URL, that's pretty much it. So we're gonna say this, we're gonna use the current field ID, the one that we populated here on the top plus upload field. So essentially we are targeting this input type hidden. Because it has the ideal of a field dash upload field. Announce if we close this CSS.vel and we're gonna pass in attachment.url. Next we're gonna show the image from mail and the move button because now we have an image. So we're gonna reference the field with the ID of current field ID plus thumbnail that's the image. And we're gonna send the ATTR SRC to attachement.url. Well the first time we're using attachment URL is to set the value in the hidden field that's gonna be safe to the database, and the second time we're using it is that the SRC of our thumbnail preview image. After we do this we'll simply remove the class of height essentially showing the element. We're gonna do something similar for the button, we're gonna say current field_ID-remove button, here we just have to remove the class of hide. All right so, let's see what we have. Let's do a refresh, let's upload a logo, this one here. And now, this one appears as a preview and we also have the ability to remove it. And if we hit the second button, we get the second logo also with the ability to remove it. Now this does not save the value of the logo in the database or the URL of the logo. So if I do a fresh, these values are gone. If I want to save them to the database, I have to upload them. Same for this. And I have to hit save changes. So now, they're going to be saved and they're going to be displayed on page refresh. The final thing to do here is to write the code for the remove logo button. So the remove logo button, remove image button click. We're gonna reference .btn-remove-img on click. We have a function. We're gonna do the same thing. We're preventing the default behavior. And then we're gonna get the ID of the corresponding upload field. It's exactly the same thing that we did here. So I'm just gonna copy and paste this code. And then, first we'll do is we're gonna remove the field value to do that, or reference the field with an ID, current_field_id +, upload field and we're gonna set the value to nothing basically. And then we're gonna hide the current image, copy.net and then we're gonna reference the thumbnail, and we're gonna add, the class of hide. Finally we're gonna hide the button. So we're gonna say this addClass hide. All right, let's give it a try. We're gonna refresh, we're removing the logo, yhat's gone, remove and that's gone as well. Now, again the changes are not yet saved. If I do a refresh the logos are still here, but if I remove these logos, save, they are gone. And then I can upload again, upload them again if I want to. And, it's all gonna work just fine. Well, our theme options page is nearly done. All that's left to do now is add field sanitation and we'll do that in the next lesson.