cloned elements cannot be selected after jquery customSelect plugin installation - clone

I am in a bit of a pickle with this form and i would really appreciate some help.
After installing the customSelect() jquery plugin, i was no longer able to select the cloned select box elements on my form.
For an example, go to...
http:// gator1016.hostgator.com /~tamarind/index.php/en/book-now.html
Click on the second slide >> click on the "add a package" button >> try and change one of the cloned select box values.
Does anyone have any suggestions as to why this is? I'm under a bit of pressure to get this fixed.
Thanks in advance.

You are running .customSelect() in a seperate script tags previous to the rest of your form script. So here is the current order of events:
customSelect takes all given selects and appends a customizable <span> next to each (this is what you styled to achieve the desired look). It also attaches event listeners to those very spans so they can properly interact with their corresponding select element.
A user clicks "add another package", you clone the entire block of form elements including the custom spans that the plugin appended.
It is important to note that in doing this, you are not copying the event listeners, just the elements. Right now, even if you ran customSelect again upon cloning, you would likely have some kind of issue because the original span would still be there.
The solution to your problem would be to keep a reference to a clone of your form block that has not already had customSelect applied. Then each time you insert a new form block, you need to apply customSelect to the "vanilla" form block.
Here is a reduced example for you
HTML
<form action="" id="myForm">
<div id="formBlock">
<select><option>one</option><option>two</option></select>
</div>
</form>
<button id="addNew">add new</button>
jQuery
//do this first:
var formBlock = $('#formBlock').clone();
//now .customSelect();
$('#formBlock select').customSelect();
$('#addNew').click(function(e){
e.preventDefault();
var newFormBlock = formBlock.clone().appendTo('#myForm'); //clone the reference to un-modified form block!!!
newFormBlock.attr({
id:'' //dont want duplicate id's
});
newFormBlock.find('select').customSelect();
});
Demo: http://jsfiddle.net/adamco/ZZGJZ/1/

You also can cleanup the elements added by the plugin, and launch again customSelect:
$('form').find('span.customselect').remove(); //remove the span
$('form').find('select.hasCustomSelect').removeAttr("style"); //clean inline style
$('form select').customSelect( { customClass: "customselect" } ); // fire again customSelect

Related

Link directly to a notebook page in a view

