NetTalk Central

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - bshields

Pages: 1 2 [3] 4 5 ... 26
31
Web Server - Ask For Help / Re: Browse View Without a Table
« on: August 31, 2020, 05:08:18 AM »
This might fast track you (or not!) but maybe it will help.


<section id="configuration">
  <div class="row">
    <div class="col-12">
      <div class="card">
        <div class="card-header">
          <h4 class="card-title">Listing & Sales Performance</h4>
        </div>
        <div class="card-content">
          <div class="table-responsive">
            <table class="table table-striped staff-table">
              <thead>
                <tr>
                  <th>Name</th>
                  <th class="dt-right">Listings</th>
                  <th class="dt-right">Sales</th>
                  <th class="dt-right">%</th>
                  <th class="dt-right">Days on Market</th>
                  <th class="dt-right">Withdrawn</th>
                  <th class="dt-right">%</th>
                </tr>
              </thead>
            </table>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>


Thats my HTML

<script src="/app-assets/vendors/js/tables/datatable/datatables.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
  $('.staff-table').DataTable( {
    "order": [[ 1, "desc" ]],
    "info":     false,
    "bLengthChange": false,
    "bFilter": false,
    "iDisplayLength": 6,
    "columnDefs": [{
        targets: -1,
        className: 'dt-right'
    }],
   "columns": [null,{"width": "100px"},{"width": "100px"},{"width": "80px"},{"width": "100px"},{"width": "100px"},{"width": "80px"}],
    "ajax": '/GenTable?c=listing'
  });
});


Thats the Scripts on the bottom of the same page.

/GenTable?c=listing

That my NetTalk function that generates the JSON.

st.SetValue('')
Access:MyFile.Open()
MyFile{PROP:SQL} = 'MyQuery'
LOOP
  NEXT(MyFile)
  IF ERRORCODE() ~= 0 THEN BREAK.
  st.Append('["'&CLIP(Field1)&'","'&CLIP(Field2)&'","'&CLIP(Field3)&'","'&LEFT(FORMAT(Field4,@n$20))&'","'&LEFT(FORMAT(Field5,@n3))&'%"]',1,',')
.
st.Prepend('{{ "data":[')
st.Append(']}')


Thats a snippet of my NetWebPage that creates the JSON.

32
Web Server - Ask For Help / Re: Browse View Without a Table
« on: August 31, 2020, 04:56:56 AM »
Hope they help. They suit me when i'm doing light weight pretty stuff. You do get pagination, sorting on columns and some other stuff.

33
Web Server - Ask For Help / Re: Browse View Without a Table
« on: August 31, 2020, 03:45:08 AM »
Quote
Your alternative then is either hand-coding a table of some kind, or waiting for NetTalk 12 (which has "Json List support")

:)

34
Web Server - Ask For Help / Re: Browse View Without a Table
« on: August 29, 2020, 03:06:35 AM »
Ok, you made this weird by not being able to change the dictionary.

Try https://datatables.net/ Its actually pretty easy and you supply the table contents via json.

I've included a pic of me using it (table at bottom of the page)

35
Web Server - Ask For Help / Re: Browse View Without a Table
« on: August 27, 2020, 06:56:01 PM »
Hi,

I use the IMDD if I need to work on some data that doesn't have a table in the database schema.

I've also hand coded my own browse in html, but if you want some or all of NTs (generous) Browse functionality, i'd suggest IMDD, its handy. I even some some generic IMDD structures for general purpose stuff.

Regards
Bill

36
Web Server - Ask For Help / Re: How to make a page not to be cached
« on: August 25, 2020, 04:15:54 AM »
Call it with an unused parameter that holds a random value.

eg:

https://mypage.com?x=8328342747

This works if people don't see your URL, it can be a bit weird if they do).


You can also set the Cache-Control header to a max-age=0. If its your page and you want to stop caching of a page that you cannot control the URL.


Probably a bunch of other ways.

37
Web Server - Ask For Help / Re: How to refresh a browse cell using Ajax
« on: August 16, 2020, 03:59:56 PM »
Hi,

You can refresh only a cell. Each uniquely named div can be refreshed independently.

The code that generates the contents of the cell is DO value::YourFieldName.

You just have to watch how NT does it and do the same.

I've attached a screen cap of the place where NT does it.

Regards
Bill

38
Web Server - Ask For Help / Re: How to refresh a browse cell using Ajax
« on: August 15, 2020, 04:55:54 PM »
Hi,

I cannot see your picture. But i know what you are trying to do.

The best way to generate the contents of a cell in a browse is to use the original browse to do it. Then you don't need to know the div id as the browser knows it.

DO value::YourFieldName

Will do it. I expect you'll need to pass an event to the browse to get it to refresh the value for you.

I'd suggest creating a simple browse and utilise the existing fresh cell option to check what events are passed. Once you see that, you can do the same thing.

