Opening input when writing #Q# in textarea - javascript

I have textarea. Now, I want to do that once you write "#q + number#" ( e.g. #q1# ), it will create new input field.
For example if you write: "Hello my name is #q1# and my favorite food is #q2#". It will open two input fields.
And when you delete one of those #q + number#, it will delete the same field that was intended to the #q#
For example: if you write "Hello my name is #q1# and my favorite food is #q2#, and the input fields look like that:
<input type="text" q="1" />
<input type="text" q="2" />
and next that I delete the #q1# it supposed to look like that:
and don't delete the value of q="2" input.
How can I do that in jQuery/JavaScript?

Take a look at this quick fiddle http://jsfiddle.net/NgxvP/1/

Here you have something to start playing with
<html>
<head>
<style>
#inputField { position:relative;
width: 200px;
height: 200px;
background-color: #cda;
}
</style>
<script src="jquery-1.7.1.min.js"></script>
<script>
// in_array function provided by phpjs.org
function in_array (needle, haystack, argStrict)
{
var key = '',
strict = !! argStrict;
if (strict)
{
for (key in haystack)
{
if (haystack[key] === needle)
{
return true;
}
}
}
else
{
for (key in haystack)
{
if (haystack[key] == needle)
{
return true;
}
}
}
return false;
}
var addedFields = new Array();
function checkFields(input, charCode)
{
var text = (charCode) ? input.value + String.fromCharCode(charCode) : input.value;
var pattern = /#q[0-9]#/g;
var matches = text.match(pattern);
if (!matches) { matches = new Array(); }
if (addedFields.length>0 && addedFields.length != matches.length)
{
for (var index in addedFields)
{
if (!in_array('#q'+ index +'#', matches))
{
$('#q'+index).remove();
delete addedFields[index];
}
}
}
if (matches)
{
for (var i=0; i<matches.length; i++)
{
var code = matches[i];
var index = code.match(/[0-9]/)[0];
if ( $('#q'+index).length == 0 )
{
addFields(index);
}
}
}
}
function addFields(i)
{
addedFields[i] = true;
var fields = '';
for (var index in addedFields)
{
fields += '<input type="text" q="'+ index +'" id="q'+ index +'" />';
}
$('#inputField').html(fields);
}
</script>
</head>
<body>
<div id="formID">
<form>
<textarea onkeypress="checkFields(this, event.charCode); return true;" onkeyup="checkFields(this); return true;"></textarea>
<div id="inputField"></div>
</form>
</div>
</body>
</html>
EDITED: to avoid appending unordered input text fields, but showing them always ordered by their index, as commented in dfsq answer
I created a jsfiddle for your convenience http://jsfiddle.net/2HA5s/

Related

document.getElementsByTagName is working but same functionality is not working with document.getElementById

I was trying to change the color of placeholder of input tag using Javascript. I am able to achieve that if I use document.getElementsByTagName, but if I am using document.getElementById then it's not working.
HTML:
<input name="txtfirstName" type="text" id="input" placeholder="First Name" />
<input type="button" name="Button1" value="Register" onclick="ChangePlaceHolderColor();" />
JavaScript (with document.getElementsByTagName):
function ChangePlaceHolderColor() {
var textBoxes = document.getElementsByTagName("input");
for (var i = 0; i < textBoxes.length; i++) {
if (textBoxes[i].type == "text") {
if (textBoxes[i].value == "") {
textBoxes[i].className += " Red";
}
}
}
}
JavaScript (with document.getElementById):
function ChangePlaceHolderColor() {
var textBoxes = document.getElementById("input");
for (var i = 0; i < textBoxes.length; i++) {
if (textBoxes[i].type == "text") {
if (textBoxes[i].value == "") {
textBoxes[i].className += " Red";
}
}
}
}
I am not able to figure why this is happening.
getElementById returns only 1 element, it is not an array
function ChangePlaceHolderColorx() {
var textBoxes = document.getElementsByTagName("input");
for (var i = 0; i < textBoxes.length; i++) {
if (textBoxes[i].type == "text") {
if (textBoxes[i].value == "") {
textBoxes[i].className += "Red";
}
}
}
}
function ChangePlaceHolderColor() {
var textBoxes = document.getElementById("input");
if (textBoxes.type == "text") {
if (textBoxes.value == "") {
textBoxes.className += "Red";
}
}
}
.Red{
color:red;
}
<input name="txtfirstName" type="text" id="input" placeholder="First Name" />
<input type="button" name="Button1" value="Register" onclick="ChangePlaceHolderColor();" />
You have to change function ChangePlaceHolderColor() to:
function ChangePlaceHolderColor() {
var textBoxes = document.getElementById("input");
if (textBoxes.type == "text") {
if (textBoxes.value == "") {
textBoxes.className += " Red";
}
}
}
this is because getElementByTagName() will return HTMLCollection which you can treat as an Array, but getElementById() will return only one element.
getElementsByTagName will always return an array of HTML elements, whereas getElementsById will always return a single HTML element.
function ChangePlaceHolderColor() {
//no loop because the return is one element.
var textBoxes = document.getElementById("input");
if (textBoxes.type == "text") {
if (textBoxes.value == "") {
textBoxes.className += " Red";
}
}
}
In HTML, element IDs must be unique on any given page.

