Bigger screens and "list" + "card" on the same page

I am looking for a solution not using iFrames to show a “card” when selecting a row in a list. Is this possible?

  1. AJAX gives only data - no HTML
  2. Storing all contents in the table gives data - no HTML
  3. iFrame gives you both data and HTML and you can do a simple database lookup from an id

http://94.237.92.101:6060/newposts (note that you need a bigger screen 1800px+)

HTML

<tr data-id={{.post_id}}>
<iframe id="subwin" src=""></iframe>
<script>const url = 'c_post?id=';</script>

Javascript

const selected = table.getElementsByClassName('selected')
table.onclick = sel;
function sel(row) {
  if (row.target.parentNode.dataset.id > 0) {
    if (selected[0]) selected[0].className = '';
    row.target.parentNode.className = 'selected';
    const el = document.querySelector('selected');
    document.getElementById('subwin').src = (url + row.target.parentNode.dataset.id);
  }
}

Websockets may be a solution, but it seems to be overkill. Or?

Yes of course it is possible. I am not sure what your bullet points actually mean however.

  1. Of course AJAX gives you data, but that data could include HTML if you wanted. Even if you want to keep HTML out of it (which would be a good idea) you can take the data returned and append, change or even create your cards on screen.

  2. This too would be very much like the AJAX solution except you would have all the data loaded at the same time. Not very scalable if the number of list items or card data is large. The one benefit here is that you could cache the data after fetching it and would then not need to make multiple AJAX requests.

  3. Not sure why you are mentioning iFrames when you specifically say you don’t want iFrames. Either way, given the first two points I really don’t think you need iFrames here. iFrame use is very rare I find these days. It is much easier to do AJAX and then display on page using your JavaScript.

Did you have a more specific question about these options or are you looking for an opinion on which way to go? Personally I think option 1 is the way to go if you have a ton of list items. Option 2 if the items are small and you want it to be really responsive by using a local cached copy of the card data.

Let us know what you are looking to do. :slight_smile:

Thank you for your input.

The rendered data + html is loaded by the web server (Go) so I need to fetch the html together with the data. I do not know anything about AJAX, and how to incorporate the data with the html. Any clue is welcome.

  1. This too would be very much like the AJAX solution except you would have all the data loaded at the same time. Not very scalable if the number of list items or card data is large. The one benefit here is that you could cache the data after fetching it and would then not need to make multiple AJAX requests.

Loading all data into a table can be expensive. As the SQL query can be massive and I guess that building the table as well. And the problem is the same as with AJAX. How do i pour the data into the html?

  1. Not sure why you are mentioning iFrames when you specifically say you don’t want iFrames. Either way, given the first two points I really don’t think you need iFrames here. iFrame use is very rare I find these days. It is much easier to do AJAX and then display on page using your JavaScript.

I did not say I don’t want iframes. I just want to know if there is other options or if iframes is the best option.

Did you have a more specific question about these options or are you looking for an opinion on which way to go? Personally I think option 1 is the way to go if you have a ton of list items. Option 2 if the items are small and you want it to be really responsive by using a local cached copy of the card data.

Yes, I am looking for opinions. And feedback. And how others do solve this?
What is the pros and cons with iframes? Any clue that can make this faster, simpler and safer.

Looks like you wanted a solution not using iFrames to me. :wink:

Ok well, not sure how the size of the query matters… but if the data coming back is going to be a lot, then ok rule out option 2.

It sounds like AJAX would be the best option for you here. However, you say you don’t know anything about AJAX. So it looks like a great little project to learn on and do it! AJAX these days is not that hard given the development of libraries and APIs.

Great place to start! If you are using jQuery, you can try the jQuery AJAX article there otherwise you can try the article labeled “A Guide to Vanilla Ajax Without jQuery”.

Either way, I think you have some solutions there to play with. I hope it helps. :slight_smile:

Go is compiled to a single executable server side file that outputs a HTML stream of text. This text is then parsed and rendered in a browser. The html output can be validated:

https://validator.w3.org/nu/?doc=http%3A%2F%2F94.237.92.101%3A6060%2Fnewposts&showsource=yes

I think the simplest solution would be to use CSS by including all “cards” inside a hidden block. display:none;

I’m not sure of the CSS script to reveal the hidden “card” it is something like using a CSS Accordion:

https://www.w3schools.com/w3css/w3css_accordions.asp

