PHP Developers Network

A community of PHP developers offering assistance, advice, discussion, and friendship.
 
Loading
It is currently Thu Nov 23, 2017 11:43 am

All times are UTC - 5 hours




Post new topic Reply to topic  [ 35 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
PostPosted: Sun Sep 10, 2017 3:53 pm 
Offline
Forum Contributor

Joined: Wed Sep 25, 2013 4:09 am
Posts: 172
requinix wrote:
> Bug?
Do you have it remembering your login?

No, but it seemes like it was fixed now when i cleared my browser cache. Before if I was not logged in and hit reply or something I came to the loginpage where i typed in my name and password. Then it said I was sucessfully logged in and then after a while I was redirected to the loginpage again. Then I retype the login info and came back to the you have been sucessfully logged in page and then i got redirected to the post..

requinix wrote:
Well yes, don't put it before the var statement. I figured that was obvious. So anywhere inside the loop callback, after the var statement, and before or after the .click.

Yeah I knew not to put it before the var statement but I meant the principle.. adding it before .click wouldnt it be the same. I thought each $nodes consist of a ...like $li object with text = <li>ean</li> and then an attached function $li.click (what you set within the loop).. if I add to $nodes before the click function wouldn't that $li only contain the text and not the .click function? And if not why do you make the .click inside the result loop? Couldn't you have made the.$li.click function before the loop so the program doesn't have to do it several times?

requinix wrote:
1a. Remember that autocomplet() runs when the user presses a key

This is another thing that bugs me.. The autocomplet actually runs when the key is released (onkeyup="autocomplet()"). I tested it and it wont run until I release the key.
The wierd thing is, I hid the IF KEY = ENTER function within the autocomplet() function, yet that function execute on key PRESS???
I thought the autocomplet() and whatever was inside would not run until a key was released????

So if I load the page and press and hold 7 (for like a sec just before it starts repeat 7777..) nothing happens. As soon as I release the 7 the autolist pop up.
If I then press and hold enter the 8989 direcly flashes and page reloads.. when i release enter nothing happens (since that function executed already on key press)?

requinix wrote:
Now is also a good time to stop using onkeypress in your HTML and put an event handler on the #ean_id the right way.

Cool Ill try that, once again thank you for all your help! When I sell this program to Google for tons of $ I promise I will share with you (and the other mods here):D .... but I must warn you, it may take awhile before I can put something together that Google would be interested in so don't go spend all those money in advance haha


Top
 Profile  
 
PostPosted: Sun Sep 10, 2017 4:37 pm 
Offline
Spammer :|
User avatar

Joined: Wed Oct 15, 2008 2:35 am
Posts: 6587
Location: WA, USA
hybris wrote:
adding it before .click wouldnt it be the same.

Sure it would.

Adding an event handler (which is what the $li.click(...) is doing) does not change the $li variable and it does not change the underlying LI element. And that's what matters: same variable, same element. Adding the event handler before or after adding $li to $nodes doesn't make a difference because either way it's the same element being worked with.

hybris wrote:
Couldn't you have made the.$li.click function before the loop so the program doesn't have to do it several times?

No. Because
Syntax: [ Download ] [ Hide ]
var $li = $("<li></li>").text(value.ean);

$li changes each time. Different element. Plus $li does not even exist before the loop.

These are some very important Javascript principles here. In fact it's the same principles that most object-oriented languages use. You should take some time now to understand what's going on.

hybris wrote:
This is another thing that bugs me.. The autocomplet actually runs when the key is released (onkeyup="autocomplet()"). I tested it and it wont run until I release the key.

Right. The actual event happens when the key goes up. keydown is another one. And there's keypress which is basically a combination of the two but doesn't allow you to catch modifiers like Ctrl or Shift.

hybris wrote:
The wierd thing is, I hid the IF KEY = ENTER function within the autocomplet() function, yet that function execute on key PRESS???

It seems like a press but it isn't. If there was a way for you to push the key down while not in the textbox, then move the focus to it, and release the key, then the event would fire. That may be impossible to do with keyboard events, but there are similar mouse events (mouseup, mousedown, click) that work the same way.

hybris wrote:
So if I load the page and press and hold 7 (for like a sec just before it starts repeat 7777..) nothing happens. As soon as I release the 7 the autolist pop up.

Yup.

hybris wrote:
If I then press and hold enter the 8989 direcly flashes and page reloads.. when i release enter nothing happens (since that function executed already on key press)?

It's because you mixed keyup and keypress (which I'm only just noticing now). Try this with the most recent code you posted:

1. Load the page
2. Put the cursor in the textbox
3. Press Enter

Now try

1. Load the page
2. Put the cursor in the textbox
3. Press '8'
4. Press Enter

Notice the slight difference in behavior? That's because the keypress event wasn't added until the keyup happened.


Since you don't need key modifiers, try using keypress for the combined autocomplete/Enter callback. That's probably more in line with what you're expecting - and what a user would expect too.


Top
 Profile  
 
PostPosted: Sun Sep 10, 2017 5:29 pm 
Offline
Forum Contributor

Joined: Wed Sep 25, 2013 4:09 am
Posts: 172
Woha this was wierd. My enter button got totally disabled even when i tried to post in here.. I tried to hit enter to get a new line but it didnt work.. In my page I have 2 similar pages Browse product and add product.. I just made a copy of browse product (without js) and named it add product.. the thing is both have a field with id ean_id. So i switched to the add product page and there enter worked in the ean_id field.. but nowhere else.. I tried to completly close my page with the x in the tab and even after the whole page was closed my enter did not work in any other tab including this forum.. I tried to delete cache but it still didnt work so I had to shutdown the whole browser and restart it to get my enter key working again.


