PHP Developers Network

A community of PHP developers offering assistance, advice, discussion, and friendship.
 
Loading
It is currently Tue Sep 17, 2019 12:21 am

All times are UTC - 5 hours




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

Joined: Wed Sep 25, 2013 4:09 am
Posts: 172
EDIT: If you want to learn jqeury/javascript this is a great thread. requinix helps me create a very nice autocomplete function in jquery with an event handler that recognze ENTER, arrow up/down where you can use the arrows to navigate the list. I never did any jquery or javascript(except the odd hello world) before and after this thread I know enough to do some basic stuff in javascript / jquery.
The autocomplete function is based upon this tutorial . You can download the sourcecode there. For noobs like me I changed the fields:
country_id to ean_id
country_list_id to *drumroll* ean_list_id
Full scripts are located near the end of page 2. Enjoy :) (Well almost full scripts anyway, removed some db handling and loginchks.. :))

EDIT: Why does the set_item(item) function only work if result[i].x is a number and not string ???? I'm going insane over this :/
Edit again: Well I forgot this little f****er ' ... there was 3 hours of my life I never get back heh

Syntax: [ Download ] [ Hide ]
text += "<li onclick=\"set_item(" + result[i].name + ")\">" + result[i].ean + "</li>";

should be

text += "<li onclick=\"set_item('" + result[i].name + "')\">" + result[i].ean + "</li>";



Hi, I'm very new to both javascript and jquery.

I have a php function that echo a json encoded array (result[]) to the autocomplet() function.

the array is in form [0](ean=>, name=>, and so on=>)

the below function works where i send a specific value (like result[1].ean) to the set_item() function but I want the set_item function to update multiple fields on my page so I would like to pass an array like result[1] or result[3] to the set_item function and from within the set_item function extract the specific values like result[1].ean or result[1].name.

I cant get it to work when trying to pass an array..

Syntax: [ Download ] [ Hide ]
function autocomplet() {
        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 text = "<li onclick=\"set_item(" + result[0].ean + ")\">" + result[0].ean + "</li>";
                                $('#ean_list_id').show();
                                if(result[0] == -1){    $('#ean_list_id').hide();}
                                for (i = 1; i < result.length; i++) { //från 1 eftersom jag redan satt 0 ovan
                    text += "<li onclick=\"set_item(" + result[i].ean +")\">" + result[i].ean + "</li>";
                                }
                                $('#ean_list_id').html(text);
                                $('#name_id').html(text);
                                //$('#ean_list_id').html(result[1].ean);
                                //$('#name_id').html(result[1].ean);
                        }
                });
        } else {
                $('#ean_list_id').hide();
        }
}
 
// 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();
       
}
 


I tried to just pass it as is

Syntax: [ Download ] [ Hide ]
var text = "<li onclick=\"set_item(" + result[0] + ")\">" + result[0].ean + "</li>";


but it didnt work.

I tried to json encode result[0] and then parse it within the set_item() function but it didnt work..

so is there a special trick to send arrays to functions in javascript?

EDIT: Also for some reason this function only works when result[i].something is a number but not string??? So .ean works .netweight works but .name does not work ??


Last edited by hybris on Tue Sep 12, 2017 8:26 pm, edited 4 times in total.

Top
 Profile  
 
PostPosted: Fri Sep 08, 2017 12:49 am 
Offline
Spammer :|
User avatar

Joined: Wed Oct 15, 2008 2:35 am
Posts: 6617
Location: WA, USA
Rather than use an onclick to set code, use a true callback with the click event. Doing so means turning that <li> string into an LI node in the document, which suggests refactoring to append elements to #ean_list_id and #name_id (why both places) rather than setting their HTML content.

Syntax: [ Download ] [ Hide ]
var result = JSON.parse(data); // you should be making jQuery do this for you. see the .ajax docs
var $nodes = $();
$.each(result, function(key, value) {
        var $li = $("<li></li>").text(value.ean);
        $li.click(function() {
                set_item(value.ean);
        });
});

$("#name_id").empty().append($nodes);
if (result[0] == -1) {
        $("#ean_list_id").hide();
} else {
        $("#ean_list_id").empty().append($nodes.clone(true)).show();
}


Top
 Profile  
 
PostPosted: Fri Sep 08, 2017 3:54 am 
Offline
Forum Contributor

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


Top
 Profile  
 
PostPosted: Fri Sep 08, 2017 6:15 am 
Offline
Spammer :|
User avatar

Joined: Wed Oct 15, 2008 2:35 am
Posts: 6617
Location: WA, USA
I don't see any particular reasons why the old code wouldn't work. Are there any Javascript errors in the browser console?

As for the new code, besides whatever bug is also plaguing the changes to the old version, using .ajax is fine - the change I was suggesting was to set the dataType and then remove the JSON.parse() call. Just that. Same success callback and everything.

And if your ajax_browserefresh.php doesn't, it should send a Content-Type header to indicate the content is JSON.
Syntax: [ Download ] [ Hide ]
header("Content-Type: application/json");

