Select DOM element via VueJS - javascript

I wrote a Chromium extension using clear JavaScript to interact with the DOM, but now I study VueJS and rewrote the extension to use Vue. I found one problem: there is one <input> element connected to Vue.
I change its value via the bg.cp property of the Vue instance, and now I need to select the DOM element. Is there any way to make text selection using the Vue instance instead of using document.getElementById('test').select()?
The final goal is to copy the <input> field to clipboard.
<body>
<div id="appBg">
<input v-model="cp" id="test">
</div>
<script>
//vue instance of div with input field
var bg = new Vue({
el: "#appBg",
data: {
cp: ""
}
});
</script>
</body>

you can use ref in DOM attribute and call it by $refs in js section
EX:
<input ref="inputName" />
and in js section call
this.$refs.inputName
here you can read explanation of it

Related

How clone and init Datepicker via vanilla JS correctly in Tailwind Elements?

I use Tailwind Elements library with Tailwind CSS in my project.
Everything works perfectly, but there is one problem appeared... because I'm trying to clone the element and add to the page a copy.
I do the clone of a form with cloneNode method like this:
I have hidden HTML template:
<template id="temp">
<form>
<div class="datepicker relative mb-3" data-mdb-toggle-button="false">
<input type="text" placeholder="Select a date" data-mdb-toggle="datepicker" />
<label class="text-gray-700">Select a date</label>
</div>
</form>
</template>
When user clicks a button somewhere in the page "+ Add new form", then the new form will be added to the page. There can be many forms as user wants. So I want to use this template to clone it and insert new and new and new nodes to the page. JS:
import 'tw-elements'
let newForm = document.querySelector("#temp").content.cloneNode(true); // clone the <form>
newForm.appendChild(document.body); // add to the <body>
After these manipulations the new form added to the page, but the Datepicker does not work.
As I understood, I should call the initialization of the element programmably via JS like this:
let datePicker = newForm.querySelect('.datepicker');
datePicker.tweDatePicker(); // smth like that maybe
Right? But how? I cannot find in the docs how to call and init the Datepicker (or any other component) via vanilla JS programmably?
Maybe you know the better approaches.

Angular and jQuery: Events not attached to dynamically created HTML elements

I am using jQuery to dynamically create new elements in an Angular Form. The form is built using Template Driven Forms approach. The dynamic elements are successfully created but they are not assigned events/callbacks apparently because the component was already compiled and did not re-compile for the dynamic elements. This keeps the new elements from reporting data or responding despite that the name attribute and ngModel directive is assigned to it. How do I go about this? I have to read the form data for storing in database.
The TypeScript File code which generates the new component's HTML is as under (do not focus on class/ID names etc for I modified them for simplifying question statement). The function uses a counter for assigning unique name to the new input element.
private counter = 0;
increaseElementDynamically(){
this.counter++;
var htmlTagDef = '<input #benchReff'+this.counter.toString()+' ="ngModel" type="text" class=" form-control mb-3" id="bench'+this.counter.toString()+'" required name="bench'+this.counter.toString()+'" ngModel>';
$("#myDiv").append(htmlTagDef);
console.log(htmlTagDef);
}
The input element is written as under in the component's HTML file
<div class="form-group col-lg-3 border-right border-primary">
<label for="benchGroup">Bench Members</label>
<div ngModelGroup="benchGroup">
<div id="customDiv">
<input #benchReff ="ngModel" type="text" class=" form-control mb-3" id="bench" required name="bench" ngModel>
</div>
</div>
<button type="button" class="btn btn-primary float-right m-3" (click)="iincreaseElementDynammically()">Add</button>
</div>
Even if a simple click event is assigned, it wont work for the dynamically created elements since they were created on runtime.
How can the proper dynamic behavior be achieved with functionality?
you need to attach click event or any other event handler using parent element delegation.
$('#myDiv').on('click','#bench', function(){ // will be triggered on click of bench input which is added dynamically
console.log('clicked');
});
Solution: jQuery was operating on front end whereas the component was recompiling. Better approach was to eliminate jQuery and use ngFor directive. For new [dynamic] elements, new IDs can be pushed to an array with ngFor operating on same array to dynamically create elements which fully supported Angular functionality.

Angular js in Dynamically create controls

