Can't get my input focus to work? - polymer

Why does my this.$.search.focus() not work?
<polymer-element name="site-search">
<template>
<style>
:host {
font-family: 'RobotoDraft', sans-serif;
font-size: 14px;
}
.condensed input, .condensed /deep/ .underline {
display: none;
}
</style>
<section horizontal layout>
<core-icon-button
id="button"
icon="search"
title="search"
aria-label="search"
disabled?="{{!canBeCondensed}}"
on-tap="{{toggleSearch}}">
</core-icon-button>
<paper-input-decorator flex
label="{{label}}"
floatingLabel="{{floatingLabel}}"
value="{{value}}"
disabled?="{{disabled || condensed}}"
class="{{ {condensed: condensed} | tokenList }}">
<input
id="search"
on-blur="{{onBlur}}"
type="search"
value="{{value}}"
committedValue="{{committedValue}}"
on-keyup="{{onKeyUp}}"
disabled?="{{disabled}}">
</paper-input-decorator>
</section>
</template>
<script>
Polymer({
publish: {
label: '',
floatingLabel: false,
disabled: {value: false, reflect: true},
canBeCondensed: false,
condensed: false,
site: window.location.hostname
},
toggleSearch: function() {
if (!this.canBeCondensed) return;
this.$.search.focus() <==== Doesn't work. Why?
this.condensed = !this.condensed;
this.$.button.hidden=true
},
onKeyUp: function(e) {
if (e.keyCode == 13) { // Enter.
var q = encodeURIComponent('site:' + this.site + ' ' + this.value);
window.open('https://www.google.com/search?q=' + q);
}
},
onBlur:function(e) {
this.condensed = !this.condensed;
this.$.button.hidden=false
},
});
</script>
</polymer-element>

Try removing .condensed input, in your css.
Because when you change the class of the paper-input-decorator, your original css will update the inner input's class too, and this will cause the input to lose focus.
Alternatively, you can remove the whole class="{{ {condensed: condensed} | tokenList }}" and hide/show the underline element in js. For example -
toggleSearch: function () {
if (!this.canBeCondensed) return;
this.$.search.focus();
//this.condensed = !this.condensed;
this.$.button.hidden = true;
var underline = document.querySelector('paper-input-decorator::shadow .underline');
underline.hidden = true;
},

Related

How to get array data from dynamic tabs and delete current tabs by jquery

