Ad Selection Panel

Ad Selection Panel

SEEK provides a themeable Ad Selection Panel you can embed within your job posting flow. It displays the SEEK ad products available to the hirer along with their associated prices.

Browser support

The Ad Selection Panel is designed to work with IE 11 and the last two versions of Chrome, Firefox, and Safari.

Step 1: Include the panel

Add the following script tag to the page where you want to insert the Ad Selection Panel:
HTML
Copy
<script
  type="text/javascript"
  src="https://seekcdn.com/hirer/indirect-posting/product-selection-panel/seek.js"
></script>

Step 2: Render the panel

The render method renders an instance of the panel in the specified DOM element.
The render method must be called on page load and whenever the properties of the draftAdvertisement object change. For example, if the hirer selects a new location you must call render to show the updated pricing.

Example JavaScript

JavaScript
Copy
SEEKAdPostingWidget.render(containerNode, options);
  • containerNode – (DOM Node) The DOM element to render the widget into.
  • options – Options for rendering the panel; see options below.

Options

Option property
Type
Description
instanceId
string
optional
A unique identifier for the new instance. This will be passed into callback methods. Should be unique per instance of the panel on the page.
mode
string
Create or Update.
onInitialLoad(event)
() => void
optional
Function to call when panel is loaded.
event (object)
  • instanceId (string | undefined)
  • isVisible (boolean)
    Flag indicating whether the panel is visible.
onChange(event)
() => void
getAuthToken
() => Promise<string>
Function to call to retrieve the browser token to use when calling the SEEK API.
isValidationEnabled
boolean
Flag indicating whether to show an error message when advertisement.typeCode is undefined. This will typically be false until the hirer presses save.
draftAdvertisement
object
The proposed state of the job ad to be posted or updated.
draftAdvertisement.typeCode
string
optional
One of: Classic, StandOut, or Premium.
Update mode only.
draftAdvertisement.hirerJobReference
string
optional
≤50 characters
draftAdvertisement.positionTitle
string
optional
draftAdvertisement.jobCategoryId
string
optional
The identifier for the position’s job category.
e.g. seekAnzPublicTest:jobCategory:seek:27HXTkNXh
draftAdvertisement.positionLocationId
string
optional
The identifier for the position’s location.
advertisement
object
optional
The current state of the posted job ad.
Update mode only.
advertisement.id
string
optional
The position profile ID of the job ad.
If this is provided, the other advertisement properties will be loaded automatically.
advertisement.typeCode
string
optional
One of: Classic, StandOut, or Premium.
advertisement.hirerJobReference
string
optional
≤50 characters
advertisement.positionTitle
string
optional
advertisement.jobCategoryId
string
optional
The identifier for the position’s job category.
e.g. seekAnzPublicTest:jobCategory:seek:2PiXemmou
advertisement.positionLocationId
string
optional
The identifier for the position’s location.
theme
object
optional
Options for configuring the look of the panel.
theme.selectionColor
string
default: #e60278
The colour to set the product border and description to when a product is selected.
theme.linkColor
string
Defaults to selectionColor
The colour to set links and popup triggers to.
theme.contractBarPrimaryBackgroundColor
string
default: #e60278
The colour to set the contract bar background to when a contract can be used to purchase a product non flexibly. For example, using a “Classic Pack” to purchase a Classic job ad. The foreground colour is always white.
theme.contractBarSecondaryBackgroundColor
string
default: #fceff5
The colour to set the contract bar background to when a contract can be used to purchase a product flexibly. For example, using a “Classic Pack” to purchase a StandOut job ad. The foreground colour is always set to the contractBarPrimaryBackgroundColor value.
theme.cautionColor
string
default: #b38800
The colour to set the product message to when the product has a cautionary message for the hirer.
theme.errorColor
string
default: #ff0000
The colour to set the product list border to when isValidationEnabled is set to true and a product hasn’t been selected.
disableCSSOMInjection
boolean
default: false
Disable CSS Object Model injection. Reduces render performance. This may need to be used if the panel is rendering unstyled. See Troubleshooting.

Sample code

