Aurelia Dragula how to use the Api instead of custom element - api

I'm trying to use aurelia dragula. All the examples I can find use the custom element
<dragula-and-drop drop-fn.call="itemDropped(item, target, source, sibling)"></dragula-and-drop>
with then having divs that act as sources/targets like this
<div class="drag-source drop-target drop-style" data-list="things">
<compose repeat.for="thing of things" view-model.bind="thing" data-index.bind="$index"></compose>
</div>
That is working great, and I can see I can add other function bindings for drag end, etc. However the documentation shows a bunch of events that Dragula can listen for, but it looks like I'd have to use the API, instead of the custom element, to make use of those. I can't seem to figure out how to make use of the Dragula object along with divs like above in the view. For instance...
import { Dragula } from 'aurelia-dragula';
...
let dragula = new Dragula();
dragula.on('drag', (el, source) => {
console.log('started dragging...');
});
doesn't pick up on the drag events from the div above.
I'm pretty new to aurelia, so maybe I'm missing something framework related?
How can I go about using the Dragula API approach instead of the custom element?
Thanks

Related

How to change HTML tags of the component dynamically after click in Vue3 composition-api?

I am writing my first app in Vue3 and I use composition-api with script setup.
Using v-for, I create components that are inputs (CrosswordTile) that make up the crossword grid.
A problem appeared during the implementation of the field containing a clue to the password.
Since the text doesn't allow text to wrap, I wanted to dynamically change the tag to after a click.
Function in parent component where I handle logic after click that change tile type works fine, but I need to change tag of "target" to and set maxLength to a different value.
If it would help here is whole code on github: https://github.com/shadowas-py/lang-cross/tree/question-tile, inside CrosswordGrid.vue.
function handleTileTypeChange(target: HTMLInputElement) {
if (target && !target.classList.contains('question-field')) {
addStyle(target, ['question-field']);
iterateCrosswordTiles(getNextTile.value(target), removeStyle, ['selected-to-word-search', 'direction-marking-tile']);
} else if (target) {
removeStyle(target, ['question-field']);
if (getPrevTile.value(target)?.classList.contains('direction-marking-tile')) {
iterateCrosswordTiles(
target,
addStyle,
['selected-to-word-search', 'direction-marking-tile'],
);
}
}
TEMPLATE of ParentComponent
<div
class="csw-grid"
#input="handleKeyboardEvent($event as any)"
#mousedown.left.stop="handleClickEvent($event)"
#click.stop="">
<div v-for="row in 10" :key="row" class="csw-row" :id="`csw-row-${row}`">
<CrosswordTile
v-for="col in 8"
:key="`${col}-${row}`"
#click.right.prevent='handleTileTypeChange($event.target)'
/>
</div>
</div>
I tried to use v-if inside CrosswordTile, but it creates a new element, but I just need to modify the original one (to add/remove HTML classes from it basing on logic inside CrosswordGrid component).
How can I get access to the current component instance properties when using the composition API in script setup or how to replace the tag dynamically?
:is and is doesn't work at all.

Apply vue-katex to content loaded from static folder

I'm trying to make a blog using Vue as laid out in the excellent demo here. I'd like to include some mathematical formulas and equations in my blog, so I thought I'd try to use vue-katex. vue-katex formats my mathematical notation perfectly when I put all my KaTeX HTML directly into my Vue templates, but to create a useable blog I need to keep my content separate from my templates (as shown in the demo).
I can't get vue-katex to format HTML content in the static folder. That's what I'd like help with.
Setup
I cloned the github repo for the demo.
I added vue-katex to package.json:
"vue-katex": "^0.1.2",
I added the KaTeX CSS to index.html:
<!-- KaTeX styles -->
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.9.0-alpha2/katex.min.css"
integrity="sha384-exe4Ak6B0EoJI0ogGxjJ8rn+RN3ftPnEQrGwX59KTCl5ybGzvHGKjhPKk/KC3abb"
crossorigin="anonymous"
>
I added the import statement to src/App.vue:
import Vue from 'vue'
import VueKatex from 'vue-katex'
Vue.use(VueKatex)
and I added a simple line of HTML with KaTeX to the BlogPost template:
<p>Here's an equation in the actual Vue template: <div class="equation" v-katex="'X \\sim N(\\mu, \\sigma^2)'"></div></p>
As I said, this works - I see formatted mathematical notation in my blog post (URL http://localhost:8080/read/neque-libero-convallis-eget):
However, I need different equations for every blog post, of course.
So I tried adding KaTeX HTML to the "content" field in the JSON for the first blog post: static/api/post/neque-libero-convallis-eget.json. I changed the "content" line to:
"content": "Here's an equation in the static folder: <div class=\"equation\" v-katex=\"'X \\sim N(\\mu, \\sigma^2)'\"></div>",
This content appears on the page, but the equation doesn't render. I see this: (the text appears but no equation is shown)
When I use Developer Tools to inspect the HTML on the page, I see this:
You can see that vue-katex has been applied to the equation I put in the template directly: it has parsed the HTML I typed into lots of spans with all the mathematical symbols, which are showing perfectly.
However the KaTeX HTML I've added to the "content" in the static folder has simply been placed on the page exactly as I typed it, and is therefore not showing up as an equation on the page. I really need to keep my blog post content in this static folder - I don't want to have to create a different .vue file for each blog post, that defeats the point!
My question is: is there a way to manually "apply" vue-katex to the HTML I place in the static folder, when it loads? Perhaps there is something I can add to the plugins/resource/index.js file, since this contains the function that loads the data from the static folder?
Many thanks in advance for any help.
*Disclaimer: I'm definitely no expert / authority on what I'm about to explain!
One thing to remember is that Vue reads the templates you write, and then replaces them as reactive components. This means that although you often write Vue attributes like v-for, v-html or in this case v-katex these attributes are only useful up until the app or component is mounted.
With this in mind, if you have a Vue app that ajax loads some html, its not going to be able to rerender itself with those Vue bindings in place.
I have somewhat ignored your current set up and set about solving the issue in another way.
Step 1: Reformat your data from the server side
I've put the posts into an array, and each post contains the template (just a string of html) and the equations separately as an array. I've used [e1] in the post as a placeholder for where the katex will go.
var postsFromServer = [{
content : `<div>
<h2>Crazy equation</h2>
<p>Look here!</p>
[e1]
</div>`,
equations : [
{
key : 'e1',
value : "c = \\pm\\sqrt{a^2 + b^2}"
}
]
}];
Step 2: When the post is rendered, do some work on it
Rather than just use v-html="post.content", I've wrapped the html output in a method
<div id="app">
<div v-for="post in posts" v-html="parsePostContent(post)">
</div>
</div>
Step 3: Create a method that renders all the katex, and then replaces the placeholders in the post
methods : {
parsePostContent(post){
// Loop through every equation that we have in our post from the server
for(var e = 0; e < post.equations.length; e++){
// Get the raw katex text
var equation = post.equations[e].value;
// Get the placeholder i.e. e1
var position = post.equations[e].key;
// Replace [e1] in the post content with the rendered katex
post.content = post.content.replace("[" + position + "]", katex.renderToString(equation));
}
// Return
return post.content;
}
}
Here is the whole set up, which renders Katex:
https://codepen.io/EightArmsHQ/pen/qxzEQP?editors=1010

Vue.js: Trigger an #click on child component from parent component in

I have a template with several divs, each containing an #click that triggers a specific function and a corresponding visual effect
<template>
<div #click="function doThis(param1)></div>
<div #click="function doThis(param2)></div>
<div #click="function doThis(param3)></div>
<div #click="function doThis(param4)></div>
<div #click="function doThis(param5)></div>
</template>
method: {
doThis(param) {
lightUpDiv(corresponding param)
}
}
I'm also calling doThis from the parent via a $broadcast. What if any, is the best Vueish way to trigger the corresponding lightUpDiv call from the $broadcast? (just use getElementById and .click()???). I used individual divs vs a v-for in the hope that this is easier.
I should note that there are several instances of the template On the page. Even if the same visual effect is caused simultaneously on all the templates that is fine. If there is a way to call them on the specific template instances that is even better.
I've spent hours trying to figure this out and cannot seem to do it. Have read all the guide and API. I know there is some way to bind the data to make the template instances unique but can't seem to get it. Definitely couldn't see the #click from $broadcast solution
Thanks for any help!!
<div #click="doThis"></div>
OR
<div #click="doThis($event)"></div>
Both are functionally equivalent, but second version is recommended as it is more explicit.
In javascript,
doThis: function(ev){
//ev is event object and ev.target refers to the div you need.
alert(ev.target.innerHTML);
}
Demo
Event object details

Windows store app using Javascript - How do I add event listener in html

In a Windows store app using Javascript, I have a listview defined in the html.
<div id ="menuListView" data-win-control="WinJS.UI.ListView" data-win-options="{
itemDataSource: viewModel.items.dataSource,
itemTemplate: menuItemTemplate,
layout: {type: WinJS.UI.GridLayout}}"></div>
I could define a click event handler in Javascript something like this:
menuListView.addEventListener("selectionchanged", clickEventHandler, false);
But since, I'm trying to use the MVVM pattern, I would like to put this piece of code in the html view and let a viewmodel handle the click event. Would it be possible?
For full NVVM functionality in your WinJS app I would recommend using a framework like http://knockoutjs.com
You can probably try something like this if you are keep to declare an event handler in HTML view :
"<button id="button1" onselectionchange="clickEventHandler(event)">An HTML button</button>"
Hope this helps :)

Access Elements of a DOJO DIV

I have two Hyper Links on to a DOJO DIv
var create = dojo.create("div",{
id:"create_links",
className:"iconRow1",
innerHTML:"<a class='popupLink' href='javascript:openCreateDialog()'>Create </a> <span>|</span><a href='javascript:openUploadDialog()'>Batch </a>"
},dojo.query(".ui-jqgrid-titlebar")[0]);
On click of the Batch Hyperlink , i have a function
function openUploadDialog()
{
// Here i want to disable the Create Hyper Link tried this way
dojo.byId('create_links')[1].disabled=true; // Not working
}
See whether i can answer your question.
HTML Part:
<div id="create_links">
g
h
</div>
JS Part:
dojo.addOnLoad(function() {
var a = dojo.query("#create_links a")[1];
dojo.connect(a,'click',function(e){
console.log(e.preventDefault())
})
})
#Kiran, you are treating the return of dojo.byId('create_links') like an array when that statement will return to you a node on the dom.
Also, hyperlinks don't support a disabled attribute to prevent them from being actionable. You could probably create a click handler that returns false to accomplish this type of functionality, or like #rajkamal mentioned, calling e.preventDefault(). #rajkamal also provides a good solution to selection the link properly.