0

I've a pop-up to display the user list which would display 10 results per page, which is working fine.

I'm getting the page nos. from the java servlet in the JSON. How do I disable the previous button, when it is the first page? Likewise, how do I disable the last button, when it is the last page?

Here's my code.

function userList(pageNo) {

 var resType="userList";
    
 createTable(resType,pageNo);
 $(document).on('click', '.next-btn', function(){
  var next = 10+pageNo;
  userList(next);

 });
 $(document).on('click', '.prev-btn', function(){
  var previ = pageNo - 10;
  userList(previ);
 });
}

function createTable(resType, pageNo) {
    $.getJSON("https://api.randomuser.me/?results="+pageNo, function(data) {
        $('#datatable tr:has(td)').remove();
        data.results.forEach(function (record) {
            var json = JSON.stringify(record);
            $('#datatable').append(
                $('<tr>').append(
                    $('<td>').append(
                        $('<input>').attr('type', 'checkbox')
                                    .addClass('selectRow')
                                    .val(json)
                    ),
                    $('<td>').append(
                        $('<a>').attr('href', record.picture.thumbnail)
                                .addClass('imgurl')
                                .attr('target', '_blank')
                                .text(record.name.first)
                    ),
                    $('<td>').append(record.dob)
                )
            );
        })
    }).fail(function(error) {
        console.log("**********AJAX ERROR: " + error);
    });            
}

var savedData = []; // The objects as array, so to have an order.

function saveData(){
    var errors = [];
    // Add selected to map
    $('input.selectRow:checked').each(function(count) {
        // Get the JSON that is stored as value for the checkbox
        var obj = JSON.parse($(this).val());
        // See if this URL was already collected (that's easy with Set)
        if (savedData.find(record => record.picture.thumbnail === obj.picture.thumbnail)) {
            errors.push(obj.name.first);
        } else {
            // Append it
            savedData.push(obj);
        }
    });
    refreshDisplay();
    if (errors.length) {
        alert('The following were already selected:\n' + errors.join('\n'));
    }
}

function refreshDisplay() {
    $('.container').html('');
    savedData.forEach(function (obj) {
        // Reset container, and append collected data (use jQuery for appending)
        $('.container').append(
            $('<div>').addClass('parent').append(
                $('<label>').addClass('dataLabel').text('Name: '),
                obj.name.first + ' ' + obj.name.last,
                $('<br>'), // line-break between name & pic
                $('<img>').addClass('myLink').attr('src', obj.picture.thumbnail), $('<br>'),
                $('<label>').addClass('dataLabel').text('Date of birth: '),
                obj.dob, $('<br>'),
                $('<label>').addClass('dataLabel').text('Address: '), $('<br>'),
                obj.location.street, $('<br>'),
                obj.location.city + ' ' + obj.location.postcode, $('<br>'),
                obj.location.state, $('<br>'),
                $('<button>').addClass('removeMe').text('Delete'),
                $('<button>').addClass('top-btn').text('Swap with top'),
                $('<button>').addClass('down-btn').text('Swap with down')
            ) 
        );
    })
    // Clear checkboxes:
    $('.selectRow').prop('checked', false);
    handleEvents();
}

function logSavedData(){
    // Convert to JSON and log to console. You would instead post it
    // to some URL, or save it to localStorage.
    console.log(JSON.stringify(savedData, null, 2));
}

function getIndex(elem) {
    return $(elem).parent('.parent').index();
}

$(document).on('click', '.removeMe', function() {
    // Delete this from the saved Data
    savedData.splice(getIndex(this), 1);
    // And redisplay
    refreshDisplay();
});

/* Swapping the displayed articles in the result list */
$(document).on('click', ".down-btn", function() {
    var index = getIndex(this);
    // Swap in memory
    savedData.splice(index, 2, savedData[index+1], savedData[index]);
    // And redisplay
    refreshDisplay();
});

$(document).on('click', ".top-btn", function() {
    var index = getIndex(this);
    // Swap in memory
    savedData.splice(index-1, 2, savedData[index], savedData[index-1]);
    // And redisplay
    refreshDisplay();
});
    
/* Disable top & down buttons for the first and the last article respectively in the result list */
function handleEvents() {
    $(".top-btn, .down-btn").prop("disabled", false).show();
    $(".parent:first").find(".top-btn").prop("disabled", true).hide();
    $(".parent:last").find(".down-btn").prop("disabled", true).hide();
}

$(document).ready(function(){
    $('#showExtForm-btn').click(function(){
        $('#extUser').toggle();
    });
    $("#extUserForm").submit(function(e){
        addExtUser();
        return false;
   });
});