JavaScript
Copy
SEEKAdPostingWidget.render(document.getElementById('seekWidget1ContainerDiv'), {
  // Unique identifier for the instance.
  instanceId: 'widget1',

  // Mode should be `Create` while posting a new job ad
  // or `Update` while updating a job ad.
  mode: 'Create',

  // Function to call when panel is loaded.
  onInitialLoad: function (event) {
    const { instanceId, isVisible } = event;
    if (isVisible) {
      console.log(`Widget ${instanceId} loaded`);
      // -> Widget widget1 loaded
    }
  },

  // `onChange` will be called each time a hirer selects an ad product.
  // See "Step 4" for more details.
  onChange: function (event) {
    const { advertisement } = event;

    // `typeCode` should be persisted in memory to be used
    //  for position posting mutations.
    const { typeCode, features } = advertisement;

    console.log(`The hirer selected the ${typeCode} ad product`);
    // -> The hirer selected the Premium ad product

    // Your software should use "features" to conditionally display bullet
    // points and branding inputs based on the selected ad product.
    const { brandingIndicator, searchBulletPointsIndicator } = features;

    if (brandingIndicator) {
      // Show brand selector
    } else {
      // Hide brand selector
    }

    if (searchBulletPointsIndicator) {
      // Show fields to enter bullet points
    } else {
      // Hide bullet point fields
    }
  },

  // Function to call to retrieve the browser token to use
  // when calling the SEEK API, see "Step 3" for more details.
  getAuthToken: function () {
    return Promise.resolve('browser token');
  },

  // `draftAdvertisement` should contain all of the hirer’s
  // current inputs if they are posting or updating.
  draftAdvertisement: {
    positionTitle: 'Developer',
    jobCategoryId: 'seekAnzPublicTest:jobCategory:seek:2EFstqFvP',
    positionLocationId: 'seekAnzPublicTest:location:seek:2TCFhBtw9',
    hirerJobReference: 'Premium521',
  },

  // `advertisement` specifies the current state of the job ad in update mode.
  //
  // Typically you would only specify the `id` of the live job ad.
  // Alternatively, you can provide the job ad's fields if you don't have the
  // position profile ID.
  advertisement: {
    // Position profile ID
    id: 'seekAnzPublicTest:positionProfile:jobAd:27cuZeA47',
  },

  // Specify a `theme` to style your ad selection
  // panel with your own colours.
  theme: {
    selectionColor: '#e60278',
    linkColor: '#e60278',
    contractBarPrimaryBackgroundColor: '#e60278',
    contractBarSecondaryBackgroundColor: '#fceff5',
    cautionColor: '#b38800',
    errorColor: '#ff0000',
  },
});

Step 3: Handle browser token requests

  1. The panel loads and executes the getAuthToken function passed to it.
  2. Your frontend requests a browser token with the query:ad-products query:organizations scope from your backend.
  3. Your backend requests a browser token from the SEEK API and returns it.
  4. Your frontend returns the browser token from the getAuthToken function.
  5. The panel can now make requests to the GraphQL endpoint.
HTTP
Copy
POST https://graphql.seek.com/auth/token HTTP/1.1
Authorization: Bearer PARTNER_TOKEN_HERE
Content-Type: application/json
User-Agent: YourPartnerService/1.2.3

{
  "hirerId": "seekAnzPublicTest:organization:seek:93WyyF1h",
  "scope": "query:ad-products query:organizations",
  "userId": "317665"
}

Step 4: Handle ad product selection

When a hirer selects an ad product, the onChange function you provided within your options will be called with the below event structure.
The advertisement.typeCode property should be persisted in memory to be used when posting the job ad.

onChange event