Thank you! I will give it a try. But how to get the data inside the html is a complete mystery to me.

To hide and show the card is no problem. The problem is that the card does not even exists when the main window is rendered. The card must be “produced” and rendered “on-the-fly” and injected into the existing main window. My example shows that iframe works, but I was asking if there was other options.

Can you elaborate on how the “card” data is found.

If the “card” data i coming from a database table then I cannot see why the “card” details are not found before displaying the list.

Edit:

I do something similar by using a JavaScript AJAX Search that calls a PHP file that accepts the search parameters, passes the parameters to a MySql database query, retrieves the results that are passed back to the browser to be rendered:

https://dasabookcafe.tk

Here is how to create the mainwindow with an empty iframe.
<iframe id="subwin" src=""></iframe>

  1. “components” or sub templates like {{template "filter"}}
  2. Pure HTML
  3. Data “fields” included data {{.data field}} fetched from Postgresql via an API

The main template http://94.237.92.101:6060/newposts looks like this:

  <body>
    {{template "header"}}
    <main>
      <nav>
        {{template "mainnav"}}
        {{template "subtopics"}}
      </nav>
      <div class="content">
        <h1>Posts</h1>
        <div class="line"></div>
        <div class="listcard">
          <div class="boxtable">
            {{template "filter"}}
            <table>
              <thead>
                <tr>
                  <th>ID</th>
                  <th>Subject</th>
                </tr>
              </thead>
              <tbody>
                {{range.}}
                <tr data-id={{.post_id}}>
                  <td>{{.post_id }}</td>
                  <td>{{.post_subject }}</td>
                </tr>
                {{ end }}
              </tbody>
              <tfoot>
                <tr>
                  <th>---</th>
                  <th>Table Footer</th>
                </tr>
              </tfoot>
            </table>
          </div>
          <div class="boxcard">
            <iframe id="subwin" src=""></iframe>
          </div>
        </div>
      </div>
    </main>
    <script>const url = 'c_post?id=';</script>
  </body>

</html>

Basically this is the javascript that populates the iframe by calling the Go web server.

const selected = table.getElementsByClassName('selected')

table.onclick = sel;

function sel(row) {
  if (row.target.parentNode.dataset.id > 0) {
    if (selected[0]) selected[0].className = '';
    row.target.parentNode.className = 'selected';
    const el = document.querySelector('selected');
    document.getElementById('subwin').src = (url + row.target.parentNode.dataset.id);
  }
}

A long answer to a short question :slight_smile:

1 Like

Excuse me, but AJAX is completely new to me but I found some code points in the right direction:

https://jsfiddle.net/4831s6u0/2/

But the formatting disappear. The same using iframe

https://jsfiddle.net/uwyhvz53/

Why?

1 Like

This demo may be useful:

https://johns-jokes.com/downloads/sp-e/jb-ajax-search/pdo/

I created 3 websites in order to figure out speed and simplicity. The table is fetching 5.000 records to enhance the differences. The live sites still require a bigger screen.

#1 Pure Go SSR
The webserver gets the API requests for both list and card. No AJAX involved. The card is filled in as an <iframe> src="url"</iframe>

live: http://94.237.92.101:6060/posts

#2 Prerendered Go page with AJAX data CSR
The webserver gets the API requests for both list and card via AJAX. The card is filled in as innerHTML

function posts() {
  alert("onload...")
  var url = "http://94.237.92.101:6061/posts";
  var xhr = new XMLHttpRequest();
  xhr.open("GET", url, true);

  xhr.setRequestHeader("Accept", "application/json");

  xhr.onload = function() {
    if (xhr.readyState === 4) {
      let posts = JSON.parse(this.responseText)
      var output = ""
      for (var i in posts) {
        output +=
          "<tr data-id=" + posts[i].post_id + ">" +
          "<td>" + posts[i].post_id + "</td>" +
          "<td>" + posts[i].post_subject + "</td>" +
          "<tr>"
      }
      document.getElementById("tbody").innerHTML = output
    }
  }
  xhr.send();
}

live: http://94.237.92.101:6063/posts

#3 Go for the list SSR + AJAX for the card
The webserver gets the API requests for the list (table). And the card is filled by innerHTML by an AJAX call.

live: http://94.237.92.101:6062/posts

The questions:

  1. Which one do you prefer as best UI? Speed, delay, flickering etc?
  2. Why does the sort and filter not work using AJAX?
  3. Are there any better ways to do this?