That goes before any output. With that in place the dataType won't be necessary at all because jQuery will automatically notice that the content is JSON.


Top
 Profile  
 
PostPosted: Fri Sep 08, 2017 10:45 am 
Offline
Forum Contributor

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


Top
 Profile  
 
PostPosted: Fri Sep 08, 2017 3:16 pm 
Offline
Spammer :|
User avatar

Joined: Wed Oct 15, 2008 2:35 am
Posts: 6617
Location: WA, USA
> onclick:null << I dunno if this is ok though or if it should say to call the set_item()?
That will be the actual "onclick" attribute. It should be empty. The .click thing with jQuery uses a different, modern mechanism that probably won't be visible with a console.log().

> // shouldnt it be ean_id here instead of name_id?
I copied what you had in the first post:
Syntax: [ Download ] [ Hide ]
$('#ean_list_id').html(text);
$('#name_id').html(text);


According to that HTML, #ean_list_id is the only thing that can have the LI items. #name_id and #ean_id are both text inputs and those cannot contain list items (because they're not lists).


Top
 Profile  
 
PostPosted: Fri Sep 08, 2017 6:01 pm 
Offline
Forum Contributor

Joined: Wed Sep 25, 2013 4:09 am
Posts: 172
I still can not get it to work and I do not really follow whats happening with the node part.

I'm very new to the entire jquery thing.. the $ sign is the same as jquery (overloaded) function right?

Syntax: [ Download ] [ Hide ]
var $nodes = $();

So this say var $nodes is a jquery function?

Syntax: [ Download ] [ Hide ]
$.each(result, function(key, value) {
                    var $li = $("<li></li>").text(value.ean);
                   
                    $li.click(function() {
                        set_item(value.ean);
                    });
                });
 

Here you go through the array result[] and I guess the $li consist of like an "outher shell" (<li></li>) that surrounds the inner part (text). (Or when thinking really hard, i guess the (<li></li>) part defines the var $li as a list item function...)
Then you set what happens if i click on $li .. to call the function set_item

Syntax: [ Download ] [ Hide ]
$("#name_id").empty().append($nodes);
 

Here my brain starts to melt...

Syntax: [ Download ] [ Hide ]
if (result[0] == -1) {
                    $("#ean_list_id").hide();
                } else {
 

same as myscript... if the php file returns -1 it means no match and ean_list is hidden..

Syntax: [ Download ] [ Hide ]
} else {
                    $("#ean_list_id").empty().append($nodes.clone(true)).show();
                }
 

and looking at this my brain is starting to evaporate....
are you removing something from ean_list_id (with the .empty()) and then you insert $nodes ...that are deep copied from something and shows it all (in the ean_list_id)???

I try to follow this but my brain really hurts.. the $nodes are still just some empty $() to me... where do you (or do you..) put the $li into the $nodes?

Maybe I got it all backwards but it is really hard to try and figure it out..

why wont the damn li thingies show up in my list? When I echo to console clearly there are some $items <li>Ean code from DB</li> there... but I can't find a way to get them from the console to the ean_list.

Edit: If I look very closely it looks like the list show (1px line) when I enter a valid ean code and then dissapere when the typed in value doesnt fit any ean anylonger.. So it seems that the script might be working just that the list items doesn't show up?

Ok so I changed the height of the list so it shows clearly and as long as I type in valid numbers the list (empty) is showing but as soon as I enter the wrong number it dissaperes so it seems to be working as intended except that it is empty?


Last edited by hybris on Sat Sep 09, 2017 7:18 am, edited 1 time in total.

Top
 Profile  
 
PostPosted: Sat Sep 09, 2017 7:10 am 
Offline
Spammer :|
User avatar

Joined: Wed Oct 15, 2008 2:35 am
Posts: 6617
Location: WA, USA
> So this say var $nodes is a jquery function?

The $ function has a few uses:
- $(function) will call the function once the page has been loaded
- $(string) will use the string as a selector to find elements
- $(array) will construct a jQuery list of elements from the array
- $(nodelist) is like the array form but works when using native document methods to find elements

$() is none of the above but behaves like the $(array) version. Since there's nothing in there, it returns an empty jQuery list, just like if you had used $(string) with a selector that didn't match anything.

Thinking about it now, $([]) would have been better because it's more clear as to what it's doing: setting up an empty jQuery list.

> Here my brain starts to melt...
.empty() removes all children from an element. Before you were adding stuff by setting the inner HTML, which obviously replaces whatever was in there. Since my method adds elements, the code needs to make sure the old list (if any) gets removed. Thus the .empty().

Then .append() to add the list of nodes...

...ah. Right.

Then .append() to add the list of nodes the code built up into #name_id. Except the code never actually added anything to $nodes.
There needs to be a $nodes.add($li) in the loop.

> and looking at this my brain is starting to evaporate....
It's basically the same as the other version: remove the children, append $nodes, and then show the list (since it may have been hidden earlier).

