I'm using the "mask" feature (from plugin jquery mask ) and the plugin intlTelInput.
The problem is that when changing the country selection, the Placeholder is incorrect. Example: if the selection is in the country Brazil, with the placeholder (11) 96123-4567, and when switching to any other country like Botswana and returning the selection to Brazil again, the placeholder is (11) 96123, which is incorrect.
My code is below:
// Make sure to place this snippet in the footer or at least after
// the HTML input we're targeting.
$(document).ready(function() {
var phoneInputID = "#phone";
var input = document.querySelector(phoneInputID);
var iti = window.intlTelInput(input, {
// allowDropdown: false,
// autoHideDialCode: false,
// autoPlaceholder: "off",
// dropdownContainer: document.body,
// excludeCountries: ["us"],
formatOnDisplay: true,
initialCountry: "BR",
// geoIpLookup: function(callback) {
// $.get("http://ipinfo.io", function() {}, "jsonp").always(function(resp) {
// var countryCode = (resp && resp.country) ? resp.country : "";
// callback(countryCode);
// });
// },
hiddenInput: "full_number",
// initialCountry: "auto",
// localizedCountries: { 'de': 'Deutschland' },
// nationalMode: false,
// onlyCountries: ['us', 'gb', 'ch', 'ca', 'do'],
// placeholderNumberType: "MOBILE",
preferredCountries: ['es'],
// separateDialCode: true,
utilsScript: "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/11.0.14/js/utils.js"
});
$(phoneInputID).on("countrychange", function(event) {
// Get the selected country data to know which country is selected.
var selectedCountryData = iti.getSelectedCountryData();
// Get an example number for the selected country to use as placeholder.
newPlaceholder = intlTelInputUtils.getExampleNumber(selectedCountryData.iso2, true, intlTelInputUtils.numberFormat.INTERNATIONAL),
// Reset the phone number input.
iti.setNumber("");
// Convert placeholder as exploitable mask by replacing all 1-9 numbers with 0s
mask = newPlaceholder.replace(/[1-9]/g, "0");
// Apply the new mask for the input
$(this).mask(mask);
});
// When the plugin loads for the first time, we have to trigger the "countrychange" event manually,
// but after making sure that the plugin is fully loaded by associating handler to the promise of the
// plugin instance.
iti.promise.then(function() {
$(phoneInputID).trigger("countrychange");
});
});
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.12/js/intlTelInput.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.14.11/jquery.mask.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.12/css/intlTelInput.css" rel="stylesheet" />
</head>
<body>
<input type="tel" id="phone" name="phone" />
</body>
</html>
The solution would be for the Placeholder to be correct when changing selection.
Related
I have dropzone box and I've implemented sortable into it. As my form submits with html and not ajax I had to add hidden inputs where I push my selected images with dropzonejs therefore I could get them in back-end.
So far everything I explained above is working
Issue
As I mentioned I've implemented sortable functionality into dropzonejs and it does sort images in dropzone box, but not in my appended hidden input
In order to get sorted images in back-end I need to apply that sortable into my appended input as well.
Code
HTML
//Drop zone box
<div class="dropzone" id="my-awesome-dropzone" action="#">
<div class="fallback">
<input name="cimages[]" type="file" multiple />
</div>
<div class="clearfix"></div>
</div>
// append hidden input include selected images for back-end use
<div id="botofform"></div>
Script
Dropzone.autoDiscover = false;
var myDropzone = new Dropzone("#my-awesome-dropzone", {
headers: {
"X-CSRF-TOKEN": $("meta[name='csrf-token']").attr("content")
},
autoProcessQueue : false,
acceptedFiles: ".jpeg,.jpg,.png,.gif",
dictDefaultMessage: "Drag an image here to upload, or click to select one",
maxFiles: 15, // Maximum Number of Files
maxFilesize: 8, // MB
addRemoveLinks: true,
dictRemoveFile: 'Remove',
dictFileTooBig: 'Image is bigger than 8MB',
// append hidden input and add selected images
accept: function(file) {
let fileReader = new FileReader();
fileReader.readAsDataURL(file);
fileReader.onloadend = function() {
let content = fileReader.result;
$('#botofform').append('<input type="hidden" class="cimages" name="cimages[]" value="'+ content +'">');
file.previewElement.classList.add("dz-success");
}
file.previewElement.classList.add("dz-complete");
}
});
// reorder images in dropzone box (need to get this results into "$('#botofform').append" above)
$(function(){
$(".dropzone").sortable({
items:'.dz-preview',
cursor: 'move',
opacity: 0.5,
containment: '.dropzone',
distance: 20,
tolerance: 'pointer',
});
});
Question
How can I apply sortable results into my appended input?
How do I reduce $('#botofform') items (inputs) when an image gets removed by dropzonejs?
You can use data-attribute for both your div where image is added and input field .So, whenever new file is uploaded you can use setAttribute("data-id", count) here count can be any random number only make sure this value should be same for both input and div because this will help us to remove and sort inputs .
Now , for sorting inputs you can use stop event this will get called when sorting is stop .Inside this you can loop through dropzone div and then get attribute which we have added earlier using this attribute we can find the input and append same to botofform div.
Finally , for deleting files you can use remove files event this will get called whenever remove link is clicked so here you simply need to get that data-id which is added to div then use this attribute to remove input as well.
Demo Code :
var count;
var random;
Dropzone.autoDiscover = false;
var myDropzone = new Dropzone("#my-awesome-dropzone", {
headers: {
"X-CSRF-TOKEN": $("meta[name='csrf-token']").attr("content")
},
autoProcessQueue: false,
acceptedFiles: ".jpeg,.jpg,.png,.gif",
dictDefaultMessage: "Drag an image here to upload, or click to select one",
maxFiles: 15, // Maximum Number of Files
maxFilesize: 8, // MB
addRemoveLinks: true,
dictRemoveFile: 'Remove',
dictFileTooBig: 'Image is bigger than 8MB',
// append hidden input and add selected images
accept: function(file) {
let fileReader = new FileReader();
fileReader.readAsDataURL(file);
fileReader.onloadend = function() {
random = 1 + Math.floor(Math.random() * 1000);
count = $(".dz-complete").length + "_" + random;
let content = fileReader.result;
console.log(count)
//add dataid
$('#botofform').append('<input type="text" class="cimages" name="cimages[]" data-id = "' + count + '" value="' + content + '">');
file.previewElement.classList.add("dz-success");
file.previewElement.setAttribute("data-id", count);
}
file.previewElement.classList.add("dz-complete");
},
removedfile: function(file) {
console.log("inside remove --" + file.previewElement.getAttribute("data-id"))
var ids = file.previewElement.getAttribute("data-id") // get attr where file is been removed
$("#botofform input[data-id=" + ids + "]").remove() //remove input field as well
file.previewElement.remove(); //remove file
}
});
$(function() {
$(".dropzone").sortable({
items: '.dz-preview',
cursor: 'move',
opacity: 0.5,
containment: '.dropzone',
distance: 20,
tolerance: 'pointer',
stop: function(event, ui) {
//cloned div
var cloned = $('div#botofform').clone()
$('#botofform').html("") //empty it
//loop through dropzone..
$('.dropzone .dz-complete').each(function() {
var data_id = $(this).data('id') //get data-id
$(cloned).find("input[data-id=" + data_id + "]").clone().appendTo($('#botofform')) //find input which has that data-id and append same to bottmform
});
}
});
});
<link rel="stylesheet" href=" http://code.jquery.com/ui/1.9.1/themes/base/jquery-ui.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/4.3.0/dropzone.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
//Drop zone box
<div class="dropzone" id="my-awesome-dropzone" action="#">
<div class="fallback">
<input name="cimages[]" type="file" multiple />
</div>
<div class="clearfix"></div>
</div>
<div id="botofform"></div>
I am trying to link my HTML form with my csv file to populate form field automatically. Based on what user selects in first field, second field should be automatically filled with the appropriate value. when the user starts typing in the first field, the input field automatically pulls data from csv file to show available options. Options appear after user completes writing 3 words in the field.
Further, to avoid any CORS issue in code, I have added additional URL in my CSV file URL which makes it accessible by any web application.
I was able to prepare this code with the help of examples available on web. However, my code is not working properly. I tried to solve this problem on my own. But I don't know about coding enough.
Can anyone please help me to solve this problem.
<script>
$(function() { function processData(allText) { var record_num = 2;
// or however many elements there are in each row
var allTextLines = allText.split(/\r\n|\n/); var lines = []; var headings = allTextLines.shift().split(','); while (allTextLines.length > 0) { var tobj = {}, entry; entry = allTextLines.shift().split(','); tobj['label'] = entry[0]; tobj['value'] = entry[1]; lines.push(tobj); } return lines; }
// Storage for lists of CSV Data
var lists = [];
// Get the CSV Content
$.get("https://cors-anywhere.herokuapp.com/www.coasilat.com/wp-content/uploads/2019/06/file.txt ", function(data) { lists = processData(data); }); $("#species").autocomplete({ minLength: 3, source: lists, select: function(event, ui) { $("#species").val(ui.item.label); $("#identifiant").val(ui.item.value); return false; } }); });)
</script>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<form>
<div class="ui-widget"> <label for="species">Species: </label> <input id="species"> <label for="identifiant">Identifiant: </label> <input id="identifiant" style="width: 6em;"> </div></form>
Here's the modified answer, working with jquery-ui autocomplete.
The solution: the $.get() is an asynchronous function (the data is not readily available on page load), so jquery-ui autocomplete didn't work with the updated lists[] array, because it (seems so that it) doesn't work with dynamically generated data. So the source of autocomplete had to be refreshed with the newly arrived data in the $.get()'s callback function.
$("#species").autocomplete('option', 'source', lists) - this is the key line, as it updates autocomplete's source with the new data.
// Only needed for working example
var myCSV = "Species,Identifiant\r\n";
myCSV += "Species A,320439\r\n";
myCSV += "Species B,349450\r\n";
myCSV += "Species C,43435904\r\n";
myCSV += "Species D,320440\r\n";
myCSV += "Species E,349451\r\n";
myCSV += "Species F,43435905\r\n";
console.log(myCSV);
// Begin jQuery Code
$(function() {
function processData(allText) {
// var record_num = 2; // or however many elements there are in each row
var allTextLines = allText.split(/\r\n|\n/);
var lines = [];
var headings = allTextLines.shift().split(',');
while (allTextLines.length > 0) {
var tobj = {},
entry;
entry = allTextLines.shift().split(',');
/*
Normally we'd read the headers into the object.
Since we will be using Autocomplete, it's looking for an array of objects with 'label' and 'value' properties.
tobj[headings[0]] = entry[0];
tobj[headings[1]] = entry[1];
*/
if (typeof entry[1] !== 'undefined') {
let prefix = !entry[0].includes('Species') ? 'Species ' : ''
tobj['label'] = prefix + entry[0];
tobj['value'] = entry[1].trim();
lines.push(tobj);
}
}
return lines;
}
let lists = [];
// For working example
// lists = processData(myCSV);
// console.log('lists1', lists)
// In your script you will get this content from the CSV File
// Get the CSV Content
$.get("https://cors-anywhere.herokuapp.com/www.coasilat.com/wp-content/uploads/2019/06/file.txt", function(data) {
lists = processData(data);
$("#species").autocomplete('option', 'source', lists)
console.log('lists2', lists)
});
$("#species").autocomplete({
minLength: 3,
source: lists,
focus: function(event, ui) {
console.log(ui)
$("#species").val(ui.item.label);
return false;
},
select: function(event, ui) {
$("#species").val(ui.item.label);
$("#identifiant").val(ui.item.value);
return false;
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" />
<div class="ui-widget">
<label for="species">Species: </label>
<input id="species">
<label for="identifiant">Identifiant: </label>
<input id="identifiant" style="width: 6em;">
</div>
The processData() function didn't work as expected with the source you provided, so that had to be modified too.
My solution is a kinda' autocomplete - it's called typeahead.
I displayed the filtered list, so you see what's happening, but you can place that anywhere - in a dropdown below the input field, for example.
$(function() {
// processing CSV data
function processData(allText) {
// splitting lines
var allTextLines = allText.split(/\r\n|\n/);
const speciesData = []
// reading data into array, if it's not the first row (CSV header) AND
// if it's not 'Species'
let j = 0; // this will be the item's index
for (let i = 0; i < allTextLines.length - 1; i++) {
if (i !== 0 && allTextLines[i] !== 'Species') {
const record = allTextLines[i].split(',')
speciesData.push({
label: record[0],
value: record[1].trim(), // it has a lot of whitespace
index: j // adding this, so we can keep track of items
})
j++; // incrementing index
}
}
// returning processed data
return speciesData;
}
// Storage for lists of processed CSV Data
let lists = [];
// Get the CSV Content
$.get("https://cors-anywhere.herokuapp.com/www.coasilat.com/wp-content/uploads/2019/06/file.txt ", function(data) {
// making processed data availabel app-wide
lists = processData(data);
// filling the 'suggestions list' the first time
suggestionListHtml(lists, $('.suggestions-container'))
});
// actions on input field input event
// only the third param differs in filterSpecies()
$('#species').on('input', function(e) {
const filteredList = filterSpecies($(this).val(), lists, 'label')
suggestionListHtml(filteredList, $('.suggestions-container'))
})
$('#identifiant').on('input', function(e) {
const filteredList = filterSpecies($(this).val(), lists, 'value')
suggestionListHtml(filteredList, $('.suggestions-container'))
})
// clicking on an item in the 'suggestions list' fills out the input fields
$('.suggestions-container').on('click', '.suggestion', function(e) {
const item = lists[$(this).attr('data-listindex')]
$('#species').val(item.label)
$('#identifiant').val(item.value)
})
});
function suggestionListHtml(filteredList, container) {
// creating HTML template for the 'suggestions list'
let html = ''
filteredList.forEach(item => {
html += `<span class="suggestion" data-listindex="${item.index}">label: ${item.label} - value: ${item.value}</span>`
})
// modifying the displayed 'suggestions list'
container
.empty()
.append(html)
}
// filtering the processed list
// #param substr - the text from the input field
// #param list - the list to be filtered
// #param attr - one of the keys in the processed list (label or value)
function filterSpecies(substr, list, attr) {
// doing the actual filtering
const filteredList = list.filter(item => {
return item[attr].toLowerCase().includes(substr.toLowerCase())
})
return filteredList
}
.suggestions-container span {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<div class="ui-widget">
<label for="species">Species: </label>
<input id="species">
<label for="identifiant">Identifiant: </label>
<input id="identifiant" style="width: 6em;">
</div>
<div class="suggestions-container">
</div>
</form>
I will post the part of a function that is adding numbers that are clicked into selected input field.
So, I need to separate it with a comma (,). I tried some of the examples but it seems not to be working on the function that I wrote.
var rowRange = 'abcdefghijklmnopqrstuvwxyz'.split('');
var $cart = $('#seats'),
$counter = $('#counter'),
sc = $('#seat-map').seatCharts({
map: [
'aaaaa__aaaaa',
'aaaaa__aaaaa'
],
naming : {
top : false,
getLabel : function (character, row, column) {
return rowRange[row - 1].toUpperCase() + column;
},
},
click: function () {
if (this.status() === 'available') {
$('#seats').split(",")
.attr('id', 'cart-item-'+this.settings.id)
.val(this.settings.label)
.appendTo($cart);
$counter.text(sc.find('selected').length+1);
return 'selected';
});
});
Seat is a input field where comma needs to be added after every click on any number.
.split(",")
when I remove this part the code works like it should, but without adding comma.
.split() doesn't work on jquery objects. Instead use it on the values in your select.
Here is an example on how it could work.
$selected = $('#selected');
$(".seat").on("click", function() {
const cur = $selected.val();
const valToInsert = $(this).text();
$selected.val(cur.length === 0 ? valToInsert : cur.split(',').concat(valToInsert).join(','));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="selected">
<button class="seat">a</button>
Can anyone tell me what i am doing wrong , i want to have different views for different users in handsontable.I am defining the table as
document.addEventListener("DOMContentLoaded", function() {
var create_table = document.getElementById('create_table');
var mydata = document.getElementById('mydata').innerHTML;//to get the hidden element
var logged_user = document.getElementById('logged_user').innerHTML;// to get remote user
var plan_creator = document.getElementById('plan_creator').innerHTML;//to get the person who has created the plan
console.log(logged_user + " " + plan_creator);
console.log(mydata);
var searchResultCount=0;
var hot,searchFiled,resultCount;
function searchResultCounter(instance, row, col, value, result) {
Handsontable.plugins.Search.DEFAULT_CALLBACK.apply(this, arguments);
if (result) {
searchResultCount++;
}
}
var buttons = {
save:document.getElementById('save'),
load:document.getElementById('load'),
file:document.getElementById('file_export')
}
var objectData = JSON.parse(mydata);//to decode data in JSON format
console.log(objectData);
hot = new Handsontable(create_table, {
data:objectData,
colHeaders: true,
rowHeaders: true,
contextMenu: true,
minRows: 30,
minCols: 13,
maxCols:18,
maxRows:100,
copyPaste:true,
dropdownMenu: true,//plugin to display menu on column header
filters:true,
columnSorting:true,//plugin to enable sorting
sortIndicator:true,//to display sorting is done
comments:true,//to add comments
colHeaders:["Testcase Name","Cell Name","Customer","Flops","Title","Status","Mfix CCR","Scenerio Brief Description","Expected Results","CCR Status","CCR No","Remarks","Testcase Path"],
if(logged_user == plan_creator) {
columns:[//when using this not able to remove column
{data:'tc_name'},
{data:'cell_name'},
{data:'customer_name'},
{data:'flops' ,type:'numeric'},
{data:'title'},
{data:'status'},
{data:'mfix_ccr'},
{data:'test_scenerio'},
{data:'expected_results'},
{data:'ccr_status'},
{data:'ccr_num'},
{data:'remarks'},
{data:'tc_path'}],
}
else{
columns:[//when using this not able to remove column
{data:'tc_name' ,readOnly:true } ,
{data:'cell_name',readOnly:true },
{data:'customer_name',readOnly:true },
{data:'flops' ,type:'numeric',readOnly:true },
{data:'title',readOnly:true },
{data:'status',readOnly:true },
{data:'mfix_ccr',readOnly:true },
{data:'test_scenerio',readOnly:true },
{data:'expected_results',readOnly:true },
{data:'ccr_status',readOnly:true },
{data:'ccr_num',readOnly:true },
{data:'remarks'},//only remarks can be added by other user
{data:'tc_path',readOnly:true }],
}
search: {
callbak:searchResultCounter
}
});
searchFiled = document.getElementById('search_filed');
resultCount=document.getElementById('resultCount');
var exportPlugin=hot.getPlugin('exportFile');
Handsontable.dom.addEvent(searchFiled, 'keyup', function(event) {
var queryResult;
console.log(this.value);
searchResultCount = 0;
queryResult = hot.search.query(this.value);
console.log(queryResult);
//resultCount.innerText = searchResultCount.toString();
hot.render();
});
buttons.file.addEventListener('click', function() {// enabling the plugin to download the file
exportPlugin.downloadFile('csv', {filename: 'MyFile',columnHeaders:true});
});
I don't get any error when i remove the if/else statement and use only one scenerio .when using above code i am getting the error, but when i remove the if/else part and just use columns attribute in a simple way , i don't get this error.But i want to have different views for the creator of plan and others.
Is there any other way to do this?
Thanks
You can't use if statements when constructing an object, but you can use the ternary ?: operator, like this:
colHeaders: ... ,
columns: logged_user == plan_creator
? /* value in case they are equal */
: /* value in case they are not equal */,
search: ...
instead of using if else like
if(logged_user == plan_creator) {
columns:[//when using this not able to remove column
{data:'tc_name'},
{data:'cell_name'},
{data:'customer_name'},
{data:'flops' ,type:'numeric'},
{data:'title'},
{data:'status'},
{data:'mfix_ccr'},
{data:'test_scenerio'},
{data:'expected_results'},
{data:'ccr_status'},
{data:'ccr_num'},
{data:'remarks'},
{data:'tc_path'}],
}
else {}
you could use the ternary Operator:
columns: (logged_user === plan_creator)
? [//when using this not able to remove column
{data:'tc_name'},
...
]
: [//when using this not able to remove column
{data:'tc_name' ,readOnly:true },
...
]
I am working on lecture validation code. I want to be able to check a line, get content and validate it, if it is what the user should put. I am using "for loop" to iterate the process. JSON to set validation process. The issue is the return error does not match. My question is what is the best way to validate code using Ace editor?
Validation Process (JSON)
{
"course" : "html",
"count" : 2,
"line" : [8, 9],
"check" : ["My name is", ""],
"error" : ["Please type your name. Start with 'My name is'","Write why you want to learn HTML"]
}
HTML & Javascript
var html = ace.edit("html-editor");
html_option = {
mode: "ace/mode/javascript",
theme: "ace/theme/monokai",
fontSize: "10pt",
showPrintMargin : false,
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: true,
wrap: true,
scrollPastEnd: true,
displayIndentGuides: true,
};
html.setOptions(html_option);
//Get the JSON validation file
var fond = $(".json").html();
fond = JSON.parse(fond);
//Begin validation on Click "Run"
$("#run").on("click", function(){
$('#run').html('<i class="fa fa-spinner fa-spin"></i> Running');
var fond_course = fond.course;
var fond_count = fond.count;
//Begin error check
for (var i = 0; i < fond_count; i++) {
var line = fond.line[i] - 1;
var error = fond.error[i] ;
var check = fond.check[i];
var fond_check = html.session.getLine(line);
var patt = new RegExp(check);
var res = patt.test(fond_check);
//If a specific line is empty
if(check === null){
html.gotoLine(line);
line = line + 1;
//Error function with parameters
//error_note(true, error, line);
}
//If a line is not equal to the JSON file value
else if(!res){
html.gotoLine(line);
line = line + 1;
//Error function with parameters
//error_note(true, error, line);
}else if(res && check !== null){
//Code is validated, now save the code
}
}
});
#html-editor{
height: 500px;
}
#run{
font-size: 20px;
padding: 10px;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.5/ace.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.5/ext-language_tools.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="run">Run</button>
<pre id="html-editor"><!DOCTYPE html>
<html>
<head>
<title>Introduction to HTML</title>
</head>
<body>
<h1>Welcome to Code</h1>
<p>Edit and replace with your name</p>
</body>
</html><pre>