Page 1 of 2
Responsive edit form idea
Posted: Fri Mar 18, 2022 2:32 am
by nc07
Hi all,
This is just an idea and maybe helpful to someone who may want to use this code for viewing on smaller screens. Some code is taken from NB itself.
Note that this is not the optimal way to make form responsive and this code has some flows as some objects such as select2 are not respected.
chrome-capture (3).gif
This code should be placed in the header
Code: Select all
function editResp(){
if(nuFormType() == 'edit'){
columns = 1;
$('.nuPortraitTab').remove();
var o = nuSERVERRESPONSE.objects;
var lw = columns == 1 ? 0 : nuPortraitLabelWidth(o);
var t = 10;
var b = -1;
var W = 0;
for(var i = 0 ; i < o.length ; i++){
var I = o[i].id;
var L = $('#label_' + I).length == 0 ? 0 : $('#label_' + I).outerHeight();
var O = $('#' + I).outerHeight();
W= ('85vw');
if(o[i].tab != b){
b = o[i].tab;
var l = $('#nuTab' + o[i].tab).html();
var d = '<div class="nuPortraitTab" id="nuPort' + b + '" style="top:' + t + 'px" >'+ l +'</div>';
$('#nuRECORD').append(d);
var OH = $('#nuPort' + b ).outerHeight();
t = t + OH + 20;
}
if(o[i].read != 2){
$('#label_' + o[i].id).css({'top' : t+2 , 'left' : 7, 'text-align' : 'left', 'font-weight' : 700});
if(columns == 1){
t = t + L + 5;
}
$('#'+o[i].id).css({'top' : t , 'left' : lw + 10, 'width':'90vw'});
if(o[i].type == 'lookup'){
var w = $('#'+o[i].id+'code').outerWidth();
var dis = $('#'+o[i].id+'description').outerWidth();
W = Math.max(W, w + dis + 30);
var wi =$(this).width();
$('#'+o[i].id+'code').css({'top' : t , 'width':wi/2, 'left' : lw + 10});
$('#'+o[i].id+'button').css({'top' : t , 'left' : lw + w + 15});
// t = t + 25;
$('#'+o[i].id+'description').css({'top' : t, 'left' : lw +w+ 35});
}
t = t + O + 5;
}
}
$("[data-nu-tab!='x'][data-nu-form='']:not([data-nu-lookup-id])").show();
$('#nuTabHolder').hide();
t = t + 50;
$('#nuRECORD').append('<div id="nuPortEnd" style="left:0px;position:absolute;top:' + t + 'px" > </div>');
if(columns == 1){
$('label').css('text-align', 'right').css({'width':W,'text-align':'left','left':15,'border':'1px red'});
}else{
$('label').css('text-align', 'left').css('width', lw);
}
var objectWidth = W + lw + 50;
var screenWidth = window.innerWidth;
var scale = screenWidth/(objectWidth);
$('#nubody').css('width', objectWidth)
.css('transform', 'scale(' + scale + ')');
$('html,body').scrollTop(0).scrollLeft(0);
}
}
function nonresp(){
var o = nuSERVERRESPONSE.objects;
var t = 10;
var b = -1;
var W = 0;
for(var i = 0 ; i < o.length ; i++){
var I = o[i].id;
var L = $('#label_' + I).outerHeight();
var LW = $('#label_' + I).outerWidth();
var wi = $('#' + I).outerWidth();
var O = $('#' + I).outerHeight();
var d = $('#'+o[i].id+'button').outerWidth();
var w = Number(o[i].width);
var T = Number(o[i].top);
var lft = Number(o[i].left);
t = t+L+20;
$('#'+o[i].id).css({'top' : T, 'width':w, 'left':lft});
$('#label_'+o[i].id).css({'top' : T , 'left':lft-w-5,'width':w, 'text-align':'right'});
$('#'+o[i].id+'code').css({'top' : T , 'width':w,'left' : lft});
$('#'+o[i].id+'button').css({'top' : T ,'left' : lft+w+5});
$('#'+o[i].id+'description').css({'top' : T, 'left' :lft+w+d+10});
$('#nuTabHolder').show();
$('.nuPortraitTab').remove();
}
}
the following code should only be placed in
forms custom js that you want to be responsive.
Code: Select all
$(document).ready(function(){
if(nuFormType() == 'edit'){
if ($(window).width() < 700) {
editResp();
}
$(window).resize(function() {
clearTimeout(window.resizedFinished);
window.resizedFinished = setTimeout(function(){
if ($(this).width() <700){
editResp();
}else {
nonresp();
}
}, 50);
});
}
});
Suggetions and comments are welcomed for improvements.
Re: Responsive edit form idea
Posted: Wed Mar 23, 2022 2:47 pm
by kev1n
Hi,
Good job! Maybe the ContentBox should be excluded.
the following code should only be placed in forms custom js that you want to be responsive.
I placed it in one form, then switched to another form. The resize code is also executed for that form.
Re: Responsive edit form idea
Posted: Sun Mar 27, 2022 11:02 pm
by nc07
kev1n wrote: ↑Wed Mar 23, 2022 2:47 pm
Hi,
Good job! Maybe the ContentBox should be excluded.
the following code should only be placed in forms custom js that you want to be responsive.
I placed it in one form, then switched to another form. The resize code is also executed for that form.
Thanks Kevin, I agree that the ContentBox should be excluded.
I have also noticed that resize code is also executed for other forms, still trying to figure out why?. Still working on updates and other possibilities.
Re: Responsive edit form idea
Posted: Tue Mar 29, 2022 4:54 pm
by kev1n
If you change nuResize() in index.php to this (or pull index.php from Github)
Code: Select all
function nuResize(){
if(typeof window['nuOnBeforeResize'] === 'function'){
if (nuOnBeforeResize() == false) return;
}
$('#nuActionHolder').css('width', '100%');
$('#nuBreadcrumbHolder').css('width', '100%');
$('#nuTabHolder').css('width', '100%');
$('.nuTabTitleColumn').css('width', '100%');
$('body').css('width', '100%');
if (window.nuVerticalTabs) {
nuSetVerticalTabs();
}
if(typeof window['nuOnResize'] === 'function'){
nuOnResize();
}
}
nuOnResize() is fired on resize.
Then this (untested) code can be used in the header:
Code: Select all
function isResponsive() {
var f = window.nuFORM.getProperty('form_id');
return f.containsAny(['5ac14228beed98e', // form A
'5aac833a3d8c0db']) // form B
}
function nuOnResize() {
if (isResponsive()) {
clearTimeout(window.resizedFinished);
window.resizedFinished = setTimeout(function() {
if ($(this).width() < 700) {
editResp();
} else {
nonresp();
}
}, 50);
}
}
function nuOnLoad() {
if (nuFormType() == 'edit') {
// Edit Form loaded
$(document).ready(function(){
if (isResponsive()) {
if ($(window).width() < 700) {
editResp();
}
}
});
}
}
Re: Responsive edit form idea
Posted: Tue Mar 29, 2022 11:18 pm
by nc07
Thanks, Kevin, The idea of passing form ID as the solution to the execution of responsive code to specific forms only works well. And now code works when only place in the header. Probably we can have some ideas/suggestions from the forum on improvements to give end-users a better experience on smaller screens.
Re: Responsive edit form idea
Posted: Wed Mar 30, 2022 6:10 pm
by kev1n
I combined your editResp() and nonresp() into a function nuSetResponsive(active).
Calling nuSetResponsive() or nuSetResponsive(true) will make the form responsive, nuSetResponsive(false) will set it back to non-responsive.
Now instead of
Code: Select all
if ($(this).width() < 700) {
editResp();
} else {
nonresp();
}
we can replace it with
Code: Select all
nuSetResponsive($(this).width() < 700);
I also removed some unused variables and renamed some to give them some more meaningful names (there's still some that could be renamed).
Updated code:
Code: Select all
function nuSetResponsive(active) {
if (nuFormType() !== 'edit') return;
var o = nuSERVERRESPONSE.objects;
$('.nuPortraitTab').remove();
// Set non-responsive
if (active === false) {
let top = 10;
for (let i = 0; i < o.length; i++) {
let id = o[i].id;
let loh = $('#label_' + id).outerHeight();
let w = Number(o[i].width);
let t = Number(o[i].top);
let l = Number(o[i].left);
top = top + loh + 20;
$('#' + o[i].id).css({ 'top': t, 'width': w, 'left': l });
$('#label_' + o[i].id).css({ 'top': t, 'left': l - w - 5, 'width': w, 'text-align': 'right' });
$('#' + o[i].id + 'code').css({ 'top': t, 'width': w, 'left': l });
$('#' + o[i].id + 'button').css({ 'top': t, 'left': l + w + 5 });
$('#' + o[i].id + 'description').css({ 'top': t, 'left': l + w + d + 10 });
$('#nuTabHolder').show();
}
return;
}
// Set responsive
columns = 2;
var lw = columns == 1 ? 0 : nuPortraitLabelWidth(o);
var t = 10;
var b = -1;
var W = 0;
for (var i = 0; i < o.length; i++) {
var I = o[i].id;
var O = $('#' + I).outerHeight();
W = ('85vw');
if (o[i].tab != b) {
b = o[i].tab;
var l = $('#nuTab' + o[i].tab).html();
var d = '<div class="nuPortraitTab" id="nuPort' + b + '" style="top:' + t + 'px" >' + l + '</div>';
$('#nuRECORD').append(d);
var OH = $('#nuPort' + b).outerHeight();
t = t + OH + 20;
}
if (o[i].read != 2) {
$('#label_' + o[i].id).css({ 'top': t + 2, 'left': 7, 'text-align': 'left', 'font-weight': 700 });
if (columns == 1) {
let L = $('#label_' + I).length == 0 ? 0 : $('#label_' + I).outerHeight();
t = t + L + 5;
}
$('#' + o[i].id).css({ 'top': t, 'left': lw + 10, 'width': '90vw' });
if (o[i].type == 'lookup') {
var w = $('#' + o[i].id + 'code').outerWidth();
var dis = $('#' + o[i].id + 'description').outerWidth();
W = Math.max(W, w + dis + 30);
var wi = $(this).width();
$('#' + o[i].id + 'code').css({ 'top': t, 'width': wi / 2, 'left': lw + 10 });
$('#' + o[i].id + 'button').css({ 'top': t, 'left': lw + w + 15 });
// t = t + 25;
$('#' + o[i].id + 'description').css({ 'top': t, 'left': lw + w + 35 });
}
t = t + O + 5;
}
}
$("[data-nu-tab!='x'][data-nu-form='']:not([data-nu-lookup-id])").show();
$('#nuTabHolder').hide();
t = t + 50;
$('#nuRECORD').append('<div id="nuPortEnd" style="left:0px;position:absolute;top:' + t + 'px" > </div>');
if (columns == 1) {
$('label').css({ 'width': W, 'text-align': 'left', 'left': 15, 'border': '1px red' });
} else {
$('label').css('text-align', 'left').css('width', lw);
}
var objectWidth = W + lw + 50;
var screenWidth = window.innerWidth;
var scale = screenWidth / (objectWidth);
$('#nubody').css('width', objectWidth)
.css('transform', 'scale(' + scale + ')');
$('html,body').scrollTop(0).scrollLeft(0);
}
function isResponsive() {
var f = window.nuFORM.getProperty('form_id');
return f.containsAny(['5ac14228beed98e', // form A
'5aac833a3d8c0db']) // form B
}
function nuOnResize() {
if (isResponsive()) {
clearTimeout(window.resizedFinished);
window.resizedFinished = setTimeout(function() {
nuSetResponsive($(this).width() < 700);
}, 50);
}
}
function nuOnLoad() {
if (nuFormType() == 'edit') {
$(document).ready(function() {
if (isResponsive()) {
if ($(window).width() < 700) {
editResp();
}
}
});
}
}
An idea I had was to pass a callback function to nuSetResponsive() that is called for every object, before an element's position is set.
In this way a user gets more control when entering the responsive mode: E.g. by hiding certain objects or by setting different dimensions or other positions for objects.
Re: Responsive edit form idea
Posted: Wed Mar 30, 2022 11:21 pm
by nc07
the combined version of the code looks much better, one thing i have noticed is that the labels now remain to the left of the field and not on top.
the onload function
Code: Select all
function nuOnLoad() {
if (nuFormType() == 'edit') {
$(document).ready(function() {
if (isResponsive()) {
if ($(window).width() < 700) {
editResp();
}
}
});
}
}
did not call the responsive function thus should be
Code: Select all
function nuOnLoad() {
if (nuFormType() == 'edit') {
$(document).ready(function() {
if (isResponsive()) {
if ($(window).width() < 700) {
//editResp();
nuSetResponsive(true);
}
}
});
}
}
Also this variable is needed in nonresponsive code block to reset lookup code decription
Code: Select all
var d = $('#'+o[i].id+'button').outerWidth();
I agree with the idea to include callback function because currently all fields via js are shown on ofcouse the developers/users should have controls.
Re: Responsive edit form idea
Posted: Thu Mar 31, 2022 2:01 am
by nc07
a few changes with label issue solved.
Code: Select all
function nuSetResponsive(active) {
if (nuFormType() !== 'edit') return;
var o = nuSERVERRESPONSE.objects;
$('.nuPortraitTab').remove();
// Set non-responsive
if (active === false) {
let top = 10;
for (let i = 0; i < o.length; i++) {
let id = o[i].id;
let loh = $('#label_' + id).outerHeight();
let d = $('#'+o[i].id+'button').outerWidth();
let w = Number(o[i].width);
let t = Number(o[i].top);
let l = Number(o[i].left);
top = top + loh + 20;
$('#' + o[i].id).css({ 'top': t, 'width': w, 'left': l });
$('#label_' + o[i].id).css({ 'top': t, 'left': l - w - 5, 'width': w, 'text-align': 'right' });
$('#' + o[i].id + 'code').css({ 'top': t, 'width': w, 'left': l });
$('#' + o[i].id + 'button').css({ 'top': t, 'left': l + w + 5 });
$('#' + o[i].id + 'description').css({ 'top': t, 'left': l + w + d + 10 });
$('#nuTabHolder').show();
}
return;
}
// Set responsive
columns = 1;
var lw = columns == 1 ? 0 : nuPortraitLabelWidth(o);
var t = 10;
var b = -1;
var W = 0;
for(var i = 0 ; i < o.length ; i++){
var I = o[i].id;
let L = $('#label_' + I).length == 0 ? 0 : $('#label_' + I).outerHeight();
var O = $('#' + I).outerHeight();
W= ('85vw');
if(o[i].tab != b){
b = o[i].tab;
var l = $('#nuTab' + o[i].tab).html();
var d = '<div class="nuPortraitTab" id="nuPort' + b + '" style="top:' + t + 'px" >'+ l +'</div>';
$('#nuRECORD').append(d);
var OH = $('#nuPort' + b ).outerHeight();
t = t + OH + 20;
}
if(o[i].read != 2){
$('#label_' + o[i].id).css({'top' : t+2 , 'left' : 7, 'text-align' : 'left', 'font-weight' : 700});
if(columns == 1){
t = t + L + 5;
}
$('#'+o[i].id).css({'top' : t , 'left' : lw + 10, 'width':'90vw'});
if(o[i].type == 'lookup'){
var cw = $('#'+o[i].id+'code').outerWidth();
var dis = $('#'+o[i].id+'description').outerWidth();
W = Math.max(W, cw + dis + 30);
var wi =$(this).width();
$('#'+o[i].id+'code').css({'top' : t , 'width':wi/2, 'left' : lw + 10});
$('#'+o[i].id+'button').css({'top' : t , 'left' : lw + cw + 15});
$('#'+o[i].id+'description').css({'top' : t, 'left' : lw +cw+ 35});
}
t = t + O + 5;
}
}
$("[data-nu-tab!='x'][data-nu-form='']:not([data-nu-lookup-id])").show();
$('#nuTabHolder').hide();
t = t + 50;
$('#nuRECORD').append('<div id="nuPortEnd" style="left:0px;position:absolute;top:' + t + 'px" > </div>');
if(columns == 1){
$('label').css('text-align', 'right').css({'width':W,'text-align':'left','left':15,'border':'1px red'});
}else{
$('label').css('text-align', 'left').css('width', lw);
}
var objectWidth = W + lw + 50;
var screenWidth = window.innerWidth;
var scale = screenWidth/(objectWidth);
$('#nubody').css('width', objectWidth)
.css('transform', 'scale(' + scale + ')');
$('html,body').scrollTop(0).scrollLeft(0);
}
function isResponsive() {
var f = window.nuFORM.getProperty('form_id');
return f.containsAny(['621fdb9842fea17', // form A
'6233976caaea6ec']); // form B
}
function nuOnResize() {
if (isResponsive()) {
clearTimeout(window.resizedFinished);
window.resizedFinished = setTimeout(function() {
nuSetResponsive($(this).width() < 700);
}, 50);
}
}
function nuOnLoad() {
if (nuFormType() == 'edit') {
$(document).ready(function() {
if (isResponsive()) {
if ($(window).width() < 700) {
//editResp();
nuSetResponsive(true);
}
}
});
}
}
Re: Responsive edit form idea
Posted: Wed Apr 06, 2022 3:08 pm
by kev1n
Code further improved:
- Hides contentbox in responsive mode
- Fixed lookup overlappings
- Changes a few variable names for better readability
Code: Select all
function nuSetResponsive(active) {
if (nuFormType() !== 'edit') return;
var o = nuSERVERRESPONSE.objects;
$('.nuPortraitTab').remove();
// Set non-responsive
if (active === false) {
let top = 10;
for (let i = 0; i < o.length; i++) {
let id = o[i].id;
let lOh = $('#label_' + id).outerHeight();
let bOh = $('#' + o[i].id + 'button').outerWidth();
let w = Number(o[i].width);
let t = Number(o[i].top);
let l = Number(o[i].left);
top = top + lOh + 20;
$('#' + id).css({ 'top': t, 'width': w, 'left': l });
$('#label_' + o[i].id).css({ 'top': t, 'left': l - w - 5, 'width': w, 'text-align': 'right' });
$('#' + id + 'code').css({ 'top': t, 'width': w, 'left': l });
$('#' + id + 'button').css({ 'top': t, 'left': l + w + 5 });
$('#' + id + 'description').css({ 'top': t, 'left': l + w + bOh + 10 });
nuSetLabelText(id, $('#label_' + o[i].id).html(), true);
}
$('#nuTabHolder').show();
} else {
// Set responsive
columns = 1;
var lw = columns == 1 ? 0 : nuPortraitLabelWidth(o);
var t = 10;
var b = -1;
var W = 0;
for (var i = 0; i < o.length; i++) {
var id = o[i].id;
W = ('85vw');
if (o[i].tab != b) {
b = o[i].tab;
var l = $('#nuTab' + o[i].tab).html();
var d = '<div class="nuPortraitTab" id="nuPort' + b + '" style="top:' + t + 'px" >' + l + '</div>';
$('#nuRECORD').append(d);
var OH = $('#nuPort' + b).outerHeight();
t = t + OH + 20;
}
if (o[i].read != 2) {
let oType = o[i].type;
if (oType == 'contentbox') {
nuHide(id);
} else {
$('#label_' + id).css({ 'top': t + 2, 'left': 7, 'text-align': 'left', 'font-weight': 700 });
if (columns == 1) {
let oh = $('#label_' + id).length == 0 ? 0 : $('#label_' + id).outerHeight();
t = t + oh + 5;
}
$('#' + id).css({ 'top': t, 'left': lw + 10, 'width': '90vw' });
if (oType == 'lookup') {
let cw = $('#' + id + 'code').outerWidth();
let dis = $('#' + id + 'description').outerWidth();
W = Math.max(W, cw + dis + 30);
let wi = $(this).width();
$('#' + id + 'code').css({ 'top': t, 'width': wi / 3, 'left': lw + 10 });
$('#' + id + 'button').css({ 'top': t, 'left': lw + wi / 3 + 15 });
$('#' + id + 'description').css({ 'top': t, 'left': lw + wi / 3 + 35 });
}
let oh = $('#' + id).outerHeight();
t = t + oh + 5;
}
}
}
// is this line necessary?
// $("[data-nu-tab!='x'][data-nu-form='']:not([data-nu-lookup-id])").show();
$('#nuTabHolder').hide();
t = t + 50;
$('#nuRECORD').append('<div id="nuPortEnd" style="left:0px;position:absolute;top:' + t + 'px" > </div>');
if (columns == 1) {
$('label').css('text-align', 'right').css({ 'width': W, 'text-align': 'left', 'left': 15, 'border': '1px red' });
} else {
$('label').css('text-align', 'left').css('width', lw);
}
var objectWidth = W + lw + 50;
var screenWidth = window.innerWidth;
var scale = screenWidth / (objectWidth);
$('#nubody').css('width', objectWidth)
.css('transform', 'scale(' + scale + ')');
$('html,body').scrollTop(0).scrollLeft(0);
}
}
function isResponsive() {
var f = window.nuFORM.getProperty('form_id');
return f.containsAny(['621fdb9842fea17', // form A
'6233976caaea6ec']); // form B
}
function nuOnResize() {
if (isResponsive()) {
clearTimeout(window.resizedFinished);
window.resizedFinished = setTimeout(function() {
nuSetResponsive($(this).width() < 700);
}, 50);
}
}
function nuOnLoad() {
if (nuFormType() == 'edit') {
$(document).ready(function() {
if (isResponsive()) {
if ($(window).width() < 700) {
//editResp();
nuSetResponsive(true);
}
}
});
}
}
Re: Responsive edit form idea
Posted: Tue Apr 12, 2022 6:30 am
by nc07
The latest code solved most of the issues. I think file objects should also be excluded. Also, there are overlapping of labels on Checkbox and auto numbers when in nonresponsive mode. i will have a further look soon.