I am trying to create a Custom Element that allows me to collapse itself from a simple click delegate, but it doesn't seem to work.
I have this code in my js file
import {inject, bindable, bindingMode} from 'aurelia-framework';
export class DataGridCustomElement {
#bindable({ defaultBindingMode: bindingMode.oneTime }) columns = [];
#bindable({ defaultBindingMode: bindingMode.oneTime }) items = [];
#bindable() collpased = true;
collapseClick() {
this.collapsed = !this.collpased;
}
}
And here is my HTML file
<template>
<require from='./data-grid.css'></require>
<div class="collapse-arrow" click.delegate="collapseClick()">
<span class="collapse-icon glyphicon ${collapsed ? 'glyphicon-plus' : 'glyphicon-minus'}" aria-hidden="true"></span>
<span>Order Lines</span>
</div>
<div class="collapse-block" css="${collapsed ? 'display:none;' : 'display:block;'}">
<table class="data-grid">
<thead>
<tr>
<td repeat.for="column of columns">
${column.title}
</td>
</tr>
</thead>
<tbody>
<tr repeat.for="item of items">
<td repeat.for="column of columns">
${item[column.propertyName]}
</td>
</tr>
</tbody>
</table>
</div>
</template>
The crazy thing is it just doesn't seem to at all. It shows collapsed as being false from the get go, even though I set it to true in the class.
I am calling it like so
<data-grid columns.bind="invoiceColumns" items.bind="lineData"></data-grid>
Any ideas? Am I missing something about Custom Elements?
Easy solution. You have a typo in this.collapsed = !this.collpased;.
Related
I'm trying to mount a Vue component to an element that is rendered by a v-html directive. The parent Vue component is a table. Every table cell has richtext content (including images).
If there is an image in the richtext, I need to add an existing copyright component, that opens an overlay. So it can't be plain HTML.
The component looks as follows (simplified):
How do I do this?
<script lang="ts" setup>
import { onMounted, ref } from '#imports'
const tableEl = ref<Array<HTMLTableElement>>([])
const imageEls = ref<Array<HTMLImageElement>>([])
onMounted(() => {
const els = tableEl.value.querySelectorAll('p > img')
imageEls.value = Array.from(els) as Array<HTMLImageElement>
imageEls.value.forEach((imageEl) => {
const parent: HTMLParagraphElement = imageEl.parentElement as HTMLParagraphElement
parent.style.position = 'relative' // Up to this point, everything works...
// How do I add my "<CopyrightNotice/>" component here?
})
})
</script>
<template>
<div>
<table>
<tr v-for="row in rows" :key="row.id">
<td ref="tdEls" v-for="col in row.cols" v-html="col.content" :key="col.id" />
</tr>
</table>
</div>
</template>
Rendered, it looks like this:
<div>
<table>
<tr>
<td>
<p>Hello World!</p>
</td>
<td>
<p>Content</p>
<p>
<img src="/link/to/src.jpg" alt="a cat">
</p>
</td>
</tr>
</table>
</div>
Instead of working with DOM using JS it is better idea to render something called vnode.
Your solution can break Vuejs reactivity / virtual DOM.
Follow documentation here: Render Functions & JSX
There is an example with combining HTML elements and Vuejs components.
I´m using ng-repeat to iterate an array and create a table. In that table, I have a button to make a download. When I click the download button I want the link to disappear and make a loading spin appear. The problem is, the spin is showing up in all the rows and not in just the one i click.
Html -
<tbody md-body>
<tr md-row ng-repeat="">
<td md-cell>
<div layout="row" layout-align="center center">
<md-progress-circular ng-if="isSubmit"></md-progress-circular>
<a ng-if="!isSubmit" ng-click="download($index)">Download</a>
</div>
</div>
</td>
</tr>
</tbody>
JS -
$scope.download = function(index) {
angular.forEach($scope.downloads, function (download) {
// I can console log the index i click
console.log(index)
});
}
You should use the $index on the ng-repeat and instead a boolean isSubmit, use the index to compare to array index.
HTML
<tr ng-repeat="item in items">
<td>
<md-progress-circular ng-if="isLoadingIndex == $index"></md-progress-circular>
<a ng-if="isLoadingIndex != $index"
ng-click="download($index)">Download</a>
</td>
</tr>
CTRL
$scope.isLoadingIndex = null;
$scope.donwload = function($index) {
$scope.isLoadingIndex = $index;
//Rest of your code...
}
i am new in VueJs and i am having that little problem, first here is my sample HTML code :
<div class="search">
<input :class="{ longwidth : isActive }" v-show="showInput" type="text">
<img #click="hideImgShowInput" v-show="hideImg" src="Assets/images/search-icon.png">
</div>
i have followed the documentation exactly, and i am using PHPStorm as editor, but my function that changes the 'isActive' variable is not working i am having this error:
Attribute :class is not allowed here
Any help would be much appreciated.
That sounds like a PHPStorm warning. Ignore it, or try a Vue-aware editor like vs code or atom. Your code looks fine to me.
This error causes the component to not render
My case is similar to the following
<script type="text/x-template" id="game-row">
<tr>
<td>{{ title }}</td>
...
</tr>
</script>
This way when adding the class attribute to tr element, causes the mentioned message
<script type="text/x-template" id="game-row">
<tr :class="{ active: isActive }">
<td>{{ title }}</td>
...
</tr>
</script>
The way to fix it was to pass the class attribute in the custom component call, as follows
<script type="text/x-template" id="game">
<div>
<p v-if="isLoading">Loading...</p>
<template v-else>
<table>
<caption>Game {{ title }}</caption>
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr
is="game-day-row"
v-for="game of games"
:class="{ 'active': isActive }" <!-- Here I set the class -->
:key="game.id"
:game="game"
></tr>
</tbody>
</table>
</template>
</div>
</script>
You can read about it in the vue class and style guide
https://v2.vuejs.org/v2/guide/class-and-style.html#With-Components
In the html output the class active is added to the tr element
I am getting issues trying to use the follow Meteor Package: dandv:jquery-rateit.
I am using it for a ticket system where each update will have a start rating. But when I have more than 1 comment the second one always return 0 value.
Here is my code:
JS:
Template.rating.events({
'click .rateit': function(e){
var rating = $('#rate').rateit('value');
console.log(rating);
Session.set('UpdateId', this._id);
var UpdateId = this._id;
console.log(UpdateId);
/*Meteor.call('saveRate',rating,UpdateId);*/
return false;
}
});
Template.rating.rendered = function () {
this.$('.rateit').rateit();
}
HTML:
<template name="Update">
{{#each Updates}}
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title" align="center">Update</h3>
</div>
<div class="panel-body">
<table class="table">
<tr>
<td width="15%" nowrap align="left">Created By:</td>
<td width="35%" align="left">{{createdBy.username}}</td>
<td width="15%" nowrap align="left">Created At:</td>
<td width="35%" align="left">{{formatDate createdAt}}</td>
<td width="15%" nowrap align="left">Rating:</td>
<td width="35%" align="left">{{> rating}}</td>
</tr>
<tr>
<td colspan="4">{{description}}</td>
</tr>
</table>
</div>
</div>
{{/each}}
</template>
<template name="rating">
<div class="rateit" id="rate"></div>
</template>
Now when I try to rate the second comment is return 0. Screenshot: http://screencast.com/t/ejaTI98X
No matter what star do I select, it always return 0. I think that the error should be probably in the HTML.
I really appreciate all your help on it. If you have any question just let me know.
Have a great day.
You iterate over Updates and I assume there are more than one update. For each update you call the template {{>rateit}} which then renders a div with id=rate, so you will end up with several divs with the same id, so you don't really know which one $('#rate') you are accessing.
In your event handler you also use the global jQuery handler.
I suggest you use the following pattern instead to scope jQuery local to the templates context
Template.rating.events({
'click .rateit': function(e,template){
var rating = template.$('.rateit').rateit('value');
console.log(rating);
Session.set('UpdateId', template.data._id);
var UpdateId = template.data._id;
console.log(UpdateId);
/*Meteor.call('saveRate',rating,UpdateId);*/
return false;
}
});
I have a button that I want to toggle the class when clicked.
This is what I currently have.
<table>
<tbody data-bind="foreach: item ">
<tr>
<td><a data-bind="click: $parent.selectItem, text: Name, css: { 'whitishBtn button_small': selected(), 'greenishBtn button_small': !selected() }"></a></td>
</tr>
</tbody>
</table>
it almost works. When green it works as expected but only has whitishBtn class when white.
figured it out
selected() ? 'greenishBtn button_small':'whitishBtn button_small'"