What I've learnt in one week of javascript dabbling

Disclaimer: I'm very new to javascript with no computer science background - which is why I'm using low-code database softwares like Knack.. So this post probably contains lessons that might waste a couple mins of your time lol,, but I'm hoping to share some tidbits (and hopefully get some basic ones in return) to grow our collective knowledge on this.

Anyway, I've been trying to delve deeper into javascript lately, and these are a few things i've learnt along the way. Hopefully it saves someone some grief out there. Apologies if it's already in the documentation, but it wasn't always that obvious to me how to do it initially. And do let me know if there are mistakes, or if you have more to contribute below.

1. Finally got autofocus cursor on a field to work

Found this solution in a forum post here somewhere (sorry I forgot where the original post is), but what I didn't realise is that I need to set the viewid to the very last view that's rendered on the page for it to work properly.

So if example on a page, you have 3 views, e.g.

  1. a details view called view_1
  2. a form view called view_2, <-- and this contains field_11 which you want to focus cursor on
  3. a table view called view_3

Then this should work:

var viewId = "view_2";     //this is the view where the autofocus field is in (won't need this here actually)
var lastviewId = "view_3"; // this is the last view on the page
var fieldId = "field_11";

$(document).on('knack-view-render.view_' + lastviewId, function (event, view, data) { //make sure to use the last view on the page, e.g. view_3
$("#" + fieldId).focus(); //set focus
});

If you don't fancy keeping things tidier with the viewId and fieldId variables, then writing the below should be equivalent to the above:

$(document).on('knack-view-render.view_3', function (event, view, data) {   //make sure to use the last view on the page, e.g. view_3
$("#field_11").focus(); //set focus
});

2. To have a timer trigger an action

i.e. ask Knack (or the user's browser?) to start doing stuff after a certain amount of time has elapsed (I used it in conjunction with point #3 below.

I found this solution in one of the documentation examples I believe. And I think it deserves it's own place in my post.

var timer = {};
var TimerDelay = 800; // in milliseconds, e.g. 800 = 0.8 secs

clearTimeout(timer); //reset timer at 0 (I think)
timer = setTimeout(function() { //stuff in this part is called when timer timeout (start of section)
alert('Timer ran out - do stuff here'); //write code here
}, TimerDelay); //2nd argument of timer timeout function (end of section)
}; //restart the timer at 0

3. To have a keyup trigger an action

i.e. ask Knack (or the user's browser?) to start doing stuff when it detects the user has 'lifted' their finger off the keyboard after making an input - I've used this with the timer above for what I wanted to do.

$("#" + viewId).find("#" + fieldId).on('keyup', function() {      //listen for keyup
alert('Key up detected - do stuff here'); //write code here
};

4. Make a field empty (or fill it with something)

//these lines are written as part of a function, with 2 variables viewId and fieldId already set up too] 
$("#" + viewId).find("#" + fieldId).val(''); //clears a field
$("#" + viewId).find("#" + fieldId).val('1'); //fills the field with a value of 1
$("#" + viewId).find("#" + fieldId).val(varA); //fills the field with whatever is stored in variable called varA

5. Some random stuff that any javascript user probably already knows (and why someone like me who refuses to get basic javascript knowledge first should have probably done so)

  • if ( 'xxx' != 'yyy' ) { means test if 'xxx' is NOT equal to 'yyy'
  • end lines with ;
  • if testing live app gives a blank page.. you've stuffed up.. use /* */ to isolate problematic code
  • use console.log or alert(..) to debug errors too (or keep track of values stored in variables)
  • var a = [] // declares an array variable
  • a.push () // adds an element to the array called 'a'
  • a.length // is the variable that stores how big the array is
  • use + to concatenate text or variables
  • use \n to make a line break

Which brings me to... What I've come up with so far which got me to picking up these random 'mini-lessons'

var bars = [];
var viewId = "view_2";
var fieldId = "field_11";
var TimerDelay = 800;

$(document).on('knack-view-render.view_3', function (event, view, data) {

var timer = {};
$("#" + fieldId).prop({type:"number"}); //make the barcode field recognised as a number
$("#" + fieldId).focus(); //set focus
$("#" + viewId).find("#" + fieldId).on('keyup', function() { //listen for keyup
clearTimeout(timer); //restart the timer at 0
if ($("#" + viewId).find("#" + fieldId).val() !== '') { //check if field is blank
timer = setTimeout(function() { //listen for timer timeout
bars.push($("#" + viewId).find("#" + fieldId).val() + '\n'); //add new element to array with a linebreak
alert(bars + '\n Total barcodes ' + bars.length); //show stored data in prompt
$("#" + viewId).find("#" + fieldId).val(''); //clear the barcode field
}, TimerDelay); //2nd argument for setTimeout function
};
});

//still work in progress...

});

My problem was that I was trying to create a form that could scan barcodes reasonably quickly - but I was having a problem of having to click the Submit button after every scan, + having to wait for the transaction to be recorded before scanning the next item.

So what I'm hoping to achieve is to have the barcodes stored in an array variable.. and then after the user clicks submit, to send all the elements in the array into the database.

It's not supposed to have the alert notification pop up every time it scans of course (that's just for me to make sure it's working).

What I haven't figured out:

  • How to show on the webpage what is currently stored in the array variable
  • How to send each element to knack's database when the user clicks submit (I know how to listen for the submit button being pressed, and how to call a particular element in an array, and how to loop iterations)
  • How to create a button that can edit/delete data that is already stored in the array.

If anyone is generous enough to share how I can achieve these, I would be really grateful :D

1 Like

Hi Ting,

Thanks for posting your journey and tips!

Some help with your autofocus function - try using the page render event instead of the last view event: https://www.knack.com/developer-documentation/#page-render

Not sure how to help with your other points directly I'm afraid.

Oh yea.. I also got another form of mine to prefill data when the user clicks the submit button. (In this case, I needed this particular field to increment by 1 based on the previously entered data - but it works a bit differently from the built-in autoincrement function)

$(document).on('knack-view-render.view_155', function (event, view, data) {
$("#view_155").find("#field_42").val(pgnumber); //set pg number
$("#field_42").focus(); //focus pg number
});

$(document).on('knack-form-submit.view_155', function(event, view, record) {
pgnumber = $("#view_155").find("#field_42").val();
pgnumber ++;
});

Hi!

I tried the following code and it works but unfortunately only when scene number matches view number (i.e. scene_3, view_3). Do you have any idea why and how I can adjust the code to solve this problem?

var fieldID = 'field_1';
$(document).on('knack-view-render.view_4', function (event, view) {
  console.log("View rendered");

  // Set focus to the input element
  $("#" + fieldID).focus();
});

Thank you in advance.

Hi @Anett I’m assuming you want this code to work for all views (which are different to scenes) here.

I strongly recommend reading and learning the Knack developer documents and especially the Javascript section. Inside that are the interface events you’re after - https://docs.knack.com/docs/using-javascript-with-knack

In there you’ll find a way to handle the render event for all views, or the event for view types. E.g.:

$(document).on('knack-view-render.any', function(event, view, data) {
  $('#field_1').focus();
});

Or you might prefer to be more specific for forms only:

$(document).on('knack-view-render.form', function(event, view, data) {
  $('#field_1').focus();
});

In other situations you may prefer to use the knack-scene-render events and the developer documnts explain in what order these occur and when.

1 Like