PHP Developers Network

A community of PHP developers offering assistance, advice, discussion, and friendship.
 
Loading
It is currently Wed Dec 13, 2017 3:57 am

All times are UTC - 5 hours




Post new topic Reply to topic  [ 35 posts ]  Go to page Previous  1, 2, 3
Author Message
PostPosted: Mon Sep 18, 2017 4:07 am 
Offline
Forum Contributor

Joined: Wed Sep 25, 2013 4:09 am
Posts: 172
Hmm I can't get the function to set the current list when pressing enter... also for some reason everytime i press enter it automatically add another input field (ingredient: (inputfield) remove) just like when i click the add new ingredient button.

I don't know why it does that when i have one of the inputfields in focus and added e.preventDefault() on keypress enter... (I would maybe understand why it did so if the add new ingredient button was in focus when pressing enter but it is not)..


I still use the ean autocomplete function. I have 5 eans starting with 7 and 1 starting with 8.

Now the program behaves like this:

* if i type something not in db (I dont get a list suggestion) and hit enter it just clear the input field and add a new row (which it shouldnt add).

* if i type 7 it display list of eans starting with 7 and if i hit enter it set the inputbox to the first ean (say 7654) in the list which it should. but adds another input field which it shouldnt.

* if i click on the next inputfield and type in 8 it display 8989 in the list which it should but when i press enter it sets the first ean 7654 again instead of 8989. and add another row which it shouldnt..

So how do i do to update the list because it show the correct list when i type in the number but always sets from the first list created..

if i reload page and press 8 in the first field and hit enter it set 8989 as it should.
if i in the next field press 7 it shows all ean starting with 7 but when i hit enter it sets 8989... so it always set the first list it loads?


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="" 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--;
        })
       
        $('#ingredient_wrapper').on("keyup", ".input_container", function(e){
            if(e.which == 13) {
             e.preventDefault();          
             //$(this).children().val($('li').first().text());
             $(this).children().val($('li').first().text());
             $(this).children("ul").hide();
             return;
            }
           
            var thislist = $(this).children("ul");
            var min_length = 0;    
            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_in(thislist, value.ean);
                            });
                            $nodes=$nodes.add($li);
                        });
                       
                        if (result[0] == -1) {
                            thislist.hide();
                        } else {
                            thislist.empty().append($nodes).show();    
                        }
                                }                                       /* Close on sucess */
                        });                                         /* Close ajax      */
            } else {
                    thislist.hide();
            }
           
           
        }) // end of on keyup
       
       
       
});

function set_item_in(elem, item) {
   // $("#"+elem).val(item);   /*For inputboxes textareas and so on else text*/
    //elem.hide();
    //elem.text(item);
    elem.parent().children().val(item);
    elem.hide();
}
 


EDIT
I fixed the add row thing by prevent default on keydown instead.. but I still can't get it to set the correct list instead of the first list it loads....


Top
 Profile  
 
PostPosted: Mon Sep 18, 2017 5:09 am 
Offline
Spammer :|
User avatar

Joined: Wed Oct 15, 2008 2:35 am
Posts: 6603
Location: WA, USA
Okay, this sort of thing I know.

Fortunately you only have one field to add/remove at a time. That's easy: with more than one you have to coordinate information so that all pieces arrive at PHP in sync with each other.

1. Name the inputs with array syntax but don't bother with a key. Just "[]".
2. Put each input and remove button somewhere within the same parent that's unique to the pair: typically
Code:
<tr><td>(input)></td><td>(remove)</td></tr> <!-- same parent tr -->

Code:
<li>(input) (remove)</li> <!-- same parent li -->

3. Make the remove button remove the entire parent (tr or li).
4. Make the add button add a new blank entry to the parent's parent (table or ul/ol).

Here's an example showing how I deal with dynamically adding and removing inputs:
Syntax: [ Download ] [ Hide ]
<ul id="ingredients">
        <li class="template"><input type="text" name="ingredient[]" placeholder="Ingredient"> <button type="button">Remove</button></li>
</ul>
<button id="#ingredients-add" type="button">Add Ingredient</button>
 

Putting the template in the HTML is really convenient.
Syntax: [ Download ] [ Hide ]
$(function() {
        var $ingredients = $("#ingredients");
        var $template = $("#ingredients > .template").remove(); // remove the template
        $template.removeClass("template");

        // if the list is empty then add the template back in
        if ($ingredients.children().length == 0) {
                $ingredients.append($template.clone());
        }

        // add the template
        $("#ingredients-add").on("click", function() {
                $ingredients.append($template.clone());
        });
        // remove the input
        $ingredients.on("click", "> li button", function() {
                $(this).closest("li").remove();
        });
});
 

