Skip to Main Content

Change text item size and maxlength dynamically

I just wrap up solution from this OTN forum post here.

If you need change item size dynamically based on some value e.g. select list, I did find it is good store values, item names and size to own table.

I did create table, sequence and trigger:

CREATE TABLE DEMO_ITEM_DYN_SIZE(
    PK_ID        NUMBER NOT NULL,
    LOV_VALUE    VARCHAR2(2) NOT NULL,
    ITEM_NAME    VARCHAR2(80) NOT NULL,
    ITEM_SIZE    NUMBER NOT NULL,
    CONSTRAINT DEMO_ITEM_DYN_SIZE_PK PRIMARY KEY(PK_ID)
);

CREATE SEQUENCE DEMO_ITEM_DYN_SIZE_SEQ NOCACHE;

CREATE OR REPLACE TRIGGER DEMO_ITEM_DYN_SIZE_TRG
BEFORE INSERT ON DEMO_ITEM_DYN_SIZE FOR EACH ROW 
BEGIN 
  IF inserting THEN
    IF :NEW.PK_ID IS NULL THEN
      SELECT DEMO_ITEM_DYN_SIZE_SEQ.nextval
      INTO :NEW.PK_ID
      FROM DUAL ;
    END IF;
  END IF;
END;
/

Insert some data to table:

INSERT INTO DEMO_ITEM_DYN_SIZE(LOV_VALUE,ITEM_NAME,ITEM_SIZE)
VALUES ('IN', 'P214_ATTRIBUTE_1', '15');
INSERT INTO DEMO_ITEM_DYN_SIZE(LOV_VALUE,ITEM_NAME,ITEM_SIZE)
VALUES ('IN', 'P214_ATTRIBUTE_2', '10');
INSERT INTO DEMO_ITEM_DYN_SIZE(LOV_VALUE,ITEM_NAME,ITEM_SIZE)
VALUES ('IN', 'P214_ATTRIBUTE_3', '5');
INSERT INTO DEMO_ITEM_DYN_SIZE(LOV_VALUE,ITEM_NAME,ITEM_SIZE)
VALUES ('IN', 'P214_ATTRIBUTE_4', '8');

INSERT INTO DEMO_ITEM_DYN_SIZE(LOV_VALUE,ITEM_NAME,ITEM_SIZE)
VALUES ('US', 'P214_ATTRIBUTE_1', '5');
INSERT INTO DEMO_ITEM_DYN_SIZE(LOV_VALUE,ITEM_NAME,ITEM_SIZE)
VALUES ('US', 'P214_ATTRIBUTE_2', '10');
INSERT INTO DEMO_ITEM_DYN_SIZE(LOV_VALUE,ITEM_NAME,ITEM_SIZE)
VALUES ('US', 'P214_ATTRIBUTE_3', '2');
INSERT INTO DEMO_ITEM_DYN_SIZE(LOV_VALUE,ITEM_NAME,ITEM_SIZE)
VALUES ('US', 'P214_ATTRIBUTE_4', '8');

INSERT INTO DEMO_ITEM_DYN_SIZE(LOV_VALUE,ITEM_NAME,ITEM_SIZE)
VALUES ('CN', 'P214_ATTRIBUTE_1', '1');
INSERT INTO DEMO_ITEM_DYN_SIZE(LOV_VALUE,ITEM_NAME,ITEM_SIZE)
VALUES ('CN', 'P214_ATTRIBUTE_2', '5');
INSERT INTO DEMO_ITEM_DYN_SIZE(LOV_VALUE,ITEM_NAME,ITEM_SIZE)
VALUES ('CN', 'P214_ATTRIBUTE_3', '8');
INSERT INTO DEMO_ITEM_DYN_SIZE(LOV_VALUE,ITEM_NAME,ITEM_SIZE)
VALUES ('CN', 'P214_ATTRIBUTE_4', '10');

COMMIT;

Create On Demand Process GET_ITEM_SIZE:

DECLARE
  l_sql VARCHAR2(32700);
