How can I access the JQuery originalEvent attribute - scala.js

I want to handle drag and drop events using the JQuery on() method. So I tried to do the following:
element.on("dragstart", { (event: JQueryEventObject) =>
val dragEvent = event.asInstanceOf[DragEvent]
dragEvent.dataTransfer.setDragImage(...)
})
But dataTransfer is undefined when I try to access it. I found a possible solution here. However the JQueryEventObject has no such originalEvent attribute so how can I access it?
NOTE. I am using the jquery-facade library for my JQuery

It looks like jquery-facade (erroneously) does not declare originalEvent. For the long term, you may want to send a pull request to that repo to add it.
In the meantime, you can force your way through with some more dynamism:
import scala.scalajs.js
import org.scalajs.dom
val originalEvent = dragEvent.asInstanceOf[js.Dynamic].originalEvent.asInstanceOf[dom.DragEvent]
originalEvent.dataTransfer.setDragImage(...)

Related

Unable to select an option from a drop down in Katalon studio

I am new to Katalon Studio and I am facing an issue regarding selection of the drop down.
Please find below the details:
This is the HTML :
I have tried using selectByIndex with the object xpath as:
//div[#class='paCriteriaContainer']//select[#class = 'pa-criteria-select a-select initialized']
It does not select any option and fails with an error stating "Unable to select option by index '2' of object"
Note:
I tried clicking on the input and then selecting the option, but that doesn't seem to work either.
Selecting by label and value don't work either
Please help me here.
Thank you
Try to capture an object and then use following methods :
WebUI.click(findTestObject(Your captured object))
WebUI.selectOptionByValue(findTestObject(Your captured object), 'TEST (2020)', false)
Did you done as I've described and it does not work ?
I tried clicking on the input and then selecting the option, but that doesn't seem to work either.
Are you sure you are clicking the right element in this case?
Try the following instead: create programmatically the element and select by value (note, value isn't the text contained, it is the value html attribute):
TestObject to = new TestObject().addProperty("xpath", ConditionType.EQUALS, "//div[#class='paCriteriaContainer']//select[#class = 'pa-criteria-select a-select initialized']")
WebUI.selectOptionByValue(to, '40696', false)
You have some options to do that, I reggardly suggest you that use always the xpath to reach all the elements that you want to use. The reasson is because the object reports usually fail and, in my opinion, this way is so much more complicated.
But obviously, the xpath will change if the web do, so take care with it.
The imports you need:
import static org.junit.Assert.*
import org.openqa.selenium.By
import org.openqa.selenium.Keys
import com.kms.katalon.core.webui.driver.DriverFactory as DriverFactory
def driver = DriverFactory.getWebDriver()
//If you want to click your input would be:
WebUI.click(WebUI.convertWebElementToTestObject(driver.findElement(By.xpath("(//input[#id='a-select-paCricteriaId_6908'])"))))
//**you just can click on "TestObject" type, and findElement returns "Element" type**
And if you want to select the option you need to know the whole path (I cannot get it with the given information).
An important tip for testing the xpath is to use this function in console mode (F12):
function getElementByXpath(path) {
return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}
//And this code in the same console to test your xpath:
getElementByXpath("YOURTESTXPATH")
Furthermore, there are other ways to reach the same objetive with xpath, for example:
import com.kms.katalon.core.testobject.TestObject as TestObject
...
TestObject tobj = new TestObject('myTestObject')
String expr = '/some/valid/xpath/expression'
tobj.addProperty('xpath', ConditionType.EQUALS, expr)
WebUI.click(tobj)
You have a lot of information if you google "how to get elements by xpath katalon".
Here you can get official information about it:
https://docs.katalon.com/katalon-studio/tutorials/detect_elements_xpath.html#what-is-xpath
Test in the browser console
$x('//*[contains(#class, "pa-criteria-select a-select initialized")]')
if more than one result appear then you can access it like this
$x('(//*[contains(#class, "pa-criteria-select a-select initialized")])[1]')
then you can also access their children
$x('(//*[contains(#class, "pa-criteria-select a-select initialized")])[1]/option')
Use WebUI.selectOptionByIndex keyword but the object should point to the select tag instead of the div.
Update the object element and your code should work

Repopulating form fields in Play Framework

Using the Play Framework (2.6) documentation; I am attempting to handle form submission. But I'm running into an issue in repopulating the form fields - which is what I want to do if it has errors (so users can edit their entry rather than having to re-enter).
newForm.bindFromRequest.fold(
errorForm => {
BadRequest(views.html.form(errorForm))
},
formData => {
val oWriteJso = Json.toJsObject(formData) match {
case x if(x.fields.nonEmpty) => getCreatedFieldValues(x)
case _ => None
}
val oRes = Redirect(routes.Application.index).flashing("success" -> "Entry saved!")
apiC.writeAndRedirect("c", collName, None, oWriteJso)(oRes)(request)
}
)
My issue is that the example in the documentation only shows how to pass errorForm directly to a form template (e.g. views.html.form) rather than being able to render the whole page again (i.e. using views.html.index or a Redirect) with the input form fields being populated from the previous request. I found this answer as the closest to this issue but it is a little old and I am using Scala so wasn't able to implement it. Just have no idea how anyone else is doing this or what the sensible, standard approach is. Thanks for any light on this_
If you use the Play helper functions for generating input tags in your view file. They should populate with your values from the last request.
For example you can create an HTML form in your view file using helper methods like this:
#helper.form(action = routes.Application.userPost()) {
#helper.inputText(userForm("name"))
#helper.inputText(userForm("age"))
}
You can take a look at Play documentation about helpers in view files at the following link:
https://www.playframework.com/documentation/2.7.x/ScalaForms#Showing-forms-in-a-view-template