Untested, of course.

What you've done... I'm not sure but there's a lot of code and it looks fairly complicated.


Top
 Profile  
 
PostPosted: Mon Sep 18, 2017 5:27 am 
Offline
Forum Contributor

Joined: Wed Sep 25, 2013 4:09 am
Posts: 172
I think you answered some previous question that I solved already.. I just needed some more lines of code to achieve it..

I have it working adding and removing fields as it is supposed to, I also have it working in each field i add when i type something i get the correct autocomplete list to show up.

If I click with the mouse on an item in the autocomplete list it sets the inputfield with the correct value.

the only remaining thing i have to fix is that if i try to set the first list item when pressing ENTER it sets the first value of the first autocomplete list I loaded and not the current list Im watching..

requinix wrote:
What you've done... I'm not sure but there's a lot of code and it looks fairly complicated.

Coming from you I <b><u>really</u></b> take that as a compliment Hahaha
I almost don't know what I did myself but after lots of trial and error and lots of cursing I got it all to work.. almost anyway... I guess the next step will be to polish the code... atm its more like bruteforcing haha

I like your template solution, very nice code.

Edit:

its only this part im having trouble with
Quote:
$('#ingredient_wrapper').on("keyup", ".input_container", function(e){
if(e.which == 13) {
e.preventDefault();
$(this).children().val($('li').first().text());
$(this).children("ul").hide();
return;
}


or more specific: $('li').first().text()
this gives me the first $('li') item in the first list I load on the page but I need to get the first $('li') item in the current list...


EDIT
I need something like this:
var tmp = $(this).children("ul").$('li').first().text();
$(this).children().val(tmp);

Edit: Ok I almost found it ... i think..

var tmp = $(this).children("ul").first().text();
$(this).children().val(tmp);

this returns the entire list not just the first li item


I'd need something like
var tmp = $(this).children("ul").filter('li').first().text();
or
var tmp = $(this).children("ul").$('li').first().text();
but its not working.. i need to find the first $('li').text() in $(this).children("ul")


Top
 Profile  
 
PostPosted: Mon Sep 18, 2017 6:19 am 
Offline
Spammer :|
User avatar

Joined: Wed Oct 15, 2008 2:35 am
Posts: 6603
Location: WA, USA
In that callback, this will be the #ingredient_wrapper. If you want to start from the .input_container that [contains the element that] triggered the event then
Syntax: [ Download ] [ Hide ]
var $container = $(e.target /* the input */).closest(".input_container");

Then you can navigate from there.


Top
 Profile  
 
PostPosted: Mon Sep 18, 2017 6:25 am 
Offline
Forum Contributor

Joined: Wed Sep 25, 2013 4:09 am
Posts: 172
OMFG I got it to work.. had to involve the grandchildren :)

tmp = $(this).children("ul").children("li").first().text();

Damn, I'm good ;)
I even got a comment my code looks complicated haha, I think that is the first time I hear that (yeah, i know it's probably not a good thing but as someone wrote before me: if it was hard to write it should be hard to read :D)


requinix wrote:
In that callback, this will be the #ingredient_wrapper. If you want to start from the .input_container that [contains the element that] triggered the event then
Syntax: [ Download ] [ Hide ]
var $container = $(e.target /* the input */).closest(".input_container");

Then you can navigate from there.


Just saw you answered. Yeah thats what I do with the $(this).children("ul") I go to the wrapper and select the ul but I couldnt figure out how to get to the first li from there but i just repeated to find the li children of ul and then use first().


You are an excellent teacher, before I started this thread I never did anything with jquery or javascript before this and now I can do most things i like even if i need some trial and error first the code is pretty ugly from time to time

I went from
alert("Hello, World!");
to create a form with buttons to add label, inputbox, and remove rows in a table where each inputfield get its own autocomplete list that you can navigate either by mouse or arrowkeys + enter that recieve its information through ajax (whitch I thought was a brand for cleaning liquid before I started this thread)...

I'd say atleast for me (43 yo ... you know how it is to learn old dogs to sit...) its beyond fantastic accomplishment to learn all that in such short time (I can only code for a few hours now and then so really from the thread start to now I haven't had many hours coding..). So hats of to my teacher!!!


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

All times are UTC - 5 hours


Who is online

Users browsing this forum: No registered users and 5 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