I am creating chatbox, and that chat box is dynamically generated on click of contact.
In dynamically generated HTML I have a textarea to enter some text, here is the HTML
<div class="chatboxinput">
<textarea id="chatboxtextareaankur" class="chatboxtextarea" keydown.delegate="checkChatBoxInputKey($event, 'id', 'name')"></textarea>
</div>
But the method "checkChatBoxInputKey" is not executing on any key down event.
Please let me know how to solve this.
It doesn't work because Aurelia's view compiler doesn't have an opportunity to compile dynamically generated markup to find the bindings, etc.
Use the if binding to add/remove an element from the DOM. Here's an example:
http://plnkr.co/edit/kBUz94?p=preview
<template>
<button click.delegate="showChatBox = true">Show Chat Box</button>
<div if.bind="showChatBox" class="chatboxinput">
<textarea id="chatboxtextareaankur" class="chatboxtextarea" keydown.delegate="checkChatBoxInputKey($event)"></textarea>
</div>
</template>
export class App {
checkChatBoxInputKey(e) {
console.log(e.which);
return true;
}
}
Related
This Meteor code does not print to console the event.which so as to use tab key event when tabbing out of an editable div.
Why editable div? Because I can style part of the string which is not allowed in input element.
BTW: Where do I find a list of the events types for Meteor Blaze. There site only lists a very limited events. Other DOM events are available as well, but...
I tried some blur and onblur for no avail.
How can I fire a tab key event on an editable div? Thanks
//client/main.js template evnet
'onblur #vin'(e){
console.log(e.which) //prints nothing
let vin = e.target.value
}
<div class="body">
<div id="vin" class="editable" contenteditable="true">{{vehicle.vin_a}}<span id="vinb">{{vehicle.vin_b}}</span><span id="vin4">{{vehicle.vin4}}</span></div>
<input type="text" placeholder="make, modle, date">
</div>
It works for me!
Here is a minimal, reproducible example:
main.html:
<head>
<title>b</title>
</head>
<body>
{{> info}}
</body>
<template name="info">
<div id="vin" class="editable" contenteditable="true">
Edit me
</div>
</template>
main.js:
import { Template } from 'meteor/templating';
import './main.html';
Template.info.events({
'blur #vin'(event, instance) {
console.log('blur!', event);
}
});
Maybe you defined the event on the wrong template?
So I have a form with multiple input fields, whenever I type something into these fields, somehow it manipulates the DOM, and removes a certain class active from the form container. Please see this GIF to see it.
Steps to reproduce:
Click create your account
Type anything in any of the shown field
Observe the faulty behavior (which is the result of removing the active class)
Template code:
// active class is getting injected here
<div class="login-forms__container">
<section class="new-user__section">
<form>
<h1>{{ $t('login.create-form.title') }}</h1>
<p>{{ $t('login.create-form.subtitle') }}</p>
<b-field>
<b-input
v-model="registerForm.fullName"
:placeholder="$t('login.create-form.name')"
type="text"
icon-pack="fas"
icon="user"
maxlength="25"
/>
</b-field>
....
<div class="field">
<small>
<a target="_blank" #click.prevent="toggleCreateAccount">
{{ $t('login.create-form.registered') }}
</a>
</small>
</div>
</form>
</section>
</div>
JS code:
methods: {
toggleCreateAccount () {
document
.querySelector('.login-forms__container')
.classList
.toggle('active');
},
What I've tried:
Disable/Enable hot reloading
Tracing DOM event listeners (through breakpoints)
Changing the class name (suspected that "active" name is too common and might get removed by other libraries)
Using e.preventDefault() and click.prevent;
Or even removing the function responsible for adding the class and inject the class manually through inspect elements
Note:- removing v-model fixes the issue
You're modifying the DOM manually in a way that Vue can't trace. When it comes time to rerender, it sees the class you added, but since it doesn't match the VDOM in the template (you don't have "active" in your template), it thinks it must be removed (VDOM = source of truth).
You should conditionally include the active class in your template, Vue will automatically patch the DOM for you.
An abbreviated example:
template: `<div :class="{'.login-forms__container': true, active: createAccountActive }">`,
data() {
createAccountActive: false,
},
methods: {
toggleCreateAccount() {
this.createAccountActive = !this.createAccountActive;
}
},
I'm learning how to use vue.js
I've a shared hosting plan where I can only use html. I'm fetching the data I need using axios and a remote wordpress installation that will act as a backend only. What I need to know, is how I can change the DOM content of the index.html using vue if the user click on a link and I need to change the layout of the page because a different presentation for the contents is needed?
See the example:
<div id="vue-app">
link to layout 2
<div class="col-12">starting layout </div>
</div>
// after the user click the link (v-on:click) the layout change
<div id="vue-app">
link to layout 1
// layout change
<div class="col-6">new layout </div>
<div class="col-6">new layout </div>
</div>
Please read up on Conditional Rendering in Vue.js.
You can have a boolean variable in the data compartment of your script tag and change it on click.
And in the tags put v-if="your_bool_variable".
<div id="vue-app" v-if="layout_switch">
link to layout 2
<div class="col-12">starting layout </div>
</div>
// after the user click the link (v-on:click) the layout change
<div id="vue-app" v-else>
link to layout 1
// layout change
<div class="col-6">new layout </div>
<div class="col-6">new layout </div>
</div>
Negate the boolean variable at the #click event.
Data could look like the following:
<script>
export default {
name: "YourComponent",
data: () => {
return {
layout_switch: true
}
},
methods: {
changeLayout() {
this.layout_switch = !this.layout_switch;
}
}
}
</script>
I use vue.js. I want add vue model in selector, who created using jquery plugin.
My code:
<div class="app">
<div class="wysiwyg-wrap"></div>
</div>
<script>
new Vue({
el: '.app',
data: {
wysiwygText: 'text demo'
},
created: function(){
$('.wysiwyg-wrap').trumbowyg();
}
});
</script>
Jquery plugin trumbowyg create inside '.wysiwyg-wrap' many html elements. How to add in one of this elements v-model binding? I want type in my redactor and save result in 'wysiwygText' from vue model.
Thank you for any answers!
This is a great use-case for custom directives. Here is an example of a custom directive that adds jQuery functionality to Vue: https://vuejs.org/examples/select2.html
You can create a simple directive
Vue.directive('wysiwyg-wrap', function () {
$(this.el).trumbowyg();
});
Then attach it to any element
<div class="app">
<div v-wysiwyg-wrap></div>
</div>
I am using Polymer 1.0 and I am building a small accordion example. I have data binding to the accordion text fine, I just want to change the icon of the accordion when I click it.
Below is my code
<dom-module id="ab-accordion">
<template>
<iron-ajax
auto
handle-as="json"
on-response="handleResponse"
debounce-duration="300"
id="ajaxreq"></iron-ajax>
<template is="dom-repeat" id="accordion" items="{{items}}" as="item">
<div class="accordion" on-click="toggleParentAcc">
<div id="accordion_header" class="accordion__header is-collapsed">
<i class="icon icon--chevron-down"></i>
<span>{{item.name}}</span>
</div>
<div id="standard_accordion_body" class="accordion__body can-collapse">
<div class="accordion__content">
<content id="content"></content>
</div>
</div>
</div>
</template>
</template>
<script>
Polymer({
is: "ab-accordion",
//Properties for the Element
properties: {
accordian: Object,
childaccordions: Object,
// Param passed in from the element - Set if the accordion is open by default.
open: String,
data: String,
reqUrl: {
type: String,
value: "https://example.com/service.aspx"
},
},
ready: function () {
this.items = [];
},
attached: function () {
// Run once the element is attached to the DOM.
},
toggleParentAcc: function (event) { // Toggle the classes of the accordions
//This is where I want to toggle the class
this.$.accordion_header.classList.toggle('is-collapsed');
if (typeof event !== 'undefined') {
event.stopPropagation(); // Stop the click from going up to the parent.
}
},
handleResponse: function (e) {
this.items = e.detail.response.sports;
}
});
</script>
</dom-module>
Basically inside the toggleParentAcc function I want to toggle the class of the div with ID accordion_header. But I just get undefined or null.
I have tried the following two lines:
this.$.accordion_header // #1
this.$$('#accordion_header') // #2
How I access that element inside the dom-repeat?
UPDATE: I can't even access the elements within the when inside the attached function.
attached: function(){
this.$.accordion_header // This is null?!
this.$$('#accordion_header'); // this is also null!
}
https://www.polymer-project.org/1.0/docs/devguide/local-dom.html#node-finding
Note: Nodes created dynamically using data binding (including those in dom-repeat and dom-if templates) are not added to the this.$ hash. The hash includes only statically created local DOM nodes (that is, the nodes defined in the element’s outermost template).
I think it would be better if you'd use Polymer.dom(this.root) instead. Also I'd advice you to not use static IDs in dom-repeat as they are meant to be unique. Use classes instead.
Looks like you might be encountering Event Retargeting which happens when events "bubble" their way up the DOM tree. Read this documentation to learn more.
When I encountered this, I solved it by using something like:
var bar = Polymer.dom(event).path[2].getAttribute('data-foo');
inside my Polymer() function.
To figure it out in your case, you should go to the console and search the DOM tree / event log to locate your target. If you have trouble locating the correct area of the console, post a comment and I might be able to help further.
I eventually figured out a way of doing this without having to select elements in the nested template.
<template id="accord_template" is="dom-repeat" items="{{items}}" as="item">
<ab-accordion-row id="[[item.id]]" name="[[item.name]]" open="[[item.open]]">
</ab-accordion-row>
</template>
ab-accordion is another element, I just feed it the data and I can then change the classes based on the params.
<div id="accordion" class="accordion" on-click="toggleAccordion">
<div class$="{{getClassAccordionHeader(open)}}">
<i class="icon icon--chevron-down"></i>
<span>{{name}}</span>
</div>
<div id="standard_accordion_body" class$="{{getClassAccordionChild(open)}}">
<div class="accordion__content">
<content></content>
</div>
</div>
</div>
try with this.
toggleParentAcc: function (event) { // Toggle the classes of the accordions
//This is where I want to toggle the class
var header = event.target.parentElement;
Polymer.dom(header).classList.toggle('is-collapsed');
// rest of your code
}