Option property
Type
Description
instanceId
string | undefined
The unique identifier initially passed in via options.
advertiserId
string
The ID of the hirer that has selected an ad product.
advertisement.id
string | undefined
The position profile ID of the job ad.
advertisement.hirerJobReference
string | undefined
advertisement.typeCode
The ad product type code selected by the hirer. This should be persisted in memory and used for position posting mutations.
advertisement.jobCategoryId
string | undefined
The identifier for the position’s job category.
advertisement.positionLocationId
string | undefined
The identifier for the position’s location.
advertisement.positionTitle
string | undefined
advertisement.price
integer
The price of the ad product in the minor currency unit. For example, this is the number of cents in dollar-denominated currencies, e.g 26989 would be returned for $269.89 AUD.
advertisement.priceDescription
string
Descriptive summary of the product price, e.g A$269.89 will be deducted from your SEEK contract or A$319.39 + GST. The currency is based on the hirer’s location as well as if they have a contract.
advertisement.paymentDueExcludingTax
The amount left to be paid after contract deductions. This is an object with both currency and value properties.
advertisement.features

Supporting features

Ad products have features that dynamically impact your software’s job posting flow. The available features are passed to your onChange handler when an ad product is selected:
Previously these features needed to be inferred from the advertisement.typeCode property. This may not work in the future when the set of typeCode values change.

Step 5: Posting the job ad

When the hirer is ready to post or update the job ad, advertisement.typeCode persisted above should be passed into the CreatePostingInstructionInput.seekAnzAdvertisementType field in the postPosition , postPositionProfileForOpening or updatePostedPositionProfile job posting mutations.
When a hirer submits the form in your software, you will need to toggle isValidationEnabled to true within options to flag to the panel to display a validation error border around the panel if an ad product has not yet been selected.
The validation error border can be styled using the theme.errorColor property within options.

Forward compatibility

The set of possible advertisement.typeCode values may change in the future. Your software should not have conditional business logic based on the advertisement.typeCode property.

Error handling

Fallback

There are errors that can prevent the panel from being shown to hirers. When they occur, you must show a fallback field that allows a hirer to select an advertisement type.
HTML
Copy
<label for="seek-advertisement-type">Ad type</label>
<select id="seek-advertisement-type">
  <option value="">Please choose an option</option>
  <option>Classic</option>
  <option>StandOut</option>
  <option>Premium</option>
</select>
The advertisement type must be selected by the hirer. It must not be defaulted.
You should also show a message informing the hirer that there was an error loading pricing and that they should contact SEEK for pricing.
You could hide the fallback field after onInitialLoad is called with isVisible set to true or you could start by not showing anything and only show the fallback field when an error occurs or if the widget fails to load within a set time frame.

Script doesn’t load properly

If for some reason the hirer’s browser fails to load the script, calling the render method will fail because SEEKAdPostingWidget will be undefined. To handle this, it’s recommended to wrap the call to the render method in a try/catch block.
JavaScript
Copy
try {
  SEEKAdPostingWidget.render(
    document.getElementById('seekWidget1ContainerDiv'),
    options,
  );
} catch (e) {
  // Show fallback field if not already visible
}

Panel fails to call onInitialLoad function

When the panel is unable to retrieve prices from the SEEK API, it may fail to call the onInitialLoad function or it may call onInitialLoad with isVisible set to false.
This can be handled 2 different ways:
  1. You could start by showing the fallback field and hide it once onInitialLoad is called with isVisible set to true.
    JavaScript
    Copy
    try {
      const options = {
        onInitialLoad: (event) => {
          if (event.isVisible) {
            // Hide fallback
          }
        },
      };
      SEEKAdPostingWidget.render(container, options);
    } catch (e) {}
  2. You could set a timer and show the fallback field after a set time frame has elapsed and the widget container doesn’t have any children:
    JavaScript
    Copy
    try {
      const container = document.getElementById('seekWidget1ContainerDiv');
      SEEKAdPostingWidget.render(container, options);
    
    
      setTimeout(function () {
        if (container.children.length === 0) {
          // Show fallback field
        }
      }, 4000);
    } catch (e) {
      // Show fallback field
    }

Troubleshooting

The panel is unstyled

If the panel renders without a stylesheet and looks unstyled, there may be an incompatibility between your software’s front-end framework and the panel’s use of the CSS Object Model .
If this is the case you can set disableCSSOMInjection to true within your panel options.
Please note: disabling CSS Object Model injection reduces rendering performance as it switches to a slower text node-based CSS injection system for adding styles to the DOM.