Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Odd type error #42

Closed
gollenia opened this issue Oct 26, 2013 · 22 comments
Closed

Odd type error #42

gollenia opened this issue Oct 26, 2013 · 22 comments

Comments

@gollenia
Copy link

Hi,

I tried to include your plugin, but I ran into serious problems. Maybe you can help me.When I add the input box and asign the data-role without any javascript, everything works like a charm:

<input type="text" id="ingredientsList" data-role="tagsinput"/>

However, as soon as i add the JavaScript:

ingredientsInput = jQuery("#ingredientsList")
ingredientsInput.tagsinput();

I'm getting this error message:

Uncaught TypeError: Property 'undefined' of object #<b> is not a function 

Adding typeahead doesn't work aswell. I tried lots of variations, last one was this:

ingredientsInput = jQuery('#sidebar input')
        ingredientsInput.tagsinput();

        ingredientsInput.tagsinput('#sidebar input').typeahead({
             local: ['hallo', 'hihi']
        }).bind('typeahead:selected', jQuery.proxy(function (obj, datum) {  
            this.tagsinput('add', datum.value);
            this.tagsinput('#sidebar input').typeahead('setQuery', '');
        }, ingredientsInput));

which spilled out

Uncaught TypeError: Object #<b> has no method '#sidebar input' 
Uncaught TypeError: Property 'undefined' of object #<b> is not a function 

What could be the problem here? Please help me!

Greetings, Thomas

@timschlechter
Copy link
Contributor

Hmmm, I'm not sure why the following doesn't work:

ingredientsInput = jQuery("#ingredientsList")
ingredientsInput.tagsinput();

Could you try to reproduce the error in something like jsfiddle?

@paulfairless
Copy link

Hi,

I had the same error which was fixed by removing data-role="tagsinput" when using the js initialisation method. The example code block suggests both should be included which seemed unusual.

Hope that helps

@gollenia
Copy link
Author

gollenia commented Nov 5, 2013

I tried that one, too. It worked, yes, but typeahead still produced an error (the second one). I'll create a jsfiddele when I have time.

@paulito415
Copy link

Hi thommyg,

Any updates on your issue? The data-role="tagsinput" fix didn't work for me. I traced it to the JS line in the bootstrap-tagsinput.js file:

var retVal = tagsinput[arg1](arg2);

I'm new to JQuery and am not sure what that line is supposed to do. My value for arg1 is '#seedvalue1' and arg2 is undefined. Just for completeness, my HTML looks like:

    <input class="form-control" id="seedvalue1" name="seedvalue" class="seedvalue1"
            placeholder="Start typing..."/>

And my JS code looks like the following:

$('#seedvalue1').tagsinput();
$('#seedvalue1').tagsinput('#seedvalue1').typeahead({
       name: 'seedac',
       remote: {
          url: '../rule/ajaxAutoComplete?attribute=%QUERY',
          replace: function (url, uriEncodedQuery) {
             return '../rule/ajaxAutoComplete?attribute=' + $('#seedattribute').val() + '&query=' + encodeURIComponent($('#seedvalue1').val());
          }
       },
       limit: 10
    }).bind('typeahead:selected', 
            $.proxy(function (obj, datum) {
                $(this).tagsinput('add', datum.value);
                $(this).tagsinput('input').typeahead('setQuery', '');
            }, 
            $('#seedvalue1')));

And the JS TypeError I received was:

Object #<TagsInput> has no method '#seedvalue1' 

Thanks,
Paul

@paulito415
Copy link

Hi Tim,

Just FYI, I'm using Bootstrap 3, JQuery 1.10.2, and Twitter Typeahead JS 0.9.3. And I just realized from browsing the bootstrap-tagsinput code that you use typeahead with a "source" attribute - this leads me to believe that you are not supporting the latest Twitter Typeahead version. Can you confirm? What confuses me is that in your example page for Bootstrap 3, you had mentioned Twitter Typeahead from the same URL @ http://twitter.github.io/typeahead.js. If you are not supporting Twitter Typeahead 0.9.3, how should I get my stuff to work with the Typeahead that you support?

