Total number of words will display in the top of Textarea., when i enter or paste some words.
Actually, I gotta total number of words, when i used the element <textarea id="text"></text>.
But i can not get the total number of word using <div id="text"></div>
Is it possible to count all the words within a element <div id="text"></div>?
JS for counting words.
counter = function() {
var value = $('#text').val();
if (value.length == 0) {
$('#wordCount').html(0);
return;
}
var regex = /\s+/gi;
var wordCount = value.trim().replace(regex, ' ').split(' ').length;
$('#wordCount').html(wordCount);
};
$(document).ready(function() {
$('#text').change(counter);
$('#text').keydown(counter);
$('#text').keypress(counter);
$('#text').keyup(counter);
$('#text').blur(counter);
$('#text').focus(counter);
});
Could someone help me to solve this?
The issue is because val() will retrieve the value of a textarea without a problem, however a div does not have a value property.
For this to work with div elements, you should change val() to text():
var value = $('#text').text();
I guess you need this:
counter = function() {
var value = $('#text').text(); //<----change .val() to .text()
if (value.length == 0) {
$('#wordCount').html(0);
return;
}
var regex = /\s+/gi;
var wordCount = value.trim().replace(regex, ' ').split(' ').length;
$('#wordCount').html(wordCount);
};
$(document).ready(function() {
counter(); //<---call the function here.
});
You need to call the function on dom ready because all the events you bound on the div needs some event to be happend by the user.
Use text instead of val:
var value = $.trim($('#text').text());
val will give you the value attribute value. Whereas text will give you the innerText of the element(div).
Optimization
var counter = function () {
var value = $.trim($(this).text()); // Trim spaces
if (value.length === 0) {
$('#wordCount').text(0);
return;
}
var wordCount = value.replace(/\s+/g, ' ').split(' ').length;
$('#wordCount').text(wordCount);
};
$(document).ready(function () {
$('#text').on('change keydown keypress keyup blur focus', counter);
});
Related
I tried searching, but am not finding a solution.
I am currently using Jquery autocomplete, along with an external service that stores the lists of possible returned results. The autocomplete is being done on a textarea, and I need to try to autocomplete for each line of text. So the user types one line, gets auto complete. Goes to a new line, starts typing, autocomplete appears only for what's on that line.
The set up is pretty standard to what JQuery shows off. I.E.:
<textarea id="entities"></textarea>
JS:
$("#entities").autocomplete({
serviceUrl: [the service url],
paramName: 'prefix'
});
I know there are ways to determine line number and get the value of a specific line such as:
$("#entities").on('keyup', function() {
var textLines = $("#entities").val().substr(0, $("#entities").selectionStart).split("\n");
var currentLineNumber = textLines.length - 1;
console.log(lines[currentLineNumber]);
});
But I'm not sure how I could call the autocomplete function upon typing a new line.
Edit: Someone suggested using contentEditable, but this results in different wrappers for each line depending on the browser.
<div id="entities" class="entities-text" contenteditable="true"></div>
IE converts each line to:
<p>Line 1</p>
<p>Line 2</p>
FF shows:
Line 1<br>
Line 2<br>
Chrome gives:
<div>Line 1</div>
<div>Line 2</div>
I am not so sure that you can achieve that so easily using a textarea and for each row of the textarea.
My suggestion is to switch to a contenteditable div, maybe formatted through CSS like a textarea if you want that style, then every time that you detect a new line, wrap the new line with an HTML element (for example a p).
Then just set the autocomplete to work with all the p elements inside that div.
Here you have a really good example on how to do that in case that you type a # (it's an autocomplete for email addresses).
Changing a bit the code, you will have your job pretty done.
autocomplete with contenteditable div instead of textarea doesn't seem to work
There is also a link to the jsfiddle example inside the post.
I think this Function help full to you ... complete your requirement.
function CreateTextAreaAutoFill(idstr, AutoFillAry) {
$("#" + idstr)
// don't navigate away from the field on tab when selecting an item
.on("keydown", function (event) {
if (event.keyCode === $.ui.keyCode.TAB &&
$(this).autocomplete("instance").menu.active) {
event.preventDefault();
}
})
.autocomplete({
minLength: 0,
source: function (request, response) {
// delegate back to autocomplete, but extract the last term
response($.ui.autocomplete.filter(
AutoFillAry, extractLast(request.term, idstr)));
},
focus: function () {
// prevent value inserted on focus
return false;
},
open: function (event, ui) {
// $(this).autocomplete('widget').find('li').css('font-size', '10px');
// $(this).autocomplete('widget').css('height', 100);
},
select: function (event, ui) {
//var terms = split(this.value);
//// remove the current input
//terms.pop();
//// add the selected item
//terms.push(ui.item.value);
//// add placeholder to get the comma-and-space at the end
//terms.push("");
//this.value = terms.join(" ");//terms.join(", ");
debugger;
var term = this.value;
var cursorPosition = $('#' + idstr).prop("selectionStart");
var SpaceInd = term.lastIndexOf(" ", (cursorPosition - 1));
// var SubStr = term.substring((SpaceInd + 1), cursorPosition);
var NewLineInd = term.lastIndexOf("\n", (cursorPosition - 1));
var SubStrInd = SpaceInd < NewLineInd ? NewLineInd : SpaceInd;
var FirstStr = this.value.substring(0, (SubStrInd + 1)) + ui.item.value;
this.value = FirstStr + this.value.substring(cursorPosition, this.value.length);
$('#' + idstr).prop('selectionEnd', FirstStr.length);
return false;
}
});
//function split(val) {
// // return val.split(/;\s*/);
// // return val.split(' ');
// var LineAry = val.split("\n");
// var FinalResult = [];
// $.each(LineAry, function (ind, Aval) {
// FinalResult = FinalResult.concat(Aval.split(' '));
// })
// return FinalResult;
//}
function extractLast(term, idstr) {
debugger;
var cursorPosition = $('#' + idstr).prop("selectionStart");
var SpaceInd = term.lastIndexOf(" ", (cursorPosition - 1));
var NewLineInd = term.lastIndexOf("\n", (cursorPosition - 1));
var SubStrInd = SpaceInd < NewLineInd ? NewLineInd : SpaceInd;
var SubStr = term.substring((SubStrInd + 1), cursorPosition);
return SubStr;//split(term).pop();
}
}
Am struggling hard to control an array object with list of span values using watcher in Angularjs.
It is partially working, when i input span elements, an array automatically gets created for each span and when I remove any span element -> respective row from the existing array gets deleted and all the other rows gets realigned correctly(without disturbing the value and name).
The problem is when I remove a span element and reenter it using my input text, it is not getting added to my array. So, after removing one span element, and enter any new element - these new values are not getting appended to my array.
DemoCode fiddle link
What am I missing in my code?
How can I get reinserted spans to be appended to the existing array object without disturbing the values of leftover rows (name and values of array)?
Please note that values will get changed any time as per a chart.
This is the code am using:
<script>
function rdCtrl($scope) {
$scope.dataset_v1 = {};
$scope.dataset_wc = {};
$scope.$watch('dataset_wc', function (newVal) {
//alert('columns changed :: ' + JSON.stringify($scope.dataset_wc, null, 2));
$('#status').html(JSON.stringify($scope.dataset_wc));
}, true);
$(function () {
$('#tags input').on('focusout', function () {
var txt = this.value.replace(/[^a-zA-Z0-9\+\-\.\#]/g, ''); // allowed characters
if (txt) {
//alert(txt);
$(this).before('<span class="tag">' + txt.toLowerCase() + '</span>');
var div = $("#tags");
var spans = div.find("span");
spans.each(function (i, elem) { // loop over each spans
$scope.dataset_v1["d" + i] = { // add the key for each object results in "d0, d1..n"
id: i, // gives the id as "0,1,2.....n"
name: $(elem).text(), // push the text of the span in the loop
value: 3
}
});
$("#assign").click();
}
this.value = "";
}).on('keyup', function (e) {
// if: comma,enter (delimit more keyCodes with | pipe)
if (/(188|13)/.test(e.which)) $(this).focusout();
if ($('#tags span').length == 7) {
document.getElementById('inptags').style.display = 'none';
}
});
$('#tags').on('click', '.tag', function () {
var tagrm = this.innerHTML;
sk1 = $scope.dataset_wc;
removeparent(sk1);
filter($scope.dataset_v1, tagrm, 0);
$(this).remove();
document.getElementById('inptags').style.display = 'block';
$("#assign").click();
});
});
$scope.assign = function () {
$scope.dataset_wc = $scope.dataset_v1;
};
function filter(arr, m, i) {
if (i < arr.length) {
if (arr[i].name === m) {
arr.splice(i, 1);
arr.forEach(function (val, index) {
val.id = index
});
return arr
} else {
return filter(arr, m, i + 1)
}
} else {
return m + " not found in array"
}
}
function removeparent(d1)
{
dataset = d1;
d_sk = [];
Object.keys(dataset).forEach(function (key) {
// Get the value from the object
var value = dataset[key].value;
d_sk.push(dataset[key]);
});
$scope.dataset_v1 = d_sk;
}
}
</script>
using angular i think you are going to want more on the html side of things particularly using ng-repeat and ng-click and ng-model first you would want to create your array which could simply be done in your code file or using ng-init. heres an example
(function(){
var app=angular.module('demoApp',[]);
app.controller('demoApp',[function(){
this.spans=[""];
this.currentSpan='';
this.addSpan=function(){
this.spans.push(this.currentSpan);
this.currentSpan='';
};
}]);
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='demoApp'>
<div ng-controller='demoApp as demo'>
<span ng-repeat='span in demo.spans track by $index' ng-click='demo.spans.splice($index,1)'>{{span}}</span><span>{{demo.currentSpan}}</span>
<textarea ng-model='demo.currentSpan' placeholder='new text'></textarea>
<button ng-click='demo.addSpan()' >add</button>
</div>
</div>
I have the following code: http://jsfiddle.net/ntywf/1987/
$(document).ready(function () {
$('input').keyup(function() {
var $th = $(this);
$th.val($th.val().replace(/[-]/g, function(str) {
//alert('You typed " ' + str + ' ".\n\nPlease use only letters and numbers.');
return '';
}));
});
});
what I want is to remove the "-" sign off when it is inserted. what happens is that the cursor is always the last decimal home. I just want this code not to let the user enter negative numbers. How can I do this? (the problem is to move the cursor within the input, since it is always sent to the last character)
You can use a KeyCode (Link) to verify what key you pressed, and use replace to remove it:
$('input').keyup(function(e) {
var code = e.keyCode || e.which;
if(code == 109 || code == 189) { //Enter keycode
//Do something
var valor = $(this).val();
$(this).val(valor.replace(/[-]/g, ''))
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="text"/>
Here what I have tried.
JS
$('input').keyup(function() {
var $th = $(this).val();
$th = $th.replace(/[-]/g, "");
$(this).val($th)
console.log( $(this).val());
});
It will remove - sign from data.
This should solve your problem
What I have done is:
I have used the inbuilt HTML input field method setSelectionRange(), which sets the start and end positions of the current text selection in an element. (From MDN)
MDN Reference : https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange
JS Code:
$(document).ready(function () {
$('input').keyup(function() {
var $th = $(this);
$th.val( $th.val().replace(/[-]/g, function(str) {
//alert('You typed " ' + str + ' ".\n\nPlease use only letters and numbers.');
return '';
} ) );
$('input')[0].setSelectionRange(0, 0); //this method sets the range to zero text starting from 0 index to 0 index
});
});
JSFiddle: http://jsfiddle.net/dreamweiver/ntywf/1998/
Use type = "numeric" and min="0" This way you can prevent your text-field from accepting alphabets as well. min=0 will always make sure that it will never accept -ve value.
<input type="number" min="0"/>
JSFIDDLE DEMO will be helpful to you.
I have the following JQuery code I am working on. When I test it, the expected values are shown in the span but not in the input text box.
JQ
$(function() {
$("#textbox").each(function() {
var input = '#' + this.id;
counter(input);
$(this).keyup(function() {
counter(input);
});
});
});
function counter(field) {
var number = 0;
var text = $(field).val();
var word = $(field).val().split(/[ \n\r]/);
words = word.filter(function(word) {
return word.length > 0 && word.match(/^[A-Za-z0-9]/);
}).length;
$('.wordCount').text(words);
$('#sentencecount').text(words);
}
Please see Fiddle. Please let me know where I have gone wrong. Still new to JS.
Thanks
Change this:
$('#sentencecount').text(words);
to this:
$('#sentencecount').val(words);
The .text() method cannot be used on form inputs or scripts. To set or get the text value of input or textarea elements, use the .val() method. To get the value of a script element, use the .html() method. -> http://api.jquery.com/text/
Trying using val() instead This should fix it up.
http://jsfiddle.net/josephs8/6B9Ga/8/
You can not set text to an input you must use value
try this.
$('#sentencecount').text(words);
//has to be
$('#sentencecount').val(words);
and i have also updated your Jsfiddle
$(function() {
$("#textbox").each(function() {
var input = '#' + this.id;
counter(input);
$(this).keyup(function() {
counter(input);
});
});
});
function counter(field) {
var number = 0;
var text = $(field).val();
var word = $(field).val().split(/[ \n\r]/);
words = word.filter(function(word) {
return word.length > 0 && word.match(/^[A-Za-z0-9]/);
}).length;
$('.wordCount').text(words);
$('#sentencecount').val(words);
}
I have the following structure:
<div id="campaignTags">
<div class="tags">Tag 1</div>
<div class="tags">Tag 2</div>
<div class="tags">Tag 3</div>
</div>
And I'm trying to match user input against the innerText of each children of #campaignTags
This is my latest attempt to match the nodes with user input jQuery code:
var value = "Tag 1";
$('#campaignTags').children().each(function(){
var $this = $(this);
if(value == $(this).context.innerText){
return;
}
The variable value is for demonstration purposes only.
A little bit more of context:
Each div.tags is added dynamically to div#campaignTags but I want to avoid duplicate values. In other words, if a user attempts to insert "Tag 1" once again, the function will exit.
Any help pointing to the right direction will be greatly appreciated!
EDIT
Here's a fiddle that I just created:
http://jsfiddle.net/TBzKf/2/
The lines related to this question are 153 - 155
I tried all the solutions, but the tag is still inserted, I guess it is because the return statement is just returning the latest function and the wrapper function.
Is there any way to work around this?
How about this:
var $taggedChild = $('#campaignTags').children().filter(function() {
return $(this).text() === value;
});
Here's a little demo, illustrating this approach in action:
But perhaps I'd use here an alternative approach, storing the tags within JS itself, and updating this hash when necessary. Something like this:
var $container = $('#campaignTags'),
$template = $('<div class="tags">'),
tagsUsed = {};
$.each($container.children(), function(_, el) {
tagsUsed[el.innerText || el.textContent] = true;
});
$('#tag').keyup(function(e) {
if (e.which === 13) {
var tag = $.trim(this.value);
if (! tagsUsed[tag]) {
$template.clone().text(tag).appendTo($container);
tagsUsed[tag] = true;
}
}
});
I used $.trim here for preprocessing the value, to prevent adding such tags as 'Tag 3 ', ' Tag 3' etc. With direct comparison ( === ) they would pass.
Demo.
I'd suggest:
$('#addTag').keyup(function (e) {
if (e.which === 13) {
var v = this.value,
exists = $('#campaignTags').children().filter(function () {
return $(this).text() === v;
}).length;
if (!exists) {
$('<div />', {
'class': 'tags',
'text': v
}).appendTo('#campaignTags');
}
}
});
JS Fiddle demo.
This is based on a number of assumptions, obviously:
You want to add unique new tags,
You want the user to enter the new tag in an input, and add on pressing enter
References:
appendTo().
filter().
keyup().
var value = "Tag 1";
$('#campaignTags').find('div.tags').each(function(){
if(value == $(this).text()){
alert('Please type something else');
}
});
you can user either .innerHTML or .text()
if(value === this.innerHTML){ // Pure JS
return;
}
OR
if(value === $this.text()){ // jQuery
return;
}
Not sure if it was a typo, but you were missing a close } and ). Use the jquery .text() method instead of innerText perhaps?
var value = "Tag 1";
$('#campaignTags').find(".tags").each(function(){
var content = $(this).text();
if(value === content){
return;
}
})
Here you go try this: Demo http://jsfiddle.net/3haLP/
Since most of the post above comes out with something here is another take on the solution :)
Also from my old answer: jquery - get text for element without children text
Hope it fits the need ':)' and add that justext function in your main customised Jquery lib
Code
jQuery.fn.justtext = function () {
return $(this).clone()
.children()
.remove()
.end()
.text();
};
$(document).ready(function () {
var value = "Tag 1";
$('#campaignTags').children().each(function () {
var $this = $(this);
if (value == $(this).justtext()) {
alert('Yep yo, return');)
return;
}
});
//
});