I have searched this forum and many others around the web, but apparently I'm trying to do something a little different than anyone else.
I have a web page (aspx) that accepts user-entered criteria and selects products based on that user criteria. Using JavaScript, I make an Ajax call to my server side code which interacts with an old, but widely-used company DLL. I receive the matching products and all their details back from the function.
I'm using result.substr and result.split (since the data is coming back as a comma delimited string) to obtain the relevant pieces of data and build the section of my table. The user can then click on an icon to the left of each table row to view further details about the selected model.
That displays another element which extracts further data from the returned comma delimited string. All of that is working beautifully. The problem I'm having is that on the that displays the further details, there also needs to be a spline chart showing some graphical data. I am returning the data required to plot the spline graphs, but am having trouble finding a way to get the data to the graph.
I would prefer to find a way to set it up just as I have the data table, where I'm using JavaScript to append to the appropriate section of the HTML.
Here is a sample of what I'm doing with the table:
table += '<td title="Details"><div class="details"><img src="/resources/ic_menu_search.png" alt="" height="20" width="20" style="cursor: pointer;" id="' + i + '" ></img></div></td>';
table += '<td><div class="model">' + TableResults[((i - 1) * 461) + 1] + '</div></td>'; //model
Then I do this to put the data in the section.
$('#datatable').append(table);
I would like to do something similar with the asp:chart control and maybe try something like:
$('#Graph > points').append(TableResults[((recNo - 1) * 461) + (111 + i)]);
But, I don't think that is valid. I also tried to use <% %> script tags to set the properties, but it obviously won't run that when the JavaScript/jquery runs. It executes before anything else.
I would also consider doing a server-side (vb.net) function to create the plot points, but I haven't found a good example yet that matches what I'm trying to do.
Any help is greatly appreciated!
I use highcharts to make all my charts and build up the format dynamically in ajax calls. So if a user changes a dropdown list, I pass that new selected index to the ajax page, then it rebuilds the entire table and passes back the html. I don't use the append feature and don't need to contact the code behind using <% %>. I simply use the .html() jQuery function to place all the html in a div.
Related
I have HTML web page and i am using Table layout to show all the values from database. Now once user select any row using radio button, i want all the values in that row passed on to Iseries/AS400 program.
Webpage image
How to get all the values from row.. please advise ...
is there any method of passing those values. In Iseries i am using CGI libraries. In html i am using POST method which i calling backend program.
if each record is a html table row and each cell html table cell, all embedded inside a true html table element, then do the following javascript at the very bottom of the html document just above the end tag:
<table id="tableRecords">
<tr>
<td>...cell 1</td>
<td>...cell 2</td>
<td>...cell 3</td>
<td>...etc...</td>
</tr>
</table>
<script type="text/javascript">
// assume each radio has a unique id and all radios have the same "class=myRadio"
let table = document.getElementById("tableRecords");
let radioButtons = table.querySelectorAll("myRadio");
let values = []; // we'll capture each cell's values into this empty array
for(let i=0; i < radioButtons.length; i++){
radioButtons[i].addEventListener("click", function() {
let tableRow = this.parentNode;// each radioButton's parent Row
function(tableRow){
[].slice.call(tableRow.children).forEach(child => {// child is each <td> which we get values from
values.push(child.textContent);
});
};
})
};
</script>
Yes, that's a very basic requirement.
You don't mention which CGI library you are using, but of of them should have documentation, examples and possibly tutorials that will show you what needs to be done to accomplish your request.
Edit
Check out the http://cgidev2.easy400.net/ site...
But basically, you'll probably want to wrap your other RPG program with a CGI RPG program that can convert the query parms or post data into the parameter's needed by the program you want called. Then it's simply a matter of redirecting the user to the new CGI program.
However
Judging from your screen shot, you've got basically a WRKSPLF screen with View, Download and Delete button's I assume you are trying to get to function...
Delete is easy, as there's no real UI for it..
View & Download are a whole other story... you can't simply "call another program" and expect the user to be able to view or download the spool data. Well you could, assuming you've built a program that will convert a spool file to HTML/TXT/PDF that a browser can display or download.
Such a program would normally store the converted stream file in the IFS; in which case it's a simple matter of calling the DspStmf() or DnlStmf() subprocedure included in CGIDEV2.
Honestly CGIDEV2 was a good option 15 years ago, but you'll have to handle a lot yourself. There's much better options now-a-days.
I suggest taking a look at the Tools and Solutions for Modernizing Your IBM i Applications Redpaper by IBM. It's a good start for some of the possibilities. However, even though it was updated in 2017, it doesn't go into some of the opensource options such as PHP, Python or node.js all of which are supported on today's IBM i and offer lot's of possibilities for new development.
Since stackoverflow isn't the place for asking for tool recommendations, consider joining the Midrange.com WEB400 mailing list.
I am building a user search filter where we can specify a number of criteria's, one per each row of a HTML table.
I am building a dynamic table using jquery on the client side, the table starts off with one row(default) on page load with a "+" image on the last <td> which when clicked I am appending a new row to the table, and this can repeat for any number of rows as shown below. Once the search button is clicked, I am bringing back results based on criteria selected. But I also need to preserve the current criteria table after postback(due to search button).
Any ideas on how to do this? I have tried putting all of the HTML for the table in a hiddenfield but I get a RequestValidationError for obvious security reasons. I have the individual selected values in each row saved in hidden variables which I am using in code behind to build the search and bring the results, do I need to rebuild the table on the client side using the values I have? Is that the only option? I also tried converting the HTML for the table into text and putting it in hidden variable, but I am not able to convert it back into HTML after the postback, it is rendering as text inside the table, below is the code for it, any help/input is appreciated.
HTML:
<input type="hidden" runat="server" value="0" id="hdnCriteriaTable" />
jQuery:
on button click, before postback(client side):
jQuery("[id*=hdnCriteriaTable]").val(jQuery("#dynamicCriteriaTable tbody").html().replace(/</g, "<").replace(/>/g, ">"));
on page load after postback(client side):
if (jQuery("[id*=hdnispostback]").val() == "1")
{
//commented out lines below are different ways I tried to make it work.
//the one with hardcoded td's is the one that renders perfectly as HTML inside the table
jQuery("#dynamicCriteriaTable>tbody").empty();
var criteriaTableHTML = jQuery("[id*=hdnCriteriaTable]").val().replace("<", /</g).replace(">", />/g).replace(""", "\"");
jQuery.parseHTML(criteriaTableHTML);
//jQuery("#dynamicCriteriaTable>tbody").append(jQuery("[id*=hdnCriteriaTable]").val().replace("<", /</g).replace(">", />/g).replace(""", "\"").toHtml());
//jQuery("#dynamicCriteriaTable>tbody").append("<tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td></tr>")
jQuery("#dynamicCriteriaTable>tbody").append(criteriaTableHTML);
//alert(jQuery("#dynamicCriteriaTable").html());
//jQuery("#dynamicCriteriaTable").toHtml();
}
This is how HTML is being rendered inside the table:
If I were you, I would rebuild the table from the values; it's clean, and you can always write a function that automates the build.
However, if you want to pass it in toto as HTML, you'll need to escape your tags somehow. I would start by replacing < and > with < and >, respectively, and if that still give you a requestValidationError, use another pair of delimiters.
Having troubles getting values from dynamically added dropdown in thymeleaf.
This is my first
<select th:field="${offer.offerItemList[__${iterationStatus.index}__].mapa}" class="form-control input-sm ofa">
<option value="0" >---Choose option---</option>
<option th:each="attribute : ${offer.offerProductAttribute}" th:value="${attribute.id}" th:text="${attribute.name}"></option>
</select>
Based on selecton from this dropdown i am generating another dropdown with code similar to this :
var options = '<select th:field="offer.list" class="form-control input-sm"> <option th:value="0">--Choose--</option>';
$.each(value.offerProductAttributeValuesList, function (index, value) {
options += '<option th:value="' + value.id + '">' + value.value+ '</option>';
});
options+= '</select>';
of.closest('tr').find('td:last').html(options);
Dom elements generate fine. Everything is ok but values are never submitted with the rest of input fields.
I have done this many times but with previously rendered
<select>
dropdown on the server side, and i would just appendTo() options, but in this case i cannot do that since i potentially have more than 20 dropdowns, based on clients selection from previous dropdown.
I hope i am being clear enough about my issue.
I am gonna answer my own question, since it took me quite some time to get around this problem, and my solution will probably help someone in the future.
The problem was : i had list of objects, and each one of those objects had another list of objects.
The problem is much easier to solve if you just render entire view from the backend (i was using thymeleaf). That way you can use thymeleaf expressions to map everything correctly
Like this :
First you gonna need for each to iterate over top level list
<tr th:each="item,iterationStatus : ${offer.offerItemList}">
You need to use iterationStatus to iterate over nested List, like this :
<select th:field="${offer.offerItemList[__${iterationStatus.index}__].mapa}">
This little piece of code __${iterationStatus.index}__ will basically use iteration index and you will end up with number for each iteration and rendered view will look like this offer.offerItemList[0].mapa, and 1 and 2 and so on.
this way values will be mapped correctly, BUT, if you want to add fields dynamically things get a bit more complicated.
There is jquery issue. Since jquery pretty much binds selectors when page is rendering, even if you write add another element, say <div class="temp">
and write perfectly good jquery function something like this $('.temp').on('click',function(){ console.log("clicked")});
nothing will happen since jquery didnt bind your newly created element to any select/event listener. The solution is to use (document).
$(document).on("click",".temp",function(){console.log('clicked');})
ok we have fixed front end issue, now newly created items work, but how do i tell spring to bind them to each object within list, which is part of another list? well you will have to use iteration index again :
When rendering the view you will need to save iteration index value in each element(using hidden fields)
Get value for each input field to jquery var like this : var iteration = $(this).closest('tbody').find('td:first-child').find('input').attr('value'); ofc this is path to where i have placed hidden input field, you will have to tell jquery where to look according to your structure.
You will simulate array and index numbers like this
var options = '<select name="offerItemList['+iteration+'].mapaValues">';
And the very last thing you need to be careful about is this : Say you have Object which you would normally send from controller like this model.addAttribute("offer",offer); object Offer has attribute, list of Products, so you would access that list with simple offer.productsList, but each product has list of AttributeValues. So final setup looks like this
offer.products[0].attributes[0].name products is an arrayList of objects of class Product, attributes is an arrayList of objects of class AttributeValues and name is a String. In order to let spring create object of class AttributeValues with information spring is receiving from dynamically(and non-dinamically) created forms from the frond-end, you will need to teach him how. If your new form with has input type="text" you are sending back String, so you will need to create a Custom constructor for
your class AttributeValues which will receive a String and which will tell Spring how to "construct" instance of that class with String.
finally create two constructors, one default and one with String as a value :
public AttributeValues(){}; and another for String public AttributeValues(String n){this.name = n;};
The problem you're most likely seeing here is that you're generating thymeleaf markup on the client-side.
Thymeleaf is a server-side templating language, so the browser (and hence the Javascript) will only ever see plain HTML coming back.
Here's a few approaches to consider:
submit the form each time to get new data in, which means no javascript is required
Output every possible dropdown into your HTML, and show/hide them as needed when the user selects options. Some fairly simple Javascript required, but as you mention - the page size may be pretty big
Add a JSON endpoint to your Spring webapp (see the spring #ResponseBody annotation) that will return just the data you need, then pull that JSON data in when the user selects a dropdown using something like jQuery.get()
In my code I have a Struts2 select tag(<s:select>). It reads something like this :
<s:select id="s" list="list" listKey="id" listValue="displayValue">
On some selection made by the user, I want to change the value of list attibute to point to some other list.(possibly using javascript/jquery)
What have you tried ? *
You have at least two ways to do this:
1) Perform an AJAX operation to get the new data (in JSON for example, like a List of 'id' and 'description');
then alter the HTML with Javascript, removing the old Options from the Select,
building and adding the new Options to the Select,
and eventually changing some Select attributes;
2) Perform an AJAX operation to get a completely new Select, elaborated server side, returned as a HTML snippet (a JSP with only one <s:select> inside);
then replace it to the original one on the page, for example using its container (like a div) as target of the AJAX operation.
* #AshishGupta suggested me to remove the "What have you tried ?" part to keep the tone positive. Please read the article, it is a must to understand why this should be always the first (positive and legit) question to askers who doesn't post code (for their own good in first place).
Hope that helps, as the rest of my answer.
Details:
I'm basically trying to implement the functionality of the example here (http://demos.telerik.com/aspnet-ajax/grid/examples/dataediting/editondblclick/defaultvb.aspx) on my own site, but instead of using a data source control located in the page markup (like in the example: SessionDataSource), I'm using a dataset that I get from some server code-behind. I am able to successfully get my double-clicked row into edit mode with my dropdowns successfully populated, however when clicking onto another row to update the one in edit mode, no-dice.
I've discovered that apparently the client-side JavaScript function updateItem() does not initiate an AJAX callback like I originally thought, so I've been trying to work my way around that. Currently I'm using my RadAjaxManager to perform an AJAX callback with the row index number like so:
function RowClick(sender,eventArgs)
{
if(editedRow && hasChanges)
{
hasChanges = false;
$find("<%= RAM.ClientID %>").ajaxRequest(editedRow);
}
}
This gets me to my server code. Awesome. But,
Problem: I must be accessing something wrong, because the GridDataItem cell text that I'm trying to obtain for the edited row all has the value " ".
Dim gdi As GridDataItem = FieldOpsScheduler.Items(rowIndex)
Dim d As DateTime = DateTime.Parse(gdi.Item("EndDate").Text) //<--FAIL
I've been scouring the Internet for hours now trying to find how I can pull off what I'm trying to do, but to no avail.
Additional Info: I'm using GridDropDownListColumnEditors on the front-side to do the editing for my table, declared like so:
<telerik:GridDropDownListColumnEditor ID="ddlce_SunAct" runat="server" DropDownStyle-Width="60px"></telerik:GridDropDownListColumnEditor>
So does anybody have any ideas on what I have to do to access the values that have been changed in my RadGrid?? Is the problem that I somehow need to rebind my RadGrid when clicking on a new row? If so how do I do that? Any solutions or ideas would be greatly appreciated. (Also although I'm doing this in VB.NET, feel free to write responses in C# if you wish as I understand that too. :-) ) Thank you in advance.
With manual binding updateItem() should still raised the UpdateCommand server event of the grid, but you will have to update the grid source by hand. Modify the local version of the online demo where you Telerik AJAX controls installation is and go from there.
Dick
http://www.telerik.com/help/aspnet-ajax/grdaccessingcellsandrows.html
If anyone else has the same problem as I did, go to the above link and scroll down to the section titled "Accessing the value of cells in edit mode".