I'm creating dynamic tabs. I'm currently facing two problems:
When I click on the span x to delete current tab, it deletes all my tabs.
When I getting the array data, it always gets the first tab data only.
Can anyone help me with this? I've tried many ways but I still cannot get my desired result. Here is my fiddle Dynamic Tabs.
Currently my array result looks like this for the 2nd problem when there is two tabs, '2023' and '2025':
[{
February: "1",
January: "1",
Year: "2023"
}, {
February: "1",
January: "1",
Year: "2023"
}]
My expected result would be:
[{
February: "1",
January: "1",
Year: "2023"
}, {
February: "1",
January: "1",
Year: "2025"
}]
$(document).ready(function() {
addTab();
});
$('#add_tab').click(function() {
addTab()
});
//delete current tab
$(".nav-tabs").on("click", "span", function() {
var anchor = $(this).siblings('a');
console.log(anchor)
$(anchor.attr('href')).remove();
$(this).parent().remove();
$(".nav-tabs").children('a').first().click();
});
function addTab() {
var nextTab = $(".nav-tabs").children().length;
var date = new Date().getFullYear() + nextTab;
// create the tab
$('<a class="nav-link" href="#tab-' + date + '" data-toggle="tab">' + date + '</a><span> x </span>').appendTo('#tabs');
// create the tab content
var html = "";
html += '<div class="tab-pane monthSettings" id="tab-' + date + '">';
html += '<label><b>Year: </b></label>';
html += '<input class="txtYear" type="text" value="' + date + '">';
html += '<label><b>January: </b></label>';
html += '<input class="txtJanuary" type="number" value="1">';
html += '<label><b>February: </b></label>';
html += '<input class="txtFebruary" type="number" value="1">';
html += '</div>';
//append to tab-content
var test = $(html).appendTo('.tab-content');
// make the new tab active
$('#tabs a:last').tab('show');
}
//get array
$(document).on('click', '#btnGetArray', function(e) {
var array = []
$(".monthSettings").each(function() {
let detail = {
Year: $(".txtYear").val() || 0,
January: $(".txtJanuary").val() || 0,
February: $(".txtFebruary").val() || 0,
}
array.push(detail)
console.log(array)
});
});
#import url('http://getbootstrap.com/2.3.2/assets/css/bootstrap.css');
.container {
margin-top: 10px;
}
.nav-tabs>a {
display: inline-block;
position: relative;
margin-right: 10px;
}
.nav-tabs>a>span {
display: none;
cursor: pointer;
position: absolute;
right: 6px;
top: 8px;
color: red;
}
.nav-tabs>a>span {
display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript" src="https://getbootstrap.com/2.3.2/assets/js/bootstrap.js"></script>
<link rel="stylesheet" type="text/css" href="https://getbootstrap.com/2.3.2/assets/css/bootstrap.css">
<div class="bg-gray-300 nav-bg">
<nav class="nav nav-tabs" id="tabs">
+ Add Year
</nav>
</div>
<div class="card-body tab-content"></div>
<button id="btnGetArray">GetData</button>
The issue is because your selectors for retrieving the .txtYear, .txtJanuary and .txtFebruary will only look at the value of the first element in the collection, no matter how many it finds.
To correct this you can use find() from the parent element, which you can reference from the each() loop, to retrieve the child elements in that iteration.
Taking this a step further, you can simplify the logic by using map() instead of each() to build your array, but the use of find() remains the same.
In addition, there's some other improvements which can be made to the code, such as ensuring all event handlers are within document.ready and using template literals to make the HTML string concatenation easier to read.
jQuery($ => {
$('#add_tab').on('click', addTab);
addTab();
$(".nav-tabs").on("click", "span", function() {
var anchor = $(this).siblings('a');
console.log(anchor)
$(anchor.attr('href')).remove();
$(this).parent().remove();
$(".nav-tabs").children('a').first().click();
});
$(document).on('click', '#btnGetArray', e => {
var array = $(".monthSettings").map((i, container) => ({
Year: $(container).find('.txtYear').val() || 0,
January: $(container).find('.txtJanuary').val() || 0,
February: $(container).find('.txtFebruary').val() || 0,
})).get();
console.log(array);
});
});
function addTab() {
var nextTab = $(".nav-tabs").children().length;
var date = new Date().getFullYear() + nextTab;
$(`<a class="nav-link" href="#tab-${date}" data-toggle="tab">${date}</a><span> x </span>`).appendTo('#tabs');
var html = `
<div class="tab-pane monthSettings" id="tab-${date}">
<label><b>Year: </b></label>
<input class="txtYear" type="text" value="${date}" />
<label><b>January: </b></label>
<input class="txtJanuary" type="number" value="1" />
<label><b>February: </b></label>
<input class="txtFebruary" type="number" value="1" />
</div>`
var test = $(html).appendTo('.tab-content');
// make the new tab active
$('#tabs a:last').tab('show');
}
#import url('http://getbootstrap.com/2.3.2/assets/css/bootstrap.css');
.container {
margin-top: 10px;
}
.nav-tabs>a {
display: inline-block;
position: relative;
margin-right: 10px;
}
.nav-tabs>a>span {
display: none;
cursor: pointer;
position: absolute;
right: 6px;
top: 8px;
color: red;
}
.nav-tabs>a>span {
display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script type="text/javascript" src="https://getbootstrap.com/2.3.2/assets/js/bootstrap.js"></script>
<link rel="stylesheet" type="text/css" href="https://getbootstrap.com/2.3.2/assets/css/bootstrap.css">
<div class="bg-gray-300 nav-bg">
<nav class="nav nav-tabs" id="tabs">
+ Add Year
</nav>
</div>
<div class="card-body tab-content"></div>
<button id="btnGetArray">GetData</button>

Display div 5 seconds after button click

I want to show a block 5 seconds after clicking the button. My current code doesn't work. What's the problem?
if ($('#identify').click(function() {
setTimeout(function() {
document.getElementById('block1').classList.remove('hide');
}, 5000);
}));
.hide {
display: none
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="submit" id="identify" class="btn btn-primary" style="padding: 10px;">Identify</button>
<div class="slideRight expandUp hide" id="block1">Text Appears</div>
Event handlers in JS don't work as you're expecting; ie. by checking state in if conditions.
Instead you should attach event handler functions to the elements which will run when the specific event occurs. This is how your code should be structured:
jQuery($ => {
$('#identify').on('click', function() {
setTimeout(function() {
$('#block1').removeClass('hide');
}, 5000);
});
});
.hide { display: none; }
#identify { padding: 10px; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="submit" id="identify" class="btn btn-primary">Identify</button>
<div class="slideRight expandUp hide" id="block1">Text Appears</div>
Note the inclusion of a document.ready handler in the above code, and also moving the inline CSS in to the stylesheet.
Try this code:
$(document).ready(function(){
$('#identify').click(function() {
setTimeout(function(){
document.getElementById('block1').classList.remove('hide');
}, 5000);
});
});
Below code will show taht div immediate and then it hide the text and then it reappers after 5 sec as in your question.
<script>
$('#identify').click(function() {
$("#block1").removeClass('hide');
setTimeout(function(){
$("#block1").addClass('hide');
}, 1000);
setTimeout(function(){
$("#block1").removeClass('hide');
}, 6000);
});
</script>

Vue 2 raw HTML bind to textarea

I'm creating an online text editor. I need to be able to get the users text from the textarea's tag, manipulate this text and bind it back to the textarea, but with HTML in it.
Example:
<textarea v-model="someText"></textarea>
Where someText is set to:
someText: '<b>bold</b>.. not bold'
and should display like:
bold.. not bold
instead of: <b>bold</b>.. not bold
I have a feeling this isn't possible with the textarea tag, but what would be a way to do this?
Typically you would use v-html, but you are correct, inside <textarea> the value will be raw, not processed (will not be bold).
To achieve what you want, maybe you could leverage the contenteditable property to create a <html-textarea>, as below.
Vue.component('html-textarea',{
template:'<div contenteditable="true" #input="updateHTML"></div>',
props:['value'],
mounted: function () {
this.$el.innerHTML = this.value;
},
methods: {
updateHTML: function(e) {
this.$emit('input', e.target.innerHTML);
}
}
});
new Vue({
el: '#app',
data: {
message: 'H<b>ELLO</b> <i>editable</i> Vue.js!'
}
});
div[contenteditable] { border: 1px solid lightblue; }
<script src="https://unpkg.com/vue"></script>
<div id="app">
<html-textarea v-model="message"></html-textarea>
<hr>
<div>
Raw message:
<pre>{{ message }}</pre>
</div>
</div>
I'd have done it this way.
<template>
<div id="app">
<form name="yourform">
<textarea v-model="someText"></textarea>
</form>
</div>
</template>
<script>
export default {
name: 'app',
data () {
return {
someText: 'bold'
}
}
}
</script>
<style scopped>
textarea
{
font-weight:bold;
}
</style>

Jquery autocomplete css error

I am trying to create a jquery autcomplete in ASP.NET MVC, but I have a problem: the results list is not sticking under the input textbox. Here is a printscreen:
http://prntscr.com/c1voo4
This is my HTML :
<link href="#Url.Content("~/Content/themes/base/jquery.ui.all.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/jquery-1.10.2.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery-ui-1.8.11.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/autocomplete.js")" type="text/javascript"></script>
<div>
#using (#Html.BeginForm("Index", "Home", FormMethod.Post))
{
<div class="ui-widget autocomplete-div">
#Html.TextBox("term", null, new
{
id = "autocomplete-textbox",
#class = "form-control",
placeholder = "Enter Name.."
})
<button type="submit" value="Search" class="btn btn-primary" id="autocomplete-button">
<span class="glyphicon glyphicon-search"></span>
</button>
</div>
}
</div>
<script>
$(function () {
$('#autocomplete-textbox').autocomplete({
source: '#Url.Action("AutoComplete")',
minlength: 1
});
});
<script>
And this is my CSS:
#autocomplete-button{
width: 3.5%;
display: inline;
background-color: orangered;
border-color: orangered;
}
#autocomplete-textbox{
width: 17.5%;
display: inline
}
I implemented JQuery Autocomplete in this way and it is working perfectly for me..
$(function(){
var url = '#Url.Action("GetData", "Home")';
$('#txtData').autocomplete({
source: function (request, response) {
$.ajax({
url: url,
data: { 'Prefix': request.term },
type: 'GET',
async: false,
cache: false,
dataType: 'json',
success: function (json) {
response($.map(json, function (data, id) {
return {
label: data,
value: data
};
}));
},
error: function (xmlHttpRequest, textStatus, errorThrown) {
console.log('some error occured', textStatus, errorThrown);
}
});
}
})

Polymer: Bind custom-element's data to main document

I have create a custom element to show chat list as follows:
<dom-module id="contact-element">
<style>
--paper-card: {
width: 100%;
}
.edit{
display: block;
}
.last{
color: #A7A7A7;
font-size: 14px;
margin-top: 4px;
}
</style>
<template>
<template is="dom-repeat" items="{{contacts}}">
<div>
<paper-card class="contactcard" on-click="setUser">
<div class="card-content">
<div>{{ item.name }}</div>
<div class="last">{{ item.last }}</div>
</div>
</paper-card>
</div>
</template>
</template>
<script>
HTMLImports.whenReady(function () {
Polymer({
is: 'contact-element',
properties: {
user: {
type: Object,
},
username: {
type: String,
reflectToAttribute: true,
}
},
ready: function(){
this.contacts = [
{name: "Rajat",last: "How are you!", unread: 1},
{name: "Neeraj",last: "Okay", unread: 0},
{name: "Vaibhav"},
{name: "Rohit"},
{name: "Hitesh"},
];
},
setUser: function(e){
var model = e.model;
this.user = model.get('item');
this.username = this.user.name;
console.log("user set: "+model.get('item.name'));
}
});
});
</script>
</dom-module>
And I want that when a user clicks on any of the object, the toolbar should get the name. For that I'm using:
<paper-toolbar>
<paper-icon-button icon="menu" paper-drawer-toggle paper-drawer-left></paper-icon-button>
<span class="flex"></span>
<!-- Title -->
<div class="app-name flex">[[ pagetitle ]]</div>
<paper-icon-button icon="add-alert"></paper-icon-button>
<paper-icon-button icon="question-answer" paper-drawer-toggle paper-drawer-right></paper-icon-button>
</paper-toolbar>
But it's not working. Any help?
I solve this by putting notify='true' into the script tag like this:
properties: {
user: {
type: Object,
notify: true
},
username: {
type: String,
reflectToAttribute: true,
}
},
Notify lets the data change event bounce up, to the element housing our custom element.