View | Details | Raw Unified | Return to bug 7977
Collapse All | Expand All

(-)a/koha-tmpl/intranet-tmpl/prog/en/css/datatables.css (+8 lines)
Lines 200-205 input { Link Here
200
    border-radius: 5px;
200
    border-radius: 5px;
201
}
201
}
202
202
203
tr.odd.selected td {
204
    background-color: #D3D3D3;
205
}
206
207
tr.even.selected td {
208
    background-color: #D3D3D3;
209
}
210
203
/*
211
/*
204
table.display {
212
table.display {
205
    width: 100%;
213
    width: 100%;
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/quotes.tt (-78 / +100 lines)
Lines 3-8 Link Here
3
    [% INCLUDE 'doc-head-close.inc' %]
3
    [% INCLUDE 'doc-head-close.inc' %]
4
    <link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" />
4
    <link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" />
5
    <script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.dataTables.min.js"></script>
5
    <script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.dataTables.min.js"></script>
6
    <script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/dataTables.fnReloadAjax.js"></script>
6
    [% INCLUDE 'datatables-strings.inc' %]
7
    [% INCLUDE 'datatables-strings.inc' %]
7
    </script>
8
    </script>
8
    <script type="text/javascript" src="[% themelang %]/js/datatables.js"></script>
9
    <script type="text/javascript" src="[% themelang %]/js/datatables.js"></script>
Lines 12-29 Link Here
12
    var oTable; /* oTable needs to be global */
13
    var oTable; /* oTable needs to be global */
13
    var sEmptyTable = _('No quotes available. Please use the \"Add Quote\" button to add a quote.'); /* override the default message in datatables-strings.inc */
14
    var sEmptyTable = _('No quotes available. Please use the \"Add Quote\" button to add a quote.'); /* override the default message in datatables-strings.inc */