I have an view that extends the current project view, where we add multiple tabs (notebook pages) to show information from other parts of a project.
One of these pages is an overview page that summarizes what is under the other tabs, and I'd like to link the headlines for each section directly to each displayed page. I've currently solved this by using the index of each tab and calling bootstrap's .tab('show') method on the link within the tab:
$(".overview-link").click(function (e) {
e.preventDefault();
var sel = '.nav-tabs a:eq(' + $(this).data('tab-index') + ')';
$(sel).tab('show');
});
This works since I've attached a data-tab-index="<int>" to each header link in my widget code, but it's brittle - if someone adds a tab later, the current indices will be broken. Earlier I relied on the anchor on each tab, but that broke as well (and would probably break if a new notebook page were inserted as well).
Triggering a web client redirect / form link directly works, but I want to show a specific page in the view:
this.do_action({
type: 'ir.actions.act_window',
res_model: 'my.model.name',
res_id: 'my.object.id',
view_mode: 'form',
view_type: 'form',
views: [[false, 'form']],
target: 'current'
});
Is there any way to link / redirect the web client directly to a specific notebook page tab through the do_action method or similar on FormWidget?
If I understood well you want to select the tab from the JavaScript (jQuery) FormWidget taking into account that the id could change if anybody install another module that adds another tab
Solution 0
You can add a class to the page in the xml form view. You can use the id of the element selected by this class name in order to call the right anchor and select the right tab item. This should happen when the page is completely loaded:
<page class="nb_page_to_select">
$('a[href=#' + $('.nb_page_to_select').attr('id') + ']').click()
NOTE: As you have said the following paragrah I assume that you know where to run this instruction. The solution I suggest is independent of the index.
This works since I've attached a data-tab-index="<int>" to each
header link in my widget code, but it's brittle - if someone adds a
tab later, the current indices will be broken. Earlier I relied on the
anchor on each tab, but that broke as well (and would probably break
if a new notebook page were inserted as well).
Solution 1
When the page is loaded you can get the tab list DOM object like this:
var tablist = $('ul[role="tablist"]')
And then you can click on the specifict tab, selecing by the text inside the anchor. So you don't depend on the tab index:
tablist.find('a:contains("Other Information")').click()
I think if you have two tabs with the same text does not make any sense, so this should be sufficient.
Solution 2
Even if you want to be more specific you can add a class to the notebook to make sure you are in the correct notebook
<notebook class="nt_to_change">
Now you can use one of this expressions in order to select the tab list
var tablist = $('div.nt_to_change ul.nav-tabs[role="tablist"]')
// or
var tablist = $('div.nt_to_change ul[role="tablist"]')
Solution 3
If the contains selector doesn't convince you because it should be equal you can do this as well to compare and filter
tablist.find('a').filter(function() {
return $.trim($(this).text()) === "Other Information";
}).click();
Where "Other Information" is the string of the notebook page
I didn't tried the solution I'm giving to you, but if it doesn't work at least may be it makes you come up with some idea.
There's a parameter for XML elements named autofocus (for buttons and fields is default_focus and takes 1 or 0 as value). If you add autofocus="autofocus" to a page in XML, this page will be the displayed one when you open the view.
So, you can try to add this through JavaScript, when the user clicks on the respective link -which honestly, I don't know how to achieve that by now-. But you can add a distinctive context parameter to each link in XML, for example context="{'page_to_display': 'page x'}". When you click on the link, I hope these context keys will arrive to your JS method.
If not, you can also modify the fields_view_get method (here I wrote how to do that: Odoo - Hide button for specific user) to check if you get the context you've added to your links and add the autofocus parameter to the respective page.
As you said:
This works since I've attached a data-tab-index="" to each header
link in my widget code, but it's brittle - if someone adds a tab
later, the current indices will be broken.
I assume that your app allow multi-user interaction in realtime, so you have to integrate somewhere in your code, an update part function.
This function will trig if something has changed and cleanout the data to rebuilt the index in order to avoid that the current indices will be broken.

load dynamic data with ajax and hidden divs

I want to create something similar to collapsible divs to show or hide content to the user.
I don't want the content to be load in one ajax call because the data is huge.
Each time a user click on an option, an ajax call will load the data.
I started using append to create the divs. Since I don't know how much option there is on each one, I couldn't build the divs in advance.
The problem I'm having with appends is when a user click on option B, options b1,b2,b3 are loading and the divs are created. But when the user decide to go back to option A and then back to option B, the divs are created again and now they are multiple.
Does anyone have an idea how to do this?
As I sayed in my comment you can do something like this:
EXAMPLE
<div id="option-a">option A</div>
<div id="option-b">option B</div>
<div id="option-c">option C</div>
<div id="option-d">option D</div>
$("#option-b").on("click", function(){
//if element doesn't exist
if( $('#submenu-b').length <= 0 ){
//add elemnent
$("#option-b").append("<span id='submenu-b'><div>B1</div><div>B2</div><div>B3</div></div>");
}
})

jqGrid: Create a custom edit form

