Jump to content

An elusive input fields matrix


ajoo

Recommended Posts

Hi all !

I  am trying to make a 3 by 3 grid of input fields inside a form using. I have created a fiddle here https://jsfiddle.net/68pgk2d4/

It simply creates a column of 9 input fields. What I want to do is to place them as below.

1 -- 4 -- 7 

2 -- 5 -- 8

3 -- 6 -- 9

If I try and manipulate the css properties of the fields after they have created ( as an eg I have changed the color property ), it affects all the fields created till that stage and not just the newly created field. ( un-commenting  i=1, will change the color of all the fields to that color. The magenta color of the 1,2,3 fields also gets changed).  I would like to know if there is a way to get a handle on each of the cells so as to target them specifically.

Please can someone help me accomplish this. 

Thanks !

 

 

Link to comment
Share on other sites

I wouldn't be surprised if there's a better way to do this, but you could build your matrix upfront.

$( document ).ready(function(){
  //INITIALIZE MATRIX
  var outputMatrix = [
    [0,0,0],
    [0,0,0],
    [0,0,0],
  ];
  
  //GET MATRIX VALUES
  counter = 0;		
  for(i=0; i<3; i++) {
    for(j=0; j<3; j++) {
      counter++;
      outputMatrix[j][i] = counter;
    }
  }		
  
  //DISPLAY MATRIX SO FAR
  console.log(outputMatrix);  //<-- display matrix in browser logs - remove when done testing
});

The "counter" values should now be sorted as

[
  [1, 4, 7],
  [2, 5, 8],
  [3, 6, 9],
]

From there, you could loop through each entry to display the matrix. Instead of outputting a <br> tag between each input, you could float the inputs to the left. When you get to a new set of inputs (e.g. 2,5,8 and 3,6,9), you can clear the float. That way 1,4,7 will be on one line; 2,5,8 will be on the next; and so on.

Link to comment
Share on other sites

$('input').css({backgroundColor: '#aaff11'});

means set all "input"s to this background color - so they all get the same value on each call.

try

$( document ).ready(function(){

    ccmatrix = $("#ccMatrix");
    var form = $("<form/>", {action: '#',method: '#'}); 
    counter = 0;        
        for(i=0; i<3; i++)
        {
            if(i===0) clr = '#ff11aa';
            if(i===1) clr = '#aaff11';
            if(i===2) clr = '#11aaff';
            
            for(j=0; j<3; j++)
            {    
                $(ccmatrix).append($("<input/>", {
                    type: 'text',
                    id: 'result',
                    name: 'u_i',
                    size: '1px',
                    value: j*3+i+1,
                    style: 'background-color:'+clr
                    }))
      
            }
            $(ccmatrix).append('<br>');
        }        
});

 

  • Like 1
Link to comment
Share on other sites

I would use grid. Using the data-pos="n" attribute selector in CSS and JS you change the color as you want. You could also just use the IDs in the linked fiddle if that's easier.

You could also use the nth-of-type() selector in CSS to cut down on the typing if you want.

Edited by maxxd
thought came to me...
  • Like 1
Link to comment
Share on other sites

Hi all !

Thank you for all the inputs. That's a lot of information to digest early morning !!😄 

@ cyberRoot : The values are not available upfront, hence the input fields are used for the grid. But thank you very much for the idea. 

@,maxxd: I'll check out the grid. I have read about it but thought this should be simple enuff to do using css and positioning. Thank you. 

@Guru Barand:  Sir, it took me  a long time to figure this out when i couldn't get to position the blocks correctly and the values in loops made no sense at all. That's when I tried to color the boxes to see what was going on and finally after hours realized that the changes were cascaded to all the previous input elements formed as well. 

Thanks !

Link to comment
Share on other sites

Hi 

@Guru Barand : I have modified the jsfiddle slightly and I want to get the bottom two blocks to somehow be placed next to the first red block.

https://jsfiddle.net/Lk5fzwbu/

The values inside the boxes are not the inputs but simply a way for me to identify them. This way the tab key moves the cursur down the column of fields as I would want it to move, i.e. downwards and not sideways, I tried to create a param ( commented out in the fiddle ) string to provide for more styles and replace the single background style but it did not work and also, surprisingly, did not give any error as well. The idea was to change the top and left absolute position of the 3rd and 6th box to place them by the side of the first block. The lower boxes would be placed relatively correctly I suppose like in the first block. It did not work at all. 😰

I could not find a single example which shows the usage / correct syntax of style inside the append method. 

Please suggest. 

Thanks loads !

 

Link to comment
Share on other sites

Using my original code with the addition of "tabindex" attributes to control the input order ...

$( document ).ready(function(){

    ccmatrix = $("#ccMatrix");
    var form = $("<form/>", {action: '#',method: '#'}); 
    counter = 0;        
        for(i=0; i<3; i++)
        {
            if(i===0) clr = '#ff11aa';
            if(i===1) clr = '#aaff11';
            if(i===2) clr = '#11aaff';
            
            for(j=0; j<3; j++)
            {    
                $(ccmatrix).append($("<input/>", {
                    type: 'text',
                    id: 'result',
                    name: 'u_i',
                    size: '1px',
                    tabindex: j*3+i+1,
                    style: 'background-color:'+clr
                    }))
      
            }
            $(ccmatrix).append('<br>');
        }        
});

 

