Set the focus to a newly added input element in extension multimodelform

Hi,

I am using the extension multimodelform http://www.yiiframework.com/extension/multimodelform

Now I want to increase the usability of my project:

After adding a new row to the form the focus should be set automatically to a certain input field in the new row.

How can this be done?

Please help.

hi there,

the extension provides few hooks you can hook into and register your own code here is an example I copied from the wiki page and modified.




// change your input id accordingly 

echo CHtml::script('function changeFocus(newElement) { 

    $(newElemment).find("#input-id").focus();

}');


$this->widget('ext.multimodelform.MultiModelForm', [

  // ...

  'jsAfterCloneCallback' => 'changeFocus',

  // ...

]);

Thank you for your answer.

I had already fiddled with jsAfterCloneCallback before without success.

Now I tried as you suggested.

But the focus does not move after click on the copy link above the multimodelform.

Now I tried some possibilities to find out the reason why it does not work:


echo CHtml::script('function changeFocus(newElement) {

   alert($(newElement).attr("id")); // first alert

   alert(newElement.attr("id")); // first alert

   alert($(newElement).find("#Werke_Komponist_Id").attr("id"));

   alert(newElement.find("#Werke_Komponist_Id").attr("id"));

   $(newElement).find("#Werke_Komponist_Id").focus(); // set the focus

   newElement.find("#Werke_Komponist_Id").focus(); // set the focus

}');

The first alerts show the id-attribute: "Werke_Komponist_Id".

The next two alerts say "undefined".

Therefore the last two lines cannot set the focus.

May be I understand something wrong. I am not really a professional.

Please help.

I believe the reason your alerts don’t work is because of an error on the page, your first call works fine the second statement throws an error and your script stops executing

alwasy wrap your el with jquery fn to do dom manipulation like


 $(newElement)




echo CHtml::script('function changeFocus(newElement) {

   alert( $(newElement).attr("id") ); // first alert


  // following will not work because you attr function is not defined, attr is only available in jquery 

   alert( newElement.attr("id")  ); // first alert


   alert(     $(newElement).find("#Werke_Komponist_Id").attr("id")   );


  // same goes here jquery object only allows you call attr its not available in the dom api

   alert(    newElement.find("#Werke_Komponist_Id").attr("id")        );


   $(newElement).find("#Werke_Komponist_Id").focus(); // set the focus


   newElement.find("#Werke_Komponist_Id").focus(); // set the focus

}');

I tried also without wrapping the element with $(…) because of the example that I found in the multimodelform code near line 285 and indeed this command does NOT produce an error.


echo CHtml::script('function changeFocus(newElement) {

    alert($(newElement).attr("id"));

    alert(newElement.attr("id")); // no error !

    alert($(newElement).find("#Werke_Komponist_Id").attr("id"));

}');

The first two alerts show the same string: "Werke_Komponist_Id".

The third alert produces "undefined".

I am not sure what seems to be the problem I can help you debug it

Thank you very much for trying to help me.

Now I found a solution:


echo CHtml::script('function changeFocus(newElement) {

  var str = $(newElement).attr("id");

    if (str.indexOf("Werke_Komponist_Id") == 0) { // Check if the attr("id") starts with that value

        setTimeout(function() { $(newElement).focus(); } , 500);

    }

}');

I had to use


if (str.indexOf("Werke_Komponist_Id") == 0)

because the extension multimodelform appends one or more numbers to each new row:

The first clone remains unchanged:


id="Werke_Komponist_Id"

The next clone get:


id="Werke_Komponist_Id2"

and the next:


id="Werke_Komponist_Id23"

and so on.

I think it is necessary to use setTimeout() to change the focus after the clone process has finished.

May be, this is not the best solution, but it seems to work. :rolleyes: