I have a web page which lists all database records from a certain server.
Along side each row are a few buttons which allow you to rename or delete records.
INPUT( _value='Rename', _type="button", _class='appbutton', _onclick='renameApplication({0},"{1}")'.format(app.id,app.name))
Which generates something like:
<input class="appbutton" type="button" value="Rename" onclick="renameApplication(3,"My Application")"></input>
(The backend templating engine is web2py, but that's not really important.)
I am generating these buttons dynamically. Currently I pass the data each button needs through onClick.
According to jQuery.click() vs onClick I shouldn't be doing this anymore. But if that is the case, how should I be passing data so that each button click can use dynamic data written server side (the application ID and name in this instance.)
I can't do dom traversal through the record to grab the data because the row structure might change.
I can't use custom attributes because I need to support less than HTML 5, and I'm not going to modify the doctype! (Can I add custom attribute to HTML tag?)
The only thing I can think of is to put data in the id attribute then parse it, but that seems very hackish.
Is there a better way?
You may try to use an jQuery on to hook the event on every button. You may put the server Id in an data attribute which is understood by jQuery, without major issues:
<input class="appbutton" type="button" value="Rename" data-id="3"></input>
Then the js:
$('#container').on('click', '.appbutton', function () {
var serverId = $(this).data('Id'); //this binds to html input
renameApplication(serverId);
});
Related
I have an IG with a link column where the target is set to URL and I use it to call javascript.
What I want to accomplish is whenever a link column is clicked, grab a value of another - hidden column and set a page item to that value:
javascript:$s('P1_ITEM',#COLUMN2#);alert($v('P1_ITEM'));
but what happens, if I reference COLUMN2 value using just #COLUMN#, I get a javascript error and if I wrap it in single quotes, the value of P1_ITEM literally gets set to #COLUMN2#.
The first thing I would recommend is that you move to a Dynamic Action rather than trying to put all the code in the link. Also, I think buttons are a better than links (and they can be styled to look like links).
Start by going to https://apex.oracle.com/ut. Navigate to Reference > Button Builder and build the button you want. Then copy the value from the Entire Markup field.
Change the Type of the Link column to HTML Expression and paste the HTML from the Button Builder in the HTML Expression field. I styled my button to look like a link (as you had it), added a custom class to the class property named my-button, and added a data-attribute for the primary key value (my table was EMP, so the PK was EMPNO). It looked like this in the end:
<button type="button" class="t-Button t-Button--link my-custom-button" data-id="&EMPNO.">Click me!</button>
Give the Interactive Grid a Static ID value of my-ig.
With that done, create a new Dynamic Action. Set Name to .my-button clicked, Event to Click, Selection Type to jQuery Selector, and jQuery Selector to .my-button. Finally, set Event Scope to Dynamic, which will use event delegation to keep the event binding working if the report refreshes (see this for details).
In the action, set Action to Execute JavaScript Code. Enter the following code in the Code field:
var id = $(this.triggeringElement).data('id');
var model = apex.region('my-ig').call('getViews').grid.model;
var record = model.getRecord(id);
var job = model.getValue(record, 'JOB');
$s('P1_ITEM', job);
alert($v('P1_ITEM'));
This code starts by obtaining the value of the primary key from the data- attribute on the button using jQuery's data method. Next, a reference to the model that is used by the IG is obtained. Then the model's getRecord method is invoked and the primary key value is passed in. Finally, the model's getValue method is used to get the 'JOB' value from the record. I went after the JOB column since I was using the EMP table, but you would go after whatever column you need.
You can learn more about the model methods here:
https://apex.oracle.com/js > Interfaces > Model.
I have web page with two textboxes on it. Upon clicking on the first, I have a bootstrap modal that displays with a searchable treeview. You click an item in the treeview, the modal closes, and the selection appears in the textbox. Works perfectly!
Now I have decided that for the other textbox I want to do the same thing. The only difference is the modal has a different title, and the source data for the modal treeview comes from a different endpoint. All the other javascript to support searching and highlighting within a treeview, opening and closing a modal, etc, is the same.
To get it to work, I duplicated all html for the modals and the js code and just changed the ID's to avoid clashes between the two. I cannot live with myself for doing this!
So in the end, I have some js and html that work together as a component that I want to reuse on a page among several textboxes or whatever type of widget I may create. How can I design my app so I can share this code and not duplicate it all over the page?
I think webcomponents is the way to go. You could create a component that receives the id and other needed data as parameters and then create instances of it...
There is a lot to unpack in this question. High level, to achieve what you're asking with JS…
You could:
Build a method that accepts an event object (or jQuery event object) as its argument; and handles extracting extracting data from the attributes of that element, setting the title, AJAXing the treeview, and returning the selection/setting the text box value
embed the unique data in data-attributes on each text box
set the click event listener to pass the event.target element, with its unique data- attributes to the method
Markup:
<input type="text" id="foo" data-endpoint="/path/to/endpoint_1" data-title="Modal Foo" value="" />
JS
function on_click_modal_spawning_textbox( event ) {
// get the salient data from the `data-` attributes on the `event.target`
// do modal stuff, programmatically replace the modal title, AJAX treeview, et cetera…
}
// assuming you're using jQuery, otherwise this would be a vanilla `.addEventListener()`
$( document ).on( 'click', 'input[ data-endpoint ]', on_click_modal_spawning_textbox );
I am creating an applicaiton where hundreds of controls are created dynamically in Jquery as below.
var $link='<a id="bucket'+data[0].ID+'" class="Initial" href="#"></i></a>';
$($btnGroupdiv).append($link);
While adding controls I am assigning unique ID to each control.
And this is how I am identifying each control while accessing it.
$(".Initial").click(function(){
var $pid=this.id.replace("bucket","");
But here's the issue.
These IDs can be changed at browser with "Inspect Element" option.
ServerSide Situation
IDs which I have assigned to controls, are the primary keys of row in table called employee.
So changing ID at browser can temper data in a different row than intended.
How do I validate these controls at serverside, if ID is changed or not or How do I restore original ID of an element at server side??
I hope my question is clear enough.
Any help is apppreciated.
For everyone who thinks this is not possible.. I would ask - How does facebook or even StckOverflow do it??
You need to define it differently for it to work with dynamic elements:
$(document).on("click", ".Initial", function(){
var $pid=this.id.replace("bucket","");
...
});
It is impossible to detect if anybody has changed the ID via the browser.
You can't (software rule n°1: never trust user input).
What you can validate serverside is:
Make sure the id exists
Make sure the user has the rights to do the action on the data related to the id.
And this is it ! If a user is doing an action he is allowed to, on valid data, why should he be stopped to do so ?
I have a user control that has a server side dropdownlist (it needs to be server side). The user control appears multiple times on a webpage so I need to make the javascript method unique. I want to validate the ddl selection client side so I don't need a postback. I found the following example:
you need to use this.id
function load_v<%= this.ID %>() { alert('anything'); }
so that even if you need two or more same controls in the same page they will have different ids. Hope this Helps! cheers :)
This works with making the javascript method unique like follows:
function DDLSelectionChanged<%=this.ID%>() { code here }
But how would I call the method using the onchange event within the asp:dropdownlist tag, e.g.
<asp:dropdownlist id="list1".... onchange="JavaScript:DDLSelectionChanged()"...>
I tried putting onchange="JavaScript:DDLSelectionChanged<%=this.ID%>()" but that doesn't work.
Please remember this is .NET 1.1.
Please do like this in your server side
DDCONTROL.attributes.add("onchange","javascript:fname(this.id);");
you need to create function named "fname" into javascript with one parameter, that parameter will give you an ID# of particular dropdown control.
I am currently using a javascript code to make an entire row in my table clickable. Once the row is clicked a function is ran, I am wondering what I can use to redirect to a PHP page and preferably send a post variable along with it. My guess is AJAX but I am not sure how or if it would work.
Javascript
function DoNav(theUrl) {
document.location.href = theUrl;
};
HTML
<tr onclick="DoNav('myphpscript.php');">
I have access to jQuery so that is also an option. Any help is appreciated, Thanks!
If you need to POST the data (not use GET), One easy option is to create a form element on the fly, attach input elements with the values you need and submit it. You can do that like so if you use jQuery:
$(function() {
$('tr').click(function() {
var mail_id = /* get the mail id of this row... not sure where since I dont' have the HTML */
$('body').append('<form method="post" action="myphpscript.php" id="donavform" style="display:none;"></form>');
$('#donavform').append('<input type="hidden" name="mid" value="'+mail_id+'" />');
$('#donavform').submit();
});
});
Hope that makes sense. If not, let me know! It's, okay...
Explanation:
The very first line is a jQuery shortcut way of saying "when the document is done loading..." So, when the page is done loading, I'm going to attach an event listener to all elements in the document. When one of those elements is clicked, we can then extract the mail id (and whatever else you need) that is in relation to that particular table row. So, if you had HTML like this:
<!-- 8435 is the mail ID in this example. -->
<tr id="row3">8435</tr>
Then we could extract the mail_id variable like so:
var mail_id = $(this).html();
Now, we are going to attach a hidden form element to the end of the body of the HTML (it doesn't really matter where we put it since it is hidden... so, the end is fine). In this form element, we set the method to POST and the action to whatever php file you need to POST to. I also set an ID so it's easily referred to in the next step.
I'm now going to select the newly-created form element using its ID and I'm going to append a new hidden input element to it with the appropriate name value pair.
$('#donavform').append('<input type="hidden" name="mid" value="'+mail_id+'" />');
Finally, I'm going to use the jQuery JavaScript submit method to trigger the submit event on the form. This is basically equivalent to pressing the 'submit' button on a normal form.
Try it out, it should work flawlessly.
If you're going to a new page, just submit the form as usual. Put the data in form fields (hidden if required). No need to Ajax, jQuery or any other magic unless you want to stay on the same page and post in the background.
If the amount of data is not ridiculously large, use a query string...
<tr onclick="DoNav('myphpscript.php?key=value');">
Or if you need a natural HTTP post, you can programmatically submit the form with Javascript...
onclick="document.forms[0].submit();"
You could send the data along in a cookie. There's a nice jQuery plugin that helps with setting cookies in the jQuery namespace.
http://plugins.jquery.com/project/cookie