WYSIWYG shortcode to AngularJS function - javascript

I have a custom WordPress shortcode that when used in a WYSIWYG returns a bunch of html with an Angular function attached.
Below is an example of what I am trying to do.
Shortcode:
add_shortcode('example', function($atts) {
extract(shortcode_atts([
'string' => 'This is default text'
], $atts));
ob_start();
?>
<div class="example-layout">
<div class="container">
<button ng-click="do_something('<?= $string; ?>')">
Click here
</button>
</div>
</div>
<?php
return ob_get_clean();
});
Usage: [example string="Override default string"]
Returns:
<div class="example-layout">
<div class="container">
<button ng-click="do_something('Override default string')">
Click here
</button>
</div>
</div>
Angular function:
$scope.do_something = function(string) {
alert(string);
};
This isn't going to work, but I am struggling to find a sensible solution.
Any help or advice would be great.

Try this way
<div class="container" ng-controller="TodoCtrl">
<button ng-click="do_something('testClick')">CLICK ME</button>
</div>
On Angular :
function TodoCtrl($scope) {
$scope.do_something = function (name){
angular.isFunction($scope[name])
$scope[name]()
}
$scope.testClick = function(){
alert("Called");
}
}

Related

Script is not working. I use dojo toolkit

I'm creating a web application using dojo toolkit's TabConatiner.
Clicking fn_addTab("/page", this) on the Menu will show the page as a tab. It looks like an iframe.
But there is a problem. Tabs imported into 'href' attribute, script in jsp don't work. If the url mapped to the controller is shown in the tab, does not the script inside the jsp have to work as well?
home.js
function fn_addTab(url, node) {
require([
'dijit/registry',
'dijit/layout/ContentPane',
'dojo/domReady!'
], function(registry, ContentPane) {
const tabContainer = registry.byId("tabContainer");
...
let tab = registry.byId(tabId);
if(typeof tab === 'undefined') {
tab = new ContentPane({
id: tabId,
title: sidebarMenuText,
href: url,
closable: true
});
tabContainer.addChild(tab);
}
tabContainer.selectChild(tab);
fn_initActiveMenu(node);
});
}
page.jsp
<section class="wrapper">
<!-- page start -->
<div class="row">
<div class="col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="page-header">page 3</h2>
</div>
<div class="panel-body">
<button id="btn" type="button" onclick="helloWorld()">Click</button>
</div>
</div>
</div>
</div>
<!-- page end-->
</section>
<script>
function helloWorld() {
alert('helloWorld?');
}
</script>
That button is not working.
helloWorld() is not defined.
Controller
#RequestMapping(value = "/page")
public String page() {
return "page/page";
}
Fixed. Use dojox/layout/ContentPane, not dijit/layout/ContentPane.
https://dojotoolkit.org/reference-guide/1.10/dojox/layout/ContentPane.html

How to store value of all the checked box to an array and pass it to PHP function using AJAX call?

I am making an Exam-Test Module. In which there will be more than one questions. Each questions has multiple choice answers. I am showing one question at a time. There will be a button called 'Next' till the last question appears. If there are no more questions, the button will say Submit Test. When user clicks on Submit Test button, all answers of all the questions will be passed to PHP function in the backend to check how many are correct and wrong? I tried doing the following thing but I am getting the array with only one answer and that of first question. How can I achieve this ? I want to store the answers of all the questions in one array and then pass that array to PHP function through AJAX .post call or jQuery call ?
index.php
<div class="modal fade test-modal" id="Test">
<div class="modal-dialog">
<div class="modal-content">
<? foreach ($questions as $i=>$question) { ?>
<div class='question'>
<div class="modal-header">
<div class="row">
<h4>QUIZ</h4>
</div>
</div>
<div class="modal-body">
<div class="row">
<div class="quest">
<ul class="list-unstyled">
<? foreach ($question->getAnsChoice as $answer) { ?>
<li>
<div class="checkbox">
<input class="cb" type="checkbox" name="answer[]" value="<?=$answer->title?>">
<?=$answer->title?>
</div>
</li>
<? } ?>
</ul>
<br>
<br>
<p class='error'>Please select an answer</p>
</div>
</div>
</div>
<div class="modal-footer">
<p class='quest_num'><?=$question->number?> of <?=count($questions)?></p>
<? if( count($questions) === 1 ) { ?>
<a id="submit_quiz" class="btn button btn-lg quiz-btn">Submit Test</a>
<? } else if ( count($questions) === $i +1 ) { ?>
<a id="submit_quiz" class="btn button btn-lg quiz-btn">Submit Test</a>
<? } else { ?>
<a class=" btn button btn-lg quiz-btn">Next Question</a>
<? } ?>
</div>
</div>
<? } ?>
</div>
</div>
</div>
javascript
<script type="text/javascript">
$(document).on('ready', function(){
$('.quiz-btn').click(function(e){
e.preventDefault()
var checkbox = $(this).parents('.question').children('.modal-body').children('.row').children('.quest').children('ul').children('li').children('.checkbox').children('.icheckbox_square');
var btn = $(this).parents('.question').children('.modal-footer').children('.quiz-btn')
var next = false
var submit = false
var answers = [];
$(checkbox).each(function(){
if ( $(this).hasClass('checked') && $(btn).html() == 'Next Question' ) {
answers.push($('.cb:checked').val());
next = true
}
else if ($(this).hasClass('checked') && $(btn).html() == 'Submit Test') {
submit = true
}
});
if ( next ) {
e.preventDefault();
$(this).parents('.question').slideUp(500);
$(this).parents('.question').next('.question').delay(500).slideDown(500);
} else if ( submit ) {
e.preventDefault();
$.post('/student/submit_quiz',{asnwers: answers}, function(data){
});
} else {
console.log(next)
$('.quest .error').fadeIn();
}
});
}
</script>
There are a couple of issues with this code that I've noticed:
$(checkbox).each(function(){
if ( $(this).hasClass('checked') && $(btn).html() == 'Next Question' ) {
answers.push($('.cb:checked').val()); // LOGIC ERROR
next = true
}
else if ($(this).hasClass('checked') && $(btn).html() == 'Submit Test') {
submit = true
}
});
The line of code that I've marked with a comment is querying the entire document for all checkboxes matching '.cb:checked' with $('.cb:checked'). Then, JQuery's .val() function gets the value of just the first element from that collection.
Here is the relevant JQuery API documentation:
Description: Get the current value of the first element in the set of matched elements.
So the JavaScript iterates through every checkbox, then repeatedly adds just the first checkbox in the document's value to the array.
To fix this, get the value from the current this object:
if ( $(this).hasClass('checked') && $(btn).html() == 'Next Question' ) {
answers.push($(this).val()); // modified line
next = true
}
The second is that the variable answers exists separately for each button. You have one button for each section and a new, separate function call for each button. You would need to hoist the answers variable outside of the event function:
$(document).on('ready', function(){
var answers = [];
$('.quiz-btn').click(function(e){
// Bla bla bla
answers.push(the_correct_value);
// Bla bla bla
});
}
If you don't want the answers variable to be available to everything in the document.ready event listener, you can use a pattern called an Immediately Invoked Function Expression:
$(document).on('ready', function(){
(function(){ // Notice how this line starts with an open bracket
var answers = [];
$('.quiz-btn').click(function(e){
// Bla bla bla
answers.push(the_correct_value);
// Bla bla bla
});
})(); // This line closes the open bracket above,
// then immediately runs the result with no arguments
// the `answers` variable is unavailable in this scope
}
The JavaScript that you included was also missing a closing bracket at the very end of the script.
All that said, the solution I would use personally would be to wrap the whole thing in a form, use a submit button, listen for the form's submit event and just create a JavaScript FormData to send the answers:
<div class="modal fade test-modal" id="Test">
<div class="modal-dialog">
<div class="modal-content">
<form action="/student/submit-quiz" method="POST"><!-- Form tag -->
<?php foreach($questions as $i => $question): ?>
<div class="question">
<div class="modal-header">
<div class="row">
<h4>QUIZ</h4>
</div>
</div>
</div>
<div class="modal-body">
<div class="row">
<div class="quest">
<ul class="list-unstyled">
<?php foreach ($question->getAnsChoice as $answer): ?>
<li>
<div class="checkbox">
<input class="cb" type="checkbox" name="answer[]" value="<?= $answer->title ?>" />
<?= $answer->title ?>
</div>
</li>
<?php endforeach; ?>
</ul>
</div>
</div>
</div>
<div class="modal-footer">
<p class="quest_num"><?= $question->number ?> of <?= count($questions) ?></p>
<?php $last = $question->number === count($questions) - 1; ?>
<!--
Ternary operators, used in these attributes, are like if statements:
if the first thing is true, return the second,
otherwise return the third.
-->
<input type="<?= $last ? 'submit' : 'button' ?>" class="btn button btn-lg quiz-btn" value="<?= $last ? 'Submit Test' : 'Next Question' ?>" />
</div>
<?php endforeach; ?>
</form>
<script>
/*
* Where the real magic happens.
*/
$('form[action="/student/submit-quiz"]').on('submit', function(e) {
e.preventDefault();
data = new FormData(this);
$.ajax({
url: this.action,
data: data,
contentType: false,
processData: false,
type: 'POST',
success: function(response) {
// do something useful with the response
console.log(response);
},
});
});
$('form[action="/student/submit-quiz"] input[type="button"]').on('click', function(e) {
$(this).parents('.question').slideUp(500);
$(this).parents('.question').next('.question').delay(500).slideDown(500);
});
</script>
</div>
</div>
</div>

Code mirror not working with angular js binding variable

Html:
<body ng-app ng-controller="OrderFormController">
<!--<h1 class="errorHeader">List of Classes</h1>-->
<header>
<div class="container">
<div id="branding">
<h1>Apex <span class="highlight"> Editor </span> </h1>
</div>
</div>
</header>
<div class="col-md-12 col-lg-12">
<div class="panel with-nav-tabs panel-default">
<div class="panel-heading">
<ul class="nav nav-tabs">
<li class="active">Apex Editor</li>
</ul>
</div>
<div class="panel-body">
<div>
<input type="text" name="apexClass" id="autocomplete" placeholder="Type the name of the Apex class you want to edit"/>
</div>
<div class="btn-group-vertical" style="padding: 1%">
<button type="button" class="btn btn-primary" id="editBtn">Edit</button>
</button>
</div>
<div class="tab-content" align="left">
<div id='error' style='display:none'>{{apexClassWrapperError.message}}</div>
<div>{{apexClassWrapper.name}}</div>
<img src="../img/ajax-loader.gif" id="loaderImage" style='display:none'>
<form>
<textarea ng-model="apexClassWrapper.body" id="code" name="code" readonly="true" >{{apexClassWrapper.body}}</textarea>
</form>
</div>
<button type="button" class="btn btn-primary" id="saveBtn" ng-click="postdata(apexClassWrapper)">Save</button>
</div>
</div>
</div>
<script src="../js/makeEditable.js"></script>
<script>
$(function() {
var editor = CodeMirror.fromTextArea(document.getElementById("code"),{
linenumber : true,
matchBrackes: true,
mode: "text/x-apex"
})
});
</script>
<footer>
<p>Web based Apex Editor</p>
<p>Developed By - Nagendra Kumar Singh</p>
</footer>
</body>
CSS and JS files included at top:
<script src="../js/codemirror.js"></script>
<script src="../js/apex.js"></script>
<script src="../js/matchbrackets.js"></script>
<link href="../css/codemirror.css" rel="stylesheet"/>
The controller is a simple one fetching the class through a RESTApi.
function OrderFormController($scope, $http) {
$('#autocomplete').autocomplete({
type: 'POST',
serviceUrl: 'http://localhost:8989/getSuggestion',
onSelect: function (suggestion) {
console.log('suggestion.value -> '+suggestion.value);
var data = {
apexClassName:suggestion.value
};
var config = {
params: data
};
$('#loaderImage').show();
$http.get("http://localhost:8989/getApexBody",config).then(function (response) {
$scope.apexClassWrapper = response.data;
$('#loaderImage').hide();
});
}
});
};
But I can only see {{apexClassWrapper.body}} in my text area, I dont see the real code when using CodeMirror, If I remove code mirror , I can see the class, but I cannot figure out a way to show the body with CodeMirror included.
There are no errors in console log and all the JS and CSS files are loaded perfectly. Please help.
Ok, So I think I may have figured it out. What I did is I set a timeout for the codemirror code to run as follows in the js file and removed it from the index.html.
$('#loaderImage').show();
$http.get("http://localhost:8989/getApexBody", config).then(function (response) {
$scope.apexClassWrapper = response.data;
$('#loaderImage').hide();
if(globalEditor) {
globalEditor.toTextArea();
}
setTimeout(function (test) {
var editor = CodeMirror.fromTextArea(document.getElementById('apexBody'), {
lineNumbers: true,
matchBrackets: true,
mode: "text/x-apex"
});
globalEditor = $('.CodeMirror')[0].CodeMirror;
}), 2000
});
The only issue in this answer is that, it creates multiple code editor window when I try to load different classes. How can I resolve that?
So finally got it working, defined a global variable and using the method toTextArea

POST request doesn't recognize in my controller using Opencart

I have a problem in my code. In my setup I created a single page for language selection. And I copy some of opencart's code on language template and also on controller. But my problem is after passing my form, the action controller doesn't get any POST data from my form.
<form action="{{ action }}" method="POST" enctype="multipart/form-data" id="form-language">
<div class="col-lg-4">
<div class="border_index_in">
<div class="holder">
<h3>ENGLISH</h3>
<button class="language-select btn btn-green" type="button" name="en-gb">Choose</button>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="border_index_in">
<div class="holder">
<h3>日本語</h3>
<button class="language-select btn btn-green" type="button" name="jap">選択</button>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="border_index_in">
<div class="holder">
<h3>中文</h3>
<button class="language-select btn btn-green" type="button" name="zh-hk">选择</button>
</div>
</div>
</div>
</form>
JS:
// Language
$('#form-language .language-select').on('click', function(e) {
e.preventDefault();
$('#form-language input[name=\'code\']').val($(this).attr('name'));
$('#form-language').submit();
});
Controller to show my language selection page
public function language_switch() {
$this->load->model('setting/extension');
$this->document->setTitle($this->config->get('config_meta_title'));
$this->document->setDescription($this->config->get('config_meta_description'));
$this->document->setKeywords($this->config->get('config_meta_keyword'));
if (isset($this->request->get['route'])) {
$this->document->addLink($this->config->get('config_url'), 'canonical');
}
$data['action'] = $this->url->link('common/language/language');
$data['code'] = $this->session->data['language'];
$styles_array = array(
'catalog/view/theme/onemidorie/stylesheet/style.css'
);
$scripts_array = array(
);
foreach($styles_array as $st) {
$this->document->addStyle($st);
}
foreach($scripts_array as $sc) {
$this->document->addScript($sc);
}
$data['styles'] = $this->document->getStyles();
$data['scripts'] = $this->document->getScripts();
$data['footer'] = $this->load->controller('common/footer');
$data['header'] = $this->load->controller('common/header');
$this->response->setOutput($this->load->view('common/language_selection', $data));
}
Controller that should accept the POST data from my form:
public function language() {
print_r($this->request->post['code']); //Notice: Undefined index: code
die;
if (isset($this->request->post['code'])) {
$this->session->data['language'] = $this->request->post['code'];
}
if (isset($this->request->post['redirect'])) {
$this->response->redirect($this->request->post['redirect']);
} else {
$this->response->redirect($this->url->link('common/home'));
}
}
Can you help me this?
You should use
print_r($this->request->post);
die;
Then you will get some post data.
because you define the name like "en-gb","jap" and "zh-hk". So please use above code then you can get solution.
You're not posting any data - you're just showing a button. Use something more like
<input type="submit" value="english" name="lang"/>
<input type="submit" value="japanese" name="lang"/>
etc. then just look at
$_POST['lang']
and see if it's english, japanese or whatever.
You can find out how opencart set language in /catalog/controller/startup/startup.php:
// Overwrite the default language object
$language = new Language($code);
$language->load($code);
$this->registry->set('language', $language);
So in controller what should accept the POST data you should dublicate this code before loading language:
// $this->request->post['code'] = 'en-gb' or 'ru-ru' or whatever.
$language = new Language($this->request->post['code']);
$language->load($this->request->post['code']);
$this->registry->set('language', $language);
// now opencart use new language and you can use it too:
$this->load->language('common/header');
$text_home = $this->language->get('text_home');
This works for me in opencart 2

How to add to html <a> tag onclick event with PHP and call the function in JavaScript file

This question maybe is little bit strange but I need to learn it asap.
I have a HTML file which is called upgrade.view.php here is the piece of code that I am on working on:
<form role="form" method="get" action='index.php?action=Frontend_upgradeChosen'>
<div class="col-md-5">
<ul name="S_PRODUCT" id="S_VARIABLE">
<?php
if (isset($oldProduct) && isset($arrayUpgrade)){
foreach ($arrayUpgrade as $value) {
$pro = $value->getnewProduct(); //
echo '<li>'.$pro->getName().'</li>';
}
?>
</ul>
</div>
</form>
</div>
//which closes the main DIV
<script type="text/javascript" language="javascript" src="<?= PATH_VIEWS_INCLUDES_URL ?>js/upgrade/upgrade.js"></script>
On the other hand I am trying to call the JS function from upgrade.js where I have this function:
function searchSN(elem) {
var a = elem.innerHTML;
alert(a);
}
Finally in my separated PHP file I have this function:
public function upgradeChosen() {
$selectedVariable = $_GET['S_PRODUCT'];
echo 'The Price is:'." ". $selectedVariable;
include $this->getPrintedView();
}
As updated version of the question I am getting the on click event from the <A> tag but not the value the value of says undefined value.
I have updated the question so that maybe it makes it more understandable what I am trying to achieve.
Many Thanks in Advance
something like this ?
function searchSN(elem) {
var a = elem.innerHTML;
alert(a);
}
<form class="" role="form" method="get" action='index.php?action=Frontend_upgradeChosen'>
<div class="col-md-5">
<ul name="S_PRODUCT" id="S_VARIABLE" >
<li>test</li>
</ul>
<button id='choose_product' type="submit" class='btn btn-default'><i class='icon-rocket'>Submit</i></button>
</div>
</form>

Categories

Resources