How to specify event handlers when using lit-html?

The main documentation under [Writing Templates] the following example for binding an event handler with lit-html is provided.
html`<button #click=${(e) => console.log('clicked')}>Click Me</button>`
Adding this a simple page with the default render and html functions imported and calling render however doesn't seem to render the button. If you remove the #click event binding then the button is rendered. There must be something I'm missing or a serious bug in the library.
version: 0.10.2
The links below relate to how events handler bindings work in lit-html:
https://polymer.github.io/lit-html/guide/writing-templates.html
https://github.com/Polymer/lit-html/issues/399
https://github.com/Polymer/lit-html/issues/145
https://github.com/Polymer/lit-html/issues/273
https://github.com/Polymer/lit-html/issues/146
The previous accepted answer was wrong. lit-extended is deprecated and that workaround only worked for a period in 2018 while lit-html was switching over to the new syntax.
The correct way to consume an event is:
html`<button #click=${e => console.log('clicked')}>Click Me</button>`
You can configure the event by assigning an object with a handleEvent method too:
const clickHandler = {
// This fires when the handler is called
handleEvent(e) { console.log('clicked'); }
// You can specify event options same as addEventListener
capture: false;
passive: true;
}
html`<button #click=${clickHandler}>Click Me</button>`
There is also lit-element which gives you a base for building web components with Lit and TypeScript enhancements to move the boilerplate noise of creating event handlers into decorators:
#eventOptions({ capture: false, passive: true })
handleClick(e: Event) { console.log('clicked'); }
render() {
return html`<button #click=${this.handleClick}>Click Me</button>`
}
It appears that in order to use event handler bindings one must not use the standard lit-html API but instead lit-extended which appears to be distributed along with lit-html. Changing import statement to import lit-extended and changing the attribute syntax as shown below seems to work for me.
Before:
import { html, render } from "lit-html";
html`<button #click=${(e) => console.log('clicked')}>Click Me</button>`
After (working):
import { html, render } from "lit-html/lib/lit-extended";
html`<button on-click=${(e) => console.log('clicked')}>Click Me</button>`
Note that the #click syntax didn't seem to work for me at all regardless of what several examples show in the GitHub issues as well as the main documentation. I'm not sure if the above syntax is the preferred way or only way to do event binding but it seems to be one that is at least working.
To me it looks like this may be a good candidate for contributing improvements to the lit-html documentation.

How to extend confluence autocomplete-content