Add space after dot

Good day. I've got some problem.
I've got input where I wrote some information.
Example:
<div class="wizard wizardstep1" ng-controller='someCtrl'>
<p class="wizardtitle">Put you Theme</p>
<input id="taskTheme" required type="text" placeholder="Put you Theme" ng-model="taskThemeWizardInputValue" ng-change="checkThemeWizardInputValue()">
</div>
And I've got my controller.
Example:
$scope.checkThemeWizardInputValue = function () {
if ($scope.taskThemeWizardInputValue === undefined) {
$scope.taskThemeWizardInputValue = "";
console.log($scope.taskThemeWizardInputValue);
console.log($scope.taskThemeWizardInputValue.length);
} else {
var strt = $scope.taskThemeWizardInputValue.split('.');
for (var i = 0 ; i < strt.length; i++) {
strt[i] = strt[i].charAt(0).toUpperCase() + strt[i].substr(1);
}
$scope.taskThemeWizardInputValue = strt.join('.');
console.log($scope.taskThemeWizardInputValue);
console.log(strt);
}
}
How I can add space after dot? Who knows?
Here is link to jsfiddle with my example.
We achieve it by adding space to each splitted string other than first one and an empty string
function someCtrl($scope) {
$scope.checkThemeWizardInputValue = function () {
if ($scope.taskThemeWizardInputValue === undefined) {
$scope.taskThemeWizardInputValue = "";
console.log($scope.taskThemeWizardInputValue);
console.log($scope.taskThemeWizardInputValue.length);
} else {
var strt = $scope.taskThemeWizardInputValue.split('.');
for (var i = 0 ; i < strt.length; i++) {
var addSpace='';
if(i>0 && strt[i].trim().length>0){
addSpace=' ';
}
strt[i] = addSpace+strt[i].trim().charAt(0).toUpperCase() + strt[i].trim().substr(1);
}
$scope.taskThemeWizardInputValue = strt.join('.');
console.log($scope.taskThemeWizardInputValue);
console.log(strt);
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<div class="wizard wizardstep1" ng-controller='someCtrl'>
<p class="wizardtitle">Put you Theme</p>
<input id="taskTheme" required type="text" placeholder="Put you Theme" ng-model="taskThemeWizardInputValue" ng-change="checkThemeWizardInputValue()">
</div>
</div>
You can do this simply by changing strt.join('.') to strt.join('. ').
$scope.checkThemeWizardInputValue = function () {
if ($scope.taskThemeWizardInputValue === undefined) {
$scope.taskThemeWizardInputValue = "";
console.log($scope.taskThemeWizardInputValue);
console.log($scope.taskThemeWizardInputValue.length);
} else {
var strt = $scope.taskThemeWizardInputValue.split('.');
for (var i = 0 ; i < strt.length; i++) {
strt[i] = strt[i].trim();
if(strt[i].length > 0) {
strt[i] = ' '+strt[i].charAt(0).toUpperCase() + strt[i].substr(1);
}
}
$scope.taskThemeWizardInputValue = strt.join('.');
console.log($scope.taskThemeWizardInputValue);
console.log(strt);
}
}
This is working fiddle
I suggest creating a directive so that you can plugin this behaviour whenever required., rather than writing your ng-change in every controller.
In directive simple line element.val(event.target.value.split(".").join(". ")); will work for you., with help of directive controller parameter.
See example fiddle

Add user input to array // Javascript

This is the code I have so far. When the user enters a word into the input box, I want that word to be stored in an array via the Add Word button. Once a number of words have been entered, the user clicks the Process Word button and I want all the words in the array to appear. How would I do this? Also could someone also explain why when nothing is entered into the input box "field is empty" does not appear?
function begin() {
var word = "List of words";
var i = returnword.length
if (userinput.length === 0) {
word = "Field is empty"
}
document.getElementById('message2').innerHTML = word
while (i--) {
document.getElementById('message').innerHTML = returnword[i] + "<br/>" + document.getElementById('message').innerHTML;
}
}
function addword() {
var arrword = [];
returnword = document.getElementById('userinput').value;
arrword.push(returnword);
}
Addword()
Your function contains an array arrword. If you keep it inside your function it will be reset every time you call the function. You need to keep your array of words outside the function
Empty input
The empty input message should be shown when you click on the Add word button. Check the input and display a message if needed
Display word
You can simply use join() to display you array
var arrayOfWord = [];
var inputElement = document.getElementById('userinput');
var errorElement = document.getElementById('error');
var wordsElement = document.getElementById('words');
function addWord() {
errorElement.innerHTML = "";
var word = inputElement.value;
if (word.trim() === "")
errorElement.innerHTML = "Empty input";
else
arrayOfWord.push(word);
inputElement.value = "";
}
function process(){
words.innerHTML = arrayOfWord.join(' - ');
}
#error {
color: tomato;
}
#words {
color: purple;
}
Enter a word <input id="userinput" /><button onclick="addWord()">Add word</button>
<div id="error"></div>
<button onclick="process()">Process</button>
<div id="words"></div>
you can do something a bit clearer with jQuery! :)
if you handle the input with jquery you can write something like:
var arrWord = [] // your array
/* Attaching a click handler on your "Add Word" button that will
execute the function on user click */
$("#addWordButtonID").on("click", function () {
var wordTyped = $('#textInputID').val() // your var that collect userInput
if (wordTyped.length != 0) { // your if statement with length === 0 condition
arrWord.push(wordTyped) // adding word typed to the array
}
})
to add jquery to your html page, just add
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
in your html header
Hopefully you already have the right html. Then you can modify your script like below:
<script>
var arrword = [];
var returnword;
function begin() {
var word = "List of words";
var i = arrword.length;
if (arrword.length === 0) {
word = "Field is empty";
}
document.getElementById('message2').innerHTML = word;
while (i--) {
document.getElementById('message').innerHTML = arrword[i] + "<br/>" + document.getElementById('message').innerHTML;
}
}
function addword() {
returnword = document.getElementById('userinput').value;
arrword.push(returnword);
}
</script>
var arrword = [];
var returnword;
function begin() {
var word = "List of words";
var i = arrword.length;
if (arrword.length === 0) {
word = "Field is empty";
}
document.getElementById('message2').innerHTML = word;
while (i--) {
document.getElementById('message').innerHTML = arrword[i] + "<br/>" + document.getElementById('message').innerHTML;
}
}
function addword() {
returnword = document.getElementById('userinput').value;
arrword.push(returnword);
}
<button id="addWord" onclick="addword()">Add Word</button>
<button id="processWords" onclick="begin()">ProcessWords</button>
<input type="text" id="userinput" value=" " />
<div id="message2">
</div>
<div id="message">
</div>

