Scalatags tag / container that prints nothing - scala

I have a website structure where I use functions to maximize code reuse. Sometimes I need a certain page to add more scripts or stylesheets to the head of the html page. The code below does what I want, except I'm forced to use a div or some other tag to contain the rest of the scalatags. I don't really want a random div tag in my document's head part. Is there some generic/empty tag I could use for this purpose? (tag("") makes a compilation error btw.)
import scalatags.Text.all._
class Temp {
def document = html(
head(
script("some javascript"),
extraScripts
),
body(
h1("A website")
)
)
def extraScripts = div( // <-- This div is the part I want to change
script("More scripts"),
script("and what not")
)
}

Related

MouseEvent.target returns an EventTarget instead of a HTMLElement when clicked inside an iframe, in ScalaJs

MouseEvent.target returns an EventTarget instead of a HTMLElement when clicked inside an iframe, in ScalaJs.
src/main/scala/tutorial/webapp/TutorialApp.scala:
package tutorial.webapp
import org.scalajs.dom._
import org.scalajs.dom.raw._
import scala.scalajs.js
object TutorialApp {
def main(args: Array[String]): Unit = {
window.document.body.innerHTML = "<p><b>main window</b></p>"
val iframe = document.createElement("iframe")
document.body.appendChild(iframe)
val iframeWindow = iframe.asInstanceOf[HTMLIFrameElement].contentWindow
iframeWindow.document.body.innerHTML = "<p><b>iframe</b></p>"
window.document.addEventListener("click", clicked)
// this works as expected:
// clicking on the 'main window' text, produces this console log:
// - clicked an HTMLElement B
// - parent is an HTMLParagraphElement P
iframeWindow.document.addEventListener("click", clicked) // this doesn't
// this does not work as expected:
// clicking on the 'iframe' text, produces this console log:
// - clicked an EventTarget B
// - parent is an HTMLElement P
}
def clicked(mouseEvent: MouseEvent) {
mouseEvent.target match {
case e: HTMLElement => console.log("clicked an HTMLElement", e.asInstanceOf[HTMLElement].tagName)
case e: EventTarget => console.log("clicked an EventTarget", e.asInstanceOf[HTMLElement].tagName)
}
val parent = mouseEvent.target.asInstanceOf[HTMLParagraphElement].parentElement
parent match {
case e: HTMLParagraphElement => console.log("parent is an HTMLParagraphElement", e.asInstanceOf[HTMLElement].tagName)
case e: HTMLElement => console.log("parent is an HTMLElement", e.asInstanceOf[HTMLElement].tagName)
}
}
}
index.html
<html>
<body>
<!-- Include Scala.js compiled code -->
<script type="text/javascript" src="./target/scala-2.12/scala-js-tutorial-fastopt.js"></script>
</body>
</html>
When I click inside the iframe on the <h1>iframe</h1>, I get an EventTarget instead of an HTMLElement. Casting it to HTMLElement works, but e.parentElement is an HTMLElement instead of HTMLParagraphElement.
Why and how to solve it?
Hoping someone will provide a more precise answer, but in the absence of that:
Iframes are typically loaded from other URLs, often from another origin, and their security model reflects that primary use case – the document inside the iframe is quite isolated from the parent document. I'm not quite sure which exact restriction you're hitting though as manually creating iframes like in your example is not very common.
Usually, the Javascript code running inside the iframe needs to be willing to communicate with Javascript code running in the parent window. Currently in your example you only have code running in the parent window, as the iframe itself does not load any scripts.
Depending on your exact use case, there are several ways to achieve this. For example, you could post custom events to the parent window as described in How to communicate between iframe and the parent site?
Iframes can be really annoying if you don't want the isolation that they come with.

Accordion dropdown filtering through ion search bar

Hi I just created the ionic accordion dropdowns by following a tutorial blog link which used widgets for creating an accordion dropdowns, Below is the link of that blog.
http://masteringionic.com/blog/2019-01-27-creating-a-simple-accordion-widget-in-ionic-4/
updated: here is the my project demo link https://stackblitz.com/github/dSaif/search-accordion
Everything is working perfect, but i want to add Ion-searchbar at the top of the accordions sothat the dropdowns gets filter by inputing text.
please assist me how can i do that. Thank you.
You are going to have to create a variable in your homepage to store your filtered results. Then you need to have a filter function that will take the input from the search bar and filter your master list. Keep in mind you should not set the new variable to the master list, this could cause issues due to object referencing.
So you should have something like
in your html
<ion-searchbar placeholder="Search a name." [(ngModel)]="searchValue" (ionChange)="filterList()"></ion-searchbar>
In your ts file
searchValue: string = '';
filteredList: Array<{ name: string, description: string, image: string }> = this.technologies;
// function called in the html whenever you change the ion searchbar value
private filterList(){
//Make a variable so as to avoid any flashing on the screen if you set it to an empty array
const localFilteredList = []
this.technologies.forEach(currentItem => {
//here goes your search criteria, in the if statement
if(currentItem.name && currentItem.name.toLowerCase().includes(this.searchValue.toLowerCase())) {
localFilteredList.push(currentItem);
}
});
//finally set the global filter list to your newly filtered list
this.filteredList = localFilteredList;
}
You also need to make sure to reference the filterList variable instead of the current one you are referencing.

