[JS] Getting child objects or their properties without jQuery

Hi all,

For a very specific reason / situation (using second view inside IFRAME in parent view – discussed here) I can’t use jQuery or any other JS script (that is already registered in main view), because IE gets totally wako on this.

My job, is to get ID of a record, which data is displayed in particular CGridView row as good as value in one of its columns. With jQuery it would be a piece of cake and solutions like that were discussed many times in Yii forums. But without jQuery this seems to be a hard piece. At least to me.

So, I’m looking for any solution to get object or it’s property inside some other object, without using jQuery. Is it possible in pure JS and if so, can anyone show me, how?

I’ve crafted a piece of JS code, which allows me to bind onclick event to every CGridView row. In this event I’m able to read HTML contents of each clicked row. So, I’m getting something like this:


<td style="width: 75px">2</td>

<td style="text-align: left; width: 260px"><div>&nbsp;Wędrowycz Jakub</div></td>

<td style="width: 150px">mężczyzna</td>

<td style="width: 150px"><div>1919-06-04</div></td>

<td style="width: 150px"><div>19060475651</div></td>

<td style="width: 75px">1</td>

My question is, how to extract value from a particular column of such row and how to get ID of the record behind each row?

For first question, the only idea I figured out, is to use JS’s string manipulation and cut off piece I’m interested in from above string. But I feel that isn’t to professional, so I would like to ask, if anyone knows a better solution?

For the second task – how to mimic, without jQuery, the behaviour of $.fn.yiiGridView.getSelection(id) function, normally used in seletionChanged property of CGridView – unfortunately I have no idea.

Thank you in advance for any tips and cheers,

Trejder

Well… I’ve got it working pretty well, but I had to use a little bit trick.

First, I’ve added two new columns (in the beginning) to my CGridView.columns, filled them with data I need and set them to be invisible:


'columns'=>array

(

    	array

    	(

            	'type'=>'raw',

            	'headerHtmlOptions'=>array('style'=>'display: none;'),

            	'htmlOptions'=>array('style'=>'display: none;'),

            	'value'=>'"{{{".$data->ID."}}}"'

    	),

    	array

    	(

            	'type'=>'raw',

            	'headerHtmlOptions'=>array('style'=>'display: none;'),

            	'htmlOptions'=>array('style'=>'display: none;'),

            	'value'=>'"{{{".$data->PATIENT."}}}"'

    	),

    	...

)

Invisible for end-user, but not for JS script! :] Notice, that these columns are of raw type and their contents are surrounded by "{{{" and "}}}".

Then I modified my onclick handler attached to every row of that CGridView, so it would extract any value surround by those "{{{" and "}}}" and return it to a proper field:


function onGridViewSelectionChange()

{            	

    	var inner = this.innerHTML;

    	var pattern = /\{\{\{.*?\}\}\}/gi;

    	var matches = inner.match(pattern);

    	matches = matches.toString().replace(/{{{/gi, "").replace(/}}}/gi, "").split(",");


    	document.getElementById("pacjent-id").value = matches[0];

    	document.getElementById("pacjent-name").value = matches[1];

}

That was all. For me this solution work like a charm.

If someone would like to use it in own application, here is an additional code that attaches above onclick event to every CGridView row, without using jQuery:


document.getElementsByClassName = function(className, objectType)

{

    	objectType = (objectType != "") ? objectType : "*";

    	var retnode = [];

    	var elem = this.getElementsByTagName(objectType);


    	for(var i = 0; i < elem.length; i++)

    	{

            	var classes = elem[i].className;

            	if (classes == className) retnode.push(elem[i]);

    	}


    	return retnode;

};


function bindEventToGridViewRows()

{

    	var oddsArray = document.getElementsByClassName('odd', 'tr');

    	var evenArray = document.getElementsByClassName('even', 'tr');

    	var objectsArray = oddsArray.concat(evenArray);


    	for(e in objectsArray)

    	{

            	anObject = objectsArray[e];


            	if(typeof anObject !== "undefined") anObject.onclick = onGridViewSelectionChange;

    	}

}


window.onload = function(){bindEventToGridViewRows()}

BTW: Since, the main goal was not to use jQuery, then you have to insert above code directly (manually), by adding <script></script> tag to your view. Because registerXXX functions of CClientScritpt are using jQuery’s documentend functions and fails to work, if jQuery is not loaded.