I try to extend autocomplete-content macro by own logic witch should be call some rest.
I finded autocomplete-content.js file where autocomplete-content is defined, but I dont have idea how to extend it by own autocompleteModule.
I tried create own JS file as resource in own add-on, but it execute before autocomplete-content.js on confluence, and autocompleteContent object was undefined.
In the end I need to have own autocomplete tool with own rest service witch will be fatch data from other DB.
If possible use AUI Select2.
Please note: AUI Select2 is based on older Select2. You have to refer to this documentation: http://select2.github.io/select2/
Something else would be to use QuickSearchDropDown
It is not really documented, but quite easy to use. Look for a file quicksearchdropdown.js in Confluence sources.
You can use it like this:
AJS.$('#myinput').quicksearch(URL_RELATIVE_TO_CONFLUENCE_BASE, false, {
makeParams: function (params) {
return {
username: params.term,
staticParam: 'blabla'
};
}
}

Rendering Plone SchemaAddForm without main_template?

I'm attempting to write a Plone add-on that requires an "Add new" form. So far, I've managed to get this working very nicely using plone.directives.form.SchemaAddForm. I have the '##create-snippet' view registered in configure.zcml, and it works perfectly when I view the page normally.
However, the ultimate goal of this project is to get this add form into a TinyMCE popup window. I've created a working TinyMCE plugin for another, irrelevant portion of the add-on, and gotten that working well. However, when I try to navigate to my "##create-snippets" view in a tinyMCE window, I get:
LocationError: (Products.Five.metaclass.DirectoryResource2 object at 0x107162fd0, 'main_template')
My understanding of this issue is that, essentially, the SchemaAddForm class (or one of it's super classes, to be exact) wraps the form with the main Plone main_template when it renders the form. Since TinyMCE windows are their own, isolated little worlds, the template isn't available, and, therefore, cannot be rendered....or something like that? Please correct me if I'm way off.
What I really want to know, is if it's possible to set things up so only the form itself will render, without using the main_template? I would REALLY like to be able to take advantage of the schema-based forms (and their built-in validation), but still be able to keep everything within a TinyMCE window.
I've toyed around with creating my own ViewPageTemplateFile() template, and getting the form to render (somehow?) within it, but frankly, I have no idea how....or if that's even possible.
Please feel free to ask for more information if there's something I've omitted. I'm kinda new to this type of Plone development.
The code generating the form:
from Products.Five.browser import BrowserView
from uwosh.snippets.snippet import SnippetManager
from plone.directives.form import SchemaAddForm
import zope.interface
from plone.autoform.form import AutoExtensibleForm
import zope.schema
from plone.directives import form
import z3c
from Products.statusmessages.interfaces import IStatusMessage
_ = zope.i18nmessageid.MessageFactory(u'uwosh.snippets')
class ISnippet(form.Schema):
title = zope.schema.TextLine(
title=u'Title',
description=u'The title to associate with the snippet.',
required=True)
description = zope.schema.TextLine(
title=u'Description',
description=u'A short explanation of the snippet.',
required=True)
body = zope.schema.Text(
title=u'Body',
description=u'The actual content to be rendered on the page.',
required=True)
class SnippetForm(SchemaAddForm):
schema = ISnippet
#z3c.form.button.buttonAndHandler(_('Save'), name='save')
def handleAdd(self, action):
data, errors = self.extractData()
if errors:
self.status = self.formErrorsMessage
return
obj = self.createAndAdd(data)
if obj is not None:
# mark only as finished if we get the new object
self._finishedAdd = True
IStatusMessage(self.request).addStatusMessage(_(u"Snippet saved"), "info")
#z3c.form.button.buttonAndHandler(_(u'Cancel'), name='cancel')
def handleCancel(self, action):
IStatusMessage(self.request).addStatusMessage(_(u"Add New Snippet operation cancelled"), "info")
self.request.response.redirect(self.nextURL())
def create(self, data):
sm = SnippetManager()
#TODO:
#Include support for different folders from this form.
snippet = sm.createSnippet(data['title'], None ,data)
return snippet
def add(self, object):
#Since, for now, snippets are based upon ATDocuments, their creation is fairly staight-forward.
#So, we don't really need separate Add/Create steps.
return
def nextURL(self):
return self.context.absolute_url() + '/##create-snippet'