Thanks,
Paul

@paulito415
Copy link

Hi Tim or thommyg,

I would really appreciate a response to my question above if you have some time. Or perhaps if you can tell me which other forum would be a more appropriate place, I can post this question there to get some better traction.

Thanks,
Paul

@gollenia
Copy link
Author

This might be a hint, however, momentarily I have no time for testing it. Maybe next week.

@paulito415
Copy link

Sorry what is the hint again?

@gollenia
Copy link
Author

Using an older typeahead version. However, I did not develop the plugin, so I don't know which typeahead version Tim used.

@gollenia
Copy link
Author

The codeline you referred to is the initialization of the return value, as ist seems. It's not a speciality of jQuery but pure JavaScript and says "create an array of functions and each of them accepts an argument".

@gollenia
Copy link
Author

Oh, and don't use bind, it's deprecated. "on" and "off" are the functions you should rely on.

@paulito415
Copy link

I see. That's OK for now - in waiting for a response I've gone ahead and found the selectize plugin which seems to support Bootstrap 3 and has autocomplete / typeahead as well. I'll give that a try - seems that mentioned all 3 of chosen, select2, and tagsinput, so it may know about the shortcomings of each and hopefully have found solutions or workarounds.

Regarding the codeline you helped clarify, is there something wrong with the logic of the code or am I passing my arg1 in wrong?

Regarding "bind", I copied that somewhere - I don't recall where though.

@gollenia
Copy link
Author

To clatify the line

retVal = tagsinput[arg1](arg2)

this can not work unless you have an array of functions stored in tagsinput like

var tagsinput = {something: function(arg) {console.log(arg)}, anything: function(arg) {...}, ... ];
arg1 = "something";
arg2 = "Hallo";
tagsinput[arg1](arg2);

However, I don't know if this would actually work. What you are trying to do ist (i guess), calling the function tagsinput with two arguments (have you done something with TeX/LaTeX before?). This is done by separating them with commas:

var retVal = tagsinput(arg1, arg2);

However, in my opinion, select2 is always a good choice.

@paulito415
Copy link

Hi thommyg,

Thanks so much for helping with this and explaining how that codeline is supposed to work. I was actually hoping Tim could chime in on his reasoning behind that line himself - as it was found in his JS code. I dug around his code some more and found that before that line, tagsinput was initialized with the line:

      var tagsinput = $(this).data('tagsinput');

It was checked for null, and if null, then a TagsInput is created with:

        tagsinput = new TagsInput(this, arg1);

So presumably the arg1 that would have been passed in the first time, when tagsinput is null and the constructor was called, is used the second time when tagsinput is not null. I guess it still doesn't explain why Chrome was reporting the error I was seeing.

Anyway, here's his function with my alerts sprinkled all over the place. Maybe you can decipher a bit better what Tim was trying to do and / or how it would lead to my error:

  $.fn.tagsinput = function(arg1, arg2) {
    var results = [];
    alert("In fn.tagsinput, this is "+($(this))+" and arg1 is "+arg1+" and arg2 is "+arg2);
    
    $(this).each(function() {
      var tagsinput = $(this).data('tagsinput');
      alert("tagsinput is "+tagsinput);
      
      // Initialize a new tags input
      if (!tagsinput) {
        alert("if block");
        tagsinput = new TagsInput(this, arg1);
        $(this).data('tagsinput', tagsinput);
        results.push(tagsinput);
        if (this.tagName === 'SELECT') {
          $('option', $(this)).attr('selected', 'selected');
        }
        alert("this val is "+$(this).val());
        // Init tags from $(this).val()
        $(this).val($(this).val());
        alert("this val is "+$(this).val());
      } else {
        alert("else block, tagsinput type is "+(typeof tagsinput)+" and arg1 is "+arg1+" and arg2 = "+arg2);
        // Invoke function on existing tags input
        var retVal = tagsinput[arg1](arg2);
        alert("retVal is "+retVal);
        if (retVal !== undefined)
          results.push(retVal);
      }
    });
    if ( typeof arg1 == 'string') {
        alert("typeof = string");
        alert("results is "+results);
      // Return the results from the invoked function calls
      return results.length > 1 ? results : results[0];
    } else {
        alert("typeof = "+(typeof arg1));
      return results;
    }
  };