I am wanting to customise the edit form in jqGrid so that instead of using the table structured layout provided I would like to use my own custom css structured layout for the form elements. How should I go about modifying the edit form to allow me to use my own custom look?
You can definitely achieve this by jquery ui dialog. However I can not put full code for you but helps you in the steps you have to do.
1 design your custom form whatever CSS and style you want to apply.
Suppose this is youe custome form
<div id="dialog-div">
<input type="text">
</div>
2 on jquery dialog open the dialog on your jqgrid editbutton click
$("#edit").click(function(){
var rowdata = $("#coolGrid").jqGrid('getGridParam','selrow');
if(rowdata){
$("#dialog-div").dialog('open');
var data = $("#coolGrid").jqGrid('getRowData',rowdata);
alert(data);
}
});
by default it will close as-
$("#dialog-div").dialog({
autoOpen: false,
});
Now as you get data in variable you can put in your edit form and of jquery dialog button save it according to your logic.
Hope this helps you.
I would recommend you first of all to read (or at least look thorough) the code of form editing module which implement the part which you want to replace. You will see that it consist from more as 2000 lines of code. If you write "I would like to ..." you should understand the amount of work for implementing what you ask. If you are able to understand the code and if you are able to write your modification of the code even using libraries like jQuery UI then you can decide whether it's worth to invest your time to do the work. The main advantage of using existing solutions is saving of the time. What you get in the way is not perfect, but using existing products you could create your own solutions quickly and with acceptable quality. The way to study existing products which you can use for free seems me more effective as large investments in reinventing the wheel.
http://guriddo.net/?kbe_knowledgebase=using-templates-in-form-editing
Using templates in form editing
As of version 4.8 we support templates in the form editing. This allow to customize the edit form in a way the developer want. To use a template it is needed to set the parameter template in the edit add/or add options of navigator. This can be done in navigator or in the editing method editGridRow :
$("#grid").jqGrid("navGrid",
{add:true, edit:true,...},
{template: "template string for edit",...}
{template: "template string for add",...},
...
);
and in editGridRow method:
$("#grid").jqGrid("editGridRow",
rowid,
{template: "template string",...}
);
To place the CustomerID field in the template the following code string should be inserted in the template string
{CustomerID}
With other words this is the name from colModel put in { }
The usual problem with table layouts is when you have columns with different widths, especially with those very wide.
I solved my problem adding the attr colspan to wide columns in the beforeShowForm event.
for example
"beforeShowForm":function() {
$('#tr_fieldnameasinColModel > td.DataTD').attr('colspan',5);
}
It's not fancy but it worked for me. Perhaps there is a more elegant way to do the same.
I could arrange the fields in several columns without having to make the form extrawide.
When user click on edit button the page navigate to another page, based on Id get the details of a row and you can display the values..
Previous answer of Creating a link in JQGrid solves your problem.

Prototype add/remove id

I´m trying to add a click event via id to a div, so that when you click on it, it moves using effects.move, but after clicking on it the first time I want the id to be removed so that it doesn´t move anymore. So far I´ve tried using observe and stopObserving - and also removing the associated id so that it doesn´t move any more. I can´t figure out how to integrate a click event with an observe, without adding it directly to the div.
Any suggestions or relative links would be greatly appreciated!
link to jsfiddle:
http://jsfiddle.net/QN4TN/2/
Once you have set the observer removing the ID will not stop the event being handled. You should do something like this:
<div id="moveme">...</div>
<script type="text/javascript">
$('moveme').observe('click', function(ev) {
ev.stop();
ev.target.stopObserving('click');
... Call move function here ...
});
</script>
This will respond to the click by removing all the click handlers from the div (And then calling your scriptaculous code). If this is a problem, you should store the pre-bound handler and then pass that as the second parameter of the stopObserving method.

jQuery children of cloned element not responding to events

Summary
I am using jQuery to clone a div ("boxCollection") containing groups ("groupBox") each of which contains a set of inputs. The inputs have change events tied to them at $(document).ready, but the inputs inside the cloned divs do not respond to the event triggers. I can not get this to work in IE7, IE8, or FF3.
Here is my sample code:
HTML:
<div class="boxCollection"><div class="groupBox" id="group_1"><input type="text"></input></div></div>
jQuery events:
$(".groupBox[id*='group']").change(function(){
index = $(this).attr("id").substring(6);
if($("input[name='collection_"+index+"']").val() == "")
{
$("input[name='collection_"+index+"']").val("Untitled Collection "+index);
}
});
jQuery clone statement:
$(".boxCollection:last").clone(true).insertAfter($(".boxCollection:last"));
Use live() to automatically put event handlers on dynamically created elements:
$(".groupBox[id*='group']").live("change", function() {
...
});
You appear to be putting a change() event handler on a <div> however (based on your sample HTML). Also, I would recommend not using an attribute selector for this. You've given it a class so instead do:
$("div.groupBox ...")...
Lastly, you are trying to give each text input a unique name. You don't say what your serverside technology is but many (most?) will handle this better than that. In PHP for example you can do:
And $_POST will contain an element "box" with an array of three values.
I'm not sure if this will work, but I'm going to give it a shot and say that you need to assign live events
$(".groupBox[id*='group']").live('change', function() { });
You'll probably have a problem with change and live in IE6/7, so I advise you to use the livequery plugin to resolve that issue.

Resources