Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to open Image in a new popup window with ViewerJs? #578

Open
Norlandz opened this issue Dec 25, 2022 · 1 comment
Open

How to open Image in a new popup window with ViewerJs? #578

Norlandz opened this issue Dec 25, 2022 · 1 comment

Comments

@Norlandz
Copy link

Is your feature request related to a problem? Please describe.
How to open Image in a new popup window with ViewerJs?

Describe the solution you'd like
Once I click on an image:

  • current behavior: display the Viewer in the current html file (ie: current Tab/Window of the browser)
  • expected behavior: pop up the Viewer in a new browser window (-- a behavior like window.open())
    so that I now have 2 windows
    1. the original html file stays in its own original window
    2. the image is opened up in a new window

Describe alternatives you've considered
NA

Additional context
NA

A clear and concise description of what you want to happen.
(see above)

A clear and concise description of any alternative solutions or features you've considered.
NA

Add any other context or screenshots about the feature request here.
(see below)


Problem

(see above)

Solution (a workaround that I currently implementing)

Logic of Source code

  • overall steps::
    have a html file with images -- main.html
    in main.html, use window.open() to open a popup window -- window_ImageGallery.html
    in main.html, collect a list of all the images in your main.html and send them to window_ImageGallery.html
    in window_ImageGallery.html, receive the html_ListOfImages, import ViewerJs and display the images

  • detailed steps::

    1. [in main.html] have an html file with images -- main.html
    2. [in main.html] collect a list of all the images in your main.html as html code data -- <li><img> html_ListOfImages
    3. [in main.html] use window.open(url) to open a popup window, which url links/refers to an html file -- window_ImageGallery.html
      (this step is preformed whenever an image is clicked)
    4. [in window_ImageGallery.html] create an html file window_ImageGallery.html thats to be opened as the popup window
      & add a list for holding the images -- <ol> windowImageGallery_ContainerOfInsertedImages
    5. [in main.html] send the <li><img> html_ListOfImages as query string in the url, to window_ImageGallery.html, when you use window.open(url)
    6. [in window_ImageGallery.html] receive the <li><img> html_ListOfImages from the query string, & place them into <ol> windowImageGallery_ContainerOfInsertedImages
    7. [in window_ImageGallery.html] import ViewerJs in window_ImageGallery.html and display the images

Example of Source code & Picture of expected behavior

[Plunker ex code:] https://plnkr.co/edit/JS5OumYxxJr0cIau?preview

image expected output

How to use/implement the Source code

  1. have an html file with images -- main.html
  2. add the following script to main.html
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
</head>
<body>
<h2>Another Example</h2>
<p>Here we have two images and we want them to fill the width of 50% of the browser window and 100% of the height.</p>
<p>In the following example we do NOT use <code class="w3-codespan">object-fit</code>, so when we resize the browser window, the aspect ratio of the images will be destroyed:</p>
<img src="https://www.w3schools.com/css/rock600x400.jpg" alt="Norway"> <img src="https://www.w3schools.com/css/paris.jpg" alt="Paris">
<h2>Polaroid Images / Cards</h2>
<div class="w3-row">
  <div class="w3-half">
    <div class="polaroid" style="max-width:400px;"> <img class="cardimg" src="https://www.w3schools.com/css/img_5terre.jpg" alt="Cinque Terre">
      <div class="container w3-white">
        <p>Cinque Terre</p>
      </div>
    </div>
  </div>
  <div class="w3-half">
    <div class="polaroid" style="max-width:400px;"> <img class="cardimg" src="https://www.w3schools.com/css/lights600x400.jpg" alt="Norway">
      <div class="container w3-white">
        <p>Northern Lights</p>
      </div>
    </div>
  </div>
</div>
<script>
let path_libNt = '.';

// open Image in a new window with ViewerJs
$(function() { 
  
  // #>> prepare the html_ListOfImages to be sent to ViewerJs
  let html_ListOfImages = '';  
  
  let jqElt_ImgWanted = $('img');
  
  // #>>> filter/-pick the wanted images
  //~ jqElt_ImgWanted = jqElt_ImgWanted.filter(function () {
  //~   let url_Elt_this = this.getAttribute('src');
  //~   let arr_allMatches_arr_matchGroups = [...url_Elt_this.matchAll(/figs\/web\/U\d\d\d\.png$/gm)];
  //~   //~ let arr_matchGroups_FirstMatch = arr_allMatches_arr_matchGroups[0];
  //~   if (arr_allMatches_arr_matchGroups.length === 0) {
  //~     return true;
  //~   } else {
  //~     return false;  
  //~   }
  //~ });
  
  let map__eltImgOri_vs_eltImgCloned = new Map();
  
  jqElt_ImgWanted.each(function (ind_curr) {
    // #>>> clone the elt -- dont modify on the ori elt
    let elt_Img_curr_clone = this.cloneNode(false);
    
    // map the ori img elt with cloned img elt
    map__eltImgOri_vs_eltImgCloned.set(this, elt_Img_curr_clone);
    
    
    // #>>> add id & index to img
    // @potential_problematic if has repeated images
    
    // @potential_problematic works only if ViewerJs es schematic of `index` is same as how I understood here //repeat-from[main.html invoke open]-to[side.html being opened]
    
    //~ elt_Img_curr_clone.setAttribute('data-id-img-for-viewerjs', 'ind_' + ind_curr + '__' + elt_Img_curr_clone.getAttribute('src'));
    elt_Img_curr_clone.setAttribute('data-index-img-for-viewerjs-immutable-ordered-at-input', ind_curr);
    
    // #>>> convert relative path to absolute path
    elt_Img_curr_clone.setAttribute('src', elt_Img_curr_clone.src);

    // #>>> concanate to a big string
    html_ListOfImages += '<li>' + elt_Img_curr_clone.outerHTML + '</li>\n';
  });
  
  // #>> open ViewerJs in a new html window & send the html_ListOfImages
  jqElt_ImgWanted.click(function() {
    // #>>> send some query string data -- a list of <img> tags, to the new html window
    // @ope must use Query String to pass html code data, else you get cross origin access exception //repeat-from[main.html invoke open]-to[side.html being opened]
    // `Uncaught DOMException: Blocked a frame with origin "null" from accessing a cross-origin frame.`
    // https://stackoverflow.com/questions/17502071/transfer-data-from-one-html-file-to-another
    let eltImgCloned_CorrespondToThis = map__eltImgOri_vs_eltImgCloned.get(this);
    let ind_ThisImg = eltImgCloned_CorrespondToThis.getAttribute('data-index-img-for-viewerjs-immutable-ordered-at-input');
    
    let url_file_html_window_ImageGallery = path_libNt + '/window_ImageGallery.html'
      + '?queryStr_html_ListOfImages=' + encodeURIComponent(html_ListOfImages) 
      //~ + '&queryStr_id_ThisImg=' + encodeURIComponent(id_ThisImg)
      + '&queryStr_ind_ThisImg=' + encodeURIComponent(ind_ThisImg);
    
    // #>>> open ViewerJs in a new html window
    // @note: the `target` `open(url, target, windowFeatures)` may be interpeted differently in diff Browsers, this case is intended for Chrome
    let window_ImageGallery = window.open(url_file_html_window_ImageGallery, undefined, 'width=1000,height=800,top=50,left=50');
  });
  
});

</script>
</body>
</html>
  1. create window_ImageGallery.html
  2. place window_ImageGallery.html in the same dir as main.html
  3. add the following script to window_ImageGallery.html
<!DOCTYPE html>
<html>
<head>
<!--<title>window_ImageGallery title</title>--> 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/viewerjs@1.11.1/dist/viewer.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/viewerjs@1.11.1/dist/viewer.min.css" rel="stylesheet">
<!--
<base href="../">
<script src="lib/jquery/jquery-3.6.0.min.js"></script> 
<script src="lib/viewerjs/dist/viewer.js"></script>
<link href="libNt/viewer.css" rel="stylesheet">
-->
<style>
  li {
    border: 1px solid black;
    padding: 1em;
    margin: 1em;
  }