image.png

  • Like 1
Link to comment
Share on other sites

Thank you Guru Barand !

May I ask if and how can we set more than one style property in the style attribute passed to input

style: 'background-color:'+clr

I tried to add change some more styles but either it's not permissible, though i doubt that, or constructing comma separated key : value pairs is not permitted. Please show the correct syntax if that can be achieved. 

What other key value can be set in the Input dynamically? Like i said earlier, I could not find any tutorial or example demonstrating other such changes. 

Finally one last thing, how can I set focus to any one particular box, say the middle one ( 5th one )?

Thanks loads !

Link to comment
Share on other sites

try

<script type="text/javascript">

var colors = [ 'red', 'green', 'blue', 'yellow', 'cyan', 'magenta', 'orange', 'coral', 'khaki' ]

$( document ).ready(function(){

    ccmatrix = $("#ccMatrix");
    var form = $("<form/>", {action: '#',method: '#'}); 
    counter = 0;        
        for(i=0; i<3; i++)
        {
            
            for(j=0; j<3; j++)
            {    
                var clr = colors[j*3+i]
                $(ccmatrix).append($("<input/>", {
                    type: 'text',
                    id: 'result',
                    name: 'u_i',
                    size: '1px',
                    tabindex: j*3+i+1,
                    autofocus: ( j*3+i+1==5 ),                                                        // set focus on 5th when page loads
                    style: 'background-color:'+clr+'; color:white; text-align:right; font-weight:600'
                    }))
      
            }
            $(ccmatrix).append('<br>');
        }        
});
</script>

 

  • Thanks 1
Link to comment
Share on other sites

Hi, 

I'll try out things and revert. I created my string of params ( commented in my fiddle ) separated by  ',' and space but did not try it with the semi colon.🤔

I do have a question though, by using styles like this would I be upsetting the CSP Policy ? Would this be considered as inline ? In which case it could be a problem since I have kept all my code thus far to be CSV compliant. 

Thanks loads Guru Barand ! 🙏

Link to comment
Share on other sites

hi Guru Barand,

This is how I finally managed to do it using css

$( document ).ready(function(){
    ccmatrix = $("#ccMatrix");
    var form = $("<form/>", {action: '#',method: '#'}); 
    counter = 0;        
        for(i=0; i<3; i++)
        {
            for(j=0; j<3; j++)
            {    
                ind = j*3+i;      
                if(ind<3) clr = '#ff11aa';
                if(ind>=3 && ind<6) clr = '#aaff11';
                if(ind>=6 && ind<=9) clr = '#11aaff';
  
                $(ccmatrix).append($("<input/>", {
                    type: 'text',
                    class: 'result',
                    name: 'u_i',
                    size: '1px',
                    tabindex: j*3+i,
                    value: j*3+i
                    }));

                $("input[tabindex = "+ind+"]").css('backgroundColor', clr);    
            }
            $(ccmatrix).append('<br>');          
          }        
});

using the tabindex property of the input to target a specific input element in the matrix using 

$("input[tabindex = "+ind+"]").css('backgroundColor', clr);

I hope this is the right way to go about it. If there is a better simpler way, please suggest. Could I have done it using say the class property or the name of the input field instead of using tabIndex? If so, then can you kindly demonstrate how it could be done by that method. 

Thank you !!

 

 

Link to comment
Share on other sites

You're looking to avoid inline styles, correct? If so, the following line of code doesn't really change anything:

$("input[tabindex = "+ind+"]").css('backgroundColor', clr);

You'll still end up with the style attribute attached to each individual input tag. Instead, you could define classes (as suggested by Barand) for your colors. I would name the classes based on whatever each color represents.

To apply the class names to the input fields, you could use the .addClass() method. More informaiton can be found here:
https://api.jquery.com/addClass/

Basically, you would define a variable like you did for "clr". Maybe the variable would be named something like "clrClass", which would be set to whatever class names you decide to use. So basically, the following lines would be replaced with the new variable and class names:

if(ind<3) clr = '#ff11aa';
if(ind>=3 && ind<6) clr = '#aaff11';
if(ind>=6 && ind<=9) clr = '#11aaff';

Then use your tabindex method like the following:

$("input[tabindex = "+ind+"]").addClass(clrClass);

 

  • Like 1
Link to comment
Share on other sites

How about

<script type="text/javascript">

    $( document ).ready(function(){

        ccmatrix = $("#ccMatrix");
        var form = $("<form/>", {action: '#',method: '#'}); 
                
            for(i=0; i<3; i++)
            {
                for(j=0; j<3; j++)
                {    
                    cname = "col"+j                              // class name for each column
      
                    $(ccmatrix).append($("<input/>", {
                        type: 'text',
                        class: 'result ' + cname,
                        name: 'u_i',
                        tabindex: j*3+i,
                        value: j*3+i,
                        autofocus: j+i==0
                        }));

                }
                $(ccmatrix).append('<br>');          
              }        
    });

