While developing the company website at my last job, I was tasked with creating a section on the List With Us page for video testimonials from real estate clients.
Think of YouTube, but with a different design and UI.
This aspect of the website has been a talking point for a few of my past job interviews, so I thought I’d write a post about how I did it.
To the left is the final product.
Essentially, the client videos are stored in an individual container. In this container, you can see the video thumbnail, the clients’ names, if they were buyers or sellers, and what agent they worked with.
It should be noted that clicking on the agent’s name take you to that agent’s profile on the website.
All of the information for the larger display is contained in each of the individual containers. This includes not only the client and agent details, but the video file being used as the HTML video element’s source. Take a look at the HTML of the individual client testimonial containers:
The entire testimonial container is contained in the div with the class testimonial-div. This greater testimonial-div has two children, which are also divs, with the classes testimonial-video and testimonial-info.
- testimonial-video contains the video element for the testimonial. In the video element, we have the video file, as well as a poster, which acts as the video thumbnail. Click here for more HTML5 video element information.
- testimonial-info contains the other pertinent information, including the client, their real estate status (buyers or renters) and the agent (or agents) information including their profile page.
*If you are using a component based library, such as React or Vue.js, you can abstract this logic into individual video components contained in a larger VideosContainer component. You could even go as far as to have the testimonial-video’s and testimonial-info’s be separate components within your video component, depending on preference.
We also have another div which will be populated with the user’s chosen testimonial video and information. This target, if you will, is given the class first-testimonial. See the HTML below:
- first-testimonial-video is going to be where we place our testimonial’s video element. This div’s video element will contain the source file and poster which will be provided by whatever individual testimonial div’s first child (video element) contains.
- first-testimonial-info (you guessed it) is going to be where we place our testimonial’s details. This div’s elements will contain the clients’ names, their real estate status, and what agent they worked with.
This first-testimonial div is essentially a larger testimonial-div. It starts out as nothing (it’s not even visible until the user clicks on a testimonial-div), but provides a larger container for the video (similar to how YouTube’s thumbnails are not, in themselves, the videos, but when clicked lead to the the larger video display).
First, I grab all the necessary elements when the page loads, applying the appropriate event listeners.
It’s a large function, but here is the first part. We grab this which contains all of the testimonial’s data, contained in two children (remember earlier in the post about the testimonial-divs having two children?).
You might remember the scrollTop jQuery animation from my last blog post, which is what’s going on lines 22449–22451. This ensures that when the user selects a testimonial-div the page scrolls back up to the top of the testimonials section of the page.
Lines 22444 through 22446 utilize the ternary operator to determine whether call play() or pause(). If a video is paused, then call play(), otherwise call pause(). So if you a video is being played, execute pause(), and vice versa. This allows the user to click on the first-testimonial container and either pause or play the video.
On line 22453, you can see the conditional checking if the event target tag is an anchor or not. This is to prevent the overall function and just redirect to the agents page. So if you clicked on the agents name (an anchor tag) then don’t execute the rest of the function and just go to the agent’s profile.
The next line is where we start transferring the information from the clicked testimonial div to the-currently empty- master testimonial container. We check the height to ensure that is not currently populated with any cloned node information. If it is not currently populated, then select the specific sections of the first-testimonial div where you want the cloned node information to go and apply styles (display block reveals the div and executes animations).
The second part of this conditional is executed if the height of the first-testimonial div is greater than 10 (you could also do 0, I don’t remember if there was a reason I chose 10 but it doesn’t really matter). If it is greater than 10, this indicates that it already contains another testimonial div’s cloned information. If this is the case then all we want to do is set the innerHTML to an empty string, effectively removing all of the pre-existing cloned node information. Then we add the new information to their specific target nodes, and there’s no need to apply all of the style changes like we did in the first part of the conditional statement. These styles were already applied when we first populated the div with cloned information. If you want to execute the same animations etc. every single time the div is populated as opposed to doing it for the first time (something that I an my supervisors thought was a bit redundant and unnecessary) then you can just execute the same lines in the first part of the conditional again. Why you would want to do that…
…but do what makes you happy. Which brings us to the last part of our video selection interface: closeVideo.
This function is self explanatory in purpose: close the video. So we need change the styles so it is no longer visible. We also remove all of the previously cloned node’s information. We’re returning the first-testimonial div back to it’s empty state #ShellArtIsBack.
And that’s it. To use the interface for yourself check it out here.**
**The site is live at the time this blog was posted. I am not sure when or if it will ever be taken down. I do not work for the company anymore.
While these libraries are good for customizing individual video players I am not sure how effective they are at the selection and listing of videos. You could use these in conjunction with my code to create an effective and robust video listing and selection interface.
For a more dynamic implementation, you can create a database video class that contains video objects. These video objects would consist of references to video files and whatever information you want to be rendered with the video object. Fetch the data, and iterate over the returned collection of objects an render the each object as a testimonial component. This is more efficient if you have a larger collection of videos, as opposed to hard coding the video components.
If you enjoyed the post or need clarification on anything mentioned, let me know in the comments. Feel free to share and leave claps!
HTML video Tag
The Node.cloneNode() method returns a duplicate of the node on which this method was called.
List With Us | Bohemia Realty Group
Bohemia Realty Group has thousands of exclusive uptown properties; our relationships with Upper Manhattan and Bronx…
Video.js: The Player Framework
Brightcove is the main sponsor of the project, employing many of the core members and investing thousands of…
Plyr - A simple, customizable HTML5 Video, Audio, YouTube and Vimeo player
A simple HTML5 media player with custom controls and WebVTT captions.