But there's a gotcha. Since it added $nodes to #name_id earlier, if the code then tries to add them to #ean_list_id then the existing elements will just be moved over. The .clone(true) is to make sure that it appends an exact copy of $nodes, not the original nodes themselves; the true is because normally .clone() won't copy things like event listeners, meaning the .click() from before would be ignored and clicking would only work on what was in #name_id (which has the original $li elements and therefore their click handlers too).

> put the $li into the $nodes?
Exactly what I noticed. That's the bug.


Top
 Profile  
 
PostPosted: Sat Sep 09, 2017 8:02 am 
Offline
Forum Contributor

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


Top
 Profile  
 
PostPosted: Sat Sep 09, 2017 8:46 am 
Offline
Spammer :|
User avatar

Joined: Wed Oct 15, 2008 2:35 am
Posts: 6617
Location: WA, USA
- With and without [] apparently work the same, before or after the .click doesn't matter.
- If you're not using #name_id then you can remove the .clone(true) from the line for #ean_list_id since the reason it was needed is not longer the case.
- After the loop, what does console.log($nodes) show?
- What does console.log(result[0]) show?
- Using the browser tools to inspect the page, look at the #ean_list_id <ul>. Do you see any <li>s in it? Does it have any inline CSS saying whether it's visible or hidden?


Top
 Profile  
 
PostPosted: Sat Sep 09, 2017 1:37 pm 
Offline
Forum Contributor

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


Top
 Profile  
 
PostPosted: Sat Sep 09, 2017 2:51 pm 
Offline
Spammer :|
User avatar

Joined: Wed Oct 15, 2008 2:35 am
Posts: 6617
Location: WA, USA
Ah. They say it right there in the documentation, it's just so unexpected that I didn't think to read.

.add returns a new jQuery list. It doesn't modify the original.
Syntax: [ Download ] [ Hide ]
$nodes = $nodes.add($li);


Top
 Profile  
 
PostPosted: Sat Sep 09, 2017 3:46 pm 
Offline
Forum Contributor

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


Top
 Profile  
 
PostPosted: Sun Sep 10, 2017 10:58 am 
Offline
Forum Contributor

Joined: Wed Sep 25, 2013 4:09 am
Posts: 172
Another question.. Im trying to setean upon pressing enter. Just to try I try to set a fixed value (8989)

It works for a sec and then the ean_id goes blank again. When I step through in console it works and sets the 8989 in the correct field. When exiting the set function and returning to the end of the keypress function }); 8989 is still visible but then the it dissaperes again when exiting the function?


Syntax: [ Download ] [ Hide ]
function autocomplet() {
   
    $('#ean_id').keypress(function(e) {  //Ska nog göra en if else if enter ... else gå vidare enl nedan..
        if(e.which == 13) {
            //alert('You pressed enter!');
                //$('#name_id').val("You pressed enter");
                set_item('8989');
        }
    });  // It works like intended to after returning from set_item(). Then suddenly the value is cleared and the debugging stops.
   
        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);
                });
               
               //$("#ean_id").empty().append($nodes);
                if (result[0] == -1) {
                    $("#ean_list_id").hide();
                } else {
                    $("#ean_list_id").empty().append($nodes.clone(true)).show();
                }
                        }
                });
        } else {
                $('#ean_list_id').hide();
        }
}
 
// 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);
}
 


Top
 Profile  
 
PostPosted: Sun Sep 10, 2017 2:21 pm 
Offline
Spammer :|
User avatar

Joined: Wed Oct 15, 2008 2:35 am
Posts: 6617
Location: WA, USA
> if I'd put the $nodes.add($li) first thing in the loop
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.

> Bug?
Do you have it remembering your login?

> It works for a sec and then the ean_id goes blank again.
Hitting Enter normally submits a form. That "blank again" is the page reloading.

You do need to fix how the form works, but besides that the autocomplete nature of the textbox means you should prevent the form submission behavior - preferably just while the autocomplete list is up.

1a. Remember that autocomplet() runs when the user presses a key. That is not the time to be adding a .keypress handler. Something like that should be done when the page first loads using $(function() { ... }).
1b. autocomplet() is itself a keypress handler already. Reuse it instead of adding a new handler.
2. Use e.preventDefault() to prevent the default behavior of the event.

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.

Syntax: [ Download ] [ Hide ]
<input type="text" id="ean_id" autocomplete="off" placeholder="Search EAN here..">
 

Syntax: [ Download ] [ Hide ]
$(function() {
        $("#ean_id").keypress(function(e) {
                // Ska nog göra en if else if enter ... else gå vidare enl nedan..
                if (e.which == 13) {
                        set_item('8989'); // replace with code to select the first/selected entry
                        e.preventDefault(); // stop Enter from having its default behavior
                        return; // stop processing
                }

                // autocomplete
                var min_length = 0; // min caracters to display the autocomplete
                var keyword = $('#ean_id').val();
                ...
        });
});

// 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);
}
 


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 35 posts ]  Go to page 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