Aanyway except from hijacking my enter key the code doesn't really work as intended. I removed on key up in the html. When i press a numeric key in ean_id field I do not see the value in ean_id field but the code starts working.. Keyword is ="" and then when the code is at the ajax sucess: then i see the number pop up in the ean_id field .... the function returns -1 and the ean list does not show up.
The next number i type can be anything and the list pops up (if the first number was correct that is)..

EDIT: I Solved this issue by adding a keyup handler (see next post)

Say I have ean 7654 in the database
I type 7 ... no list show up
I type 1 the list show up with 7654 (since the 1 wasnt registred until the ajax call sucess)
No matter what I type here will get the list up since now it makes the ajaxcall with 71.

Syntax: [ Download ] [ Hide ]
$(function() {
   
    /*Event handler - It register keypresses and what will happend if a certain key (like ENTER) is pressed*/
    $('#ean_id').keypress(function(e) {  
        if(e.which == 13) {                        /* 13 motsvarar enter*/
            set_item('8989');
                e.preventDefault();                     /*Default is page reload.. this prevents that*/
                return;
        }                                          /*Note, event handler is not colsed here...*/
   
        /*The autocomplete function*/            
        var min_length = 0;                            /*min caracters to display the autocomplete*/
        var keyword = $('#ean_id').val();
        if (keyword.length >= min_length) {
                $.ajax({                                    
                        url: 'ajax_php/ajax_browserefresh.php',
                        type: 'POST',
                        data: {keyword:keyword},
                        success:function(data){                     /* HERE I SEE THE NUMBER ON SCREEN */
                            var result = JSON.parse(data);
                            var $nodes = $([]);
                           
                    $.each(result, function(key, value) {
                        var $li = $("<li></li>").text(value.ean);
                        $li.click(function() {
                            set_item(value.ean);
                            set_item_in('name_id', value.name); //aand so on
                        });
                        $nodes=$nodes.add($li);
                    });
                   
                    if (result[0] == -1) {
                        $("#ean_list_id").hide();
                    } else {
                        $("#ean_list_id").empty().append($nodes).show();
                    }
                        }
                });                                         /*Close ajax*/
        } else {
                $('#ean_list_id').hide();
        }
    });                                             /*Close eventhandler*/
});
// set_item : this function will be executed when we select an item
function set_item(item) {
        // change input value
        $('#ean_id').val(item);
        // hide proposition list
        $('#ean_list_id').hide();
        $('#name_id').show();
        //$('#name_id').val(name);
}

function set_item_in(elem, item) {
    $("#"+elem).val(item);
}
 


requinix wrote:
Plus $li does not even exist before the loop.

Yeah I know but you could have declared it before the loop?
var $li;
click
loop

requinix wrote:
Adding an EVENT HANDLER /../ does not change the underlying LI element.

Oh I didn't think of that. Ok (finally) got it thanks :)


Last edited by hybris on Sun Sep 10, 2017 6:47 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Sun Sep 10, 2017 6:39 pm 
Offline
Forum Contributor

Joined: Wed Sep 25, 2013 4:09 am
Posts: 172
I solved it by adding a key up handler but I dont know if thats a "good way" to do it?

Syntax: [ Download ] [ Hide ]
$(function() {
   
    /*Event handler - It register keypresses and what will happend if a certain key (like ENTER) is pressed*/
    $('#ean_id').keypress(function(e) {  
        if(e.which == 13) {                        /* 13 motsvarar enter*/
            set_item('8989');
                e.preventDefault();                     /*Default is page reload.. this prevents that*/
                return;
        }                                          
    });
   
    $('#ean_id').keyup(function(e){
 

        /*The autocomplete function*/            
        var min_length = 0;                            /*min caracters to display the autocomplete*/
        var keyword = $('#ean_id').val();
        if (keyword.length >= min_length) {
                $.ajax({
                        url: 'ajax_php/ajax_browserefresh.php',
                        type: 'POST',
                        data: {keyword:keyword},
                        success:function(data){
                            var result = JSON.parse(data);
                            var $nodes = $([]);
                           
                    $.each(result, function(key, value) {
                        var $li = $("<li></li>").text(value.ean);
                        $li.click(function() {
                            set_item(value.ean);
                            set_item_in('name_id', value.name); //aand so on
                        });
                        $nodes=$nodes.add($li);
                    });
                   
                    if (result[0] == -1) {
                        $("#ean_list_id").hide();
                    } else {
                        $("#ean_list_id").empty().append($nodes).show();
                    }
                        }
                });                                         /*Close ajax*/
        } else {
                $('#ean_list_id').hide();
        }
    });                                            /*Close eventhandler*/
                                               
});
 


Edit: But now upon releasing enter the list starts to show so I had to add