Regards
Bill

40
Web Server - Ask For Help / Reorder
« on: August 08, 2020, 09:53:26 PM »
Hi All,

Just thought I share something i have to do from time to time.

Often we have a browse that the customer is allowed to order. In the past (because I'm lazy) I often just give them, up and down arrow buttons and let them slide things around for themselves. I know its crap, my customers know its crap, its all crap.

I've done drag and drop before, so i decided it was time to do it properly... Well not really, a respected customer asked me to do it better.

In the attached screen cap. You can see both methods. On the right you can see the up and down arrows. On the left you can see a hamburger menu (also often used as a gripper).

You can drag the gripper and drop the row into the correct place.

It requires a couple of steps:

1. Create the gripper
2. Add some JS to do the browser side bit
3. Add some Clarion to do the server side bit
4. Write some clarion to reorder your table, given what they dragged where.

1. The Gripper

My gripper is just a column in my table and i create the html for it. I put this in "value:: Start" embed. Usual stuff. Make sure you tick allow XHTML in the column.

Drag# += 1
DragHandle = '<div id="PresentItemDrag_'&PIt:SysID&'" draggable="true" ondragstart="drag(event,'&Drag#&')" ondrop="drop(event,'&Drag#&')" ondragover="allowDrop(event)"> <i class="fas fa-bars"></i> </div>'


2. Some Client Side JS

I added mine into the HTML section before form

<script>
function drop(e,idx) {
  e.preventDefault();
  var data=e.dataTransfer.getData("Text");
  sv('','presentitemtable_presenttablepanel','','_refresh_=current','move='+data+','+idx+','+'<!-- Net:s:PRE:SysID -->','_parentproc_=presenttablepanel');
}

function drag(e,idx) {
  e.dataTransfer.setData("Text",idx);
}

function allowDrop(e) {
  e.preventDefault();
}

function handleDragEnter(e) {
  this.className = 'over';
  return false;
}

function handleDragLeave(e) {
  this.className = '';
  return false;
}
</script>


For your reference my table is PresentItemTable and its contained within a memory form PresentTablePanel. You'll have your own.

I am ordering a child file (a bit like the old invoice and line items example ie 1:MANY). PRE:SysID is my parent record SysID. I know its already in the SessionQueue.

3. Clarion on the Server to catch the reorder

I use the browse table itself to capture when the client tells me to do a reorder. There might be better ways, but works for me. I like to keep this stuff grouped together.

In Embed ProcedureSetup:

  IF p_web.IfExistsValue('move') = True
    ProcessPresentItemActions(p_web)
    RefreshAnyParent(p_web)
  .


4. My Reorder Code

Its done in ProcessPresentItemActions(p_web) and it collects to, from and parent sysid from the values passed by javascript.



Not sure if this is something others are doing in a different way. Just thought I'd share. I haven't explained it all, so there is still some mystery for the adventurous!

It's all part of my new idea of being nice to my users :)

Regards
Bill


41
Web Server - Ask For Help / Re: dynamically rename url path
« on: August 06, 2020, 08:14:30 PM »
Hi Jason,

As your "Product" function is really designed to perform the work of a "virtual" page, eg Consultation.

Wait until the embed point _SendFile (so any other NetTalk pages are dealt with first). If the page requested doesn't match one of your built in page names, its now the right time to check if a virtual page (one your customer has made up) has been requested.

At this time, check your database (don't bother checking if the page is .jpg, .png, .js, .css otherwise it will unnecessarily slow your system down) to see if the page requested matches one defined by your customers.

If it does, you call product and have it do the work.

Your URL will be what the human typed/followed, so it will already be correct and doesn't need fixing.

Just make sure your builtin names don't clash with arbitrary names your customers are allowed to invent.

Regards
Bill

42
Web Server - Ask For Help / Re: Starting Clarion proc from javascript
« on: July 14, 2020, 05:26:47 PM »
Hi,

Create a NetWebPage with a contentType of 'application/json'. We normally use json to talk to JS.

Its usually nice to give it a page name of 'YourProc.json' or similar so JS has a better idea of what its dealing with.

There are a bunch of ways of calling a server side function from JS. I often use .get or .ajax which are part of jQuery.

$.get('YourFunc.json?YoucanpassURLparamaters=1',function(data){
  if (data.somevariable==1) {
    // You can add some JS code in here based on the response
  };
});


Get is the simplest.

In clarion:

Packet.Append('{{"somevariable":1}')

Will allow you to read this variable in JS (as shown above).

Regards
Bill

43
Awesome. I'll give it a try.

44
Hi Bruce,

The URLDecode method in StringTheory is the same as the _Unescape in NetTalk, so no faster.

Fortunately, StringTheory's Replace is very fast. I got more speed out of it, by using Replace for the popular characters I had to decode, then letting URLDecode handle the rest.

Being JSON, it was lots of [,],{ and }. Hundreds of thousands of them.

Ultimately, it was still too slow. As Mandrill keeps throwing packets at me.

My ultimate solution is crap (but effective) and frankly I was desperate. I modified _AddSetting to not automatically unescape the p_setting string in the event the parameter was clearly from mandrill.

The process i use to parse and process the JSON is decoupled from the POST function. I save the incoming JSON to disk into a queue and have a daemon that processes them in an orderly fashion. I just added Unescaping to the daemon.


To answer your question, using Replace on [ ] { } , then URLDecode (for the scraps) took the time from 180 seconds to 50 seconds.

Regards
Bill

45
Web Server - Ask For Help / Re: Drag & Drop file upload
« on: July 11, 2020, 08:34:48 PM »
Hi,

I've done drag and drop within NetTalk for reordering uploaded photos. I know thats not the same but the drag and drop that is supported within html is "usable".

A html element say DIV can have a "draggable" attribute, so the browser knows it can be dragged.

Then you also have events for "ondrop" and "ondragover". Its all done client side in javascript. Untill you know what you want tell the server to do, then I can do an ajax call to tell NetTalk what needs to change in my database and if necessary refresh the div/divs.

I do have trouble with NetTalk 10 and multiple upload drop "destinations" on a popup window, not sure if thats me, NT10 and whether NT11 may have the same issue.

Its totally do-able, but it will take some work.

I've attached a picture and some of the html to give you a clue.

   <td>
      <div id="draggable_001" class="movable_img" ondrop="drop(event,1)" ondragover="allowDrop(event)">
         <a href="https://titan.inhabit.com.au/images/65/0003114436.JPG?s=0" target="_blank">
            <img draggable="true" ondragstart="drag(event,1)" src="https://titan.inhabit.com.au/thumbs/65/0003114436.JPG?s=0" width="100" alt="" border="0">
         </a>
      </div>
   </td>
   <td>
      <div id="draggable_002" class="movable_img" ondrop="drop(event,2)" ondragover="allowDrop(event)">
         <a href="https://titan.inhabit.com.au/images/65/0003114448.JPG?s=0" target="_blank">
            <img draggable="true" ondragstart="drag(event,2)" src="https://titan.inhabit.com.au/thumbs/65/0003114448.JPG?s=0" width="100" alt="" border="0">
         </a>
      </div>
   </td>
   <td>
      <div id="draggable_003" class="movable_img" ondrop="drop(event,3)" ondragover="allowDrop(event)">
         <a href="https://titan.inhabit.com.au/images/65/0003114446.JPG?s=0" target="_blank">
            <img draggable="true" ondragstart="drag(event,3)" src="https://titan.inhabit.com.au/thumbs/65/0003114446.JPG?s=0" width="100" alt="" border="0">
         </a>
      </div>
   </td>
   <td>
      <div id="draggable_004" class="movable_img" ondrop="drop(event,4)" ondragover="allowDrop(event)">
         <a href="https://titan.inhabit.com.au/images/65/0003114449.JPG?s=0" target="_blank">
            <img draggable="true" ondragstart="drag(event,4)" src="https://titan.inhabit.com.au/thumbs/65/0003114449.JPG?s=0" width="100" alt="" border="0">
         </a>
      </div>
   </td>
   <td>
      <div id="draggable_bin" ondrop="drop(event,-1)" ondragover="allowDrop(event)">
         <img draggable="false" src="https://titan.inhabit.com.au/_ui/rsc/trash-can.png" width="100" height="75" alt="" border="0">
      </div>
   </td>


<script>
function drop(e,idx) {
  e.preventDefault();
  var data=e.dataTransfer.getData("Text");
  if (data=="killfp1") {
    sv('','listingtable_listingtablew','','_refresh_=current','killfp1=65,'+idx+',519386','_parentproc_=listingtablew');
  } else if (data=="killfp2") {
    sv('','listingtable_listingtablew','','_refresh_=current','killfp2=65,'+idx+',519386','_parentproc_=listingtablew');
  } else if (idx==-1) {
    sv('','listingtable_listingtablew','','_refresh_=current','delete='+data+',519386','_parentproc_=listingtablew');
  } else {
    sv('','listingtable_listingtablew','','_refresh_=current','move='+data+','+idx+',519386','_parentproc_=listingtablew');
  }
}

function drag(e,idx) {
  e.dataTransfer.setData("Text",idx);
}

function allowDrop(e) {
  e.preventDefault();
}

function handleDragEnter(e) {
  this.className = 'over';
  return false;
}

function handleDragLeave(e) {
  this.className = '';
  return false;
}
</script>


Regards
Bill

Pages: 1 2 [3] 4 5 ... 26