Event binding on dynamically added datepicker not working - javascript

I'm using kendo datepicker here, i have an original div with two datepickers and a duplicated div with two datepickers as well, when i duplicate the div the datepicker events fire once only on the first duplicated div then it stops working, i tried event binding but it didn't work, can anybody help here?
$(document).ready(function() {
$(".from, .to").kendoDatePicker();
$('.calendar').click(function() {
$(this).siblings('.k-datepicker').find('input').data("kendoDatePicker").open();
});
$('.from, .to').each(function(index, el) {
$(el).bind("focus", function() {
$(this).data("kendoDatePicker").open();
});
});
$('.duplicate-btn').on('click', function(e) {
e.preventDefault();
var duplicateable = $(this).next('.duplicate');
var html = $('<div>').append(duplicateable.clone()).html();
$(html).insertBefore(duplicateable);
var new_el = duplicateable.next('.duplicate');
new_el.fadeIn(600).removeClass('duplicate');
});
});
.k-dropdown-wrap .k-select,
.k-numeric-wrap .k-select,
.k-picker-wrap .k-select {
display: none !important;
}
div {
margin-bottom: 15px;
}
.duplicate {
display: none;
}
<link href="http://kendo.cdn.telerik.com/2018.3.911/styles/kendo.common.min.css" rel="stylesheet">
<div>
<label>From</label>
<input class="from">
<button class="calendar">Calendar</button>
</div>
<div>
<label>To</label>
<input class="to">
<button class="calendar">Calendar</button>
</div>
<button class="duplicate-btn">Duplicate</button>
<div class="duplicate">
<div>
<label>From</label>
<input class="from">
<button class="calendar">Calendar</button>
</div>
<div>
<label>To</label>
<input class="to">
<button class="calendar">Calendar</button>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2018.3.911/js/kendo.all.min.js"></script>

You should not clone() those elements. They go with a lot of properties from the widget. Instead I suggest you to use templates to create new elements and then initialize the widgets on them:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.1017/styles/kendo.common.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.1017/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.1017/styles/kendo.default.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.1017/styles/kendo.mobile.all.min.css">
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2018.3.1017/js/angular.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2018.3.1017/js/jszip.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2018.3.1017/js/kendo.all.min.js"></script>
<script>
$(function() {
$(document).on('focus', '[data-role="datepicker"]', function(index, el) {
$(this).data("kendoDatePicker").open();
});
$('input[type="date"]').kendoDatePicker();
$('button').on('click', function() {
let newDatesTemplate = kendo.template($("#dates-template").html()),
newDates = newDatesTemplate({}),
$newDatesDOM = $(newDates);
$newDatesDOM
.appendTo('#container')
.find('input')
.kendoDatePicker();
});
});
</script>
<script id="dates-template">
<div>
<input type="date" class="from">
<input type="date" class="to">
</div>
</script>
</head>
<body>
<div>
<input type="date" class="from">
<input type="date" class="to">
</div>
<div id="container"></div>
<button>Add more dates</button>
</body>
</html>
Explanation:
The template:
<script id="dates-template">
<div>
<input type="date" class="from">
<input type="date" class="to">
</div>
</script>
A simple example of the template.
Adding more elements:
let newDatesTemplate = kendo.template($("#dates-template").html()), // Creates the template with the `script#dates-template` content
newDates = newDatesTemplate({}), // Runs the template
$newDatesDOM = $(newDates); // Creates a jQuery object with the result
$newDatesDOM
.appendTo('#container') // Appends the new DOM elements to a target element
.find('input')
.kendoDatePicker(); // Inits the widgets
Now this will do the magic you want:
$(document).on('focus', '[data-role="datepicker"]', function(index, el) {
$(this).data("kendoDatePicker").open();
});
That event delegation will execute an event in the original elements and in the dynamically added elements because it is bound to the document.
Demo

Right off the bat, I can see you're assigning two different divs to the same variable declared twice.
var datepicker = $(".from").data("kendoDatePicker");
var datepicker = $(".to").data("kendoDatePicker");
Start off by declaring it separately:
var datepicker_from = $(".from").data("kendoDatePicker");
var datepicker_to = $(".to").data("kendoDatePicker");

Related

Making 2+ Text areas reflect each other

