I know there are already some discussions about this topic, but I can’t find the right solution.In all the approaches you just grab your span and your inputfield, then call a new variable input value and then ,using text content = value it should work, but in my case it doesn’t.Probably I’m missing something.This is my html
<div class="wrapper" id="wrapper">
<div class="settings-panel" id ="settings-panel">
<div class="settings-panel-wrapper">
<!----close button !---->
<div class="firstline">
<h3>Clock settings</h3>
<div id="close-button">
<img id="close-image" src="{% static 'media/cancel.png' %}" alt="cancel">
</div>
</div>
<hr>
<!----close button !---->
<div id="time-box">
<span class="description">Time(in minutes)</span>
<div class="timeslots" id="timeslots">
<div id="pomodoro">
<label>Pomodoro</label>
<input id="time-study-input "type="number" min="0"step="1" value="40">
</div>
<div id="Short-Break">
<label>Short Break</label>
<input id="short-break-input "type="number" min="0" step="1" value="5">
</div>
<div id="Long-Break">
<label>Long Break</label>
<input id="long-break-input "type="number" min="0" step="1" value="15">
</div>
</div>
<button id="save-changes" onclick="savechanges()">Save changes</button>
</div>
</div>
</div>
<div class="clock-container" id ="clock-container">
<div class="features-clock">
<button id="settings-button">Settings</button>
</div>
<div class="countdown-container">
<span id=countdown-timer-study></span>
</div>
</div>
</div>
this is script.js(probably you don’t need css)
const settings_panel = document.getElementById("settings-panel");
const settings_button= document.querySelector("#settings-button");
const wrapper = document.getElementById("wrapper");
const close_button = document.getElementById("close-button");
const body = document.querySelector("body");
const big_wrapper = document.getElementById("big-wrapper");
var time_study_input = document.getElementById("time-study-input");
var short_break_input = document.getElementById("short-break-input");
var long_break_input = document.getElementById("long -break-input");
var countdown_timer_study= document.getElementById("countdown-timer-study");
settings_button.addEventListener("click", ()=>{
settings_panel.style.display="block";
wrapper.style.backgroundColor ="rgba(0,0,0,0.3)";
})
close_button.addEventListener("click", () => {
settings_panel.style.display = "none";
wrapper.style.backgroundColor = "rgba(221, 217, 217, 0)";
})
function savechanges(){
var time_study_value = time_study_input.value;
countdown_timer_study.textContent =time_study_value;
settings_panel.style.display = "none";
wrapper.style.backgroundColor = "rgba(221, 217, 217, 0)";
}
as you can see I am trying to build a pomodoro app so when the user wants to customize the timer I can grab the input value and insert it into the span that is going to represent the time limit(as you can see I also setup a default value of 40, is this the right way to do it?).I am trying to improve my front-end skills which are definitely terrible, so any tip about code simplification (pointing out which parts are redundant or inefficient) is very welcome.
Your problem is extremely subtle. You have an extra space at the end of the id time-study-input. Try this:
<div id="pomodoro">
<label>Pomodoro</label>
<input id="time-study-input" type="number" min="0"step="1" value="40">
</div>
Related
I'm in need of getting a working search bar for these cards (only one included in the code to save space), the js I've been using worked fine for now, but recently I had to add a new div (with class sce-all) which made it search only some of the items or actually too many from different divs and makes the other info into display:none when I search for anything from div (with class sce-e). When I try to search anything right now, it also searches from div (with class sce-e), I only need it to search from div (with class sce-tt) or it could be both, but it gives it the display:none tag currently. I tried changing up the ('.card div:nth-child(2)') in the js which is the cause of the problem it seems.
Thanks for any help
const searchEl = document.querySelector('.searchbox');
const x = document.querySelectorAll('.card div:nth-child(2)');
function search(e) {
x.forEach((item, index) => {
if (!item.innerHTML.toLowerCase().includes(e.target.value)) {
item.parentElement.style.display = 'none';
} else {
item.parentElement.style.display = 'block';
}
})
}
searchEl.addEventListener("keyup", search);
<form class='searchbox'>
<input class="searchbar" type="text" placeholder="Search.." name="search">
</form>
<div class="main-container">
<div class="cards-vid">
<div class="video anim card">
<div class="video-wrapper">
<div class="video-wrapper-inside">
<a href="vid.mp4"><video preload="metadata">
<source src="vid.mp4#t=139" type="video/mp4">
</video></a>
</div>
</div>
<div class="sce-all">
<div class="sce-e">Link Title<span class="length-t">0ms</span></div>
<div class="sce-tt">Title</div>
</div>
<div class="tags-and-info">
<div class="tags"><a><span class="category-tag">Main</span></a><span class="language-edit">ENG</span></div>
<hr class="sce-hr">
<div class="sce-inf">Info<span class="seperate video-seperate"></span>0h 46m<span class="seperate video-seperate"></span>2023</div>
</div>
</div>
</div>
</div>
Change x to just select the .sce-tt divs. Then when it decides whether to hide or show the parent, use closest('.card') to find the containing card, rather than specifying .parent.
const searchEl = document.querySelector('.searchbox');
const x = document.querySelectorAll('.card .sce-tt');
function search(e) {
x.forEach((item, index) => {
if (!item.innerHTML.toLowerCase().includes(e.target.value)) {
item.closest(".card").style.display = 'none';
} else {
item.closest(".card").style.display = 'block';
}
})
}
searchEl.addEventListener("keyup", search);
<form class='searchbox'>
<input class="searchbar" type="text" placeholder="Search.." name="search">
</form>
<div class="main-container">
<div class="cards-vid">
<div class="video anim card">
<div class="video-wrapper">
<div class="video-wrapper-inside">
<a href="vid.mp4"><video preload="metadata">
<source src="vid.mp4#t=139" type="video/mp4">
</video></a>
</div>
</div>
<div class="sce-all">
<div class="sce-e">Link Title<span class="length-t">0ms</span></div>
<div class="sce-tt">Title</div>
</div>
<div class="tags-and-info">
<div class="tags"><a><span class="category-tag">Main</span></a><span class="language-edit">ENG</span></div>
<hr class="sce-hr">
<div class="sce-inf">Info<span class="seperate video-seperate"></span>0h 46m<span class="seperate video-seperate"></span>2023</div>
</div>
</div>
</div>
</div>
in my WordPress site i created java bootstrap loan calculator its working perfectly on desktop but when i use mobile chrome its not working. i tried with wp-coder plugin and try with manually adding this. in chrome dev tools mobile view its working fine with the real devise this issue occured.is there any way to resolve this issue i much appreciate you help to resolve this issue
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.min.css"
/>
<div class="columns is-12-tablet is-6-desktop is-3-widescreen" style="height: 500px; width:100% " >
<div class="column w-50 p-3 " >
<div class="card w-50 p-3">
<div class="card-content w-50 p-3">
<form id="loan-form">
<div class="level w-50 p-3">
<div class="level-left is-marginless w-50 p-3s">
<div class="level-item">
<p class="number">1</p>
<p> Loan Amount </p>
<p id="yearssliderfuc"> </p>
</div>
</div>
</div>
<input id="amount" type="range" min="20000" max="200000" step="10000" onchange="yrthslide();computeResults()" />
<div class="level">
<div class="level-left is-marginless">
</div>
<div class="level-right">
<div class="level-item">
<div class="field">
<div class="control has-icons-right">
<span class="icon is-small is-right">
</span>
</div>
</div>
</div>
</div>
</div>
<div class="level">
<!-- Left side -->
<div class="level-left is-marginless">
<div class="level-item">
<p class="number">2</p>
<p> Number Of Days </p>
<p id="monthssliderfuc"> </p>
</div>
</div>
</div>
<input id="years" min="30" max="120" step="30" type="range" onchange="monthslide();computeResults()" />
<div class="control">
<br>
</div>
</form>
</div>
</div>
<div >
<div class="notification is-link has-text">
<p id="totalPayment" class="title ">LKR</p>
<p class="subtitle is-4">Total Amount</p>
</div>
</div>
<div >
</div>
</div>
<script >
function computeResults(e) {
// UI
const UIamount = document.getElementById("amount").value;
/* var UIinterest = 50
if(UIamount> 50){
var UIinterest = 50
}*/
if(UIamount<50000){
var UIinterest = 16/100;
}else if(UIamount>50000 && amount<90000){
UIinterest = 18/100;
}else if(UIamount>100000 && amount<140000){
UIinterest = 20/100;
}else{
UIinterest = 22/100
}
const UIyears = document.getElementById("years").value;
var interestperday = (UIamount * UIinterest)/365;
console.log(interestperday);
console.log("interest per day");
const monthly = parseFloat(interestperday);
const monthlyPayment = monthly.toFixed(2);
var interest = interestperday*UIyears;
const interestfinalee = parseFloat(interest);
console.log(interestfinalee);
console.log("interest all time");
var ProFees = (UIamount*10)/100;
const ProFeesfin = parseFloat(ProFees);
console.log(ProFeesfin);
console.log("ProFees");
var DocHFees = (UIamount*5)/100;
const DocHFeesfin = parseFloat(DocHFees);
console.log(DocHFeesfin);
console.log("DocHFees");
var TransFee = (UIamount*5)/100;
const TransFeefin = parseFloat(TransFee);
console.log(TransFeefin);
console.log("TransFee");
const UIamountfin = parseFloat(UIamount);
// Calculating total payment
const all = TransFeefin + DocHFeesfin + ProFeesfin + interestfinalee + UIamountfin
console.log(all);
console.log("allallallallallallallallallallallallallall");
///*****************************************************
const totalPayment = all.toFixed(2);
document.getElementById("totalPayment").innerHTML = "LKR " + totalPayment;
e.preventDefault();
}
function monthslide(){
var Monthslider = document.getElementById("years").value
document.getElementById("monthssliderfuc").innerHTML = Monthslider;
}
function yrthslide(){
var Monthslider = document.getElementById("amount").value
document.getElementById("yearssliderfuc").innerHTML = Monthslider;
}
</script>
You are using the "computeResults()" function, but "computeResults()" function is not defined and the "Calculate()" function is not being used.
Update: Add other details, after the code has been updated:
e.preventDefault() function is not defined and that generates the issue, I removed that and it already works in mobile.
problem resolved.
its because of same function name for mobile view and desktop view after changing the function names its resolved
I want the button with the id #show-text-area execute the postButton(); function only once so it won't create a second elements whenever clicked (i want it to create it for only one time and won't work again until clicked another button).
Hope my question was clear enough.
HTML
<div id="post-creator" class="creator-container">
<div class="post-type">
<div class="text-post" id="post">
<button onclick="postButton();">Post</button>
</div>
<div class="media-post">Image & Video</div>
<div class="link-post">Link</div>
</div>
<div class="post-title">
<input type="text" class="title-text" name="post-title" placeholder="Title">
</div>
<div class="post-content">
</div>
<div class="post-footer">
<div class="spoiler">Spoiler</div>
<div class="nsfw">NSFW</div>
<button class="post">post</button>
</div>
</div>
Javascript
let postButton = function() {
let textarea = document.createElement('textarea');
textarea.setAttribute('class', 'post-data');
textarea.setAttribute('placeholder', 'Text (optional)');
document.querySelector('.post-content').appendChild(textarea);
}
You could disable the button after activation, this has the benefit of informing the user that further clicks won't do anything.
let postButton = function() {
let textarea = document.createElement('textarea');
textarea.setAttribute('class', 'post-data');
textarea.setAttribute('placeholder', 'Text (optional)');
document.querySelector('.post-content').appendChild(textarea);
document.getElementsByTagName("button")[0].disabled = true;
}
Otherwise you could simply have the function short-circuit if it has already been called.
// alreadyPosted is scoped outside of the function so it will retain its value
// across calls to postButton()
let alreadyPosted = false;
let postButton = function() {
// do nothing if this isn't the first call
if (alreadyPosted) { return; }
// mark the function as called
alreadyPosted = true;
let textarea = document.createElement('textarea');
textarea.setAttribute('class', 'post-data');
textarea.setAttribute('placeholder', 'Text (optional)');
document.querySelector('.post-content').appendChild(textarea);
document.getElementsByTagName("button")[0].disabled = true;
}
The following works.
let postButton = function(event) {
event.target.disabled = true;
let textarea = document.createElement('textarea');
textarea.setAttribute('class', 'post-data');
textarea.setAttribute('placeholder', 'Text (optional)');
document.querySelector('.post-content').appendChild(textarea);
};
document.getElementById('post').addEventListener('click', postButton);
<div id="post-creator" class="creator-container">
<div class="post-type">
<div class="text-post" id="post">
<button>Post</button>
</div>
<div class="media-post">Image & Video</div>
<div class="link-post">Link</div>
</div>
<div class="post-title">
<input type="text" class="title-text" name="post-title" placeholder="Title">
</div>
<div class="post-content">
</div>
<div class="post-footer">
<div class="spoiler">Spoiler</div>
<div class="nsfw">NSFW</div>
<button class="post">post</button>
</div>
</div>
You can also use hide show function on textarea if you do not want to create one.
let postButton = function() {
let d = document.getElementById('post_data').style.display;
if(d=='none'){
document.getElementById('post_data').style.display = 'block';
}
}
document.getElementById('post_data').style.display = 'none';
document.getElementById('post_btn').addEventListener('click', postButton);
<div id="post-creator" class="creator-container">
<div class="post-type">
<div class="text-post">
<button id="post_btn">Post</button>
</div>
<div class="media-post">Image & Video</div>
<div class="link-post">Link</div>
</div>
<div class="post-title">
<input type="text" class="title-text" name="post-title" placeholder="Title">
</div>
<div class="post-content">
<textarea class="post-data" id="post_data" placeholder="Text (optional)"></textarea>
</div>
<div class="post-footer">
<div class="spoiler">Spoiler</div>
<div class="nsfw">NSFW</div>
<button class="post">post</button>
</div>
</div>
I am trying to build a simple on page search that uses event listeners to look at a containers data and then hides that whole container if it doesn't have the required information.
So far I have:
// get search element
let searchInput = document.getElementById ('searchInput');
// add event listener
searchInput.addEventListener ('keyup', searchPage);
function searchPage(){
//search input detection
let searchValue = document.getElementById('searchInput').value;
//set parameters to search from
let parent = document.getElementById('product-container');
let child = parent.getElementsByTagName('span');
for(let i = 0;i < child.length;i++){
let a = child[i];
if(a.innerHTML.indexOf(searchValue) >= -1) {
child[i].parentNode.style.display = '';
} else {
child[i].parentNode.style.display = 'none';
};
};
};
But this only acts on the first product-container it finds, there are 5 such containers on the page.
How do I make this look through all containers, but hide the ones that don't contain any of the information typed in the search bar.
I am getting products from an API so using html replace to add to the following template:
<script id="template" type="text/template">
<div class="product">
<div class="product--header">{{ type }}</div>
<div class="product--image"><img src="../app/assets/images/no-image.png" alt="no image"> </div>
<div class="product--information" id="product--information">
<div class="product--title"><span>{{ name }}</span></div>
<!--This is just a place holder we would house the prices here if they were on the API -->
<div class="product--price">£55</div>
<div class="product--brand"><strong>Brand:</strong><span> {{ brand }}</span></div>
<div class="product--colour"><strong>Colour:</strong><span> {{ colour }}</span></div>
<div class="product--sizes">
<select>
<option value="" disabled selected>Select Size </option>
{{ options }}
</select>
</div>
<div class="product--description"><strong>Description:</strong><br><div class="product--description__content"><span> {{ description }} </span></div></div>
<div class="product--code"><strong>Product ID:</strong><span> {{ productid }}</span></div>
<div class="product--buttons">
<button class="btn--buy" aria-label="Add to Basket">Add to basket</button>
<button class="btn--save" aria-label="Save for Later">Save for later</button>
</div>
<button class="product--add-to-wishlist" aria-label="Add to Wishlist"><i class="fas fa-heart"></i></button>
</div>
</div>
</script>
The search box code is as follows:
<input type="text" name="search" id="searchInput" placeholder="Enter Search...">
and the code that the template goes into is:
<div id="product-container">
<div class="featured"></div>
<div class="products"></div>
</div>
Because you have multiple product containers, use document.getElementsByClassName() instead of document.getElementById() and provide product-container class as argument.
let searchInput = document.getElementsByClassName ('container');
You need to modify searchPage() method. Instead of using document to find searchValue and parent use this.
let searchValue = this.getElementsByClassName('searchInput')[0].value;
let parent = this.getElementsByClassName('container')[0];
Please, add HTML code.
EDIT: If I understand correctly you have one search input which will search multiple product containers. Here is one simple example, which you can easily apply to your problem.
HTML:
<input type="text" name="search" id="searchInput" placeholder="Enter Search...">
<div class="product-container">
<span class="product">Kiwi</span>
<p>Kiwi description</p>
</div>
<div class="product-container">
<span class="product">Banana</span>
<p>Banana description</p>
</div>
<div class="product-container">
<span class="product">Apple</span>
<p>Apple description</p>
</div>
JS:
let searchInput = document.getElementById ('searchInput');
searchInput.addEventListener ('keyup', searchPage);
function searchPage(){
let searchValue = this.value.toUpperCase();
let products = document.getElementsByClassName('product');
for(let i = 0; i < products.length; i++) {
console.log(products[i].innerHTML.toUpperCase());
if (products[i].innerHTML.toUpperCase().indexOf(searchValue) > -1)
products[i].parentNode.style.display = '';
else
products[i].parentNode.style.display = 'none';
};
};
CSS:
.product-container {
display: flex;
flex-direction: column;
margin-bottom: 10px;
background: grey;
}
.product-container span {
font-size: 20px;
}
.product {
display: block;
}
https://jsfiddle.net/gardelin/koc5eg6v/25/
I am very new to the smart table. I have gone through its documentation on Smart Table.
But the I haven't found how to bind data on click event in smart table?
Code is very big but I am trying to post it here.
<div class="table-scroll-x" st-table="backlinksData" st-safe-src="backlinks" st-set-filter="myStrictFilter">
<div class="crawlhealthshowcontent">
<div class="crawlhealthshowcontent-right">
<input type="text" class="crserachinput" placeholder="My URL" st-search="{{TargetUrl}}" />
<a class="bluebtn">Search</a>
</div>
<div class="clearfix"></div>
</div>
<br />
<div class="table-header clearfix">
<div class="row">
<div class="col-sm-6_5">
<div st-sort="SourceUrl" st-skip-natural="true">
Page URL
</div>
</div>
<div class="col-sm-2">
<div st-sort="SourceAnchor" st-skip-natural="true">
Anchor Text
</div>
</div>
<div class="col-sm-1">
<div st-sort="ExternalLinksCount" st-skip-natural="true">
External<br />Links
</div>
</div>
<div class="col-sm-1">
<div st-sort="InternalLinksCount" st-skip-natural="true">
Internal<br />Links
</div>
</div>
<div class="col-sm-1">
<div st-sort="IsFollow" st-skip-natural="true">
Type
</div>
</div>
</div>
</div>
<div class="table-body clearfix">
<div class="row" ng-repeat="backlink in backlinksData" ng-if="backlinks.length > 0">
<div class="col-sm-6_5">
<div class="pos-rel">
<span class="display-inline wrapWord" tool-tip="{{ backlink.SourceUrl }}"><b>Backlink source:</b> <a target="_blank" href="{{backlink.SourceUrl}}">{{ backlink.SourceUrl }}</a></span><br />
<span class="display-inline wrapWord" tool-tip="{{ backlink.SourceTitle }}"><b>Link description:</b> {{ backlink.SourceTitle }}</span> <br />
<span class="display-inline wrapWord" tool-tip="{{ backlink.TargetUrl }}"><b>My URL:</b> <a target="_blank" href="{{backlink.TargetUrl}}">{{ backlink.TargetUrl }}</a></span><br />
</div>
</div>
<div class="col-sm-2">
<div class="pos-rel">
{{ backlink.SourceAnchor }}
</div>
</div>
<div class="col-sm-1">
<div>
{{ backlink.ExternalLinksCount }}
</div>
</div>
<div class="col-sm-1">
<div>
{{ backlink.InternalLinksCount }}
</div>
</div>
<div class="col-sm-1">
<div ng-if="!backlink.IsFollow">
No Follow
</div>
</div>
</div>
<div class="row" ng-if="backlinks.length == 0">
No backlinks exists for selected location.
</div>
</div>
<div class="pos-rel" st-pagination="" st-displayed-pages="10" st-template="Home/PaginationCustom"></div>
</div>
and my js code is here.
module.controller('backlinksController', [
'$scope','$filter', 'mcatSharedDataService', 'globalVariables', 'backlinksService',
function ($scope,$filter, mcatSharedDataService, globalVariables, backlinksService) {
$scope.dataExistsValues = globalVariables.dataExistsValues;
var initialize = function () {
$scope.backlinks = undefined;
$scope.sortOrderAsc = true;
$scope.sortColumnIndex = 0;
};
initialize();
$scope.itemsByPage = 5;
var updateTableStartPage = function () {
// clear table before loading
$scope.backlinks = [];
// end clear table before loading
updateTableData();
};
var updateTableData = function () {
var property = mcatSharedDataService.PropertyDetails();
if (property == undefined || property.Primary == null || property.Primary == undefined || property.Primary.PropertyId <= 0) {
return;
}
var params = {
PropertyId: property.Primary.PropertyId
};
var backLinksDataPromise = backlinksService.getBackLinksData($scope, params);
$scope.Loading = backLinksDataPromise;
};
mcatSharedDataService.subscribeCustomerLocationsChanged($scope, updateTableStartPage);
}
]);
module.filter('myStrictFilter', function ($filter) {
return function (input, predicate) {
return $filter('filter')(input, predicate, true);
}
});
But It is working fine with the direct search on textbox.
but according to the requirement I have to perform it on button click.
Your suggestions and help would be appreciated.
Thanks in advance.
You can search for a specific row by making some simple tweaks.
add a filter to the ng-repeat, and filter it by a model that you will insert on the button click, like so: <tr ng-repeat="row in rowCollection | filter: searchQuery">
in your view, add that model (using ng-model) to an input tag and define it in your controller
then pass the value to the filter when you click the search button
here's a plunk that demonstrates this
you can use filter:searchQuery:true for strict search
EDIT:
OK, so OP's big problem was that the filtered values wouldn't show properly when paginated, the filter query is taken from an input box rather then using the de-facto st-search plug-in, So I referred to an already existing issue in github (similar), I've pulled out this plunk and modified it slightly to fit the questioned use case.