Convert a string into a character array using JavaScript

Continue on my Javascript - Radio Button onChange
Here is my code:
<html>
<head>
<script type="text/javascript">
function Change(radio)
{
for(i = 1; i <=3; i++)
{
if(i == radio.value)
{
setvalue = "Y";
value = setvalue;
radiovalue = radio.value;
}
else
{
setvalue = "N";
value = setvalue;
radiovalue = radio.value;
}
ChangeValue(setvalue,value);
}
function ChangeValue(setvalue,value)
{
var getvalue = value;
document.write(getvalue);
}
}
</script>
</head>
<body>
<?php
for($i = 1; $i <= 3; $i++)
{
?>
<input type="radio" name="choice" value="<?php echo $i;?>" onchange="Change(this)" /><br />
<?php
}
?>
</body>
</html>
From the above code, if I clicked the first radio button, the output is YNN.
Now I want to separate the value with commas (YNN) and put the result into an array ("Y","N","N").
I wrote the following inside ChangeValue function:
function ChangeValue(setvalue, value)
{
var getvalue = value;
document.write(getvalue);
var seperate = new array();
seperate = getvalue.spilt(",");
}
However the above code doesn't put my value into array.
What am I doing wrong? Any solutions to solve this problem?
You have to split the string into separate chars as array.
var str = 'YNN'; //or whatever
var strWithComma = str.split(''); //to char array
After this you can join the chars to a new string for display output.
var str = 'YNN';
var strWithComma = str.split('').join(','); //'YNN' (string) --> ['Y','N','N'] (string/char array) --> "Y,N,N" (string)
Hope this helps
Demo
The JavaScript String object has a split method which does what you're requesting. It partitions the string based on a specified delimiter, and returns an array with each partition at its own index. If you split with a blank (empty string) delimiter, you tokenize the string into individual characters.
To get the values of your radio buttons as a string, you can iterate through them and examine the value property of each one.
var input = "YNN"
var result = input.split(''); // returns ["Y", "N", "N"]
var valStr = "";
function main() {
var radioBtns = document.getElementsByName("choice");
for (var i = 0; i < radioBtns.length; i++) {
radioBtns[i].onchange = valChange;
}
valStr = Array(radioBtns.length + 1).join("N")
}
function valChange(event) {
var changedElem = event.target;
var elemValue = changedElem.value;
var elemIdx = +elemValue - 1;
var resultStr = replaceChar(valStr, elemIdx, 'Y');
getElem("outputStr").innerHTML = resultStr;
getElem("outputArr").innerHTML = resultStr.split('');
}
function replaceChar(str, idx, chr) {
return str.substr(0, idx) + chr + str.substr(idx + chr.length);
}
function getElem(id) {
return document.getElementById(id);
}
window.onload = main;
span[id^="output"] {
border: 2px solid black;
margin: 2px;
width: 50px;
}
div {
margin-top: 7px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Select an option:
<br />
<input type="radio" name="choice" value="1" />
<br />
<input type="radio" name="choice" value="2" />
<br />
<input type="radio" name="choice" value="3" />
<div>String Output: <span id="outputStr"> </span>
</div>
<div>Array Output: <span id="outputArr"> </span>
</div>

I have an issue to create dynamic fields with string count using Javascript OR Jquery

I have an issue to create dynamic fields with string count using JavaScript or jQuery.
Briefing
I want to create dynamic fields with the help of sting count, for example when I write some text on player textfield like this p1,p2,p3 they create three file fields on dynamicDiv or when I remove some text on player textfield like this p1,p2 in same time they create only two file fields that's all.
The whole scenario depend on keyup event
Code:
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
function commasperatedCount(){
var cs_count = $('#player').val();
var fields = cs_count.split(/,/);
var fieldsCount = fields.length;
for(var i=1;i<=fieldsCount;i++){
var element = document.createElement("input");
element.setAttribute("type", 'file');
element.setAttribute("value", '');
element.setAttribute("name", 'file_'+i);
var foo = document.getElementById("dynamicDiv");
foo.appendChild(element);
}
}
</script>
<form>
<label>CountPlayerData</label>
<input type="text" name="player" id="player" onkeyup="return commasperatedCount();" autocomplete="off" />
<div id="dynamicDiv"></div>
<input type="submit" />
</form>
var seed = false,
c = 0,
deleted = false;
$('#player').on('keyup', function(e) {
var val = this.value;
if ($.trim(this.value)) {
if (e.which == 188) {
seed = false;
}
if (e.which == 8 || e.which == 46) {
var commaCount = val.split(/,/g).length - 1;
if (commaCount < c - 1) {
deleted = true;
}
}
commasperatedCount();
} else {
c = 0;
deleted = false;
seed = false;
$('#dynamicDiv').empty();
}
});
function commasperatedCount() {
if (deleted) {
$('#dynamicDiv input:last').remove();
deleted = false;
c--;
return false;
}
if (!seed) {
c++;
var fields = '<input value="" type="file" name="file_' + c + '">';
$('#dynamicDiv').append(fields);
seed = true;
}
}​
DEMO
<script>
function create(playerList) {
try {
var player = playerList.split(/,/);
} catch(err) {
//
return false;
}
var str = "";
for(var i=0; i<player.length; i++) {
str += '<input type="file" id="player-' + i + '" name="players[]" />';
//you wont need id unless you are thinking of javascript validations here
}
if(playerList=="") {str="";} // just in case text field is empty ...
document.getElementById("dynamicDiv").innerHTML = str;
}
</script>
<input id="playerList" onKeyUp="create(this.value);" /><!-- change event can also be used here -->
<form>
<div id="dynamicDiv"></div>
</form>

Categories

Resources