I have used jQuery's autocomplete plugin in the past, but never before through Yii's implementation of it as a widget.
I am dynamically creating another autocomplete field and not able to set it to live:
$('input.ui-autocomplete-input').live("keydown.autocomplete", function() {
$(this).autocomplete();
});
or simply calling .autocomplete() when it is created to get it to work. Any ideas why this would work differently through Yii than through just using the plugin itself, or am I missing something really simple?
Thanks for any help!
My solution was overly simple.
Each autocomplete field must have a unique name attribute. I was using
<input name="family[]"/>
<input name="family[]"/>
<input name="family[]"/>
Fixed by changing it to:
<input name="family_0"/>
<input name="family_1"/>
<input name="family_2"/>
Just a little embarrassing, but worth posting in case anyone else ever overlooks such a simple issue.
Note: the code above isn't exact, the point is to make sure you are using unique names for each of the fields that are using jQueryUI's autocomplete.
CJuiAutoComplete relies on jQuery UI's autocomplete so please be sure that jQuery UI is registered for the view you create a field dynamically in:
Yii::app()->clientScript->registerCoreScript("jquery.ui");
Also be sure that source parameter with your autocomplete tags is provided for autocomplete() call. The following works fine for me:
<?php
$source = array(
"hello",
"test"
);
?>
<div id="wrapper">
</div>
<?php
Yii::app()->clientScript->registerScript("autocomplete", "
$('<input />')
.addClass('ui-autocomplete-input')
.appendTo($('#wrapper'));
$('input.ui-autocomplete-input').autocomplete({
'source': " . CJavaScript::encode($source) . "
});
", CClientScript::POS_READY);
Related
I am trying to use Knockout Validation in combination with Bootstrap Combobox Plugin.
I have a select control that is bound to my observable property which has the required attribute (for KO Validation).
<select data-bind="attr: { options: TypeAheadSource, value: XYZ, validationOptions: {errorElementClass: 'input-validation-error'}, typeaheadCombobox: {}"></select>
I have a custom binding associated with the select control in which I basically just call the Bootstrap Combobox Plugin. That creates a Div with an input control over the select control and hides the select control.
The knockout validation fires up when I dont select a value in the comobox and shows the error message next to the control BUT the field is not highlighted. Here is how it looks like
As you can see, the error message shows up but the input field is not highlighted.
Here is the final html that is generated when the validation fires.
<div class="combobox-container">
<input style="position:static;" type="text" autocomplete="off" data-bind="{ value: Name, validationOptions: { errorElementClass: 'input-validation-error' }" class="input-large">
<span class="add-on btn dropdown-toggle" data-dropdown="dropdown"><span class="caret"></span>
<span class="combobox-clear"><i class="icon-remove"></i></span></span>
<select data-bind="validationOptions: { errorElementClass: 'input-validation-error' }, options: TypeAheadSource, value: Name, typeaheadSimpleCombobox: { }" class="combobox input-validation-error"></select>
</div>
As you can see, the select control (which was hidden by the plugin) gets the validation error class I defined ('input-validation-error') but the input control created by the plugin does not.
That is the main issue here.
So, I thought it could be becasue the input control is not directly bound to the property. So, I tried adding the same value binding as the select control to the input control created by the plugin inside the custom binding. I also added the validationOptions binding. These changes didnt work either.
Strange thing is I also have a typeahead textbox bound to another property which uses a similar design (custom binding to create the typeahead plugin over an input control) and the validation + highlighting works perfectly on that. Here is the final html from that.
<input type="text" data-bind="value: xyz, validationOptions: { errorElementClass: 'input-validation-error' }, typeaheadTextBox: { source: $data.TypeAheadSource }" class="typeaheadValue input-mini" data-provide="customtypeahead" autocomplete="off">
Could someone tell me if I am missing any additional steps. I am sure you might need more details.
Please leave a comment and I will try to add more details.
Thanks.
I figured the issue. In case someone has the same issue, here is what I did.
Even though I setting up the value bindings on the input control created by the plugin, the bindings were applied before the control is created and so, I had to reapply the bindings specifically on the input control created by the plugin. That did the trick for me.
I have a question regarding using bootstrap combobox plugin in conjunction with knockout (and mvc).
I have a situation where I am using out of box MVC html helpers like Dropdownlisfor, textboxfor, etc in my template. I am using Knockout to bind a collection of data to the template. The mvc html helpers create a 'select' control for the DropDownlistfor helper. I need this to be rendered before I want to call my bootstrap plugin on the control so that all the necessary validation attributes, etc are set up. I initially used afterrender and in that method, I found the 'select' control and called the plugin on it.
Our issue is we dont want to do this every time we have to use the bootstrap combobox control in a similar way somewhere else. So, I have been researching about Custom Bindings (which I should have done already in the first place) and had a question about how I can use custom bindings in my stuation.
I found this article where he created a custom binding for bootstrap typeahead control. I can make a similar one to that for combobox. But I can only call it after the control is rendered. So, is there a way for us to specify KO to only perform custom binding "afterrender" instead of right away. That way, the select control is rendered and I can then call the plugin in the custom binding over the select control.
Here is some more info.
I have a table which uses a template
<table>
<tbody data-bind='template: {name: "editorRowTemplate", foreach: rules, afterRender: function(data) {{$root.view.templateRendered(data) } }'> </tbody>
</table>
I have the template which is similar to this
<script id="editorRowTemplate" type="text/html">
<tr class="dataRow" data-bind="attr: { id: 'EditorRow' + $index() }">
<td>
<div class="editor-field">
#Html.KnockOutDropDownListFor(rule => ruleTemplate.ReserveWordId, new List<SelectListItem>(), null,
new { #class = "combobox", data_bind = "options: $root.ReserveWords, optionsText:'Name', optionsValue:'ReserveWordId', attr : {id: $index(), name: $index()}" }, ((int)this.Model.Prefix).ToString())
#Html.KnockOutValidationMessageFor(rule => ruleTemplate.ReserveWordId, "*", new { data_bind = "attr : { 'data-valmsg-for': $index()}" }, ((int)this.Model.Prefix).ToString())
</div>
</td>
</tr>
</script>
I have my own html helpers (KnockoutDropDownListFor, etc) which generate a select control with specified KO bindings.
Please suggest what would be a good way to go about it.
Let me know if you need more info.
I'm not sure I fully understand the question. However you do not need to worry about waiting for the MVC helpers to render because this will happen server side and the knockout stuff will happen client side.
You also can use $(document).ready(function() {...}); if you want to make sure the DOM has loaded before doing anything.
As we all know, javax.swing.JComboBox is a dropdown selection having E elements in it. When setting .setEditable(true), we now can make that JComboBox also a JTextField for other E element.
After searching with Google on this, it returned to us a suggestion of using by JQuery about autocomplete presented here. Autocomplete is working on the selection but here's the problem, we need to trigger the onChange attribute that contains the ${remoteFunction} to render a particular template on the update attribute of the said ${remoteFunction}.
<g:select
id="itemSelectId"
onChange="${remoteFunction(
controller:'item', action:'itemSelect',
update:[success:'updateItemId'],
params:'\'id=\' + escape(this.value)'"/>
<div id="updateItemId></div>
And on the <script> provided on the link we just change #combobox to #itemSelectId.
Have a look at select2, that library might offer the features you are looking for.
I've been trying to get a Dojo (1.6) dijit.Tooltip to work when defined in a wijit template.
So, if I have wijit template that includes the following:
<a data-dojo-attach-point="tooltipMe" href="" onclick="return false;">
Show a Tooltip
</a>
<div data-dojo-type="dijit.Tooltip" data-dojo-props="connectId:'tooltipMe'">
Got to love hovering over links. Sometimes you a get a free tooltip
</div>
I can see the link of course, but nothing happens when I hover. Scouting round the newsgroups it seems there might be a problem with defining tooltips in wijit templates, but it's not mentioned in the Dojo docs.
Is it possible to define tooltips inline like this? Or am I just doing something wrong, it seems like the obvious place to do it.
If not, is there an accepted approach for creating and linking tooltips to DOM nodes defined in wijit templates?
Tooltips connectId property has to be the id of a DOM node. data-dojo-attach-point is not an id, it just creates a reference in the instantiated widget.
So in your case you need to assign an id to the a-node and use the same id in connectId. To avoid id clashes when creating multiple instances of your widget you can use the ${id} variable substitution to ensure that all ids are unique:
Your code should look something like this:
<a id="${id}_link" data-dojo-attach-point="tooltipMe" href="" onclick="return false;">
Show a Tooltip
</a>
<div data-dojo-type="dijit.Tooltip" data-dojo-props="connectId:'${id}_link'">
Got to love hovering over links. Sometimes you a get a free tooltip
</div>
I've had problems doing it this way before. I used script to create them on my page after I had done some other work, maybe something like this will help you out if you use it in the template postCreate method.
var span = dojo.query('.hasEntry span').forEach(function(node, index, nodelist)
{
new dijit.Tooltip({
connectId:node,
position:"above",
label: toolTipLabel
});
});
Responding to an old thread here, but just wanted to share a solution for people looking to use tooltips without IDs on their custom widget elements. It's not as pretty as just using tooltip, but it works. It uses the "dijit/popup" and "dijit/TooltipDialog" modules.
this.editTooltipDialog = new TooltipDialog({
content: "<p>I love tooltips</p>",
onMouseLeave: function(){
popup.close(this.editTooltipDialog);
}
});
on(this.targetDiv, 'mouseover', lang.hitch(this, function(){
popup.open({
popup: this.editTooltipDialog,
around: this.targetDiv
});
}));
I tried to replicate the issue in jsFiddle: http://jsfiddle.net/phusick/EcLLb/.
I found out that dijit.Tooltip widget from the template is instantized, but it does not connect mouse events, presumably because DOM node it attempts to connect to does not exist yet (i.e. has not been added to document DOM tree).
To prove the aforementioned I tried to connect the tooltip in widget's postCreate method, when all DOM building is done and it worked:
postCreate: function() {
this.inherited(arguments);
this.tooltip1.set("connectId", this.tooltipMe); // w/o this the tooltip won't show
}
So you can instantize tooltips via a template markup and then just connect then to DOM nodes in postCreate method.
I'm working with a dynamic DOM here, and have called the jQuery UI datepicker to all inputs with a specific class name, in this case .date
It works great with the first, static, construct but when I clone it the event handlers don't seem to want to move over. I get the Firebug error:
inst is undefined
I tried looking into jQuery's new live() function but couldn't combine the two. Any ideas?
Ah, got it. Right after I append the HTML to the DOM I run this on all the inputs I'd like to have a datepicker pop up with. Datepicker adds a class to elements it has been attached to, so we can filter out existing inputs and only apply it to new ones.
$('.date').not('.hasDatePicker').datepicker();
I hope this helps people as I was Googling for days and didn't find anything!
You should also note that it would be faster to check for input.date in the new generated HTML by setting that as a context, rather than the whole page, as it will save time, due to this being a more efficient operation.
I had a similar Issue, I had multiple tables on a page and each had multiple datepickers, also on click of button "AddLine" it added a table row with dynamic HTML and datepicker.
I realized after a lot of search that my input date fields had no "id" defined they looked like this
<input type="text" class="datepicker" name="mDate1" value="" size=8 >
jquery was pointing all the date fields values to the very first date field defined on page, the calendar would popup on all the date fields but the value of 1st date field would change, I made a change to the html like this
<input type="text" class="datepicker" id="Date1" name="mDate1" value="" size=8 >
by adding a "id" and it started working, for the dynamic date fields I change the Id like this
var allColumns = $("#"+$tableId+" tr:last td");
$(allColumns).each(function (i,val) {
if($(val).find(":input").hasClass("datepicker")){
$(val).find(":input").attr("id",newId+$(val).find(":input").attr("id"));
}
});
You need to use the 'live' event to make it work with dynamic DOM. So, if the class for your datepicker inputs is 'date-input', following code will make it work:
$(document).ready(function() {
$('.date-input').live('click', function() {
$(this).datepicker('destroy').datepicker({showOn:'focus'}).focus();
});
});
This might be a little late, but all the suggestions above didn't work for me, I came up with an easy solution for this.
First, what is causing the problem:
JQuery assign datepicker to element id. if you are cloning element, then same id might be cloned as well. which jQuery doesn't like. You might end up with either receiving null reference error or the date being assigned to first input field regardless which input field you click on.
Solution:
1) destroy datepicker
2) assign new unique ids to all input field
3) assign datepicker for each input
Make sure your input is something like this
<input type="text" name="ndate[]" id="date1" class="n1datepicker">
Before you clone, destroy datepicker
$('.n1datepicker').datepicker('destroy');
After you clone, add these lines as well
var i = 0;
$('.n1datepicker').each(function () {
$(this).attr("id",'date' + i).datepicker();
i++;
});
and the magic happens
Use
$j(id or class).removeClass('hasDatepicker').datepicker();
It is working
Use jQuery selectors:
$(".mydatepicker:not(.hasDatepicker)").datepicker()
Multiple instances of the jquery-ui library on the page will cause this error too. Removing redundant instances work for my case
I experienced the same symptom, in this caused by having a td containing element with the same id attribute as the input,
<td id="fld_xyz"><input id="fld_xyz" class="date" /></td>
I know this isn't ideal anyway, but it's worth knowing that the datepicker component seems to be relying on the uniqueness of the id.
I had this problem. My situation ended up being I had another element with the same ID as the input with the datepicker.
Today I faced the same issue... I am using datetimepicker plugin in my application.
Also using jquery's default datepicker too. When ever I am invoking them both on document ready I am getting the error inst is undefined.
$(document).ready(function(){
$(".datepickerCustom").datetimepicker();
$(".datepicker").datepicker();
$("#MainForm").validationEngine('attach');
....
});
So I changed the code to invoke before document ready like below:
$(".datepickerCustom").datetimepicker();
$(".datepicker").datepicker();
$(document).ready(function(){
$("#MainForm").validationEngine('attach');
....
});
Now every thing is working fine. No problems.
I had a similar problem with data picker not working after a first call. I found an answer to my issue here:
http://www.stemkoski.com/problem-with-jquery-ui-datepicker-dynamic-dom/
I was cloning sections dynamically from template and inadvertently including the class that datepicker adds once its called:
hasDatepicker
I placed my first datepicker call after I clone the template and that did it. I then added a datepicker call after each instance of clone:
$(source).clone().appendTo(destination).find(".datepicker").datepicker();
After trying many of the answers here, this is what worked for me and is showing on the first click/focus
function vincularDatePickers() {
$('.mostrar_calendario').live('click', function () {
$(this).datepicker({ showButtonPanel: true, changeMonth: true, changeYear: true, showOn: 'focus' }).focus();
});
}
this needs that your input have the class 'mostrar_calendario'
live is for JQuery 1.3+ for newer versions you need to adapt this to "on"
See more about the difference here http://api.jquery.com/live/
If it still doesn't work, it is because of the cloned id. You can completely remove datepicker like this:
$(selector).removeClass('hasDatepicker').removeAttr('id').datepicker();