function addExtUser() {
    var extObj = {
        name: {
            title: "mr", // No ladies? :-)
            first: $("#name").val(),
            // Last name ?
        },
        dob: $("#dob").val(),
        picture: {
            thumbnail: $("#myImg").val()
        },
        location: { // maybe also ask for this info?
        }
    };
    savedData.push(extObj);
    refreshDisplay(); // Will show some undefined stuff (location...)
}
table, th, td {
    border: 1px solid #ddd;
    border-collapse: collapse;
    padding: 10px;
}

.parent {
    height: 25%;
    width: 90%;
    padding: 1%;
    margin-left: 1%;
    margin-top: 1%;
    border: 1px solid black;

}

.parent:nth-child(odd){
    background: skyblue;
}

.parent:nth-child(even){
    background: green;
}

label {
    float: left;
    width: 80px;
}
input {
    width: 130px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="userList(0)">Create Table</button>
<table id="datatable">
    <tr><th>Select</th><th>Name</th><th>DOB</th></tr>
</table>
<button onclick="saveData()">Save Selected</button>
<br />
<div class="container"></div>
<button onclick="logSavedData()">Get Saved Data</button>
<button id="showExtForm-btn">Open External Form</button>

<div id="extUser" style="display:none">
    <form id="extUserForm">
        <p>
            <label for="name">Name:</label>
            <input type="text" id="name" required>
        </p>
        <br />
        <p>
            <label for="myImg">Image:</label>
            <input type="url" id="myImg" required>
        </p>
        <br />
        <p>
            <label for="dob">DOB:</label>
            <input type="date" id="dob" required>
        </p>
        <br />
        <button>Submit</button>
    </form>
</div>
Sunny
  • 902
  • 3
  • 18
  • 41
  • Your URL argument `results` is not determining the page (first record), but the number of records to return. Do you have another argument for setting the first number of the record? – trincot Apr 12 '17 at 08:10
  • How do you know which is your last page? Do you have a record count? A specific response from the server? – trincot Apr 12 '17 at 08:12

2 Answers2

1

You should add the prev/next buttons to your HTML as hidden, and then reference them by ID instead of class (as you will only have one of each).

Keep track of the current page number in a global variable.

Show the "prev" button only when the page number is greater than 0. For the "next" button you could apply this trick:

Instead of loading 10 records, load one more, but not for display: if it exists, then the "next" button should be visible.

Here is a snippet with those changes (all changes are in HTML and top part of the script):

var currentPageNo = 0; // Keep track of currently displayed page

$('#next-btn').click(function(){ // Give buttons an ID (include them in HTML as hidden)
    userList(currentPageNo+10);
});
$('#prev-btn').click(function(){
    userList(currentPageNo-10);
});

function userList(pageNo) {
 var resType="userList";
 createTable(resType,pageNo);
}

function createTable(resType, pageNo) {
    // Update global variable
    currentPageNo = pageNo; 
    // Set visibility of the "prev" button:
    $('#prev-btn').toggle(pageNo > 0);
    // Ask one record more than needed, to determine if there are more records after this page:
    $.getJSON("https://api.randomuser.me/?results=11&start="+pageNo, function(data) {
        $('#datatable tr:has(td)').remove();
        // Check if there's an extra record which we do not display, 
        // but determines that there is a next page
        $('#next-btn').toggle(data.results.length > 10);
        // Slice results, so 11th record is not included:
        data.results.slice(0, 10).forEach(function (record, i) { // add second argument for numbering records
            var json = JSON.stringify(record);
            $('#datatable').append(
                $('<tr>').append(
                    $('<td>').append(
                        $('<input>').attr('type', 'checkbox')
                                    .addClass('selectRow')
                                    .val(json),
                        (i+1+pageNo) // display row number
                    ),
                    $('<td>').append(
                        $('<a>').attr('href', record.picture.thumbnail)
                                .addClass('imgurl')
                                .attr('target', '_blank')
                                .text(record.name.first)
                    ),
                    $('<td>').append(record.dob)
                )
            );
        });
        // Show the prev and/or buttons
        
        
    }).fail(function(error) {
        console.log("**********AJAX ERROR: " + error);
    });            
}

var savedData = []; // The objects as array, so to have an order.

function saveData(){
    var errors = [];
    // Add selected to map
    $('input.selectRow:checked').each(function(count) {
        // Get the JSON that is stored as value for the checkbox
        var obj = JSON.parse($(this).val());
        // See if this URL was already collected (that's easy with Set)
        if (savedData.find(record => record.picture.thumbnail === obj.picture.thumbnail)) {
            errors.push(obj.name.first);
        } else {
            // Append it
            savedData.push(obj);
        }
    });
    refreshDisplay();
    if (errors.length) {
        alert('The following were already selected:\n' + errors.join('\n'));
    }
}

function refreshDisplay() {
    $('.container').html('');
    savedData.forEach(function (obj) {
        // Reset container, and append collected data (use jQuery for appending)
        $('.container').append(
            $('<div>').addClass('parent').append(
                $('<label>').addClass('dataLabel').text('Name: '),
                obj.name.first + ' ' + obj.name.last,
                $('<br>'), // line-break between name & pic
                $('<img>').addClass('myLink').attr('src', obj.picture.thumbnail), $('<br>'),
                $('<label>').addClass('dataLabel').text('Date of birth: '),
                obj.dob, $('<br>'),
                $('<label>').addClass('dataLabel').text('Address: '), $('<br>'),
                obj.location.street, $('<br>'),
                obj.location.city + ' ' + obj.location.postcode, $('<br>'),
                obj.location.state, $('<br>'),
                $('<button>').addClass('removeMe').text('Delete'),
                $('<button>').addClass('top-btn').text('Swap with top'),
                $('<button>').addClass('down-btn').text('Swap with down')
            ) 
        );
    })
    // Clear checkboxes:
    $('.selectRow').prop('checked', false);
    handleEvents();
}

function logSavedData(){
    // Convert to JSON and log to console. You would instead post it
    // to some URL, or save it to localStorage.
    console.log(JSON.stringify(savedData, null, 2));
}

function getIndex(elem) {
    return $(elem).parent('.parent').index();
}

$(document).on('click', '.removeMe', function() {
    // Delete this from the saved Data
    savedData.splice(getIndex(this), 1);
    // And redisplay
    refreshDisplay();
});

/* Swapping the displayed articles in the result list */
$(document).on('click', ".down-btn", function() {
    var index = getIndex(this);
    // Swap in memory
    savedData.splice(index, 2, savedData[index+1], savedData[index]);
    // And redisplay
    refreshDisplay();
});

$(document).on('click', ".top-btn", function() {
    var index = getIndex(this);
    // Swap in memory
    savedData.splice(index-1, 2, savedData[index], savedData[index-1]);
    // And redisplay
    refreshDisplay();
});
    
/* Disable top & down buttons for the first and the last article respectively in the result list */
function handleEvents() {
    $(".top-btn, .down-btn").prop("disabled", false).show();
    $(".parent:first").find(".top-btn").prop("disabled", true).hide();
    $(".parent:last").find(".down-btn").prop("disabled", true).hide();
}

$(document).ready(function(){
    $('#showExtForm-btn').click(function(){
        $('#extUser').toggle();
    });
    $("#extUserForm").submit(function(e){
        addExtUser();
        return false;
   });
});

function addExtUser() {
    var extObj = {
        name: {
            title: "mr", // No ladies? :-)
            first: $("#name").val(),
            // Last name ?
        },
        dob: $("#dob").val(),
        picture: {
            thumbnail: $("#myImg").val()
        },
        location: { // maybe also ask for this info?
        }
    };
    savedData.push(extObj);
    refreshDisplay(); // Will show some undefined stuff (location...)
}
table, th, td {
    border: 1px solid #ddd;
    border-collapse: collapse;
    padding: 10px;
}

.parent {
    height: 25%;
    width: 90%;
    padding: 1%;
    margin-left: 1%;
    margin-top: 1%;
    border: 1px solid black;

}

.parent:nth-child(odd){
    background: skyblue;
}

.parent:nth-child(even){
    background: green;
}

label {
    float: left;
    width: 80px;
}
input {
    width: 130px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="userList(0)">Load First Page</button>
<button id="next-btn" style="display:none">Next Page</button>
<button id="prev-btn" style="display:none">Previous Page</button>
<table id="datatable">
    <tr><th>Select</th><th>Name</th><th>DOB</th></tr>
</table>
<button onclick="saveData()">Save Selected</button>
<br />
<div class="container"></div>
<button onclick="logSavedData()">Get Saved Data</button>
<button id="showExtForm-btn">Open External Form</button>

<div id="extUser" style="display:none">
    <form id="extUserForm">
        <p>
            <label for="name">Name:</label>
            <input type="text" id="name" required>
        </p>
        <br />
        <p>
            <label for="myImg">Image:</label>
            <input type="url" id="myImg" required>
        </p>
        <br />
        <p>
            <label for="dob">DOB:</label>
            <input type="date" id="dob" required>
        </p>
        <br />
        <button>Submit</button>
    </form>
</div>

As this URL provides random data, the pages will not show the same data when you revisit them. Also, there is apparently no last page in this random data set. I have guessed the URL parameter for specifying the first record (start), since the results parameter is for specifying the page size, not the first record number. Adapt as needed.

trincot
  • 317,000
  • 35
  • 244
  • 286
  • thanks, what if I've 1 more button which calls the same createTable function? I'm using the same previous & next buttons there as well. It is quite similar to the userList function. Only the resultType is different. And the data received from JSON is different in that case as I'm also retrieving resultType from the JSON. However, the implementation, look and feel(UI) remains exactly the same. function myAdminList(pageNo){var resType="myadmingroup"; createTable(resType, pageNo);} – Sunny Apr 12 '17 at 09:29
  • Yes, sure. But you'll have to define what needs to happen with the objects already selected in memory and in the `div.container` section: will they continue to keep the information? And will you then allow a mix of both types to be collected into that selection? You'll need to adapt the display of those items, and the way they are keyed (thumbnail URL exists for both types?), so they can cope with both types... etc. I think you need to work a bit on that before coming back ;-) – trincot Apr 12 '17 at 09:41
  • Yes, that's fine. I need them as well in there. I'd need a mix of both, so that part is working fine. I've actually used them as modals. To expalin it better, please check the fiddle link. The only part that is not working as expected is the next & previous button which should ideally get disabled on the last & firstpage respectively. Also, when I click on the next & previous button, the data in the table of the modal gets refreshed or changed multiple times automatically! https://jsfiddle.net/Sunny1719/tnnyhbsn/ – Sunny Apr 12 '17 at 09:49
  • I don't see much of a mix in that fiddle: it only has one button to load the userList. – trincot Apr 12 '17 at 09:54
  • Sorry, I'd added all the buttons now. I'd created this fiddle just to show how it looks like. Please let me know if you need any information. https://jsfiddle.net/Sunny1719/tnnyhbsn/2/ – Sunny Apr 12 '17 at 10:05
  • In both modals you have given the same id to the table: `datatable`. Id attribute values must be unique. I would suggest naming them: `userListTable` and `userAdminTable` (although I think you wanted to use `adminList` instead of `userAdmin`, but that is a detail). Anyway, use the same prefix before `table` as you have *resType* values. Then it is easy in `createTable` to do `$('#' + resType + 'Table').append(` ... and elsewhere ... etc. Make sure to also duplicate function `userList` as `userAdmin` with appropriate type. Please try and ask a new question if needed. – trincot Apr 12 '17 at 12:04
  • Oh, actually I'm using a class in general instead of ID there. But hadn't mentioned the same in the fiddle. Anyways, I tried doing that but it is actually hiding the buttons completely in that case, since, even for the previous - next buttons, I'm using class instead of ids. – Sunny Apr 12 '17 at 12:34
  • Keep trying to figure it out with `console.log`, etc. If you really get stuck, ask a new question specifically about that. – trincot Apr 12 '17 at 13:24
  • Ok, I'll ask a sepearate question for that. However, once I click on 'Next' and then click on 'previous', the row numbers don't change. – Sunny Apr 13 '17 at 06:03
  • Don't the row numbers change as they should in the answer I have given here? Seems to work fine for me. – trincot Apr 13 '17 at 06:15
  • Oh, sorry, my bad! I believe it is happening because I added another pop-up there. Regarading the page refresh, I'd added the question here.. http://stackoverflow.com/questions/43386118/page-refereshing-multiple-times-while-clicking-on-next-or-previous-button – Sunny Apr 13 '17 at 07:31
  • I'd updated my question based on my requirement and added it here. Could you please help me with that? http://stackoverflow.com/questions/43392063/check-the-last-and-the-first-page-and-disable-button-next-previous-buttons-accor – Sunny Apr 13 '17 at 12:15
0

Check previ value is less or equal to 10 if so hide it. Same reverse logic apply for next button. And on next button you can show prev-btn .

$(document).on('click', '.prev-btn', function(){
        var previ = pageNo - 10;
        if(previ < = 10)
          $(this).hide();
        UserList(previ);
    });
4b0
  • 21,981
  • 30
  • 95
  • 142
  • Thanks, but it is not working! It is hiding all the results in the popup instead of the button. – Sunny Apr 12 '17 at 06:36
  • Show your html . Its only hide button which have class ` .prev-btn` – 4b0 Apr 12 '17 at 06:47
  • Please ignore the html mistakes.in the script I can't exactly use the page no. because in my JSON url it comes from JAVA servlet. Hence,that page no. will not work here in the url. Otherwise, the logic remains the same! – Sunny Apr 12 '17 at 07:57