Using dojo dom.byId is not getting an element added programmatically

I'm creating a dom element programatically using dojo and I can "see" it in the dom with its id, but when I attempt a dom.byId("myId") it returns null.
I have a similar jsfiddle that is actually working (so it doesn't reproduce my problem, but it gives an idea of what I'm trying to do): if you click the button (ignore the lack of styling) in the run output panel, it alerts the content of the element retrieved by dom.byId. But similar code within my dojo widget is not working. Here's the code:
var content = lang.replace(selectFilterTemplate, {
"layer-id": layer.id,
"layer-index": idx,
"filter-name": filter.name
}); // this gets template HTML code similar to what's in the HTML panel of the jsfiddle, only it has placeholder tags {} instead of literals, and the tags are replaced with the attributes of the layer, idx, and filter objects here
// Use dojo dom-construct to create a div with the HTML from above
var node = domConstruct.create("div", { "innerHTML": content });
// put the new div into a dojo ContentPane
var filterPanel = new ContentPane({
"id": layer.id + "-filter-" + idx + "-panel",
"content": node,
"style": "width: 200px; float: left;"
});
// Get the dom element:
var mstag = dom.byId(layer.id + "-filter-" + idx + "-ms-tag")
// this is the same as the "var ms = dom.byId("IssuePoints-filter-1-ms-tag")" in the jsfiddle, but this one returns null. If I view the contents of the 'node' variable in the browser debugging console at this point, I can see the <select> tag with the id I'm referencing.
Why would I be getting null in my dom.byId() if I can see that element in the dom in the debugging console?
It seems that the element is added to the dom at a later point. You may see it with the debugger but it is not yet available the moment you call byId().
In the code you posted you create the filterPanel element but you do not place it in the dom. I assume this happens at a later stage. In contrast, the jsfiddle places the Button element with placeAt() directly after constructing it.

How to render a template from controller within template -- Java, Play 2.1

Is it possible to call a controller method to render a template within a template?
Or is that totally the wrong aproach?
In the div container there is only a sting displayed but not the redered html from my productTable template.
The displayed string inside the <div class="products">:
SimpleResult(200, Map(Content-Type -> text/html; charset=utf-8))
Template:
#categories.map {cat =>
<div>some html</div>
<div class="products">#controller.Products.getByCatergoyId(cat.id)</div>
}
Controller:
public static Result getByCatergoyId(Long catId) {
List<Product> products = Product.find.where().eq("category.id", catId).findList();
return ok(views.html.display.productTable.render(products));
}
If you want to get the code from the productTable view your method shouldn't return a Result but just a String containing rendered code.... aaaannnyyyyway , there is definitely much better way for rendering sub-templates in Play, check the Tags section of the documentation it does exactly what you want directly from the view, of course you will need to pass a product object to it.
Just create tags package in your view package and add there your sub-template (responsible for rendering only pat of page) it behaves exactly the same as common template.

Weird KRL foreach behavior

I've been getting some odd behavior using a foreach today. I have a dataset that's pulling in a JSON document. Part of it is an array, which I pick() out and send to the foreach. Here's my global block:
global {
dataset appserver <- "http://imaj-app.lddi.org:8010/list/popular" cachable for 1 hour;
popular = appserver.pick("$..images")
}
There's one rule first that sets up the page. It looks like this:
rule setup {
select when web pageview "www\.google\.com"
pre {
imagelist = <<
<div id="462popular" style="margin-left:auto;margin-right:auto;width:450px">
<p>Popular images from the CS 462 Image Project</p>
<span class="image"></span>
</div>
>>;
}
prepend('#footer', imagelist);
}
And here's the rule that's not working:
rule images {
select when web pageview "www\.google\.com"
foreach popular setting (image)
pre {
thumburl = image.pick("$..thumburl");
viewurl = "http://imaj-web.lddi.org/view?imagekey=" + image.pick("$..imagekey");
html = <<
<span class="image"><img src="#{thumburl}" style="border:none"/></span>
>>;
}
after('#462popular .image', html);
}
I get something like this (notice how small the scrollbar thumb is):
Any ideas what's going on here?
You have a recursion problem with your html structure and your after selector to insert new content.
Your selector for inserting new content is
#462popular .image
which means that the contents of html will be inserted after every element with the class of image inside an element with the id of #462popular.
Inside the html that you are inserting you have an element with the class name of image which means you are multiplying the number of elements with the class of image inside #462popular every time you go through the loop.
: )