Jump to content

Vitalikssssss

Caspio Rockstar
  • Content Count

    384
  • Joined

  • Last visited

  • Days Won

    37

Reputation Activity

  1. Thanks
    Vitalikssssss reacted to Alison in Add a value from the Dropdown field to the Text field   
    Hi @Vitalikssssss,

    You should add two text fields to the Selected fields on the Submission form and one of them make a Dropdown form element. After that create a Header and Footer element and past the following code into the footer after disabling HTML edotir:

     
    <script> document.addEventListener("DataPageReady", function() { let dropdown = document.getElementById('InsertRecordname'); let textfield = document.getElementById('InsertRecordnumber'); let change = function() { textfield.value = this.options[this.selectedIndex].value; }; if (document.addEventListener !== undefined) { dropdown.addEventListener('change', change, true); } else if (document.attachEvent) { dropdown.attachEvent('onchange', change); } else { dropdown.onchange = change; } }); </script> InsertRecordname and InsertRecordnumber are the ids of the text fields elements  where InsertRecordname is set to the Dropdown form element.

      

  2. Thanks
    Vitalikssssss got a reaction from Ed727 in Auto-submit form only on initial load   
    Hi @Ed727,
    I assume that you have both Datapages deployed on a web-page with an embed method.
    You can use a JS which clicks on Submit button if my assumption is correct.
    Here a a code which you can use on web-page:
    <script> function submit () { document.querySelector("input[id*='Submit']").click(); } setTimeout(submit, 5000); </script> Hope this helps.
    Regards,
    vitalikssssss
  3. Like
    Vitalikssssss got a reaction from lypoextract in How do you port applications to multiple platforms?   
    Hi @lypoextract,
    You can use import/export of application if you would like to transfer it to different account.
    Here is a documentation: https://howto.caspio.com/apps/exporting-an-app/
    Hope this helps.
    Regards,
    vitalikssssss
  4. Thanks
    Vitalikssssss got a reaction from Elderberg in Date Range on Submission Form   
    Hi @Elderberg,
    I can suggest using a simple Dropdown or Listbox for date selection and a lookup table which will be updated via Tasks on daily basis.
    Here is an example of Task which adds yesterdays, current date, and tomorrows date on daily basis.

    You may also import this Task from attached archive.
    Hope this helps.
    Regards,
    vitalikssssss
    CaspioData_2019-Dec-02_1638.zip
  5. Like
    Vitalikssssss got a reaction from irumlailoo in data transfer   
    Hi @Yolanda,
    You can find answer in this blog post:
    https://blog.caspio.com/update-on-caspios-data-transfer-policy/
    Regards,
    vitalikssssss
  6. Like
    Vitalikssssss got a reaction from wimtracking2 in js Multi-select for 3 Listboxes on same Submit datapage   
    Hi @DesiLogi,
    Try using the following script in the Footer of the Datapage:
    <script type="text/javascript"> function f_listbox(v_state) { if ( v_state.indexOf(",") > 0 ) { for (let i=0 ; i < o_state.options.length; i++ ) { if(o_state[i].value == v_state) { o_state.remove(i); break ; } } let o_st = v_state.split(", ") ; for (let j=0 ; j < o_st.length; j++) { for (let i=0 ; i < o_state.options.length; i++ ) { if(o_st[j]== o_state.options[i].value){ o_state.options[i].selected = true ; break ; } } } } } document.addEventListener('DataPageReady', function (event) { let v_state = ["CompanyName", "FirstName", "LastName"]; //Field names goes here let o_state = []; v_state.forEach(function(el) { if (el !== null) { o_state.push(document.getElementById("EditRecord"+el)); } }); o_state.forEach(function(el){ if (el !== null) { el.multiple = true; } }); f_listbox(v_state); }); </script>  
  7. Like
    Vitalikssssss got a reaction from RickManolo in Add text field entry to a text area   
    Hi @RickManolo,
    Well, for me the easiest way to do this is to use a Virtual field to display "Notes" and make an actual field "Notes" as hidden.
    I assume that you use Single Record Update or Details Datapage. 
    If the answer for above is yes, you can use the following JS code to concat existing Note with AddNote input after Update of the record.
    <script type="text/javascript"> document.addEventListener('BeforeFormSubmit', function (event) { let target = document.querySelector('[id*="EditRecordNotes"]'); let n_notes = document.querySelector('input[id*="EditRecordAdd_Note"]').value; let o_notes = document.querySelector('input[name*="cbParamVirtual1"]').value; target.value = o_notes + n_notes; }); </script> Change the name of the fields if necessary, and also make sure you disable HTML editor prior to pasting the code.
    Hope this helps.
    Regards,
    vitalikssssss 
     
     
  8. Like
    Vitalikssssss got a reaction from GWBjr in Record Level Access based on partial field match   
    @GWBjr

    Try this expression:
    'www.' + Substring([@field:Email], ((Charindex('@', [@field:Email]))+1), Len([@field:Email])) Regards,
    vitalikssssss
  9. Thanks
    Vitalikssssss got a reaction from Ed727 in Line breaks in Text(64000) fields not recognized in html block insert   
    Hi @Ed727,
    I am afraid that long text without HTML tags  will be rendered as a single line string.
    Regards,
    vitalikssssss
  10. Thanks
    Vitalikssssss reacted to kpcollier in Make JS Work With Empty Fields   
    Haha, wow. Your code looks SO nice, specially compared to the way I did it. Thank you @Vitalikssssss it works great.
  11. Thanks
    Vitalikssssss got a reaction from kpcollier in Make JS Work With Empty Fields   
    Hi @kpcollier,
    Try this code:
     
    <script type="text/javascript"> document.addEventListener('DataPageReady', function (event) { let v_fields = ["Labor1_Rate", "Labor1_Hours", "Labor2_Rate", "Labor2_Hours", "Labor3_Rate","Labor3_Hours", "Labor4_Rate", "Labor4_Hours", "Labor5_Rate", "Labor5_Hours", "Labor6_Rate", "Labor6_Hours", "Labor7_Rate", "Labor7_Hours", "Labor8_Rate", "Labor8_Hours", "Labor9_Rate", "Labor9_Hours", "Labor10_Rate", "Labor10_Hours", "Labor11_Rate", "Labor11_Hours", "Labor12_Rate", "Labor12_Hours", "Labor13_Rate", "Labor13_Hours", "Labor14_Rate", "Labor14_Hours", "Labor15_Rate", "Labor15_Hours", ]; let t_field = ["Labor1_Total", "Labor2_Total", "Labor3_Total", "Labor4_Total", "Labor5_Total", "Labor6_Total", "Labor7_Total", "Labor8_Total", "Labor9_Total", "Labor10_Total", "Labor11_Total", "Labor12_Total", "Labor13_Total", "Labor14_Total", "Labor15_Total",]; let sub_total = document.getElementById("InsertRecordLabor_SubTotal"); sub_total.value = 0; let v_state = []; let t_state = []; v_fields.forEach(function(el) { if (el !== null) { v_state.push(document.getElementById("InsertRecord"+el)); } }); v_state.forEach(function(el){ if (el !== null) { el.addEventListener("keyup", calculate); } }); t_field.forEach(function(el) { if (el !== null) { t_state.push(document.getElementById("InsertRecord"+el)); } }); function calculate() { let i = 0; t_state.forEach(element => { if (element !== null) { element.value = ((!isNaN(v_state[i].value)) ? v_state[i].value : 0) * ((!isNaN(v_state[i+1].value)) ? v_state[i+1].value : 0); sub_total.value = +sub_total.value + +element.value; console.log(sub_total.value); i+=2; } }); } }); </script>  
    This code should resolve the issue.
    Regards,
    Vitalikssssss
  12. Like
    Vitalikssssss got a reaction from kpcollier in Button To Copy Address - Cascading Elements   
    Hi @kpcollier,
    You can use "start with" type of comparison in query selector like this:
    document.querySelector("input[id^='InsertRecordPrimary_Address']").value; The whole code would look like this:
    <script type="text/javascript"> document.addEventListener('DataPageReady', function (event) { function f_address(){ if(document.getElementById('cbParamVirtual4').checked) { document.querySelector("input[id^='InsertRecordBilling_Address']").value = document.querySelector("input[id^='InsertRecordPrimary_Address']").value; document.querySelector("input[id^='InsertRecordBilling_City']").value = document.querySelector("input[id^='InsertRecordPrimary_City']").value; document.querySelector("input[id^='InsertRecordBilling_State']").value = document.querySelector("input[id^='InsertRecordPrimary_State']").value; document.querySelector("input[id^='InsertRecordBilling_Zip']").value = document.querySelector("input[id^='InsertRecordPrimary_Zip']").value; } else { document.querySelector("input[id^='InsertRecordBilling_Address']").value = ""; document.querySelector("input[id^='InsertRecordBilling_City']").value = ""; document.querySelector("input[id^='InsertRecordBilling_State']").value = ""; document.querySelector("input[id^='InsertRecordBilling_Zip']").value = ""; } } document.getElementById('cbParamVirtual4').onclick= f_address; }); </script>  
    Regards,
    vitalikssssss
  13. Like
    Vitalikssssss got a reaction from deemuss in Set Check box with a formula?   
    Hi @scottd,
    Here is a topic with a solution:
    Hope this helps
    Regards,
    vitalikssssss
  14. Thanks
    Vitalikssssss reacted to NiceDuck in Record authentication field upon delete   
    Hello,

    Thank you for the response Shiro and Vitaliksssss.
    I just want to share what I did to resolve this issue.  Instead of using the Caspio's default delete functions, what I did is I added a erase field which is a yes/no filed on my records and I created a trigger that will delete those records with 'yes' values on these fields.
    since the record is updated instead of deleted, the datapage will be able to capture the authentication fields first before the trigger delete the record. I will simplify my workflow as this
    check the yes/no field assign for deletion --> update the record --> record is updated/inserted on the table --> trigger will check for records with a 'yes' value on its erase field --> delete those records.
    This works on inline edit, bulk edit and details pages. However, if you deleted a record from Caspio Bridge, it will not be recorded on your history log. 
    Hope this helps anyone.
    quack.
  15. Like
    Vitalikssssss got a reaction from Corpcatalog in Line Chart time series   
    Hi @Corpcatalog,
    You can build such Chart in Caspio but you would need to modify your table first.
    You table should look like the following:

    You can build the following Chart once you transform your table:

    You may import attached Datapage to your account in order to see the settings for the Chart Datapage.
    Hope this helps.
    Regards,
    vitalikssssss
     
     
    CaspioData_2019-Sep-10_1309.zip
  16. Thanks
    Vitalikssssss reacted to Alison in Set a placeholder to the Multiselect Dropdown form element   
    I want to share a solution on how to set a  placeholder to the Multiselect Dropdown form element on the search form.
    You should put the following code into the Footer after disabling HTML Editor on the advanced tab:
     
    <script> document.addEventListener('DataPageReady', function () { document.querySelector('[id^="ComboBoxValue"]').setAttribute("placeholder", "Your value for the placeholder"); }); </script>
     
  17. Thanks
    Vitalikssssss reacted to Andrew in XIRR function   
    Hello @Vitalikssssss!
    It is possible to implement such a formula within Tabular report using additional JS.

    Please follow these steps:
    1. You need to create additional APP parameter to use the "moment.js" library.
    Please check this article to get familiar with the APP Parameters in Caspio - https://howto.caspio.com/apps/app-parameters/


    2. Create the Tabular Report and add the Header/Footer. Please insert this code into the Header:
    <div style='display:flex; justify-content:flex-start;padding:30px;'> <input placeholder="Guess Rate, %" id='rate'></input> <button id='click' class='cbResultSetAddButton' style='margin-left:10px;'>Calculate XIRR</button> <div id='result' style='margin-left:10px;'></div> </div> <script src="[@app:URL_1]"></script> <script> "use strict"; document.addEventListener('DataPageReady', function () { document.querySelector('#click').addEventListener('click', function (event) { var formatDate = 'DD/MM/YYYY'; var columnDateNumber = 2; //Change based on your column position on a result set var columnValuesNumber = 3; //Change based on your column position on a result set //Not changeable part var datesSelector = "tr>td:nth-child(".concat(columnDateNumber, ")[class^=\"cbResultSetData\"]"); var valuesSelector = "tr>td:nth-child(".concat(columnValuesNumber, ")[class^=\"cbResultSetData\"]"); var dates = []; var values = []; document.querySelectorAll(datesSelector).forEach(function (item, index) { if (!item.hasAttribute('style')) { return dates.push(item.innerText); } }); document.querySelectorAll(valuesSelector).forEach(function (item, index) { if (!item.hasAttribute('style')) { return values.push(+item.innerText); } }); var guess = +document.querySelector('#rate').value; var some; if (guess != 0) { some = guess/100; } document.querySelector('#result').innerHTML = "Result:<strong>".concat(XIRR(values, dates, some, formatDate)*100, "%</strong>"); }); }); function XIRR(values, dates, guess, local) { // Credits: algorithm inspired by Apache OpenOffice // Calculates the resulting amount var irrResult = function irrResult(values, dates, rate) { var r = rate + 1; var result = values[0]; for (var i = 1; i < values.length; i++) { result += values[i] / Math.pow(r, moment(dates[i], local).diff(moment(dates[0], local), "days") / 365); } return result; }; // Calculates the first derivation var irrResultDeriv = function irrResultDeriv(values, dates, rate) { var r = rate + 1; var result = 0; for (var i = 1; i < values.length; i++) { var frac = moment(dates[i], local).diff(moment(dates[0], local), "days") / 365; result -= frac * values[i] / Math.pow(r, frac + 1); } return result; }; // Check that values contains at least one positive value and one negative value var positive = false; var negative = false; for (var i = 0; i < values.length; i++) { if (values[i] > 0) positive = true; if (values[i] < 0) negative = true; } // Return error if values does not contain at least one positive value and one negative value if (!positive || !negative) return "#NUM!"; // Initialize guess and resultRate var guess = typeof guess === "undefined" ? 0.1 : guess; var resultRate = guess; // Set maximum epsilon for end of iteration var epsMax = 1e-10; // Set maximum number of iterations var iterMax = 50; // Implement Newton's method var newRate, epsRate, resultValue; var iteration = 0; var contLoop = true; do { resultValue = irrResult(values, dates, resultRate); newRate = resultRate - resultValue / irrResultDeriv(values, dates, resultRate); epsRate = Math.abs(newRate - resultRate); resultRate = newRate; contLoop = epsRate > epsMax && Math.abs(resultValue) > epsMax; } while (contLoop && ++iteration < iterMax); if (contLoop) return "#NUM!"; // Return internal rate of return return resultRate; } </script> You should change the selectors of your Date and Value fields, if they are placed in the different position.
    Selectors can be changed here: 
    var columnDateNumber = 2; //Change based on your column position on a result set var columnValuesNumber = 3; //Change based on your column position on a result set Please find the print screen attached.

    Do not forget to Disable the HTML editor.

     
    Also, find the dummy application with this customization attached - XIRR_Function_1_0_2019-Aug-22_1503.zip
    Please let me know if you need any assistance.
  18. Thanks
    Vitalikssssss got a reaction from SonoftheSun in Total Hours Worked / Datediff   
    I have tweaked the formula provided by @MayMusic further since some time I need zero in front of single-digit hour e.g. 7:00.
    So, for the total&aggeration field it looks like this:
    (CASE WHEN LEN(CAST ((SUM(DATEDIFF(SECOND, [@field:Start_time], [@field:End_time]))/3600) AS VARCHAR(6))) < 2 THEN '0'+ CAST ((SUM(DATEDIFF(SECOND, [@field:Start_time], [@field:Hora_fin]))/3600) AS VARCHAR(6)) ELSE CAST ((SUM(DATEDIFF(SECOND, [@field:Start_time], [@field:Hora_fin]))/3600) AS VARCHAR(6)) END) + ':' + (CASE WHEN LEN(CAST ((SUM(DATEDIFF(SECOND, [@field:Start_time], [@field:Hora_fin]))%3600/60) AS VARCHAR(6))) < 2 THEN '0'+ CAST ((SUM(DATEDIFF(SECOND, [@field:Start_time], [@field:Hora_fin]))%3600/60) AS VARCHAR(6)) ELSE CAST ((SUM(DATEDIFF(SECOND, [@field:Start_time], [@field:Hora_fin]))%3600/60) AS VARCHAR(6)) END) Hope it would help someone.
    Regards,
    vitalikssssss
     
  19. Thanks
    Vitalikssssss got a reaction from kpcollier in Button to Submit Name   
    Hi @kpcollier,
    I have seen similar behavior on Caspio Ready Made App called Resource scheduling.
    http://apps.caspio.com/demo9/rs/login.html
    Login in as a member, perform a simple search and you will see a Tabular Report with "Reserve this Item" button which performs similar logic.
    I believe you need the following items in order to create similarly flow within your app:
    1. Single record update form with default elements hidden by CSS.
    2. Embed this DP in the HTML block of the report by using the Iframe deployment method.
    I need to mention that DP performance might decrease if you have a lot of records on Result set (e.g. 250 per page).
    Hope this helps.
    Regards,
    Vitalikssssss
     
  20. Thanks
    Vitalikssssss reacted to MayMusic in Total Hours Worked / Datediff   
    Count the total mins either in the table or as cal field on your report. Here we call it TimeSpan

     

    Datediff(minute,[@field:StartTime], [@field:EndTime])

     

    Then in the aggregation use that to get the total:

     

    CAST ((SUM(TimeSpan)/60) AS VARCHAR(6)) + ':' +CAST ((SUM(TimeSpan)%60) AS VARCHAR(2))

  21. Thanks
    Vitalikssssss reacted to Andrew in Chart Datapage   
    Hello @Vitalikssssss
    You can implement such a chart using the Highchart library and Tabular Report Datapage.
    Steps:
    1. Create the Tabular Report Datapage based on the table you want to use to draw a chart.
    2. Use predefined criteria to find the actual row from the table.
    3. Add all the fields you want to draw to ResultSet.
    5. Add two APP parameters to your Application. Find the files attached. Name the files in the same way as it is on the screenshot below.

    6. Add the following code to Header/Footer of the result set page.
    Header:
    <script src="[@app:JQueryScript/]"></script> <script src="[@app:HighchartsScript/]"></script> <div id="container" style="height: 400px"></div> <style> .cbResultSetTableCellNumberDate, .cbResultSetTotalsDataCellNumberDate { text-align: left !important; } form[action^="https://c1abc032.caspio.com/dp/9a23600092ea09cd1acf435e847b"] { display: none; } </style> You should only change the DeployURL in this snippet of code.
    Use the Deploy URL of the same Datapage you work on after you create it.
    form[action^="Your_Deploy_URL"]
    Footer:
    <script type="text/javascript"> document.addEventListener('DataPageReady', function () { /* ________ Check if Highcharts library is loaded ________ */ var myVar = setInterval(myTimer, 200); function myTimer() { console.log(typeof Highcharts); if(typeof Highcharts !== "undefined") { myStopFunction(myVar); drawChart(); } } function myStopFunction(val) { clearInterval(val); } /* ________ Draw Chart function ________ */ function drawChart() { let labelsRow = document.querySelectorAll('.cbResultSetLabelLink'); let labels = []; let valuesRow = document.querySelectorAll('.cbResultSetTableCellNumberDate'); let values = []; let resultSet = []; for(let i = 0; i < labelsRow.length; i++) { labels .push(labelsRow[i].innerText); values.push(+valuesRow[i].innerText); } for(let i = 0; i < values.length; i++) { if(values[i] === 0) { continue; } else { resultSet.push({ name: labels[i], data: [ values[i] ] }); } } var chart = Highcharts.chart('container', { chart: { type: 'column' }, title: { text: 'Comparosin chart' }, xAxis: { labels: { enabled: false } }, yAxis: { min: 0, title: { text: 'Value' } }, credits: { enabled: false }, series: resultSet }); } }); </script>  
    highcharts.js jquery.js
  22. Thanks
    Vitalikssssss reacted to DefinitelyNot31337 in Login after User Registration   
    Hello @TroubleShooter,
     
    Yes, you can. Currently, it is only possible with JavaScript.
     
    The idea is to place the Registration Form and Standalone Login Page side-by-side (or at least, in the same page).
    You may hide the Login Form ( using <div style="display: none;"></div> on the Header/Footer of the DataPage || More about here...), on your Registration Page but I rather keep them visible so the users can opt to just log-in if they already have an account; or register, if they don't.
     
    After registration, JavaScript will fill-out the login form, and submits it programatically, therefore logging-in the newly registered user.
     
    The only requirements to this implementation are:
    1.) Login DataPage and Registration Form DataPage are deployed on the same page.
    2.) Both DataPages are AJAX-Enabled!
    3.) Headers/Footers should have the HTML Editor disabled from the Advanced tab.
     
    Without futher ado, let's do this.
    1.) Open DataPage Configuration for your Registration Page:
    2.) Go to 'Configure Fields Section'
    2.1.) Add a Header and Footer (Disable HTML Editor from the advanced tab)
    2.2.) Paste the code snippet in the Footer and modify the following information.
    <script> document.addEventListener('BeforeFormSubmit', function() { var registrationDP = "[@cbAppKey]"; var loginDP = "378fd3458dfsjhefjhqerwfdsyui3274239"; //Replace with the AppKey of your Standalone Login Scren var username_field = "username"; //replace with the name of your username field (CASE SENSITIVE!) var password_field = "password"; //replace with the name of your password field (CASE SENSITIVE!) //No modifications necessary from this point onward. document.querySelector(`[action*="${loginDP}"] [id*=xip_username]`).value = document.querySelector(`[action*="${registrationDP}"] [id*=InsertRecord${username_field}]`).value document.querySelector(`[action*="${loginDP}"] [id*=xip_password]`).value = document.querySelector(`[action*="${registrationDP}"] [id*=InsertRecord${password_field}]`).value }) </script>  
    5.) Go to 'Destination and Messaging'
    5.5) Set Destination after record submit to: Display a message; Disable the HMTL Editor!
    5.6) Paste the code snippet below; then modify.
    Registered Successfully. <script> var loginDP = "378fd3458dfsjhefjhqerwfdsyui3274239"; document.querySelector(`[action*="${loginDP}"]`).submit(); </script>  
     
    After saving, you should be good to go.
    Working example: https://stage.caspio.com/support/forums/DefinitelyNot31337/register-login/index.html
    Application Export Package: CaspioData_2019-Apr-02_0219.zip
     
    Good luck and happy hacking!
     
    Regards
    DN31337!
  23. Like
    Vitalikssssss got a reaction from kpcollier in Checkbox In Search To Include Additional Results   
    Hi @kpcollier,
    I believe you can switch the comparison operator for "Tech_Status" to "Not Equal".

    Hope this helps.
    Regards,
    vitalikssssss
  24. Like
    Vitalikssssss got a reaction from kpcollier in 'Freeze' Field When Given A Value   
    Hi @kpcollier,
    You can check the status before the update to make sure it is not equal to the list of previous statuses. 
    Here is an example for one of the Trigger blocks:

    Hope this helps.
    Regards,
    vitalikssssss
     
  25. Thanks
    Vitalikssssss got a reaction from JEllington in Create multiple records in “child” table conditionally   
    Hi @Alison,
    You can design Trigger in such a way which allow you to achieve the desired functionality.
    You need to make sure that:
    1. Your parent/child table has one-to-many relationship;
    2. You create a special table which will be used as insert template.
    3. Please note that you would need to list the same number of records in insert template as the number of days which you could have in the date range.
    4. You need to create a Trigger.
    You may import my example into your account and check the structure there. 
    Regards,
    vitalikssssss
    Submit_multiple_records_date_range_1_0_2018-Sep-28_1423.zip
×
×
  • Create New...