14
    $(document).ready(function() {
15
    $(document).ready(function() {
16
        /* NOTE: This is an ajax-source datatable and *not* a server-side sourced datatable. */
17
        /* See the datatable docs if you don't understand this difference. */
15
        oTable = $("#quotes_editor").dataTable({
18
        oTable = $("#quotes_editor").dataTable({
16
                    "bAutoWidth"        : false,
19
                    "bAutoWidth"        : false,
17
                    "bProcessing"       : true,
20
                    "bProcessing"       : true,
18
                    //"bServerSide"       : true,
19
                    "bPaginate"         : true,
21
                    "bPaginate"         : true,
20
                    "sPaginationType"   : "full_numbers",
22
                    "sPaginationType"   : "full_numbers",
21
                    "sAjaxSource"       : "/cgi-bin/koha/tools/quotes/quotes_ajax.pl",
23
                    "sAjaxSource"       : "/cgi-bin/koha/tools/quotes/quotes_ajax.pl",
22
                    "aoColumns"         : [
24
                    "aoColumns"         : [
23
                                            { "sWidth": "3%"  },
25
                                            { "sWidth": "3%"  },
24
                                            { "sWidth": "11%" },
26
                                            { "sWidth": "11%" },
25
                                            { "sWidth": "65%" },
27
                                            { "sWidth": "75%" },
26
                                            { "sWidth": "10%" },
27
                                            { "sWidth": "11%" },
28
                                            { "sWidth": "11%" },
28
                                          ],
29
                                          ],
29
                   "oLanguage"          : {
30
                   "oLanguage"          : {
Lines 33-45 Link Here
33
                        return true;
34
                        return true;
34
                    },
35
                    },
35
                    "fnRowCallback": function( nRow, aData, iDisplayIndex ) {
36
                    "fnRowCallback": function( nRow, aData, iDisplayIndex ) {
36
                        noEditFields = [0,3,4]; /* id, timestamp, action */
37
                        /* do foo on the current row and its child nodes */
37
                        quoteID = $('td', nRow)[0].innerHTML;
38
                        var noEditFields = [];
38
                        /* console.log('Quote ID: '+quoteID); */
39
                        var quoteID = $('td', nRow)[0].innerHTML;
39
                        /* do foo on various cells in the current row */
40
                        $(nRow).attr("id", quoteID); /* set row ids to quote id */
40
                        $('td:eq(1)', nRow).attr("id", quoteID); /* we use the id attribute to carry the quote id */
41
                        $('td:eq(0)', nRow).click(function() {$(this.parentNode).toggleClass('selected',this.clicked);}); /* add row selectors */
41
                        $('td:eq(2)', nRow).attr("id", quoteID);
42
                        $('td:eq(0)', nRow).attr("title", "Click ID to select/deselect quote");
42
                        $('td:eq(4)', nRow).html('<input type="button" class="delete" value="Delete" onclick="fnClickDeleteRow('+quoteID+');" />');
43
                        if (isNaN(quoteID)) {
44
                            noEditFields = [0,1,2,3]; /* all fields when adding a quote */
45
                        }
46
                        else {
47
                            noEditFields = [0,3]; /* id, timestamp */
48
                        }
43
                        /* apply no_edit id to noEditFields */
49
                        /* apply no_edit id to noEditFields */
44
                        for (i=0; i<noEditFields.length; i++) {
50
                        for (i=0; i<noEditFields.length; i++) {
45
                            $('td', nRow)[noEditFields[i]].setAttribute("id","no_edit");
51
                            $('td', nRow)[noEditFields[i]].setAttribute("id","no_edit");
Lines 62-142 Link Here
62
        });
68
        });
63
    });
69
    });
64
70
65
        function fnClickAddQuote() {
71
        function fnClickAddQuote(e, node) {
66
            var quoteSource = $('#quoteSource').val();
72
            console.log('keyCode: '+e.keyCode);
67
            var quoteText = $('#quoteText').val()
73
            console.log('charCode: '+e.charCode);
68
            /* If passed a quote source, add the quote to the db */
74
            if (e.charCode) {
69
            if (quoteSource && quoteText) {
75
                /* some browsers only give charCode, so this will need to be */
70
                $.ajax({
76
                /* fixed up to handle that */
71
                    url: "/cgi-bin/koha/tools/quotes/quotes_ajax.pl",
77
                console.log('charCode: '+e.charCode);
72
                    type: "POST",
73
                    data: {
74
                            "source"    : quoteSource,
75
                            "text"      : quoteText,
76
                            "action"    : "add",
77
                    },
78
                    success: function(){oTable.fnDraw(false)}
79
                });
80
            }
78
            }
81
            else {
79
            if (e.keyCode == 13) {
82
                alert('Please supply both the text and source of the quote before saving.');
80
                var quoteSource = $('#quoteSource').val();
83
            }
81
                var quoteText = $('#quoteText').val()
84
        }
82
                /* If passed a quote source, add the quote to the db */
85
83
                if (quoteSource && quoteText) {
86
        function fnClickAddRow() {
87
            /* This adds a row to the datatable */
88
            var lastID = $('#quotes_editor tbody tr:last td:first').text(); /* grab the last quote id to validate add request */
89
            if (lastID !== '--') {
90
                $('#quotes_editor').one('draw', function (){
91
                    var tbody = document.getElementById('quotes_editor');
92
                    var lastRow = tbody.rows.length;
93
                    var row = tbody.insertRow(lastRow);
94
                    var currentRow = lastRow+1;
95
                    row.innerHTML ='<td id="no_edit">--</td><td><input id="quoteSource" type="text" style="height:14px; width:99%" /></td><td><input id="quoteText" type="text" style="height:14px; width:99%" /></td><td id="no_edit">--</td><td id="no_edit"><input type="button" class="delete" value="Delete" disable="disable"/><input type="button" class="save" value="Save" onclick="fnClickAddQuote();"/><input type="button" class="cancel" value="Cancel" onclick="fnClickDeleteRow();"/></td>';
96
                    if (currentRow % 2 == 0) {
97
                        row.className="odd";
98
                    }
99
                    else {
100
                        row.className="even";
101
                    }
102
                });
103
                oTable.fnPageChange('last', true);
104
            }
105
            else {
106
                alert('You must either save or cancel your current addition before adding another.');
107
            }
108
        }
109
110
        function fnClickDeleteRow(quoteID) {
111
            //console.log('Quote ID: '+quoteID);
112
            if (quoteID) {
113
                /* Delete the row from the db */
114
                if (confirm('Are you sure you wish to delete quote '+quoteID+'?')) {
115
                    $.ajax({
84
                    $.ajax({
116
                        url: "/cgi-bin/koha/tools/quotes/quotes_ajax.pl",
85
                        url: "/cgi-bin/koha/tools/quotes/quotes_ajax.pl",
117
                        type: "POST",
86
                        type: "POST",
118
                        data: {
87
                        data: {
119
                                "id"        : quoteID,
88
                                "source"    : quoteSource,
120
                                "action"    : "delete",
89
                                "text"      : quoteText,
90
                                "action"    : "add",
121
                        },
91
                        },
122
                    /* On a successful delete, redraw the table */
92
                        success: function(data){
123
                    success: function(){oTable.fnDraw(false)}
93
                                    var newQuote = data[0];
94
                                    var aRow = oTable.fnUpdate(
95
                                        newQuote,
96
                                        node,
97
                                        false,
98
                                        false
99
                                    );
100
                                    oTable.fnPageChange( 'last' );
101
                                    $('.add_quote_button').attr('onclick', 'fnClickAddRow()'); // re-enable add button
102
                            }
124
                    });
103
                    });
125
                }
104
                }
126
                else {
105
                else {
127
                    return;
106
                    alert('Please supply both the text and source of the quote before saving.');
128
                }
107
                }
129
            }
108
            }
130
            else {
109
            else if (e.keyCode == 27) {
131
                /* Delete the row from the table */
110
                if (confirm('Are you sure you want to cancel adding this quote?')) {
132
                if (confirm('Your quote will not be saved! Do you wish to continue?')) {
111
                    oTable.fnDeleteRow(node);
133
                    $('#quotes_editor tbody tr:last').remove();
134
                }
112
                }
135
                else {
113
                else {
136
                    return;
114
                    return;
137
                }
115
                }
138
            }
116
            }
139
        }
117
        }
118
119
        function fnClickAddRow() {
120
            $('.add_quote_button').removeAttr('onclick'); // disable add button once it has been clicked
121
            var aRow = oTable.fnAddData(
122
                [
123
                    'NA', // this is hackish to fool the datatable sort routine into placing this row at the end of the list...
124
                    '<input id="quoteSource" type="text" style="height:14px; width:99%" onkeydown="fnClickAddQuote(event,this.parentNode.parentNode)"/>',
125
                    '<input id="quoteText" type="text" style="height:14px; width:99%" onkeydown="fnClickAddQuote(event,this.parentNode.parentNode)"/>',
126
                    '0000-00-00 00:00:00',
127
                ],
128
                false
129
            );
130
            oTable.fnPageChange( 'last' );
131
            $('#quoteSource').focus();
132
        }
133
134
        function fnClickDeleteRow() {
135
            var idsToDelete = oTable.$('.selected').map(function() {
136
                  return this.id;
137
            }).get().join(', ');
138
            if (confirm('Are you sure you wish to delete quote(s) '+idsToDelete+'?')) {
139
                oTable.$('.selected').each(function(){
140
                        var quoteID = $(this).attr('id');
141
                            $.ajax({
142
                                url: "/cgi-bin/koha/tools/quotes/quotes_ajax.pl",
143
                                type: "POST",
144
                                data: {
145
                                        "id"        : quoteID,
146
                                        "action"    : "delete",
147
                                },
148
                                /* Delete the row from the datatable */
149
                                success: function(){
150
                                    oTable.fnDeleteRow(this);
151
                                    oTable.fnReloadAjax(null, null, true);
152
                                }
153
                            });
154
                    });
155
            }
156
            else {
157
                return;
158
            }
159
        }
140
    //]]>
160
    //]]>
141
    </script>
161
    </script>
142
</head>
162
</head>
Lines 151-172 Link Here
151
        <div id="yui-main">
171
        <div id="yui-main">
152
            <div class="yui-b">
172
            <div class="yui-b">
153
                <div id="toolbar">
173
                <div id="toolbar">
154
                <ul class="toolbar">
174
                    <ul class="toolbar">
155
                <li>
175
                        <li>
156
                    <input type="button" class="add_quote_button" value="Add Quote" style="border-radius: 5px;" onclick="fnClickAddRow();"/>
176
                            <input type="button" class="add_quote_button" value="Add Quote" style="border-radius: 5px;" onclick="fnClickAddRow();"/>
157
                    <input type="button" class="import_quote_button" value="Import Quotes" style="border-radius: 5px;" onclick="parent.location='quotes-upload.pl'"/>
177
                            <input type="button" class="import_quote_button" value="Import Quotes" style="border-radius: 5px;" onclick="parent.location='quotes-upload.pl'"/>
158
                    <span class="hint" style="">Click Source or Text field to edit contents. Press <Enter> to save changes.</span>
178
                            <input type="button" class="delete_quote_button" value="Delete Quote(s)" style="border-radius: 5px;" onclick="fnClickDeleteRow();"/>
159
                </li>
179
                            <span class="hint" style="">Click Source or Text field to edit contents. Press &lt;Enter&gt; to save changes.</span>
160
                </ul>
180
                        </li>
181
                    </ul>
161
                </div>
182
                </div>
183
                <h2>Quote Editor</h2>
162
                <table id="quotes_editor" style="float: left; width: 100%;">
184
                <table id="quotes_editor" style="float: left; width: 100%;">
163
                <thead>
185
                <thead>
164
                    <tr>
186
                    <tr>
165
                        <th>ID</th>
187
                        <th><span style="cursor: help" onclick="event.stopPropagation();alert('Click on the quote\'s id to select or deselect the quote. Multiple quotes may be selected.');">ID</span></th>
166
                        <th>Source</th>
188
                        <th>Source</th>
167
                        <th>Text</th>
189
                        <th>Text</th>
168
                        <th>Last Displayed</th>
190
                        <th>Last Displayed</th>
169
                        <th>Actions</th>
191
<!--                        <th>Actions</th>-->
170
                    </tr>
192
                    </tr>
171
                </thead>
193
                </thead>
172
                <tbody>
194
                <tbody>
Lines 176-182 Link Here
176
                        <td></td>
198
                        <td></td>
177
                        <td>Loading data...</td>
199
                        <td>Loading data...</td>
178
                        <td></td>
200
                        <td></td>
179
                        <td></td>
201
<!--                        <td></td>-->
180
                    </tr>
202
                    </tr>
181
                </tbody>
203
                </tbody>
182
                </table>
204
                </table>
(-)a/tools/quotes/quotes_ajax.pl (-8 / +7 lines)
Lines 55-60 if ($params->{'action'} eq 'add') { Link Here
55
        warn sprintf('Database returned the following error: %s', $sth->errstr);
55
        warn sprintf('Database returned the following error: %s', $sth->errstr);
56
        exit 0;
56
        exit 0;
57
    }
57
    }
58
    my $new_quote_id = $dbh->{q{mysql_insertid}}; # ALERT: mysqlism here
59
    $sth = $dbh->prepare('SELECT * FROM quotes WHERE id = ?;');
60
    $sth->execute($new_quote_id);
61
    print to_json($sth->fetchall_arrayref);
58
    exit 1;
62
    exit 1;
59
}
63
}
60
elsif ($params->{'action'} eq 'edit') {
64
elsif ($params->{'action'} eq 'edit') {
Lines 65-71 elsif ($params->{'action'} eq 'edit') { Link Here
65
        warn sprintf('Database returned the following error: %s', $sth->errstr);
69
        warn sprintf('Database returned the following error: %s', $sth->errstr);
66
        exit 0;
70
        exit 0;
67
    }
71
    }
68
    print $params->{'value'};
72
    print $sth->fetchrow_array();
69
    exit 1;
73
    exit 1;
70
}
74
}
71
elsif ($params->{'action'} eq 'delete') {
75
elsif ($params->{'action'} eq 'delete') {
Lines 82-100 else { Link Here
82
    my $iTotalRecords = '';
86
    my $iTotalRecords = '';
83
    my $sth = '';
87
    my $sth = '';
84
88
85
    # FIXME: the use of "Action" in the SELECTs below is a hack to supply the fifth column; there should be a nicer way todo this...
86
    if (my $filter = $params->{'sSearch'}) {
89
    if (my $filter = $params->{'sSearch'}) {
87
        # This seems a bit brute force and ungraceful, but it provides a very general, simple search on all fields
90
        # This seems a bit brute force and ungraceful, but it provides a very general, simple search on all fields
88
        my $like = " id LIKE \"%$filter%\" OR source LIKE \"%$filter%\" OR text LIKE \"%$filter%\" OR timestamp LIKE \"%$filter%\"";
91
        my $like = " id LIKE \"%$filter%\" OR source LIKE \"%$filter%\" OR text LIKE \"%$filter%\" OR timestamp LIKE \"%$filter%\"";
89
        $iTotalRecords = $dbh->selectrow_array("SELECT count(*) FROM quotes WHERE $like;");
92
        $iTotalRecords = $dbh->selectrow_array("SELECT count(*) FROM quotes WHERE $like;");
90
        # At present we only support sorting by a single column
93
        $sth = $dbh->prepare("SELECT * FROM quotes;");
91
        #$sth = $dbh->prepare("SELECT *, \"Action\" FROM quotes WHERE $like ORDER BY $sort_columns->[$params->{'iSortCol_0'}] $params->{'sSortDiri_0'} LIMIT $params->{'iDisplayStart'}, $params->{'iDisplayLength'};");
92
        $sth = $dbh->prepare("SELECT *, \"Action\" FROM quotes;");
93
    }
94
    }
94
    else {
95
    else {
95
        $iTotalRecords = $dbh->selectrow_array('SELECT count(*) FROM quotes;');
96
        $iTotalRecords = $dbh->selectrow_array('SELECT count(*) FROM quotes;');
96
        #$sth = $dbh->prepare("SELECT *, \"Action\" FROM quotes ORDER BY $sort_columns->[$params->{'iSortCol_0'}] $params->{'sSortDiri_0'} LIMIT $params->{'iDisplayStart'}, $params->{'iDisplayLength'};");
97
        $sth = $dbh->prepare("SELECT * FROM quotes;");
97
        $sth = $dbh->prepare("SELECT *, \"Action\" FROM quotes;");
98
    }
98
    }
99
99
100
    $sth->execute();
100
    $sth->execute();
101
- 

Return to bug 7977