In my application one block is loaded with the controls dynamically. After loading the dynamic controls the data is update by using the angular js. But the angular js is working with static placed controls. But not with dynamic controls.
Here I placing the dynamic code What I tried to get.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("button").click(function(){
$("#ren").html('<p>Name: <input type="text" ng-model="name"></p>');
});
});
</script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="">
<p>Input something in the input box:</p>
<div id="ren"></div>
<p ng-bind="name"></p>
</div>
<button>click</button>
</body>
</html>
Here the input control dynamically added to the div. The text I enter in control does not appering on paragraph. But this work fine if the input control place in div static.
Am I doing any wrongly. please solve my problem.
Probably your html attached via jquery function, is not registered to angular's watch tree. as a result, it doesn't trigger a digest cycle when you type to input with ng-model. Also this kind of usages angular with jquery in the dom edition level is not recommended. In my opinion, you should use directive instead of that jquery-dom operation
I'd prefer to do it in angular way, rather than mixing jQuery with angular. Because directly adding DOM to angular context will not worked as angular compiled DOM(means angular binding will not work on newly injected DOM). You need to compile that DOM with $compile service with specific scope before injecting it into DOM to enable binding on it.
Lets follow this way, which is fully angular way of doing it. There would be ng-click directive on the button, and will toggle a flag to show and hide element & we will render that array using ng-if
HTML
<p>Input something in the input box:</p>
<div id="ren">
<p ng-if="showName">Name: <input type="text" ng-model="name"></p>
</div>
<p ng-bind="name"></p>
</div>
<button type="button" ng-click="showName!=showName">click</button>

How do we set mask on a dynamically inserted input?

Since Angular-UI-Mask is acting oddly, I'm using jquery-inputmask to some of my inputs, but when an input is dynamically inserted ny Angular it gets no mask:
<li ng-repeat="item in items">
<input type="text" name="birth_date" class="span2 format_date" ng-model="birth_date" placeholder="Data de Nascimento" required />
</li>
This is the related script
<script type="text/javascript">
jQuery(document).ready(function(){
$(".format_date").inputmask("99/99/9999");
});
</script>
Is there anything I can do to force it to set the mask to new inputs?
jQuery plugins like jQuery.inputMask work by (as your code shows) attaching behaviour to DOM elements when the document is 'ready'. This will run once, and never again, so for dynamically-added content this approach doesn't work.
Instead, you need something that will run whenever the corresponding DOM is changed. So whenever an 'item' in your 'items' list is added, the element is added and the corresponding jQuery function is run against that element. You need to use AngularJS for this and you could write your own directive, but thankfully, someone has already written the code for you: the jQuery Passthrough plugin as part of Angular UI's UI.Utils.
Here is a working Plunkr.
You need to include the script at the top, like so (I downloaded it from GitHub):
<script src="ui-utils.jq.js"></script>
Load the module into AngularJS, for example:
var app = angular.module('myApp', ['ui.jq']);
And then use the directive in your HTML markup:
<input type="text" ui-jq="inputmask" ui-options="'99/99/9999', { 'placeholder': 'dd/mm/yyyy' }" />

Binding an event after a page reload and creating new html element using Knockout.js, HTML and JS only?

I am new to knockout libraries and we are working on an iPad web app. The situation is when a user check a checkbox in a HTML page, we need to add a new div in the page with some text boxes in it and remove it when he uncheck those.
Point to be noted: the new div is binded to data that needs to be default loaded in the text box or selects.
Its an iPad web app. It uses Knockout, jQuery, JS and HTML with MVVM.
The question is, can Knockout bind html elements after the page load, as custom handler works/register themselves only during init and can a dynamic div be created using js and html, if yes then how to put it between two static divs?
You can bind elements after page load using ko.applyBindings(viewModel, ElementSelector), like so:
ko.applyBindings(myModel, $("#myDiv"));
However, this isn't something you generally want to do. It's much easier to use the If binding in Knockout, which will dynamically add or remove child elements from the page.
<input type="checkbox" data-bind='checked: showChild' />
<div id="container" data-bind="if: showChild">
<!-- stuff here will only be generated if the checkbox is selected -->
</div>
If you had multiple different elements to show based on a value of something, say a select list, you could use the template feature instead:
//viewmodel properties
self.Options = ko.observableArray(["Name", "Age", "Height"])
self.TemplateToUse = ko.observable()
//html
<select data-bind="options: Options, value: TemplateToUse">
</select>
<div data-bind='template: { name: TemplateToUse }'>
<!-- template whose name is selected value -->
</div>
//templates
<script type="text/html" id="Age">
<span>Age</span>
</script>
<script type="text/html" id="Name">
<span>Name</span>
</script>
<script type="text/html" id="Height">
<span>Height</span>
</script>

Categories