BEGIN

  l_sql := '
    SELECT item_name,
      item_size
    FROM demo_item_dyn_size
    WHERE lov_value = :P214_COUNTRY'
    ;
   APEX_UTIL.JSON_FROM_SQL(l_sql);

EXCEPTION WHEN OTHERS THEN 
  HTP.PRN('{"row":[]}');
END ;

Remember change P214_COUNTRY according your select list name.

Insert to page JavaScript Function and Global Variable Declaration:

function getItemSize(pThis){
 var lVal=$v(pThis),
 lId=$x(pThis).id;
 if(lVal!="%"+"null%"&&lVal){
  $.ajax({
   url:"wwv_flow.show",
   dataType:"json",
   traditional:true,
   cache:false,
   type:"POST",
   data:{
    p_flow_id:"&APP_ID.",
    p_flow_step_id:"&APP_PAGE_ID.",
    p_instance:"&APP_SESSION.",
    p_request:"APPLICATION_PROCESS=GET_ITEM_SIZE",
    p_arg_names:lId,
    p_arg_values:lVal
   },
   success:function(jd){
    if(jd.row.length==0){
     $("#R_DYN_SIZE input[type='text']").attr({"size":30,"maxlength":30});
     return;
    }
    $.each(jd.row,function(i,jr){
     $($x(jr.ITEM_NAME)).attr({"size":jr.ITEM_SIZE,"maxlength":jr.ITEM_SIZE});
    });
   }
  });
 }else{
  $("#R_DYN_SIZE input[type='text']").attr({"size":30,"maxlength":30}).val("");
 }
}

Insert to page JavaScript Execute when Page Loads:

$("#P214_COUNTRY").change(function(){
 getItemSize(this);
}).trigger("change");

Remember change P214_COUNTRY according your select list name.

Above JavaScript code should set default length for text items, if select list value is null. In example I set all text items on region at once. For that you need set region static id "R_DYN_SIZE".

I did also create validation for each text item to check length is what specified on control table.

Validation Function Returning Boolean

DECLARE
  l_size NUMBER;
BEGIN
  BEGIN
    SELECT item_size
    INTO l_size
    FROM demo_item_dyn_size
    WHERE item_name = 'P214_ATTRIBUTE_1' -- Text item
      AND lov_value = :P214_COUNTRY      -- Select list
    ;
  EXCEPTION WHEN NO_DATA_FOUND THEN
    /* Default size */
    l_size := 30;
  END;

  IF LENGTH(:P214_ATTRIBUTE_1) > l_size THEN
    RETURN FALSE;
  END IF;
  RETURN TRUE;
END;

Remember change P214_COUNTRY according your select list name and P214_ATTRIBUTE_1 according text item name.

Comments

  • Animesh 26 Feb 2013
    Hi Jari, I was just off for lunch,when i came back and restarted. It was working fine. - Animesh
  • Jari Laine 26 Feb 2013

    Hi Animesh,

    I do not have any idea why it did not work initially. How you did debug problem on that time?

    Regards, Jari

  • Animesh 26 Feb 2013

    Hi Jari,

    First of all sorry for troubling you. Well, in APEX 4.2 I did that mistake(Placing JavaScript in worng place). But in my real app it was correct which is in APEX 4.1. The problem is the same app is working fine now, without any changes. Can you please tell me why initially it was not working and after I restarted my system it is working fine. I am afraid.

    - Thanks and Regards Animesh India

  • Jari Laine 26 Feb 2013

    Hi Animesh,

    You have placed JavaScript funtion to page JavaScript File URLs. Go edit your page and place JavaScript functions to correct places in page JavaScripts.

    Regards, Jari

  • Animesh 26 Feb 2013

    Hi Jari, I have placed an example on

    http://apex.oracle.com/

    WS:xxx PASS:xxz

    Please have a look. - Animesh

  • Animesh 26 Feb 2013

    Hi Jari, Its is not working for me. Is there any thing extra we need to do? - Animesh