Positioning div via Javascript

I have a template where I need different page header informations (for multiple daughter companies) depending on a datamapper field that I try to use with a Javascript condition:

// top left position: top: -340.167px; left: -37.8px;
// BuyErn div:        top: -337.01px; left: 772.933px;
// Euroshopping div:  top: 20.9833px; left: 773.933px;

query("#header_BE").css("top","-337.01px");
query("#header_BE").css("left","772.933");

query("#hearder_ES").css("top","20.9833px");
query("#hearder_ES").css("left","773.93");

if (record.fields.VertriebswegBezeichnung == "Ern International bvba") {
  query("#header_BE").css("top","-340.167px");
  query("#header_BE").css("left","-37.8px");
  
  //query("#header_BE").css("visibility", "visible");
  //query("#hearder_ES").css("visibility", "hidden");
  //header_BE
}

if (record.fields.VertriebswegBezeichnung == "Euroshopping Deutschland") {
  query("#hearder_ES").css("top","-340.167px");
  query("#hearder_ES").css("left","-37.8");

  //query("#hearder_ES").css("visibility", "visible");
  //query("#header_BE").css("visibility", "hidden");
  //header_ES
}

The divs are positioned outside of the page and should be moved onto the page depending on the field and condition.

But setting the div’s position via query().css() does not work, even if it should.

From what I see this is because offset-x and offset-y in the source code at the div overwrite the CSS property. If I delete offset-x and offset-y they are almost immediately recreated by Designer. As far as I can see I cannot target them with a query().css() because offset-x and offset-y are nonstandard html attributes.

How do I get rid of offset-x and offset-y or how can I target them in Javascript to change their values instead of changing top and left?

As you can see from my test code I experimented with visibility of the divs and that basically works, but then all divs would overlay each other which is very unergonomic to maintain, since all divs contents are show over each other (and then you can no longer select them by clicking).

TIA.

regards,
Xanathon

Wouldn’t it be much easier to have each different header being on a Masterpage and trigger them for each daughter companies?

I see no option on master pages to use them according to Javascript conditions. If that is not possible IMHO it makes no difference if I include multiple headers on a content page (section) or on the same master page?

I would use a single box on the master page (as the info needs to be on every page) and use a script to change the contents of the box rather than showing/hiding boxes. This makes it easier to maintain (extend) in the long run. The information could be taken from a snippet.

You can view the technique of reading info from a snippet in the Bundle Offer letter sample which you can download from the Welcome Screen (Welcome > New > Print > Bundle Offer letter)

We have also a how to on this approach, see:

Erik

The info only needs to be on the first (single) master page, not on all master pages.

Since the headers are vastly different from each other with multiple completely different positioned data and logos it would be way too cumbersome to create lots of single content boxes and tables and juggle them using Javascript. In my opinion the only way to do this without too much effort and without making it unmaintainable is to create multiple divs including all the correctly positioned content elements and show them depending on a condition.

An additional problem is that I cannot see how a snippet exactly looks in the designer pane. That makes it hard to maintain in the future and makes it hard to design pixel perfect in the Designer pane (which is something required by management). If I copy one of the complete header divs html into a snippet, the snippet preview in the Design tab is empty.

The way from the tutorial may work with something simple as an address, but I do not think this is feasible for more complex designs with fields, logos and nested tables for example.

In that case I would set two class names for each box. One class to identify the company and a second is a shared class, something like companybox. In your script you can first hide all items with the companybox class and subsequently show the box of the specific company.

In the following example I simply used “box” and “boxa”,“boxb”,“boxc”

Subsequently create a script that hides all boxes with the class “box” and add some logic to show box based on the data field. I used the “each matched element” mode so I don’t need to write a for loop.

The merge result:

I’m sorry, but that will not work, since elements are not neatly apart from each other as in your example, but overlap and in the Designer working tab all that overlapping is shown, so you can no longer work on specific elements, it looks very messy and is not maintanable. Setting the visibility via Javascript only works in the preview tab.

Also I need all elements (adresses, customer data, order data, logos, return adresses, contact information and so on) handled by one surrounding div or this becomes VERY cumbersom if I have to address all these header elements singlehandedly by Javascript conditions.

I am still convinced a header div containing all elements for that company that can be shown or hidden is the best solution. I would simply hide and show the complete div at the position in the page, that works fine, but in the design tab all the elements overlap and create a big mess. In the preview tab everything is fine, but because of the design tab problems (showing everything overlapping) this is not maintainable at all. That’s why I want to move the position of the header divs outside of the page as long as they are not needed.

Is really not possible to change a div’s position using Javascript? Changing div position is minimal standard Javascript stuff …

Basically I have this problem solved completely already, the only answer I need is how to change divs positions via Javascript.

As a sidenote: the offset-x and offset-y attributes are in pixels, not in mm.

The explanation I received for why Connect uses the x-offset and y-offset attributes, rather than CSS, is to better support dynamic pagination. That’s why you can’t eliminate them, it would break other fundamental features of Connect.

What I’ve done in similar situations (where I have overlapping elements, making it hard to select/edit in Design mode), is 1) give each element a unique ID and select what I want to edit via the Outline view and just live with it 2) edit in Preview, again, just living with the overlap in Design view 3) use snippets for my variable content and load the appropriate snippet for the document 4) generate my content in the data mapper and just have a single DIV that displays that content.

@TGREER you are correct, we use custom attributes to have coordinates relative to the page (these sit outside the main text flow).

Having a ‘layer’ option would make things easier to manage. I’ll put that on our backlog [internal ref SHARED-90507]

@TGREER thank you for your insights and suggestions, but unfortunately none of them are applicable to my problem.

I find it especially frustrating that Objectif Lune advertises a WYSIWYG-Editor and then simple things like multiple different headers lead to a big mess of overlapping content that is a visual catastrophy and highly unmaintainable so you are forced to use the source editor.

“Edit in Preview” is not an option, since the Objectif Lune trainer running our training strongly advised against doing that, because it would lead to all kinds of problems, iirc the explanation was that the preview pane only is for preview and not for editing. Can please someone from Objectif Lune chime in and confirm or disprove that? Working in the preview tab would at least be a workaround.

Also I cannot understand why snippet content is not shown in the preview window so I cannot see how it looks. If I create a snippet for every header version (by converting the whole header div into a snippet) I just have to guess how it looks. How is this maintainable?

The snippets do not behave as expected. If I paste the div into a snippet and click the “design” tab,

<p>
    <br>
</p>

is automatically added to the snippet without me wanting that. Also there is no Preview tab for snippets, so I am not able to change them later visually which makes them unmaintainable.

I understand the frustration. Designing a GUI that allows multiple “content areas” that overlap position is a challenge, and Connect improves with each version. That’s my apologia, for what it’s worth.

There was a bug in one of the earlier versions of Connect that wiped out all your varaible data if you Saved while in Preview mode. But that’s been corrected, and I find no issues when I edit in Preview, then toggle back to Design and Save.

My favorite solution, though, is to move the logic out of the template and into the data map. The template will have a DIV and a field from the data model. In the data map, I compute the value of that field with Javascript, as complex as needed, to put the HTML the template “wants” into that field. I set the Type to “HTML” and in the Template, make sure that the “Insert Method” (under “Options” when you right-click and Edit the script for that field) is also set to HTML.

Happy to chime in! As nicely explained by @TGREER, we received reports in the past of data ending up in the Design/Source mode. When we are made aware of these issues, we make every effort to address and resolve them in a subsequent release. We always consider improvement requests and discuss them within the team.

Snippets might not be the best approach for your scenario but without having more details I’m a bit in the blind. After reviewing earlier comments, I created the following template-based samples to illustrate some of the techniques.

The sample data used: brands.OL-datamapper (3.0 KB)

I often work with my snippet editor open next to the main editor (drag the tab to the right hand side of the editor till a vertical separator line appears). Changes made to the editor are automatically updated in the main editor. This technique also works with the source code-based editors like Handlebars snippets and CSS files. In the future I hope we can provide the same for the Design and Preview mode of the main editor.

I hope the examples help you move forward with your project.

Erik

The snippet editor with the various brand boxes.

The brands Handlebars snippet opened next to the main editor.

1 Like

Thank you, I will look into those option.

@Erik Thanks again, “Moving Boxes” does exactly what I want to do, but the other examples also will come in handy in the future.

1 Like

After looking into the examples, I finally understand parts of my confusion.

If I doubleclick a html-snippet, a new tab opens, that has two subtabs, Source and Design. But the “Design” tab actually is a “Preview” tab, this behaviour is different from the main center view with it’s Source, Design and Preview tabs.

@Erik After evaluating all this I just wanted to ask if I really do understand this right:

If I want to work with html snippets or handlebars, I need an additional external html-editor tool to get proper WYSIWYG? Is this really the case?

The Design tab displays the unmerged state, while the Preview tab shows the merged state where the template is combined with data. Snippets, on the other hand, don’t have a separate merged view; they are inserted into the section where the complete design is viewed in Preview mode.

HTML snippets and Handlebars snippets are typically modifed in the application and their merged state is viewed in Preview mode the main editor. HTML snippets could live in a CMS and fetched via an API. In that case the content is edited in the CMS where the template consumes the content. You could for example fetch posts from a WordPress website and use that as content in your OL Connect template.