Syntax: [ Download ] [ Hide ]
 $('#ean_id').keyup(function(e){
        if(e.which == 13) {return;}                    /*If enter was pressed exit function else continue*/
        /*The autocomplete function*/
 


to fix it...

So now I want to set the first $li item when pressing Enter instead of just set the fixed value '8989'.. So I did:

Syntax: [ Download ] [ Hide ]
$('#ean_id').keypress(function(e) {  
        if(e.which == 13) {                        /* 13 motsvarar enter*/
            $('li').first().click()
                e.preventDefault();                     /*Default is page reload.. this prevents that*/
                return;
        }                                          /*Note, event handler is not colsed here...*/
    });
 


Holy F**k this is FUN!!!
requinix in this thread you took me
from: Not having a clue about either javascript or jquery or how to debug javascript
to: Aha, so maybe if i do this it might work.. lets check the console why it shows the list when it should be hidden...

Im not saying I'm comfortable in either jquery or javascript yet but atleast I'm on that level I can start debugging the code and understand (atleast a small part) of jquery documentation..
I'm pretty proud I managed to make enter set the first list item and then figure out how not to display the list upon pressing enter (to add the return statement on enter in keyup)..

I really love your answers btw, that you use the correct words like elements and so on. Most of the time I do not understand what you mean right away (I only understand some parts) but then after playing around some and then go back to your answers I get it. This is mostly due to me not working profesionally with coding (yet anyway) so I dont understand all the err special words like objects, classes, elements, DOM right away (well ofc I know what object and class is but some of the other words) but you point me in the right direction so I can read up on things.. You are an excellent teacher and I'm really grateful you took the time to help me! Now I will see if I can get the arrow down key to select the first item in the list :)

And wow this is so fun! I really start to like javascript and jquery :)


Top
 Profile  
 
PostPosted: Mon Sep 11, 2017 5:06 am 
Offline
Forum Contributor

Joined: Wed Sep 25, 2013 4:09 am
Posts: 172
Just when I thought I'd started to get a hang of it the computer refused to do what I want..

I just can't get it to focus in on the first list item when I press arrow down.

I know I caught the arrow down event good (if I paste the $('li').first().click() code in there it works).

but i cant get the program to focus on the first $li (I thought that would be a good place to start (...and then try to make it scroll through the rest of the $li when pressing more times...)

Syntax: [ Download ] [ Hide ]
$(function() {
   
    /*Event handler - It register keypresses and what will happend if a certain key (like ENTER) is pressed*/
    $('#ean_id').keypress(function(e) {  
        if(e.which == 13) {                        /* 13 motsvarar enter*/
            $('li').first().click()
                e.preventDefault();                     /*Default is page reload.. this prevents that*/
                return;
        }
    });

    $('#ean_id').keyup(function(e){
        if(e.which == 13) {
            return;                                     /*If enter was pressed exit function else continue*/
        } else if (e.which == 40){
           
            //$('ean_list_id').find(':focusable').first().focus();
            //$(if I press arrow down cant you just focus in on that damn li you stupid computer!)
            //$('ean_list_id').find('li').focus();
            //$('ean_list_id').find('$li').focus();
            //alert('Keydown');
            //$('li').first().focusin();
            //$('li').first().focus();
            //$('#ean_list_id').focus();
            //$('#ean_list_id').trigger("Focus");
            //$('li').first().trigger( "focus" );
            //e.preventDefault();
            return ;
        }          
        /*The autocomplete function*/            
        var min_length = 0;                            /*min caracters to display the autocomplete*/
        var keyword = $('#ean_id').val();
        if (keyword.length >= min_length) {
                $.ajax({
                        url: 'ajax_php/ajax_browserefresh.php',
                        type: 'POST',
                        data: {keyword:keyword},
                        success:function(data){
                            var result = JSON.parse(data);
                            var $nodes = $([]);
                           
                    $.each(result, function(key, value) {
                        var $li = $("<li></li>").text(value.ean);
                        $li.click(function() {
                            set_item(value.ean);
                            set_item_in('name_id', value.name); //aand so on
                        });
                        $nodes=$nodes.add($li);
                    });
                   
                    if (result[0] == -1) {
                        $("#ean_list_id").hide();
                    } else {
                            $("#ean_list_id").empty().append($nodes).show();    
                    }
                        }
                });                                         /*Close ajax*/
        } else {
                $('#ean_list_id').hide();
        }
    });                                            /*Close eventhandler*/
                                               
});
// set_item : this function will be executed when we select an item
function set_item(item) {
        // change input value
        $('#ean_id').val(item);
        // hide proposition list
        $('#ean_list_id').hide();
        //$('#name_id').show();
        //$('#name_id').val(name);
}

function set_item_in(elem, item) {
    $("#"+elem).val(item);
}
 


the css

Syntax: [ Download ] [ Hide ]
* {
        margin: 0;
        padding: 0;
}

body {
        padding: 10px;
        background: #eaeaea;
        text-align: center;
        font-family: arial;
        font-size: 12px;
        color: #333333;
}
.container {
        width: auto;
        height: auto: #ffffff;
        border: 1px solid #cccccc;
        border-radius: 10px;
        /*margin: auto;*/
        margin:10px;
        text-align: left;
        /*width:300px;*/
}
.header {
        padding: 10px;
}
.main_title {
        background: #cccccc;
        color: #ffffff;
        padding: 10px;
        font-size: 20px;
        line-height: 20px;
}
.content {
        padding: 5px;
        min-height: 200px;
       
}
.footer {
        padding: 10px;
        text-align: right;
}
.footer a {
        color: #999999;
        text-decoration: none;
}
.footer a:hover {
        text-decoration: underline;
}
.label_div {
        width: 120px;
        float: left;
        line-height: 28px;
} */
.input_container {
        height: 30px;
        float: left;
}
.input_container input {
        height: 20px;
        width: 200px;
        padding: 3px;
        border: 1px solid #cccccc;
        border-radius: 0;
}
.input_container ul {
        width: 200px;
        border: 1px solid #eaeaea;
        position: absolute;
        z-index: 9;
        background: #f3f3f3;
        list-style: none;
}
.input_container ul li {
        padding: 2px;
}
.input_container ul li:hover {
        background: #eaeaea;
}

#ean_list_id {
        display: none;
}
 


Also tried with the added css
Syntax: [ Download ] [ Hide ]
.input_container ul li:focus {
    outline:solid 1px black;
}
.input_container ul li.select {
        background: #eaeaea;
}
but no luck :(

EDIT:
Syntax: [ Download ] [ Hide ]
  $('#ean_id').keyup(function(e){
        if(e.which == 13) {
            return;                                     /*If enter was pressed exit function else continue*/
        } else if (e.which == 40){
            //$('li').first().click();
            //$('ean_list_id').show();
            //$('ean_list_id').focus;
            //$('li').first().focus();
            $("#name_id").focus();
            return ;
        }    
 

Hmm this works and shift the focus to the name_id when i press key down so why can't i focus ean_list_id or first $li???

also tried to set tabindex on ul...
Syntax: [ Download ] [ Hide ]
<ul id="ean_list_id" tabindex="-1"></ul>
but still no luck :/


Top
 Profile  
 
PostPosted: Mon Sep 11, 2017 12:32 pm 
Offline
Spammer :|
User avatar

Joined: Wed Oct 15, 2008 2:35 am
Posts: 6587
Location: WA, USA
You can't really put focus on text. You can apply styling to the "active" <li> to make it look selected. Or maybe you should be using a <select>?


Top
 Profile  
 
PostPosted: Mon Sep 11, 2017 4:44 pm 
Offline
Forum Contributor

Joined: Wed Sep 25, 2013 4:09 am
Posts: 172
I think i got the css right.. when i click and hold on a li item the bg colour changes to #a4f5e7
Why wont it set the first li to active when i press arrow down?
(I tried with prevent default and copy the function to .keypress but my computer just wont let me mess with the li items?

Syntax: [ Download ] [ Hide ]
$('#ean_id').keyup(function(e){
        if(e.which == 13) {
            return;                                     /*If enter was pressed exit function else continue*/
        } else if (e.which == 40){
            $('li').first().addClass("active");      
             return ;
        }          
 


Syntax: [ Download ] [ Hide ]
.input_container ul li:hover {
        background: #eaeaea;
}
.input_container ul li:focus {
    outline:solid 1px black;
}
.input_container ul li:active {
        background: #a4f5e7;
}
 


Top
 Profile  
 
PostPosted: Tue Sep 12, 2017 12:29 am 
Offline
Spammer :|
User avatar

Joined: Wed Oct 15, 2008 2:35 am
Posts: 6587
Location: WA, USA
:active is a pseudo-class for the time when the user is interacting with the element. Kinda like :focus. You can't programmatically make it happen as far as I know.

Either change your CSS to use just .active, or make the rule apply to both :active and .active.


Top
 Profile  
 
PostPosted: Tue Sep 12, 2017 4:38 pm 
Offline
Forum Contributor

Joined: Wed Sep 25, 2013 4:09 am
Posts: 172
Ok, then atleast my javascript worked but I messed up the css :) I changed : to . and it worked right away. Thanks.

Now my loginbug returned.. when i get to login sucess I get redirected back to login on the first try.. second try i get logged in? Wierd.

Edit: Ok so I'm back on track again.. Pretty proud of my key down function... Now I just have to reverse this for key up and figure out how to change the function when press ENTER so it will ...ah, I think i just got it.. and the autocomplete function is finally done! :)

Syntax: [ Download ] [ Hide ]
else if (e.which == 40){                      /*Arrow down*/
            var $selected = $('li').filter(".active");
            if ($selected.length < 1){
                $('li').eq(0).addClass("active");
            } else if (! $selected.is(':last-child') ){
                $('li').removeClass("active");
                $selected.next().addClass("active");
            }
            return ;
        }  
 


What would be really neat would be to copy the reminder from the first list item to after the cursor in the input field (greyed out) and on first enter fill in the greyed out part and on second enter set the value.. That would be awesome but I think I'll need some more practice before that.. I have no clue at all how to do something like that:

Syntax: [ Download ] [ Hide ]

Input box = <b>123</b>| 456
First list item: 123456
second list item: 654321
 


Edit again: Maybe I should rename this Thread to : requinix teaches stupid student jquery/javascript in 6 days :)


Ph34R my skillZ Muahahaha
Syntax: [ Download ] [ Hide ]
if(e.which == 13) {                           /* 13 motsvarar enter*/
            var $selected = $('li').filter(".active");
            if ($selected.length < 1){
                $('li').first().click();
            } else {
                $selected.click();
            }
 


Sweet now it actually works as I want!

Huge thanks requinix!!!!


Top
 Profile  
 
PostPosted: Tue Sep 12, 2017 8:03 pm 
Offline
Forum Contributor

Joined: Wed Sep 25, 2013 4:09 am
Posts: 172
Full scripts for the young padawans :D

I hope this will help someone who like me is struggeling to learn ajax/jquery/javascript. Enjoy :)

browsescript.js
Syntax: [ Download ] [ Hide ]
$(function() {
    /*Event handler - It register keypresses and what will happend if a certain key (like ENTER) is pressed*/
    $('#ean_id').keypress(function(e) {                     /*I only want the key mod trigger when the searchbox has focus*/
        if(e.which == 13) {                                 /* 13 == enter  see http://keycode.info/ */
            var $selected = $('li').filter(".active");      /* $('li') .active is set during key up */
            if ($selected.length < 1){                      /* easy way of testing if null */
                $('li').first().click();                    /* .click() function is defined in $.each(result, function(key, value) {} loop*/
            } else {
                $selected.click();
            }
                e.preventDefault();                     /*Default is page reload.. this prevents that without this it just flickers then page is reloaded*/
                return;
        }
    });
   
    $('#ean_id').keyup(function(e){
        if(e.which == 13) {
            return;                                     /*If enter was pressed exit function else continue*/
        } else if (e.which == 38){
            //alert('key uppppp');
            var $selected = $('li').filter(".active");
            if ($selected.length > 0 || ! $('li').eq(0)){
                $('li').removeClass("active");
                $selected.prev().addClass("active");
            }
            return;
        } else if (e.which == 40){                      /*Arrow down*/
            var $selected = $('li').filter(".active");
            if ($selected.length < 1){                   /*Chk if null*/
                $('li').eq(0).addClass("active");
            } else if (! $selected.is(':last-child') ){
                $('li').removeClass("active");
                $selected.next().addClass("active");
            }
            return ;
        }    
       
       
        /*The autocomplete function*/            
        var min_length = 0;                            /*min caracters to display the autocomplete*/
        var keyword = $('#ean_id').val();
        if (keyword.length >= min_length) {
                $.ajax({
                        url: 'ajax_php/ajax_browserefresh.php',
                        type: 'POST',
                        data: {keyword:keyword},
                        success:function(data){
                            var result = JSON.parse(data);
                            var $nodes = $([]);
                           
                    $.each(result, function(key, value) {
                        var $li = $("<li></li>").text(value.ean);
                        $li.click(function() {
                            set_item(value.ean);
                            set_item_in('name_id', value.name); //aand so on
                            /* set_item_in ('label id goes here', value.property goes here) add as many as u like*/
                        });
                        $nodes=$nodes.add($li);
                    });
                   
                    if (result[0] == -1) {
                        $("#ean_list_id").hide();
                    } else {
                            $("#ean_list_id").empty().append($nodes).show();    
                    }
                        }
                });                                         /*Close ajax*/
        } else {
                $('#ean_list_id').hide();
        }
    });                                            /*Close eventhandler*/
                                               
});
// set_item : this function will be executed when we select an item
function set_item(item) {
        $('#ean_id').val(item);
        $('#ean_list_id').hide();
}

function set_item_in(elem, item) {
   // $("#"+elem).val(item);                           /*For inputboxes textareas and so on*/
    $("#"+elem).text(item);                /*For labels and so on.. can use html instead of text*/
}
 


productform_style.css
Syntax: [ Download ] [ Hide ]
* {
        margin: 0;
        padding: 0;
}

body {
        padding: 10px;
        background: #eaeaea;
        text-align: center;
        font-family: arial;
        font-size: 12px;
        color: #333333;
}
.container {
        width: auto;
        height: auto: #ffffff;
        border: 1px solid #cccccc;
        border-radius: 10px;
        /*margin: auto;*/
        margin:10px;
        text-align: left;
        /*width:300px;*/
}
.header {
        padding: 10px;
}
.main_title {
        background: #cccccc;
        color: #ffffff;
        padding: 10px;
        font-size: 20px;
        line-height: 20px;
}
.content {
        padding: 5px;
        min-height: 200px;
       
}
.footer {
        padding: 10px;
        text-align: right;
}
.footer a {
        color: #999999;
        text-decoration: none;
}
.footer a:hover {
        text-decoration: underline;
}
.label_div {
        width: 120px;
        float: left;
        line-height: 28px;
} */
.input_container {
        height: 30px;
        float: left;
}
.input_container input {
        height: 20px;
        width: 200px;
        padding: 3px;
        border: 1px solid #cccccc;
        border-radius: 0;
}
.input_container ul {
        width: 200px;
        border: 1px solid #eaeaea;
        position: absolute;
        z-index: 9;
        background: #f3f3f3;
        list-style: none;
}
.input_container ul li {
        padding: 2px;
}
.input_container ul li:hover {
        background: #eaeaea;
}
.input_container ul li:focus {
    outline:solid 1px black;
}
.input_container ul li.active {
        background: #a4f5e7;
}

#ean_list_id {
        display: none;
}
 


BrowseProduct.php
Syntax: [ Download ] [ Hide ]
<?php
/* I use a page class to create my pages so for the php file to create the page I only show relevant stuff to this searchbox*/
           
               
                <link rel="stylesheet" href="style/productform_style.css" />
                <script type="text/javascript" src="js/jquery-3.2.1.min.js"></script>
                <script type="text/javascript" src="js/browsescript.js"></script>
               
            </head>
           
            <body>
                <table>
                    <tr>    
                        <form>
                            <td><div class="label_div">Enter EAN code: </div></td>
                            <td><div class="input_container">
                                <input type="text" id="ean_id" autocomplete="off" placeholder="Search EAN here..">
                                <ul id="ean_list_id" tabindex="-1"></ul>
                            </div></td>
                         
                        </form>
                    </tr>
                </table>
         
                <div class="container">        
                    <div class="content">
                        <table>
                            <tr>
                                <td><div class="label_div">Product name: </div></td>
                                <td><label id="name_id"> </label></td>
                            </tr>                                              
                        </table>
                    </div><!-- content -->    
                </div><!-- container -->
            </body>
        </html>
       
 


ajax_browserefresh.php
Syntax: [ Download ] [ Hide ]
<?php
require(DBConnect.php"); //open db conn $mysqli
$q=$_POST['keyword'];

if ($stmt = $mysqli->prepare("
SELECT
    EAN,
    name
    FROM mytable WHERE EAN like CONCAT(?,'%') ")) {
    $stmt->bind_param('i', $q);
    $stmt->execute();
    $stmt->bind_result($ean, $name);
    $stmt->store_result();
    $i=0;
    while($row=$stmt->fetch()){
        $result[$i][ean]=$ean;
        $result[$i][name]=$name;      
        $i++;
    }
}

if ($result[0] != null) {
    echo json_encode($result);
} else {
    $result[0]=-1;
    echo json_encode($result);
}


Top
 Profile  
 
PostPosted: Sun Sep 17, 2017 1:35 pm 
Offline
Forum Contributor

Joined: Wed Sep 25, 2013 4:09 am
Posts: 172
Hi again,

I'm having a blast with jquery / javascript and managed to (after several tries) to add some input fields to a table when clicking a button. I also managed to add a remove function that removes the input field.


The code below is for a form with some fixed input fields and then 2 identical tables: one add ingredient and the other add allergen.

the i variable keep track on how many input fields i have for ingredients and the j variable how many inputfields for allergens. The k variable is just to be able to give each field a unike id.. it only increases (i & j decreases when removing a field).


Syntax: [ Download ] [ Hide ]
$(function() {
   
   
    /* Function to add or remove ingredient or allergen input fields*/
   
        var i = 1;
        var j = 1;
        var k = 2; // gives a unique ID to each added field (does not decrement as i and j)
        $('#add_ingredient').click(function() {
               $('#Ingredient_table').append('<tr><td><p>Ingredient</p></td><td><div class="input_container"><input type="text" id="ingredientid['+k+']" size="20" name="ingredient['+k+']" value="'+k+'" placeholder="Input Value" /><ul id="ingredient_list_id['+k+']" tabindex="-1"></ul></div></td><td><a href="#" class="remove_field"><p style="font-size:50%;">Remove</p></a></td></tr>');
                i++; k++;
                return false;
        });
       
        $('#Ingredient_table').on("click",".remove_field",function(e){
            e.preventDefault();    
            $(this).parents('tr').remove();  //parents could be switched with closest
            i--;
        })
       
        $('#add_allergen').click(function() {
               $('#Allergen_table').append('<tr><td><p>Allergen</p></td><td><input type="text" id="allergenid['+k+']" size="20" name="allergen['+k+']" value="'+k+'" placeholder="Input Value" /></td><td><a href="#" class="remove_field"><p style="font-size:50%;">Remove</p></a></td></tr>');
                j++; k++;
                return false;
        });
       
        $('#Allergen_table').on("click",".remove_field",function(e){
            e.preventDefault();    
            $(this).parents('tr').remove();  //parents could be switched with closest
            j--;
        })
       
            /*The autocomplete function*/      
        function autocomplet(){  
        var min_length = 0;                            /*min caracters to display the autocomplete*/
        var keyword = $('#ingredientid[]').val(); /* ??????????????????????? */
        if (keyword.length >= min_length) {
                $.ajax({
                        url: 'ajax_php/ajax_browserefresh.php',
                        type: 'POST',
                        data: {keyword:keyword},
                        success:function(data){
                            var result = JSON.parse(data);
                            var $nodes = $([]);
                           
                    $.each(result, function(key, value) {
                        var $li = $("<li></li>").text(value.ean);
                        $li.click(function() {
                            set_item(value.ean);
                           
                        });
                        $nodes=$nodes.add($li);
                    });
                   
                    if (result[0] == -1) {
                        $("#ingredient_list_id['+k+']").hide();
                    } else {
                            $("#ingredient_list_id['+k+']").empty().append($nodes).show();    
                    }
                        }
                });                                         /*Close ajax*/
        } else {
                $('#ingredient_list_id').hide();
        }
        }
    //});    
 
      // ingredient_list_id
});

 



I don't really have a clue how I properly give each list a unique id (I'm trying to use the var k) so each inputbux get an id like ingredientid[k] and every ul get id ingredient_list_id[k] but I don't know if im on the right track at all or if I should do it completly different?


I would like to each time i start to type in an (added input field the list shall pop up with autocomplete suggestions.. the ingredient list will call one php file and the allergen list (not implemented yet) shall call another php script)

EDIT: and do i need to put k in id? Lots of the examples i seen for dynamically adding and removing fields do not use id at all, just name.. and they write the names with [] like name="allergens[]"

I dont know if that makes the name work as an array automatically or if they just add the [] to indicate that this name can have multiple fields... ?

Edit again: I guess I'm asking how to write the var keyword =$('#ingredientid[k]).val() since i dont know what k is on the field they type... maybe the user adds like 10 fields so k=12 (starts on 2) and then begins typing in the first field (ingiredientd[2]) but since they added several fields first k=12.... I hope you understand what I mean..


Last edited by hybris on Sun Sep 17, 2017 4:38 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Sun Sep 17, 2017 2:42 pm 
Offline
Spammer :|
User avatar

Joined: Wed Oct 15, 2008 2:35 am
Posts: 6587
Location: WA, USA
So I'm totally lost now.

What I do know is that you should not be throwing around IDs like that. Certainly not in any way where multiple elements have the same one. If you want to apply logical rules to fields then use classes (even if there is no CSS to go with it) and if you want to work with particular form elements then you can query by their name (though classes are often easier). Like, when I design HTML for UIs I throw around lots of classes and data-* attributes; when I do need to focus on a particular subset of elements that may exist in similar forms elsewhere on the page then I'll wrap the elements in one container with a unique ID and do Javascript work based on that container itself - which sounds pretty vague to me, but I know what I mean.

Can you refresh my memory on what the resulting markup looks like and how you're trying to use it in the Javascript?


Top
 Profile  
 
PostPosted: Sun Sep 17, 2017 4:01 pm 
Offline
Forum Contributor

Joined: Wed Sep 25, 2013 4:09 am
Posts: 172
requinix wrote:
So I'm totally lost now.


Ok, so that makes two of us now haha

This is a completely new script for a new page and not at all connected with the old autocomplete script you helped me with before (which is working great :) ).

In this page I want to manually save a product to my database. All other info like product name and so on I know how many fields it takes but not for ingredients or allergens.

So the page looks something like:
Syntax: [ Download ] [ Hide ]

Food name: (input box)
net weight: (inputbox)
grossweight:(inputbox)
...
manufacturer: (Inputbox)
..
.


then a new table
Ingredient: (Input box)
<button> Add more ingredients</button>

When clicking that button it looks like this:

Ingredient: (Input box)
Ingredient: (Input box)   remove
Ingredient: (Input box)   remove
Ingredient: (Input box)   remove
<button> Add more ingredients</button>

and exacly the same for allergens (another table)
Allergen: (Inputbox)
<button> Add more allergens</button>
 


requinix wrote:
you should not be throwing around IDs like that.

Yeah, I have this little voice inside my head telling me the same thing... thats why I tried to make unique IDs with using a variable k (increasing int) so I get something like
ingredientid[2]
ingredientid[3]
ingredientid[4]
and so on.. the i & j variables are just to keep track of how many inputfields I have for ingredients and allergens (increase when I add new field with button and decrease when i hit remove... The reason I cant have them as id counter is if I add 1 2 3 4 5 and then remove 1 4 5 and then add 3 new fields I will have 2 4 3 4 5 so I use k which will give 2 4 6 7 8.... if i do as just stated before..

requinix wrote:
I'll wrap the elements in one container with a unique ID

Yeah I tried to do that using a div .wrapper class and add the new elements to it (all tutorials on jquery add and remove inputbox I found did it this way) (probably for a reason) but since I use tables in the rest of the form I wanted to see if I could add it to the table instead (took me several hours to get it right heh).

Also the first ingredient: (inputbox) that I placed with the html was inside a table so when I added the new fields to the wrapper div they appered above my table and I couldnt get it to look good.. Now I add and remove them from the table and it looks and behaves the way I want.. except I have no clue on how to target the fields individually (or if I even have to.. but I guess I do...)

I just copied the autocomplet() function from the previous script to have something to work with (like for testing i add ean numbers as ingredients and when I get it to work I do a new php file to search the DB for ingredients instead of eans...


I will resend the login info to the page as a pm if you want to take a look how it looks and works with the buttons.


edit
from the page.php file....
Syntax: [ Download ] [ Hide ]

/../

<table class="content_table">
                        <?php
                        foreach ($product as $key=>$value) {
                        switch($key){
                            case "nutrition_info":
                            foreach ($nutritionlist as $k=>$v) {
                                $k=ucfirst($k);
                                ?>
                                <tr>
                                    <td style="background-color: white;"><?php echo $k;?></td>
                                    <td style="background-color: white;"><input name="<?php echo $k;?>" type="text" size="10" id="<?php echo $k."_id";?>"></td>
                                    <td style="background-color: white;"><?php echo $v;?></td>
                                </tr>
                            <?php    
                            }
                            break;    
                        }
                        }
                        ?>
                        </table>
                        </div>
                    </div> <!-- End top wrapper -->
                    <div class="wrapper">
                        <div id="ingredient_nfo"><h2 style="text-align:center;">Ingredients list</h2>
                            <div class="field_wrapper" id="ingredient_wrapper">
                                <table class="content_table" id="Ingredient_table">
                                    <tr>
                                        <td>Ingredient</td>
                                        <td><div class="input_container"><input type="text" name="ingredient[]" size="20" id="ingredientid[]" autocomplete="off"><ul id="ingredient_list_id" tabindex="-1"></ul></div></td>
                                         <ul id="ingredient_list_id" tabindex="-1"></ul>
                                        <td></td>
                                    </tr>
                                </table>
                            </div>
                            <center><button class="add_button" id="add_ingredient">Add ingredient</button></center>
                        </div>
                       
                        <div id="allergen_nfo"><h2 style="text-align:center;">Allergen information</h2>
                        <table class="content_table" id="Allergen_table">
                                <tr>
                                    <td>Allergen</td>
                                    <td><input type="text" name="allergen[]" size="20" id="allergenid[]" autocomplete="off"><ul id="allergen_list_id" tabindex="-1"></ul></td>
                                    <td></td>
                                </tr>
                               
                            </table>
                            <center></center><button class="add_button" id="add_allergen">Add allergen</button></center>
                        </div>
                    </div> <!-- End bottom wrapper -->
                    <button class="add_button" id="submit_button" type="submit" form="Add_product" value="Submit">Submit</button>
                  </form>
                </div>        
   
 



Edit: I tried to use div class input_container to make an onklick -> alert function just to see if it would work..

the php file:
Syntax: [ Download ] [ Hide ]
<td>Ingredient</td>
                                        <td><div class="input_container"><input type="text" name="ingredient[]"
                                        size="20" id="ingredientid[]" autocomplete="off">
                                         <ul id="ingredient_list_id" tabindex="-1"></ul></div></td>
                                         <ul id="ingredient_list_id" tabindex="-1"></ul>
 


the js file

Syntax: [ Download ] [ Hide ]
$('#add_ingredient').click(function() {
               $('#Ingredient_table').append('<tr><td><p>Ingredient</p></td><td><div class="input_container"><input type="text" id="ingredientid['+k+']" size="20" name="ingredient['+k+']" value="'+k+'" placeholder="Input Value" /><ul id="ingredient_list_id['+k+']" tabindex="-1"></ul></div></td><td><a href="#" class="remove_field"><p style="font-size:50%;">Remove</p></a></td></tr>');

...
..
.

$('.input_container').click(function(){
            alert('Click');
        })

 


But it only works on the first -> Ingredient: (input box) (which i add in the .php script)
but not the ones i add with the button??? (that i add in the js)

Edit:
when i print_r $_POST on submit it seems like all ingredients and allergens i add in the fields are posted correctly (as an array) so atleast that part seems to be working :) I suspect its enough to name the fields like name=ingredient[] and it will store all the fields in an array so no need to write name=ingredient['+k+'].. so I guess i can remove the id field from these since I don't really need it...

Ok so the $_post is working (i tried to remove id= and name=blabla['+k+'] and it still works.. )


Top
 Profile  
 
PostPosted: Sun Sep 17, 2017 5:56 pm 
Offline
Forum Contributor

Joined: Wed Sep 25, 2013 4:09 am
Posts: 172
Ok I guess I can make it to work with:

$('#ingredient_wrapper').on("click", ".input_container", function(e){
alert('Click');
})

edit: click should be keypress ^^ and then I run the autocomplete function...

Damn you're good. Once again you pointed me in the right direction :) Thanks :)


+'Hmm for some reason id=ingredient_list_id'+k+' works but not ingredient_list['+k+'] ...

so if i name the ids: blabla_id1 it works but id: blabla_id[1] does not work... I think that is what messed it all up for me...


Top
 Profile  
 
PostPosted: Sun Sep 17, 2017 8:17 pm 
Offline
Forum Contributor

Joined: Wed Sep 25, 2013 4:09 am
Posts: 172
Edit: Im just tired... fixed it with saving $this.children in a variable before the ajax call.. so now its working as intended :)

Ok so its almost working now except that the ul wont fill up with the $li items... so its pretty useless since the whole point is to populate the list heh...

But lo and behold, I know what's wrong..

to get which list to populate i use $this

Syntax: [ Download ] [ Hide ]
 $('#ingredient_wrapper').on("keyup", ".input_container", function(e){
             $(this).children("ul").show();
 


and now $this refers to the ingredient_wrapper which is what I want..
but when I do the ajax call $this switches to mean the ajax function or something similar so
when i get to

Syntax: [ Download ] [ Hide ]
if (result[0] == -1) {
                        $(this).children("ul").hide();
                    } else {
                           
                            $(this).children("ul").empty().append($nodes).show();    
                    }
                        }
 

instead of find ul children in ingredient_wrapper it tries to find ul in the ajax function..

Or atleast that is what I think... problem is I don't know how to fix this to get $this to mean the ingredient_wrapper again...



Syntax: [ Download ] [ Hide ]
$(function() {
   
   
    /* Function to add or remove ingredient or allergen input fields*/
   
        var i = 1;
        var j = 1;
        var k = 2; // gives a unique ID to each added field (does not decrement as i and j)
        $('#add_ingredient').click(function() {
               $('#Ingredient_table').append('<tr><td><p>Ingredient</p></td><td><div class="input_container"><input type="text"  size="20" name="ingredient[]" value="'+k+'" placeholder="Input Value" /><ul id="ingredient_list_id_'+k+'" tabindex="-1"></ul></div></td><td><a href="#" class="remove_field"><p style="font-size:50%;">Remove</p></a></td></tr>');
                i++; k++;
                return false;
        });
       
        $('#Ingredient_table').on("click",".remove_field",function(e){
            e.preventDefault();    
            $(this).parents('tr').remove();  //parents could be switched with closest
            i--;
        })
       
        $('#add_allergen').click(function() {
               $('#Allergen_table').append('<tr><td><p>Allergen</p></td><td><input type="text" id="allergenid_'+k+'" size="20" name="allergen['+k+']" value="'+k+'" placeholder="Input Value" /></td><td><a href="#" class="remove_field"><p style="font-size:50%;">Remove</p></a></td></tr>');
                j++; k++;
                return false;
        });
       
        $('#Allergen_table').on("click",".remove_field",function(e){
            e.preventDefault();    
            $(this).parents('tr').remove();  //parents could be switched with closest
            j--;
        })
       
     /*   $('.input_container').click(function(){
            alert('Click');
        }) */

       
        $('#ingredient_wrapper').on("keyup", ".input_container", function(e){
             $(this).children("ul").show();
            var min_length = 0;    
            //var keyword = $(this).children("input").val();
            var keyword = $(this).children().val();
            if (keyword.length >= min_length) {
                $.ajax({
                        url: 'ajax_php/ajax_browserefresh.php',
                        type: 'POST',
                        data: {keyword:keyword},
                        success:function(data){
                            var result = JSON.parse(data);
                            var $nodes = $([]);
                           
                    $.each(result, function(key, value) {
                        var $li = $("<li></li>").text(value.ean);
                        $li.click(function() {
                            set_item(value.ean);
                        });
                        $nodes=$nodes.add($li);
                    });
                   
                    if (result[0] == -1) {
                        $(this).children("ul").hide();
                    } else {
                           
                            $(this).children("ul").empty().append($nodes).show();    
                    }
                        }
                });                                         /*Close ajax*/
        } else {
                $(this).children("ul").hide();
        }
       
       
          // $(this).children("ul").show();
        })
       
            /*The autocomplete function*/      
        function autocomplet(){  
        var min_length = 0;                            /*min caracters to display the autocomplete*/
        //var keyword = $('#ean_id').val();
        var keyword = $('#ingredientid[2]').val();
        if (keyword.length >= min_length) {
                $.ajax({
                        url: 'ajax_php/ajax_browserefresh.php',
                        type: 'POST',
                        data: {keyword:keyword},
                        success:function(data){
                            var result = JSON.parse(data);
                            var $nodes = $([]);
                           
                    $.each(result, function(key, value) {
                        var $li = $("<li></li>").text(value.ean);
                        $li.click(function() {
                            set_item(value.ean);
                           
                        });
                        $nodes=$nodes.add($li);
                    });
                   
                    if (result[0] == -1) {
                        $("#ingredient_list_id['+k+']").hide();
                    } else {
                            $("#ingredient_list_id['+k+']").empty().append($nodes).show();    
                    }
                        }
                });                                         /*Close ajax*/
        } else {
                $('#ean_list_id').hide();
        }
        }
    //});    
 
      // ingredient_list_id
});

 


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 35 posts ]  Go to page Previous  1, 2, 3  Next

All times are UTC - 5 hours


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
Powered by phpBB® Forum Software © phpBB Group