// NOTE: [This JS must loaded as last item]
function SELECT_MODAL_MULTI_CATEGORY_PRODUCT(){};

	// ===============================================================
	// Part 0 : Initialize Form
	// ===============================================================	
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV = null;
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.SEARCH_CMD = null;
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.APPLY_CMD = null;
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.ADD_ALL_CMD = null;
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.INPUT_INSTANCE = null;
	
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.PRESET_MAP_ARRAY = null;
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.AUTO_SELECT = false;
	
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_MAP_ARRAY = null;
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_IGNORE_NEXT_REQUEST = false;
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_CALLBACK_METHOD = null;
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_CALLBACK_CONTROL = null;
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_CALLBACK_FIELD = null;
	
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PREV_BBI = null;
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_NEXT_BBI = null;
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB = null;

	// ===============================================================
	// Part 1 : Initialize Form
	// ===============================================================
	
	/**
	 *	Show Customer Selection modal
	 *	@param CALLBACK_METHOD Optional Callback on successful action. Method(ID, DESCRIPTION, CUSTOM_FIELD)
	 *	@param CALLBACK_CONTROL Optional Modal will assign a value to a element on success.
	 *	@param CALLBACK_FIELD Optional custom field to be returned as third parameter at callback method.
	 */	
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.SHOW = function
	(
		CALLBACK_METHOD, CALLBACK_CONTROL, CALLBACK_FIELD, GET_MAP_ARRAY
	)
	{
		// Initialize
		// _______________________________________________________________________
		if(JSVC_VAR.VAR_ISSET(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV) == false)
		{
			// Initialize Modal and DGV
			// ...........................................
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV = DataGridView("SELECT_MODAL_MULTI_CATEGORY_PRODUCT_DGV");
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV.ON_CLICK
			(			
				function(COL_INDEX, ROW_INDEX)
				{
					if(COL_INDEX != SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV.COLUMN.INDEX("ROW_IS_SELECTED"))
					{
						SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV.CELL.VALUE("ROW_IS_SELECTED", ROW_INDEX, true);
					}
				}
			);   	
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.INPUT_INSTANCE = JSOC_WINDOW.VAR_INPUT_INSTANCE_CLONE("SELECT_MODAL_MULTI_CATEGORY_PRODUCT");		

			// Initialize: Load more items to the list
			// ...........................................
			if(JSOC_ELEMENT.VAR_ELEMENT_EXISTS("SELECT_MODAL_MULTI_CATEGORY_PRODUCT_LOAD_PREV_BBI"))
			{
	    		SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PREV_BBI = JSOC_ELEMENT.VAR_GET("SELECT_MODAL_MULTI_CATEGORY_PRODUCT_LOAD_PREV_BBI");  
				SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PREV_BBI.onclick = 
					function()
					{
						var CURRENT_INDEX = JSOC_CMB.VAR_SELECTED_INDEX(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB);
						if(CURRENT_INDEX > 0)
						{
							JSOC_CMB.VAR_SELECTED_INDEX(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB, CURRENT_INDEX - 1);
							SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB.onchange();
						}
					};
			}		
			if(JSOC_ELEMENT.VAR_ELEMENT_EXISTS("SELECT_MODAL_MULTI_CATEGORY_PRODUCT_LOAD_NEXT_BBI"))
			{
	    		SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_NEXT_BBI = JSOC_ELEMENT.VAR_GET("SELECT_MODAL_MULTI_CATEGORY_PRODUCT_LOAD_NEXT_BBI");  
				SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_NEXT_BBI.onclick = 
					function()
					{
						var CURRENT_INDEX = JSOC_CMB.VAR_SELECTED_INDEX(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB);
						if(CURRENT_INDEX + 1 < JSOC_CMB.VAR_COUNT(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB))
						{
							JSOC_CMB.VAR_SELECTED_INDEX(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB, CURRENT_INDEX + 1);
							SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB.onchange();
						}
					};
			}		
			if(JSOC_ELEMENT.VAR_ELEMENT_EXISTS("SELECT_MODAL_MULTI_CATEGORY_PRODUCT_LOAD_PAGING_CMB"))
			{
	    		SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB = JSOC_ELEMENT.VAR_GET("SELECT_MODAL_MULTI_CATEGORY_PRODUCT_LOAD_PAGING_CMB");  
				SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB.onchange = 
					function()
					{
						SELECT_MODAL_MULTI_CATEGORY_PRODUCT.HTTP_SEARCH_LOAD_PAGE();
					};
			}
			
			// Initialize: Button
			// ...........................................
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.SEARCH_CMD = JSOC_ELEMENT.VAR_GET("SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_CMD");
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.SEARCH_CMD.onclick =
				function()
				{
					SELECT_MODAL_MULTI_CATEGORY_PRODUCT.HTTP_SEARCH();
				};
			
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.APPLY_CMD = JSOC_ELEMENT.VAR_GET("SELECT_MODAL_MULTI_CATEGORY_PRODUCT_APPLY_CMD");
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.APPLY_CMD.onclick = 
				function()
				{
					SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DIALOG_OK();
				};
				
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.ADD_ALL_CMD = JSOC_ELEMENT.VAR_GET("SELECT_MODAL_MULTI_CATEGORY_PRODUCT_ADD_ALL_CMD");
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.ADD_ALL_CMD.onclick = function()
				{
					SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DIALOG_ADD_ALL();
				};				
				
			// Load Foreign Key
			// ...........................................
			if
			(
				JSOC_ELEMENT.VAR_ELEMENT_EXISTS("SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_CAT_PRODUCT_CAT_UOM_ID_CMB") == true 
			)
			{
				JSOC_CMB.VAR_CLEAR("SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_CAT_PRODUCT_CAT_UOM_ID_CMB");
				JSOC_CMB.VAR_ADD("SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_CAT_PRODUCT_CAT_UOM_ID_CMB", FLAG_BIGINT_NULL.toString(),"Any Uom");
				// To use custom populate
				// var GET_MAP_ARRAY = JSCUS_SQL._CATEGORY._UOM.CUS_PREPARE_MAPPED_ARRAY_FOR_GET();
				// JSVC_MAP_ARRAY.VAR_SET(GET_MAP_ARRAY, 'PARAM_', JSCUS_SQL._SYSTEM._STATUS.STATUS_ACTIVE);	
				JSCUS_SQL._CATEGORY._UOM.CUS_GET_THEN_POPULATE_COMBOBOX
				(
					function(IS_SUCCESS, RESPONSE_STRING)
					{
						// Set Default index
						JSOC_CMB.VAR_SELECTED_INDEX("SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_CAT_PRODUCT_CAT_UOM_ID_CMB", 0);
						
						// Forward populate complete event.		
						$('.BSSP_SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_CAT_PRODUCT_CAT_UOM_ID_CMB').selectpicker('refresh');
						HTTP_POPULATE_RESULT();
					},		
					"SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_CAT_PRODUCT_CAT_UOM_ID_CMB",
					true, 2
					// , GET_MAP_ARRAY 
				);
			}
		}
		
		// Copy params to cache
		// _______________________________________________________________________
		SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_CALLBACK_METHOD = CALLBACK_METHOD;
		SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_CALLBACK_CONTROL = CALLBACK_CONTROL;
		SELECT_MODAL_MULTI_CATEGORY_PRODUCT.PRESET_MAP_ARRAY = GET_MAP_ARRAY;
		
		// Display Modal
		// _______________________________________________________________________
		JSOC_WINDOW.VAR_INPUT_INSTANCE_RESTORE(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.INPUT_INSTANCE);
		SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_MAP_ARRAY = null;
		SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_IGNORE_NEXT_REQUEST = false;
		
		if(JSVC_VAR.VAR_ISSET(GET_MAP_ARRAY) == false)
		{
			JSOC_DIALOG.VAR_MODAL("SELECT_MODAL_MULTI_CATEGORY_PRODUCT", true);
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.HTTP_SEARCH();
		}
		else
		{
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.HTTP_SEARCH_PRESET(GET_MAP_ARRAY);
		}
		
		// Prepare callback methods
		// _______________________________________________________________________	
		if(JSVC_VAR.VAR_ISSET(CALLBACK_FIELD) == false)
		{		
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_CALLBACK_FIELD = null;
		}
		else
		{
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_CALLBACK_FIELD = CALLBACK_FIELD;	
		}
	};
	
	
	// ===============================================================
	// Part 2.A : Search Option
	// ===============================================================
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.HTTP_SEARCH = function()
	{
		// Actual Function
		// _______________________________________________________________________
		var GET_MAP_ARRAY = JSCUS_SQL._CATEGORY._PRODUCT.CUS_PREPARE_MAPPED_ARRAY_FOR_GET();	
		SELECT_MODAL_MULTI_CATEGORY_PRODUCT.AUTO_SELECT = false;
		
		JSCUS_SQL._ADD_FROM
		(
			GET_MAP_ARRAY, 'SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_CAT_PRODUCT_CAT_UOM_ID_CMB', 'PARAM_CAT_PRODUCT_CAT_UOM_ID'
		);
		JSCUS_SQL._ADD_FROM
		(
			GET_MAP_ARRAY, 'SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_CAT_PRODUCT_BARCODE_TXT', 'PARAM_CAT_PRODUCT_BARCODE'
		);	
		JSCUS_SQL._ADD_FROM
		(
			GET_MAP_ARRAY, 'SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_CAT_PRODUCT_ITEMCODE_TXT', 'PARAM_CAT_PRODUCT_ITEMCODE'
		);	
		JSCUS_SQL._ADD_FROM
		(
			GET_MAP_ARRAY, 'SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_CAT_PRODUCT_DESCRIPTION_TXT', 'PARAM_CAT_PRODUCT_DESCRIPTION'
		);	
		JSCUS_SQL._ADD_FROM
		(
			GET_MAP_ARRAY, 'SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_CAT_PRODUCT_HAS_RECIPE_CMB', 'PARAM_CAT_PRODUCT_HAS_RECIPE'
		);
		JSCUS_SQL._ADD_FROM
		(
			GET_MAP_ARRAY, 'SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_CAT_PRODUCT_ING_PRICE_FROM_TXT', 'PARAM_CAT_PRODUCT_ING_PRICE_FROM'
		);
		JSCUS_SQL._ADD_FROM
		(
			GET_MAP_ARRAY, 'SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_CAT_PRODUCT_ING_PRICE_TO_TXT', 'PARAM_CAT_PRODUCT_ING_PRICE_TO'
		);
		JSCUS_SQL._ADD_FROM
		(
			GET_MAP_ARRAY, 'SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_CAT_PRODUCT_ING_NET_CONTENT_FROM_TXT', 'PARAM_CAT_PRODUCT_ING_NET_CONTENT_FROM'
		);
		JSCUS_SQL._ADD_FROM
		(
			GET_MAP_ARRAY, 'SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_CAT_PRODUCT_ING_NET_CONTENT_TO_TXT', 'PARAM_CAT_PRODUCT_ING_NET_CONTENT_TO'
		);
		JSCUS_SQL._ADD_FROM
		(
			GET_MAP_ARRAY, 'SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_CAT_PRODUCT_MIXTURE_QTY_FROM_TXT', 'PARAM_CAT_PRODUCT_MIXTURE_QTY_FROM'
		);
		JSCUS_SQL._ADD_FROM
		(
			GET_MAP_ARRAY, 'SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_CAT_PRODUCT_MIXTURE_QTY_TO_TXT', 'PARAM_CAT_PRODUCT_MIXTURE_QTY_TO'
		);
		JSCUS_SQL._ADD_FROM
		(
			GET_MAP_ARRAY, 'SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_CAT_PRODUCT_MIXTURE_COST_FROM_TXT', 'PARAM_CAT_PRODUCT_MIXTURE_COST_FROM'
		);
		JSCUS_SQL._ADD_FROM
		(
			GET_MAP_ARRAY, 'SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_CAT_PRODUCT_MIXTURE_COST_TO_TXT', 'PARAM_CAT_PRODUCT_MIXTURE_COST_TO'
		);
		JSCUS_SQL._ADD_FROM
		(
			GET_MAP_ARRAY, 'SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_CAT_PRODUCT_STATUS_CMB', 'PARAM_CAT_PRODUCT_STATUS'
		);
		JSCUS_SQL._ADD_FROM
		(
			GET_MAP_ARRAY, 'SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_CAT_PRODUCT_SYSTEM_GENERATED_TXT', 'PARAM_CAT_PRODUCT_SYSTEM_GENERATED'
		);
		JSCUS_SQL._ADD_FROM
		(
			GET_MAP_ARRAY, 'SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_ORDER_BY_CMB', 'PARAM_ORDER_FIELD'
		);	
		JSCUS_SQL._ADD_FROM
		(
			GET_MAP_ARRAY, 'SELECT_MODAL_MULTI_CATEGORY_PRODUCT_SEARCH_LIMIT_CMB', 'PARAM_LIMIT'
		);	
					
		// REGULAR Search Mode
		// _______________________________________________________________________	
		JSOC_DIALOG.VAR_LOADING_SPINNER(true);
		JSCUS_SQL._CATEGORY._PRODUCT.CUS_GET
		(
			GET_MAP_ARRAY,
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.HTTP_SEARCH_CALLBACK,
			true
		); 			
		
		// Update Paging Cache
		// _______________________________________________________________________
		SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_MAP_ARRAY = GET_MAP_ARRAY;
	};


	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.HTTP_SEARCH_PRESET = function(PREPARED_MAP_ARRAY)
	{	
		// Pre-populate Elements
		// _______________________________________________________________________	
		SELECT_MODAL_MULTI_CATEGORY_PRODUCT.AUTO_SELECT = true;
					
		// REGULAR Search Mode
		// _______________________________________________________________________	
		JSOC_DIALOG.VAR_LOADING_SPINNER(true);
		JSCUS_SQL._CATEGORY._PRODUCT.CUS_GET
		(
			PREPARED_MAP_ARRAY,
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.HTTP_SEARCH_CALLBACK,
			true
		); 			
		
		// Update Paging Cache
		// _______________________________________________________________________
		SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_MAP_ARRAY = GET_MAP_ARRAY;
	};
		
	
	// ===============================================================
	// Part 2.B : Search Pagination
	// ===============================================================
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.HTTP_SEARCH_LOAD_PAGE = function()
	{
		// Abort if no GET cache is found
		// _______________________________________________________________________		
		if
		(
			JSVC_VAR.VAR_ISSET(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_MAP_ARRAY) == false ||
			JSOC_CMB.VAR_SELECTED_INDEX(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB) < 0
		)
		{
			return;
		}
		
		// Update Paging row count
		// _______________________________________________________________________
		SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_MAP_ARRAY['PARAM_SKIP'] = 
		JSVC_NUM.VAR_NVALL(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_MAP_ARRAY['PARAM_LIMIT']) *
		JSOC_CMB.VAR_SELECTED_INDEX(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB);	
		
		// REGULAR Search Mode
		// _______________________________________________________________________
		SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_IGNORE_NEXT_REQUEST = true;
		JSOC_DIALOG.VAR_LOADING_SPINNER(true);
		JSCUS_SQL._CATEGORY._PRODUCT.CUS_GET
		(
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_MAP_ARRAY,
			function (IS_SUCCESS, RESPONSE_STRING)
			{
				SELECT_MODAL_MULTI_CATEGORY_PRODUCT.HTTP_SEARCH_CALLBACK(IS_SUCCESS, RESPONSE_STRING, false);
			},
			true
		);
	};

	// ===============================================================
	// Part 2.C : Search Paging Control
	// ===============================================================	
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.HTTP_SEARCH_LOAD_PAGING_UPDATE = function(ROW_COUNT)
	{
		// Abort if no paging function enabled
		// _______________________________________________________________________
		if
		(
			JSVC_VAR.VAR_ISSET(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB) == false || 
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_IGNORE_NEXT_REQUEST == true
		)
		{
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_IGNORE_NEXT_REQUEST = false;
			return;
		}
		
		// Initialize
		// _______________________________________________________________________
		var PAGING_INDEX = 0;
		var PAGING_COUNT = 
			ROW_COUNT / JSVC_NUM.VAR_NVALL(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_MAP_ARRAY['PARAM_LIMIT']);
		PAGING_COUNT = Math.trunc(PAGING_COUNT) + 1;
		JSOC_CMB.VAR_CLEAR(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB);
		
		// Populate Paging
		// _______________________________________________________________________
		while(PAGING_COUNT > PAGING_INDEX)
		{
			JSOC_CMB.VAR_ADD
			(
				SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB, 
				(PAGING_INDEX + 1).toString(), 
				(PAGING_INDEX + 1).toString()
			);
			PAGING_INDEX ++;
		}
	};
	
	
	// ===============================================================
	// Part 2.D : Search Search Handler
	// ===============================================================	
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.HTTP_SEARCH_CALLBACK = function(IS_SUCCESS, RESPONSE_STRING, KEEP_DGV_ITEMS = false)
	{
		// Disable Dialogs
		// _______________________________________________________________________
		CUS_SEND_DIALOG_TRY_DISMISS();
		
		// Validate
		// _______________________________________________________________________
		if(IS_SUCCESS === false)
		{
			console.error("CONNECTION ERROR: \n" + RESPONSE_STRING);
			return;
		}
		
		// Validate JSON Response
		// _______________________________________________________________________
		var JSON_OBJECT = JSRC_JSON.REF_CREATE(RESPONSE_STRING);
		if(JSRC_JSON.REF_IS_SUCCESS(JSON_OBJECT) === false)
		{
			console.error("REQUEST ERROR: \n" + RESPONSE_STRING);
			return;
		}
		
		// Back to DGV Top
		// _______________________________________________________________________	
		if(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_IGNORE_NEXT_REQUEST == true)
		{
			JSOC_ELEMENT.VAR_GET("SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV").scrollIntoView
			(
				{
			  		behavior: 'auto', 
			  		block: 'start'
				}
			);		
		}
		
		// JSON Empty (Clears the DataGrodView)
		// _______________________________________________________________________
		if(JSRC_JSON.REF_READ(JSON_OBJECT, "JSON_COUNT") <= 0)
		{
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.HTTP_SEARCH_LOAD_PAGING_UPDATE(0);
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV.ROW.CLEAR();
			if(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV.COLUMN.TOTAL_IS_READY())
			{
				SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV.COLUMN.TOTAL_REFRESH();
			}
			return;
		}
		SELECT_MODAL_MULTI_CATEGORY_PRODUCT.HTTP_SEARCH_LOAD_PAGING_UPDATE
		(
			JSVC_NUM.VAR_NVALL
			(
				JSRC_JSON.REF_READ(JSON_OBJECT, "RECORD_COUNT", 1)
			)
		);
		
		// Populate DGV
		// _______________________________________________________________________
		SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV.POPULATE_FROM_QUERY
		(
				JSON_OBJECT, 
				'',
				KEEP_DGV_ITEMS,
				false,
				SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_MAP_ARRAY['PARAM_SKIP'] + 1,
				[2, 1]
		);

		
		// Initialize
		// _______________________________________________________________________	
		var WEBTABLE_DATE = null;
		var CURRENT_CELL_VALUE = null;
		var ROW_INDEX = 0;
	
	
		// DateTime Format
		// _______________________________________________________________________	
		
		
		// Color Coding (Uncomment to use)
		// _______________________________________________________________________	
		//SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV.CELL.ELEMENT("COLUMN_NAME", ROW_INDEX).style.color = "#1cc88a"; // Safe
		//SELECT_MODAL_MULTI_CATEGORY_PRODUCT_DGV.CELL.ELEMENT("COLUMN_NAME", ROW_INDEX).style.color = "#5a5c69"; // Neutral
		//SELECT_MODAL_MULTI_CATEGORY_PRODUCT_DGV.CELL.ELEMENT("COLUMN_NAME", ROW_INDEX).style.color = "#f6c23e"; // Caution
		//SELECT_MODAL_MULTI_CATEGORY_PRODUCT_DGV.CELL.ELEMENT("COLUMN_NAME", ROW_INDEX).style.color = "#e74a3b"; // Warning


		// Auto-total tool
		// _______________________________________________________________________	
		if(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV.COLUMN.TOTAL_IS_READY())
		{
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV.COLUMN.TOTAL_REFRESH();
		}
		
		// Auto Dismiss
		if(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.AUTO_SELECT == true)
		{
			// If rows exists
			if(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV.ROW.COUNT() > 0)
			{
				SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV.CELL.VALUE("ROW_IS_SELECTED", 0, true);
				SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DIALOG_OK();
			}
			
			// If no result found
			else
			{
				console.log('SELECT_MODAL_MULTI_CATEGORY_PRODUCT : Preset not found');
				console.log(['SELECT_MODAL_MULTI_CATEGORY_PRODUCT.PRESET_MAP_ARRAY', SELECT_MODAL_MULTI_CATEGORY_PRODUCT.PRESET_MAP_ARRAY]);
				alert('Unable to populate product : selmodal');
			}
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DIALOG_OK();
		}
	};
				
				
	// ===============================================================
	// Part 3 : Return Selected Item
	// ===============================================================	
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DIALOG_OK = function()
	{
		// Initialize
		// _______________________________________________________________________
		var ROW_COUNT = SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV.ROW.COUNT();
		var ROW_INDEX = 0;
		
		var SELECTED_IDS = [];
		var SELECTED_DESCRIPTIONS = [];
		var SELECTED_CUSTOMS = [];
		
		// Get selected option
		// _______________________________________________________________________
		while(ROW_COUNT > ROW_INDEX)
		{
			if(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV.CELL.VALUE('ROW_IS_SELECTED', ROW_INDEX))
			{
				SELECTED_IDS.push(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV.CELL.VALUE('CAT_PRODUCT_ID', ROW_INDEX));
				SELECTED_DESCRIPTIONS.push(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV.CELL.VALUE('CAT_PRODUCT_DESCRIPTION', ROW_INDEX));
				if(JSVC_VAR.VAR_ISSET(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_CALLBACK_FIELD))
				{		
					SELECTED_CUSTOMS.push(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV.CELL.VALUE(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_CALLBACK_FIELD, ROW_INDEX));
				}
			}
			ROW_INDEX ++;
		}
		
		// Dismiss Modal
		// _______________________________________________________________________
		SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DIALOG_SUCCESS_ACTION
		(
			SELECTED_IDS, 
			SELECTED_DESCRIPTIONS, 
			SELECTED_CUSTOMS
		);
	};
	
	
	// ===============================================================
	// Part 3.B : Add ALL Item
	// ===============================================================	
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DIALOG_ADD_ALL = function()
	{
		// Abort if nothing to add
		// _______________________________________________________________________
		if
		(
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV.ROW.COUNT() <= 0 && 
			JSOC_CMB.VAR_COUNT(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB) <= 1
		)
		{
			JSVC_ERROR.VAR_ARGUMENT_EXCEPTION_NOTHING_SELECTED(true);
			return;
		}
		
		
		// Initialize
		// _______________________________________________________________________
		var ROW_COUNT = 0;
		var ROW_INDEX = 0;
		var APPLY_EXTRA_DELAY = false;
		
		var SELECTED_IDS = [];
		var SELECTED_DESCRIPTIONS = [];
		var SELECTED_CUSTOMS = [];
		
		
		// Move to First Page
		// _______________________________________________________________________
		if(JSOC_CMB.VAR_SELECTED_INDEX(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB) > 0)
		{
			JSOC_CMB.VAR_SELECTED_INDEX(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB, 0);
			SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB.onchange();
		}
		
		
		// Add to result + to next page
		// _______________________________________________________________________
		var ADD_ALL_METHOD = function()
		{
			// Show Progress
			// ...........................................
			JSOC_DIALOG.VAR_LOADING_SPINNER(true);
		
			// Abort if on-going HTTP request is running
			// ...........................................
			if(CUS_SEND_REQUEST_HAS_QUEUE())
			{
				JSRC_THREAD.REF_POST_DELAYED
				(
					function()
					{
						APPLY_EXTRA_DELAY = true;
						ADD_ALL_METHOD();
					},
					300
				);	
				return;
			}			
			
			// Add extra delay while preparing for DataGridView
			// ...........................................
			if(APPLY_EXTRA_DELAY == true)
			{
				JSRC_THREAD.REF_POST_DELAYED
				(
					function()
					{
						APPLY_EXTRA_DELAY = false;
						ADD_ALL_METHOD();
					},
					1200
				);				
				return;
			}
			
			// Add all contacts
			// ...........................................
			ROW_COUNT = SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV.ROW.COUNT();
			ROW_INDEX = 0;
			while(ROW_COUNT > ROW_INDEX)
			{
				SELECTED_IDS.push(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV.CELL.VALUE('CAT_PRODUCT_ID', ROW_INDEX));
				SELECTED_DESCRIPTIONS.push(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV.CELL.VALUE('CAT_PRODUCT_DESCRIPTION', ROW_INDEX));
				if(JSVC_VAR.VAR_ISSET(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_CALLBACK_FIELD))
				{		
					SELECTED_CUSTOMS.push(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DGV.CELL.VALUE(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_CALLBACK_FIELD, ROW_INDEX));
				}
				
				ROW_INDEX ++;
			}		
			
			// To next page
			// ...........................................
			if
			(
				JSOC_CMB.VAR_COUNT(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB) > 
				JSOC_CMB.VAR_SELECTED_INDEX(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB) + 1
			)
			{
				JSOC_CMB.VAR_SELECTED_INDEX
				(
					SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB, 
					JSOC_CMB.VAR_SELECTED_INDEX(SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB) + 1
				);
				SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_CMB.onchange();
				
				JSRC_THREAD.REF_POST_DELAYED
				(
					function()
					{
						APPLY_EXTRA_DELAY = true;
						ADD_ALL_METHOD();
					},
					300
				);
			}
			
			// Dismiss Modal
			// ...........................................
			else
			{
				// Disable Dialogs
				CUS_SEND_DIALOG_TRY_DISMISS();
		
				// Dimiss Modal
				SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DIALOG_SUCCESS_ACTION
				(
					SELECTED_IDS, 
					SELECTED_DESCRIPTIONS, 
					SELECTED_CUSTOMS
				);
			}
		};		
		ADD_ALL_METHOD();
	};
	
	
	// ===============================================================
	// Part 4 : Dismiss Modal
	// ===============================================================	
	SELECT_MODAL_MULTI_CATEGORY_PRODUCT.DIALOG_SUCCESS_ACTION = function
	(
		SELECTED_IDS, 
		SELECTED_DESCRIPTIONS, 
		SELECTED_CUSTOMS, 
	)
	{
		// Initialize
		// _______________________________________________________________________
		var CALLBACK_ELEMENT = SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_CALLBACK_CONTROL;
		var CALLBACK_METHOD = SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_CALLBACK_METHOD;
		
		
		// Dismiss Cache
		// _______________________________________________________________________
		SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_MAP_ARRAY = null;
		SELECT_MODAL_MULTI_CATEGORY_PRODUCT.LOAD_PAGING_IGNORE_NEXT_REQUEST = false;
		SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_CALLBACK_METHOD = null;
		SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_CALLBACK_CONTROL = null;
		SELECT_MODAL_MULTI_CATEGORY_PRODUCT.CACHE_CALLBACK_FIELD = null;
		
				
		// Handle Callback by control
		// _______________________________________________________________________
		if(JSVC_VAR.VAR_ISSET(CALLBACK_ELEMENT))
		{
			// Initialize
			// ...........................................
			CALLBACK_ELEMENT = JSOC_ELEMENT.VAR_GET(CALLBACK_ELEMENT);
			
			// Set Value
			// ...........................................
			JSOC_ELEMENT.VAR_VALUE(CALLBACK_ELEMENT, SELECTED_IDS.toString());
		}
		
		
		// Handle Callback method
		// _______________________________________________________________________
		if(JSVC_VAR.VAR_ISSET(CALLBACK_METHOD))
		{
			CALLBACK_METHOD(SELECTED_IDS, SELECTED_DESCRIPTIONS, SELECTED_CUSTOMS);
		}
		
		
		// Close Modal
		// _______________________________________________________________________	
		JSOC_DIALOG.VAR_MODAL("SELECT_MODAL_MULTI_CATEGORY_PRODUCT", false);		
	};
	
	
	// ===============================================================	
	// Load Required Script
	// ===============================================================	
	if(typeof JSCUS_SQL._CATEGORY._PRODUCT == 'undefined')
	{
		document.write('<script src="' + JSCUS_CACHE.SERVER_URL + '\/res\/comm\/category\/product.js"><\/script>');
	}
