Topic on Project:Support desk

I need html forms and Javascript in MediaWiki - Extension:CalcII doesn't work on newer MediaWiki Versions

17
85.158.138.21 (talkcontribs)

Hello,

I need a tag extension for calculating in MediaWiki. I need an input field and an output (result) field. For calculating JavaScript should be ok. I found the extension calcII but it is for older MediaWiki-Versions. Can someone show me how to write a simple tag extension similar to calcII? I already read a lot about extensions but did't find out how to get JavaScript work to manipulate a form.

MediaWiki 1.19.3 PHP 5.3.3-7 MySQL 5.1.73-1


Thanks in advance! Karsten

Florianschmidtwelzow (talkcontribs)

Hello,

i think this is the right site for you: https://www.mediawiki.org/wiki/Manual:Developing_extensions

I think, if i understand you right, you want to create a parser Extension? Then look, too, here: https://www.mediawiki.org/wiki/Manual:Parser_functions

To create a form you can use Html Class or HtmlForm class. To add a JavaScript file to the head, you can use addScriptFile in class OutputPage (https://doc.wikimedia.org/mediawiki-core/master/php/html/classOutputPage.html#a5ecdfe5c2253e36c580e0187c46d8c43). And the other is: read, read, read, learn, learn, learn :)

Hope that helps.

85.158.138.21 (talkcontribs)

Hello Florian,

thank you for the links and the hint with the classes. I now have the following code (where calculator.js has a function "delete_all()) but get an error "delete_all" is null:

<?php
if ( !defined( 'MEDIAWIKI' ) ) {
	die( "This is not a valid entry point.\n" );
}
$dir = __DIR__ . '/';
$wgExtensionMessagesFiles['Calculator'] = $dir . 'calculator.i18n.php';

$wgHooks['ParserFirstCallInit'][] = 'wfCalculator';
 
function wfCalculator(Parser $parser) {
  
 $parser->setHook( 'calc', 'renderCalculator');

return true;
}
 
function renderCalculator( $input, array $args, Parser $parser, PPFrame $frame) {
 
global $wgOut;

$wgOut->addScriptFile(__DIR__ . '/calculator.js', $wgStyleVersion);
$wgOut->AddHTML('<form name="data";">');
$wgOut->AddHTML('<table bgcolor="#FFFFFF"><tr><td>');
$wgOut->AddHTML('<textarea name="tarea" cols="30" rows="10" wrap="off"/>');
$wgOut->AddHTML($input);
$wgOut->AddHTML('</textarea></td><td><textarea name="result" cols="20" rows="10" value=""/></textarea></td></tr>');
$wgOut->AddHTML('<tr><td><input type="button" value="calculate" onclick="calculate()"/></td>');
$wgOut->AddHTML('<td><input type="button" value="delete" onclick="delete_all()"/></td>');
$wgOut->AddHTML('</tr></table>');
$wgOut->AddHTML('</form>');
$wgOut->AddHTML('</center>');
}

When using mediawiki classes, do I have to import them with "$wgAutoloadLocalClasses"? I already studied a lot of other extensions but didn't find out how to get it work.

Florianschmidtwelzow (talkcontribs)

Hello :)

That what you do, is to add Text to the page, for this you don't need to use ParserFirstCallInit. I thought you want to create a tag, maybe <calculator> or something else :) Where you want to add the form to make clear to me, what you want :)

P.S.: To add JavaScript Files to the page header, please use Manual:Hooks/BeforePageDisplay, there you get as first param the OutputPage class and you don't have to use the "ugly" global $wgOut :P Where you have saved the calculator.js and is it visible in source code of your page? :)

> When using mediawiki classes, do I have to import them with "$wgAutoloadLocalClasses"? If you want to load a PHP class, then: yes :)

85.158.138.21 (talkcontribs)

Hello,

I have a an extension-folder "calculator" where I stored my php and my js-File. The calculator.js is not visible in source code of my page. I need a tag "calc" i.e. <calc>x^2+5</calc>. On the page the user should have an input-field where he can define x and a result field that contains the result of the formula after pushing a button. That's why I think a tag extension would be the right thing. So <calc>... in the source code should be replaced in the page by a form.

Florianschmidtwelzow (talkcontribs)

Ah, sorry, i overlooked wfCalculator function, which is not correct, i think, please use:

function wfCalculator(Parser $parser) {
 
 $parser->setFunctionHook( 'calc', 'renderCalculator' );
 
 return true;
}

And then add a function to the hook BeforePageDisplay to add your javascript file:

$wgHooks['BeforePageDisplay'][] = 'onBeforePageDisplay';
function onBeforePageDisplay( &$out, &$skin ) {
 
 $out->addScriptFile(__DIR__ . '/calculator.js', $wgStyleVersion);
}

After this you can implement your ParserHook:

function renderCalculator( $parser, $arg ) {
$output = '';
$output .= '<form name="data";">';
$output .= '<table bgcolor="#FFFFFF"><tr><td>';
$output .= '<textarea name="tarea" cols="30" rows="10" wrap="off"/>';
$output .= $arg;
$output .= '</textarea></td><td><textarea name="result" cols="20" rows="10" value=""/></textarea></td></tr>';
$output .= '<tr><td><input type="button" value="calculate" onclick="calculate()"/></td>';
$output .= '<td><input type="button" value="delete" onclick="delete_all()"/></td>';
$output .= '</tr></table>';
$output .= '</form>';
$output .= '</center>';

// Output for a parser hook isn't set via OutputPage, you just return the content (the tag will be replaced with this return)
return $output;
}

Something like this. Hope you can work with this :)

85.158.139.100 (talkcontribs)

Hi Florian,

I was not able to import the calculator.js-File. Don't ask me why. I now tried:

$output .= '<script type="text/javascript" src="http://-servername-/vm/extensions/Calculator/calculator.js">';

and it worked. With

function wfCalculator(Parser $parser) {
 
 $parser->setFunctionHook( 'calc', 'renderCalculator' );
 
 return true;
}

replacing the tag didn't work. It has to be

"$parser->setHook".

Thanks for your support!

Florianschmidtwelzow (talkcontribs)

Yeah, setFunctionHook is for functions like {{calc:x|2|5}}, was my fault :) setHook is the right for you.

Is calculator.js not added in source code?

85.158.139.100 (talkcontribs)

What do you mean "added in source code"?

Florianschmidtwelzow (talkcontribs)

If you use the hook BeforePageDisplay and use $out->addScriptFile( __DIR__ . '/calculator.js' ); it doesn't work you said? Can you check (after you use the hook) if you can find calculator.js in the source code of the HTML page (in Browser)?

Background:

$output .= '<script type="text/javascript" src="http://-servername-/vm/extensions/Calculator/calculator.js">';

isn't very beautiful ;)

85.158.139.100 (talkcontribs)

At the end of the html source code I find:

<script src="/usr/share/mediawiki/vm/extensions/Calculator/calculator.js?303"></script>
Florianschmidtwelzow (talkcontribs)
85.158.139.100 (talkcontribs)

Now I have the following that doesn't work:

...
$wgResourceModules ['ext.Calculator']= array(
  'scripts'       => __DIR__ . '/calculator.js',
  'localBasePath' => __DIR__,
  'remoteExtPath' => 'Calculator'
);

$wgHooks['BeforePageDisplay'][] = 'onBeforePageDisplay';
   
function onBeforePageDisplay( &$out, &$skin ) {
   $out->addModules(array('ext.Calculator'));
   return true;
}
...

and in html source:

<script>if(window.mw){ mw.loader.load(["mediawiki.user","mediawiki.page.ready","mediawiki.action.watch.ajax","ext.Drafts","ext.vector.collapsibleNav","ext.vector.collapsibleTabs","ext.vector.simpleSearch","ext.Calculator"], null, true); }</script>
Florianschmidtwelzow (talkcontribs)

Hello!

that's probably because you try to read the script file like this (this is, what ReqourceLoader want to include: __DIR__ . __DIR__ . '/calculator.js'

) That can not work, please use:
$wgResourceModules ['ext.Calculator']= array(
  'scripts'       => 'calculator.js',
  'localBasePath' => __DIR__,
  'remoteExtPath' => 'Calculator'
);

P.S.: You can use the developer tools of your browser (e.g. with Ctrl + J in Chrome) and click on network. There is a load.php with where your ext.Calculator is in modules parameter. If you click on this you can see errors of resource loader in comments at the top of response :) That sometimes helps to find some errors, i think in this too (i'm unsure, if RL adds this error message).

85.158.138.26 (talkcontribs)

Hello,

in the response I see

...
mw.loader.implement("ext.Calculator",function($){function rechnen(){var m1eingabe_w=window.document.felder.formel.value;
...

So he did load the js-File but with pushing a button I still get the error: "delete_all" is undefined.

In html-source I see

<script src="/vm/load.php?debug=false&lang=de&modules=ext.Calculator%2CDrafts%7Cjquery.autoEllipsis%2CcheckboxShiftClick%2CcollapsibleTabs%2CdelayedBind%2ChighlightText%2CmakeCollapsible%2Cmw-jump%2Cplaceholder%2Csuggestions%2CtabIndex%7Cmediawiki.action.watch.ajax%7Cmediawiki.api%2Cuser%7Cmediawiki.api.watch%7Cmediawiki.legacy.mwsuggest%7Cmediawiki.page.ready&skin=vector&version=20140702T091942Z&*" type="text/javascript"></script>
Florianschmidtwelzow (talkcontribs)

Hello! :)

Maybe it's better to use jQuery, instead of "plain" JavaScript only. You can remove onclick="delete_all()" from the button and set an unique id, e.g. id="calculator_delete_all" and then use jQuery to run a function:

( function ( $ ) {
  $( '#calculator_delete_all' ).on( 'click', function() {
    // do your stuff after button is clicked
  } );
}( jQuery ) );

(like ever: untested :P)

Reply to "I need html forms and Javascript in MediaWiki - Extension:CalcII doesn't work on newer MediaWiki Versions"