@paulito415
Copy link

Hi Tim or thommyg,

Any updates on this? I'm hitting a wall with selectize because I can't seem to set default values for an input once it's been selectized. For some reason, even though several people have raised this issue, the author seemed to not have deemed it important enough or worthy of his response.

Really hoping Tim is monitoring this and will one day have some free time to look into my question...

Thanks,
Paul

@arrk-mariap
Copy link

Hi Paul,

Did you manage to use Twitter Typeahead with Bootstrap3 tag library. I am in same fix as you were 2 months back.

Please let me know what helped you.

Thanks,
maria.

@paulito415
Copy link

Hi Maria,

I eventually dropped Twitter Typeahead and went back to selectize.

Just shows how banging my head on the wall long enough will eventually yield results, when I have no other choice because TimSchlechter the author of bootstrap-tagsinput seems to have dropped off the face of the earth since his last post 4 months ago. Sorry just had to vent...

My problem with selectize was the inability to set a default value that I have loaded from my database. I eventually solved my problem with selectize when I realized that selectize.setValue doesn't do anything when you don't have any options. So I just had 2 helper functions do exactly that.

/**
 * Sets the selectize field by parsing a string with a delimiter. 
 * 
 * This is very important - must add the option before you can call 
 * setValue otherwise there is no option to match the value
 * 
 * @param value
 * @param delimiter
 * @param inputField
 */
function setSelectizeField(value, delimiter, inputField) {
    // Parse the seedCondition value
    var options = value.split(delimiter);
    var values = [];
    var selectize = inputField[0].selectize;
    for (var i = 0; i < options.length; i++) {
        values.push(options[i]);
        // Sadly, the value field of 'name' cannot be passed in as a parameter
        selectize.addOption({'id':options[i], 'name':options[i]}); 
    }
    selectize.setValue(values);
}
/**
 * Sets the selectize field by inspecting a value array to feeding it into 
 * the inputField. 
 * 
 * This is very important - must add the option before you can call setValue 
 * otherwise there is no option to match the value
 * 
 * @param value
 * @param delimiter
 * @param inputField
 */
function setSelectizeFields(valueArray, inputField) {
    var selectize = inputField[0].selectize;
    var values = [];
    for (var i = 0; i < valueArray.length; i++) {
        values.push(valueArray[i].id);
        selectize.addOption({'id':valueArray[i].id, 'name':valueArray[i].label}); 
    }
    selectize.setValue(values);
}

And that seemed to have solved my problem of setting default values for my selectize input.

@muralikrishnatananki
Copy link

Hi,
It was nice using this plugin but, I need Confirm box on beforeItemRemoved - if(confirm) then remove else not... I tried using

$('input#emaildb-privatetag').on('beforeItemRemove', function (event) {
deleteFn(event);
// where div consisting of cancel and delete buttons only on delete it should be removed not on cancel
});

@alok111444
Copy link

I have read all Comments to finding out the solution , But I am not getting my solution,

My console Errror is : TypeError: $(...).tagsinput is not a function,
I had also tired removing data-role="tagsinput", But again its not working :)

@swn73
Copy link

swn73 commented Dec 4, 2016

yes,, I got the same problem with @alok111444 ,

$(...).tagsinput is not a function,

@shekhar-ramco
Copy link

having the same problem.. was this solved?

@shekhar-ramco
Copy link

shekhar-ramco commented Feb 16, 2017

I got it solved by refreshing the input element. Hope it helps someone. Here's the snippet

<input type="text" id="emailAddresses" ng-model="detailCtrl.instruction.ltaRequest.emailAddresses" tag-input="primary" data-role="tagsinput"> <script> $('#emailAddresses').tagsinput('refresh'); </script> </input>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants