I am a fresher in mediawiki. I was trying to implement Manual:Tag extensions/Example (https://www.mediawiki.org/wiki/Manual:Tag_extensions/Example). But the example is based on mediawiki version < 1.3. I have a submit button. I want to save the current user name and a flag (say 1) to a database table if the submit button is clicked. but I am getting
Uncaught SyntaxError: Unexpected identifier (at load.php?lang=en&modules=ext.Example.welcome%7Cjquery&skin=vector&version=h3cy2:1:383).
Can I anyone suggest how to resolve the issue
My hook
class PollHooks implements
\MediaWiki\Hook\ParserFirstCallInitHook
{
Public function onParserFirstCallInit( $parser ) {
$parser->setHook( 'btn', [ self::class, 'pollRender' ] );
//$parser->setHook( 'poll', [self::class, 'pollRender' ] );
}
public static function pollRender( $data, $attribs, $parser, $frame ) {
$ret = '<table class="wtable">';
$ret .= '<tr>';
$ret .= '<td align="center" colspan=2><input id="btn002" type="button" value="Submit"></td>';
$ret .= '</tr>';
$ret .= '</table>';
return $ret;
}
My index.js
( function () {
$("#btn001").click
(
function() {
alert("Button clicked " + mw.user.getName() + ".");
console.log("Button clicked.");
$var user = mw.user.getName();
$flag = 1;
$.get(
mw.util.wikiScript(),
{
action: 'ajax',
rsargs: [user, flag],
rs: 'MediaWiki\\Extension\\Example\\SubmitApi'
}
);
}
);
}() );
SubmitApi.php
use ApiBase;
use Wikimedia\ParamValidator\ParamValidator;
class SubmitApi extends ApiBase {
public function execute() {
/* … */
global $wgUser;
$dbw = wfGetDB( DB_REPLICA );
// Insert vote
$insertQuery = $dbw->insert(
'polldb',
array(
'poll_user' => $user,
'poll_flag' => $flag
)
);
$dbw->commit();
}
public function getAllowedParams() {
return [
'level' => [
ParamValidator::PARAM_TYPE => 'integer',
ParamValidator::PARAM_REQUIRED => true,
]
];
}
}
?>
index.js:
$var user = mw.user.getName();
Remove the $ from $var.
I am not at all an HTML expert. I program microcontrollers and got off onto a tangent.
I created an html doc to show a table of microcontroller registers, register addresses and register descriptions. I created a table with 3 columns - and about 120 rows. Some of the register addresses are bit addressable - if their addresses end in 0 or 8.
I wanted to highlight these 'special' register addresses - by showing them in red. So, in the table cells with a register address ending in 0 or 8, I use "" and "" to surround the address value.
My table has 3 columns, Register, Address, and Description. Then one row might look like
"ACC 0xE0 Accumulator".
I got my table all done and it looks great. Then I got the idea that I want to be able to sort the table on any column. For example, if I click on "Address" I want the table to re-display and sort by the values in that column.
I searched, and found a way to do it. It works by having a "sort" button - click on that and it re-displays sort on the first column values. I implemented a simple version of it and got it working. I then changed it to instead sort on the second column when the "sort" button was clicked.
That didn't exactly work .... because of all those "" whatevers.
The example I copied from his here:
https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_sort_table
Is there anything 'simple' I can do to use this method - but still be able have certain entries in the Address column be shown red ?
I should probably stick to programming microcontrollers, but I like a challenge.
sample code for sort on a selected column,
that's free...
const
myButtonSort = document.querySelector('#my-button-sort')
, colSelector = document.querySelector('#sel-col')
, myTable_tBody = document.querySelector('#my-table > tbody')
;
myButtonSort.onclick = _ =>
{
let col = parseInt(colSelector.value );
[...myTable_tBody.querySelectorAll('tr')]
.map(row=>({row, str:row.cells[col].textContent }))
.sort((a,b)=>a.str.localeCompare(b.str))
.forEach(el=>
{
myTable_tBody.appendChild(el.row)
})
}
table {
border-collapse : collapse;
margin : 2em 1em;
}
td,th {
padding : .2em .8em;
border : 1px solid darkblue;
}
thead {
background : lightseagreen ;
}
<select id="sel-col">
<option value="0">column x</option>
<option value="1">column y</option>
</select>
<button id="my-button-sort">sort</button>
<table id="my-table">
<thead>
<tr> <th>x</th> <th>y</th> </tr>
</thead>
<tbody>
<tr> <td>aa</td><td> 1 </td></tr>
<tr> <td>zz</td><td> 2 </td></tr>
<tr> <td>ee</td><td> 3 </td></tr>
<tr> <td>cc</td><td> 4 </td></tr>
</tbody>
</table>
Ascending and descending sort example:
const myArray =
[ { worth: '100', name: 'jessca', reason: 'money', email: 'j#gmail.com', number: '4456', instagram: 'hvg_ujh', tiktok: 'hhgh.thg' }
, { worth: '265', name: 'e', reason: 'money', email: 'e#gmail.com', number: '3456', instagram: 'hvg_ujh', tiktok: 'hhgh.thg' }
, { worth: '6000', name: 'ssica', reason: 'sex', email: 's#gmail.com', number: '0456', instagram: 'hvg_ujh', tiktok: 'hhgh.thg' }
, { worth: '855', name: 'sica', reason: 'sex', email: 'ss#gmail.com', number: '9456', instagram: 'hvg_ujh', tiktok: 'hhgh.thg' }
, { worth: '8679', name: 'ica', reason: 'sex', email: 'i#gmail.com', number: '0756', instagram: 'hvg_ujh', tiktok: 'hhgh.thg' }
, { worth: '1', name: 'ca', reason: 'money', email: 'c#gmail.com', number: '14856', instagram: 'hvg_ujh', tiktok: 'hhgh.thg' }
]
const
t_Head = document.querySelector('#myTable thead')
, t_Head_THs = document.querySelectorAll('#myTable thead tr th')
, th_list = [...t_Head_THs].map( TH => TH.dataset.column)
, t_Body = document.querySelector('#myTable tbody')
, sortOrder = [ 'none' ,'asc', 'desc' ]
, sortType = { worth: 'num', name:'str', reason:'str', email:'str', number:'num', instagram:'str', tiktok:'str' }
, sortProcess =
{ 'asc:num' : (a,b) => +a.str - +b.str
, 'desc:num' : (a,b) => +b.str - +a.str
, 'asc:str' : (a,b) => a.str.localeCompare(b.str)
, 'desc:str' : (a,b) => b.str.localeCompare(a.str)
};
myArray.forEach( row =>
{
let TR = t_Body.insertRow()
for (col of th_list)
TR.insertCell().textContent = row[col]
})
t_Head.onclick = ({target}) =>
{
if (!target.matches('th')) return
let
dataOrder = sortOrder[(sortOrder.indexOf(target.dataset.order) +1 )% sortOrder.length]
, dataType = sortType[target.dataset.column]
;
t_Head_THs.forEach( TH => { TH.dataset.order = (TH===target) ? dataOrder : 'none' })
if (dataOrder !== 'none')
{
[...t_Body.querySelectorAll('tr')]
.map ( row => ({row, str:row.cells[target.cellIndex].textContent }))
.sort ( sortProcess[`${dataOrder}:${dataType}`])
.forEach ( elm => t_Body.appendChild(elm.row ))
}
}
body {
font-family : Arial, Helvetica, sans-serif;
font-size : 16px;
}
table {
border-collapse : separate;
border-spacing : 1px;
background-color : darkblue;
margin : 1em;
}
th, td {
border : none;
background : whitesmoke;
padding : .3em .4em;
}
th {
background-color : #76ced1;
white-space : nowrap;
cursor : pointer;
}
th::before {
content : attr(data-column) ' ';
text-transform : capitalize;
}
th[data-order=asc]::after { content : '\25B2'; }
th[data-order=desc]::after { content : '\25BC'; }
th[data-order=none]::after { content : '\25B2'; color:transparent; } /* get the same width */
<table id="myTable">
<thead>
<tr>
<th data-column="worth" data-order="none"></th>
<th data-column="name" data-order="none"></th>
<th data-column="reason" data-order="none"></th>
<th data-column="email" data-order="none"></th>
<th data-column="number" data-order="none"></th>
<th data-column="instagram" data-order="none"></th>
<th data-column="tiktok" data-order="none"></th>
</tr>
</thead>
<tbody></tbody>
</table>
This might get you started:
const table = document.getElementById("test"),
th = test.querySelectorAll("th"),
sortDefault = 0, //default sorted column number
orderDefault = 0; //default order: 0 = ascending, 1 = descending
table.dataset.sort = sortDefault;
table.dataset.order = orderDefault;
/* add click listeners on table headers */
for(let i = 0; i < th.length; i++)
{
th[i].addEventListener("click", e =>
{
/* if this column was sorted, change it's order */
if (+table.dataset.sort == e.target.cellIndex)
table.dataset.order = +table.dataset.order ? 0 : 1;
/* tell table which column is currently sorted */
table.dataset.sort = e.target.cellIndex;
sortColumn();
});
}
populateTable(); //fill table with random data
sortColumn(); //initial sort of the table
function sortColumn()
{
const rows = Array.from(table.children);
rows.splice(0, 1); //remove header from the list
rows.sort((a, b) =>
{
a = a.children[table.dataset.sort].textContent;
b = b.children[table.dataset.sort].textContent;
a = a.replace(/\W/g, ""); //remove non alphanumerical characters
b = b.replace(/\W/g, ""); //remove non alphanumerical characters
a = a.replace(/0x[a-fA-F0-9]+/, n => Number(n)); //convert 0xHEX to decimal
b = b.replace(/0x[a-fA-F0-9]+/, n => Number(n)); //convert 0xHEX to decimal
return a.localeCompare(b, undefined, {numeric: true, sensitivity: 'base'})
});
if (+table.dataset.order)
rows.reverse();
for(let i = 0; i < rows.length; i++)
{
table.appendChild(rows[i]);
}
}
function populateTable()
{
for(let i = 0, _tr = document.createElement("tr"), _td = document.createElement("td"); i < 10; i++)
{
const tr = _tr.cloneNode(true);
let td = _td.cloneNode(true);
td.textContent = "reg " + rand(0, 199);
tr.appendChild(td);
td = _td.cloneNode(true);
td.textContent = "address 0x" + rand(0, 255).toString(16);
if (rand(0,1))
td.textContent = td.textContent.replace(/ (.*)/, ' "$1"');
tr.appendChild(td);
td = _td.cloneNode(true);
td.textContent = "desc " + rand(0, 99999).toString(16);
tr.appendChild(td);
table.appendChild(tr);
}
function rand(min, max)
{
return Math.floor(Math.random() * (max - min + 1)) + min;
}
}
#test
{
border-collapse: collapse;
}
#test tr td
{
border: 1px solid black;
}
#test td
{
padding: 0.5em 1em;
}
#test th
{
user-select: none;
cursor: pointer;
}
#test th:after
{
visibility: hidden;
}
#test[data-order="0"] th:after
{
content: "▲";
}
#test[data-order="1"] th:after
{
content: "▼";
}
#test[data-sort="0"] th:nth-child(1):after,
#test[data-sort="1"] th:nth-child(2):after,
#test[data-sort="2"] th:nth-child(3):after
{
visibility: visible;
}
<table id="test">
<tr>
<th>Register</th>
<th>Address</th>
<th>Description</th>
</tr>
</table>
I've looked at previous examples of this problem but I can't find a solution for what is causing this notice based on what I've seen from other people. This appears when I am adding a new post only.
1145 is:
$post = get_post( $args[0] );
I'm not getting any other kind of error so I'm not sure where in my code this is causing the problem.
Any help on this?
This is the code:
//show metabox in post editing page
add_action('add_meta_boxes', 'kk_add_metabox' );
//save metabox data
add_action('save_post', 'kk_save_metabox' );
//register widgets
add_action('widgets_init', 'kk_widget_init');
function kk_add_metabox() {
add_meta_box('kk_youtube', 'YouTube Video Link','kk_youtube_handler', 'post');
}
/**
* metabox handler
*/
function kk_youtube_handler($post)
{
$youtube_link = esc_attr( get_post_meta( $post->ID, 'kk_youtube', true ) );
echo '<label for="kk_youtube">YouTube Video Link</label><input type="text" id="kk_youtube" name="kk_youtube" value="' . $youtube_link . '" />';
}
/**
* save metadata
*/
function kk_save_metabox($post_id) {
if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
//check if user can edit post
if( !current_user_can( 'edit_post' ) ) {
return;
}
if( isset($_POST['kk_youtube'] )) {
update_post_meta($post_id, 'kk_youtube', esc_url($_POST['kk_youtube']));
}
}
/**
* register widget
*/
function kk_widget_init() {
register_widget('KK_Widget');
}
/**
* Class KK_Widget widget class
*/
class KK_Widget extends WP_Widget
{
function __construct()
{
$widget_options = array(
'classname' => 'kk_class', // For CSS class name
'description' => 'Show a YouTube video from post metadata'
);
$this->WP_Widget('kk_id', 'YouTube Video', $widget_options);
}
/**
* Show widget form in Appearance/Widgets
*/
function form($instance)
{
$defaults = array(
'title' => 'YouTube Video'
);
$instance = wp_parse_args((array)$instance, $defaults);
var_dump($instance);
$title = esc_attr($instance['title']);
echo '<p>Title <input type="text" class="widefat" name="' . $this->get_field_name('title') . '" value="' . $title . '" /></p>';
}
function update($new_instance, $old_instance)
{
$instance = $old_instance;
$instance['title'] = strip_tags($new_instance['title']);
return $instance;
}
/**
* Show widget in post/page
*/
function widget($args, $instance)
{
global $before_widget;
global $after_widget;
global $before_title;
global $after_title;
extract( $args );
$title = apply_filters('widget_title', $instance['title']);
//show only if single post
if(is_single()) {
echo $before_widget;
echo $before_title.$title.$after_title;
//get post metadata
$kk_youtube = esc_url(get_post_meta(get_the_ID(), 'kk_youtube', true));
//print widget content
echo '<iframe width="200" height="200" frameborder="0" allowfullscreen src="http://www.youtube.com/embed/' . $this->get_yt_videoid($kk_youtube) . '"></iframe>';
echo $after_widget;
}
}
function get_yt_videoid($url)
{
parse_str(parse_url($url, PHP_URL_QUERY), $my_array_of_vars);
return $my_array_of_vars['v'];
}
}
I found the solution here https://wordpress.org/support/topic/patch-notice-undefined-offset-0-in-capabilitiesphp-on-line-1102
May seem different issue but I could fix the issue changing:
if ( ! current_user_can( 'edit_post' ) ) return;
to
if ( ! current_user_can( 'edit_posts' ) ) return;
In other scenary
if you have a custom taxonomy, you must be sure that 'assign_term' capability on 'capabilities' args is related to 'edit_posts'
'assign_terms' => 'edit_posts',
or
'assign_terms' => 'edit_mycustomposttypes',
(note the 's' at end)
example:
$capabilities = array(
'manage_terms' => 'manage_mytaxs',
'edit_terms' => 'manage_mytaxs',
'delete_terms' => 'manage_mytaxs',
**'assign_terms' => 'edit_mycustomposttypes',**
);
$args = array(
'show_ui' => true,
'show_admin_column' => true,
**'capabilities' => $capabilities,**
);
register_taxonomy( 'mytax', 'mycustomposttype', $args );
This line:
if( !current_user_can( 'edit_post' ) ) {
Should be:
if( !current_user_can( 'edit_post', $post_id ) ) {
I have around 700 product list in my Databse table.
I am using bootstrap's tokenfield for auotcomplete, i have to use auto complete in search textbox.
I am getting syntax error :
SyntaxError: missing ] after element list
...B','Lino Perros Men's Leather Wallet - Pink','Lenovo A269i','Lenovo S660 - Tita**
in console.
<?php $t = $this->general_model->auto_complete_sug(); ?>
$( document ).ready(function() {
$('#tokenfield-2').tokenfield({
autocomplete: {
source: <?=$t?>,
delay : 100
},
limit: 1,
minLength: 1,
showAutocompleteOnFocus: true
});
});
<input type="text" class="span2" name="search" id="tokenfield-2" placeholder="Search...">
In my model: I have created this functions:
public function auto_complete_sug()
{
$data = $this->auto_complete_token_fun();
$data1 = explode(',', $data);
$data1 = array_unique($data1);
foreach ($data1 as $value1) {
$temparr[] = $value1;
}
$str = '[';
$c = count($temparr);
$counter = 0;
foreach ($temparr as $val) {
$counter++;
$str .= "'".$val."'";
if($counter < $c){
$str .= ",";
}
}
$str .= ']';
return $str;
}
public function auto_complete_token_fun()
{
// $this->db->query("SET GLOBAL group_concat_max_len = 10000000");
$q = $this->db->query("SELECT GROUP_CONCAT( sub_category_name ) AS scname
FROM `tbl_subcategory` WHERE status = 'Active' ");
if($q->num_rows() > 0)
{
$d = $q->row_array();
return $d['scname'];
}
else
{
return '';
}
}
Please help!!
I'm trying to delete some rows with checkbox and i'm not sure what am i doing wrong.
The view:
<table class="table table-hover">
<?php echo form_open('site/delete');?>
<?php
foreach ($query as $row){
echo '<tr><td>
<label class="checkbox">
'.form_checkbox('delete[]', $row['link'])."<a href='".$row['link']."'>".$row['title']."</a></td><td>".substr($row['pub_date'], 5, 12).
"</label>
</td></tr>";
} ?>
<?php echo form_submit('submit','Delete');?>
<?php echo form_close();?>
</table>
controller:
function delete()
{
$url = $this->input->post('delete');
if(isset($url))
{
$this->load->model('membership_model');
$this->membership_model->delete();
$this->main_menu();
}
else
{
redirect('site/main_menu');
}
model:
function delete()
{
$delete = $this->input->post('delete');
for($i=0;$i<count($delete);$i++) {
$del_link = $delete[$i];
$this->db->where('link',$del_link);
$this->db->delete('feeds');
}
}
When i click delete nothing changes. I want to delete rows with box checked from my database.
controller
public function delete()
{
$did= $this->input->post('delete');
if(!empty ($did))
{
foreach ($did as $key => $value)
{
$res=$this->membership_model->delete($value);//pass particular id to delete
$this->main_menu();
}
}
else
{
redirect('site/main_menu');
}
}
Model:
function delete($fid)
{
$this->db->where('link', $fid);
$this->db->delete('feeds');
}