I want to know how to match values of an array to a textarea and if it does not match, it display a error message like " something wrong Are you sure about what you got into the text field? "
function populateVariable(appLang){
var selector = $('#field_new');
var variables = [];
// var exists;
//input select
selector.children('div').each(function(id, el) {
$(el).children('.sub_block').each(function (id, el) {
variables.push("$" + $(el).children('input')[0].value + "$ ")
})
});
selector.children('div').each(function(id, el) {
$(el).children('.option-item').each(function (id, el) {
variables.push("$" + $(el).children('input')[0].value + "$ ")
})
});
$('#valueInput').text(appLang.getKey('valueInput') + variables);
}
<div class="" id="formulaire-preview-text">
<div id="valueInput"></div><br>
<div id="inputs"></div><br>
<textarea id="formulaire-preview-textarea" rows="12" cols="60"></textarea>
</div>
This function get all values of input and put them on an array "variables"
If you want to check, after populate your array (from select, or input, it 's what did you do in your code), if the value of the text-area is in your array, you have to do this :
var myArr = ['x','hallo','world','js','2018','hi', 'text','yourvalues','select','blabla']
//inArray is good becouse you get and can save the position in the array
$('#formulaire-preview-textarea').on('input', function (evt) {
var value = evt.target.value
if ( $.inArray(value,myArr) >= 0 ){
$('#error').text(value+ " in array");
}else{
$('#error').text(value + " not in array, something wrong Are you sure about what you got into the text field");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="error">
</div>
<div class="" id="formulaire-preview-text">
<div id="valueInput"></div><br>
<div id="inputs"></div><br>
<textarea id="formulaire-preview-textarea" rows="12" cols="60"></textarea>
</div>
Use Array.prototype.includes()
var array1 = [1, 2, 3];
console.log(array1.includes(2));
// expected output: true
var pets = ['cat', 'dog', 'bat'];
console.log(pets.includes('cat'));
// expected output: true
console.log(pets.includes('at'));
// expected output: false
See https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Array/includes
Related
I have a modal
<div class="modal-body">
<textarea id="data" class="form-control" oninput="this.style.height = ''; this.style.height = this.scrollHeight + 3 +'px'"></textarea>
</div>
and to save the user entered text from the textarea I have a save button and on click I want to save the text
$('#save').click(function () {
var value = $("#data").val();
}
I would like the text to be stored in an array with each line an item in the array. So
text of the below would be an array of 4 items. Some line items will have a space between them but they need to be kept together as a single item in the array.
ABC123
XYZ 444
12323321
OOOO XXXX
Setting var value to be var value = []; reads each letter into an individual array item so not what I need.
Thank you!
try this
$("#save").click(function () {
const value = $("#data").val();
const splitted = value.split("\n");
console.log(splitted);
});
Try this:
HTML:
<div class="modal-body">
<textarea id="data" class="form-control" oninput="this.style.height = ''; this.style.height = this.scrollHeight + 3 +'px'"></textarea>
</div>
<button id="save-btn">save</button>
js:
const textArea = document.querySelector("#data");
const saveBtn = document.querySelector("#save-btn");
arr = [];
const saveData = function(){
arr = textArea.value.split(/\r?\n/);
console.log(arr);
}
saveBtn.addEventListener('click', saveData);
example:
https://codepen.io/huskyslava/pen/PoORBVN?editors=1111
I have no expertise in javascript but I want to render this data which is showing in my console.log below
How can I make forloop or something like that to render this data in my html input?
create.html
<div class="col-sm-2">
<div class="form-group">
<label>Expected Values</label>
<input type="text" class="form-control" value="{{vital.expected_values}}" readonly>
</div>
</div>
<div class="col-sm-2">
<div class="form-group">
<label>Price</label>
<input type="text" class="form-control" value="{{vital.price}}" readonly>
</div>
</div>
<script type="text/javascript">
$(document).ready(function () {
$("#id_vitals").change(function () {
var vitals = $(this).val();
$.ajax({
url: $('#personForm').data('url'),
data: { 'vital_id': vitals },
success: function (response) {
console.log(response[vitals['name']])
}
});
});
})
</script>
I would do it somehow like that:
// Your data
let dataArray = [{data: 1, otherData: 2, elseData: 3}]
// The element, where you want to show it
let targetElement = document.getElementById('your-targer-id');
// The container element for elements
let newContainer = document.createElement('ul');
// Pure JS loop, easy to understand what is happening
// But you can also do it with .map();
for (let i = 0; i < dataArray.length; i++) {
// Add every line
newContainer.innerHTML+='<li>' + dataArray[i].data + '</li>';
// Or other things, depending how you want to show the data
newContainer.innerHTML+='<li> data value is: ' + dataArray[i].data + ' and otherData value is: ' + dataArray[i].otherData + '</li>'; //etc
}
// Append created list in target element
targetElement.appendChild(newContainer);
EDIT - now I see, that you want to display multiple values in text input, rather like so:
let dataArray = [...your-data-array]
let targetElement = document.getElementById('target-input');
for (let i = 0; i < dataArray.lenght; i++) {
// loop throug elements and add it to value attribute of input, separated by coma.
targetElement.value+=dataArray[i].expected_values + ', ';
}
Hope I can explain well.
So I have 8 boxes with class .boxA with a numeric value generated from js:
<div class="tfooter">
<div class="boxA" id="bx3" value="3">3</div>
<div class="boxA" id="bx27" value="27">27</div>
<div class="boxA" id="bx46" value="46">46</div>
<div class="boxA" id="bx40" value="40">40</div>
<div class="boxA" id="bx42" value="42">42</div>
<div class="boxA" id="bx29" value="29">29</div>
<div class="boxA" id="bx13" value="13">13</div>
<div class="boxA" id="bx1" value="1">1</div>
</div>
First of all I push all values in a array:
var randomnumber = Math.ceil(Math.random()*50);
var array = [];
$(".boxA").each(function(){
var dNumber = $(this).attr('value');
array.push(dNumber);
});
Each of this boxes contain a random number from 1 to 50.
Now, I want to generate another random number and check if exists in the array. If exists, generate another number until it's unique in that array. When is unique, create another div.
I've tryed with indexOf, with inArray, with while, but I can't get it working. The problem is that generate. Generate new number until not in array.
Thank you very much!
You could avoid the trial-and-error method by first building an array with the allowed values (i.e. those that do not appear in the list), and then pick a random value from that.
Here is a snippet that will add a new (non-used) number at the top of the list at the press of a button:
function getUsedNumbers() {
return $(".boxA").map(function(){
return +$(this).attr('value');
}).get();
}
function getCandidates(exclude) {
// Generate a list of values from 0 to 49, and make it a Set
// (Sets allow for faster look-up and value removal)
var candidates = new Set(Array(50).keys());
for (value of exclude) {
// Remove the already used value from our Set:
candidates.delete(value);
}
// Convert Set back to array and return it:
return [...candidates];
}
function pickRandomly(array) {
return array[Math.floor(Math.random()*array.length)];
}
$('#add').click(function () {
var used = getUsedNumbers();
var candidates = getCandidates(used);
// Safety:
if (!candidates.length) {
alert('No more candidate values available');
return;
}
var choice = pickRandomly(candidates);
// Insert the selected number at the top of the list:
$(".tfooter").prepend(
$("<div>").addClass("boxA").text(choice).attr({
id: "bx"+choice, value: choice
})
);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="add">Add</button>
<div class="tfooter">
</div>
If you do this repeatedly, then it is not so efficient to re-read the list of values from the page each time, since you actually know what is there already.
Consider making the candidates Set the master reference for your data, and only depend on that to generate the output.
You need to use $.inArray() to check if the random number exists in an existing array or not. if the number doesn't exist, it adds that random number to the array. Below is an updated code:
$("#generateNewNumber").on('click', function() {
var newArray = [];
$(".boxA").each(function() {
newArray.push(parseInt($(this).attr('value')));
});
var randomNumber = Math.ceil(Math.random() * 50);
console.log('Random number is: ' + randomNumber);
if ($.inArray(randomNumber, newArray) !== -1) {
console.log(randomNumber + ' exisits in array');
} else {
newArray.push(parseInt(randomNumber));
$(".tfooter").append('<div class="boxA" id="bx' + randomNumber + '" value="' + randomNumber + '">' + randomNumber + '</div>')
console.log(randomNumber + " doesn't exisits in array, hence adding in an array.");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="generateNewNumber">Generate Random Number</button>
<div class="tfooter">
<div class="boxA" id="bx3" value="3">3</div>
<div class="boxA" id="bx27" value="27">27</div>
<div class="boxA" id="bx46" value="46">46</div>
<div class="boxA" id="bx40" value="40">40</div>
<div class="boxA" id="bx42" value="42">42</div>
<div class="boxA" id="bx29" value="29">29</div>
<div class="boxA" id="bx13" value="13">13</div>
<div class="boxA" id="bx1" value="1">1</div>
</div>
Here is how I would had set up the code:
Create the array with numbers 1-50 in it.
Create a random number based on the list's length.
Randomly splice a position. That position will then be removed from the array but return a an array with one item.
If the array is empty (length 0), start over at 1.
Then you don't need to check if the number exists, because it has already been removed from the array.
function createBoxNumbersArray(startNumber, endNumber) {
var boxNumbers = [];
for (var i = startNumber; i <= endNumber; i++) {
boxNumbers.push(i);
}
return boxNumbers;
}
function getRandom(boxNumbers) {
position = Math.floor((Math.random() * boxNumbers.length-1));
return boxNumbers.splice(position, 1)[0];
}
var boxNumbers = createBoxNumbersArray(1, 50);
var randomBoxNumber = getRandom(boxNumbers);
Seems like indexOf would be the way to go. Your problem is that you're probably comparing the HTML attribute value (a string) to the random number (a number).
so, once you update to:
array.push(parseInt(dNumber));
You will be able to check
if(array.indexOf(randomnumber) >= 0) { } // regenerate random
Am struggling hard to bind 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>
Am giving another try, checking my luck on SO... I tried using another object to track the data while appending, but found difficult.
You should be using the scope as a way to bridge the full array and the tags. use ng-repeat to show the tags, and use the input model to push it into the main array that's showing the tags. I got it started for you here: http://jsfiddle.net/d5ah88mh/9/
function rdCtrl($scope){
$scope.dataset = [];
$scope.inputVal = "";
$scope.removeData = function(index){
$scope.dataset.splice(index, 1);
redoIndexes($scope.dataset);
}
$scope.addToData = function(){
$scope.dataset.push(
{"id": $scope.dataset.length+1,
"name": $scope.inputVal,
"value": 3}
);
$scope.inputVal = "";
redoIndexes($scope.dataset);
}
function redoIndexes(dataset){
for(i=0; i<dataset.length; i++){
$scope.dataset[i].id = i;
}
}
}
<div ng-app>
<div ng-controller="rdCtrl">
<div id="tags" style="border:none;width:370px;margin-left:300px;">
<span class="tag" style="padding:10px;background-color:#808080;margin-left:10px;margin-right:10px;" ng-repeat="data in dataset" id="4" ng-click="removeData($index)">{{data.name}}</span>
<div>
<input type="text" style="margin-left:-5px;" id="inptags" value="" placeholder="Add ur 5 main categories (enter ,)" ng-model="inputVal" />
<button type="submit" ng-click="addToData()">Submit</button>
<img src="../../../static/app/img/accept.png" ng-click="assign()" id="assign" style="cursor:pointer;display:none" />
</div>
</div>
<div id="status" style="margin-top:100px;"></div>
</div>
</div>
I have these text fields.
<input type="text" value="<p>aaaaaaaaaaa</p>" id="tab_4_0_li_div_content"><input type="text" value="lab" id="tab_4_0_li_data"><input type="text" value="<p>dddd</p>" id="tab_4_1_li_div_content"><input type="text" value="client" id="tab_4_1_li_data">
Here tab_4_*_li_data is a <li> html of tab , and tab_4_0_li_div_content is id of <div> which will be show on <li> click.
Now I want to extract data from this input fields using regular expression. For example
client,lab
as key
and
<p>aaaaaaaaaaa</p>,<p>dddd</p>
as value of key.
If you see these are related to each others.
tab_4_0_li_div_content tab_4_0_li_data
<p>aaaaaaaaaaa</p> lab
tab_4_1_li_div_content tab_4_1_li_data
<p>dddd</p> client
Div content part can content any thing, It's an text area.
So how we do this?
There is no reason to have to use a regular expression to parse HTML. One thing, you are not going to have a good time going it. Second, use the power of the DOM
var contents = $("[id$=content]"); //find the elements that have an id that end with content
var datas = $("[id$=data]"); //find the elements that have an id that end with data
var details = {}; //object to hold results
datas.each( function(i) { details[datas[i].value] = contents[i].value; }); //start looping and generate the object with the details you are after
console.log(details); //Object {lab: "<p>aaaaaaaaaaa</p>", client: "<p>dddd</p>"}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="text" value="<p>aaaaaaaaaaa</p>" id="tab_4_0_li_div_content"><input type="text" value="lab" id="tab_4_0_li_data"><input type="text" value="<p>dddd</p>" id="tab_4_1_li_div_content"><input type="text" value="client" id="tab_4_1_li_data">
Now that code assumes the data and content elements are in the same order, if not, than it would require a little processing, but it is not that hard to do.
var datas = $("[id$=data]");
var details = {};
datas.each(function(i, elem) {
var id = elem.id;
var val = $("#" + id.replace("data", "div_content")).val();
details[elem.value] = val;
});
console.log(details); //Object {lab: "<p>aaaaaaaaaaa</p>", client: "<p>dddd</p>"}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="text" value="<p>aaaaaaaaaaa</p>" id="tab_4_0_li_div_content">
<input type="text" value="lab" id="tab_4_0_li_data">
<input type="text" value="<p>dddd</p>" id="tab_4_1_li_div_content">
<input type="text" value="client" id="tab_4_1_li_data">
You can do it like this:
function getValuesById(id1,id2){
var vals = {};
if(id1 === undefined)
id1 = "\\d+";
if(id2 === undefined)
id2 = "\\d+";
$("input").each(function (index, value) {
console.log(new RegExp('tab_(' + id1 + '_' + id2 + ')_li_data'));
var match = value.id.match(new RegExp('tab_(' + id1 + '_' + id2 + ')_li_data'));
if (match) {
vals[value.value] = $("#tab_" + match[1] + "_li_div_content").val();
}
});
return vals;
}
Here I search through all input fields and match against tab_DIGITS_DIGITS_li_div_data and put that as a key and corresponding li_div_content as value in object values.
Check it out here: JSFiddle
UPDATE: I have updated the code to a function where you can send in a parameter to your two numerical values and will use any number if not supplied, i.e. use as getValuesById(4) for values like tab_4_*_li