</style>
</head>
<body>
<h1>window_ImageGallery heading</h1>
<ol id="windowImageGallery_ContainerOfInsertedImages">
</ol>
<script>
window.onload = function () {
  // #>> get parameter from URL
  // @ope must use Query String to pass html code data, else you get cross origin access exception //repeat-from[main.html invoke open]-to[side.html being opened]
  // `Uncaught DOMException: Blocked a frame with origin "null" from accessing a cross-origin frame.`
  // https://stackoverflow.com/questions/17502071/transfer-data-from-one-html-file-to-another
  let data = getParamFromUrl();
  
  let html_ListOfImages = decodeURIComponent(data.queryStr_html_ListOfImages);
  //~ let id_ThisImgThatOpenedTheHtmlWindow = decodeURIComponent(data.queryStr_id_ThisImg);
  let ind_ThisImgThatOpenedTheHtmlWindow = decodeURIComponent(data.queryStr_ind_ThisImg);
  
  // #>> add the Images to the list
  document.getElementById('windowImageGallery_ContainerOfInsertedImages').innerHTML = html_ListOfImages;
  
  // #>> show the Images in ViewerJs 
  // must not be outside the `window.onload` ... [[dk execution order ...]]
  let ele_windowImageGallery_ContainerOfInsertedImages = document.getElementById('windowImageGallery_ContainerOfInsertedImages');
  let imageViewerJs_ImageGallery = new Viewer(ele_windowImageGallery_ContainerOfInsertedImages, {
    transition: false
  });
  
  //~ imageViewerJs_ImageGallery.show();
  // `view()` base on index, not id ... 
  // @potential_problematic works only if ViewerJs es schematic of `index` is same as how I understood here //repeat-from[main.html invoke open]-to[side.html being opened]
  imageViewerJs_ImageGallery.view(ind_ThisImgThatOpenedTheHtmlWindow);
  
  // #>> change title
  //~ document.title = id_ThisImgThatOpenedTheHtmlWindow;
  ele_windowImageGallery_ContainerOfInsertedImages.addEventListener('viewed', function (event_viewed) {
    let ele_CurrentViewImage = event_viewed.detail.originalImage;
    let ind_CurrentViewImageIndex = ele_CurrentViewImage.getAttribute('data-index-img-for-viewerjs-immutable-ordered-at-input');
    // ^(.*[\\\/])?(.*?)(\.[^.]*?|)$
    // https://stackoverflow.com/questions/9363145/regex-for-extracting-filename-from-path
    let url_CurrentViewImageSrc = ele_CurrentViewImage.getAttribute('src');
    //~ console.log(url_CurrentViewImageSrc);
    //~ let arr_matchGroups = url_CurrentViewImageSrc.match(/^(.*[\\\/])?(.*?)(\.[^.]*?|)$/gm); // sth with the design of flag `g`
    let arr_allMatches_arr_matchGroups = [...url_CurrentViewImageSrc.matchAll(/^(.*[\\\/])?(.*?)(\.[^.]*?|)$/gm)];
    let arr_matchGroups_FirstMatch = arr_allMatches_arr_matchGroups[0];
    
    document.title = ind_CurrentViewImageIndex + '_' + arr_matchGroups_FirstMatch[2] + arr_matchGroups_FirstMatch[3];
    //~ console.log(event_viewed.detail.originalImage + ';;' + event_viewed.detail.originalImage.id + ';;' + document.title);
  });
  
};

function getParamFromUrl() {
  let url = document.location.href;
  let params = url.split('?')[1].split('&');
  let data = {};
  let tmp;
  for (let i = 0, l = params.length; i < l; i++) {
    tmp = params[i].split('=');
    data[tmp[0]] = tmp[1];
  }
  return data
}
</script>
</body>
</html>
  1. open main.html & click an image -> window_ImageGallery.html will popup with images
  • note::
    1. note: the target open(url, target, windowFeatures) may be interpeted differently in diff Browsers, this case is intended for Chrome
    2. window_ImageGallery.html not necessary be in same dir of main.html, you can put it in a library
      & modify the code let url_file_html_window_ImageGallery = path_libNt + '/window_ImageGallery.html'
    3. modify the code as you want if you understand it
@fengyuanchen
Copy link
Owner

Good job!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants