0

I have this html code which takes a list of images (of any reasonable length) and displays them in a table with 4 columns

<div>
    <table>
        <tr>
            <th>A</th>
            <th>B</th>
            <th>C</th>
            <th>D</th>
        </tr>
        {% for image in image_list %}
            {% cycle "<tr>" '' '' '' %}
                <td align="center"><img src="{{ image }}"></td>
            {% cycle '' '' '' "</tr>" %}
        {% endfor %}
    </table>
</div>

I am converting the page to work asynchronously using Ajax. I have the list of images in a javascript array, but I do not know how to send image_list to the html from javascript. This is my javascript so far

function displayImageList(message_text, context) {
  console.log(context);
    }

function bid_made(username) {
    var object = ''
    $.ajax(
        {
        type:"GET",
        url: "get-image-list/"+username,
        cache: false,
        data:{object: object},
        success: function(context) {
            displayImageList(status, context)
            }
        })
}

views.py

def get_image_list(request, username):
    if request.method == 'GET':
        user_images = app.get_user_images(username)
        context = {'user_images': user_images}
        return JsonResponse(context, safe=False)
    else:
        return HttpResponse('unsuccessful')

My console log shows that context contains an Array, so I am happy it is working that far. The console log displays:

{user_images: Array(3)}

I need to extend the displayImageList function.

I can update a single item on the page using a function

function showImage(src, width, height, alt) {
    document.getElementById("top-image").src = src;
    };

But updating from a list defeats me. Can someone show me how to do it?

7
  • image_list is returned by your view function. If you do it async via AJAX, use the AJAX success function to handle the returned data. So you call AJAX to make the request to your view, the view handles the logic and returns the object to the AJAX success function which itself again manipulates the html. Maybe share your ajax and view functions Commented Jul 2, 2020 at 16:13
  • Thnaks. Updated Commented Jul 2, 2020 at 16:29
  • can you please share the view that is triggered by get-image-list/"+username Commented Jul 2, 2020 at 16:30
  • Updated for views Commented Jul 2, 2020 at 16:35
  • 1
    sounds like your method needs to find an element by id, loop through context and echo out the table rows and then apply it as inner html to the element. Commented Jul 2, 2020 at 16:38

2 Answers 2

1

doing this with vanillaJS / Jquery will be pretty messy and annoying. it'd look a little like this:

<table id="table">
    <tr>
        <th>A</th>
        <th>B</th>
        <th>C</th>
        <th>D</th>
    </tr>
</table>

function displayImageList(message_text, context) {
  var table = $('#table'); // get the table
  context.user_images.forEach(image => { // cycle the images
    // create your elements
    var row = document.createElement('tr');
    var cell = document.createElement('td');
    var img = document.createElement('img');
    img.src = image; // set the src, maybe do more?

    // append the elements
    cell.appendChild(img);
    row.appendChild(cell);
    table.appendChild(row);
  })
}

this might work, but if you're trying to build more of a full featured webapp, you probably want to look into frameworks like Angular or React that have a lot of tools around them to make all this stuff a lot easier.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. I'll check it out tomorrow
This is perfect once I'd sorted out how to get 4 columns in a row :)
0

Pretty simple! If you've got an array of image data, simply .forEach() over it, creating <td> and <img> markup for each one. Then append the resulting HTML to an existing HTML element.

// create image tag with attributes
function createImageEl(imageObj) {
  const { src, width, height, alt } = imageObj;
  const imgEl = document.createElement('img');
  imgEl.src = src;
  imgEl.width = width;
  imgEl.height = height;
  imgEl.alt = alt;
  return imgEl;
}

// create table cells containing images
function populateImageRow(images) {
  const imageRowEl = document.getElementById('images');
  
  images.forEach(imageObj => {
    const imageEl = createImageEl(imageObj);
    const tdEl = document.createElement('td');
    tdEl.appendChild(imageEl);
    imageRowEl.appendChild(tdEl);
  });
}

//
// the following will happen in the "success" callback of your AJAX call
//

// mockup of the data from your ajax call
const image_list = [
  {
    src: 'https://picsum.photos/id/0/200',
    width: 200,
    height: 200,
    alt: 'alt text'
  },
  {
    src: 'https://picsum.photos/200?blur=2',
    width: 200,
    height: 200,
    alt: 'alt text'
  },
  {
    src: 'https://picsum.photos/id/1003/200',
    width: 200,
    height: 200,
    alt: 'alt text'
  },
  {
    src: 'https://picsum.photos/200?grayscale',
    width: 200,
    height: 200,
    alt: 'alt text'
  }
];

// execute
populateImageRow(image_list);
<table>
  <thead>
    <tr>
      <th>A</th>
      <th>B</th>
      <th>C</th>
      <th>D</th>
    </tr>
  </thead>
  <tbody>
    <tr id="images"></tr>
  </tbody>
</table>

2 Comments

using innerHTML without sanitation is pretty dangerous if any of this is currently or may in the future be user controlled input
Agreed! Edited.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.