</script>

<style type="text/css">
   .col0 { background-color: #ff11aa;}
   .col1 { background-color: #aaff11;}
   .col2 { background-color: #11aaff;}
   .result {text-align: right; width: 50px; padding: 4px; margin: 8px }
</style>

image.png.2491d2c08ea4a2752e4b2a0dde260866.png

  • Thanks 1
Link to comment
Share on other sites

5 hours ago, ajoo said:

I hope this is the right way to go about it.

It's not.

5 hours ago, ajoo said:

If there is a better simpler way, please suggest.

Here.

5 hours ago, ajoo said:

Could I have done it using say the class property or the name of the input field instead of using tabIndex?

Yes.

5 hours ago, ajoo said:

If so, then can you kindly demonstrate how it could be done by that method. 

Here.

Admittedly, I'm asking you to think a little when it comes to some of it, but ... really? Beyond that, Barand has been his typical self and gone above and beyond the call of duty to answer your questions in no uncertain terms and with concrete code examples; yet there are more requests to simply do it for you.

  • Like 1
Link to comment
Share on other sites

Hi !

@cyberRoot Thank you for that insight. Yes I am trying to avoid any inline code. After what you have pointed out, I think I will have to scrutinize my existing code as well.

I think Guru Barand has implemented the addclass mechanism, you suggested in your reply already.

@maxxd Thanks for replying to so many of my doubts. 

Quote

Could I have done it using say the class property or the name of the input field instead of using tabIndex?

Quote

if so, then can you kindly demonstrate how it could be done by that method. 

To both of the above, I was actually referring to this bit of code below

$("input[tabindex = "+ind+"]")

where I was wondering if the same functionality could be achieved using name or .class in place of tabindex. Even though it works it does seem rather ugly to use like this. ( tabindex needed to be defined before it was used. I know that the for such array of elements, the name property gets assigned an array with an inherent index value) .

Quote

Admittedly, I'm asking you to think a little when it comes to some of it, but ... really? Beyond that, Barand has been his typical self and gone above and beyond the call of duty to answer your questions in no uncertain terms and with concrete code examples; yet there are more requests to simply do it for you.

Only for the sake of clarification, It's because I am thinking and trying things out that I get all these questions in my head and I do like to clarify as far as possible. I do not come back with my doubts unless I have tried out things further, read and searched the net and tried to find my answers. For eg. In my last reply, I found a method to target the individual cell but came back to clarify if it was the correct method and to learn if it could be done using the name property etc. So it's not like I am asking to do it but a bit of code definitely helps clarify a lot.

Thank you for the fiddle on grids. I'll study it and maybe change to do eventually like that. I do have more questions, but seriously, I am a bit scared to ask them. 

Yes Guru Barand is has, as always, been most helpful and generous too !

@ Guru Barand : I can't thank you enough for all your help and all that I have learnt from you. 

No offence to anyone  please. I can only be grateful for all the help and assistance that I have received at the forum for years !  Thank you all !🙏

 

 

 

 

Link to comment
Share on other sites

6 hours ago, ajoo said:

Thank you for the fiddle on grids. I'll study it and maybe change to do eventually like that.

Be aware that Internet Explorer doesn't support grids (and let) as well as other browsers like Chrome and Firefox. More information can be found here:
https://caniuse.com/#feat=css-grid
https://caniuse.com/#feat=let - note that "let" can easily be switched to "var"

If you're using analytics services (e.g. Google Analytics), you should be able to get a general idea of how much of an issue that will be.

Link to comment
Share on other sites

7 hours ago, ajoo said:

I do have more questions, but seriously, I am a bit scared to ask them.

Don't let my bad mood scare you off - most people around here are very helpful and nice.

Having said that, one of the things that's going to help you learn how to code is to try things. The code you've already seen in this thread uses class-based selectors and dynamic ID and class assignment. So, if you extrapolate the two, you can use the dynamic class/ID assignment you've seen with the appropriate selector method. If you try it and it doesn't work out, then post the code you've tried and we can help you figure out why it didn't work; the important part is to show the work you've done.

Link to comment
Share on other sites

Hi ! 

@cyberRoot: Thanks for the additional information. I am aware that it's not supported by IE but it seems to work fine in chrome. I have never used let in for loops earlier so I simply removed the let and it works fine anyways. 

I have read the links you have provided and it seems that there is no advantage of using it except for the fact that it may be a bit faster since it is bound only once for all iterations. I'll look up google analytics, though i have not ever used it.

Thanks !

 @Maxxd : Thanks for the reply. I think all experts in the forum and really very helpful and nice without exceptions. I'll do try out things in quite detail actually before I ask. I'll keep in mind your advice. Thank you again !

 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.