javascript on action error - javascript

after changing the select box it must collect checked check box ids and the submit it
$("#action").change(function(){
if(($(this).val())!='0'){
var data = { 'req_ids[]' : []};
var doit = $("#action").val();
$(".checkboxes:checked").each(function(){
data['req_ids[]'].push($(this).attr('id'));
});
var size = Object.size(data['req_ids[]']);
if(size>0){
$.post("workplan-requests.php?action=update&do="+doit, data);
$("tr.checked").remove();
}
$("#action").val('0');
}
});
but when i select my action in select box by changing it,
it show this error:
TypeError: Object.size is not a function
var size = Object.size(data['req_ids[]']);
i know this error is because the java script run whole code at same time but how can i do this with out problem!?

it should be
var size = data['req_ids[]'].length;
Also try
$("#action").change(function () {
if (($(this).val()) != '0') {
var data = {};
data['req_ids[]'] = $(".checkboxes:checked").map(function () {
return this.id
}).get();
var size = data['req_ids[]'].length;
if (size > 0) {
var doit = $("#action").val();
$.post("workplan-requests.php?action=update&do=" + doit, data);
$("tr.checked").remove();
}
$("#action").val('0');
}
});

Related

refresh drop down list after button click in web app

I have a web app with one drop down list and 2 buttons. The drop down list get values from a sheet. The buttons write back in the sheet. The script I have works fine with that:
<script>
$(function() {
$('#txt1').val('');
google.script.run
.withSuccessHandler(updateSelect)
.getSelectOptions();
});
function updateSelect(opt)
{
var select = document.getElementById("sel1");
select.options.length = 0;
for(var i=0;i<opt.length;i++)
{
select.options[i] = new Option(opt[i],opt[i]);
}
}
function listS() {
const selectElem = document.getElementById('sel1')
const index = selectElem.selectedIndex;
if (index > -1) {
const e = document.getElementById("sel1");
const value = e.options[index].value;
const body = { index: index, value: value };
google.script.run.withSuccessHandler(yourCallBack).yourServerSideFunc(body);
}
}
document.getElementById("but1").addEventListener("click",listS);
function yourCallBack(response) {
}
</script>
In Java script:
function getSelectOptions()
{
var ss=SpreadsheetApp.openById('1onuWoUKh1XmvEAmKktwJekD782BFIru-MDA0omqzHjw');
var sh=ss.getSheetByName('Database');
var rg=sh.getRange(2,1,sh.getLastRow()-1,8);
var vA=rg.getValues();
var useremail = Session.getActiveUser().getEmail();
var opt=[];
for(var i=0;i<vA.length;i++)
{
if(vA[i][1] == "Pending Approval"){
if(vA[i][7]+"#xxx.com" == useremail || vA[i][7]+"#xxx.com" == useremail) {
opt.push(vA[i][3]+" REQ ID: "+vA[i][0]);
}
}
};
if (opt.length == 0) {opt.push("You do not have pending requests")};
return opt;
}
function doGet() {
var output = HtmlService.createHtmlOutputFromFile('list');
return output;
}
function yourServerSideFunc(body) {
var value = body["value"];
var ss = SpreadsheetApp.openById('1onuWoUKh1XmvEAmKktwJekD782BFIru-MDA0omqzHjw');
var sh = ss.getSheetByName('Database');
var rg=sh.getRange(1,1,sh.getLastRow()-1,4);
var vA=rg.getValues();
var str = "Approved";
for(var i=0;i<vA.length;i++)
{
if(vA[i][3]+" REQ ID: "+vA[i][0] == value) {
sh.getRange(i+1, 2).setValue(str);
}
};
return ContentService.createTextOutput(JSON.stringify({message: "ok"})).setMimeType(ContentService.MimeType.JSON);
Now I am trying to regenerate the drop down list values after the button is clicked. I tried to add
var output = HtmlService.createHtmlOutputFromFile('list');
return output;
in yourServerSideFunc(body) function to regenerate the HTML but does not work. I have tried to force a HTML refresh, but also did not work.
How can I easily re-trigger the generation of the drop down list items? Worst case scenario it is ok to refresh the whole page, but it should be simple to regenerate the drop down list since I have already the code for it.
I ended up with this work around.
function listS() {
const selectElem = document.getElementById('sel1')
const index = selectElem.selectedIndex;
if (index > -1) {
const e = document.getElementById("sel1");
const value = e.options[index].value;
const body = { index: index, value: value };
google.script.run.withSuccessHandler(yourCallBack).yourServerSideFunc(body);
//ADDED:
var select = document.getElementById("sel1");
select.options[index] = new Option("Approved! Please refresh","Approved! Please refresh");
selectElem.selectedIndex = index;
}
}
It does not really meet the original goal to refresh the list from the sheet. It would be great if someone else posted a solution to call the server function. I tried to add google.script.run.doGet() and similar, but it seems that it does not call the server side functions properly.

Why searchbox become lagging when typing word to search data in CSV?

I developed the store locator using open street map and leaflet. The problem is when I want to type in searchbox it will become lagging to finish the word. That store locator read from the CSV file that has 300++ data. Below is the code for the searchbox:
var locationLat = [];
var locationLng = [];
var locMarker;
var infoDiv = document.getElementById('storeinfo');
var infoDivInner = document.getElementById('infoDivInner');
var toggleSearch = document.getElementById('searchIcon');
var hasCircle = 0;
var circle = [];
//close store infor when x is clicked
var userLocation;
$("#infoClose").click(function() {
$("#storeinfo").hide();
if (map.hasLayer(circle)) {
map.removeLayer(circle);
}
});
var listings = document.getElementById('listingDiv');
var stores = L.geoJson().addTo(map);
var storesData = omnivore.csv('assets/data/table_1.csv');
function setActive(el) {
var siblings = listings.getElementsByTagName('div');
for (var i = 0; i < siblings.length; i++) {
siblings[i].className = siblings[i].className
.replace(/active/, '').replace(/\s\s*$/, '');
}
el.className += ' active';
}
function sortGeojson(a,b,prop) {
return (a.properties.name.toUpperCase() < b.properties.name.toUpperCase()) ? -1 : ((a.properties.name.toUpperCase() > b.properties.name.toUpperCase()) ? 1 : 0);
}
storesData.on('ready', function() {
var storesSorted = storesData.toGeoJSON();
//console.log(storesSorted);
var sorted = (storesSorted.features).sort(sortGeojson)
//console.log(sorted);
storesSorted.features = sorted;
//console.log(storesSorted)
stores.addData(storesSorted);
map.fitBounds(stores.getBounds());
toggleSearch.onclick = function() {
//var s = document.getElementById('searchbox');
//if (s.style.display != 'none') {
//s.style.display = 'yes';
//toggleSearch.innerHTML = '<i class="fa fa-search"></i>';
//$("#search-input").val("");
//search.collapse();
//document.getElementById('storeinfo').style.display = 'none';
//$('.item').show();
//} else {
//toggleSearch.innerHTML = '<i class="fa fa-times"></i>';
//s.style.display = 'block';
//attempt to autofocus search input field when opened
//$('#search-input').focus();
//}
};
stores.eachLayer(function(layer) {
//New jquery search
$('#searchbox').on('change paste keyup', function() {
var txt = $('#search-input').val();
$('.item').each(function() {
if ($(this).text().toUpperCase().indexOf(txt.toUpperCase()) != -1) {
$(this).show();
} else {
$(this).hide();
}
});
});
I dont know what is the cause of the lag in the search box. It is something wrong in code or the csv file? Thank you
Every iteration of $('.item').each is causing a layout change because $(this).hide() or $(this).show() causes the item to removed/added to the DOM as the style is set to display:none back and forth. DOM manipulations and the corresponding layout changes are expensive.
You can consider accumulating the changes and doing one batch update to the DOM using a function like appendChild

SharePoint 2013 list column title modification with javascript

I want to modify SharePoint 2013 list column title in views with javascript. There is a code I found here at stackoverflow, but I want to reference the column with the display name / internal name, not with the column position.
(function () {
function preTaskFormRenderer(renderCtx) {
modifyHeaderData(renderCtx);
}
function modifyHeaderData(renderCtx)
{
var viewTitle = renderCtx.viewTitle;
var linkTitleField = renderCtx.ListSchema.Field[1];
linkTitleField.DisplayName = viewTitle + ':' + linkTitleField.DisplayName;
}
function registerRenderer()
{
var ctxForm = {};
ctxForm.Templates = {};
ctxForm.OnPreRender = preTaskFormRenderer;
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(ctxForm);
}
ExecuteOrDelayUntilScriptLoaded(registerRenderer, 'clienttemplates.js');
})();
Example:
SP.SOD.executeFunc("clienttemplates.js", "SPClientTemplates", function() {
SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
OnPreRender: function(ctx) {
var field = getFieldByDisplayName(ctx,"Task Name");
if(field)
field.DisplayName = "Task Name:::";
}
});
});
function getFieldByDisplayName(ctx,name)
{
var result = ctx.ListSchema.Field.filter(function(f){return f.DisplayName == name;} ); //find field by display name
return result.length > 0 ? result[0] : null;
}
Result

BarcodeScanner2 = TypeError: Cannot set property 'innerHTML' of null

I am trying to develop a barcode scanning app using phonegap-1.4.1 in android. I am trying to store all the values in an array code[] and later on I am displaying the values using the array. I am creating a local storage of the values. Here is my declaration of an array and a counter.
localStorage["counter"]=0;
var code = ["Test1", "Test2","Test3", "Test4"];
localStorage.setItem("code", JSON.stringify(code));
Here is my javascript file for scanning the barcode and I am using an recursive function in this so that the app scanning continues and the values are stored in the array.
var scanCode = function () {
window.plugins.barcodeScanner.scan(
function (result) {
if(result.cancelled == true ) {
window.location.href = 'page5.html';
} else {
var test2 = JSON.parse(localStorage.getItem("code"));
var k = parseInt(localStorage.getItem("counter"));
document.getElementById(test2[k]).innerHTML = "result.text";
k++;
localStorage["counter"] = k;
alert("Scanned Code: " + result.text + ". Format: " + result.format + ". Cancelled: " + result.cancelled);
scanCode();}
}, function (error) {
alert("Scan failed: " + error);
window.location.href = 'page5.html';
});
}
And after storing the values I am displaying the values in some page5.html as
<tr>
<td >1</td>
<td>
<p id="Test1"></p></td>
</tr>
But I am getting the error as BarcodeScanner2 = TypeError: Cannot set property 'innerHTML' of null. Somebody please help me on this issue. Thanks in advance.
Add below javascript Function in your html file ( top of the page).
function SaveDataToLocalStorage(barcodeValue)
{
var oldItems = JSON.parse(localStorage.getItem('barcodes')) || [];
var newItem = {
'barcode': barcodeValue
};
oldItems.push(newItem);
localStorage.setItem('barcodes', JSON.stringify(oldItems));
}
Now Change Your barcode Scan Code as below :
var scanCode = function () {
window.plugins.barcodeScanner.scan(function (result) {
if(result.cancelled == true ) {
window.location.href = 'page5.html';
} else {
// below function save your data in localstorage.
SaveDataToLocalStorage(result.text);
scanCode();
}
}, function (error) {
alert("Scan failed: " + error);
window.location.href = 'page5.html';
});
}
Now, if you want to display all barcodes in page5.html just read all barcodes from localstorage and display it in page.
use following function page5.html to display all barcodes in page5.html
function displayValues()
{
var oldItems = JSON.parse(localStorage.getItem('barcodes')) || [];
for(var i=oldItems.length-1;i>=0;i--)
{
var html=document.getElementById("allCodes").innerHTML;
document.getElementById("allCodes").innerHTML=html+"<br>"+oldItems[i].barcode;
}
}
make one div name allCodes in page5.html
Your page5.html
<body>
<div id="allCodes">
</div>
</body>
<script>
function displayValues()
{
var oldItems = JSON.parse(localStorage.getItem('barcodes')) || [];
for(var i=oldItems.length-1;i>=0;i--)
{
var html=document.getElementById("allCodes").innerHTML;
document.getElementById("allCodes").innerHTML=html+"<br>"+oldItems[i].barcode;
}
}
displayValues();
</script>
//Display in table :
function displayValues()
{
var oldItems = JSON.parse(localStorage.getItem('barcodes')) || [];
if(oldItems.length>0)
{
document.getElementById("allCodes").innerHTML="<table border='2'>";
}
for(var i=oldItems.length-1;i>=0;i--)
{
var html=document.getElementById("allCodes").innerHTML;
html=html+"<tr><td>"+oldItems[i].barcode+"</td></tr>";
document.getElementById("allCodes").innerHTML=html;
}
if(oldItems.length>0)
{
var old=document.getElementById("allCodes").innerHTML;
document.getElementById("allCodes").innerHTML=old+"</table>"
}
}
The error is clearly related to document.getElementById(test2[k]) returning no element, hence, there is no element with the id given. In your sample this would be Test1.
Set the id of the paragraph to Test1 instead of Text and it find the element.

Cannot search multiselect after modification

I have 2 multi selects in a page, and I need to transfer some of the option in first into second, while mantaining the search capabilities.
The problem is, that when I use the search input, it restores the selects to their original options...
Here is the jquery search function:
jQuery.fn.filterByText = function(textbox) {
return this.each(function() {
var select = this;
var options = [];
$(select).find('option').each(function() {
options.push({value: $(this).val(), text: $(this).text()});
});
$(select).data('options', options);
$(textbox).bind('change keyup', function() {
var options = $(select).empty().data('options');
var search = $.trim($(this).val());
var regex = new RegExp(search,"gi");
$.each(options, function(i) {
var option = options[i];
if(option.text.match(regex) !== null) {
$(select).append(
$('<option>').text(option.text).val(option.value)
);
}
});
});
});
};
Here is the js fiddle : http://jsfiddle.net/C2XXR/ !
*I believe the problem lies in the options variable, but have no idea on how to solve it *
Thanks!
I have updated the fiddle. http://jsfiddle.net/C2XXR/2/
I have updated the code for right and left transfer. You have to change the option array itself got the filter, adding them in the dom will not work. In the changed code one issue is once we add from right to left or left to right it is getting added in the last position of the target select.
Please check and let me know if this is what you want.
Below is the main changed function. Later you can create a common function i suppose. Code can be optimized more.
$('[id^=\"btnRight\"]').click(function (e) {
var selected = $(this).parent().prev('select');
var target = $(this).parent().next('select');
target.find('option[value="999"]').remove()
var options = selected.data('options');
var selectedVal = selected.find('option:selected').val()
var tempOption = [];
$.each(options, function(i) {
var option = options[i];
if(option.value != selectedVal) {
tempOption.push(option);
}
});
var targetOptions = target.data('options');
targetOptions.push({value: selected.find('option:selected').val(), text: selected.find('option:selected').text()});
target.data('options', targetOptions);
selected.find('option:selected').remove().appendTo('#isselect_code');
selected.data('options', tempOption);
});
$('[id^=\"btnLeft\"]').click(function (e) {
var selected = $(this).parent().next('select');
var target = $(this).parent().prev('select');
var options = selected.data('options');
var selectedVal = selected.find('option:selected').val()
var tempOption = [];
$.each(options, function(i) {
var option = options[i];
if(option.value != selectedVal) {
tempOption.push(option);
}
});
if( tempOption.length == 0 )
{
// add 999 here
}
var targetOptions = target.data('options');
targetOptions.push({value: selected.find('option:selected').val(), text: selected.find('option:selected').text()});
target.data('options', targetOptions);
selected.find('option:selected').remove().appendTo('#canselect_code');;
selected.data('options', tempOption);
});
the problem with your code is that after you click btnRight or btnLeft your collection of options for each select is not updated, so try after click on each button to call your filterByText as the following :
$('[id^=\"btnRight\"]').click(function (e) {
$(this).parent().next('select').find('option[value="999"]').remove()
$(this).parent().prev('select').find('option:selected').remove().appendTo('#isselect_code');
$('#canselect_code').filterByText($('#textbox'), true);
$('#isselect_code').filterByText($('#textbox1'), true)
});
$('[id^=\"btnLeft\"]').click(function (e) {
$(this).parent().next('select').find('option:selected').remove().appendTo('#canselect_code');
$('#canselect_code').filterByText($('#textbox'), true);
$('#isselect_code').filterByText($('#textbox1'), true)
});

Categories