I am making a note-taking app and I want 2 text areas to when you type in one the other changes to
what you are doing in one. I want so when I change the title of the page it will change in other places on the page. I'll provide my current code what my page looks like (I want the change to be with my Unititled and an area next to the dropdown arrow) and what I want it to do, I've tried change and input events and I can't seem to figure it out.[My Current Site][1]
What I Want - https://share.vidyard.com/watch/Wj6uTmEiB9LR8iiZy7sVf9
[1]: https://i.stack.imgur.com/3vzEB.png
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Study App</title>
<link rel="stylesheet" href="study.css" />
<link href="https://unpkg.com/boxicons#2.0.7/css/boxicons.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-
awesome/5.15.1/css/all.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" charset="utf-
8"></script>
</head>
<body>
<script src="study.js"></script>
<div class="dropdown">
<nav><label for="touch"><span>Settings</span></label>
<input type="checkbox" id="touch" />
<ul class="slide">
<li><a>
<div class="dark"><button onclick="myFunction()">
<input class="toggle" type="checkbox" /></button></div>
</a></li>
<li></li>
</ul>
</nav>
</div>
</div>
<div class="arrowdown">
<input type="checkbox" id="myCheckbox" onchange="rotateElem()" checked><i class="fas fa-angle-
right dropdown"></i></button>
<div class="pages">
Add Page
</div>
</div>
</div>
<script type="text/javascript">
var checkBox = document.getElementById("myCheckbox");
function rotateElem() {
if (checkBox.checked == false) {
document.querySelector('.fas.fa-angle-right.dropdown').style.transform = 'rotate(90deg)';
} else {
document.querySelector('.fas.fa-angle-right.dropdown').style.transform = 'rotate(0deg)';
}
}
</script>
<div class="tabs"></div>
<div class="sidebar">
<div class="sidebar-top">
<h1><span class="study">Study</span><span class="app">App</span></h1>
</div>
<div class="title">
<textarea id="shortInput" spellcheck="true" placeholder="Untitled" cols="30" rows="1">
</textarea>
</div>
<div class="textbox">
<textarea id="longInput" spellcheck="true" placeholder="Start typing..." cols="30" rows="10"></textarea>
</div>
<script type="text/javascript">
$('.pages').hide();
$(document).ready(function() {
$('input').click(function() {
$('.pages').slideToggle();
});
});
</script>
<script src="study.js"></script>
</body>
</html>
One possible approach would be to store the synchronised value in a variable, and add event listeners to each element for any changes. Then update the value of each element with the new value when the change occurs.
// Store the synchronised content
let value = ''
// Add change listeners to each element
const elements = document.querySelectorAll('.synced')
for (let i = 0; i < elements.length; i++) {
// Different browsers will work better with different events
// but there's no problem with listening for multiple
elements[i].addEventListener('change', handleChange)
elements[i].addEventListener('input', handleChange)
elements[i].addEventListener('keyup', handleChange)
}
// When a change occurs, set the value of all the synchronised elements
function handleChange(e) {
value = e.target.value
for (let i = 0; i < elements.length; i++) {
elements[i].value = value
}
}
<textarea class="synced"></textarea>
<textarea class="synced"></textarea>
<textarea class="synced"></textarea>
jQuery version:
// Store the synchronised content
let value = ''
// Get all the of the relevant elements
const elements = $('.synced')
// Different browsers will work better with different events
// but there's no problem with listening for multiple
elements.on('change input keyup', function() {
value = $(this).val()
elements.val(value)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea class="synced"></textarea>
<textarea class="synced"></textarea>
<textarea class="synced"></textarea>

MDC - Text Input can't be initialized

I'm setting up a text input with MDC but when I'm initializing with JS it comes out this error:
This is my code:
// MDC
const mdc = window.mdc;
// Auto init
mdc.autoInit();
$('.mdc-text-fields').each((index, element) => {
const textField = mdc.textField.MDCTextField.attachTo($(element)[0]);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/material-components-web#4.0.0/dist/material-components-web.min.css">
<script src="https://unpkg.com/material-components-web#latest/dist/material-components-web.min.js">
<div class="mdc-text-field">
<input class="mdc-text-field__input" type="text">
<label class="mdc-floating-label" for="class_name">Nome classe</label>
<div class="mdc-line-ripple"></div>
</div>
Can you help me?
Thanks
Strangely, it worked now removing const textField =...
This is the new JS code:
// MDC
const mdc = window.mdc;
// Auto init
mdc.autoInit();
$('.mdc-text-fields').each((index, element) => {
mdc.textField.MDCTextField.attachTo(element);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/material-components-web#4.0.0/dist/material-components-web.min.css">
<script src="https://unpkg.com/material-components-web#latest/dist/material-components-web.min.js">
<div class="mdc-text-field">
<input class="mdc-text-field__input" type="text">
<label class="mdc-floating-label" for="class_name">Nome classe</label>
<div class="mdc-line-ripple"></div>
</div>
Reference for this solution: https://stackoverflow.com/a/52021265/7520280

How to fix display automatic 2 digits the last phone number to second textfield?

I've combined this script from http://jsbin.com/oleto5/5/edit?html,js,output and http://jsfiddle.net/AEMLoviji/tABDr/
But there is a little problem in code : $('#numbers').val($('#tt').val()+String.fromCharCode(event.keyCode));
If I remove +String.fromCharCode(event.keyCode)); and script be replaced to .substr(-2)); does not work.
If I use +String.fromCharCode(event.keyCode)); is not perfect when I remove digits.
Example :
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>berkelilingkesemua.info</title>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" class="jsbin" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js" type="text/javascript" class="jsbin"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.5/jquery-ui.js" type="text/javascript" class="jsbin"></script>
</head>
<body>
<script type="text/javascript">
$(function(){
$('#txt').keydown(function(){
setTimeout(function() {
$('#output').text($('#txt').val().substr(-2));
}, 50);
});
});
</script>
<input id="txt" type="text" />
<div id="output"></div>
<hr>
Second script is combined by me from first script becomes like below.
<hr />
<script type="text/javascript">
$(document).ready(function() {
$("#tt").keydown(function (event) {
setTimeout(function() {
}, 50);
{
$('#numbers').val($('#tt').val()+String.fromCharCode(event.keyCode));
}
});
});
</script>
<input type="text" id="tt" />
<input type="text" id="numbers" />
</body>
</html>
Are there solution about this script ?.
Let's analyze it:
1. You're using HTML5, so why not to use the "input" event? It's more reliable then a "keyup"
2. To speed things up, always try to store a DOM element in a variable, so you won't have to navigate trough all the DOM tree every time, you press a button
3. Use slice() method, to get a proper string.
var source = $("#tt"),
target = $("#numbers");
source.on('input', function() {
target.val(source.val().slice(-2));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="tt" />
<input type="text" id="numbers" />
I think you're after one of the following.
$('#output').text( $(this).val().slice(0, -2) );
$('#output').text( $(this).val().slice(-2) );
A demo using .slice():
$(function() {
$('#txt').keyup(function() {
var $this = $(this);
$('#output1').val( $this.val().slice(0, -2) ); //Grab everything but the last 2 characters.
$('#output2').val( $this.val().slice(-2) ); //Grab the last 2 characters.
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="txt" />
<br/><br/>
<input type="text" id="output1"></span><br/>
<input type="text" id="output2"></span>

When I click the button, function doesn't get called [duplicate]

This question already has answers here:
Why does jQuery or a DOM method such as getElementById not find the element?
(6 answers)
Closed 8 years ago.
I'm new to JavaScript and JQuery, and I'm trying to figure out why my function doesn't get called when I press the button. My only clue is that the Firefox Console is showing TypeError: document.getElementById(...) is null. I found this example, which says "document.write will overwrite the entire DOM if it's called after the document has finished being parsed" and that's why it's happening. I took a look at my code, and I moved the button into my div tag and it's still happening. I also tried moving the button into it's own div tags. Compiler didn't seem to like syntax when I tried adding html tags where the button is. I'm not sure what I'm supposed to do to fix this.
I'm following this example for the function call on button click. Hopefully I'm applying it ok to my project.
This is my code:
<!DOCTYPE html>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<html>
<head>
<title>jQuery Michele Project</title>
<link href="css/skins/polaris/polaris.css" rel="stylesheet">
<link href="css/skins/all.css" rel="stylesheet">
<link href="css/demo/css/custom.css" rel="stylesheet">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="js/jquery-1.11.0.js"></script>
<script type="text/javascript" src="js/jquery.ui.core.js"></script>
<script type="text/javascript" src="js/jquery.ui.widget.js"></script>
<script src="js/icheck.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('.input').iCheck({
checkboxClass:'icheckbox_polaris',
radioClass:'iradio_polaris',
increaseArea:'10%'
});
});
</script>
<script type="text/javascript">
// Returns an array with values of the selected (checked) checkboxes in "frm"
function getSelectedChbox(frm) {
// JavaScript & jQuery Course - http://coursesweb.net/javascript/
var selchbox = []; // array that will store the value of selected checkboxes
// gets all the input tags in frm, and their number
var inpfields = frm.getElementsByTagName('input');
var nr_inpfields = inpfields.length;
// traverse the inpfields elements, and adds the value of selected (checked) checkbox in selchbox
for(var i=0; i<nr_inpfields; i++) {
if(inpfields[i].type == 'checkbox' && inpfields[i].checked == true)
selchbox.push(inpfields[i].value);
}
return selchbox;
}
document.getElementById('btntest').onclick = function() {
var selchb = getSelectedChbox(this.form);
alert(selchb);
}
</script>
<style type="text/css">
ul {list-style-type: none}
img {padding-right: 20px; float:left}
#infolist {width:500px}
</style>
</head>
<body>
<form>
<div class="skin skin-line">
<div class="arrows">
<div class="top" data-to="skin-flat"></div>
<div class="bottom" data-to="skin-polaris"></div>
</div>
</div>
<div class="skin skin-polaris">
<div class="arrows">
<div class="top" data-to="skin-line"></div>
<div class="bottom" data-to="skin-futurico"></div>
</div>
<h3>Select Items for Column Headings</h3>
<dl class="clear">
<dd class="selected">
<div class="skin-section">
<h4>Live</h4>
<ul class="list">
<li>
<input tabindex="21" type="checkbox" id="polaris-checkbox-1">
<label for="polaris-checkbox-1">Checkbox 1</label>
</li>
<li>
<input tabindex="22" type="checkbox" id="polaris-checkbox-2" checked>
<label for="polaris-checkbox-2">Checkbox 2</label>
</li>
<li>
<input type="checkbox" id="polaris-checkbox-3" >
<label for="polaris-checkbox-3">Checkbox 3</label>
</li>
<li>
<input type="checkbox" id="polaris-checkbox-4" checked >
<label for="polaris-checkbox-4">Checkbox 4</label>
</li>
</ul>
</div>
<script>
$(document).ready(function(){
$('.skin-polaris input').iCheck({
checkboxClass: 'icheckbox_polaris',
radioClass: 'iradio_polaris',
increaseArea: '20%'
});
});
</script>
//$('#checkbox').prop('checked')
</dd>
</dl>
</div>
<div id="loading">
<input type="button" value="Click" id="btntest" />
</div>
</form>
</body>
</html>
The issue is you assign the click handler before the element is available in the DOM. To resolve, you should wrap it in a DOM ready function:
$(function(){
document.getElementById('btntest').onclick = function() {
var selchb = getSelectedChbox(this.form);
alert(selchb);
}
});
Note: $(function(){ ... }); is a shortcut for $(document).ready(function(){ ... });
You're running document.getElementById('btntest') before that element exists. Put this script after your button on the page, not before it:
<script>
document.getElementById('btntest').onclick = function() {
var selchb = getSelectedChbox(this.form);
alert(selchb);
}
</script>

Do I use fadeIn() wrong?

Looking at fadeIn() I get the impression that I just have to add .fadeIn("slow") to an element like so
$('#template').tmpl(data).prependTo('#content').fadeIn("slow");
but it appears instantaneously and doesn't even give an error.
It can be seen here
http://jsfiddle.net/HYLYq/8/
$(document).ready(function(){
$('form').live('submit', function(){
var aform = $(this).serializeArray();
var data = {};
var i = aform.length;
while(i--) {
data[aform [i].name] = aform [i].value;
}
$('#template').tmpl(data).prependTo('#content').fadeIn("slow");
return false;
});
});
<script src="http://code.jquery.com/jquery-1.6.1.min.js"></script>
<script src="http://jqueryui.com/ui/jquery.ui.core.js"></script>
<script src="http://jqueryui.com/ui/jquery.ui.widget.js"></script>
<script src="http://jqueryui.com/ui/jquery.ui.datepicker.js"></script>
<!-- jQuery.tmpl() -->
<script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
<script src="http://jqueryui.com/external/jquery.bgiframe-2.1.2.js"></script>
<script src="http://jqueryui.com/ui/jquery.ui.core.js"></script>
<script src="http://jqueryui.com/ui/jquery.ui.widget.js"></script>
<script src="http://jqueryui.com/ui/jquery.ui.mouse.js"></script>
<script src="http://jqueryui.com/ui/jquery.ui.button.js"></script>
<script src="http://jqueryui.com/ui/jquery.ui.draggable.js"></script>
<script src="http://jqueryui.com/ui/jquery.ui.position.js"></script>
<script src="http://jqueryui.com/ui/jquery.ui.dialog.js"></script>
<!-- template that will be used for inserting a form live when the okay bottom have been pressed and succeeded -->
<script type="text/x-jquery-tmpl" id="template">
${title} ${owner}
</script>
<form id="create_form" name="create_form" action="" method="post">
<input type="text" name="title" id="title" value="test1" />
<input type="text" name="owner" id="owner" value="test2" /><br class="new"/>
<button class="n" type="submit">Create</button>
</form>
<div id="content"> </div>
Any idea what's wrong?
You need to .hide() it before appending it to the DOM.
$('#template').tmpl(data).hide().prependTo('#content').fadeIn("slow");
Alternatively, you could put style="display:none;" in the HTML of your template and then you wouldn't need .hide().
EDIT: Also, your template is only text. So, .hide() will not work unless you wrap it in something first. A <span> or <div> should work just fine.
Hide the element first, then only fadein effect will be visible
$(document).ready(function(){
$('form').live('submit', function(){
var aform = $(this).serializeArray();
var data = {};
var i = aform.length;
while(i--) {
data[aform [i].name] = aform [i].value;
}
$('#template').tmpl(data).prependTo('#content');
$("#content").hide();
$("#content").fadeIn("slow");
return false;
});
});

Categories

Resources