I think that the data should be searched and only return about a dozen items and I prefer using:

CSS Accordion Demo

Source:

<?php declare(strict_types=1);

require 'rows_and_content.php';


?><!DOCTYPE html><html lang="en-gb">
<head>
<title> Pure CSS Accordion </title>
<!--
<link href="2-cosmetics.css" rel="stylesheet">
-->
<style>
/* [DOES NOT MATTER] */
html, body {
  font-family: tahoma, arial;
  background: #f2f2f2;
}

/* [THE ENTIRE TAB] */
.tab {
  position: relative;
  width: 88%; max-width: 88em;
  margin: 0.42em auto;
}
/* [THE LABEL] */
.tab input {
  display: none;
}
.tab label {
  display: block;
  /*
  background-color: #2d5faf;
  */
  color: #fff;
  font-weight: bold;
  padding: 10px;
  cursor: pointer;
}
.tab label::after {
  content: "\25b6";
  position: absolute;
  right: 10px;
  top:   10px;
  display: block;
  transition: all 0.4s;
}
/*
.tab input[type=checkbox]:checked + label::after,
*/
.tab input[type=radio]:checked + label::after {
  transform: rotate(90deg);
}

/* [THE CONTENTS] */
.tab-content {
  overflow: hidden;
  background: #ccdef9; background: snow;
  /* CSS animation will not work with auto height */
  /* This is why we use max-height */
  transition: max-height 0.4s; 
  max-height: 0;
}
.tab-content p {
  margin: 0.88em;
  background-color: snow;
}
.tab input:checked ~ .tab-content {
  /* Set the max-height to a large number */
  /* Or 100% viewport height */
  max-height: 100vh;
}
.clb  {clear: both;}
.clr1 {background-color: #2d5faf;}
.clr2 {background-color: #2daf5f; background-color: #900;}
.fll  {float: left;} .flr {float: right;} 
.ooo  {margin: 0; padding: 0 0 0.88em; }
</style>
</head>
<body>

<h1 class="ooo"> Posts</h1>
<h5 class="clb ooo fll"> 
  <a href="http://94.237.92.101:6060/newposts"> Source </a> 
</h5>

<h5 class="flr ooo"> 
  <a href="https://www.sitepoint.com/community/t/bigger-screens-and-list-card-on-the-same-page/366281"> Forum </a> 
</h5>

<hr class="clb">

  <?php      
    $cnt = 1;
    foreach($rows as $key => $item) : 
      $clr = $cnt % 2 ? 'clr1' : 'clr2';

      echo $row = <<< ____EOT
        <div class="tab $clr">
        <input id="tab-r{$cnt}" type="radio" name="tabr">
        <label for="tab-r{$cnt}"> {$cnt}: {$key}</label>
        <div class="tab-content">
          <p> {$item} </p>
      </div>
    </div>
____EOT;
    $cnt++;
    endforeach;
  ?>
  <h3> 
    <a href="https://search.google.com/test/mobile-friendly">
      Google Mobile Friendly 
    </a>
  </h3> 
  <?php require '/var/www/footer.php'; ?>
</body>
</html>

The content is in this form:

$rows = [
'Title 001' => 'Content 001', 
'Title 002' => 'Content 002', 
'Title 003' => 'Content 003', 
];

Notice the Validation links in the footer and also the Google Mobile Friendly Test - no need for remarkably wide screens.

Although the site uses PHP I am sure that Google’s Go Language can search the database for specific items and return the results in an array.

Thanks for the input. In order to make it clear, I over simplified the example.

In reality there will be maybe 50 columns in the “card” and accordion is just what I thought should be excellent to group information.

But in the “list” with maybe 10 columns, the accordion way will be hard to grasp.

So, what I am searching for is a way to load lists in a fast and simple way. My guess is that both Go and AJAX will be to slow to handle 5000 rows. This number of rows is “just-to-show-the-problem”.

I find it difficult to understand your intentions, is it possible to show a screen dump of whaat you already have?

The overall goal is to create an expandable “admin” template for SQL-data based on CRUD. My intention is to create a user interface that focus on speed and simplicity. Using as few “languages” as possible in order to make it maintainable for years. The live links in this thread are just a mini minor step towards this goal. The first sub goal is to load data and present it as fast and reliable as possible.